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 plugins.lists.simplelist import SimpleList
31 from portal import signals
32 from portal.forms import UserRegisterForm, SliceRequestForm, ContactForm
33 from portal.util import RegistrationView, ActivationView
34 from portal.models import PendingUser, PendingSlice
35 from manifold.core.query import Query
36 from unfold.page import Page
37 from myslice.viewutils import topmenu_items, the_user
38 from django.http import HttpResponseRedirect
40 class DashboardView(TemplateView):
41 template_name = "dashboard.html"
43 def get_context_data(self, **kwargs):
44 user_hrn = 'ple.upmc.jordan_auge'
45 #user_hrn = 'iotlab.auge'
47 #messages.info(self.request, 'You have logged in')
48 page = Page(self.request)
51 #slice_query = Query().get('slice').filter_by('user.user_hrn', 'contains', user_hrn).select('slice_hrn')
52 slice_query = Query().get('user').filter_by('user_hrn', '==', user_hrn).select('user_hrn', 'slice.slice_hrn')
53 auth_query = Query().get('network').select('network_hrn')
54 page.enqueue_query(slice_query)
55 page.enqueue_query(auth_query)
59 slicelist = SimpleList(
62 key = 'slice.slice_hrn',
66 authlist = SimpleList(
73 context = super(DashboardView, self).get_context_data(**kwargs)
74 context['person'] = self.request.user
75 context['networks'] = authlist.render(self.request)
76 context['slices'] = slicelist.render(self.request)
78 # XXX This is repeated in all pages
79 # more general variables expected in the template
80 context['title'] = 'Test view that combines various plugins'
81 # the menu items on the top
82 context['topmenu_items'] = topmenu_items('Dashboard', self.request)
83 # so we can sho who is logged
84 context['username'] = the_user(self.request)
86 context.update(page.prelude_env())
90 class UserRegisterView(RegistrationView):
92 A registration backend which follows a simple workflow:
94 1. User signs up, inactive account is created.
96 2. Email is sent to user with activation link.
98 3. User clicks activation link, account is now active.
100 Using this backend requires that
102 * ``registration`` be listed in the ``INSTALLED_APPS`` setting
103 (since this backend makes use of models defined in this
106 * The setting ``ACCOUNT_ACTIVATION_DAYS`` be supplied, specifying
107 (as an integer) the number of days from registration during
108 which a user may activate their account (after that period
109 expires, activation will be disallowed).
111 * The creation of the templates
112 ``registration/activation_email_subject.txt`` and
113 ``registration/activation_email.txt``, which will be used for
114 the activation email. See the notes for this backends
115 ``register`` method for details regarding these templates.
117 Additionally, registration can be temporarily closed by adding the
118 setting ``REGISTRATION_OPEN`` and setting it to
119 ``False``. Omitting this setting, or setting it to ``True``, will
120 be interpreted as meaning that registration is currently open and
123 Internally, this is accomplished via storing an activation key in
124 an instance of ``registration.models.RegistrationProfile``. See
125 that model and its custom manager for full documentation of its
126 fields and supported operations.
129 form_class = UserRegisterForm
131 def register(self, request, **cleaned_data):
133 Given a username, email address and password, register a new
134 user account, which will initially be inactive.
136 Along with the new ``User`` object, a new
137 ``registration.models.RegistrationProfile`` will be created,
138 tied to that ``User``, containing the activation key which
139 will be used for this account.
141 An email will be sent to the supplied email address; this
142 email should contain an activation link. The email will be
143 rendered using two templates. See the documentation for
144 ``RegistrationProfile.send_activation_email()`` for
145 information about these templates and the contexts provided to
148 After the ``User`` and ``RegistrationProfile`` are created and
149 the activation email is sent, the signal
150 ``registration.signals.user_registered`` will be sent, with
151 the new ``User`` as the keyword argument ``user`` and the
152 class of this backend as the sender.
155 first_name = cleaned_data['first_name']
156 last_name = cleaned_data['last_name']
157 affiliation= cleaned_data['affiliation']
158 email = cleaned_data['email']
159 password = cleaned_data['password1']
161 #password2 = cleaned_data['password2']
162 keypair = cleaned_data['keypair']
164 #if Site._meta.installed:
165 # site = Site.objects.get_current()
167 # site = RequestSite(request)
170 new_user = PendingUser.objects.create_inactive_user(first_name, last_name, email, password, site)
171 signals.user_registered.send(sender=self.__class__,
176 def get_context_data(self, **kwargs):
177 context = super(UserRegisterView, self).get_context_data(**kwargs)
178 context['topmenu_items'] = topmenu_items('Register', self.request)
179 context['username'] = the_user (self.request)
182 def registration_allowed(self, request):
184 Indicate whether account registration is currently permitted,
185 based on the value of the setting ``REGISTRATION_OPEN``. This
186 is determined as follows:
188 * If ``REGISTRATION_OPEN`` is not specified in settings, or is
189 set to ``True``, registration is permitted.
191 * If ``REGISTRATION_OPEN`` is both specified and set to
192 ``False``, registration is not permitted.
195 return getattr(settings, 'REGISTRATION_OPEN', True)
197 def get_success_url(self, request, user):
199 Return the name of the URL to redirect to after successful
203 return ('user_register_complete', (), {})
206 class UserValidateView(ActivationView):
207 def activate(self, request, activation_key):
209 Given an an activation key, look up and activate the user
210 account corresponding to that key (if possible).
212 After successful activation, the signal
213 ``registration.signals.user_activated`` will be sent, with the
214 newly activated ``User`` as the keyword argument ``user`` and
215 the class of this backend as the sender.
218 activated_user = RegistrationProfile.objects.activate_user(activation_key)
220 signals.user_activated.send(sender=self.__class__,
223 return activated_user
225 def get_success_url(self, request, user):
226 return ('registration_activation_complete', (), {})
229 # DEPRECATED #from portal.portalpage import PortalPage
230 # DEPRECATED #from plugins.wizard import Wizard
231 # DEPRECATED #from plugins.form import CreateForm
232 # DEPRECATED #from plugins.raw.raw import Raw # XXX
234 # DEPRECATED #from myslice.viewutils import the_user
236 # DEPRECATED #from django.template.loader import render_to_string
237 # DEPRECATED #from django.template import RequestContext
238 # DEPRECATED #from django.views import generic
240 # DEPRECATED #from django.contrib.formtools.wizard.views import NamedUrlSessionWizardView
241 # DEPRECATED ##from django.core.files.storage import FileSystemStorage
242 # DEPRECATED #from django.core.files.storage import default_storage
244 # DEPRECATED ##class MerlinWizard(NamedUrlSessionWizardView):
249 # DEPRECATED ## @classonlymethod
250 # DEPRECATED ## def as_view(cls, *args, **kwargs):
251 # DEPRECATED ## kwargs.update({
252 # DEPRECATED ## 'form_list': [
253 # DEPRECATED ## NameForm,
254 # DEPRECATED ## QuestForm,
255 # DEPRECATED ## ColorForm,
257 # DEPRECATED ## 'url_name': 'merlin_wizard'
259 # DEPRECATED ## return super(MerlinWizard, cls).as_view(*args, **kwargs)
261 # DEPRECATED #class UserRegisterWizardView(NamedUrlSessionWizardView):
262 # DEPRECATED ##class UserRegisterWizardView(LoginRequiredMixin, NamedUrlSessionWizardView):
263 # DEPRECATED # # Notice that I specify a file storage instance. If you don't specify this,
264 # DEPRECATED # # and you need to support FileField or ImageField in your forms, you'll get
265 # DEPRECATED # # errors from Django. This is something else I think could be handled by
266 # DEPRECATED # # the views better. Seems to me that it should just use whatever the
267 # DEPRECATED # # default/specified storage is for the rest of your project/application.
268 # DEPRECATED # file_storage = default_storage # FileSystemStorage()
269 # DEPRECATED # template_name = "register_user_wizard.html"
271 # DEPRECATED # def done(self, form_list, **kwargs):
272 # DEPRECATED # step1_form = form_list[0]
273 # DEPRECATED # step2_form = form_list[1]
275 # DEPRECATED # productext = self.create_product(product_form)
276 # DEPRECATED # shippings = self.create_shippings(productext, shipping_forms)
277 # DEPRECATED # images = self.create_images(productext, image_forms)
279 # DEPRECATED # if all([productext, shippings, images]):
280 # DEPRECATED # del self.request.session["wizard_product_wizard_view"]
282 # DEPRECATED # messages.success(self.request,
283 # DEPRECATED # _("Your product has been created."))
284 # DEPRECATED # return HttpResponseRedirect(self.get_success_url(productext))
286 # DEPRECATED # messages.error(self.request, _("Something went wrong creating your "
287 # DEPRECATED # "product. Please try again or contact support."))
288 # DEPRECATED # return HttpResponseRedirect(reverse("register_wizard"))
290 # DEPRECATED # #def get_form_kwargs(self, step):
291 # DEPRECATED # # if step == "product":
292 # DEPRECATED # # return {"user": self.request.user}
293 # DEPRECATED # # return {}
295 # DEPRECATED ## The portal should hook the slice and user creation pages
297 # DEPRECATED #def register_user(request):
299 # DEPRECATED # if request.method == 'POST':
300 # DEPRECATED # form = UserRegisterForm(request.POST) # Nous reprenons les données
301 # DEPRECATED # if form.is_valid():
302 # DEPRECATED # first_name = form.cleaned_data['first_name']
303 # DEPRECATED # last_name = form.cleaned_data['last_name']
304 # DEPRECATED # email = form.cleaned_data['email']
305 # DEPRECATED # password = form.cleaned_data['password']
306 # DEPRECATED # password2 = form.cleaned_data['password2']
307 # DEPRECATED # keypair = form.cleaned_data['keypair']
308 # DEPRECATED # ## Ici nous pouvons traiter les données du formulaire
309 # DEPRECATED # #sujet = form.cleaned_data['sujet']
310 # DEPRECATED # #message = form.cleaned_data['message']
311 # DEPRECATED # #envoyeur = form.cleaned_data['envoyeur']
312 # DEPRECATED # #renvoi = form.cleaned_data['renvoi']
313 # DEPRECATED # ## Nous pourrions ici envoyer l'e-mail grâce aux données que nous venons de récupérer
314 # DEPRECATED # #envoi = True
316 # DEPRECATED # form = UserRegisterForm()
317 # DEPRECATED # return render(request, 'register_user.html', locals())
319 # DEPRECATED #def index(request):
321 # DEPRECATED # WIZARD_TITLE = 'User registration'
322 # DEPRECATED # STEP1_TITLE = 'Enter your details'
323 # DEPRECATED # STEP2_TITLE = 'Select your institution'
324 # DEPRECATED # STEP3_TITLE = 'Authentication'
325 # DEPRECATED # STEP4_TITLE = 'Request a slice (optional)'
326 # DEPRECATED # STEP5_TITLE = 'Waiting for validation'
327 # DEPRECATED # STEP6_TITLE = 'Account validated'
329 # DEPRECATED # STEP0 = render_to_string('account_validated.html', context_instance=RequestContext(request))
330 # DEPRECATED # STEP2_HTML = """
331 # DEPRECATED # coucou
333 # DEPRECATED # STEP4 = """
336 # DEPRECATED # STEP5 = render_to_string('account_validated.html', context_instance=RequestContext(request))
338 # DEPRECATED # p = PortalPage(request)
340 # DEPRECATED # # This is redundant with the Wizard title
341 # DEPRECATED # p << "<h3>User registration</h3>"
343 # DEPRECATED # sons = []
344 # DEPRECATED # start_step = 1
346 # DEPRECATED # # STEP 1
347 # DEPRECATED # # If the user already exists (is logged), let's display a summary of his account details
348 # DEPRECATED # # Otherwise propose a form to fill in
349 # DEPRECATED # if the_user(request):
350 # DEPRECATED # # Fill a disabled form with user info
351 # DEPRECATED # # Please logout to register another user
352 # DEPRECATED # sons.append(Raw(page=p, title=STEP1_TITLE, togglable=False, html=STEP0))
353 # DEPRECATED # start_step += 1
355 # DEPRECATED # # We could pass a list of fields also, instead of retrieving them from metadata
356 # DEPRECATED # # Otherwise we need some heuristics to display nice forms
357 # DEPRECATED # # XXX Could we log the user in after the form is validated ?
358 # DEPRECATED # # XXX Explain the password is for XXX
359 # DEPRECATED # field_list = [{
360 # DEPRECATED # 'name' : 'First name',
361 # DEPRECATED # 'field' : 'firstname',
362 # DEPRECATED # 'type' : 'text',
363 # DEPRECATED # 'validate_rx' : '^[a-zA-Z -]+$',
364 # DEPRECATED # 'validate_err': 'Your first name must be comprised of letters only',
365 # DEPRECATED # 'description' : 'Enter your first name',
367 # DEPRECATED # 'name' : 'Last name',
368 # DEPRECATED # 'field' : 'lastname',
369 # DEPRECATED # 'type' : 'text',
370 # DEPRECATED # 'validate_rx' : '^[a-zA-Z -]+$',
371 # DEPRECATED # 'validate_err': 'Your last name must be comprised of letters only',
372 # DEPRECATED # 'description' : 'Enter your last name',
374 # DEPRECATED # 'name' : 'Email',
375 # DEPRECATED # 'field' : 'email',
376 # DEPRECATED # 'type' : 'text',
377 # DEPRECATED # 'description' : 'Enter your email address',
379 # DEPRECATED # 'name' : 'Password',
380 # DEPRECATED # 'field' : 'password',
381 # DEPRECATED # 'type' : 'password',
382 # DEPRECATED # 'description' : 'Enter your password',
384 # DEPRECATED # 'name' : 'Confirm password',
385 # DEPRECATED # 'field' : 'password2',
386 # DEPRECATED # 'type' : 'password',
387 # DEPRECATED # 'description' : 'Enter your password again',
389 # DEPRECATED # sons.append(CreateForm(page = p, title = STEP1_TITLE, togglable = False, object = 'local:user', fields = field_list))
391 # DEPRECATED # # STEP 2
392 # DEPRECATED # # If the user already exists (is logged), let's display a summary of its institution
393 # DEPRECATED # # Otherwise propose a form to fill in (we should base our selection on the email)
394 # DEPRECATED # if the_user(request):
395 # DEPRECATED # # Fill a disabled form with institution
396 # DEPRECATED # # Please logout to register another user
397 # DEPRECATED # sons.append(Raw(page=p, title=STEP2_TITLE, togglable=False, html="User created"))
398 # DEPRECATED # start_step += 1
400 # DEPRECATED # sons.append(CreateForm(page = p, title = STEP2_TITLE, togglable = False, object = 'slice')) #institution'))
402 # DEPRECATED # # STEP3
403 # DEPRECATED # # Please should your prefered authentication method
404 # DEPRECATED # # This step should allow the user to either choose the user or managed mode in MySlice
405 # DEPRECATED # sons.append(Raw(page = p, title = STEP3_TITLE, togglable = False, html = STEP2_HTML))
407 # DEPRECATED # # Step 4: Request a slice (optional)
408 # DEPRECATED # sons.append(CreateForm(page = p, title = STEP4_TITLE, togglable = False, object = 'slice'))
410 # DEPRECATED # # Step 5: Your request is waiting for validation
411 # DEPRECATED # # Periodic refresh
412 # DEPRECATED # sons.append(Raw(page = p, title = STEP5_TITLE, togglable = False, html = STEP4))
414 # DEPRECATED # # Step 6: Account validation = welcome for newly validated users
415 # DEPRECATED # # . delegation
416 # DEPRECATED # # . platforms
417 # DEPRECATED # # . slice
418 # DEPRECATED # # . pointers
419 # DEPRECATED # sons.append(Raw(page = p, title = STEP6_TITLE, togglable = False, html = STEP5))
421 # DEPRECATED # wizard = Wizard(
422 # DEPRECATED # page = p,
423 # DEPRECATED # title = WIZARD_TITLE,
424 # DEPRECATED # togglable = False,
425 # DEPRECATED # sons = sons,
426 # DEPRECATED # start_step = start_step,
429 # DEPRECATED # p << wizard.render(request) # in portal page if possible
431 # DEPRECATED # return p.render()
434 # view for contact form
435 def contact(request):
436 if request.method == 'POST': # If the form has been submitted...
437 form = ContactForm(request.POST) # A form bound to the POST data
438 if form.is_valid(): # All validation rules pass
439 # Process the data in form.cleaned_data
440 first_name = form.cleaned_data['first_name']
441 last_name = form.cleaned_data['last_name']
442 affiliation = form.cleaned_data['affiliation']
443 subject = form.cleaned_data['subject']
444 message = form.cleaned_data['message']
445 email = form.cleaned_data['email'] # email of the sender
446 cc_myself = form.cleaned_data['cc_myself']
448 recipients = ['yasin.upmc@gmail.com']
450 recipients.append(email)
452 from django.core.mail import send_mail
453 send_mail("Onelab user submitted a query ", [first_name,last_name,affiliation,subject,message], email, recipients)
454 return render(request,'contact_sent.html') # Redirect after POST
456 form = ContactForm() # An unbound form
458 return render(request, 'contact.html', {
463 def slice_request(request):
464 if request.method == 'POST': # If the form has been submitted...
465 form = SliceRequestForm(request.POST) # A form bound to the POST data
466 if form.is_valid(): # All validation rules pass
467 # Process the data in form.cleaned_data
468 slice_name = form.cleaned_data['slice_name']
469 number_of_nodes = form.cleaned_data['number_of_nodes']
470 type_of_nodes = form.cleaned_data['type_of_nodes']
471 purpose = form.cleaned_data['purpose']
472 email = form.cleaned_data['email'] # email of the sender
473 cc_myself = form.cleaned_data['cc_myself']
475 recipients = ['yasin.upmc@gmail.com','jordan.auge@lip6.fr']
477 recipients.append(email)
479 from django.core.mail import send_mail
480 send_mail("Onelab New Slice request form submitted", [slice_name,number_of_nodes,type_of_nodes,purpose], email, recipients)
481 return render(request,'slicereq_recvd.html') # Redirect after POST
483 form = SliceRequestForm() # An unbound form
486 # template_env['form'] = form
487 # template_env['topmenu_items'] = topmenu_items('Request a slice', request)
488 # template_env['unfold1_main'] = render(request, 'slice_request_.html', {
491 # from django.shortcuts import render_to_response
492 # from django.template import RequestContext
493 # return render_to_response ('view-unfold1.html',template_env,
494 # context_instance=RequestContext(request))
496 return render(request, 'slice_request.html', {
498 'topmenu_items': topmenu_items('Request a slice', request),
499 'username': the_user (request)