user session lost in redirection.
[daarmaan:daarmaan.git] / daarmaan / server / views / index.py
1 # -----------------------------------------------------------------------------
2 #    Daarmaan - Single Sign On Service for Yellowen
3 #    Copyright (C) 2012 Yellowen
4 #
5 #    This program is free software; you can redistribute it and/or modify
6 #    it under the terms of the GNU General Public License as published by
7 #    the Free Software Foundation; either version 2 of the License, or
8 #    (at your option) any later version.
9 #
10 #    This program is distributed in the hope that it will be useful,
11 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
12 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 #    GNU General Public License for more details.
14 #
15 #    You should have received a copy of the GNU General Public License along
16 #    with this program; if not, write to the Free Software Foundation, Inc.,
17 #    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 # -----------------------------------------------------------------------------
19
20 from django.shortcuts import render_to_response as rr
21 from django.shortcuts import redirect
22 from django.template import RequestContext
23 from django.contrib.auth import authenticate, login
24 from django.utils.translation import ugettext as _
25 from django.core.urlresolvers import reverse
26 from django.http import HttpResponseRedirect, Http404
27 from django.conf.urls import patterns, url
28 from django.conf import settings
29
30 from daarmaan.server.forms import PreRegistrationForm, NewUserForm, LoginForm
31 from daarmaan.server.models import VerificationCode
32
33
34 class IndexPage(object):
35     """
36     Daarmaan index page class.
37     """
38     template = "index.html"
39     register_template = "register.html"
40     new_user_form_template = "new_user_form.html"
41
42     @property
43     def urls(self):
44         """
45         First Page url patterns.
46         """
47         urlpatterns = patterns(
48             '',
49             url(r"^$", self.index,
50                 name="home"),
51             url(r"^register/$", self.pre_register,
52                 name="home"),
53
54             url(r"^verificate/([A-Fa-f0-9]{40})/$", self.verificate,
55                 name="verificate"),
56             url(r"^registration/done/$", self.registration_done,
57                 name="registration-done"),
58
59             )
60         return urlpatterns
61
62     def index(self, request):
63         """
64         Index view.
65         """
66         if request.user.is_authenticated():
67             return HttpResponseRedirect(reverse('dashboard-index'))
68
69         if request.method == "POST":
70             return self.login(request)
71
72         else:
73             form = LoginForm()
74             next_url = request.GET.get("next", "")
75             return rr(self.template,
76                       {"form": form,
77                        "next": next_url},
78                       context_instance=RequestContext(request))
79
80
81     def login(self, request):
82         """
83         Login view that only accept a POST request.
84         """
85         next_url = request.POST.get("next", None)
86
87         form = LoginForm(request.POST)
88
89         if form.is_valid():
90             username = form.cleaned_data['username']
91             password = form.cleaned_data['password']
92             remember = form.cleaned_data.get("remember_me", False)
93             next_url = form.cleaned_data.get("next_", None)
94
95             # Authenticate the user
96             user = authenticate(username=username,
97                                 password=password)
98             if user is not None:
99                 if user.is_active:
100                     login(request, user)
101                     self._setup_session(request)
102                     print ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ", user
103                     if next_url:
104                         import urllib
105                         return HttpResponseRedirect(
106                             urllib.unquote_plus(next_url)
107                         )
108
109                     return redirect(reverse("dashboard-index", args=[]))
110
111                 else:
112                     return rr(self.template,
113                               {"form": form,
114                                "msgclass": "text-error",
115                                "next": next_url,
116                                "msg": _("Your account is disabled.")},
117                               context_instance=RequestContext(request))
118             else:
119                 return rr(self.template,
120                           {"form": form,
121                            "msgclass": "text-error",
122                            "next": next_url,
123                            "msg": _("Username or Password is invalid.")},
124                           context_instance=RequestContext(request))
125
126         else:
127             return rr(self.template,
128                       {"form": form,
129                        "next": next_url},
130                        context_instance=RequestContext(request))
131
132     def pre_register(self, request):
133         """
134         Handle the registeration request.
135         """
136         from django.contrib.auth.models import User
137         from django.db import IntegrityError
138
139         if request.method == "POST":
140             form = PreRegistrationForm(request.POST)
141             msg = None
142             klass = ""
143             if form.is_valid():
144                 # In case of valid information from user.
145                 email = form.cleaned_data["email"]
146                 username = form.cleaned_data["username"]
147
148                 # Check for email exists
149                 emails_count = User.objects.filter(email=email).count()
150                 if emails_count:
151                     failed = True
152                     msg = _("This email has been registered before.")
153                     klass = "text-error"
154
155                 else:
156                     try:
157                         # Create and save an inactive user
158                         user = User(username=username,
159                                 email=email)
160                         user.active = False
161                         user.save()
162
163                         if settings.EMAIL_VERIFICATION:
164                             # Generate and send a verification code to user
165                             # only if EMAIL_VERIFICATION was set
166                             verif_code = VerificationCode.generate(user)
167
168                             verification_link = reverse("verificate",
169                                                         args=[verif_code])
170
171                             print ">>> ", verification_link
172                             self.send_verification_mail(user,
173                                                         verification_link)
174
175                             msg = _("A verfication mail has been sent to your e-mail address.")
176                         else:
177                             msg = _("You're request submited, thanks for your interest.")
178
179                         klass = "text-success"
180                         form = PreRegistrationForm()
181                     except IntegrityError:
182                         # In case of exists username
183                         msg = _("User already exists.")
184                         klass = "text-error"
185
186             return rr(self.register_template,
187                   {"form": form,
188                    "msg": msg,
189                    "msgclass": klass},
190                   context_instance=RequestContext(request))
191         else:
192             form = PreRegistrationForm()
193             return rr(self.register_template,
194                   {"form": form},
195                   context_instance=RequestContext(request))
196
197     def _setup_session(self, request):
198         """
199         Insert all needed values into user session.
200         """
201         # TODO: Do we need to set the user services to his session.
202         return
203         services = request.user.get_profile().services.all()
204         services_id = [i.id for i in services]
205         request.session["services"] = services_id
206
207     def verificate(self, request, verification_code):
208         """
209         This view is responsible for verify the user mail address
210         from the given verification code and redirect to the basic
211         information form view.
212         """
213
214         # Look up for given verification code in the VerificationCode
215         # model. And check for the validation of an any possible exists
216         # code
217         try:
218             verified_code = VerificationCode.objects.get(
219                 code=verification_code)
220         except VerificationCode.DoesNotExist:
221             raise Http404()
222
223         # If the verified_code was valid (belongs to past 48 hours for
224         # example) the new user form will allow user to finalize his/her
225         # registeration process.
226         if verified_code.is_valid():
227             form = NewUserForm(initial={
228                 "verification_code": verified_code.code})
229
230             form.action = reverse("registration-done", args=[])
231             return rr(self.new_user_form_template,
232                       {"form": form,
233                        "user": verified_code.user},
234                       context_instance=RequestContext(request))
235         else:
236             raise Http404()
237
238     def send_verification_mail(self, user, verification_link):
239         """
240         Send the verification link to the user.
241         """
242         from django.core.mail import send_mail
243
244         msg = verification_link
245         send_mail('[Yellowen] Verification', msg, settings.EMAIL,
246                   [user.email], fail_silently=False)
247
248     def registration_done(self, request):
249         if request.method == "POST":
250             form = NewUserForm(request.POST)
251             try:
252                 verified_code = VerificationCode.objects.get(
253                     code = request.POST.get("verification_code", ""))
254
255             except VerificationCode.DoesNotExist:
256                 from django.http import HttpResponseForbidden
257                 return HttpResponseForbidden()
258
259             if form.is_valid():
260                 pass1 = form.cleaned_data["password1"]
261                 pass2 = form.cleaned_data["password2"]
262                 fname = form.cleaned_data["first_name"]
263                 lname = form.cleaned_data["last_name"]
264
265                 if pass1 != pass2:
266                     form._errors = {
267                         "password1": _("Two password fields did not match."),
268                         "password2": _("Two password fields did not match.")}
269                     msg = _("Two password fields did not match.")
270                     klass = "text-error"
271                 elif len(pass1) < 6:
272                     form._errors = {
273                         "password1": _("Password should be more than 6 character long.")}
274                     msg = _("Password should be more than 6 character long.")
275                     klass = "text-error"
276                 elif len(pass1) > 40:
277                     form._errors = {
278                         "password1": _("Password should be less than 40 character long.")}
279                     msg = _("Password should be less than 40 character long.")
280                     klass = "text-error"
281                 else:
282                     user = verified_code.user
283                     user.set_password(pass1)
284                     user.first_name = fname
285                     user.last_name = lname
286                     user.active = True
287                     user.save()
288
289                     # Clean up all the expired codes and currently used one
290                     verified_code.delete()
291                     VerificationCode.cleanup()
292
293                     # Login the user
294                     user = authenticate(username=user.username,
295                                         password=pass1)
296
297                     login(request, user)
298
299                     return redirect(reverse(
300                         "dashboard-index",
301                         args=[]))
302
303             print ">>> ", msg
304             return rr(self.new_user_form_template,
305                       {"form": form,
306                        "user": verified_code.user,
307                        "msg": msg,
308                        "msgclass": klass},
309                       context_instance=RequestContext(request))
310         else:
311             raise Http404()
312
313
314 index_page = IndexPage()