Trying to solve the pb when session expires
[myslice.git] / portal / actions.py
1 from django.http                    import HttpResponse
2 from manifold.core.query            import Query
3 from manifoldapi.manifoldapi        import execute_query,execute_admin_query
4 from portal.models                  import PendingUser, PendingSlice, PendingAuthority, PendingProject, PendingJoin
5 from unfold.page                    import Page
6
7 import json
8
9 from django.contrib.auth.models     import User
10 from django.contrib.sites.models    import Site
11 from django.contrib.auth            import get_user_model
12 from django.template.loader         import render_to_string
13 from django.core.mail               import EmailMultiAlternatives, send_mail
14
15 from myslice.theme                  import ThemeView
16 from myslice.configengine           import ConfigEngine
17 from myslice.settings               import logger
18
19 theme = ThemeView()
20
21 import activity.slice
22
23 # Thierry: moving this right into the code so 
24 # most people can use myslice without having to install sfa
25 # XXX tmp sfa dependency, should be moved to SFA gateway
26 #from sfa.util.xrn                import Xrn 
27
28 def get_myslice_platform(request):
29     platform_query  = Query().get('local:platform').select('platform_id','platform','gateway_type','disabled','config').filter_by('platform','==','myslice')
30     platform_details = execute_query(request, platform_query)
31     if isinstance(platform_details,list):
32         for platform_detail in platform_details:
33             return platform_detail
34     else:
35         return None
36
37 def get_myslice_account(request):
38     try:
39         platform_myslice = get_myslice_platform(request)
40         account_query  = Query().get('local:account').select('user_id','platform_id','auth_type','config').filter_by('platform_id','==',platform_myslice['platform_id'])
41         account_details = execute_query(request, account_query)
42         if isinstance(account_details,list):
43             for account_detail in account_details:
44                 return account_detail
45         else:
46             return None
47     except Exception as e:
48         print e
49         return None
50
51 def get_registry_url(request):
52     try:
53         platform_detail = get_myslice_platform(request)
54         platform_config = json.loads(platform_detail['config'])
55         import socket
56         hostname = socket.gethostbyaddr(socket.gethostname())[0]
57         registry = platform_config.get('registry','N/A')
58         if 'localhost' in registry:
59             port = registry.split(':')[-1:][0]
60             registry = "http://" + hostname +':'+ port
61         return registry
62     except Exception as e:
63         print e
64         return None
65
66 def get_jfed_identity(request):
67     try:
68         account_detail = get_myslice_account(request)
69         account_config = json.loads(account_detail['config'])
70         if 'user_private_key' in account_config:
71             private_key = account_config['user_private_key']
72             user_hrn = account_config.get('user_hrn','N/A')
73             platform_detail = get_myslice_platform(request)
74             registry = get_registry_url(request)
75             #registry = 'http://sfa-fed4fire.pl.sophia.inria.fr:12345/'
76             jfed_identity = user_hrn + '\n' + registry + '\n' + private_key 
77             return jfed_identity
78         else:
79             return None
80     except Exception as e:
81         print e
82         return None
83
84 # Get the list of pis in a given authority
85 def authority_get_pis(request, authority_hrn):
86     # CACHE PB with fields
87     page = Page(request)
88     metadata = page.get_metadata()
89     auth_md = metadata.details_by_object('authority')
90     auth_fields = [column['name'] for column in auth_md['column']]
91
92     # REGISTRY ONLY TO BE REMOVED WITH MANIFOLD-V2
93     query = Query.get('myslice:authority').filter_by('authority_hrn', '==', authority_hrn).select(auth_fields)
94     results = execute_admin_query(request, query)
95     #print "authority_get_pis = %s" % results
96     # NOTE: temporarily commented. Because results is giving empty list. 
97     # Needs more debugging
98     #if not results:
99     #    raise Exception, "Authority not found: %s" % authority_hrn
100     #result, = results
101     #return result['pi_users']
102     return results
103
104 #check the user is pi or not in the registry
105 def authority_check_pis(request, user_email):
106     try:
107         user_query  = Query().get('local:user').filter_by('email', '==', user_email).select('user_id','email','password','config')
108         user_details = execute_admin_query(request, user_query)
109     
110         # getting the authority_hrn
111         for user_detail in user_details:
112             user_id = user_detail['user_id']
113             if user_detail['config']:
114                 config = json.loads(user_detail['config'])
115                 authority_hrn = config.get('authority','Unknown Authority')
116  
117         account_query  = Query().get('local:account').filter_by('user_id', '==', user_id).select('user_id','platform_id','auth_type','config')
118         account_details = execute_admin_query(request, account_query)
119     
120         platform_query  = Query().get('local:platform').select('platform_id','platform')
121         platform_details = execute_admin_query(request, platform_query)
122     
123         for account_detail in account_details:
124             for platform_detail in platform_details:
125                 if platform_detail['platform_id'] == account_detail['platform_id']:
126                     if 'myslice' in platform_detail['platform']:
127                         account_config = json.loads(account_detail['config'])
128                         user_hrn = account_config.get('user_hrn','N/A')
129
130         pi_status = False
131         pis = authority_get_pis (request, authority_hrn)
132         for pi in pis:
133             pi_list = pi['pi_users']
134
135         if user_hrn in pi_list:
136             pi_status = True
137         return pi_status
138
139     except Exception as e:
140         logger.error("Exception in actions.py in authority_check_pis {}".format(e))
141         return None
142
143
144 def authority_add_pis(request, authority_hrn,user_hrn):
145     try:
146         # getting pis of the authority of the user
147         pis = authority_get_pis (request, authority_hrn)
148         for pi in pis:
149             pi_list = pi['pi_users']
150    
151         updated_pi_list = pi_list.append(user_hrn) 
152         query = Query.update('myslice:authority').filter_by('authority_hrn', '==', authority_hrn).set({'pi_users':pi_list})
153         results = execute_query(request,query)
154         newpis = authority_get_pis (request, authority_hrn)
155         return newpis
156     except Exception as e: 
157         logger.error("Exception in actions.py in authority_add_pis {}".format(e))
158         return None
159
160
161 def authority_remove_pis(request, authority_hrn,user_hrn):
162     try:
163         # getting pis of the authority of the user
164         pis = authority_get_pis (request, authority_hrn)
165         for pi in pis:
166             pi_list = pi['pi_users']
167  
168         updated_pi_list = pi_list.remove(user_hrn) 
169         query = Query.update('authority').filter_by('authority_hrn', '==', authority_hrn).set({'pi_users':pi_list})
170         results = execute_query(request,query)
171         newpis = authority_get_pis (request, authority_hrn)
172         return newpis
173     except Exception as e: 
174         logger.error("Exception in actions.py in authority_remove_pis {}".format(e))
175         return None
176
177
178 def authority_get_pi_emails(request, authority_hrn):
179     pi_users = authority_get_pis(request,authority_hrn)
180     logger.info("pi_users = %s" % pi_users)
181
182     if any(pi['pi_users'] == None or not pi['pi_users']  for pi in pi_users):
183         #theme.template_name = 'email_default_recipients.txt' 
184         #default_email = render_to_string(theme.template, request)
185         #default_email = default_email.replace('\n', '')
186         #return default_email
187         # the above doesn't work
188         return ['support@onelab.eu']
189     else:
190         pi_user_hrns = [ hrn for x in pi_users for hrn in x['pi_users'] ]
191
192         # REGISTRY ONLY TO BE REMOVED WITH MANIFOLD-V2
193         query = Query.get('myslice:user').filter_by('user_hrn', 'included', pi_user_hrns).select('user_email')
194         results = execute_admin_query(request, query)
195         return [result['user_email'] for result in results]
196
197 #clear user credentials
198 def clear_user_creds(request, user_email):
199     try:
200         user_query  = Query().get('local:user').filter_by('email', '==', user_email).select('user_id','email','password','config')
201         user_details = execute_admin_query(request, user_query)
202     
203         # getting the user_id from the session
204         for user_detail in user_details:
205             user_id = user_detail['user_id']
206             user_email = user_detail['email']
207     
208         account_query  = Query().get('local:account').filter_by('user_id', '==', user_id).select('user_id','platform_id','auth_type','config')
209         account_details = execute_admin_query(request, account_query)
210     
211         platform_query  = Query().get('local:platform').select('platform_id','platform')
212         platform_details = execute_admin_query(request, platform_query)
213     
214         for account_detail in account_details:
215             for platform_detail in platform_details:
216                 if platform_detail['platform_id'] == account_detail['platform_id']:
217                     if 'myslice' in platform_detail['platform']:
218                         account_config = json.loads(account_detail['config'])
219                         #user_cred = account_config.get('delegated_user_credential','N/A')
220                         user_cred = account_config.get('user_credential','N/A')
221                         if 'N/A' not in user_cred:
222                             user_hrn = account_config.get('user_hrn','N/A')
223                             user_pub_key = json.dumps(account_config.get('user_public_key','N/A'))
224                             user_priv_key = json.dumps(account_config.get('user_private_key','N/A'))
225                             updated_config = '{"user_public_key":'+ user_pub_key + ', "user_private_key":'+ user_priv_key + ', "user_hrn":"'+ user_hrn + '"}'
226                             user_params = { 'config': updated_config}
227                             manifold_update_account(request, user_id,user_params)
228                             return user_email
229                         else:
230                             return None
231
232     except Exception as e:
233         logger.error("Exception in actions.py in clear_user_creds {}".format(e))
234         return None
235
236 def is_pi(wsgi_request, user_hrn, authority_hrn):
237     # authorities from user where user_hrn == "ple.upmc.jordan_auge"
238     logger.debug("#### actions.py is_pi authority_hrn = {}".format(authority_hrn))
239     try:
240         # CACHE PB with fields
241         page = Page(wsgi_request)
242         metadata = page.get_metadata()
243         user_md = metadata.details_by_object('user')
244         user_fields = [column['name'] for column in user_md['column']]
245         
246         # REGISTRY ONLY TO BE REMOVED WITH MANIFOLD-V2
247         query  = Query().get('myslice:user').select(user_fields).filter_by('user_hrn','==',user_hrn)
248         #query = Query.get('myslice:user').filter_by('user_hrn', '==', user_hrn).select('pi_authorities')
249         results = execute_query(wsgi_request, query)
250         for user_detail in results:
251             if authority_hrn in user_detail['pi_authorities']:
252                 return True
253     except Exception as e:
254         logger.error("Exception in actions.py in is_pi {}".format(e))
255     return False
256     
257 # SFA get record
258
259 def sfa_get_user(request, user_hrn, pub=None):
260
261     # REGISTRY ONLY TO BE REMOVED WITH MANIFOLD-V2
262     query_sfa_user = Query.get('myslice:user').filter_by('user_hrn', '==', user_hrn)
263     result_sfa_user = execute_admin_query(request, query_sfa_user)
264     return result_sfa_user[0]                        
265
266 def sfa_update_user(request, user_hrn, user_params):
267     # user_params: keys [public_key] 
268     if 'email' in user_params:
269         user_params['user_email'] = user_params['email']
270
271     # REGISTRY ONLY TO BE REMOVED WITH MANIFOLD-V2
272     query = Query.update('myslice:user').filter_by('user_hrn', '==', user_hrn).set(user_params).select('user_hrn')
273     results = execute_admin_query(request,query)
274     return results
275
276 def sfa_add_authority(request, authority_params):
277
278     # REGISTRY ONLY TO BE REMOVED WITH MANIFOLD-V2
279     query = Query.create('myslice:authority').set(authority_params).select('authority_hrn')
280     results = execute_query(request, query)
281     logger.info("sfa_add_auth results={}".format(results))
282     if not results:
283         raise Exception, "Could not create %s. Already exists ?" % authority_params['hrn']
284     return results
285
286 def sfa_add_user_to_slice(request, user_hrn, slice_params):
287 # UPDATE myslice:slice SET researcher=['ple.upmc.jordan_auge','ple.inria.thierry_parmentelat','ple.upmc.loic_baron','ple.upmc.ciro_scognamiglio','ple.upmc.mohammed-yasin_rahman','ple.upmc.azerty'] where slice_hrn=='ple.upmc.myslicedemo'
288
289     # REGISTRY ONLY TO BE REMOVED WITH MANIFOLD-V2
290     query_current_users = Query.get('myslice:slice').select('user').filter_by('slice_hrn','==',slice_params['hrn'])
291     results_current_users = execute_query(request, query_current_users)
292     slice_params['researcher'] = slice_params['researcher'] | results_current_users
293
294     # REGISTRY ONLY TO BE REMOVED WITH MANIFOLD-V2
295     query = Query.update('myslice:slice').filter_by('user_hrn', '==', user_hrn).set(slice_params).select('slice_hrn')
296     results = execute_query(request, query)
297 # Also possible but not supported yet
298 # UPDATE myslice:user SET slice=['ple.upmc.agent','ple.upmc.myslicedemo','ple.upmc.tophat'] where user_hrn=='ple.upmc.azerty'
299     if not results:
300         raise Exception, "Could not create %s. Already exists ?" % slice_params['hrn']
301     return results
302
303 # Propose hrn
304
305 def manifold_add_user(wsgi_request, request):
306     """Add a Manifold user corresponding to a user request.
307
308     Args:
309         wsgi_request: a WSGIRequest instance
310         request (dict): a dictionary containing the user request built from the
311             form.
312
313     Returns:
314         The user_id of the inserted user.
315
316     Raises:
317         ?
318     
319     """
320     USER_CONFIG = '{"firstname": "%(first_name)s", "lastname": "%(last_name)s", "authority": "%(authority_hrn)s"}'
321
322     user_params = {
323         'email'     : request['email'],
324         'password'  : request['password'],
325         'config'    : USER_CONFIG % request,
326         'status'    : 1,
327     }
328
329     query = Query.create('local:user').set(user_params).select('email')
330     results = execute_admin_query(request, query)
331     if not results:
332         raise Exception, "Failed creating manifold user: %s" % user_params['email']
333     result = results[0]
334     return result['email']
335
336 def manifold_update_user(request, email, user_params):
337     # user_params: password, config e.g., 
338     query = Query.update('local:user').filter_by('email', '==', email).set(user_params).select('email')
339     results = execute_admin_query(request,query)
340     # NOTE: results remains empty and goes to Exception. However, it updates the manifold DB.
341     # That's why I commented the exception part. -- Yasin 
342     #if not results:
343     #    raise Exception, "Failed updating manifold user: %s" % user_params['email']
344     #result, = results
345     return results
346
347 def manifold_add_account(request, account_params):
348     query = Query.create('local:account').set(account_params).select(['user', 'platform'])
349     results = execute_admin_query(request,query)
350     if not results:
351         raise Exception, "Failed creating manifold account on platform %s for user: %s" % (account_params['platform'], account_params['user'])
352     result, = results
353     return result['user_id']
354
355 def manifold_update_account(request,user_id,account_params):
356     # account_params: config
357     query = Query.update('local:account').filter_by('platform', '==', 'myslice').filter_by('user_id', '==', user_id).set(account_params).select('user_id')
358     results = execute_admin_query(request,query)
359     return results
360
361 #explicitly mention the platform_id
362 def manifold_delete_account(request, user_id, platform_id = None):
363     query = Query.delete('local:account').filter_by('user_id', '==', user_id)
364     if platform_id is not None:
365         query.filter_by('platform_id', '==', platform_id)
366     results = execute_admin_query(request,query)
367     return results
368
369 def manifold_delete_user(request, user_id):
370     query = Query.delete('local:user').filter_by('user_id', '==', user_id).select('user_id')
371     results = execute_admin_query(request,query)
372     return results
373
374
375 #not tested
376 def manifold_add_platform(request, platform_params):
377     query = Query.create('local:platform').set(platform_params).select(['user', 'platform'])
378     results = execute_admin_query(request,query)
379     if not results:
380         raise Exception, "Failed creating manifold platform %s for user: %s" % (platform_params['platform'], platform_params['user'])
381     result, = results
382     return result['platform_id']
383
384 def delete_local_user(wsgi_request, user_email):
385     user_query = Query().get('local:user') \
386         .filter_by('email', '==', user_email)           \
387         .select('user_id','config')
388     user = execute_admin_query(wsgi_request, user_query)
389     if len(user) == 0:
390         return False
391         #raise Exception, "User not found, check local DB"
392     else:
393         user_id = user[0]['user_id']
394         user_config = json.loads(user[0]['config'])
395         authority_hrn = user_config.get('authority', None)
396         
397         if is_pi(wsgi_request, '$user_hrn', authority_hrn):
398             # removing from Django auth_user
399             UserModel = get_user_model()
400             UserModel._default_manager.filter(email__iexact = user_email).delete()
401
402             # removing manifold account
403             manifold_delete_account(wsgi_request, user_id)           
404                      
405             # removing manifold user
406             manifold_delete_user(wsgi_request, user_id)
407         else:
408             return False
409             #raise Exception, "No sufficient rights on authority = ",authority_hrn
410
411     return True      
412
413
414 def make_request_user(user):
415     request = {}
416     request['type']          = 'user'
417     request['id']            = user.id
418     request['timestamp']     = user.created # XXX in DB ?
419     request['authority_hrn'] = user.authority_hrn
420     request['first_name']    = user.first_name
421     request['last_name']     = user.last_name
422     request['email']         = user.email
423     request['login']         = user.login
424     request['user_hrn']      = user.user_hrn
425     request['public_key']    = user.public_key
426     request['private_key']   = user.private_key
427     return request
428
429 def make_request_slice(slice):
430     request = {}
431     request['type'] = 'slice'
432     request['id'] = slice.id
433     request['user_hrn'] = slice.user_hrn
434     request['timestamp'] = slice.created
435     request['authority_hrn'] = slice.authority_hrn
436     request['slice_name'] = slice.slice_name
437     request['number_of_nodes'] = slice.number_of_nodes
438     request['type_of_nodes'] = slice.type_of_nodes
439     request['purpose'] = slice.purpose
440     return request
441
442 def make_request_project(project):
443     request = {}
444     request['type'] = 'project'
445     request['id'] = project.id
446     request['user_hrn'] = project.user_hrn
447     request['email'] = project.email
448     request['timestamp'] = project.created
449     request['authority_hrn'] = project.authority_hrn
450     request['project_name'] = project.project_name
451     request['purpose'] = project.purpose
452     return request
453
454 def make_request_join(join):
455     request = {}
456     request['type'] = 'join'
457     request['id'] = join.id
458     request['user_hrn'] = join.user_hrn
459     request['email'] = join.email
460     request['timestamp'] = join.created
461     request['authority_hrn'] = join.authority_hrn
462     request['project_name'] = join.project_name
463     return request
464
465 def make_request_authority(authority):
466     request = {}
467     request['type']                  = 'authority'
468     request['id']                    = authority.id
469     request['site_name']             = authority.site_name
470     request['site_latitude']         = authority.site_latitude
471     request['site_longitude']        = authority.site_longitude
472     request['site_url']              = authority.site_url
473     request['site_authority']        = authority.site_authority
474     request['site_abbreviated_name'] = authority.site_abbreviated_name
475     request['address_line1']         = authority.address_line1
476     request['address_line2']         = authority.address_line2
477     request['address_line3']         = authority.address_line3
478     request['address_city']          = authority.address_city
479     request['address_postalcode']    = authority.address_postalcode
480     request['address_state']         = authority.address_state
481     request['address_country']       = authority.address_country
482     request['authority_hrn']         = authority.authority_hrn
483     request['timestamp']             = authority.created
484     return request
485
486 def make_requests(pending_users, pending_slices, pending_authorities, pending_projects, pending_joins):
487     logger.info("$$$$$$$$$$$$$$$  make_request")
488     requests = []
489     for user in pending_users:
490         requests.append(make_request_user(user))
491     for slice in pending_slices:
492         requests.append(make_request_slice(slice))
493     for authority in pending_authorities:
494         requests.append(make_request_authority(authority))
495     for project in pending_projects:
496         requests.append(make_request_project(project))
497     for join in pending_joins:
498         requests.append(make_request_join(join))
499     return requests   
500
501 def get_request_by_id(ids):
502     logger.info("$$$$$$$$$$$$$$$$  get_request_by_id")
503     sorted_ids = { 'user': [], 'slice': [], 'authority': [], 'project': [], 'join': [] }
504     for type__id in ids:
505         type, id = type__id.split('__')
506         sorted_ids[type].append(id)
507         
508     if not ids:
509         pending_users  = PendingUser.objects.all()
510         pending_slices = PendingSlice.objects.all()
511         pending_authorities = PendingAuthority.objects.all()
512         pending_projects = PendingProject.objects.all()
513         pending_joins = PendingJoin.objects.all()
514     else:
515         pending_users  = PendingUser.objects.filter(id__in=sorted_ids['user']).all()
516         pending_slices = PendingSlice.objects.filter(id__in=sorted_ids['slice']).all()
517         pending_authorities = PendingAuthority.objects.filter(id__in=sorted_ids['authority']).all()
518         pending_projects = PendingProject.objects.filter(id__in=sorted_ids['project']).all()
519         pending_joins = PendingJoin.objects.filter(id__in=sorted_ids['join']).all()
520
521     return make_requests(pending_users, pending_slices, pending_authorities, pending_projects, pending_joins)
522
523 def get_requests(authority_hrns=None):
524     logger.info("$$$$$$$$$$$$$   get_request_by_authority auth_hrns = {}".format(authority_hrns))
525     if not authority_hrns:
526         ## get those pending users who have confirmed their emails
527         pending_users  = PendingUser.objects.filter(status__iexact = 'True')
528         pending_slices = PendingSlice.objects.all()
529         pending_authorities = PendingAuthority.objects.all()
530         pending_projects = PendingProject.objects.all()
531         pending_joins = PendingJoin.objects.all()
532     else:
533         pending_users  = PendingUser.objects
534         pending_slices = PendingSlice.objects
535         pending_authorities = PendingAuthority.objects
536         pending_projects = PendingProject.objects
537         pending_joins = PendingJoin.objects
538         from django.db.models import Q
539         list_user_Q = list()
540         list_slice_Q = list()
541         list_auth_Q = list()
542         list_proj_Q = list()
543         list_join_Q = list()
544         for hrn in authority_hrns:
545             list_user_Q.append(Q(authority_hrn__startswith=hrn, status__iexact = 'True'))
546             list_slice_Q.append(Q(authority_hrn__startswith=hrn))
547             list_auth_Q.append(Q(site_authority__startswith=hrn))
548             list_proj_Q.append(Q(authority_hrn__startswith=hrn))
549             list_join_Q.append(Q(authority_hrn__startswith=hrn))
550         from operator import __or__ as OR
551         pending_users        = pending_users.filter(reduce(OR, list_user_Q))
552         pending_slices       = pending_slices.filter(reduce(OR, list_slice_Q))
553         pending_authorities  = pending_authorities.filter(reduce(OR, list_auth_Q))
554         pending_projects     = pending_projects.filter(reduce(OR, list_proj_Q))
555         pending_joins        = pending_joins.filter(reduce(OR, list_join_Q))
556         #pending_authorities  = pending_authorities.all() #filter(reduce(OR, list_Q))
557
558     return make_requests(pending_users, pending_slices, pending_authorities, pending_projects, pending_joins)
559
560 # XXX Is it in sync with the form fields ?
561
562 def portal_validate_request(wsgi_request, request_ids):
563     status = {}
564
565     if not isinstance(request_ids, list):
566         request_ids = [request_ids]
567
568     requests = get_request_by_id(request_ids)
569     for request in requests:
570         # type, id, timestamp, details, allowed -- MISSING: authority_hrn
571         # CAREFUL about details
572         # user  : first name, last name, email, password, keypair
573         # slice : number of nodes, type of nodes, purpose
574         
575         request_status = {}
576
577         if request['type'] == 'user':
578
579             try:
580                 create_user(wsgi_request, request)
581                 request_status['SFA user'] = {'status': True }
582                 PendingUser.objects.get(id=request['id']).delete()
583             except Exception, e:
584                  request_status['SFA user'] = {'status': False, 'description': str(e)}
585                        
586 #            user_params = {'status':2}
587 #            manifold_update_user(request, request['email'], user_params)
588
589             # MANIFOLD user should be added beforehand, during registration
590             #try:
591             #    manifold_user_params = { key: request[key] for key in MANIFOLD_USER_KEYS }
592             #    # XXX # manifold_add_user(manifold_user_params)
593             #    request_status['MySlice user'] = {'status': True }
594             #except Exception, e:
595             #    request_status['MySlice user'] = {'status': False, 'description': str(e)}
596
597             # XXX
598             #manifold_account_params = { key: request[key] for key in MANIFOLD_ACCOUNT_KEYS }
599             #manifold_add_account(manifold_account_params)
600             #request_status['MySlice testbed accounts'] = {'status': False }
601
602         elif request['type'] == 'slice':
603             try:
604                 create_slice(wsgi_request, request)
605                 request_status['SFA slice'] = {'status': True }
606                 PendingSlice.objects.get(id=request['id']).delete()
607
608                 # Clear user's Credentials
609                 sfa_user = sfa_get_user(wsgi_request, request['user_hrn'])
610                 clear_user_creds(wsgi_request,sfa_user['user_email'])
611
612             except Exception, e:
613                 request_status['SFA slice'] = {'status': False, 'description': str(e)}
614
615         elif request['type'] == 'authority':
616             try:
617                 #hrn = "%s.%s" % (request['authority_hrn'], request['site_authority'])
618                 hrn = request['site_authority']
619                 # XXX tmp sfa dependency
620                 from sfa.util.xrn import Xrn 
621                 urn = Xrn(hrn, request['type']).get_urn()
622                 
623                 # Only hrn is required for Manifold Query 
624                 sfa_authority_params = {
625                     'authority_hrn'        : hrn,
626                     #'authority_urn'        : urn,
627                     #'type'       : request['type'],
628                     #'pi'        : None,
629                     #'enabled'    : True
630                 }
631                 logger.info("ADD Authority")
632                 sfa_add_authority(wsgi_request, sfa_authority_params)
633                 request_status['SFA authority'] = {'status': True }
634                 PendingAuthority.objects.get(id=request['id']).delete()
635
636             except Exception, e:
637                 request_status['SFA authority'] = {'status': False, 'description': str(e)}
638
639         elif request['type'] == 'project':
640             try:
641                 hrn = request['authority_hrn'] + '.' + request['project_name']
642
643                 # Only hrn is required for Manifold Query 
644                 sfa_authority_params = {
645                     'authority_hrn'        : hrn
646                 }
647                 sfa_add_authority(wsgi_request, sfa_authority_params)
648                 request_status['SFA project'] = {'status': True }
649                 PendingProject.objects.get(id=request['id']).delete()
650                 
651                 # Add user as a PI of the project
652                 authority_add_pis(wsgi_request, hrn , request['user_hrn'])
653
654                 # Clear user's Credentials
655                 #sfa_user = sfa_get_user(wsgi_request, request['user_hrn'])
656                 clear_user_creds(wsgi_request,request['email'])
657
658             except Exception, e:
659                 request_status['SFA project'] = {'status': False, 'description': str(e)}
660
661         elif request['type'] == 'join':
662             try:
663                 # Add user as a PI of the project
664                 authority_add_pis(wsgi_request, request['authority_hrn'] , request['user_hrn'])
665
666                 request_status['SFA join'] = {'status': True }
667                 PendingJoin.objects.get(id=request['id']).delete()
668
669                 # Clear user's Credentials
670                 clear_user_creds(wsgi_request,request['email'])
671
672             except Exception, e:
673                 request_status['SFA join'] = {'status': False, 'description': str(e)+' - '+str(request)}
674         else:
675             request_status['other'] = {'status': False, 'description': 'unknown type of request'}
676         # XXX Remove from Pendings in database
677
678         status['%s__%s' % (request['type'], request['id'])] = request_status
679
680     return status
681
682 def validate_action(request, **kwargs):
683     ids = filter(None, kwargs['id'].split('/'))
684     status = portal_validate_request(request, ids)
685     json_answer = json.dumps(status)
686     return HttpResponse (json_answer, content_type="application/json")
687
688
689 def reject_action(request, **kwargs):
690     ids = filter(None, kwargs['id'].split('/'))
691     status = portal_reject_request(request, ids)
692     json_answer = json.dumps(status)
693     return HttpResponse (json_answer, content_type="application/json")
694
695
696 def portal_reject_request(wsgi_request, request_ids):
697     status = {}
698     # get the domain url    
699     current_site = Site.objects.get_current()
700     current_site = current_site.domain
701
702
703     if not isinstance(request_ids, list):
704         request_ids = [request_ids]
705
706     requests = get_request_by_id(request_ids)
707     for request in requests:
708         # type, id, timestamp, details, allowed -- MISSING: authority_hrn
709         # CAREFUL about details
710         # user  : first name, last name, email, password, keypair
711         # slice : number of nodes, type of nodes, purpose
712         
713         request_status = {}
714
715         if request['type'] == 'user':
716             try:
717                 request_status['SFA user'] = {'status': True }
718                 # getting user email based on id 
719                 ## RAW SQL queries on Django DB- https://docs.djangoproject.com/en/dev/topics/db/sql/
720                 for user in PendingUser.objects.raw('SELECT * FROM portal_pendinguser WHERE id = %s', [request['id']]):
721                     user_email= user.email
722                     first_name = user.first_name
723                     last_name = user.last_name
724
725                 ctx = {
726                     'first_name'    : first_name, 
727                     'last_name'     : last_name, 
728                     'portal_url'    : current_site,
729                     }
730                 try:
731                     theme.template_name = 'user_request_denied.txt'
732                     text_content = render_to_string(theme.template, ctx)
733                     theme.template_name = 'user_request_denied.html'
734                     html_content = render_to_string(theme.template, ctx)
735                     theme.template_name = 'email_default_sender.txt'
736                     sender =  render_to_string(theme.template, ctx)
737                     sender = sender.replace('\n', '')
738                                
739                     subject = 'User request denied.'
740
741                     msg = EmailMultiAlternatives(subject, text_content, sender, [user_email])
742                     msg.attach_alternative(html_content, "text/html")
743                     msg.send()
744                 except Exception as e:
745                     logger.error("Failed to send email, please check the mail templates and the SMTP configuration of your server")   
746
747                 # removing from Django portal_pendinguser
748                 PendingUser.objects.get(id=request['id']).delete()
749             
750                 delete_local_user(wsgi_request, user_email)
751             except Exception, e:
752                 request_status['SFA authority'] = {'status': False, 'description': str(e)}
753                       
754         elif request['type'] == 'slice':
755             request_status['SFA slice'] = {'status': True } 
756
757             # getting user email based on id 
758             ## RAW SQL queries on Django DB- https://docs.djangoproject.com/en/dev/topics/db/sql/
759             for user in PendingSlice.objects.raw('SELECT * FROM portal_pendingslice WHERE id = %s', [request['id']]):
760                 user_email= user.type_of_nodes # XXX type_of_nodes field contains the email [shd be renamed in DB]
761                 slice_name = user.slice_name
762                 purpose = user.purpose
763                 url = user.number_of_nodes
764
765             ctx = {
766                 'slice_name': slice_name,
767                 'purpose': purpose,
768                 'url': url,
769                 'portal_url': current_site,
770                 }
771             try:
772                 theme.template_name = 'slice_request_denied.txt'
773                 text_content = render_to_string(theme.template, ctx)
774                 theme.template_name = 'slice_request_denied.html'
775                 html_content = render_to_string(theme.template, ctx)
776                 theme.template_name = 'email_default_sender.txt'
777                 sender =  render_to_string(theme.template, ctx)
778                 sender = sender.replace('\n', '')
779                                
780                 subject = 'Slice request denied.'
781
782                 msg = EmailMultiAlternatives(subject, text_content, sender, [user_email])
783                 msg.attach_alternative(html_content, "text/html")
784                 msg.send()
785             except Exception as e:
786                 logger.error("Failed to send email, please check the mail templates and the SMTP configuration of your server")
787                       
788             PendingSlice.objects.get(id=request['id']).delete()
789
790         elif request['type'] == 'authority':
791             request_status['SFA authority'] = {'status': True }
792             
793             # getting user email based on id 
794             ## RAW SQL queries on Django DB- https://docs.djangoproject.com/en/dev/topics/db/sql/
795             for user in PendingAuthority.objects.raw('SELECT * FROM portal_pendingauthority WHERE id = %s', [request['id']]):
796                 user_email= user.address_line1 # XXX address_line1 field contains the email [shd be renamed in DB]
797                 site_name = user.site_name
798                 city = user.address_city
799                 country = user.address_country
800                 short_name = user.site_abbreviated_name
801                 url = user.site_url
802
803             ctx = { 
804                 'site_name': site_name,
805                 'short_name': short_name,
806                 'url': url,
807                 'city': city,
808                 'country': country,                          
809                 'portal_url'    : current_site,
810                 }
811                 
812             try:
813                 theme.template_name = 'authority_request_denied.txt'
814                 text_content = render_to_string(theme.template, ctx)
815                 theme.template_name = 'authority_request_denied.html'
816                 html_content = render_to_string(theme.template, ctx)
817                 theme.template_name = 'email_default_sender.txt'
818                 sender =  render_to_string(theme.template, ctx)
819                 sender = sender.replace('\n', '')
820                 subject = 'Authority request denied.'
821                 msg = EmailMultiAlternatives(subject, text_content, sender, [user_email])
822                 msg.attach_alternative(html_content, "text/html")
823                 msg.send()
824             except Exception as e:
825                 logger.error("Failed to send email, please check the mail templates and the SMTP configuration of your server")
826
827             PendingAuthority.objects.get(id=request['id']).delete()
828
829         # XXX TMP we should send an email to the user to inform him/her
830         elif request['type'] == 'project':
831             request_status['SFA project'] = {'status': True }
832             PendingProject.objects.get(id=request['id']).delete()
833
834         elif request['type'] == 'join':
835             request_status['SFA join'] = {'status': True }
836             PendingJoin.objects.get(id=request['id']).delete()
837
838         status['%s__%s' % (request['type'], request['id'])] = request_status
839
840     return status
841
842 # Django and ajax
843 # http://djangosnippets.org/snippets/942/
844
845
846
847 #-------------------------------------------------------------------------------
848 # REQUESTS - Slices
849 #-------------------------------------------------------------------------------
850
851 def create_slice(wsgi_request, request):
852     """
853     Arguments:
854         wsgi_request (~ WSGIRequest) : 
855         request (dict) : the slice request in our own dict format
856
857     Raises:
858         Exception
859     """
860     hrn = "%s.%s" % (request['authority_hrn'], request['slice_name'])
861     # XXX tmp sfa dependency
862     from sfa.util.xrn import Xrn 
863     urn = Xrn(hrn, request['type']).get_urn()
864     
865     # Add User to Slice if we have the user_hrn in pendingslice table
866     user_hrn = request.get('user_hrn', None)
867     user_hrns = list([user_hrn]) if user_hrn else list()
868    
869     # CACHE PB with fields
870     page = Page(wsgi_request)
871     metadata = page.get_metadata()
872     user_md = metadata.details_by_object('user')
873     user_fields = [column['name'] for column in user_md['column']]
874
875     # REGISTRY ONLY TO BE REMOVED WITH MANIFOLD-V2
876     #user_query  = Query().get('myslice:user').select('user_hrn','user_email').filter_by('user_hrn','==',user_hrn)
877     user_query  = Query().get('myslice:user').select(user_fields).filter_by('user_hrn','==',user_hrn)
878     user_details_sfa = execute_admin_query(wsgi_request, user_query)
879     if not user_details_sfa:
880         raise Exception, "User %s doesn't exist, validate user before validating slice" % user_hrn
881     for user in user_details_sfa:
882         user_email = user['user_email']
883
884     # XXX LOIC Quick fix because this is totally inconsistent
885     if not 'number_of_nodes' in request:
886         request['number_of_nodes']=""
887
888     # XXX We should create a slice with Manifold terminology
889     slice_params = {
890         'slice_hrn'        : hrn, 
891         'slice_urn'        : urn,
892         'slice_type'       : request['type'],
893         'url'              : request['number_of_nodes'],
894         'users'            : user_hrns,
895         'slice_enabled'    : True
896     }
897     # ignored in request: id, timestamp,  number_of_nodes, type_of_nodes, purpose
898
899     # REGISTRY ONLY TO BE REMOVED WITH MANIFOLD-V2
900     query = Query.create('myslice:slice').set(slice_params).select('slice_hrn')
901     results = execute_query(wsgi_request, query)
902     if not results:
903         raise Exception, "Could not create %s. Already exists ?" % slice_params['hrn']
904     else:
905         clear_user_creds(wsgi_request,user_email)
906         # log user activity
907         activity.slice.validate(request, { "slice" : hrn })
908         try:
909             theme.template_name = 'slice_request_validated.txt'
910             text_content = render_to_string(theme.template, request)
911             theme.template_name = 'slice_request_validated.html'
912             html_content = render_to_string(theme.template, request)
913         
914             theme.template_name = 'email_default_sender.txt'
915             sender =  render_to_string(theme.template, request)
916             sender = sender.replace('\n', '')
917
918             subject = 'Slice request validated'
919
920             msg = EmailMultiAlternatives(subject, text_content, sender, [user_email])
921             msg.attach_alternative(html_content, "text/html")
922             msg.send()
923         except Exception as e:
924             logger.error("Failed to send email, please check the mail templates and the SMTP configuration of your server")
925        
926     return results
927
928 def create_pending_slice(wsgi_request, request, email):
929     """
930     """
931
932     # Insert an entry in the PendingSlice table
933     s = PendingSlice(
934         slice_name      = request['slice_name'],
935         user_hrn        = request['user_hrn'],
936         authority_hrn   = request['authority_hrn'],
937         number_of_nodes = request['url'], # field needs to be renamed
938         purpose         = request['purpose'],
939         type_of_nodes   = request['email'] # field needs to be renamed 
940     )
941     s.save()
942
943     try:
944         # Send an email: the recipients are the PI of the authority
945         recipients = authority_get_pi_emails(wsgi_request, request['authority_hrn'])
946
947         theme.template_name = 'slice_request_email.txt' 
948         text_content = render_to_string(theme.template, request)
949     
950         theme.template_name = 'slice_request_email.html' 
951         html_content = render_to_string(theme.template, request)
952     
953         theme.template_name = 'slice_request_email_subject.txt'
954         subject = render_to_string(theme.template, request)
955         subject = subject.replace('\n', '')
956     
957         sender = email
958         msg = EmailMultiAlternatives(subject, text_content, sender, recipients)
959         msg.attach_alternative(html_content, "text/html")
960         msg.send()
961     except Exception as e:
962         logger.error("Failed to send email, please check the mail templates and the SMTP configuration of your server")
963
964
965 def create_pending_project(wsgi_request, request):
966     """
967     """
968
969     # Insert an entry in the PendingProject table
970     s = PendingProject(
971         project_name    = request['project_name'],
972         user_hrn        = request['user_hrn'],
973         email           = request['email'],
974         authority_hrn   = request['authority_hrn'],
975         purpose         = request['purpose'],
976     )
977     s.save()
978
979 def create_pending_join(wsgi_request, request):
980     """
981     """
982
983     # Insert an entry in the PendingJoin table
984     s = PendingJoin(
985         user_hrn        = request['user_hrn'],
986         email           = request['email'],
987         project_name    = request['project_name'],
988         authority_hrn   = request['authority_hrn'],
989     )
990     s.save()
991
992
993 #     try:
994 #         # Send an email: the recipients are the PI of the authority
995 #         recipients = authority_get_pi_emails(wsgi_request, request['authority_hrn'])
996
997 #         theme.template_name = 'slice_request_email.txt' 
998 #         text_content = render_to_string(theme.template, request)
999 #     
1000 #         theme.template_name = 'slice_request_email.html' 
1001 #         html_content = render_to_string(theme.template, request)
1002 #     
1003 #         theme.template_name = 'slice_request_email_subject.txt'
1004 #         subject = render_to_string(theme.template, request)
1005 #         subject = subject.replace('\n', '')
1006 #     
1007 #         sender = email
1008 #         msg = EmailMultiAlternatives(subject, text_content, sender, recipients)
1009 #         msg.attach_alternative(html_content, "text/html")
1010 #         msg.send()
1011 #     except Exception, e:
1012 #         print "Failed to send email, please check the mail templates and the SMTP configuration of your server"
1013
1014
1015 #-------------------------------------------------------------------------------
1016 # REQUESTS - Users
1017 #-------------------------------------------------------------------------------
1018
1019 def manifold_add_reference_user_accounts(wsgi_request, request):
1020     """When a new user is created, add reference accounts to the reference platform.
1021     """
1022     # XXX XXX XXX The rest of this function has to be checked XXX XXX XXX
1023
1024     # Retrieve user information
1025     user_query  = Query().get('local:user')             \
1026         .select('user_id', 'config', 'email', 'status') \
1027         .filter_by('email', '==', request['email'])
1028     user_details = execute_admin_query(wsgi_request, user_query)
1029
1030     # USER MAIN ACCOUNT != reference
1031     #print 'USER MAIN ACCOUNT != reference'
1032     list_accounts_query = Query().get('local:account')              \
1033         .select('user_id', 'platform_id', 'auth_type', 'config')    \
1034         .filter_by('user_id', '==', user_details[0]['user_id'])     \
1035         .filter_by('auth_type', '!=', 'reference')
1036     list_accounts = execute_admin_query(wsgi_request, list_accounts_query)
1037
1038     # XXX main_platform is being erased several times ???
1039     for account in list_accounts:
1040         main_platform_query = Query().get('local:platform')         \
1041             .select('platform_id', 'platform')                      \
1042             .filter_by('platform_id', '==', account['platform_id'])
1043         main_platform = execute_admin_query(wsgi_request, main_platform_query)
1044
1045     # Add reference accounts on SFA enabled platforms
1046     platforms_query = Query().get('local:platform') \
1047         .filter_by('disabled', '==', '0')           \
1048         .filter_by('gateway_type', '==', 'sfa')     \
1049         .select('platform_id', 'gateway_type')
1050     platforms = execute_admin_query(wsgi_request, platforms_query)
1051     for platform in platforms:
1052         #print "add reference to platform ",platform
1053         manifold_account_params = {
1054             'user_id'       : user_details[0]['user_id'],
1055             'platform_id'   : platform['platform_id'],
1056             'auth_type'     : 'reference',
1057             'config'        : '{"reference_platform": "' + main_platform[0]['platform'] + '"}',
1058         }
1059         manifold_add_account(wsgi_request, manifold_account_params)
1060
1061 def sfa_create_user(wsgi_request, request, namespace = None, as_admin = False):
1062     """
1063     Arguments:
1064         wsgi_request (~ WSGIRequest) : 
1065         request (dict) : the user request in our own dict format
1066
1067     Raises:
1068         Exception
1069     """
1070     from sfa.util.xrn import Xrn 
1071
1072     auth_pi = request.get('pi', None)
1073     auth_pi = list([auth_pi]) if auth_pi else list()
1074
1075     # We create a user request with Manifold terminology
1076     sfa_user_params = {
1077         'user_hrn'          : request['user_hrn'],
1078         'user_email'        : request['email'],
1079         'user_urn'          : Xrn(request['user_hrn'], request['type']).get_urn(),
1080         'user_type'         : request['type'],
1081         'keys'              : request['public_key'],
1082         'user_first_name'   : request['first_name'],
1083         'user_last_name'    : request['last_name'],
1084         'pi_authorities'    : auth_pi,
1085         'user_enabled'      : True
1086     }
1087
1088     if namespace is not None:
1089         query = Query.create('%s:user' % namespace).set(sfa_user_params).select('user_hrn')
1090     else:
1091         # REGISTRY ONLY TO BE REMOVED WITH MANIFOLD-V2
1092         query = Query.create('myslice:user').set(sfa_user_params).select('user_hrn')
1093
1094     if as_admin:
1095         results = execute_admin_query(wsgi_request, query)
1096     else:
1097         results = execute_query(wsgi_request, query)
1098
1099     if not results:
1100         raise Exception, "Could not create %s. Already exists ?" % sfa_user_params['user_hrn']
1101     else:
1102         try:
1103             theme.template_name = 'user_request_validated.txt'
1104             text_content = render_to_string(theme.template, request)
1105             theme.template_name = 'user_request_validated.html'
1106             html_content = render_to_string(theme.template, request)
1107         
1108             theme.template_name = 'email_default_sender.txt'
1109             sender =  render_to_string(theme.template, request)
1110             sender = sender.replace('\n', '')
1111
1112
1113             subject = 'Account validated'
1114
1115             msg = EmailMultiAlternatives(subject, text_content, sender, [request['email']])
1116             msg.attach_alternative(html_content, "text/html")
1117             msg.send()
1118         except Exception as e:
1119             logger.error("Failed to send email, please check the mail templates and the SMTP configuration of your server")
1120
1121     return results
1122
1123 def iotlab_create_user (wsgi_request, request, namespace = None, as_admin=False):
1124    
1125     import requests
1126     import time
1127     from requests.auth import HTTPBasicAuth
1128    
1129     engine = ConfigEngine() 
1130     URL_REST = engine.iotlab_url()
1131     LOGIN_ADMIN = engine.iotlab_admin_user()
1132     PASSWORD_ADMIN = engine.iotlab_admin_password()
1133
1134     auth = HTTPBasicAuth(LOGIN_ADMIN,PASSWORD_ADMIN)
1135     headers = {'content-type': 'application/json'}
1136
1137     for user in PendingUser.objects.raw('SELECT * FROM portal_pendinguser WHERE email = %s', [request['email']]):
1138         password= user.password
1139
1140
1141     iotlab_user_params = {
1142         "type"          : "SA",
1143         #"login"         : request['email'], #auto generated by iotlab
1144         "password"      : password,
1145         "firstName"     : request['first_name'],
1146         "lastName"      : request['last_name'],
1147         "email"         : request['email'],
1148         "structure"     : request['authority_hrn'],
1149         "city"          : "N/A",
1150         "country"       : "N/A",
1151         "sshPublicKey"  : request['public_key'],
1152         "motivations"   : "SFA federation",
1153     }    
1154    
1155     iotlab_user_params1 = json.dumps(iotlab_user_params)
1156     r=requests.post(url=URL_REST, data=iotlab_user_params1, headers=headers, auth=auth)
1157     logger.info('Create iotlab user : {} {}'.format(r.status_code, r.text))
1158     return r.text
1159
1160 def create_user(wsgi_request, request, namespace = None, as_admin = False):
1161     # XXX This has to be stored centrally
1162     USER_STATUS_ENABLED = 2
1163
1164     # NOTE : if we were to create a user directly (just like we create slices,
1165     # we would have to perform the steps in create_pending_user too
1166
1167     # Add the user to the SFA registry
1168     sfa_create_user(wsgi_request, request, namespace, as_admin)
1169
1170     # Update Manifold user status
1171     manifold_update_user(wsgi_request, request['email'], {'status': USER_STATUS_ENABLED})
1172
1173     # Add reference accounts for platforms
1174     manifold_add_reference_user_accounts(wsgi_request, request)
1175
1176     # Add the user to iotlab portal if theme is set to onelab
1177     if theme.theme == 'onelab':
1178         iotlab_create_user (wsgi_request, request)
1179
1180 def create_pending_user(wsgi_request, request, user_detail):
1181     """
1182     """
1183
1184     # Insert an entry in the PendingUser table
1185     b = PendingUser(
1186         first_name    = request['first_name'],
1187         last_name     = request['last_name'],
1188         authority_hrn = request['authority_hrn'],
1189         email         = request['email'],
1190         password      = request['password'],
1191         public_key    = request['public_key'],
1192         private_key   = request['private_key'],
1193         user_hrn      = request['user_hrn'],
1194         pi            = request['pi'],
1195         email_hash    = request['email_hash'],
1196         status        = 'False',
1197     )
1198     b.save()
1199     # sends email to user to activate the email
1200     theme.template_name = 'activate_user.html'
1201     html_content = render_to_string(theme.template, request)
1202     theme.template_name = 'activate_user.txt'
1203     text_content = render_to_string(theme.template, request)
1204     theme.template_name = 'activate_user_email_subject.txt'
1205     subject = render_to_string(theme.template, request)
1206     subject = subject.replace('\n', '')
1207     theme.template_name = 'email_default_sender.txt'
1208     sender =  render_to_string(theme.template, request)
1209     sender = sender.replace('\n', '')
1210     recipient = [request['email']]
1211     #recipient = recipient.append(request['email'])
1212
1213     msg = EmailMultiAlternatives(subject, text_content, sender, recipient)
1214     msg.attach_alternative(html_content, "text/html")
1215     msg.send()
1216    
1217     # saves the user to django auth_user table [needed for password reset]
1218     user = User.objects.create_user(request['email'], request['email'], request['password'])
1219
1220     # Creating a manifold user
1221     user_id = manifold_add_user(wsgi_request, request)
1222
1223     # Creating a Manifold account on the MySlice platform
1224     # Note the JSON representation of public and private keys already includes quotes
1225     account_config = {
1226         'user_hrn'          : request['user_hrn'],
1227         'user_public_key'   : request['public_key'],
1228     }
1229     if request['private_key']:
1230         account_config['user_private_key'] = request['private_key']
1231
1232     user_id = user_detail['user_id'] + 1 # the user_id for the newly created user in local:user
1233
1234     # XXX TODO: Require a myslice platform
1235     # ALERT: this will disapear with ROUTERV2 of Manifold
1236     # We have to consider the case where several registries can be used
1237     # Removed hardcoded platform = 5
1238     # This platform == 'myslice' is a TMP FIX !!
1239     try:
1240         reg_platform_query = Query().get('local:platform') \
1241             .filter_by('platform', '==', 'myslice')           \
1242             .select('platform_id')
1243         reg_platform = execute_admin_query(wsgi_request, reg_platform_query)
1244
1245         reg_platform_id = reg_platform[0]['platform_id']
1246         account_params = {
1247             'platform_id'   : reg_platform_id, # XXX ALERT !!
1248             'user_id'       : user_id, 
1249             'auth_type'     : request['auth_type'], 
1250             'config'        : json.dumps(account_config),
1251         }
1252         manifold_add_account(wsgi_request, account_params)
1253     except Exception as e:
1254         logger.error("Failed creating manifold account on platform {} for user: {}".format('myslice', request['email']))
1255
1256     try:
1257         # Send an email: the recipients are the PI of the authority
1258         # If No PI is defined for this Authority, send to a default email (different for each theme)
1259         recipients = authority_get_pi_emails(wsgi_request, request['authority_hrn'])
1260         
1261         theme.template_name = 'user_request_email.html'
1262         html_content = render_to_string(theme.template, request)
1263  
1264         theme.template_name = 'user_request_email.txt'
1265         text_content = render_to_string(theme.template, request)
1266     
1267         theme.template_name = 'user_request_email_subject.txt'
1268         subject = render_to_string(theme.template, request)
1269         subject = subject.replace('\n', '')
1270     
1271         theme.template_name = 'email_default_sender.txt'
1272         sender =  render_to_string(theme.template, request)
1273         sender = sender.replace('\n', '')
1274     
1275         msg = EmailMultiAlternatives(subject, text_content, sender, recipients)
1276         msg.attach_alternative(html_content, "text/html")
1277         msg.send()
1278     except Exception, e:
1279         logger.error("Failed to send email, please check the mail templates and the SMTP configuration of your server")
1280         import traceback
1281         logger.error(traceback.format_exc())