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