OneLab Contact Us form created. Email to be tested from dev machine.
[myslice.git] / portal / views.py
1 # -*- coding: utf-8 -*-
2 #
3 # portal/views.py: views for the portal application
4 # This file is part of the Manifold project.
5 #
6 # Authors:
7 #   Jordan Augé <jordan.auge@lip6.fr>
8 #   Mohammed Yasin Rahman <mohammed-yasin.rahman@lip6.fr>
9 # Copyright 2013, UPMC Sorbonne Universités / LIP6
10 #
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.
14
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
18 # details.
19
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.
23
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
39
40 class DashboardView(TemplateView):
41     template_name = "dashboard.html"
42
43     def get_context_data(self, **kwargs):
44         user_hrn = 'ple.upmc.jordan_auge'
45
46         messages.info(self.request, 'You have logged in')
47
48
49         page = Page(self.request)
50
51         # Slow...
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)
57
58         page.expose_queries()
59
60         slicelist = SimpleList(
61             title = None,
62             page  = page,
63             key   = 'slice.slice_hrn',
64             query = slice_query,
65         )
66          
67         authlist = SimpleList(
68             title = None,
69             page  = page,
70             key   = 'network_hrn',
71             query = auth_query,
72         )
73
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)
78
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) 
86
87         context.update(page.prelude_env())
88
89         return context
90
91 class UserRegisterView(RegistrationView):
92     """
93     A registration backend which follows a simple workflow:
94
95     1. User signs up, inactive account is created.
96
97     2. Email is sent to user with activation link.
98
99     3. User clicks activation link, account is now active.
100
101     Using this backend requires that
102
103     * ``registration`` be listed in the ``INSTALLED_APPS`` setting
104       (since this backend makes use of models defined in this
105       application).
106
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).
111
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.
117
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
122     permitted.
123
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.
128     
129     """
130     form_class = UserRegisterForm
131     
132     def register(self, request, **cleaned_data):
133         """
134         Given a username, email address and password, register a new
135         user account, which will initially be inactive.
136
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.
141
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
147         them.
148
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.
154
155         """
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']
161         
162         #password2  = cleaned_data['password2']
163         keypair    = cleaned_data['keypair']
164
165         #if Site._meta.installed:
166         #    site = Site.objects.get_current()
167         #else:
168         #    site = RequestSite(request) 
169         site = None
170
171         new_user = PendingUser.objects.create_inactive_user(first_name, last_name, email, password, site)
172         signals.user_registered.send(sender=self.__class__,
173                                      user=new_user,
174                                      request=request)
175         return new_user
176
177     def registration_allowed(self, request):
178         """
179         Indicate whether account registration is currently permitted,
180         based on the value of the setting ``REGISTRATION_OPEN``. This
181         is determined as follows:
182
183         * If ``REGISTRATION_OPEN`` is not specified in settings, or is
184           set to ``True``, registration is permitted.
185
186         * If ``REGISTRATION_OPEN`` is both specified and set to
187           ``False``, registration is not permitted.
188         
189         """
190         return getattr(settings, 'REGISTRATION_OPEN', True)
191
192     def get_success_url(self, request, user):
193         """
194         Return the name of the URL to redirect to after successful
195         user registration.
196         
197         """
198         return ('user_register_complete', (), {})
199
200
201 class UserValidateView(ActivationView):
202     def activate(self, request, activation_key):
203         """
204         Given an an activation key, look up and activate the user
205         account corresponding to that key (if possible).
206
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.
211         
212         """
213         activated_user = RegistrationProfile.objects.activate_user(activation_key)
214         if activated_user:
215             signals.user_activated.send(sender=self.__class__,
216                                         user=activated_user,
217                                         request=request)
218         return activated_user
219
220     def get_success_url(self, request, user):
221         return ('registration_activation_complete', (), {})
222
223
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
228 # DEPRECATED #
229 # DEPRECATED #from myslice.viewutils  import the_user
230 # DEPRECATED #
231 # DEPRECATED #from django.template.loader import render_to_string
232 # DEPRECATED #from django.template import RequestContext
233 # DEPRECATED #from django.views import generic
234 # DEPRECATED #
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
238 # DEPRECATED #
239 # DEPRECATED ##class MerlinWizard(NamedUrlSessionWizardView):
240 # DEPRECATED ##
241 # DEPRECATED ##    ...
242 # DEPRECATED ##    ...
243 # DEPRECATED ##
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,
251 # DEPRECATED ##            ],
252 # DEPRECATED ##            'url_name': 'merlin_wizard'
253 # DEPRECATED ##        })
254 # DEPRECATED ##        return super(MerlinWizard, cls).as_view(*args, **kwargs)
255 # DEPRECATED #
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"
265 # DEPRECATED #
266 # DEPRECATED #    def done(self, form_list, **kwargs):
267 # DEPRECATED #        step1_form = form_list[0]
268 # DEPRECATED #        step2_form = form_list[1]
269 # DEPRECATED #
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)
273 # DEPRECATED #
274 # DEPRECATED #        if all([productext, shippings, images]):
275 # DEPRECATED #            del self.request.session["wizard_product_wizard_view"]
276 # DEPRECATED #
277 # DEPRECATED #            messages.success(self.request,
278 # DEPRECATED #                _("Your product has been created."))
279 # DEPRECATED #            return HttpResponseRedirect(self.get_success_url(productext))
280 # DEPRECATED #
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"))
284 # DEPRECATED #
285 # DEPRECATED #    #def get_form_kwargs(self, step):
286 # DEPRECATED #    #    if step == "product":
287 # DEPRECATED #    #        return {"user": self.request.user}
288 # DEPRECATED #    #    return {}
289 # DEPRECATED #
290 # DEPRECATED ## The portal should hook the slice and user creation pages
291 # DEPRECATED #
292 # DEPRECATED #def register_user(request):
293 # DEPRECATED #    
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
310 # DEPRECATED #    else:
311 # DEPRECATED #        form = UserRegisterForm()
312 # DEPRECATED #    return render(request, 'register_user.html', locals())
313 # DEPRECATED #
314 # DEPRECATED #def index(request):
315 # DEPRECATED #
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'
323 # DEPRECATED #
324 # DEPRECATED #    STEP0 = render_to_string('account_validated.html', context_instance=RequestContext(request))
325 # DEPRECATED #    STEP2_HTML   = """
326 # DEPRECATED #    coucou
327 # DEPRECATED #    """
328 # DEPRECATED #    STEP4 = """
329 # DEPRECATED #    mede
330 # DEPRECATED #    """
331 # DEPRECATED #    STEP5 = render_to_string('account_validated.html', context_instance=RequestContext(request))
332 # DEPRECATED #
333 # DEPRECATED #    p = PortalPage(request)
334 # DEPRECATED #
335 # DEPRECATED #    # This is redundant with the Wizard title
336 # DEPRECATED #    p << "<h3>User registration</h3>"
337 # DEPRECATED #
338 # DEPRECATED #    sons = []
339 # DEPRECATED #    start_step = 1
340 # DEPRECATED #
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
349 # DEPRECATED #    else:
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',
361 # DEPRECATED #        }, {
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',
368 # DEPRECATED #        }, { 
369 # DEPRECATED #            'name'        : 'Email',
370 # DEPRECATED #            'field'       : 'email',
371 # DEPRECATED #            'type'        : 'text',
372 # DEPRECATED #            'description' : 'Enter your email address',
373 # DEPRECATED #        }, {
374 # DEPRECATED #            'name'        : 'Password',
375 # DEPRECATED #            'field'       : 'password',
376 # DEPRECATED #            'type'        : 'password',
377 # DEPRECATED #            'description' : 'Enter your password',
378 # DEPRECATED #        }, {
379 # DEPRECATED #            'name'        : 'Confirm password',
380 # DEPRECATED #            'field'       : 'password2',
381 # DEPRECATED #            'type'        : 'password',
382 # DEPRECATED #            'description' : 'Enter your password again',
383 # DEPRECATED #        }]
384 # DEPRECATED #        sons.append(CreateForm(page = p, title = STEP1_TITLE, togglable = False, object = 'local:user', fields = field_list))
385 # DEPRECATED #
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
394 # DEPRECATED #    else:
395 # DEPRECATED #        sons.append(CreateForm(page = p, title = STEP2_TITLE, togglable = False, object = 'slice')) #institution'))
396 # DEPRECATED #
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))
401 # DEPRECATED #
402 # DEPRECATED #    # Step 4: Request a slice (optional)
403 # DEPRECATED #    sons.append(CreateForm(page = p, title = STEP4_TITLE, togglable = False, object = 'slice'))
404 # DEPRECATED #
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))
408 # DEPRECATED #
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))
415 # DEPRECATED #
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,
422 # DEPRECATED #    )
423 # DEPRECATED #
424 # DEPRECATED #    p << wizard.render(request) # in portal page if possible
425 # DEPRECATED #
426 # DEPRECATED #    return p.render()
427
428
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']
442
443             recipients = ['yasin.upmc@gmail.com']
444             if cc_myself:
445                 recipients.append(sender)
446
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
450     else:
451         form = ContactForm() # An unbound form
452
453     return render(request, 'contact.html', {
454         'form': form,
455     })
456