aaa79b2f0ce29dc550c5f8a15e289fad4a167fc9
[unfold.git] / portal / projectrequestview.py
1 from django.shortcuts           import render
2 from django.contrib.sites.models import Site
3
4 from manifold.core.query        import Query
5 from manifoldapi.manifoldapi    import execute_admin_query, execute_query
6
7 from unfold.loginrequired       import LoginRequiredAutoLogoutView
8
9 from portal.actions import create_pending_project, create_pending_join, sfa_add_authority, authority_add_pis, is_pi
10 from portal.models import PendingProject, PendingJoin
11
12 from myslice.theme import ThemeView
13
14 import json, time, re
15
16 class ProjectRequestView(LoginRequiredAutoLogoutView, ThemeView):
17     template_name = 'projectrequest_view.html'
18     
19     def getAuthorities(self, request):
20         authorities_query = Query.get('authority').select('name', 'authority_hrn')
21         authorities = execute_admin_query(request, authorities_query)
22         if authorities is not None:
23             authorities = sorted(authorities, key=lambda k: k['authority_hrn'])
24             authorities = sorted(authorities, key=lambda k: k['name'])
25         return authorities
26     
27     def getUserAuthority(self, request):
28         # Get user_email (XXX Would deserve to be simplified)
29         user_query  = Query().get('local:user').select('email','config')
30         user_details = execute_query(request, user_query)
31         for user_detail in user_details:
32             user_config = json.loads(user_detail['config'])
33             user_authority = user_config.get('authority','N/A')
34         return user_authority
35     
36     def getUserHrn(self, request):
37         user_hrn = None
38         
39         account_query  = Query().get('local:account').select('user_id','platform_id','auth_type','config')
40         account_details = execute_query(request, account_query)
41
42         platform_query  = Query().get('local:platform').select('platform_id','platform','gateway_type','disabled')
43         platform_details = execute_query(request, platform_query)
44         
45         # getting user_hrn from local:account
46         for account_detail in account_details:
47             for platform_detail in platform_details:
48                 if platform_detail['platform_id'] == account_detail['platform_id']:
49                     # taking user_hrn only from myslice account
50                     # NOTE: we should later handle accounts filter_by auth_type= managed OR user
51                     if 'myslice' in platform_detail['platform']:
52                         account_config = json.loads(account_detail['config'])
53                         user_hrn = account_config.get('user_hrn','N/A')
54         return user_hrn        
55
56     def getUserEmail(self, request):
57         # Get user_email (XXX Would deserve to be simplified)
58         user_query  = Query().get('local:user').select('email','config')
59         user_details = execute_query(request, user_query)
60         user_email = user_details[0].get('email')
61         return user_email
62                    
63     def post(self, request):
64         return self.handle_request(request, 'POST')
65
66     def get(self, request):
67         return self.handle_request(request, 'GET')
68
69     def handle_request(self, wsgi_request, method):
70         errors = []
71         authority_hrn = None
72         authority_name = None
73         
74         #errors.append(wsgi_request.POST)
75
76         user_hrn = self.getUserHrn(wsgi_request)
77
78         user_email = self.getUserEmail(wsgi_request)
79         
80         authorities = self.getAuthorities(wsgi_request)
81         
82         user_authority = self.getUserAuthority(wsgi_request)
83         
84         # getting the org from authority
85         for authority in authorities:
86             if authority['authority_hrn'] == user_authority:
87                 authority_name = authority['name']
88         
89         if method == 'POST' :
90         
91             if 'join' in wsgi_request.POST:
92                 post = {
93                     'user_hrn'          : user_hrn,
94                     'email'             : user_email,
95                     'project_name'      : wsgi_request.POST.get('project_name', ''),
96                     'authority_hrn'     : wsgi_request.POST.get('project_name', ''),
97                 }
98
99             else:
100                 post = {
101                     'user_hrn'          : user_hrn,
102                     'email'             : user_email,
103                     'authority_hrn'     : wsgi_request.POST.get('authority_name', ''),
104                     'project_name'      : wsgi_request.POST.get('project_name', ''),
105                     'purpose'           : wsgi_request.POST.get('purpose', ''),
106                 }
107
108                 if (post['authority_hrn'] is None or post['authority_hrn'] == ''):
109                     errors.append('Organization is mandatory')
110     
111                 if (post['purpose'] is None or post['purpose'] == ''):
112                     errors.append('Experiment purpose is mandatory')
113
114                 if (re.search(r'^[A-Za-z0-9_]*$', post['project_name']) == None):
115                     errors.append('Project name may contain only letters, numbers, and underscore.')
116
117             # What kind of project name is valid?
118             if (post['project_name'] is None or post['project_name'] == ''):
119                 errors.append('Project name is mandatory')
120             
121             if not errors:
122                 print "is_pi on auth_hrn = ", user_authority
123                 if is_pi(wsgi_request, user_hrn, user_authority):
124                     # PIs can directly create/join project in their own authority...
125                     if 'join' in wsgi_request.POST:
126                         authority_add_pis(wsgi_request, post['project_name'], user_hrn)
127                     else:
128                         hrn = post['authority_hrn'] + '.' + post['project_name']
129                         sfa_add_authority(wsgi_request, {'authority_hrn':hrn})
130                         authority_add_pis(wsgi_request, hrn, user_hrn)
131                     self.template_name = 'slice-request-done-view.html'
132                 else:
133                     # Otherwise a wsgi_request is sent to the PI
134                     if 'join' in wsgi_request.POST:
135                         create_pending_join(wsgi_request, post)
136                     else:
137                         create_pending_project(wsgi_request, post)
138                     self.template_name = 'slice-request-ack-view.html'
139
140         # retrieves the pending projects creation list
141         pending_projects = PendingProject.objects.all().filter(user_hrn=user_hrn)
142         # retrieves the pending join a project list
143         pending_join_projects = PendingJoin.objects.all().filter(user_hrn=user_hrn)
144
145         root_authority = user_authority.split('.', 1)[0]                  
146         env = {
147                'errors':        errors,
148                'username':      wsgi_request.user,
149                'theme':         self.theme,
150                'authorities':   authorities,
151                'authority_hrn': user_authority,
152                'root_authority_hrn': root_authority,
153                'pending_projects': pending_projects,
154                'pending_join_projects': pending_join_projects,
155         }
156         return render(wsgi_request, self.template, env)
157     
158         
159     
160         """
161         """
162         errors = []
163         slice_name =''
164         purpose=''
165         url=''
166         authority_hrn = None
167         authority_name = None
168         # Retrieve the list of authorities
169         authorities_query = Query.get('authority').select('name', 'authority_hrn')
170         authorities = execute_admin_query(wsgi_request, authorities_query)
171         if authorities is not None:
172             authorities = sorted(authorities, key=lambda k: k['authority_hrn'])
173             authorities = sorted(authorities, key=lambda k: k['name'])
174
175         # Get user_email (XXX Would deserve to be simplified)
176         user_query  = Query().get('local:user').select('email','config')
177         user_details = execute_query(wsgi_request, user_query)
178         user_email = user_details[0].get('email')
179         # getting user_hrn
180         for user_detail in user_details:
181             user_config = json.loads(user_detail['config'])
182             user_authority = user_config.get('authority','N/A')              
183         # getting the org from authority        
184         for authority in authorities:
185             if authority['authority_hrn'] == user_authority:
186                 authority_name = authority['name']
187
188         # Handle the case when we use only hrn and not name
189         if authority_name is None:
190             authority_name = user_authority
191         #
192         account_query  = Query().get('local:account').select('user_id','platform_id','auth_type','config')
193         account_details = execute_query(wsgi_request, account_query)
194         #
195         platform_query  = Query().get('local:platform').select('platform_id','platform','gateway_type','disabled')
196         platform_details = execute_query(wsgi_request, platform_query)
197         
198         user_hrn = None
199         # getting user_hrn from local:account
200         for account_detail in account_details:
201             for platform_detail in platform_details:
202                 if platform_detail['platform_id'] == account_detail['platform_id']:
203                     # taking user_hrn only from myslice account
204                     # NOTE: we should later handle accounts filter_by auth_type= managed OR user
205                     if 'myslice' in platform_detail['platform']:
206                         account_config = json.loads(account_detail['config'])
207                         user_hrn = account_config.get('user_hrn','N/A')
208                         acc_auth_cred = account_config.get('delegated_authority_credentials','N/A')
209
210
211         # checking if pi or not
212         if acc_auth_cred == {} or acc_auth_cred == 'N/A':
213             pi = "is_not_pi"
214         else:
215             pi = "is_pi"
216
217
218         # Page rendering
219 #         page = Page(wsgi_request)
220 #         page.add_js_files  ( [ "js/jquery.validate.js", "js/jquery-ui.js" ] )
221 #         page.add_css_files ( [ "https://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" ] )
222 #         page.expose_js_metadata()
223
224         if method == 'POST':
225             # The form has been submitted
226
227             # get the domain url
228 #             current_site = Site.objects.get_current()
229 #             current_site = current_site.domain
230             
231             # getting the authority_hrn from the selected organization
232             for authority in authorities:
233                 if authority['name'] == wsgi_request.POST.get('org_name', ''):
234                     authority_hrn = authority['authority_hrn']
235
236             # Handle the case when we use only hrn and not name
237             if authority_hrn is None:
238                 authority_hrn = wsgi_request.POST.get('org_name', '')
239
240             slice_request = {
241                 'type'              : 'slice',
242                 'id'                : None,
243                 'user_hrn'          : user_hrn,
244                 'email'             : user_email,
245                 'timestamp'         : time.time(),
246                 'authority_hrn'     : authority_hrn,
247                 'organization'      : wsgi_request.POST.get('org_name', ''),
248                 'slice_name'        : wsgi_request.POST.get('slice_name', ''),
249                 'url'               : wsgi_request.POST.get('url', ''),
250                 'purpose'           : wsgi_request.POST.get('purpose', ''),
251                 'current_site'      : current_site
252             }
253             
254             # create slice_hrn based on authority_hrn and slice_name
255 #             slice_name = slice_request['slice_name']
256             req_slice_hrn = authority_hrn + '.' + slice_name
257             # comparing requested slice_hrn with the existing slice_hrn 
258             slice_query  = Query().get('myslice:slice').select('slice_hrn','parent_authority').filter_by('parent_authority','==',authority_hrn)
259             slice_details_sfa = execute_admin_query(wsgi_request, slice_query)
260             for _slice in slice_details_sfa:
261                 if _slice['slice_hrn'] == req_slice_hrn:
262                     errors.append('Slice already exists. Please use a different slice name.')
263             
264
265             # What kind of slice name is valid?
266             if (slice_name is None or slice_name == ''):
267                 errors.append('Slice name is mandatory')
268             
269             if (re.search(r'^[A-Za-z0-9_]*$', slice_name) == None):
270                 errors.append('Slice name may contain only letters, numbers, and underscore.')
271             
272             organization = slice_request['organization']    
273             if (organization is None or organization == ''):
274                 errors.append('Organization is mandatory')
275
276
277     
278             purpose = slice_request['purpose']
279             if (purpose is None or purpose == ''):
280                 errors.append('Experiment purpose is mandatory')
281
282             url = slice_request['url']
283
284             if not errors:
285                 if is_pi(wsgi_request, user_hrn, authority_hrn):
286                     # PIs can directly create slices in their own authority...
287                     create_slice(wsgi_request, slice_request)
288                     clear_user_creds(wsgi_request, user_email)
289                     self.template_name = 'slice-request-done-view.html'
290                 else:
291                     # Otherwise a wsgi_request is sent to the PI
292                     create_pending_slice(wsgi_request, slice_request, user_email)
293                     self.template_name = 'slice-request-ack-view.html'
294                 
295                 # log user activity
296                 activity.user.slice(wsgi_request)
297                 
298                 return render(wsgi_request, self.template, {'theme': self.theme}) # Redirect after POST
299         else:
300             slice_request = {}
301
302         template_env = {
303             'username': wsgi_request.user.email,
304             'errors': errors,
305             'slice_name': slice_name,
306             'purpose': purpose,
307             'email': user_email,
308             'user_hrn': user_hrn,
309             'url': url,
310             'pi': pi,
311             'authority_name': authority_name,        
312             'authority_hrn': user_authority,        
313             'cc_myself': True,
314             'authorities': authorities,
315             'theme': self.theme,
316             'section': "Slice request"
317         }
318         template_env.update(slice_request)
319         template_env.update(page.prelude_env())
320         return render(wsgi_request, self.template, template_env)