IdentityManagement: sosmbprovider.2.py

File sosmbprovider.2.py, 5.9 kB (added by Joel Pearson, 2 years ago)

Removed extraneous comments - please ignore previous version

Line 
1 # sosmbprovider.py
2 """
3 NOTE: This is intended as "example code", not as a finished product!
4 Use at your own risk. (etc.)
5
6 Written by Joel Pearson for the TurboGears project.
7
8 This is a TurboGears Identity provider where passwords are checked against
9 a Windows/Samba domain. It is a subclass of SqlObjectIdentityProvider,
10 which provides all functionality except password checking, including
11 the models for users and groups.
12
13 Requires Python Win32 extensions, so it only works on Windows servers.
14
15 To use:
16
17 1) Install the Win32 extensions.
18
19 2) Follow all instructions provided for setting up and using the SqlObjectProvider,
20 including creating the tables and adding users and groups. Try logging in.
21 MAKE SURE THIS WORKS BEFORE PROCEEDING!
22
23 3) Save this file into the identity folder under your TurboGears installation
24 as "sosmbprovider.py".
25
26 4) Edit the entry_points.txt file of your TurboGears installation (such as
27 C:\Python24\Lib\site-packages\TurboGears-0.9a6-py2.4.egg\EGG-INFO\entry_points.txt)
28 and add the following line under the [turbogears.identity.provider] section:
29
30 sosmbprovider = turbogears.identity.sosmbprovider:SoSmbIdentityProvider
31
32 5) Add the following lines under the [global] section in a config file (such as app.cfg):
33
34 identity.provider='sosmbprovider'
35 identity.sosmbprovider.smb_domain="PUT_YOUR_DOMAIN_HERE"
36
37 6) Restart TurboGears, and try to log in. Identity should authenticate logins
38 using the usernames and passwords of the domain you specified in step 4.
39
40 IMPORTANT: You still have to create a user record in the database for each
41 domain user that you want to have log in. The only difference between this
42 provider and the standard sqlobject provider is that sosmbprovider ignores
43 the password field in the user model, and validates the user-supplied password
44 against the domain password, instead.
45
46 """
47
48 from soprovider import *
49
50 from win32security import LogonUser, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT
51 from win32security import error as LogonError
52    
53 # Global class references -- these will be set when the Provider is initialised.
54 user_class= None
55 group_class= None
56 permission_class= None
57 visit_class = None
58 smb_domain = None
59
60 class SoSmbIdentityProvider(SqlObjectIdentityProvider):
61     '''
62     IdentityProvider that uses a model from a database (via SQLObject).
63     '''
64    
65     def __init__(self):
66         super(SoSmbIdentityProvider, self).__init__()
67         get = turbogears.config.get
68         global user_class, group_class, permission_class, visit_class
69         global smb_domain
70
71         user_class_path= get( "identity.soprovider.model.user",
72                               __name__ + ".TG_User" )
73         #log.debug('userclassp:%s'% user_class_path)
74         #user_class_path = 'kronos.model.Person'
75         user_class= load_class(user_class_path)
76         if user_class:
77             log.info("Succesfully loaded \"%s\"" % user_class_path)
78         try:
79             self.user_class_db_encoding= \
80                 user_class.sqlmeta.columns['user_name'].dbEncoding
81         except (KeyError, AttributeError):
82             self.user_class_db_encoding= 'UTF-8'
83         group_class_path= get( "identity.soprovider.model.group",
84                                 __name__ + ".TG_Group" )
85         group_class= load_class(group_class_path)
86         if group_class:
87             log.info("Succesfully loaded \"%s\"" % group_class_path)
88            
89         permission_class_path= get( "identity.soprovider.model.permission",
90                                     __name__ + ".TG_Permission" )
91         permission_class= load_class(permission_class_path)
92         if permission_class:
93             log.info("Succesfully loaded \"%s\"" % permission_class_path)
94        
95         visit_class_path= get( "visit.soprovider.model",
96                                 __name__ + ".TG_VisitIdentity" )
97         visit_class= load_class(visit_class_path)
98         if visit_class:
99             log.info("Succesfully loaded \"%s\"" % visit_class_path)
100        
101         smb_domain = get("identity.sosmbprovider.smb_domain", None)
102            
103     def validate_identity( self, user_name, password, visit_key ):
104         '''
105         Look up the identity represented by user_name and determine whether the
106         password is correct.
107         
108         Must return either None if the credentials weren't valid or an object
109         with the following properties:
110             user_name: original user name
111             user: a provider dependant object (TG_User or similar)
112             groups: a set of group IDs
113             permissions: a set of permission IDs
114         '''
115         try:
116             user_name= to_db_encoding( user_name, self.user_class_db_encoding )
117             user= user_class.by_user_name( user_name )
118
119             if not self.validate_password(user_name, password):
120                 log.info( "Passwords don't match for user: %s", user_name )
121                 return None
122            
123             # Link the user to the visit
124             try:
125                 link= visit_class.by_visit_key( visit_key )
126                 link.user_id= user.id
127             except SQLObjectNotFound:
128                 link= visit_class( visit_key=visit_key, user_id=user.id )
129             return SqlObjectIdentity( visit_key, user )
130            
131         except SQLObjectNotFound:
132             log.warning( "No such user: %s", user_name )
133             return None
134
135
136     def validate_password(self, user_name, password):
137         '''
138         Validates user_name and password against a Windows/Samba domain
139         specified in the identity.sosmbprovider.smb_domain config parameter.
140         It's just a wrapper for win32security.LogonUser().
141         '''
142         global smb_domain
143         try:
144             token = LogonUser(user_name,
145                               smb_domain,
146                               password,
147                               LOGON32_LOGON_NETWORK,
148                               LOGON32_PROVIDER_DEFAULT)
149         except LogonError, e:
150             #print e
151             return False
152         else:
153             return bool(token)   # usually True