Merge branch 'fibre' of ssh://git.onelab.eu/git/myslice into fibre
[unfold.git] / auth / manifoldbackend-130314.py
1 import time
2
3 # import ldap for LDAP authentication - Edelberto
4 import ldap
5
6 from django.contrib.auth.models import User
7
8 from manifoldapi.manifoldapi    import ManifoldAPI, ManifoldException, ManifoldResult
9 from manifold.core.query        import Query
10
11 # Name my backend 'ManifoldBackend'
12 class ManifoldBackend:
13
14
15     # Create an authentication method
16     # This is called by the standard Django login procedure
17     def authenticate(self, token=None):
18     
19         # LDAP local/global var
20         checkldap = None
21
22         if not token:
23             return None
24
25         try:
26             #usernameldap is from LDAP user form. If it is filled - See portal/homeview.py too
27             usernameldap = token['usernameldap']
28             username = token['username']
29             password = token['password']
30             request = token['request']
31
32             # if data are not from LDAP form then normal (local) login
33             if not usernameldap:
34                 auth = {'AuthMethod': 'password', 'Username': username, 'AuthString': password}
35                 api = ManifoldAPI(auth)
36                 sessions_result = api.forward(Query.create('local:session').to_dict())
37                 print "result"
38                 sessions = sessions_result.ok_value()
39                 print "ok"
40                 if not sessions:
41                     print "GetSession failed", sessions_result.error()
42                     return
43                 print "first", sessions
44                 session = sessions[0]
45
46                 # Change to session authentication
47                 api.auth = {'AuthMethod': 'session', 'session': session['session']}
48                 self.api = api
49
50                 # Get account details
51                 # the new API would expect Get('local:user') instead
52                 persons_result = api.forward(Query.get('local:user').to_dict())
53                 persons = persons_result.ok_value()
54                 if not persons:
55                     print "GetPersons failed",persons_result.error()
56                     return
57                 person = persons[0]
58                 print "PERSON=", person
59
60                 request.session['manifold'] = {'auth': api.auth, 'person': person, 'expires': session['expires']}
61             ################################
62             # Edelberto LDAP authentication
63             # if data are from LDAP form, so
64             else:
65             # XXX UGLY
66             # Needing to create an specific entries at settings.py (or myslice.ini) for these vars
67             ##################################################
68             # Edelberto - UFF - esilva@ic.uff.br
69             # v1 - ldap authentication module
70             # Note: focus on LDAP FIBRE-BR for DN
71             #       if uses other DN, configuration are needed
72             ###################################################
73             #Searching an LDAP Directory
74
75                 try:
76                     #uid = "debora@uff.br"
77
78                     # Receiving an email address, how can we split and mount it in DN format?
79                     #mail = "debora@uff.br"
80                     mail = usernameldap
81                     login = mail.split('@')[0]
82                     org = mail.split('@')[1]
83                     o = org.split('.')[0]
84                     dc = org.split('.')[1]
85                     '''
86                     print mail
87                     print login
88                     print org
89                     print o
90                     print dc
91                     '''
92
93                     # DN format to authenticate - IMPORTANT!
94                     #FIBRE-BR format
95                     uid = "uid="+mail+",ou=people,o="+o+",dc="+dc
96                     #uid = "uid=debora@uff.br,ou=people,o=uff,dc=br"
97                     # User password from LDAP form
98                     #userPassword = "fibre"
99                     userPassword = password
100
101                     # testing with:
102                     # wrong password for test
103                     #    userPassword = "fibre2"
104                     
105                     # Parameters to connect on LDAP
106                     ldap.set_option(ldap.OPT_REFERRALS, 0)
107                     # LDAP Server Address
108                     l = ldap.open("127.0.0.1")
109                     # LDAP version
110                     l.protocol_version = ldap.VERSION3
111
112                     #l.simple_bind(uid, userPassword)
113                     # l.bind_s is necessary to do the authentication with a normal LDAP user
114                     l.bind_s(uid, userPassword, ldap.AUTH_SIMPLE)
115                     #print l.bind_s(uid, userPassword, ldap.AUTH_SIMPLE)
116
117                     # DN base - Our root dc (dc=br)
118                     baseDN="dc="+dc
119                     searchScope = ldap.SCOPE_SUBTREE
120                     retrieveAttributes = None
121                     # User only can see its credentials. He search only his attributes
122                     searchFilter = "uid="+mail
123
124                     # Getting all attributes
125                     try:
126                         ldap_result_id = l.search(baseDN, searchScope, searchFilter, retrieveAttributes)
127                         result_set = []
128                         # while exist attributes, save them in a list!
129                         while 1:
130                         #   print l.result(ldap_result_id, 0)
131                             result_type, result_data = l.result(ldap_result_id, 0)
132                             if (result_data == []):
133                             #print ("User %s don't allowed to bind in LDAP", uid)
134                                 break
135                             else:
136                                 ## Appendng to a list
137                                 if result_type == ldap.RES_SEARCH_ENTRY:
138                                     result_set.append(result_data)
139                                     #    print result_set
140                     except ldap.LDAPError, e:
141                         print e
142
143                     # Matching if the user is really who his say
144                     #checkldap = None
145                     if l.compare_s(uid, 'uid', mail):
146                         # DEBUG
147                         checkldap = True
148                         print "match"
149
150                 # Now, based on default Manifold Auth
151                         auth = {'AuthMethod': 'password', 'Username': usernameldap, 'AuthString': password}
152                         api = ManifoldAPI(auth)
153                         sessions_result = api.forward(Query.create('local:session').to_dict())
154                         print "result"
155                         sessions = sessions_result.ok_value()
156                         print "ok"
157                         if not sessions:
158                             print "GetSession failed", sessions_result.error()
159                             return
160                         print "first", sessions
161                         session = sessions[0]
162
163                         # Change to session authentication
164                         api.auth = {'AuthMethod': 'session', 'session': session['session']}
165                         self.api = api
166
167                         # Get account details
168                         # the new API would expect Get('local:user') instead
169                         persons_result = api.forward(Query.get('local:user').to_dict())
170                         persons = persons_result.ok_value()
171                         if not persons:
172                             print "GetPersons failed",persons_result.error()
173                             return
174                         person = persons[0]
175                         print "PERSON=", person
176
177                         request.session['manifold'] = {'auth': api.auth, 'person': person, 'expires': session['expires']}
178
179                     else:
180                         print "no match. User doesnt allowed"
181                         checkldap = False
182
183                 except ldap.LDAPError, e:
184                     print "E: LDAP Search user", e                      
185         # end of LDAP
186        
187         # Follow the same of Manifold 
188         except ManifoldException, e:
189             print "ManifoldBackend.authenticate caught ManifoldException, returning corresponding ManifoldResult"
190             return e.manifold_result
191         except Exception, e:
192             print "E: manifoldbackend", e
193             import traceback
194             traceback.print_exc()
195             return None
196     
197         if not usernameldap:
198             try:
199                 # Check if the user exists in Django's local database
200                user = User.objects.get(username=username)
201             except User.DoesNotExist:
202                 # Create a user in Django's local database
203                 user = User.objects.create_user(username, usernamep, 'passworddoesntmatter')
204                 user.first_name = "DUMMY_FIRST_NAME" #person['first_name']
205                 user.last_name = "DUMMY LAST NAME" # person['last_name']
206                 user.email = person['email']
207             return user
208         else:
209             if checkldap:
210                 try:
211                     # Check if the user exists in Django's local database
212                     user = User.objects.get(username=usernameldap)
213                 except User.DoesNotExist:
214                     # Create a user in Django's local database
215                     user = User.objects.create_user(username, usernameldap, 'passworddoesntmatter')
216                     user.first_name = "DUMMY_FIRST_NAME" #person['first_name']
217                     user.last_name = "DUMMY LAST NAME" # person['last_name']
218                     user.email = person['email']
219                 return user
220
221     # Required for your backend to work properly - unchanged in most scenarios
222     def get_user(self, user_id):
223         try:
224             return User.objects.get(pk=user_id)
225         except User.DoesNotExist:
226             return None
227
228