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'
46 messages.info(self.request, 'You have logged in')
49 page = Page(self.request)
52 #slice_query = Query().get('slice').filter_by('user.user_hrn', 'contains', user_hrn).select('slice_hrn')
53 slice_query = Query().get('user').filter_by('user_hrn', '==', user_hrn).select('slice.slice_hrn')
54 auth_query = Query().get('network').select('network_hrn')
55 page.enqueue_query(slice_query)
56 page.enqueue_query(auth_query)
60 slicelist = SimpleList(
63 key = 'slice.slice_hrn',
67 authlist = SimpleList(
74 context = super(DashboardView, self).get_context_data(**kwargs)
75 context['person'] = self.request.user
76 context['networks'] = authlist.render(self.request)
77 context['slices'] = slicelist.render(self.request)
79 # XXX This is repeated in all pages
80 # more general variables expected in the template
81 context['title'] = 'Test view that combines various plugins'
82 # the menu items on the top
83 context['topmenu_items'] = topmenu_items('dashboard', self.request)
84 # so we can sho who is logged
85 context['username'] = the_user(self.request)
87 context.update(page.prelude_env())
91 class UserRegisterView(RegistrationView):
93 A registration backend which follows a simple workflow:
95 1. User signs up, inactive account is created.
97 2. Email is sent to user with activation link.
99 3. User clicks activation link, account is now active.
101 Using this backend requires that
103 * ``registration`` be listed in the ``INSTALLED_APPS`` setting
104 (since this backend makes use of models defined in this
107 * The setting ``ACCOUNT_ACTIVATION_DAYS`` be supplied, specifying
108 (as an integer) the number of days from registration during
109 which a user may activate their account (after that period
110 expires, activation will be disallowed).
112 * The creation of the templates
113 ``registration/activation_email_subject.txt`` and
114 ``registration/activation_email.txt``, which will be used for
115 the activation email. See the notes for this backends
116 ``register`` method for details regarding these templates.
118 Additionally, registration can be temporarily closed by adding the
119 setting ``REGISTRATION_OPEN`` and setting it to
120 ``False``. Omitting this setting, or setting it to ``True``, will
121 be interpreted as meaning that registration is currently open and
124 Internally, this is accomplished via storing an activation key in
125 an instance of ``registration.models.RegistrationProfile``. See
126 that model and its custom manager for full documentation of its
127 fields and supported operations.
130 form_class = UserRegisterForm
132 def register(self, request, **cleaned_data):
134 Given a username, email address and password, register a new
135 user account, which will initially be inactive.
137 Along with the new ``User`` object, a new
138 ``registration.models.RegistrationProfile`` will be created,
139 tied to that ``User``, containing the activation key which
140 will be used for this account.
142 An email will be sent to the supplied email address; this
143 email should contain an activation link. The email will be
144 rendered using two templates. See the documentation for
145 ``RegistrationProfile.send_activation_email()`` for
146 information about these templates and the contexts provided to
149 After the ``User`` and ``RegistrationProfile`` are created and
150 the activation email is sent, the signal
151 ``registration.signals.user_registered`` will be sent, with
152 the new ``User`` as the keyword argument ``user`` and the
153 class of this backend as the sender.
156 first_name = cleaned_data['first_name']
157 last_name = cleaned_data['last_name']
158 affiliation= cleaned_data['affiliation']
159 email = cleaned_data['email']
160 password = cleaned_data['password1']
162 #password2 = cleaned_data['password2']
163 keypair = cleaned_data['keypair']
165 #if Site._meta.installed:
166 # site = Site.objects.get_current()
168 # site = RequestSite(request)
171 new_user = PendingUser.objects.create_inactive_user(first_name, last_name, email, password, site)
172 signals.user_registered.send(sender=self.__class__,
177 def registration_allowed(self, request):
179 Indicate whether account registration is currently permitted,
180 based on the value of the setting ``REGISTRATION_OPEN``. This
181 is determined as follows:
183 * If ``REGISTRATION_OPEN`` is not specified in settings, or is
184 set to ``True``, registration is permitted.
186 * If ``REGISTRATION_OPEN`` is both specified and set to
187 ``False``, registration is not permitted.
190 return getattr(settings, 'REGISTRATION_OPEN', True)
192 def get_success_url(self, request, user):
194 Return the name of the URL to redirect to after successful
198 return ('user_register_complete', (), {})
201 class UserValidateView(ActivationView):
202 def activate(self, request, activation_key):
204 Given an an activation key, look up and activate the user
205 account corresponding to that key (if possible).
207 After successful activation, the signal
208 ``registration.signals.user_activated`` will be sent, with the
209 newly activated ``User`` as the keyword argument ``user`` and
210 the class of this backend as the sender.
213 activated_user = RegistrationProfile.objects.activate_user(activation_key)
215 signals.user_activated.send(sender=self.__class__,
218 return activated_user
220 def get_success_url(self, request, user):
221 return ('registration_activation_complete', (), {})
224 # DEPRECATED #from portal.portalpage import PortalPage
225 # DEPRECATED #from plugins.wizard import Wizard
226 # DEPRECATED #from plugins.form import CreateForm
227 # DEPRECATED #from plugins.raw.raw import Raw # XXX
229 # DEPRECATED #from myslice.viewutils import the_user
231 # DEPRECATED #from django.template.loader import render_to_string
232 # DEPRECATED #from django.template import RequestContext
233 # DEPRECATED #from django.views import generic
235 # DEPRECATED #from django.contrib.formtools.wizard.views import NamedUrlSessionWizardView
236 # DEPRECATED ##from django.core.files.storage import FileSystemStorage
237 # DEPRECATED #from django.core.files.storage import default_storage
239 # DEPRECATED ##class MerlinWizard(NamedUrlSessionWizardView):
244 # DEPRECATED ## @classonlymethod
245 # DEPRECATED ## def as_view(cls, *args, **kwargs):
246 # DEPRECATED ## kwargs.update({
247 # DEPRECATED ## 'form_list': [
248 # DEPRECATED ## NameForm,
249 # DEPRECATED ## QuestForm,
250 # DEPRECATED ## ColorForm,
252 # DEPRECATED ## 'url_name': 'merlin_wizard'
254 # DEPRECATED ## return super(MerlinWizard, cls).as_view(*args, **kwargs)
256 # DEPRECATED #class UserRegisterWizardView(NamedUrlSessionWizardView):
257 # DEPRECATED ##class UserRegisterWizardView(LoginRequiredMixin, NamedUrlSessionWizardView):
258 # DEPRECATED # # Notice that I specify a file storage instance. If you don't specify this,
259 # DEPRECATED # # and you need to support FileField or ImageField in your forms, you'll get
260 # DEPRECATED # # errors from Django. This is something else I think could be handled by
261 # DEPRECATED # # the views better. Seems to me that it should just use whatever the
262 # DEPRECATED # # default/specified storage is for the rest of your project/application.
263 # DEPRECATED # file_storage = default_storage # FileSystemStorage()
264 # DEPRECATED # template_name = "register_user_wizard.html"
266 # DEPRECATED # def done(self, form_list, **kwargs):
267 # DEPRECATED # step1_form = form_list[0]
268 # DEPRECATED # step2_form = form_list[1]
270 # DEPRECATED # productext = self.create_product(product_form)
271 # DEPRECATED # shippings = self.create_shippings(productext, shipping_forms)
272 # DEPRECATED # images = self.create_images(productext, image_forms)
274 # DEPRECATED # if all([productext, shippings, images]):
275 # DEPRECATED # del self.request.session["wizard_product_wizard_view"]
277 # DEPRECATED # messages.success(self.request,
278 # DEPRECATED # _("Your product has been created."))
279 # DEPRECATED # return HttpResponseRedirect(self.get_success_url(productext))
281 # DEPRECATED # messages.error(self.request, _("Something went wrong creating your "
282 # DEPRECATED # "product. Please try again or contact support."))
283 # DEPRECATED # return HttpResponseRedirect(reverse("register_wizard"))
285 # DEPRECATED # #def get_form_kwargs(self, step):
286 # DEPRECATED # # if step == "product":
287 # DEPRECATED # # return {"user": self.request.user}
288 # DEPRECATED # # return {}
290 # DEPRECATED ## The portal should hook the slice and user creation pages
292 # DEPRECATED #def register_user(request):
294 # DEPRECATED # if request.method == 'POST':
295 # DEPRECATED # form = UserRegisterForm(request.POST) # Nous reprenons les données
296 # DEPRECATED # if form.is_valid():
297 # DEPRECATED # first_name = form.cleaned_data['first_name']
298 # DEPRECATED # last_name = form.cleaned_data['last_name']
299 # DEPRECATED # email = form.cleaned_data['email']
300 # DEPRECATED # password = form.cleaned_data['password']
301 # DEPRECATED # password2 = form.cleaned_data['password2']
302 # DEPRECATED # keypair = form.cleaned_data['keypair']
303 # DEPRECATED # ## Ici nous pouvons traiter les données du formulaire
304 # DEPRECATED # #sujet = form.cleaned_data['sujet']
305 # DEPRECATED # #message = form.cleaned_data['message']
306 # DEPRECATED # #envoyeur = form.cleaned_data['envoyeur']
307 # DEPRECATED # #renvoi = form.cleaned_data['renvoi']
308 # DEPRECATED # ## Nous pourrions ici envoyer l'e-mail grâce aux données que nous venons de récupérer
309 # DEPRECATED # #envoi = True
311 # DEPRECATED # form = UserRegisterForm()
312 # DEPRECATED # return render(request, 'register_user.html', locals())
314 # DEPRECATED #def index(request):
316 # DEPRECATED # WIZARD_TITLE = 'User registration'
317 # DEPRECATED # STEP1_TITLE = 'Enter your details'
318 # DEPRECATED # STEP2_TITLE = 'Select your institution'
319 # DEPRECATED # STEP3_TITLE = 'Authentication'
320 # DEPRECATED # STEP4_TITLE = 'Request a slice (optional)'
321 # DEPRECATED # STEP5_TITLE = 'Waiting for validation'
322 # DEPRECATED # STEP6_TITLE = 'Account validated'
324 # DEPRECATED # STEP0 = render_to_string('account_validated.html', context_instance=RequestContext(request))
325 # DEPRECATED # STEP2_HTML = """
326 # DEPRECATED # coucou
328 # DEPRECATED # STEP4 = """
331 # DEPRECATED # STEP5 = render_to_string('account_validated.html', context_instance=RequestContext(request))
333 # DEPRECATED # p = PortalPage(request)
335 # DEPRECATED # # This is redundant with the Wizard title
336 # DEPRECATED # p << "<h3>User registration</h3>"
338 # DEPRECATED # sons = []
339 # DEPRECATED # start_step = 1
341 # DEPRECATED # # STEP 1
342 # DEPRECATED # # If the user already exists (is logged), let's display a summary of his account details
343 # DEPRECATED # # Otherwise propose a form to fill in
344 # DEPRECATED # if the_user(request):
345 # DEPRECATED # # Fill a disabled form with user info
346 # DEPRECATED # # Please logout to register another user
347 # DEPRECATED # sons.append(Raw(page=p, title=STEP1_TITLE, togglable=False, html=STEP0))
348 # DEPRECATED # start_step += 1
350 # DEPRECATED # # We could pass a list of fields also, instead of retrieving them from metadata
351 # DEPRECATED # # Otherwise we need some heuristics to display nice forms
352 # DEPRECATED # # XXX Could we log the user in after the form is validated ?
353 # DEPRECATED # # XXX Explain the password is for XXX
354 # DEPRECATED # field_list = [{
355 # DEPRECATED # 'name' : 'First name',
356 # DEPRECATED # 'field' : 'firstname',
357 # DEPRECATED # 'type' : 'text',
358 # DEPRECATED # 'validate_rx' : '^[a-zA-Z -]+$',
359 # DEPRECATED # 'validate_err': 'Your first name must be comprised of letters only',
360 # DEPRECATED # 'description' : 'Enter your first name',
362 # DEPRECATED # 'name' : 'Last name',
363 # DEPRECATED # 'field' : 'lastname',
364 # DEPRECATED # 'type' : 'text',
365 # DEPRECATED # 'validate_rx' : '^[a-zA-Z -]+$',
366 # DEPRECATED # 'validate_err': 'Your last name must be comprised of letters only',
367 # DEPRECATED # 'description' : 'Enter your last name',
369 # DEPRECATED # 'name' : 'Email',
370 # DEPRECATED # 'field' : 'email',
371 # DEPRECATED # 'type' : 'text',
372 # DEPRECATED # 'description' : 'Enter your email address',
374 # DEPRECATED # 'name' : 'Password',
375 # DEPRECATED # 'field' : 'password',
376 # DEPRECATED # 'type' : 'password',
377 # DEPRECATED # 'description' : 'Enter your password',
379 # DEPRECATED # 'name' : 'Confirm password',
380 # DEPRECATED # 'field' : 'password2',
381 # DEPRECATED # 'type' : 'password',
382 # DEPRECATED # 'description' : 'Enter your password again',
384 # DEPRECATED # sons.append(CreateForm(page = p, title = STEP1_TITLE, togglable = False, object = 'local:user', fields = field_list))
386 # DEPRECATED # # STEP 2
387 # DEPRECATED # # If the user already exists (is logged), let's display a summary of its institution
388 # DEPRECATED # # Otherwise propose a form to fill in (we should base our selection on the email)
389 # DEPRECATED # if the_user(request):
390 # DEPRECATED # # Fill a disabled form with institution
391 # DEPRECATED # # Please logout to register another user
392 # DEPRECATED # sons.append(Raw(page=p, title=STEP2_TITLE, togglable=False, html="User created"))
393 # DEPRECATED # start_step += 1
395 # DEPRECATED # sons.append(CreateForm(page = p, title = STEP2_TITLE, togglable = False, object = 'slice')) #institution'))
397 # DEPRECATED # # STEP3
398 # DEPRECATED # # Please should your prefered authentication method
399 # DEPRECATED # # This step should allow the user to either choose the user or managed mode in MySlice
400 # DEPRECATED # sons.append(Raw(page = p, title = STEP3_TITLE, togglable = False, html = STEP2_HTML))
402 # DEPRECATED # # Step 4: Request a slice (optional)
403 # DEPRECATED # sons.append(CreateForm(page = p, title = STEP4_TITLE, togglable = False, object = 'slice'))
405 # DEPRECATED # # Step 5: Your request is waiting for validation
406 # DEPRECATED # # Periodic refresh
407 # DEPRECATED # sons.append(Raw(page = p, title = STEP5_TITLE, togglable = False, html = STEP4))
409 # DEPRECATED # # Step 6: Account validation = welcome for newly validated users
410 # DEPRECATED # # . delegation
411 # DEPRECATED # # . platforms
412 # DEPRECATED # # . slice
413 # DEPRECATED # # . pointers
414 # DEPRECATED # sons.append(Raw(page = p, title = STEP6_TITLE, togglable = False, html = STEP5))
416 # DEPRECATED # wizard = Wizard(
417 # DEPRECATED # page = p,
418 # DEPRECATED # title = WIZARD_TITLE,
419 # DEPRECATED # togglable = False,
420 # DEPRECATED # sons = sons,
421 # DEPRECATED # start_step = start_step,
424 # DEPRECATED # p << wizard.render(request) # in portal page if possible
426 # DEPRECATED # return p.render()
429 # view for contact form
430 def contact(request):
431 if request.method == 'POST': # If the form has been submitted...
432 form = ContactForm(request.POST) # A form bound to the POST data
433 if form.is_valid(): # All validation rules pass
434 # Process the data in form.cleaned_data
435 first_name = form.cleaned_data['first_name']
436 last_name = form.cleaned_data['last_name']
437 affiliation = form.cleaned_data['affiliation']
438 subject = form.cleaned_data['subject']
439 message = form.cleaned_data['message']
440 email = form.cleaned_data['email']
441 cc_myself = form.cleaned_data['cc_myself']
443 recipients = ['yasin.upmc@gmail.com']
445 recipients.append(sender)
447 from django.core.mail import send_mail
448 send_mail(subject, message, email, recipients)
449 return render(request,'contact_sent.html') # Redirect after POST
451 form = ContactForm() # An unbound form
453 return render(request, 'contact.html', {