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