1 # -*- coding: utf-8 -*-
3 # portal/views.py: views for the portal application
4 # This file is part of the Manifold project.
7 # Jordan Augé <jordan.auge@lip6.fr>
8 # Mohammed Yasin Rahman <mohammed-yasin.rahman@lip6.fr>
9 # Copyright 2013, UPMC Sorbonne Universités / LIP6
11 # This program is free software; you can redistribute it and/or modify it under
12 # the terms of the GNU General Public License as published by the Free Software
13 # Foundation; either version 3, or (at your option) any later version.
15 # This program is distributed in the hope that it will be useful, but WITHOUT
16 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
20 # You should have received a copy of the GNU General Public License along with
21 # this program; see the file COPYING. If not, write to the Free Software
22 # Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 from django.conf import settings
25 from django.contrib.sites.models import Site, RequestSite
26 from django.contrib import messages
27 from django.views.generic import View
28 from django.views.generic.base import TemplateView
29 from django.shortcuts import render
31 from plugins.lists.simplelist import SimpleList
33 from plugins.pres_view import PresView
34 from portal.event import Event
37 from portal import signals
38 from portal.forms import UserRegisterForm, SliceRequestForm, ContactForm
39 from portal.util import RegistrationView, ActivationView
40 from portal.models import PendingUser, PendingSlice
41 from manifold.core.query import Query
42 from unfold.page import Page
43 from myslice.viewutils import topmenu_items, the_user
44 from django.http import HttpResponseRedirect, HttpResponse
46 from M2Crypto import Rand, RSA, BIO
49 class DashboardView(TemplateView):
50 template_name = "dashboard.html"
52 def get_context_data(self, **kwargs):
53 # We might have slices on different registries with different user accounts
54 # We note that this portal could be specific to a given registry, to which we register users, but i'm not sure that simplifies things
55 # Different registries mean different identities, unless we identify via SFA HRN or have associated the user email to a single hrn
57 #messages.info(self.request, 'You have logged in')
58 page = Page(self.request)
61 #slice_query = Query().get('slice').filter_by('user.user_hrn', 'contains', user_hrn).select('slice_hrn')
62 slice_query = Query().get('user').filter_by('user_hrn', '==', '$user_hrn').select('user_hrn', 'slice.slice_hrn')
63 auth_query = Query().get('network').select('network_hrn')
64 page.enqueue_query(slice_query)
65 page.enqueue_query(auth_query)
67 page.expose_js_metadata()
70 slicelist = SimpleList(
73 key = 'slice.slice_hrn',
77 authlist = SimpleList(
84 context = super(DashboardView, self).get_context_data(**kwargs)
85 context['person'] = self.request.user
86 context['networks'] = authlist.render(self.request)
87 context['slices'] = slicelist.render(self.request)
89 # XXX This is repeated in all pages
90 # more general variables expected in the template
91 context['title'] = 'Test view that combines various plugins'
92 # the menu items on the top
93 context['topmenu_items'] = topmenu_items('Dashboard', self.request)
94 # so we can sho who is logged
95 context['username'] = the_user(self.request)
97 context.update(page.prelude_env())
101 class UserRegisterView(RegistrationView):
103 A registration backend which follows a simple workflow:
105 1. User signs up, inactive account is created.
107 2. Email is sent to user with activation link.
109 3. User clicks activation link, account is now active.
111 Using this backend requires that
113 * ``registration`` be listed in the ``INSTALLED_APPS`` setting
114 (since this backend makes use of models defined in this
117 * The setting ``ACCOUNT_ACTIVATION_DAYS`` be supplied, specifying
118 (as an integer) the number of days from registration during
119 which a user may activate their account (after that period
120 expires, activation will be disallowed).
122 * The creation of the templates
123 ``registration/activation_email_subject.txt`` and
124 ``registration/activation_email.txt``, which will be used for
125 the activation email. See the notes for this backends
126 ``register`` method for details regarding these templates.
128 Additionally, registration can be temporarily closed by adding the
129 setting ``REGISTRATION_OPEN`` and setting it to
130 ``False``. Omitting this setting, or setting it to ``True``, will
131 be interpreted as meaning that registration is currently open and
134 Internally, this is accomplished via storing an activation key in
135 an instance of ``registration.models.RegistrationProfile``. See
136 that model and its custom manager for full documentation of its
137 fields and supported operations.
140 form_class = UserRegisterForm
142 def register(self, request, **cleaned_data):
144 Given a username, email address and password, register a new
145 user account, which will initially be inactive.
147 Along with the new ``User`` object, a new
148 ``registration.models.RegistrationProfile`` will be created,
149 tied to that ``User``, containing the activation key which
150 will be used for this account.
152 An email will be sent to the supplied email address; this
153 email should contain an activation link. The email will be
154 rendered using two templates. See the documentation for
155 ``RegistrationProfile.send_activation_email()`` for
156 information about these templates and the contexts provided to
159 After the ``User`` and ``RegistrationProfile`` are created and
160 the activation email is sent, the signal
161 ``registration.signals.user_registered`` will be sent, with
162 the new ``User`` as the keyword argument ``user`` and the
163 class of this backend as the sender.
166 first_name = cleaned_data['first_name']
167 last_name = cleaned_data['last_name']
168 affiliation= cleaned_data['affiliation']
169 email = cleaned_data['email']
170 password = cleaned_data['password1']
172 #password2 = cleaned_data['password2']
173 keypair = cleaned_data['keypair']
175 #if Site._meta.installed:
176 # site = Site.objects.get_current()
178 # site = RequestSite(request)
181 new_user = PendingUser.objects.create_inactive_user(first_name, last_name, email, password, site)
182 signals.user_registered.send(sender=self.__class__,
187 def get_context_data(self, **kwargs):
188 context = super(UserRegisterView, self).get_context_data(**kwargs)
189 context['topmenu_items'] = topmenu_items('Register', self.request)
190 context['username'] = the_user (self.request)
193 def registration_allowed(self, request):
195 Indicate whether account registration is currently permitted,
196 based on the value of the setting ``REGISTRATION_OPEN``. This
197 is determined as follows:
199 * If ``REGISTRATION_OPEN`` is not specified in settings, or is
200 set to ``True``, registration is permitted.
202 * If ``REGISTRATION_OPEN`` is both specified and set to
203 ``False``, registration is not permitted.
206 return getattr(settings, 'REGISTRATION_OPEN', True)
208 def get_success_url(self, request, user):
210 Return the name of the URL to redirect to after successful
214 return ('user_register_complete', (), {})
217 class UserValidateView(ActivationView):
218 def activate(self, request, activation_key):
220 Given an an activation key, look up and activate the user
221 account corresponding to that key (if possible).
223 After successful activation, the signal
224 ``registration.signals.user_activated`` will be sent, with the
225 newly activated ``User`` as the keyword argument ``user`` and
226 the class of this backend as the sender.
229 activated_user = RegistrationProfile.objects.activate_user(activation_key)
231 signals.user_activated.send(sender=self.__class__,
234 return activated_user
236 def get_success_url(self, request, user):
237 return ('registration_activation_complete', (), {})
240 # DEPRECATED #from portal.portalpage import PortalPage
241 # DEPRECATED #from plugins.wizard import Wizard
242 # DEPRECATED #from plugins.form import CreateForm
243 # DEPRECATED #from plugins.raw.raw import Raw # XXX
245 # DEPRECATED #from myslice.viewutils import the_user
247 # DEPRECATED #from django.template.loader import render_to_string
248 # DEPRECATED #from django.template import RequestContext
249 # DEPRECATED #from django.views import generic
251 # DEPRECATED #from django.contrib.formtools.wizard.views import NamedUrlSessionWizardView
252 # DEPRECATED ##from django.core.files.storage import FileSystemStorage
253 # DEPRECATED #from django.core.files.storage import default_storage
255 # DEPRECATED ##class MerlinWizard(NamedUrlSessionWizardView):
260 # DEPRECATED ## @classonlymethod
261 # DEPRECATED ## def as_view(cls, *args, **kwargs):
262 # DEPRECATED ## kwargs.update({
263 # DEPRECATED ## 'form_list': [
264 # DEPRECATED ## NameForm,
265 # DEPRECATED ## QuestForm,
266 # DEPRECATED ## ColorForm,
268 # DEPRECATED ## 'url_name': 'merlin_wizard'
270 # DEPRECATED ## return super(MerlinWizard, cls).as_view(*args, **kwargs)
272 # DEPRECATED #class UserRegisterWizardView(NamedUrlSessionWizardView):
273 # DEPRECATED ##class UserRegisterWizardView(LoginRequiredMixin, NamedUrlSessionWizardView):
274 # DEPRECATED # # Notice that I specify a file storage instance. If you don't specify this,
275 # DEPRECATED # # and you need to support FileField or ImageField in your forms, you'll get
276 # DEPRECATED # # errors from Django. This is something else I think could be handled by
277 # DEPRECATED # # the views better. Seems to me that it should just use whatever the
278 # DEPRECATED # # default/specified storage is for the rest of your project/application.
279 # DEPRECATED # file_storage = default_storage # FileSystemStorage()
280 # DEPRECATED # template_name = "register_user_wizard.html"
282 # DEPRECATED # def done(self, form_list, **kwargs):
283 # DEPRECATED # step1_form = form_list[0]
284 # DEPRECATED # step2_form = form_list[1]
286 # DEPRECATED # productext = self.create_product(product_form)
287 # DEPRECATED # shippings = self.create_shippings(productext, shipping_forms)
288 # DEPRECATED # images = self.create_images(productext, image_forms)
290 # DEPRECATED # if all([productext, shippings, images]):
291 # DEPRECATED # del self.request.session["wizard_product_wizard_view"]
293 # DEPRECATED # messages.success(self.request,
294 # DEPRECATED # _("Your product has been created."))
295 # DEPRECATED # return HttpResponseRedirect(self.get_success_url(productext))
297 # DEPRECATED # messages.error(self.request, _("Something went wrong creating your "
298 # DEPRECATED # "product. Please try again or contact support."))
299 # DEPRECATED # return HttpResponseRedirect(reverse("register_wizard"))
301 # DEPRECATED # #def get_form_kwargs(self, step):
302 # DEPRECATED # # if step == "product":
303 # DEPRECATED # # return {"user": self.request.user}
304 # DEPRECATED # # return {}
306 # DEPRECATED ## The portal should hook the slice and user creation pages
308 # DEPRECATED #def register_user(request):
310 # DEPRECATED # if request.method == 'POST':
311 # DEPRECATED # form = UserRegisterForm(request.POST) # Nous reprenons les données
312 # DEPRECATED # if form.is_valid():
313 # DEPRECATED # first_name = form.cleaned_data['first_name']
314 # DEPRECATED # last_name = form.cleaned_data['last_name']
315 # DEPRECATED # email = form.cleaned_data['email']
316 # DEPRECATED # password = form.cleaned_data['password']
317 # DEPRECATED # password2 = form.cleaned_data['password2']
318 # DEPRECATED # keypair = form.cleaned_data['keypair']
319 # DEPRECATED # ## Ici nous pouvons traiter les données du formulaire
320 # DEPRECATED # #sujet = form.cleaned_data['sujet']
321 # DEPRECATED # #message = form.cleaned_data['message']
322 # DEPRECATED # #envoyeur = form.cleaned_data['envoyeur']
323 # DEPRECATED # #renvoi = form.cleaned_data['renvoi']
324 # DEPRECATED # ## Nous pourrions ici envoyer l'e-mail grâce aux données que nous venons de récupérer
325 # DEPRECATED # #envoi = True
327 # DEPRECATED # form = UserRegisterForm()
328 # DEPRECATED # return render(request, 'register_user.html', locals())
330 # DEPRECATED #def index(request):
332 # DEPRECATED # WIZARD_TITLE = 'User registration'
333 # DEPRECATED # STEP1_TITLE = 'Enter your details'
334 # DEPRECATED # STEP2_TITLE = 'Select your institution'
335 # DEPRECATED # STEP3_TITLE = 'Authentication'
336 # DEPRECATED # STEP4_TITLE = 'Request a slice (optional)'
337 # DEPRECATED # STEP5_TITLE = 'Waiting for validation'
338 # DEPRECATED # STEP6_TITLE = 'Account validated'
340 # DEPRECATED # STEP0 = render_to_string('account_validated.html', context_instance=RequestContext(request))
341 # DEPRECATED # STEP2_HTML = """
342 # DEPRECATED # coucou
344 # DEPRECATED # STEP4 = """
347 # DEPRECATED # STEP5 = render_to_string('account_validated.html', context_instance=RequestContext(request))
349 # DEPRECATED # p = PortalPage(request)
351 # DEPRECATED # # This is redundant with the Wizard title
352 # DEPRECATED # p << "<h3>User registration</h3>"
354 # DEPRECATED # sons = []
355 # DEPRECATED # start_step = 1
357 # DEPRECATED # # STEP 1
358 # DEPRECATED # # If the user already exists (is logged), let's display a summary of his account details
359 # DEPRECATED # # Otherwise propose a form to fill in
360 # DEPRECATED # if the_user(request):
361 # DEPRECATED # # Fill a disabled form with user info
362 # DEPRECATED # # Please logout to register another user
363 # DEPRECATED # sons.append(Raw(page=p, title=STEP1_TITLE, togglable=False, html=STEP0))
364 # DEPRECATED # start_step += 1
366 # DEPRECATED # # We could pass a list of fields also, instead of retrieving them from metadata
367 # DEPRECATED # # Otherwise we need some heuristics to display nice forms
368 # DEPRECATED # # XXX Could we log the user in after the form is validated ?
369 # DEPRECATED # # XXX Explain the password is for XXX
370 # DEPRECATED # field_list = [{
371 # DEPRECATED # 'name' : 'First name',
372 # DEPRECATED # 'field' : 'firstname',
373 # DEPRECATED # 'type' : 'text',
374 # DEPRECATED # 'validate_rx' : '^[a-zA-Z -]+$',
375 # DEPRECATED # 'validate_err': 'Your first name must be comprised of letters only',
376 # DEPRECATED # 'description' : 'Enter your first name',
378 # DEPRECATED # 'name' : 'Last name',
379 # DEPRECATED # 'field' : 'lastname',
380 # DEPRECATED # 'type' : 'text',
381 # DEPRECATED # 'validate_rx' : '^[a-zA-Z -]+$',
382 # DEPRECATED # 'validate_err': 'Your last name must be comprised of letters only',
383 # DEPRECATED # 'description' : 'Enter your last name',
385 # DEPRECATED # 'name' : 'Email',
386 # DEPRECATED # 'field' : 'email',
387 # DEPRECATED # 'type' : 'text',
388 # DEPRECATED # 'description' : 'Enter your email address',
390 # DEPRECATED # 'name' : 'Password',
391 # DEPRECATED # 'field' : 'password',
392 # DEPRECATED # 'type' : 'password',
393 # DEPRECATED # 'description' : 'Enter your password',
395 # DEPRECATED # 'name' : 'Confirm password',
396 # DEPRECATED # 'field' : 'password2',
397 # DEPRECATED # 'type' : 'password',
398 # DEPRECATED # 'description' : 'Enter your password again',
400 # DEPRECATED # sons.append(CreateForm(page = p, title = STEP1_TITLE, togglable = False, object = 'local:user', fields = field_list))
402 # DEPRECATED # # STEP 2
403 # DEPRECATED # # If the user already exists (is logged), let's display a summary of its institution
404 # DEPRECATED # # Otherwise propose a form to fill in (we should base our selection on the email)
405 # DEPRECATED # if the_user(request):
406 # DEPRECATED # # Fill a disabled form with institution
407 # DEPRECATED # # Please logout to register another user
408 # DEPRECATED # sons.append(Raw(page=p, title=STEP2_TITLE, togglable=False, html="User created"))
409 # DEPRECATED # start_step += 1
411 # DEPRECATED # sons.append(CreateForm(page = p, title = STEP2_TITLE, togglable = False, object = 'slice')) #institution'))
413 # DEPRECATED # # STEP3
414 # DEPRECATED # # Please should your prefered authentication method
415 # DEPRECATED # # This step should allow the user to either choose the user or managed mode in MySlice
416 # DEPRECATED # sons.append(Raw(page = p, title = STEP3_TITLE, togglable = False, html = STEP2_HTML))
418 # DEPRECATED # # Step 4: Request a slice (optional)
419 # DEPRECATED # sons.append(CreateForm(page = p, title = STEP4_TITLE, togglable = False, object = 'slice'))
421 # DEPRECATED # # Step 5: Your request is waiting for validation
422 # DEPRECATED # # Periodic refresh
423 # DEPRECATED # sons.append(Raw(page = p, title = STEP5_TITLE, togglable = False, html = STEP4))
425 # DEPRECATED # # Step 6: Account validation = welcome for newly validated users
426 # DEPRECATED # # . delegation
427 # DEPRECATED # # . platforms
428 # DEPRECATED # # . slice
429 # DEPRECATED # # . pointers
430 # DEPRECATED # sons.append(Raw(page = p, title = STEP6_TITLE, togglable = False, html = STEP5))
432 # DEPRECATED # wizard = Wizard(
433 # DEPRECATED # page = p,
434 # DEPRECATED # title = WIZARD_TITLE,
435 # DEPRECATED # togglable = False,
436 # DEPRECATED # sons = sons,
437 # DEPRECATED # start_step = start_step,
440 # DEPRECATED # p << wizard.render(request) # in portal page if possible
442 # DEPRECATED # return p.render()
445 # DEPRECATED ## view for my_account
446 # DEPRECATED # class MyAccountView(TemplateView):
447 # DEPRECATED # template_name = "my_account.html"
449 # DEPRECATED # def from_process(self, request, **cleaned_data):
450 # DEPRECATED # #if request.method == 'POST':
451 # DEPRECATED # # if request.POST['submit_name']:
452 # DEPRECATED # if 'fname' in request.POST:
453 # DEPRECATED # messsag= "Got Name"
454 # DEPRECATED # #return render(request, 'portal/my_account.html')
455 # DEPRECATED # #response = HttpResponse("Here's the text of the Web page.")
456 # DEPRECATED # return HttpResponse(message)
458 # DEPRECATED # def get_context_data(self, **kwargs):
459 # DEPRECATED # page = Page(self.request)
460 # DEPRECATED # context = super(MyAccountView, self).get_context_data(**kwargs)
461 # DEPRECATED # context['person'] = self.request.user
462 # DEPRECATED # # XXX This is repeated in all pages
463 # DEPRECATED # # more general variables expected in the template
464 # DEPRECATED # context['title'] = 'User Profile Page'
465 # DEPRECATED # # the menu items on the top
466 # DEPRECATED # context['topmenu_items'] = topmenu_items('my_account', self.request)
467 # DEPRECATED # # so we can sho who is logged
468 # DEPRECATED # context['username'] = the_user(self.request)
469 # DEPRECATED # context.update(page.prelude_env())
470 # DEPRECATED # return context
474 # View for my_account form
475 def my_account(request):
476 return render(request, 'my_account.html', {
478 'topmenu_items': topmenu_items('My Account', request),
479 'username': the_user (request)
483 #my_acc form value processing
484 def acc_process(request):
485 # getting the user_id from the session [now hardcoded]
486 get_user = PendingUser.objects.get(id='1') # here we will get the id/email from session e.g., person.email
487 if 'submit_name' in request.POST:
488 edited_first_name = request.POST['fname']
489 edited_last_name = request.POST['lname']
490 #email = 'test_email@gmail.com'
491 #password = 'test_pp'
492 #message = 'F_Name: %s L_name: %s dummy_pp: %s' % (first_name, last_name, password)
495 # insert into DB [needed for registration page]
496 #approach borrowed from register view
497 #new_user = PendingUser.objects.create_inactive_user(edited_first_name, edited_last_name, email, password, site)
498 #conventional approach
499 #b = PendingUser(first_name=edited_first_name, last_name=edited_last_name)
502 # select and update [will be used throughout this view]
503 # select the logged in user [for the moment hard coded]
504 #get_user = PendingUser.objects.get(id='1') # here we will get the id/email from session e.g., person.email
505 # update first and last name
506 get_user.first_name = edited_first_name
507 get_user.last_name = edited_last_name
510 return HttpResponse('Success: Name Updated!!')
511 elif 'submit_pass' in request.POST:
512 edited_password = request.POST['password']
513 # select the logged in user [for the moment hard coded]
514 #get_user = PendingUser.objects.get(id='1') # here we will get the id/email from session e.g., person.email
516 get_user.password = edited_password
518 return HttpResponse('Success: Password Changed!!')
519 elif 'generate' in request.POST:
521 #from M2Crypto import Rand, RSA, BIO
525 def blank_callback():
526 "Replace the default dashes"
530 Rand.rand_seed (os.urandom (KEY_LENGTH))
532 key = RSA.gen_key (KEY_LENGTH, 65537, blank_callback)
533 # Create memory buffers
534 pri_mem = BIO.MemoryBuffer()
535 pub_mem = BIO.MemoryBuffer()
536 # Save keys to buffers
537 key.save_key_bio(pri_mem, None)
538 key.save_pub_key_bio(pub_mem)
541 public_key = pub_mem.getvalue()
542 private_key = pri_mem.getvalue()
544 keypair = '{"user_public_key":"'+ public_key + '", "user_private_key":"'+ private_key + '"}'
545 keypair = re.sub("\r", "", keypair)
546 keypair = re.sub("\n", "\\n", keypair)
547 #keypair = keypair.rstrip('\r\n')
548 keypair = ''.join(keypair.split())
549 get_user.keypair = keypair
551 return HttpResponse('Success: New Keypair Generated! %s' % keypair)
553 elif 'upload_key' in request.POST:
554 up_file = request.FILES['pubkey']
555 file_content = up_file.read()
556 file_name = up_file.name
557 file_extension = os.path.splitext(file_name)[1]
558 allowed_extension = ['.pub','.txt']
559 if file_extension in allowed_extension and re.search(r'ssh-rsa',file_content):
560 file_content = '{"user_public_key":"'+ file_content +'"}'
561 file_content = re.sub("\r", "", file_content)
562 file_content = re.sub("\n", "\\n",file_content)
563 file_content = ''.join(file_content.split())
564 get_user.keypair = file_content
566 return HttpResponse('Success: Publickey uploaded! Old records overwritten')
568 return HttpResponse('Please upload a valid RSA public key [.txt or .pub].')
571 message = 'You submitted an empty form.'
572 return HttpResponse(message)
574 def register_4m_f4f(request):
575 #return render(request, 'register_4m_f4f.html')
577 #def reg_4m_f4f_process(request):
578 if 'submit' in request.POST:
579 #get_email = PendingUser.objects.get(email)
580 reg_fname = request.POST['firstname']
581 reg_lname = request.POST['lastname']
582 reg_aff = request.POST['affiliation']
583 reg_email = request.POST['email'].lower()
585 #POST value validation
586 if (re.search(r'^[\w+\s.@+-]+$', reg_fname)==None):
587 messages.error(request, 'First Name may contain only letters, numbers, spaces and @/./+/-/_ characters.')
588 #return HttpResponse("Only Letters, Numbers, - and _ allowd in First Name")
589 return render(request, 'register_4m_f4f.html')
590 if (re.search(r'^[\w+\s.@+-]+$', reg_lname) == None):
591 messages.error(request, 'Last Name may contain only letters, numbers, spaces and @/./+/-/_ characters.')
592 #return HttpResponse("Only Letters, Numbers, - and _ is allowed in Last name")
593 return render(request, 'register_4m_f4f.html')
594 if (re.search(r'^[\w+\s.@+-]+$', reg_aff) == None):
595 messages.error(request, 'Affiliation may contain only letters, numbers, spaces and @/./+/-/_ characters.')
596 #return HttpResponse("Only Letters, Numbers and _ is allowed in Affiliation")
597 return render(request, 'register_4m_f4f.html')
598 if PendingUser.objects.filter(email__iexact=reg_email):
599 messages.error(request, 'Email already registered.Please provide a new email address.')
600 #return HttpResponse("Email Already exists")
601 return render(request, 'register_4m_f4f.html')
602 if 'generate' in request.POST['question']:
604 #from M2Crypto import Rand, RSA, BIO
608 def blank_callback():
609 "Replace the default dashes"
613 Rand.rand_seed (os.urandom (KEY_LENGTH))
615 key = RSA.gen_key (KEY_LENGTH, 65537, blank_callback)
616 # Create memory buffers
617 pri_mem = BIO.MemoryBuffer()
618 pub_mem = BIO.MemoryBuffer()
619 # Save keys to buffers
620 key.save_key_bio(pri_mem, None)
621 key.save_pub_key_bio(pub_mem)
623 public_key = pub_mem.getvalue()
624 private_key = pri_mem.getvalue()
626 keypair = '{"user_public_key":"'+ public_key + '", "user_private_key":"'+ private_key + '"}'
627 keypair = re.sub("\r", "", keypair)
628 keypair = re.sub("\n", "\\n", keypair)
629 #keypair = keypair.rstrip('\r\n')
630 keypair = ''.join(keypair.split())
631 #return HttpResponse(keypair)
633 up_file = request.FILES['user_public_key']
634 file_content = up_file.read()
635 file_name = up_file.name
636 file_extension = os.path.splitext(file_name)[1]
637 allowed_extension = ['.pub','.txt']
638 if file_extension in allowed_extension and re.search(r'ssh-rsa',file_content):
639 keypair = '{"user_public_key":"'+ file_content +'"}'
640 keypair = re.sub("\r", "", keypair)
641 keypair = re.sub("\n", "\\n",keypair)
642 keypair = ''.join(keypair.split())
644 return HttpResponse('Please upload a valid RSA public key [.txt or .pub].')
646 b = PendingUser(first_name=reg_fname, last_name=reg_lname, affiliation=reg_aff,
647 email=reg_email, password=request.POST['password'], keypair=keypair)
650 return render(request, 'user_register_complete.html')
651 return render(request, 'register_4m_f4f.html')
654 # view for contact form
655 def contact(request):
656 if request.method == 'POST': # If the form has been submitted...
657 form = ContactForm(request.POST) # A form bound to the POST data
658 if form.is_valid(): # All validation rules pass
659 # Process the data in form.cleaned_data
660 first_name = form.cleaned_data['first_name']
661 last_name = form.cleaned_data['last_name']
662 affiliation = form.cleaned_data['affiliation']
663 subject = form.cleaned_data['subject']
664 message = form.cleaned_data['message']
665 email = form.cleaned_data['email'] # email of the sender
666 cc_myself = form.cleaned_data['cc_myself']
668 recipients = ['yasin.upmc@gmail.com']
670 recipients.append(email)
672 from django.core.mail import send_mail
673 send_mail("Onelab user submitted a query ", [first_name,last_name,affiliation,subject,message], email, recipients)
674 return render(request,'contact_sent.html') # Redirect after POST
676 form = ContactForm() # An unbound form
678 return render(request, 'contact.html', {
680 'topmenu_items': topmenu_items('Contact Us', request),
681 'username': the_user (request)
686 def slice_request(request):
687 if request.method == 'POST': # If the form has been submitted...
688 form = SliceRequestForm(request.POST) # A form bound to the POST data
689 if form.is_valid(): # All validation rules pass
690 # Process the data in form.cleaned_data
691 slice_name = form.cleaned_data['slice_name']
692 number_of_nodes = form.cleaned_data['number_of_nodes']
693 type_of_nodes = form.cleaned_data['type_of_nodes']
694 purpose = form.cleaned_data['purpose']
695 email = form.cleaned_data['email'] # email of the sender
696 cc_myself = form.cleaned_data['cc_myself']
698 recipients = ['yasin.upmc@gmail.com','jordan.auge@lip6.fr']
700 recipients.append(email)
702 from django.core.mail import send_mail
703 send_mail("Onelab New Slice request form submitted", [slice_name,number_of_nodes,type_of_nodes,purpose], email, recipients)
704 return render(request,'slicereq_recvd.html') # Redirect after POST
706 form = SliceRequestForm() # An unbound form
709 # template_env['form'] = form
710 # template_env['topmenu_items'] = topmenu_items('Request a slice', request)
711 # template_env['unfold1_main'] = render(request, 'slice_request_.html', {
714 # from django.shortcuts import render_to_response
715 # from django.template import RequestContext
716 # return render_to_response ('view-unfold1.html',template_env,
717 # context_instance=RequestContext(request))
719 return render(request, 'slice_request.html', {
721 'topmenu_items': topmenu_items('Request a slice', request),
722 'username': the_user (request)
726 class PresViewView(TemplateView):
727 template_name = "view-unfold1.html"
729 def get_context_data(self, **kwargs):
731 page = Page(self.request)
733 pres_view = PresView(page = page)
735 context = super(PresViewView, self).get_context_data(**kwargs)
737 #context['ALL_STATIC'] = "all_static"
738 context['unfold1_main'] = pres_view.render(self.request)
740 # XXX This is repeated in all pages
741 # more general variables expected in the template
742 context['title'] = 'Test view that combines various plugins'
743 # the menu items on the top
744 context['topmenu_items'] = topmenu_items('PresView', self.request)
745 # so we can sho who is logged
746 context['username'] = the_user(self.request)
748 prelude_env = page.prelude_env()
749 context.update(prelude_env)
753 def json_me(config_file,type):
755 for ligne in config_file:
756 if not ligne.startswith('#'):
757 args = ligne.split(';')
758 json_answer += str('{ "name": "' + args[0] + '" ,"id":"' + args[1] + '" ,"descriptif":"' + args[2]+'"')
760 json_answer += str(',"contraints":')
762 json_answer += str('""')
764 json_answer += str(args[3])
765 json_answer += str('},')
766 return json_answer[:-1]
769 DIR = '/var/myslice/'
770 STATIC = '%s/config_method_static' % DIR
771 DYNAMIC = '%s/config_method_dynamic' % DIR
772 ANIMATION = '%s/config_method_animation' % DIR
774 def pres_view_methods(request, type):
778 elif type =="static":
779 config = open(STATIC, "r")
780 json_answer = str('{ "options": [')
781 json_answer += str(json_me(config,"static"))
782 json_answer += str('] }')
784 elif type =="dynamic":
785 config = open(DYNAMIC, "r")
786 json_answer = str('{ "options": [')
787 json_answer += str(json_me(config,"dynamic"))
788 json_answer += str('] }')
790 elif type =="animation":
791 config = open(ANIMATION, "r")
792 json_answer = str('{ "options": [')
793 json_answer += str(json_me(config,"animation"))
794 json_answer += str('] }')
797 config = open(STATIC, "r")
798 json_answer = str('{ "static": [')
799 json_answer += str(json_me(config,"static"))
800 json_answer += str('],')
801 json_answer += str('"dynamic": [')
803 config = open(DYNAMIC, "r")
804 json_answer += str(json_me(config,"dynamic"))
805 json_answer += str('],')
806 json_answer += str('"animation": [')
808 config = open(ANIMATION, "r")
809 json_answer += str(json_me(config,"animation"))
810 json_answer += str('] }')
814 return HttpResponse (json_answer, mimetype="application/json")
816 def pres_view_animation(request, constraints, id):
818 # sites crees depuis 2008
819 # static.py?contraints=']date_created':1262325600&id='name_id"'
821 # method = request.getvalue('method') #ex : GetSites
822 #constraints = "']date_created':1262325600"
828 # method = 'GetSites'#request.getvalue('method') #ex : GetSites
829 # constraints = {}#request.getvalue('constraints') // nul = {}
830 # response_field = "'site_id','name','date_created'"#request.getvalue('response_field')
832 config_file = open(ANIMATION, "r")
833 for ligne in config_file:
834 if not ligne.startswith('#'):
835 ligne = ligne.split('\n')
836 first = ligne[0].split(';')
837 if (str(first[1]) == str(id)):
841 #Les print_method, print_option sont definis par le client (js)
842 #Les animations acceptent que les connexions anonymous
843 # args = "postmsg;animation;;;anonymous;https://www.planet-lab.eu/PLCAPI/;"
844 args = ";;"+str(save[8])+";"+str(save[9])+";anonymous;"+str(save[5])+";"+str(save[6])+";{"+str(constraints)+"};"+str(save[7])+";"
847 #Creation d'un objet event
851 "print_options": event.print_options,
852 "print_method": event.print_method,
853 "message": event.data
858 json_answer = json.dumps(cmd)
859 return HttpResponse (json_answer, mimetype="application/json")
861 def pres_view_static(request, constraints, id):
862 #constraints = "']date_created':1262325600"
865 # method = 'GetSites'#request.getvalue('method') #ex : GetSites
866 # constraints = {}#request.getvalue('constraints') // nul = {}
867 # response_field = "'site_id','name','date_created'"#request.getvalue('response_field')
869 config_file = open(STATIC, "r")
870 for ligne in config_file:
871 if not ligne.startswith('#'):
872 ligne = ligne.split('\n')
873 first = ligne[0].split(';')
874 if (str(first[1]) == str(id)):
878 #Les print_method, print_option sont definis par le client (js)
879 #Les animations acceptent que les connexions anonymous
880 # args = "postmsg;animation;;;anonymous;https://www.planet-lab.eu/PLCAPI/;"
881 args = ";;"+str(save[8])+";"+str(save[9])+";anonymous;"+str(save[5])+";"+str(save[6])+";{"+str(constraints)+"};"+str(save[7])+";"
884 #Creation d'un objet event
888 "print_options": event.print_options,
889 "print_method": event.print_method,
890 "message": event.data
895 json_answer = json.dumps(cmd)
896 return HttpResponse (json_answer, mimetype="application/json")