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
30 from django.utils.decorators import method_decorator
31 from django.contrib.auth.decorators import login_required
33 from plugins.lists.simplelist import SimpleList
34 from plugins.hazelnut import Hazelnut
35 from plugins.pres_view import PresView
36 from portal.event import Event
39 from portal import signals
40 from portal.forms import SliceRequestForm, ContactForm
41 from portal.util import RegistrationView, ActivationView
42 from portal.models import PendingUser, PendingSlice
43 from manifold.core.query import Query
44 from unfold.page import Page
45 from myslice.viewutils import topmenu_items, the_user
46 from django.http import HttpResponseRedirect, HttpResponse
48 from M2Crypto import Rand, RSA, BIO
51 class DashboardView(TemplateView):
52 template_name = "dashboard.html"
54 #This view requires login
55 @method_decorator(login_required)
56 def dispatch(self, *args, **kwargs):
57 return super(DashboardView, self).dispatch(*args, **kwargs)
59 def get_context_data(self, **kwargs):
60 # We might have slices on different registries with different user accounts
61 # 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
62 # Different registries mean different identities, unless we identify via SFA HRN or have associated the user email to a single hrn
64 #messages.info(self.request, 'You have logged in')
65 page = Page(self.request)
68 #slice_query = Query().get('slice').filter_by('user.user_hrn', 'contains', user_hrn).select('slice_hrn')
69 slice_query = Query().get('user').filter_by('user_hrn', '==', '$user_hrn').select('user_hrn', 'slice.slice_hrn')
70 auth_query = Query().get('network').select('network_hrn')
71 page.enqueue_query(slice_query)
72 page.enqueue_query(auth_query)
74 page.expose_js_metadata()
77 slicelist = SimpleList(
80 key = 'slice.slice_hrn',
84 authlist = SimpleList(
91 context = super(DashboardView, self).get_context_data(**kwargs)
92 context['person'] = self.request.user
93 context['networks'] = authlist.render(self.request)
94 context['slices'] = slicelist.render(self.request)
96 # XXX This is repeated in all pages
97 # more general variables expected in the template
98 context['title'] = 'Test view that combines various plugins'
99 # the menu items on the top
100 context['topmenu_items'] = topmenu_items('Dashboard', self.request)
101 # so we can sho who is logged
102 context['username'] = the_user(self.request)
104 context.update(page.prelude_env())
108 # DEPRECATED #class UserRegisterView(RegistrationView):
110 # DEPRECATED # A registration backend which follows a simple workflow:
112 # DEPRECATED # 1. User signs up, inactive account is created.
114 # DEPRECATED # 2. Email is sent to user with activation link.
116 # DEPRECATED # 3. User clicks activation link, account is now active.
118 # DEPRECATED # Using this backend requires that
120 # DEPRECATED # * ``registration`` be listed in the ``INSTALLED_APPS`` setting
121 # DEPRECATED # (since this backend makes use of models defined in this
122 # DEPRECATED # application).
124 # DEPRECATED # * The setting ``ACCOUNT_ACTIVATION_DAYS`` be supplied, specifying
125 # DEPRECATED # (as an integer) the number of days from registration during
126 # DEPRECATED # which a user may activate their account (after that period
127 # DEPRECATED # expires, activation will be disallowed).
129 # DEPRECATED # * The creation of the templates
130 # DEPRECATED # ``registration/activation_email_subject.txt`` and
131 # DEPRECATED # ``registration/activation_email.txt``, which will be used for
132 # DEPRECATED # the activation email. See the notes for this backends
133 # DEPRECATED # ``register`` method for details regarding these templates.
135 # DEPRECATED # Additionally, registration can be temporarily closed by adding the
136 # DEPRECATED # setting ``REGISTRATION_OPEN`` and setting it to
137 # DEPRECATED # ``False``. Omitting this setting, or setting it to ``True``, will
138 # DEPRECATED # be interpreted as meaning that registration is currently open and
139 # DEPRECATED # permitt ed.
141 # DEPRECATED # Internally, this is accomplished via storing an activation key in
142 # DEPRECATED # an instance of ``registration.models.RegistrationProfile``. See
143 # DEPRECATED # that model and its custom manager for full documentation of its
144 # DEPRECATED # fields and supported operations.
147 # DEPRECATED ## DEPRECATED # form_class = UserRegisterForm
149 # DEPRECATED # def register(self, request, **cleaned_data):
151 # DEPRECATED # Given a username, email address and password, register a new
152 # DEPRECATED # user account, which will initially be inactive.
154 # DEPRECATED # Along with the new ``User`` object, a new
155 # DEPRECATED # ``registration.models.RegistrationProfile`` will be created,
156 # DEPRECATED # tied to that ``User``, containing the activation key which
157 # DEPRECATED # will be used for this account.
159 # DEPRECATED # An email will be sent to the supplied email address; this
160 # DEPRECATED # email should contain an activation link. The email will be
161 # DEPRECATED # rendered using two templates. See the documentation for
162 # DEPRECATED # ``RegistrationProfile.send_activation_email()`` for
163 # DEPRECATED # information about these templates and the contexts provided to
166 # DEPRECATED # After the ``User`` and ``RegistrationProfile`` are created and
167 # DEPRECATED # the activation email is sent, the signal
168 # DEPRECATED # ``registration.signals.user_registered`` will be sent, with
169 # DEPRECATED # the new ``User`` as the keyword argument ``user`` and the
170 # DEPRECATED # class of this backend as the sender.
173 # DEPRECATED # first_name = cleaned_data['first_name']
174 # DEPRECATED # last_name = cleaned_data['last_name']
175 # DEPRECATED # affiliation= cleaned_data['affiliation']
176 # DEPRECATED # email = cleaned_data['email']
177 # DEPRECATED # password = cleaned_data['password1']
179 # DEPRECATED # #password2 = cleaned_data['password2']
180 # DEPRECATED # keypair = cleaned_data['keypair']
182 # DEPRECATED # #if Site._meta.installed:
183 # DEPRECATED # # site = Site.objects.get_current()
184 # DEPRECATED # #else:
185 # DEPRECATED # # site = RequestSite(request)
186 # DEPRECATED # site = None
188 # DEPRECATED # new_user = PendingUser.objects.create_inactive_user(first_name, last_name, email, password, site)
189 # DEPRECATED # signals.user_registered.send(sender=self.__class__,
190 # DEPRECATED # user=new_user,
191 # DEPRECATED # request=request)
192 # DEPRECATED # return new_user
194 # DEPRECATED # def get_context_data(self, **kwargs):
195 # DEPRECATED # context = super(UserRegisterView, self).get_context_data(**kwargs)
196 # DEPRECATED # context['topmenu_items'] = topmenu_items('Register', self.request)
197 # DEPRECATED # context['username'] = the_user (self.request)
198 # DEPRECATED # return context
200 # DEPRECATED # def registration_allowed(self, request):
202 # DEPRECATED # Indicate whether account registration is currently permitted,
203 # DEPRECATED # based on the value of the setting ``REGISTRATION_OPEN``. This
204 # DEPRECATED # is determined as follows:
206 # DEPRECATED # * If ``REGISTRATION_OPEN`` is not specified in settings, or is
207 # DEPRECATED # set to ``True``, registration is permitted.
209 # DEPRECATED # * If ``REGISTRATION_OPEN`` is both specified and set to
210 # DEPRECATED # ``False``, registration is not permitted.
213 # DEPRECATED # return getattr(settings, 'REGISTRATION_OPEN', True)
215 # DEPRECATED # def get_success_url(self, request, user):
217 # DEPRECATED # Return the name of the URL to redirect to after successful
218 # DEPRECATED # user registration.
221 # DEPRECATED # return ('user_register_complete', (), {})
224 # DEPRECATED #class UserValidateView(ActivationView):
225 # DEPRECATED # def activate(self, request, activation_key):
227 # DEPRECATED # Given an an activation key, look up and activate the user
228 # DEPRECATED # account corresponding to that key (if possible).
230 # DEPRECATED # After successful activation, the signal
231 # DEPRECATED # ``registration.signals.user_activated`` will be sent, with the
232 # DEPRECATED # newly activated ``User`` as the keyword argument ``user`` and
233 # DEPRECATED # the class of this backend as the sender.
236 # DEPRECATED # activated_user = RegistrationProfile.objects.activate_user(activation_key)
237 # DEPRECATED # if activated_user:
238 # DEPRECATED # signals.user_activated.send(sender=self.__class__,
239 # DEPRECATED # user=activated_user,
240 # DEPRECATED # request=request)
241 # DEPRECATED # return activated_user
243 # DEPRECATED # def get_success_url(self, request, user):
244 # DEPRECATED # return ('registration_activation_complete', (), {})
247 # DEPRECATED #from portal.portalpage import PortalPage
248 # DEPRECATED #from plugins.wizard import Wizard
249 # DEPRECATED #from plugins.form import CreateForm
250 # DEPRECATED #from plugins.raw.raw import Raw # XXX
252 # DEPRECATED #from myslice.viewutils import the_user
254 # DEPRECATED #from django.template.loader import render_to_string
255 # DEPRECATED #from django.template import RequestContext
256 # DEPRECATED #from django.views import generic
258 # DEPRECATED #from django.contrib.formtools.wizard.views import NamedUrlSessionWizardView
259 # DEPRECATED ##from django.core.files.storage import FileSystemStorage
260 # DEPRECATED #from django.core.files.storage import default_storage
262 # DEPRECATED ##class MerlinWizard(NamedUrlSessionWizardView):
267 # DEPRECATED ## @classonlymethod
268 # DEPRECATED ## def as_view(cls, *args, **kwargs):
269 # DEPRECATED ## kwargs.update({
270 # DEPRECATED ## 'form_list': [
271 # DEPRECATED ## NameForm,
272 # DEPRECATED ## QuestForm,
273 # DEPRECATED ## ColorForm,
275 # DEPRECATED ## 'url_name': 'merlin_wizard'
277 # DEPRECATED ## return super(MerlinWizard, cls).as_view(*args, **kwargs)
279 # DEPRECATED #class UserRegisterWizardView(NamedUrlSessionWizardView):
280 # DEPRECATED ##class UserRegisterWizardView(LoginRequiredMixin, NamedUrlSessionWizardView):
281 # DEPRECATED # # Notice that I specify a file storage instance. If you don't specify this,
282 # DEPRECATED # # and you need to support FileField or ImageField in your forms, you'll get
283 # DEPRECATED # # errors from Django. This is something else I think could be handled by
284 # DEPRECATED # # the views better. Seems to me that it should just use whatever the
285 # DEPRECATED # # default/specified storage is for the rest of your project/application.
286 # DEPRECATED # file_storage = default_storage # FileSystemStorage()
287 # DEPRECATED # template_name = "register_user_wizard.html"
289 # DEPRECATED # def done(self, form_list, **kwargs):
290 # DEPRECATED # step1_form = form_list[0]
291 # DEPRECATED # step2_form = form_list[1]
293 # DEPRECATED # productext = self.create_product(product_form)
294 # DEPRECATED # shippings = self.create_shippings(productext, shipping_forms)
295 # DEPRECATED # images = self.create_images(productext, image_forms)
297 # DEPRECATED # if all([productext, shippings, images]):
298 # DEPRECATED # del self.request.session["wizard_product_wizard_view"]
300 # DEPRECATED # messages.success(self.request,
301 # DEPRECATED # _("Your product has been created."))
302 # DEPRECATED # return HttpResponseRedirect(self.get_success_url(productext))
304 # DEPRECATED # messages.error(self.request, _("Something went wrong creating your "
305 # DEPRECATED # "product. Please try again or contact support."))
306 # DEPRECATED # return HttpResponseRedirect(reverse("register_wizard"))
308 # DEPRECATED # #def get_form_kwargs(self, step):
309 # DEPRECATED # # if step == "product":
310 # DEPRECATED # # return {"user": self.request.user}
311 # DEPRECATED # # return {}
313 # DEPRECATED ## The portal should hook the slice and user creation pages
315 # DEPRECATED #def register_user(request):
317 # DEPRECATED # if request.method == 'POST':
318 # DEPRECATED # form = UserRegisterForm(request.POST) # Nous reprenons les données
319 # DEPRECATED # if form.is_valid():
320 # DEPRECATED # first_name = form.cleaned_data['first_name']
321 # DEPRECATED # last_name = form.cleaned_data['last_name']
322 # DEPRECATED # email = form.cleaned_data['email']
323 # DEPRECATED # password = form.cleaned_data['password']
324 # DEPRECATED # password2 = form.cleaned_data['password2']
325 # DEPRECATED # keypair = form.cleaned_data['keypair']
326 # DEPRECATED # ## Ici nous pouvons traiter les données du formulaire
327 # DEPRECATED # #sujet = form.cleaned_data['sujet']
328 # DEPRECATED # #message = form.cleaned_data['message']
329 # DEPRECATED # #envoyeur = form.cleaned_data['envoyeur']
330 # DEPRECATED # #renvoi = form.cleaned_data['renvoi']
331 # DEPRECATED # ## Nous pourrions ici envoyer l'e-mail grâce aux données que nous venons de récupérer
332 # DEPRECATED # #envoi = True
334 # DEPRECATED # form = UserRegisterForm()
335 # DEPRECATED # return render(request, 'register_user.html', locals())
337 # DEPRECATED #def index(request):
339 # DEPRECATED # WIZARD_TITLE = 'User registration'
340 # DEPRECATED # STEP1_TITLE = 'Enter your details'
341 # DEPRECATED # STEP2_TITLE = 'Select your institution'
342 # DEPRECATED # STEP3_TITLE = 'Authentication'
343 # DEPRECATED # STEP4_TITLE = 'Request a slice (optional)'
344 # DEPRECATED # STEP5_TITLE = 'Waiting for validation'
345 # DEPRECATED # STEP6_TITLE = 'Account validated'
347 # DEPRECATED # STEP0 = render_to_string('account_validated.html', context_instance=RequestContext(request))
348 # DEPRECATED # STEP2_HTML = """
349 # DEPRECATED # coucou
351 # DEPRECATED # STEP4 = """
354 # DEPRECATED # STEP5 = render_to_string('account_validated.html', context_instance=RequestContext(request))
356 # DEPRECATED # p = PortalPage(request)
358 # DEPRECATED # # This is redundant with the Wizard title
359 # DEPRECATED # p << "<h3>User registration</h3>"
361 # DEPRECATED # sons = []
362 # DEPRECATED # start_step = 1
364 # DEPRECATED # # STEP 1
365 # DEPRECATED # # If the user already exists (is logged), let's display a summary of his account details
366 # DEPRECATED # # Otherwise propose a form to fill in
367 # DEPRECATED # if the_user(request):
368 # DEPRECATED # # Fill a disabled form with user info
369 # DEPRECATED # # Please logout to register another user
370 # DEPRECATED # sons.append(Raw(page=p, title=STEP1_TITLE, togglable=False, html=STEP0))
371 # DEPRECATED # start_step += 1
373 # DEPRECATED # # We could pass a list of fields also, instead of retrieving them from metadata
374 # DEPRECATED # # Otherwise we need some heuristics to display nice forms
375 # DEPRECATED # # XXX Could we log the user in after the form is validated ?
376 # DEPRECATED # # XXX Explain the password is for XXX
377 # DEPRECATED # field_list = [{
378 # DEPRECATED # 'name' : 'First name',
379 # DEPRECATED # 'field' : 'firstname',
380 # DEPRECATED # 'type' : 'text',
381 # DEPRECATED # 'validate_rx' : '^[a-zA-Z -]+$',
382 # DEPRECATED # 'validate_err': 'Your first name must be comprised of letters only',
383 # DEPRECATED # 'description' : 'Enter your first name',
385 # DEPRECATED # 'name' : 'Last name',
386 # DEPRECATED # 'field' : 'lastname',
387 # DEPRECATED # 'type' : 'text',
388 # DEPRECATED # 'validate_rx' : '^[a-zA-Z -]+$',
389 # DEPRECATED # 'validate_err': 'Your last name must be comprised of letters only',
390 # DEPRECATED # 'description' : 'Enter your last name',
392 # DEPRECATED # 'name' : 'Email',
393 # DEPRECATED # 'field' : 'email',
394 # DEPRECATED # 'type' : 'text',
395 # DEPRECATED # 'description' : 'Enter your email address',
397 # DEPRECATED # 'name' : 'Password',
398 # DEPRECATED # 'field' : 'password',
399 # DEPRECATED # 'type' : 'password',
400 # DEPRECATED # 'description' : 'Enter your password',
402 # DEPRECATED # 'name' : 'Confirm password',
403 # DEPRECATED # 'field' : 'password2',
404 # DEPRECATED # 'type' : 'password',
405 # DEPRECATED # 'description' : 'Enter your password again',
407 # DEPRECATED # sons.append(CreateForm(page = p, title = STEP1_TITLE, togglable = False, object = 'local:user', fields = field_list))
409 # DEPRECATED # # STEP 2
410 # DEPRECATED # # If the user already exists (is logged), let's display a summary of its institution
411 # DEPRECATED # # Otherwise propose a form to fill in (we should base our selection on the email)
412 # DEPRECATED # if the_user(request):
413 # DEPRECATED # # Fill a disabled form with institution
414 # DEPRECATED # # Please logout to register another user
415 # DEPRECATED # sons.append(Raw(page=p, title=STEP2_TITLE, togglable=False, html="User created"))
416 # DEPRECATED # start_step += 1
418 # DEPRECATED # sons.append(CreateForm(page = p, title = STEP2_TITLE, togglable = False, object = 'slice')) #institution'))
420 # DEPRECATED # # STEP3
421 # DEPRECATED # # Please should your prefered authentication method
422 # DEPRECATED # # This step should allow the user to either choose the user or managed mode in MySlice
423 # DEPRECATED # sons.append(Raw(page = p, title = STEP3_TITLE, togglable = False, html = STEP2_HTML))
425 # DEPRECATED # # Step 4: Request a slice (optional)
426 # DEPRECATED # sons.append(CreateForm(page = p, title = STEP4_TITLE, togglable = False, object = 'slice'))
428 # DEPRECATED # # Step 5: Your request is waiting for validation
429 # DEPRECATED # # Periodic refresh
430 # DEPRECATED # sons.append(Raw(page = p, title = STEP5_TITLE, togglable = False, html = STEP4))
432 # DEPRECATED # # Step 6: Account validation = welcome for newly validated users
433 # DEPRECATED # # . delegation
434 # DEPRECATED # # . platforms
435 # DEPRECATED # # . slice
436 # DEPRECATED # # . pointers
437 # DEPRECATED # sons.append(Raw(page = p, title = STEP6_TITLE, togglable = False, html = STEP5))
439 # DEPRECATED # wizard = Wizard(
440 # DEPRECATED # page = p,
441 # DEPRECATED # title = WIZARD_TITLE,
442 # DEPRECATED # togglable = False,
443 # DEPRECATED # sons = sons,
444 # DEPRECATED # start_step = start_step,
447 # DEPRECATED # p << wizard.render(request) # in portal page if possible
449 # DEPRECATED # return p.render()
452 # DEPRECATED ## view for my_account
453 # DEPRECATED # class MyAccountView(TemplateView):
454 # DEPRECATED # template_name = "my_account.html"
456 # DEPRECATED # def from_process(self, request, **cleaned_data):
457 # DEPRECATED # #if request.method == 'POST':
458 # DEPRECATED # # if request.POST['submit_name']:
459 # DEPRECATED # if 'fname' in request.POST:
460 # DEPRECATED # messsag= "Got Name"
461 # DEPRECATED # #return render(request, 'portal/my_account.html')
462 # DEPRECATED # #response = HttpResponse("Here's the text of the Web page.")
463 # DEPRECATED # return HttpResponse(message)
465 # DEPRECATED # def get_context_data(self, **kwargs):
466 # DEPRECATED # page = Page(self.request)
467 # DEPRECATED # context = super(MyAccountView, self).get_context_data(**kwargs)
468 # DEPRECATED # context['person'] = self.request.user
469 # DEPRECATED # # XXX This is repeated in all pages
470 # DEPRECATED # # more general variables expected in the template
471 # DEPRECATED # context['title'] = 'User Profile Page'
472 # DEPRECATED # # the menu items on the top
473 # DEPRECATED # context['topmenu_items'] = topmenu_items('my_account', self.request)
474 # DEPRECATED # # so we can sho who is logged
475 # DEPRECATED # context['username'] = the_user(self.request)
476 # DEPRECATED # context.update(page.prelude_env())
477 # DEPRECATED # return context
481 # View for my_account form
482 def my_account(request):
483 return render(request, 'my_account.html', {
485 'topmenu_items': topmenu_items('My Account', request),
486 'username': the_user (request)
490 class PlatformsView(TemplateView):
491 template_name = "platforms.html"
493 def get_context_data(self, **kwargs):
494 page = Page(self.request)
496 network_query = Query().get('local:platform').filter_by('disabled', '==', '0').select('platform','platform_longname','gateway_type')
497 page.enqueue_query(network_query)
499 page.expose_js_metadata()
500 page.expose_queries()
501 networklist = Hazelnut(
504 domid = 'checkboxes',
505 # this is the query at the core of the slice list
506 query = network_query,
507 query_all = network_query,
509 datatables_options = {
510 # for now we turn off sorting on the checkboxes columns this way
511 # this of course should be automatic in hazelnut
512 'aoColumns' : [None, None, None, None, {'bSortable': False}],
513 'iDisplayLength' : 25,
514 'bLengthChange' : True,
518 # networklist = SimpleList(
522 # query = network_query,
525 context = super(PlatformsView, self).get_context_data(**kwargs)
526 context['person'] = self.request.user
527 context['networks'] = networklist.render(self.request)
529 # XXX This is repeated in all pages
530 # more general variables expected in the template
531 context['title'] = 'Platforms connected to MySlice'
532 # the menu items on the top
533 context['topmenu_items'] = topmenu_items('Platforms', self.request)
534 # so we can sho who is logged
535 context['username'] = the_user(self.request)
537 context.update(page.prelude_env())
541 #my_acc form value processing
542 def acc_process(request):
543 # getting the user_id from the session [now hardcoded]
544 get_user = PendingUser.objects.get(id='1') # here we will get the id/email from session e.g., person.email
545 if 'submit_name' in request.POST:
546 edited_first_name = request.POST['fname']
547 edited_last_name = request.POST['lname']
548 #email = 'test_email@gmail.com'
549 #password = 'test_pp'
550 #message = 'F_Name: %s L_name: %s dummy_pp: %s' % (first_name, last_name, password)
553 # insert into DB [needed for registration page]
554 #approach borrowed from register view
555 #new_user = PendingUser.objects.create_inactive_user(edited_first_name, edited_last_name, email, password, site)
556 #conventional approach
557 #b = PendingUser(first_name=edited_first_name, last_name=edited_last_name)
560 # select and update [will be used throughout this view]
561 # select the logged in user [for the moment hard coded]
562 #get_user = PendingUser.objects.get(id='1') # here we will get the id/email from session e.g., person.email
563 # update first and last name
564 get_user.first_name = edited_first_name
565 get_user.last_name = edited_last_name
568 return HttpResponse('Success: Name Updated!!')
569 elif 'submit_pass' in request.POST:
570 edited_password = request.POST['password']
571 # select the logged in user [for the moment hard coded]
572 #get_user = PendingUser.objects.get(id='1') # here we will get the id/email from session e.g., person.email
574 get_user.password = edited_password
576 return HttpResponse('Success: Password Changed!!')
577 elif 'generate' in request.POST:
579 #from M2Crypto import Rand, RSA, BIO
583 def blank_callback():
584 "Replace the default dashes"
588 Rand.rand_seed (os.urandom (KEY_LENGTH))
590 key = RSA.gen_key (KEY_LENGTH, 65537, blank_callback)
591 # Create memory buffers
592 pri_mem = BIO.MemoryBuffer()
593 pub_mem = BIO.MemoryBuffer()
594 # Save keys to buffers
595 key.save_key_bio(pri_mem, None)
596 key.save_pub_key_bio(pub_mem)
599 public_key = pub_mem.getvalue()
600 private_key = pri_mem.getvalue()
602 keypair = '{"user_public_key":"'+ public_key + '", "user_private_key":"'+ private_key + '"}'
603 keypair = re.sub("\r", "", keypair)
604 keypair = re.sub("\n", "\\n", keypair)
605 #keypair = keypair.rstrip('\r\n')
606 keypair = ''.join(keypair.split())
607 get_user.keypair = keypair
609 return HttpResponse('Success: New Keypair Generated! %s' % keypair)
611 elif 'upload_key' in request.POST:
612 up_file = request.FILES['pubkey']
613 file_content = up_file.read()
614 file_name = up_file.name
615 file_extension = os.path.splitext(file_name)[1]
616 allowed_extension = ['.pub','.txt']
617 if file_extension in allowed_extension and re.search(r'ssh-rsa',file_content):
618 file_content = '{"user_public_key":"'+ file_content +'"}'
619 file_content = re.sub("\r", "", file_content)
620 file_content = re.sub("\n", "\\n",file_content)
621 file_content = ''.join(file_content.split())
622 get_user.keypair = file_content
624 return HttpResponse('Success: Publickey uploaded! Old records overwritten')
626 return HttpResponse('Please upload a valid RSA public key [.txt or .pub].')
629 message = 'You submitted an empty form.'
630 return HttpResponse(message)
632 def register_4m_f4f(request):
634 if request.method == 'POST':
635 #get_email = PendingUser.objects.get(email)
636 reg_fname = request.POST.get('firstname', '')
637 reg_lname = request.POST.get('lastname', '')
638 reg_aff = request.POST.get('affiliation','')
639 reg_email = request.POST.get('email','').lower()
641 #POST value validation
642 if (re.search(r'^[\w+\s.@+-]+$', reg_fname)==None):
643 errors.append('First Name may contain only letters, numbers, spaces and @/./+/-/_ characters.')
644 #return HttpResponse("Only Letters, Numbers, - and _ allowd in First Name")
645 #return render(request, 'register_4m_f4f.html')
646 if (re.search(r'^[\w+\s.@+-]+$', reg_lname) == None):
647 errors.append('Last Name may contain only letters, numbers, spaces and @/./+/-/_ characters.')
648 #return HttpResponse("Only Letters, Numbers, - and _ is allowed in Last name")
649 #return render(request, 'register_4m_f4f.html')
650 if (re.search(r'^[\w+\s.@+-]+$', reg_aff) == None):
651 errors.append('Affiliation may contain only letters, numbers, spaces and @/./+/-/_ characters.')
652 #return HttpResponse("Only Letters, Numbers and _ is allowed in Affiliation")
653 #return render(request, 'register_4m_f4f.html')
654 if PendingUser.objects.filter(email__iexact=reg_email):
655 errors.append('Email already registered.Please provide a new email address.')
656 #return HttpResponse("Email Already exists")
657 #return render(request, 'register_4m_f4f.html')
658 if 'generate' in request.POST['question']:
660 #from M2Crypto import Rand, RSA, BIO
664 def blank_callback():
665 "Replace the default dashes"
669 Rand.rand_seed (os.urandom (KEY_LENGTH))
671 key = RSA.gen_key (KEY_LENGTH, 65537, blank_callback)
672 # Create memory buffers
673 pri_mem = BIO.MemoryBuffer()
674 pub_mem = BIO.MemoryBuffer()
675 # Save keys to buffers
676 key.save_key_bio(pri_mem, None)
677 key.save_pub_key_bio(pub_mem)
679 public_key = pub_mem.getvalue()
680 private_key = pri_mem.getvalue()
682 keypair = '{"user_public_key":"'+ public_key + '", "user_private_key":"'+ private_key + '"}'
683 keypair = re.sub("\r", "", keypair)
684 keypair = re.sub("\n", "\\n", keypair)
685 #keypair = keypair.rstrip('\r\n')
686 keypair = ''.join(keypair.split())
687 #return HttpResponse(keypair)
689 up_file = request.FILES['user_public_key']
690 file_content = up_file.read()
691 file_name = up_file.name
692 file_extension = os.path.splitext(file_name)[1]
693 allowed_extension = ['.pub','.txt']
694 if file_extension in allowed_extension and re.search(r'ssh-rsa',file_content):
695 keypair = '{"user_public_key":"'+ file_content +'"}'
696 keypair = re.sub("\r", "", keypair)
697 keypair = re.sub("\n", "\\n",keypair)
698 keypair = ''.join(keypair.split())
700 errors.append('Please upload a valid RSA public key [.txt or .pub].')
702 #b = PendingUser(first_name=reg_fname, last_name=reg_lname, affiliation=reg_aff,
703 # email=reg_email, password=request.POST['password'], keypair=keypair)
706 b = PendingUser(first_name=reg_fname, last_name=reg_lname, affiliation=reg_aff,
707 email=reg_email, password=request.POST['password'], keypair=keypair)
709 return render(request, 'user_register_complete.html')
711 return render(request, 'register_4m_f4f.html',{
712 'topmenu_items': topmenu_items('Register', request),
714 'firstname': request.POST.get('firstname', ''),
715 'lastname': request.POST.get('lastname', ''),
716 'affiliation': request.POST.get('affiliation', ''),
717 'email': request.POST.get('email', ''),
718 'password': request.POST.get('password', ''),
722 # view for contact form
723 def contact(request):
724 if request.method == 'POST': # If the form has been submitted...
725 form = ContactForm(request.POST) # A form bound to the POST data
726 if form.is_valid(): # All validation rules pass
727 # Process the data in form.cleaned_data
728 first_name = form.cleaned_data['first_name']
729 last_name = form.cleaned_data['last_name']
730 affiliation = form.cleaned_data['affiliation']
731 subject = form.cleaned_data['subject']
732 message = form.cleaned_data['message']
733 email = form.cleaned_data['email'] # email of the sender
734 cc_myself = form.cleaned_data['cc_myself']
736 recipients = ['yasin.upmc@gmail.com']
738 recipients.append(email)
740 from django.core.mail import send_mail
741 send_mail("Onelab user submitted a query ", [first_name,last_name,affiliation,subject,message], email, recipients)
742 return render(request,'contact_sent.html') # Redirect after POST
744 form = ContactForm() # An unbound form
746 return render(request, 'contact.html', {
748 'topmenu_items': topmenu_items('Contact Us', request),
749 'username': the_user (request)
754 def slice_request(request):
755 if request.method == 'POST': # If the form has been submitted...
756 form = SliceRequestForm(request.POST) # A form bound to the POST data
757 if form.is_valid(): # All validation rules pass
758 # Process the data in form.cleaned_data
759 slice_name = form.cleaned_data['slice_name']
760 number_of_nodes = form.cleaned_data['number_of_nodes']
761 type_of_nodes = form.cleaned_data['type_of_nodes']
762 purpose = form.cleaned_data['purpose']
763 email = form.cleaned_data['email'] # email of the sender
764 cc_myself = form.cleaned_data['cc_myself']
766 recipients = ['yasin.upmc@gmail.com','jordan.auge@lip6.fr']
768 recipients.append(email)
770 from django.core.mail import send_mail
771 send_mail("Onelab New Slice request form submitted", [slice_name,number_of_nodes,type_of_nodes,purpose], email, recipients)
772 return render(request,'slicereq_recvd.html') # Redirect after POST
774 form = SliceRequestForm() # An unbound form
777 # template_env['form'] = form
778 # template_env['topmenu_items'] = topmenu_items('Request a slice', request)
779 # template_env['unfold1_main'] = render(request, 'slice_request_.html', {
782 # from django.shortcuts import render_to_response
783 # from django.template import RequestContext
784 # return render_to_response ('view-unfold1.html',template_env,
785 # context_instance=RequestContext(request))
787 return render(request, 'slice_request.html', {
789 'topmenu_items': topmenu_items('Request a slice', request),
790 'username': the_user (request)
794 class PresViewView(TemplateView):
795 template_name = "view-unfold1.html"
797 def get_context_data(self, **kwargs):
799 page = Page(self.request)
801 pres_view = PresView(page = page)
803 context = super(PresViewView, self).get_context_data(**kwargs)
805 #context['ALL_STATIC'] = "all_static"
806 context['unfold1_main'] = pres_view.render(self.request)
808 # XXX This is repeated in all pages
809 # more general variables expected in the template
810 context['title'] = 'Test view that combines various plugins'
811 # the menu items on the top
812 context['topmenu_items'] = topmenu_items('PresView', self.request)
813 # so we can sho who is logged
814 context['username'] = the_user(self.request)
816 prelude_env = page.prelude_env()
817 context.update(prelude_env)
821 def json_me(config_file,type):
823 for ligne in config_file:
824 if not ligne.startswith('#'):
825 args = ligne.split(';')
826 json_answer += str('{ "name": "' + args[0] + '" ,"id":"' + args[1] + '" ,"descriptif":"' + args[2]+'"')
828 json_answer += str(',"contraints":')
830 json_answer += str('""')
832 json_answer += str(args[3])
833 json_answer += str('},')
834 return json_answer[:-1]
837 DIR = '/var/myslice/'
838 STATIC = '%s/config_method_static' % DIR
839 DYNAMIC = '%s/config_method_dynamic' % DIR
840 ANIMATION = '%s/config_method_animation' % DIR
842 def pres_view_methods(request, type):
846 elif type =="static":
847 config = open(STATIC, "r")
848 json_answer = str('{ "options": [')
849 json_answer += str(json_me(config,"static"))
850 json_answer += str('] }')
852 elif type =="dynamic":
853 config = open(DYNAMIC, "r")
854 json_answer = str('{ "options": [')
855 json_answer += str(json_me(config,"dynamic"))
856 json_answer += str('] }')
858 elif type =="animation":
859 config = open(ANIMATION, "r")
860 json_answer = str('{ "options": [')
861 json_answer += str(json_me(config,"animation"))
862 json_answer += str('] }')
865 config = open(STATIC, "r")
866 json_answer = str('{ "static": [')
867 json_answer += str(json_me(config,"static"))
868 json_answer += str('],')
869 json_answer += str('"dynamic": [')
871 config = open(DYNAMIC, "r")
872 json_answer += str(json_me(config,"dynamic"))
873 json_answer += str('],')
874 json_answer += str('"animation": [')
876 config = open(ANIMATION, "r")
877 json_answer += str(json_me(config,"animation"))
878 json_answer += str('] }')
882 return HttpResponse (json_answer, mimetype="application/json")
884 def pres_view_animation(request, constraints, id):
886 # sites crees depuis 2008
887 # static.py?contraints=']date_created':1262325600&id='name_id"'
889 # method = request.getvalue('method') #ex : GetSites
890 #constraints = "']date_created':1262325600"
896 # method = 'GetSites'#request.getvalue('method') #ex : GetSites
897 # constraints = {}#request.getvalue('constraints') // nul = {}
898 # response_field = "'site_id','name','date_created'"#request.getvalue('response_field')
900 config_file = open(ANIMATION, "r")
901 for ligne in config_file:
902 if not ligne.startswith('#'):
903 ligne = ligne.split('\n')
904 first = ligne[0].split(';')
905 if (str(first[1]) == str(id)):
909 #Les print_method, print_option sont definis par le client (js)
910 #Les animations acceptent que les connexions anonymous
911 # args = "postmsg;animation;;;anonymous;https://www.planet-lab.eu/PLCAPI/;"
912 args = ";;"+str(save[8])+";"+str(save[9])+";anonymous;"+str(save[5])+";"+str(save[6])+";{"+str(constraints)+"};"+str(save[7])+";"
915 #Creation d'un objet event
919 "print_options": event.print_options,
920 "print_method": event.print_method,
921 "message": event.data
926 json_answer = json.dumps(cmd)
927 return HttpResponse (json_answer, mimetype="application/json")
929 def pres_view_static(request, constraints, id):
930 #constraints = "']date_created':1262325600"
933 # method = 'GetSites'#request.getvalue('method') #ex : GetSites
934 # constraints = {}#request.getvalue('constraints') // nul = {}
935 # response_field = "'site_id','name','date_created'"#request.getvalue('response_field')
937 config_file = open(STATIC, "r")
938 for ligne in config_file:
939 if not ligne.startswith('#'):
940 ligne = ligne.split('\n')
941 first = ligne[0].split(';')
942 if (str(first[1]) == str(id)):
946 #Les print_method, print_option sont definis par le client (js)
947 #Les animations acceptent que les connexions anonymous
948 # args = "postmsg;animation;;;anonymous;https://www.planet-lab.eu/PLCAPI/;"
949 args = ";;"+str(save[8])+";"+str(save[9])+";anonymous;"+str(save[5])+";"+str(save[6])+";{"+str(constraints)+"};"+str(save[7])+";"
952 #Creation d'un objet event
956 "print_options": event.print_options,
957 "print_method": event.print_method,
958 "message": event.data
963 json_answer = json.dumps(cmd)
964 return HttpResponse (json_answer, mimetype="application/json")