Changeset 1534

Show
Ignore:
Timestamp:
11/10/06 22:30:32 (2 years ago)
Author:
mgood
Message:

AccountManagerPlugin:

  • add an HttpAuthStore to support logins by checking the password against
    HTTP authentication for a URL (re #173)
  • update the modules to check whether the current password store supports
    writing passwords or deleting accounts
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • accountmanagerplugin/trunk/acct_mgr/admin.py

    r1524 r1534  
    7979    def _do_users(self, req): 
    8080        perm = PermissionSystem(self.env) 
    81         data = {} 
     81        listing_enabled = self.account_manager.supports('get_users') 
     82        create_enabled = self.account_manager.supports('set_password') 
     83        delete_enabled = self.account_manager.supports('delete_user') 
     84 
     85        data = { 
     86            'listing_enabled': listing_enabled, 
     87            'create_enabled': create_enabled, 
     88            'delete_enabled': delete_enabled, 
     89        } 
     90 
    8291        if req.method == 'POST': 
    8392            if req.args.get('add'): 
    84                 try: 
    85                     _create_user(req, self.env, check_permissions=False) 
    86                 except TracError, e: 
    87                     data['registration_error'] = e.message 
     93                if create_enabled: 
     94                    try: 
     95                        _create_user(req, self.env, check_permissions=False) 
     96                    except TracError, e: 
     97                        data['registration_error'] = e.message 
     98                else: 
     99                    data['registration_error'] = 'The password store does ' \ 
     100                                                 'not support creating users' 
    88101            elif req.args.get('remove'): 
    89                 sel = req.args.get('sel') 
    90                 sel = isinstance(sel, list) and sel or [sel] 
    91                 for account in sel: 
    92                     self.account_manager.delete_user(account) 
     102                if delete_enabled: 
     103                    sel = req.args.get('sel') 
     104                    sel = isinstance(sel, list) and sel or [sel] 
     105                    for account in sel: 
     106                        self.account_manager.delete_user(account) 
     107                else: 
     108                    data['deletion_error'] = 'The password store does not ' \ 
     109                                             'support deleting users' 
    93110 
    94         accounts = {} 
    95         for username in self.account_manager.get_users(): 
    96             accounts[username] = {'username': username} 
     111        if listing_enabled: 
     112            accounts = {} 
     113            for username in self.account_manager.get_users(): 
     114                accounts[username] = {'username': username} 
    97115 
    98         for username, name, email in self.env.get_known_users(): 
    99             account = accounts.get(username) 
    100             if account: 
    101                 account['name'] = name 
    102                 account['email'] = email 
     116            for username, name, email in self.env.get_known_users(): 
     117                account = accounts.get(username) 
     118                if account: 
     119                    account['name'] = name 
     120                    account['email'] = email 
    103121 
    104         db = self.env.get_db_cnx() 
    105         cursor = db.cursor() 
    106         cursor.execute("SELECT sid,last_visit FROM session WHERE authenticated=1") 
    107         for username, last_visit in cursor: 
    108             account = accounts.get(username) 
    109             if account and last_visit: 
    110                 account['last_visit'] = format_datetime(last_visit) 
     122            db = self.env.get_db_cnx() 
     123            cursor = db.cursor() 
     124            cursor.execute("SELECT sid,last_visit FROM session WHERE " 
     125                           "authenticated=1") 
     126            for username, last_visit in cursor: 
     127                account = accounts.get(username) 
     128                if account and last_visit: 
     129                    account['last_visit'] = format_datetime(last_visit) 
    111130 
    112         data['accounts'] = sorted(accounts.itervalues(), 
    113                                   key=lambda acct: acct['username']) 
     131            data['accounts'] = sorted(accounts.itervalues(), 
     132                                      key=lambda acct: acct['username']) 
    114133 
    115134        return 'admin_users.html', data 
  • accountmanagerplugin/trunk/acct_mgr/api.py

    r1068 r1534  
    108108            self._notify('deleted', user) 
    109109 
     110    def supports(self, operation): 
     111        return hasattr(self.password_store, operation) 
     112 
    110113    def password_store(self): 
    111114        try: 
  • accountmanagerplugin/trunk/acct_mgr/templates/account.html

    r1508 r1534  
    3838      </form> 
    3939 
    40       <form method="post" action="" 
     40      <form method="post" action="" py:if="account.delete_enabled" 
    4141            onsubmit="return confirm('Are you sure you want to delete your account?');"> 
    4242        <input type="hidden" name="action" value="delete" /> 
  • accountmanagerplugin/trunk/acct_mgr/templates/admin_users.html

    r1524 r1534  
    1313    <h2>Manage User Accounts</h2> 
    1414 
    15     <form id="addaccount" class="addnew" method="post"
     15    <form id="addaccount" class="addnew" method="post" py:if="create_enabled"
    1616      <fieldset> 
    1717        <div class="system-message" 
     
    4141    </form> 
    4242 
    43     <form method="post"> 
     43    <py:choose> 
     44    <div class="system-message" 
     45         py:when="not listing_enabled"> 
     46      <p>This password store does not support listing users</p> 
     47    </div> 
     48    <form method="post" py:otherwise="" py:strip="not delete_enabled"> 
     49      <div class="system-message" 
     50           py:if="deletion_error"><p>${deletion_error}</p></div> 
    4451      <table class="listing" id="accountlist"> 
    4552        <thead> 
    46           <tr><th class="sel">&nbsp;</th><th>Account</th><th>Name</th><th>Email</th><th>Last Login</th></tr> 
     53          <tr> 
     54            <th class="sel" py:if="delete_enabled">&nbsp;</th> 
     55            <th>Account</th><th>Name</th><th>Email</th><th>Last Login</th> 
     56          </tr> 
    4757        </thead> 
    4858        <tbody> 
    4959          <tr py:for="account in accounts"> 
    50             <td><input type="checkbox" name="sel" value="${account.username}" /></td> 
     60            <td py:if="delete_enabled"> 
     61              <input type="checkbox" name="sel" value="${account.username}" /> 
     62            </td> 
    5163            <td>${account.username}</td> 
    5264            <td>${account.name}</td> 
     
    5668        </tbody> 
    5769      </table> 
    58       <div class="buttons"
     70      <div class="buttons" py:if="delete_enabled"
    5971        <input type="submit" name="remove" value="Remove selected accounts" /> 
    6072      </div> 
    6173    </form> 
     74    </py:choose> 
    6275  </body> 
    6376</html> 
  • accountmanagerplugin/trunk/acct_mgr/web_ui.py

    r1508 r1534  
    129129                                'account.') 
    130130 
     131    def __init__(self): 
     132        self._write_check(log=True) 
     133 
     134    def _write_check(self, log=False): 
     135        writable = AccountManager(self.env).supports('set_password') 
     136        if not writable and log: 
     137            self.log.warn('AccountModule is disabled because the password ' 
     138                          'store does not support writing.') 
     139        return writable 
     140 
    131141    #INavigationContributor methods 
    132142    def get_active_navigation_item(self, req): 
     
    134144 
    135145    def get_navigation_items(self, req): 
     146        if not self._write_check(): 
     147            return 
    136148        if req.authname != 'anonymous': 
    137149            yield 'metanav', 'account', Markup('<a href="%s">My Account</a>', 
     
    140152    # IRequestHandler methods 
    141153    def match_request(self, req): 
    142         return req.path_info in ('/account', '/reset_password') 
     154        return (req.path_info in ('/account', '/reset_password') 
     155                and self._write_check(log=True)) 
    143156 
    144157    def process_request(self, req): 
     
    154167            req.redirect(self.env.href.wiki()) 
    155168        action = req.args.get('action') 
     169        delete_enabled = AccountManager(self.env).supports('delete_user') 
     170        data = {'delete_enabled': delete_enabled} 
    156171        if req.method == 'POST': 
    157172            if action == 'change_password': 
    158                 return self._do_change_password(req
     173                data.update(self._do_change_password(req)
    159174            elif action == 'delete': 
    160                 return self._do_delete(req
    161         return {} 
     175                data.update(self._do_delete(req)
     176        return data 
    162177 
    163178    def _do_reset_password(self, req): 
     
    228243    implements(INavigationContributor, IRequestHandler, ITemplateProvider) 
    229244 
     245    def __init__(self): 
     246        self._write_check(log=True) 
     247 
     248    def _write_check(self, log=False): 
     249        writable = AccountManager(self.env).supports('set_password') 
     250        if not writable and log: 
     251            self.log.warn('RegistrationModule is disabled because the password ' 
     252                          'store does not support writing.') 
     253        return writable 
     254 
    230255    #INavigationContributor methods 
    231256 
     
    234259 
    235260    def get_navigation_items(self, req): 
     261        if not self._write_check(): 
     262            return 
    236263        if req.authname == 'anonymous': 
    237264            yield 'metanav', 'register', Markup('<a href="%s">Register</a>', 
     
    241268 
    242269    def match_request(self, req): 
    243         return req.path_info == '/register' 
     270        return req.path_info == '/register' and self._write_check(log=True) 
    244271 
    245272    def process_request(self, req): 
  • accountmanagerplugin/trunk/setup.py

    r1503 r1534  
    2929            'acct_mgr.web_ui = acct_mgr.web_ui', 
    3030            'acct_mgr.htfile = acct_mgr.htfile', 
     31            'acct_mgr.http = acct_mgr.http', 
    3132            'acct_mgr.api = acct_mgr.api', 
    3233            'acct_mgr.admin = acct_mgr.admin',