Merge branch 'fibre' of ssh://git.onelab.eu/git/myslice into fibre
[unfold.git] / portal / homeview.py
1 # this somehow is not used anymore - should it not be ?
2 from django.core.context_processors import csrf
3 from django.http import HttpResponseRedirect
4 from django.contrib.auth import authenticate, login, logout, get_user_model
5 from django.template import RequestContext
6 from django.shortcuts import render_to_response
7 from django.shortcuts import render
8
9 import json
10
11 from unfold.loginrequired import FreeAccessView
12
13 from manifold.core.query                import Query
14 #from manifoldapi.manifoldapi            import execute_query
15 # LDAP query admin // If transfer this code to actions.py maybe don't need more execute_admin_query
16 from manifoldapi.manifoldapi            import execute_query, execute_admin_query
17 # Edelberto - LDAP XXX
18 from portal.models              import PendingUser
19 from django.contrib.auth.models import User   #Pedro
20 from portal.actions             import create_pending_user, create_user, create_user_in_ldap, clear_user_creds
21 from registrationview           import RegistrationView
22 from random     import randint
23 from hashlib    import md5
24 from django.contrib.sites.models import Site
25 import os.path, re
26 ##################
27
28
29 from manifoldapi.manifoldresult import ManifoldResult
30 from ui.topmenu import topmenu_items, the_user
31 from myslice.configengine import ConfigEngine
32
33 from myslice.theme import ThemeView
34
35 # Edelberto LDAP authentication XXX
36 import ldap
37
38 #import activity.user
39
40 class HomeView (FreeAccessView, ThemeView):
41     template_name = 'home-view.html'
42         
43     # expose this so we can mention the backend URL on the welcome page
44     def default_env (self):
45         return { 
46                  'MANIFOLD_URL':ConfigEngine().manifold_url(),
47                  }
48
49     def post (self,request):
50         env = self.default_env()
51         env['theme'] = self.theme
52         env['section'] = "Dashboard"
53         
54         username = request.POST.get('username').lower()
55         password = request.POST.get('password')
56        
57         # LDAP form - If FIBRE, then get the possibilite to authenticate using usernameldap
58         #if self.theme == 'fibre':
59         #usernameldap = request.POST.get('usernameldap')
60         #token = {'usernameldap': usernameldap, 'username': username ,'password': password, 'request': request}    
61
62         ##################################################
63         ########## XXX  Edelberto 010914 XXX
64         #################################################
65         ## first you must open a connection to the server
66         try:
67                 # Connect to UFRJ
68                 l = ldap.initialize("ldap://200.130.15.186:389")
69                 # Bind/authenticate with a root user to search all objects
70                 l.simple_bind_s("cn=Manager,dc=br,dc=fibre","fibre2013")
71                 
72                 l.protocol_version = ldap.VERSION3
73         except ldap.LDAPError, e:
74                 print e
75
76         ## Base directory
77         baseDN = "dc=fibre"
78         searchScope = ldap.SCOPE_SUBTREE
79         ## retrieve all attributes
80         retrieveAttributes = None
81         #retrieveAttributes = ['userEnable']
82         searchFilter = "uid=" + username
83         print searchFilter
84
85         in_ldap = 0
86
87         try:
88             if username != "admin":
89                 ldap_result_id = l.search(baseDN, searchScope, searchFilter, retrieveAttributes)
90                 result_set = []
91                 result_type, result_data = l.result(ldap_result_id, 0)
92                 if (result_data == []):
93                         print "User doesnt exist in LDAP"
94                         in_ldap = 0
95                 else:
96                         if result_type == ldap.RES_SEARCH_ENTRY:
97                                 result_set.append(result_data)
98                         else:
99                                 result_set.append(result_data)
100                         # TRUE or FALSE for userEnable attribute
101                         userEnable = result_set[0][0][1]['userEnable'][0]
102                         if userEnable == 'TRUE':
103                                 in_ldap = 1
104                                 enabled = 1
105                                 print "In LDAP and Enabled"
106
107                                 dn = result_set[0][0][0]
108                                 try:
109                                         l.simple_bind_s(dn,password)
110                                         pwd = 1
111                                         print "User password OK"
112
113                                 except:
114                                         pwd = 0
115                                         print "User password WRONG"
116
117                                 if in_ldap and enabled and pwd:
118                                         ldap_mail = result_set[0][0][1]['mail'][0]
119
120                                         user_exists =  Query().get('local:user')             \
121                                                 .select('status') \
122                                                 .filter_by('email', '==', username)
123                                         results = execute_admin_query(request, user_exists)
124                                         print "DEBUG: %s" % user_exists
125                                         if results:
126                                                 print "DEBUG: user exists on MySlice DBs"
127                                         else:
128                                                 print "DEBUG: user NOT exists on MySlice DBs"
129                                                 
130                                                 cn              = result_set[0][0][1]['cn'][0] 
131                                                 sn              =  result_set[0][0][1]['sn'][0]
132
133                                                 fname=None
134                                                 lname=None
135
136                                                 try:
137                                                     fname =  sn.split(' ')[0]
138                                                     lname =  sn.split(' ')[1]
139                                                 except:
140                                                     fname = sn
141                                                     lname = ""
142
143                                                 #authority_hrn  =  'fibre' + '.' + username.split('@')[1] 
144                                                 authority_hrn   =  'fibre'
145                                                 print authority_hrn
146                                                 email           = ldap_mail
147                                                 print ldap_mail
148                                                 username        = username
149                                                 print username
150                                                 password        = password
151                                                 print password
152                                                 # user_hrn      = 'fibre' + '.' + username.split('@')[1] + '.' + username
153                                                 user_hrn        = 'fibre' + '.' + username
154                                                 print user_hrn
155
156                                                 # Based on registrationview
157
158
159                                                 # get the domain url
160                                                 current_site = Site.objects.get_current()
161                                                 current_site = current_site.domain
162                                                 print current_site
163
164                                                 post_email = ldap_mail
165                                                 salt = randint(1,100000)
166                                                 email_hash = md5(str(salt)+post_email).hexdigest()
167                                                 print email_hash
168
169                                                 user_request = {
170                                                 'first_name'    : fname,
171                                                 'last_name'     : lname,
172                                                 'organization'  : authority_hrn,
173                                                 'authority_hrn' : authority_hrn,
174                                                 'email'         : ldap_mail,
175                                                 'username'      : username,
176                                                 'password'      : password,
177                                                 'current_site'  : current_site,
178                                                 'email_hash'    : email_hash,
179                                                 'pi'            : '',
180                                                 'user_hrn'      : user_hrn,
181                                                 'reasons'       : 'already exists in the LDAP',
182                                                 'type'          : 'user',
183                                                 'validation_link': 'https://' + current_site + '/portal/email_activation/'+ email_hash
184                                                 }
185
186                                                 # Validate input
187                                                 errors = []
188                                                 UserModel = get_user_model()
189                                                 if (re.search(r'^[\w+\s.@+-]+$', user_request['first_name']) == None):
190                                                         errors.append('First name may contain only letters, numbers, spaces and @/./+/-/_ characters.')
191                                                 if (re.search(r'^[\w+\s.@+-]+$', user_request['last_name']) == None):
192                                                         errors.append('Last name may contain only letters, numbers, spaces and @/./+/-/_ characters.')
193                                                 if (re.search(r'^[\w,]+$' , username) == None):
194                                                         errors.append('Username may contain only letters,numbers and -/_ characters.')
195                                                 # checking in django_db !!
196                                                 if PendingUser.objects.filter(email__iexact = user_request['email']):
197                                                         errors.append('Email is pending for validation. Please provide a new email address.')
198                                                 if User.objects.filter(username__iexact = user_request['username']):
199                                                         errors.append('This username is already in use, try another one')
200                                                 # Does the user exist in Manifold?
201                                                 user_query  = Query().get('local:user').select('user_id','email')
202                                                 user_details = execute_admin_query(request, user_query)
203                                                 for user_detail in user_details:
204                                                         if user_detail['email'] == user_request['email']:
205                                                                 errors.append('Email already registered in Manifold. Please provide a new email address.')
206                                                 # Does the user exist in sfa? [query is very slow!!]
207                                                 #user_query  = Query().get('user').select('user_hrn','user_email')
208                                                 # XXX Test based on the user_hrn is quick
209                                                 #user_query  = Query().get('user').select('user_hrn','user_email').filter_by('user_hrn','==',user_request['user_hrn'])
210                                                 user_query  = Query().get('user').select('user_hrn','user_email').filter_by('user_hrn','==',user_hrn)
211                                                 user_details_sfa = execute_admin_query(request, user_query)
212
213                                                 #if 'generate' in wsgi_request.POST['question']:
214                                                 user_request['auth_type'] = 'managed'
215
216                                                 # XXX Common code, dependency ?
217                                                 from Crypto.PublicKey import RSA
218                                                 private = RSA.generate(1024)
219
220                                                 # Example: private_key = '-----BEGIN RSA PRIVATE KEY-----\nMIIC...'
221                                                 # Example: public_key = 'ssh-rsa AAAAB3...'
222                                                 user_request['private_key'] = private.exportKey()
223                                                 user_request['public_key']  = private.publickey().exportKey(format='OpenSSH')
224
225                                                 # XXX Verify if errors exist - After!
226                                                 #if not errors:
227                                                 create_user_in_ldap(request, user_request, user_detail)
228                                                 #create_pending_user(request, user_request, user_detail)
229
230                                                 #create_user(request, user_request)
231                                                             
232                                                 env['state'] = "LDAP associated. Please, login again."
233                                                 return render_to_response(self.template, env, context_instance=RequestContext(request))
234                                                         
235
236                                 else:
237                                         env['state'] = "Access denied. Verify LDAP userEnable and password."
238                                         return render_to_response(self.template, env, context_instance=RequestContext(request))
239
240                         else:
241                                 in_ldap = 1
242                                 enabled = 0
243                                 print "In LDAP but Disabled"
244                                 env['state'] = "Access denied. Verify LDAP userEnable."
245                                 return render_to_response(self.template, env, context_instance=RequestContext(request))
246
247         #print result_set
248         except ldap.LDAPError, e:
249                 print e 
250
251         #else:
252         if in_ldap and enabled and pwd or username=="admin":
253
254 ################################################################################
255 ### XXX Edelberto LDAP auth end XXX
256 ###############################################################################        
257                 # Follow original code
258                 ## pass request within the token, so manifold session key can be attached to the request session.
259                 token = {'username': username, 'password': password, 'request': request}    
260
261                 # our authenticate function returns either
262                 # . a ManifoldResult - when something has gone wrong, like e.g. backend is unreachable
263                 # . a django User in case of success
264                 # . or None if the backend could be reached but the authentication failed
265                 auth_result = authenticate(token=token)
266                 # use one or two columns for the layout - not logged in users will see the login prompt
267                 # high-level errors, like connection refused or the like
268                 if isinstance (auth_result, ManifoldResult):
269                     manifoldresult = auth_result
270                     # let's use ManifoldResult.__repr__
271                     env['state']="%s"%manifoldresult
272                     
273                     return render_to_response(self.template,env, context_instance=RequestContext(request))
274                 # user was authenticated at the backend
275                 elif auth_result is not None:
276                     user=auth_result
277                     if user.is_active:
278                         print "LOGGING IN"
279                         login(request, user)
280                         
281                         if request.user.is_authenticated(): 
282                             env['person'] = self.request.user
283                             env['username'] = self.request.user
284                             
285                             ## check user is pi or not
286                             platform_query  = Query().get('local:platform').select('platform_id','platform','gateway_type','disabled')
287                             account_query  = Query().get('local:account').select('user_id','platform_id','auth_type','config')
288
289                             # Edleberto
290                             #cc_auth_cred = {}          
291
292                             platform_details = execute_query(self.request, platform_query)
293                             account_details = execute_query(self.request, account_query)
294                             for platform_detail in platform_details:
295                                 for account_detail in account_details:
296                                     if platform_detail['platform_id'] == account_detail['platform_id']:
297                                         if 'config' in account_detail and account_detail['config'] is not '':
298                                             account_config = json.loads(account_detail['config'])
299                                             if 'myslice' in platform_detail['platform']:
300                                                 acc_auth_cred = account_config.get('delegated_authority_credentials','N/A')
301                             # assigning values
302                             if acc_auth_cred=={} or acc_auth_cred=='N/A':
303                                 pi = "is_not_pi"
304                             else:
305                                 pi = "is_pi"
306                             env['pi'] = pi                
307                         else: 
308                             env['person'] = None
309                         return render_to_response(self.template,env, context_instance=RequestContext(request))
310                     else:
311                         env['state'] = "Your account is not active, please contact the site admin."
312                         env['layout_1_or_2']="layout-unfold2.html"
313                         
314                         return render_to_response(self.template,env, context_instance=RequestContext(request))
315                 # otherwise
316         else:
317             # log user activity
318             #activity.user.login(self.request, "error")
319
320             env['state'] = "Your username and/or password were incorrect."
321
322             return render_to_response(self.template, env, context_instance=RequestContext(request))
323
324     def get (self, request, state=None):
325         env = self.default_env()
326         acc_auth_cred={}
327         if request.user.is_authenticated():
328            
329             ## check user is pi or not
330             platform_details = {}
331             account_details = {}
332             acc_auth_cred = {}
333             acc_user_cred = {}
334             platform_query  = Query().get('local:platform').select('platform_id','platform','gateway_type','disabled')
335             account_query  = Query().get('local:account').select('user_id','platform_id','auth_type','config')
336             # XXX Something like an invalid session seems to make the execute fail sometimes, and thus gives an error on the main page
337             platform_details = execute_query(self.request, platform_query)
338             account_details = execute_query(self.request, account_query)
339             if platform_details is not None and platform_details != {}:
340                 for platform_detail in platform_details:
341                     for account_detail in account_details:
342                         if 'platform_id' in platform_detail:
343                             if platform_detail['platform_id'] == account_detail['platform_id']:
344                                 if 'config' in account_detail and account_detail['config'] is not '':
345                                     account_config = json.loads(account_detail['config'])
346                                     if 'myslice' in platform_detail['platform']:
347                                         acc_auth_cred = account_config.get('delegated_authority_credentials','N/A')
348                                         acc_user_cred = account_config.get('delegated_user_credential','N/A')
349             # assigning values
350             if acc_auth_cred=={} or acc_auth_cred=='N/A':
351                 pi = "is_not_pi"
352             else:
353                 pi = "is_pi"
354
355             # check if the user has creds or not
356             if acc_user_cred == {} or acc_user_cred == 'N/A':
357                 user_cred = 'no_creds'
358             else:
359                 user_cred = 'has_creds'
360            
361
362             env['pi'] = pi
363             env['user_cred'] = user_cred                
364             env['person'] = self.request.user
365         else: 
366             env['person'] = None
367
368         env['theme'] = self.theme
369         env['section'] = "Dashboard"
370
371
372         env['username']=the_user(request)
373         env['topmenu_items'] = topmenu_items(None, request)
374         if state: env['state'] = state
375         elif not env['username']: env['state'] = None
376         # use one or two columns for the layout - not logged in users will see the login prompt
377         
378 #         account_query  = Query().get('local:account').select('user_id','platform_id','auth_type','config')
379 #         account_details = execute_query(self.request, account_query)
380 #         for account_detail in account_details:
381 #             account_config = json.loads(account_detail['config'])
382 #             platform_name = platform_detail['platform']
383 #             if 'myslice' in platform_detail['platform']:
384 #                 acc_user_cred = account_config.get('delegated_user_credential','N/A')
385 #                 acc_slice_cred = account_config.get('delegated_slice_credentials','N/A')
386 #                 acc_auth_cred = account_config.get('delegated_authority_credentials','N/A')
387
388 #                 if 'N/A' not in acc_user_cred:
389 #                     exp_date = re.search('<expires>(.*)</expires>', acc_user_cred)
390 #                     if exp_date:
391 #                         user_exp_date = exp_date.group(1)
392 #                         user_cred_exp_list.append(user_exp_date)
393
394 #                     my_users = [{'cred_exp': t[0]}
395 #                         for t in zip(user_cred_exp_list)]
396 #                
397
398 #                 if 'N/A' not in acc_slice_cred:
399 #                     for key, value in acc_slice_cred.iteritems():
400 #                         slice_list.append(key)
401 #                         # get cred_exp date
402 #                         exp_date = re.search('<expires>(.*)</expires>', value)
403 #                         if exp_date:
404 #                             exp_date = exp_date.group(1)
405 #                             slice_cred_exp_list.append(exp_date)
406
407 #                     my_slices = [{'slice_name': t[0], 'cred_exp': t[1]}
408 #                         for t in zip(slice_list, slice_cred_exp_list)]
409
410 #                 if 'N/A' not in acc_auth_cred:
411 #                     for key, value in acc_auth_cred.iteritems():
412 #                         auth_list.append(key)
413 #                         #get cred_exp date
414 #                         exp_date = re.search('<expires>(.*)</expires>', value)
415 #                         if exp_date:
416 #                             exp_date = exp_date.group(1)
417 #                             auth_cred_exp_list.append(exp_date)
418
419         
420         return render_to_response(self.template, env, context_instance=RequestContext(request))
421