Changeset 5466 for TI01-discovery


Ignore:
Timestamp:
08/07/09 10:46:54 (10 years ago)
Author:
cbyrom
Message:

Add to code to allow the OAI editor to be used with the new openid
based security system. Add the policy file and secured ini file +
adjust handling of users - enforcing page access via URL content

  • basically either by provider ID or via 'admin=1' parameter for

admin users. For the latter, provider security_redirector module to
allow admin users to use same point of entry as normal users.

Location:
TI01-discovery/trunk/OAIInfoEditor
Files:
3 added
1 deleted
18 edited

Legend:

Unmodified
Added
Removed
  • TI01-discovery/trunk/OAIInfoEditor/README.txt

    r5256 r5466  
    3939- harvestDir - the directory to harvest OAI documents to 
    4040 
    41 [USER_LIST] 
    42 - userIDs - include a list of user IDs which have access to the OAI Info Editor 
    43  
    44 NB, each user ID should then have its own section - e.g. if userIDs is as follows: 
    45  
    46 userIDs: calum bob fred 
    47  
    48 there needs to be three futher sections, [calum], [bob] and [fred]  
    49  
    50 - the content of these additional sections should include the following: 
    51 - pw - the password matching the user ID 
    52 - providerNames - a semicolon delimeted list of provider names that the user ID has 
    53 view/edit access rights to.  NB, if the user can view/edit everything, providerNames 
    54 should be set to the value, admin 
    55  
    56 - e.g. for the above example: 
    57  
    58 [calum] 
    59 pw: gloopy 
    60 providerNames: admin 
    61  
    62 [bob] 
    63 pw: bob 
    64 providerNames: provider1 
    65  
    66 [fred] 
    67 pw: fred 
    68 providerNames: provider2;provider3 
    69  
    70 - calum is then an admin user and bob can view/edit provider1 info, whereas fred 
    71 can view/edit provider2 AND provider3 info. 
    7241  
    7342ii) Add a config file for the postgres DB used by the discovery service; this is required 
  • TI01-discovery/trunk/OAIInfoEditor/editor.config

    r5242 r5466  
    88server:         http://localhost:5001 
    99 
    10 # SMTP server for sending mails 
     10# SMTP server for sending mails - notifying when harvests have been ran 
    1111mailserver:       outbox.rl.ac.uk 
     12 
     13# Email of the site administrator - displayed when users try to access a resource 
     14# they don't have access rights for 
     15adminemail: calum.byrom@tessella.com 
     16 
    1217 
    1318# The following should only be needed for debugging some parts of the code when running on sandboxes behind a firewall 
     
    2025backupFileDir: oaiInfoEditorDataBackups 
    2126harvestDir: harvestData 
    22  
    23 [USER_LIST] 
    24 # include a list of users (user IDs) who can use the editor 
    25 # NB, these should then each have their own sections - which specify values 
    26 # for 'pw' (the user password) and 'providerNames' (the provider info editable by the user) 
    27 # if the providerNames list includes 'admin' the user is given admin rights and can update and 
    28 # add any new provider info.  NB, the providerName list should use ';' as the delimiter - e.g. 
    29 # providerNames:blah blow;quack;provider 32;provider fred 
    30 userIDs: calum bob fred 
    31  
    32 [calum] 
    33 pw: gloopy 
    34 providerNames: admin 
    35  
    36 [bob] 
    37 pw: bob 
    38 providerNames: provider1 
    39  
    40 [fred] 
    41 pw: fred 
    42 providerNames: provider2 provider3 
    43  
    4427 
    4528 
  • TI01-discovery/trunk/OAIInfoEditor/oai_info_editor/config/oiemiddleware.py

    r5253 r5466  
    77from paste.deploy import CONFIG 
    88from ndg.common.src.models.myconfig import myConfig 
    9 from oai_info_editor.model.user import * 
    109from oai_info_editor.dal.providerinfodao import * 
    1110from oai_info_editor.lib.harvester import Harvester  
     
    4443        self.globals.proxy = cf.get('SERVERS','proxyServer') 
    4544        self.globals.mailServer = cf.get('SERVERS', 'mailserver') 
     45        self.globals.adminEmail = cf.get('SERVERS', 'adminemail') 
    4646         
    4747        self.globals.dataDir = cf.get('DATA_STORE', 'appDataFileDir') 
     
    5252         
    5353        self.globals.harvester = Harvester(self.globals.mailServer, outDir = harvestDir) 
    54  
    55  
    56         self.globals.users = {} 
    57         users = cf.get('USER_LIST', 'userIDs') 
    58          
    59         if not users: 
    60             raise ValueError("No user config data has been specified - so no one can use the editor") 
    61          
    62         logging.debug("Setting up users for editor") 
    63         for userID in users.split(): 
    64             pw = cf.get(userID, 'pw') 
    65             providerNames = cf.get(userID, 'providerNames').split(';') 
    66             names = [] 
    67             for name in providerNames: 
    68                 names.append(name.strip()) 
    69              
    70             providerNames = names 
    71          
    72             if self.globals.users.has_key(userID): 
    73                 raise ValueError("Two identical users ('%s') specified in config file - this is not allowed" 
    74                                  %userID) 
    75              
    76             self.globals.users[userID] = User(userID, providerNames) 
    77         logging.debug("- editor user objects set up") 
    7854 
    7955        # store a data access object to general use 
  • TI01-discovery/trunk/OAIInfoEditor/oai_info_editor/config/routing.py

    r5239 r5466  
    2626    map.connect('deleteProviderInfo', 'deleteProviderInfo/:providerName', controller = 'edit', action='deleteProviderInfo') 
    2727    map.connect('createProviderInfo', 'createProviderInfo', controller = 'edit', action='createProviderInfo') 
    28     map.connect('harvestProviderInfo', 'harvestProviderInfo/:providerName/:repositoryName', controller = 'harvest', action='harvestProviderInfo') 
    29  
    30     map.connect('deleteRepositoryInfo', 'deleteProviderInfo/:providerName/:repositoryName',  
    31                 controller = 'edit', action='deleteRepositoryInfo') 
    32     map.connect('createRepositoryInfo', 'createProviderInfo/:providerName/:repositoryName',  
    33                 controller = 'edit', action='createRepositoryInfo') 
     28    map.connect('harvestProviderInfo', 'harvestProviderInfo/:repositoryName/:providerName', controller = 'harvest', action='harvestProviderInfo') 
     29    map.connect('/', controller = 'home', action='index') 
    3430 
    3531    map.connect('help', 'help', controller = 'home', action='showHelpPage') 
    36      
    3732 
    3833    return map 
  • TI01-discovery/trunk/OAIInfoEditor/oai_info_editor/controllers/edit.py

    r5251 r5466  
    1313    RI_DELIMITER, NAME_ELEMENT_NAME, SPLIT_BY_SET_NAME, URL_ELEMENT_NAME 
    1414import oai_info_editor.model.providerinfo as PI 
     15from oai_info_editor.controllers.master import ADMIN_PARAMETER 
    1516  
    1617class EditController(MasterController): 
     
    1819    def createProviderInfo(self): 
    1920        ''' 
    20         Create provider info data. 
     21        Create provider info data.  NB, only admin users should be able to 
     22        access this method. 
    2123        ''' 
    2224        logging.debug("Setting up oai info editor create page") 
     
    2527        self._setUpController(providerName = providerName) 
    2628 
    27         c.saveLink = h.url_for('saveProviderInfo', providerName = providerName) 
    28         c.deleteLink = h.url_for('deleteProviderInfo', providerName = providerName) 
     29        c.saveLink = h.url_for('saveProviderInfo', providerName = providerName) + ADMIN_PARAMETER 
     30        c.deleteLink = h.url_for('deleteProviderInfo', providerName = providerName) + ADMIN_PARAMETER 
    2931        c.harvestLink = '' 
    3032         
     
    103105        c.saveLink = h.url_for('saveProviderInfo', providerName = urllib.quote(providerName)) 
    104106        c.deleteLink = h.url_for('deleteProviderInfo', providerName = providerName) 
    105          
     107 
     108        if c.user.isAdmin: 
     109            c.saveLink += ADMIN_PARAMETER 
     110             
    106111        c.title = const.EDIT_PAGE_TITLE %unquotedName 
    107112        return self._renderTemplate('genshi', 'edit_provider_infos', **self.inputs) 
     
    110115    def deleteProviderInfo(self, providerName): 
    111116        ''' 
    112         Delete the provider info for the specified provider name 
     117        Delete the provider info for the specified provider name.  NB, only  
     118        admin users should be able to access this method. 
    113119        @param providerName: name of the provider whose data is to be deleted 
    114120        ''' 
     
    124130 
    125131        # now, return to the view page 
    126         h.redirect_to('home') 
     132        h.redirect_to('home') + ADMIN_PARAMETER 
    127133 
    128134         
     
    156162 
    157163        # now, return to the view page 
    158         h.redirect_to('viewProviderInfo', providerName = urllib.quote(pi.name)) 
     164        viewLink = h.url_for('viewProviderInfo', providerName = urllib.quote(pi.name)) 
     165        if c.user.isAdmin: 
     166            viewLink += ADMIN_PARAMETER 
     167        h.redirect_to(viewLink) 
  • TI01-discovery/trunk/OAIInfoEditor/oai_info_editor/controllers/harvest.py

    r5253 r5466  
    1111class HarvestController(MasterController): 
    1212 
    13     def harvestProviderInfo(self, providerName, repositoryName): 
     13    def harvestProviderInfo(self, repositoryName, providerName): 
    1414        ''' 
    1515        Harvest the repository info associated with the input name and provider 
     16        @param repositoryName: name of repository whose info should be displayed 
    1617        @param providerName: name of provider whose info should be displayed 
    17         @param repositoryName: name of repository whose info should be displayed 
    1818        ''' 
     19        repositoryName = urllib.unquote(repositoryName) 
    1920        providerName = urllib.unquote(providerName) 
    20         repositoryName = urllib.unquote(repositoryName) 
    2121        self._setUpController(providerName = providerName) 
    2222        logging.info("Setting up page to display info for provider, '%s'" %providerName) 
  • TI01-discovery/trunk/OAIInfoEditor/oai_info_editor/controllers/home.py

    r5235 r5466  
    88from oai_info_editor.lib.constants import * 
    99from oai_info_editor.controllers.master import MasterController 
    10  
     10from oai_info_editor.controllers.master import ADMIN_PARAMETER 
    1111 
    1212class HomeController(MasterController): 
     
    2323 
    2424        if c.user.isAdmin: 
    25             c.createLink = h.url_for('createProviderInfo') 
     25            c.createLink = h.url_for('createProviderInfo') + ADMIN_PARAMETER 
    2626         
    2727        return self._renderTemplate('genshi', 'home') 
     
    3434        ''' 
    3535        logging.info("Rendering help page") 
     36        self._setUpController() 
    3637        c.title = HELP_PAGE_TITLE 
    3738        return self._renderTemplate('genshi', 'oai_info_editor_help') 
  • TI01-discovery/trunk/OAIInfoEditor/oai_info_editor/controllers/master.py

    r5237 r5466  
    1010import oai_info_editor.lib.constants as constants 
    1111import oai_info_editor.model.providerinfo as PI 
     12from oai_info_editor.model.user import User 
    1213 
     14ADMIN_FLAG = 'admin' 
     15ADMIN_PARAMETER = "?%s=1" %ADMIN_FLAG 
     16BASE_SERVER_URL = "http://%s/logout" 
    1317class MasterController(BaseController): 
    1418 
     
    2226        self.cf = request.environ['appConfig'] 
    2327         
    24         # TODO: determine the ID of the current user 
    25         userID = 'calum' 
     28        c.user = self.__getUserDetails() 
    2629         
    27         if not userID in g.users: 
    28             raise ValueError("Unrecognised user, '%s' - access to editor denied" %userID) 
     30        c.logoutLink = BASE_SERVER_URL %request.environ['HTTP_HOST']  
     31        c.homeLink = h.url_for('home') 
     32        c.helpLink = h.url_for('help') 
     33 
     34        if c.user.isAdmin: 
     35            c.homeLink += ADMIN_PARAMETER 
     36            c.helpLink += ADMIN_PARAMETER 
    2937         
    30         c.user = g.users[userID] 
    3138        c.providerInfos = g.dao.getProviderInfoForUser(c.user) 
    3239        if providerName: 
     
    6673            # settings unless these are specified in inputs - so only use if really 
    6774            # needed 
     75            # NB, the admin=1 parameter may end up here; delete, if so 
     76            if inputs.has_key(ADMIN_FLAG): 
     77                del inputs[ADMIN_FLAG] 
     78                 
    6879            if inputs or c.errors: 
    6980                for key, val in inputs.items(): 
    7081                    inputs[key] = str(val) 
    71          
     82 
    7283                return htmlfill.render(html, inputs, errors = c.errors) 
    7384            else: 
     
    7889            c.errors = {'Rendering error': e} 
    7990            return render('genshi', 'error') 
     91 
     92 
     93    def __getUserDetails(self): 
     94        ''' 
     95        Create User object from available data - this stores the user ID and 
     96        whether the user has admin rights or not. 
     97        @return:  
     98        ''' 
     99        # NB, not always possibly or necessary to know the user ID 
     100        userID = request.path_info.split('/')[-1] 
     101        if userID in ["home", "help", "createProviderInfo"]: 
     102            userID = None 
     103             
     104        return User(userID, ADMIN_FLAG in request.params and request.params[ADMIN_FLAG] == '1') 
  • TI01-discovery/trunk/OAIInfoEditor/oai_info_editor/controllers/view.py

    r5239 r5466  
    99from oai_info_editor.controllers.master import MasterController 
    1010import oai_info_editor.lib.constants as const 
     11from oai_info_editor.controllers.master import ADMIN_PARAMETER 
    1112 
    1213class ViewController(MasterController): 
     
    3637                                  repositoryName = const.REPOSITORY_REPLACEMENT) 
    3738        if c.user.isAdmin: 
    38             c.createLink = h.url_for('createProviderInfo') 
     39            c.createLink = h.url_for('createProviderInfo') + ADMIN_PARAMETER 
    3940            # NB, these links are provider dependent and we can display several 
    4041            # provider's data in a page - so finish constructing the links in the 
    4142            # templates 
    4243            c.deleteLink = h.url_for('deleteProviderInfo', providerName = '') 
     44            c.harvestLink += ADMIN_PARAMETER 
    4345         
    4446        return self._renderTemplate('genshi', 'view_provider_infos') 
  • TI01-discovery/trunk/OAIInfoEditor/oai_info_editor/editor.config

    r5255 r5466  
    2222harvestDir: harvestData 
    2323 
    24 [USER_LIST] 
    25 # include a list of users (user IDs) who can use the editor 
    26 # NB, these should then each have their own sections - which specify values 
    27 # for 'pw' (the user password) and 'providerNames' (the provider info editable by the user) 
    28 # if the providerNames list includes 'admin' the user is given admin rights and can update and 
    29 # add any new provider info.  NB, the providerName list should use ';' as the delimiter - e.g. 
    30 # providerNames:blah blow;quack;provider 32;provider fred 
    31 userIDs: calum bob fred 
    32  
    33 [calum] 
    34 pw: gloopy 
    35 providerNames: admin 
    36  
    37 [bob] 
    38 pw: bob 
    39 providerNames: provider1 
    40  
    41 [fred] 
    42 pw: fred 
    43 providerNames: provider2;provider3 
    44  
    45  
    4624 
    4725[layout] 
  • TI01-discovery/trunk/OAIInfoEditor/oai_info_editor/model/providerinfocollection.py

    r5242 r5466  
    182182        ''' 
    183183        Return provider info records valid to the input user 
     184        NB, owing to the new security system, which cannot provide user info, 
     185        the behaviour here is changed; now return everything and restrict access 
     186        only when the user tries to access a particular resource 
     187         
    184188        @param user: a User object with user details 
    185189        @return list of ProviderInfo objects which the user can update 
    186190        ''' 
    187191        logging.debug("Retrieving provider info for user, '%s'" %user.userID) 
    188  
    189         pis = [] 
    190         if user.isAdmin: 
    191             logging.debug(" - user has admin rights - returning all data") 
    192             return self.providerInfos 
    193          
    194         for pi in self.providerInfos: 
    195             if pi.name in user.providerNames: 
    196                 logging.debug("- adding appropriate info") 
    197                 pis.append(pi) 
    198  
    199         if not pis: 
    200             logging.debug("- no valid provider data found for user") 
    201          
    202         return pis 
     192        logging.debug(" - with new security system need to return everything.") 
     193        return self.providerInfos 
    203194 
    204195 
  • TI01-discovery/trunk/OAIInfoEditor/oai_info_editor/model/user.py

    r5226 r5466  
    11''' 
    2  Class representing an editor user - allowing basic authentication and authorisation 
     2 Class representing an editor user - holding simple info for A&A 
    33   
    44 @author: C Byrom, Tessella Apr 2009 
     
    88from oai_info_editor.lib.constants import * 
    99 
    10 ADMIN_USER_NAME = 'admin' 
    11  
    1210class User(object): 
    1311     
    14     def __init__(self, userID, providerNames): 
     12    def __init__(self, userID, isAdmin): 
    1513        ''' 
    1614        Initialise a User object 
    1715        @param userID: the ID of the user 
    18         @param providerNames: names of the providers that the user may edit 
     16        @param isAdmin: if True, the user has admin rights; False otherwise 
    1917        ''' 
    2018        logging.debug('Setting up User object for ID, %s' %userID) 
    2119        self.userID = userID 
    22         self.providerNames = providerNames 
    23         self.isAdmin = False 
    24         if ADMIN_USER_NAME in self.providerNames: 
    25             self.isAdmin = True 
     20        self.isAdmin = isAdmin 
    2621        logging.debug("User set up") 
    2722 
  • TI01-discovery/trunk/OAIInfoEditor/oai_info_editor/templates/error.html

    r5245 r5466  
    66        <xi:include href="utils.html" /> 
    77        <head> 
    8         <title py:content="c.title">title</title> 
    98    </head> 
    109  <body> 
    11       <panelTab>Details</panelTab> 
    1210        <div id="contents"> 
    1311            <div class="metadata"> 
  • TI01-discovery/trunk/OAIInfoEditor/oai_info_editor/templates/home.html

    r5253 r5466  
    99import oai_info_editor.lib.constants as constants 
    1010import urllib 
     11from oai_info_editor.controllers.master import ADMIN_PARAMETER 
    1112        ?> 
    1213            <script py:if="c.popupMessage" type="text/javascript"> 
     
    3132                              <tr> 
    3233                                <td py:if="c.user.isAdmin"> 
    33                                         <a href="${h.url_for('viewProviderInfo', providerName = constants.ALL_PROVIDER_IDS)}">All data</a> 
     34                                        <a href="${h.url_for('viewProviderInfo', providerName = constants.ALL_PROVIDER_IDS) + ADMIN_PARAMETER}">All data</a> 
    3435                                </td> 
    3536                              </tr> 
    3637                              <tr py:for="pi in c.providerInfos"> 
     38                                <?python 
     39                                        viewLink = h.url_for('viewProviderInfo', providerName = urllib.quote(pi.name)) 
     40                                        if c.user.isAdmin: 
     41                                                viewLink += ADMIN_PARAMETER 
     42                                        ?> 
    3743                                <td> 
    38                                         <a href="${h.url_for('viewProviderInfo', providerName = urllib.quote(pi.name))}">${Markup(pi.name)}</a> 
     44                                        <a href="$viewLink">${Markup(pi.name)}</a> 
    3945                                </td> 
    4046                              </tr> 
  • TI01-discovery/trunk/OAIInfoEditor/oai_info_editor/templates/layout.html

    r5245 r5466  
    2929 
    3030      <div id="logo"><img src="$g.LeftLogo" alt="$g.LeftAlt" /></div> 
    31  
    3231      <div id="content"> 
    3332                <table class="homeHelpBar"> 
    3433                        <tr><td align="left"> 
    35                             <a py:if="c.title != EDITOR_HOME_TITLE" href="${h.url_for('home')}">Home</a> 
    36                             </td><td align="right"><a py:if="c.title != HELP_PAGE_TITLE" href="${h.url_for('help')}">Help</a> 
     34                            <a py:if="c.title != EDITOR_HOME_TITLE" href="$c.homeLink">Home</a> 
     35                            </td><td align="right"><a py:if="c.title != HELP_PAGE_TITLE" href="$c.helpLink">Help</a> 
    3736                            </td></tr> 
    3837                    </table> 
  • TI01-discovery/trunk/OAIInfoEditor/oai_info_editor/templates/ndgPage.html

    r5226 r5466  
    3131                    </tbody></table> 
    3232                </td> 
    33                 <td align="right"></td> 
     33                <td align="right"> 
     34                        <!--  NB, to view any pages in this app you must have logged in --> 
     35                                <span py:if="c.logoutLink"> 
     36                                        <a href="$c.logoutLink">Logout</a> 
     37                                </span> 
     38                </td> 
    3439            </tr> 
    3540        </tbody></table></center> 
  • TI01-discovery/trunk/OAIInfoEditor/oai_info_editor/templates/oai_info_editor_help.html

    r5255 r5466  
    4141                                <div class="headingblock">                   
    4242                    <p> 
    43                     The home page is available <a href="${h.url_for('home')}"> 
     43                    The home page is available <a href="$c.homeLink"> 
    4444                    here</a>; this provides links to the pages for the different 
    4545                    providers available to the system (as described in the next  
     
    9191                            <dt><b>Provider Email</b></dt><dd> 
    9292                            the email address of the provider - NB, this is primarily used for communicating 
    93                             the results of the ingest process (section <a href="${h.url_for('harvest')}"> 
     93                            the results of the ingest process (section <a href="#harvest"> 
    9494                        Harvesting Data</a>). 
    9595                            </dd> 
  • TI01-discovery/trunk/OAIInfoEditor/oai_info_editor/templates/provider_info.html

    r5251 r5466  
    1010                import oai_info_editor.model.providerinfo as PI 
    1111                import urllib 
     12                from oai_info_editor.controllers.master import ADMIN_PARAMETER 
    1213        ?> 
    1314       <script py:if="c.user.isAdmin" type="text/javascript"> 
     
    3940        <tr> 
    4041                <span py:if="editLink">  
     42                <?python 
     43                        editLink = '%s%s' %(editLink, urllib.quote(record.name)) 
     44                        if c.user.isAdmin: 
     45                                editLink += ADMIN_PARAMETER 
     46                        ?> 
    4147                        <td> 
    42                         <a href="${'%s%s' %(editLink, urllib.quote(record.name))}" onclick="Div_show('loading');">Edit</a> 
     48                        <a href="$editLink" onclick="Div_show('loading');">Edit</a> 
    4349                        </td> 
    4450                        <td py:if="c.user.isAdmin"> 
    45                         <a href="${'%s%s' %(c.deleteLink, urllib.quote(record.name))}" onclick="return confirmProviderInfoDelete();">Delete</a> 
     51                        <a href="${'%s%s%s' %(c.deleteLink, urllib.quote(record.name), ADMIN_PARAMETER)}" onclick="return confirmProviderInfoDelete();">Delete</a> 
    4652                        </td> 
    4753                        <td py:if="not c.user.isAdmin" /> 
Note: See TracChangeset for help on using the changeset viewer.