root/accountmanagerplugin/0.10/acct_mgr/api.py

Revision 3729, 5.2 kB (checked in by pacopablo, 6 months ago)

Forgot call to commit(). Really fixes #1113

Line 
1 # -*- coding: utf-8 -*-
2 #
3 # Copyright (C) 2005 Matthew Good <trac@matt-good.net>
4 #
5 # "THE BEER-WARE LICENSE" (Revision 42):
6 # <trac@matt-good.net> wrote this file.  As long as you retain this notice you
7 # can do whatever you want with this stuff. If we meet some day, and you think
8 # this stuff is worth it, you can buy me a beer in return.   Matthew Good
9 #
10 # Author: Matthew Good <trac@matt-good.net>
11
12 from trac.core import *
13 from trac.config import Option, ExtensionOption
14
15 class IPasswordStore(Interface):
16     """An interface for Components that provide a storage method for users and
17     passwords.
18     """
19
20     def config_key(self):
21         """
22         '''Deprecated''': new implementations of this interface are not required
23         to implement this method, since the prefered way to configure the
24         `IPasswordStore` implemenation is by using its class name in
25         the `password_store` option.
26
27         Returns a string used to identify this implementation in the config.
28         This password storage implementation will be used if the value of
29         the config property "account-manager.password_format" matches.
30         """
31
32     def get_users(self):
33         """Returns an iterable of the known usernames
34         """
35
36     def has_user(self, user):
37         """Returns whether the user account exists.
38         """
39
40     def set_password(self, user, password):
41         """Sets the password for the user.  This should create the user account
42         if it doesn't already exist.
43         Returns True if a new account was created, False if an existing account
44         was updated.
45         """
46
47     def check_password(self, user, password):
48         """Checks if the password is valid for the user.
49         """
50
51     def delete_user(self, user):
52         """Deletes the user account.
53         Returns True if the account existed and was deleted, False otherwise.
54         """
55
56 class IAccountChangeListener(Interface):
57     """An interface for receiving account change events.
58     """
59
60     def user_created(self, user, password):
61         """New user
62         """
63
64     def user_password_changed(self, user, password):
65         """Password changed
66         """
67
68     def user_deleted(self, user):
69         """User deleted
70         """
71
72 class AccountManager(Component):
73     """The AccountManager component handles all user account management methods
74     provided by the IPasswordStore interface.
75
76     The methods will be handled by the underlying password storage
77     implementation set in trac.ini with the "account-manager.password_format"
78     setting.
79     """
80
81     implements(IAccountChangeListener)
82
83     _password_store = ExtensionOption('account-manager', 'password_store',
84                                       IPasswordStore)
85     _password_format = Option('account-manager', 'password_format')
86     stores = ExtensionPoint(IPasswordStore)
87     change_listeners = ExtensionPoint(IAccountChangeListener)
88
89     # Public API
90
91     def get_users(self):
92         return self.password_store.get_users()
93
94     def has_user(self, user):
95         return self.password_store.has_user(user)
96
97     def set_password(self, user, password):
98         if self.password_store.set_password(user, password):
99             self._notify('created', user, password)
100         else:
101             self._notify('password_changed', user, password)
102
103     def check_password(self, user, password):
104         return self.password_store.check_password(user, password)
105
106     def delete_user(self, user):
107         db = self.env.get_db_cnx()
108         cursor = db.cursor()
109         # Delete session attributes
110         cursor.execute("DELETE FROM session_attribute where sid=%s", (user,))
111         # Delete session
112         cursor.execute("DELETE FROM session where sid=%s", (user,))
113         # Delete any custom permissions set for the user
114         cursor.execute("DELETE FROM permission where username=%s", (user,))
115         db.commit()
116         db.close()
117         # Delete from password store
118         if self.password_store.delete_user(user):
119             self._notify('deleted', user)
120
121     def supports(self, operation):
122         try:
123             store = self.password_store
124         except AttributeError:
125             return False
126         else:
127             return hasattr(store, operation)
128
129     def password_store(self):
130         try:
131             return self._password_store
132         except AttributeError:
133             # fall back on old "password_format" option
134             fmt = self._password_format
135             for store in self.stores:
136                 config_key = getattr(store, 'config_key', None)
137                 if config_key is None:
138                     continue
139                 if config_key() == fmt:
140                     return store
141             # if the "password_format" is not set re-raise the AttributeError
142             raise
143     password_store = property(password_store)
144
145     def _notify(self, func, *args):
146         func = 'user_' + func
147         for l in self.change_listeners:
148             getattr(l, func)(*args)
149
150     # IAccountChangeListener methods
151
152     def user_created(self, user, password):
153         self.log.info('Created new user: %s' % user)
154
155     def user_password_changed(self, user, password):
156         self.log.info('Updated password for user: %s' % user)
157
158     def user_deleted(self, user):
159         self.log.info('Deleted user: %s' % user)
Note: See TracBrowser for help on using the browser.