Statistics
| Branch: | Tag: | Revision:

root / pithos / im / views.py @ bee5ffa6

History | View | Annotate | Download (13.6 kB)

1 79746386 Antony Chazapis
# Copyright 2011 GRNET S.A. All rights reserved.
2 79746386 Antony Chazapis
# 
3 79746386 Antony Chazapis
# Redistribution and use in source and binary forms, with or
4 79746386 Antony Chazapis
# without modification, are permitted provided that the following
5 79746386 Antony Chazapis
# conditions are met:
6 79746386 Antony Chazapis
# 
7 79746386 Antony Chazapis
#   1. Redistributions of source code must retain the above
8 79746386 Antony Chazapis
#      copyright notice, this list of conditions and the following
9 79746386 Antony Chazapis
#      disclaimer.
10 79746386 Antony Chazapis
# 
11 79746386 Antony Chazapis
#   2. Redistributions in binary form must reproduce the above
12 79746386 Antony Chazapis
#      copyright notice, this list of conditions and the following
13 79746386 Antony Chazapis
#      disclaimer in the documentation and/or other materials
14 79746386 Antony Chazapis
#      provided with the distribution.
15 79746386 Antony Chazapis
# 
16 79746386 Antony Chazapis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 79746386 Antony Chazapis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 79746386 Antony Chazapis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 79746386 Antony Chazapis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 79746386 Antony Chazapis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 79746386 Antony Chazapis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 79746386 Antony Chazapis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 79746386 Antony Chazapis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 79746386 Antony Chazapis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 79746386 Antony Chazapis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 79746386 Antony Chazapis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 79746386 Antony Chazapis
# POSSIBILITY OF SUCH DAMAGE.
28 79746386 Antony Chazapis
# 
29 79746386 Antony Chazapis
# The views and conclusions contained in the software and
30 79746386 Antony Chazapis
# documentation are those of the authors and should not be
31 79746386 Antony Chazapis
# interpreted as representing official policies, either expressed
32 79746386 Antony Chazapis
# or implied, of GRNET S.A.
33 79746386 Antony Chazapis
34 93f046ab Giorgos Verigakis
import json
35 93f046ab Giorgos Verigakis
import logging
36 93f046ab Giorgos Verigakis
import socket
37 93f046ab Giorgos Verigakis
38 2d8da097 Antony Chazapis
from datetime import datetime
39 65e57f32 Giorgos Verigakis
from functools import wraps
40 393196a8 Giorgos Verigakis
from math import ceil
41 93f046ab Giorgos Verigakis
from random import randint
42 93f046ab Giorgos Verigakis
from smtplib import SMTPException
43 65e57f32 Giorgos Verigakis
44 b40254ee Giorgos Verigakis
from django.conf import settings
45 93f046ab Giorgos Verigakis
from django.core.mail import send_mail
46 5b9d15ad Antony Chazapis
from django.http import HttpResponse, HttpResponseRedirect
47 65e57f32 Giorgos Verigakis
from django.shortcuts import redirect
48 65e57f32 Giorgos Verigakis
from django.template.loader import render_to_string
49 93f046ab Giorgos Verigakis
from django.utils.http import urlencode
50 93f046ab Giorgos Verigakis
from django.utils.translation import ugettext as _
51 552ea518 Antony Chazapis
from django.core.urlresolvers import reverse
52 65e57f32 Giorgos Verigakis
53 bee5ffa6 Sofia Papagiannaki
from urllib import quote
54 bee5ffa6 Sofia Papagiannaki
55 93f046ab Giorgos Verigakis
from pithos.im.models import User, Invitation
56 93f046ab Giorgos Verigakis
from pithos.im.util import isoformat
57 65e57f32 Giorgos Verigakis
58 65e57f32 Giorgos Verigakis
59 393196a8 Giorgos Verigakis
def render_response(template, tab=None, status=200, **kwargs):
60 393196a8 Giorgos Verigakis
    if tab is None:
61 393196a8 Giorgos Verigakis
        tab = template.partition('_')[0]
62 65e57f32 Giorgos Verigakis
    kwargs.setdefault('tab', tab)
63 393196a8 Giorgos Verigakis
    html = render_to_string(template, kwargs)
64 393196a8 Giorgos Verigakis
    return HttpResponse(html, status=status)
65 65e57f32 Giorgos Verigakis
66 65e57f32 Giorgos Verigakis
67 93f046ab Giorgos Verigakis
def requires_login(func):
68 93f046ab Giorgos Verigakis
    @wraps(func)
69 93f046ab Giorgos Verigakis
    def wrapper(request, *args):
70 93f046ab Giorgos Verigakis
        if not settings.BYPASS_ADMIN_AUTH:
71 93f046ab Giorgos Verigakis
            if not request.user:
72 93f046ab Giorgos Verigakis
                next = urlencode({'next': request.build_absolute_uri()})
73 552ea518 Antony Chazapis
                login_uri = reverse(index) + '?' + next
74 93f046ab Giorgos Verigakis
                return HttpResponseRedirect(login_uri)
75 93f046ab Giorgos Verigakis
        return func(request, *args)
76 93f046ab Giorgos Verigakis
    return wrapper
77 93f046ab Giorgos Verigakis
78 93f046ab Giorgos Verigakis
79 65e57f32 Giorgos Verigakis
def requires_admin(func):
80 65e57f32 Giorgos Verigakis
    @wraps(func)
81 65e57f32 Giorgos Verigakis
    def wrapper(request, *args):
82 b8f6710f Giorgos Verigakis
        if not settings.BYPASS_ADMIN_AUTH:
83 b8f6710f Giorgos Verigakis
            if not request.user:
84 b40254ee Giorgos Verigakis
                next = urlencode({'next': request.build_absolute_uri()})
85 552ea518 Antony Chazapis
                login_uri = reverse(index) + '?' + next
86 b8f6710f Giorgos Verigakis
                return HttpResponseRedirect(login_uri)
87 61efb530 Antony Chazapis
            if not request.user.is_admin:
88 b8f6710f Giorgos Verigakis
                return HttpResponse('Forbidden', status=403)
89 65e57f32 Giorgos Verigakis
        return func(request, *args)
90 65e57f32 Giorgos Verigakis
    return wrapper
91 65e57f32 Giorgos Verigakis
92 65e57f32 Giorgos Verigakis
93 65e57f32 Giorgos Verigakis
def index(request):
94 552ea518 Antony Chazapis
    return render_response('index.html', next=request.GET.get('next', ''))
95 65e57f32 Giorgos Verigakis
96 65e57f32 Giorgos Verigakis
97 65e57f32 Giorgos Verigakis
@requires_admin
98 7e392d16 Antony Chazapis
def admin(request):
99 7e392d16 Antony Chazapis
    stats = {}
100 7e392d16 Antony Chazapis
    stats['users'] = User.objects.count()
101 32e87ed2 Giorgos Verigakis
    
102 32e87ed2 Giorgos Verigakis
    invitations = Invitation.objects.all()
103 32e87ed2 Giorgos Verigakis
    stats['invitations'] = invitations.count()
104 32e87ed2 Giorgos Verigakis
    stats['invitations_accepted'] = invitations.filter(is_accepted=True).count()
105 32e87ed2 Giorgos Verigakis
    
106 7e392d16 Antony Chazapis
    return render_response('admin.html', tab='home', stats=stats)
107 7e392d16 Antony Chazapis
108 7e392d16 Antony Chazapis
109 7e392d16 Antony Chazapis
@requires_admin
110 65e57f32 Giorgos Verigakis
def users_list(request):
111 7e392d16 Antony Chazapis
    users = User.objects.order_by('id')
112 b40254ee Giorgos Verigakis
    
113 b40254ee Giorgos Verigakis
    filter = request.GET.get('filter', '')
114 b40254ee Giorgos Verigakis
    if filter:
115 b40254ee Giorgos Verigakis
        if filter.startswith('-'):
116 b40254ee Giorgos Verigakis
            users = users.exclude(uniq__icontains=filter[1:])
117 b40254ee Giorgos Verigakis
        else:
118 b40254ee Giorgos Verigakis
            users = users.filter(uniq__icontains=filter)
119 b40254ee Giorgos Verigakis
    
120 393196a8 Giorgos Verigakis
    try:
121 393196a8 Giorgos Verigakis
        page = int(request.GET.get('page', 1))
122 393196a8 Giorgos Verigakis
    except ValueError:
123 393196a8 Giorgos Verigakis
        page = 1
124 393196a8 Giorgos Verigakis
    offset = max(0, page - 1) * settings.ADMIN_PAGE_LIMIT
125 393196a8 Giorgos Verigakis
    limit = offset + settings.ADMIN_PAGE_LIMIT
126 393196a8 Giorgos Verigakis
    
127 393196a8 Giorgos Verigakis
    npages = int(ceil(1.0 * users.count() / settings.ADMIN_PAGE_LIMIT))
128 393196a8 Giorgos Verigakis
    prev = page - 1 if page > 1 else None
129 393196a8 Giorgos Verigakis
    next = page + 1 if page < npages else None
130 393196a8 Giorgos Verigakis
    return render_response('users_list.html',
131 393196a8 Giorgos Verigakis
                            users=users[offset:limit],
132 b40254ee Giorgos Verigakis
                            filter=filter,
133 393196a8 Giorgos Verigakis
                            pages=range(1, npages + 1),
134 393196a8 Giorgos Verigakis
                            page=page,
135 393196a8 Giorgos Verigakis
                            prev=prev,
136 393196a8 Giorgos Verigakis
                            next=next)
137 bee5ffa6 Sofia Papagiannaki
    
138 65e57f32 Giorgos Verigakis
@requires_admin
139 65e57f32 Giorgos Verigakis
def users_create(request):
140 65e57f32 Giorgos Verigakis
    if request.method == 'GET':
141 393196a8 Giorgos Verigakis
        return render_response('users_create.html')
142 65e57f32 Giorgos Verigakis
    if request.method == 'POST':
143 7e392d16 Antony Chazapis
        user = User()
144 65e57f32 Giorgos Verigakis
        user.uniq = request.POST.get('uniq')
145 65e57f32 Giorgos Verigakis
        user.realname = request.POST.get('realname')
146 65e57f32 Giorgos Verigakis
        user.is_admin = True if request.POST.get('admin') else False
147 65e57f32 Giorgos Verigakis
        user.affiliation = request.POST.get('affiliation')
148 2d8da097 Antony Chazapis
        user.quota = int(request.POST.get('quota') or 0) * (1024 ** 3)  # In GiB
149 2d8da097 Antony Chazapis
        user.renew_token()
150 65e57f32 Giorgos Verigakis
        user.save()
151 65e57f32 Giorgos Verigakis
        return redirect(users_info, user.id)
152 65e57f32 Giorgos Verigakis
153 65e57f32 Giorgos Verigakis
@requires_admin
154 65e57f32 Giorgos Verigakis
def users_info(request, user_id):
155 7e392d16 Antony Chazapis
    user = User.objects.get(id=user_id)
156 32e87ed2 Giorgos Verigakis
    states = [x[0] for x in User.ACCOUNT_STATE]
157 32e87ed2 Giorgos Verigakis
    return render_response('users_info.html',
158 32e87ed2 Giorgos Verigakis
                            user=user,
159 32e87ed2 Giorgos Verigakis
                            states=states)
160 65e57f32 Giorgos Verigakis
161 65e57f32 Giorgos Verigakis
162 65e57f32 Giorgos Verigakis
@requires_admin
163 65e57f32 Giorgos Verigakis
def users_modify(request, user_id):
164 7e392d16 Antony Chazapis
    user = User.objects.get(id=user_id)
165 65e57f32 Giorgos Verigakis
    user.uniq = request.POST.get('uniq')
166 65e57f32 Giorgos Verigakis
    user.realname = request.POST.get('realname')
167 65e57f32 Giorgos Verigakis
    user.is_admin = True if request.POST.get('admin') else False
168 65e57f32 Giorgos Verigakis
    user.affiliation = request.POST.get('affiliation')
169 32e87ed2 Giorgos Verigakis
    user.state = request.POST.get('state')
170 32e87ed2 Giorgos Verigakis
    user.invitations = int(request.POST.get('invitations') or 0)
171 2d8da097 Antony Chazapis
    user.quota = int(request.POST.get('quota') or 0) * (1024 ** 3)  # In GiB
172 65e57f32 Giorgos Verigakis
    user.auth_token = request.POST.get('auth_token')
173 2d8da097 Antony Chazapis
    try:
174 2d8da097 Antony Chazapis
        auth_token_expires = request.POST.get('auth_token_expires')
175 2d8da097 Antony Chazapis
        d = datetime.strptime(auth_token_expires, '%Y-%m-%dT%H:%MZ')
176 2d8da097 Antony Chazapis
        user.auth_token_expires = d
177 2d8da097 Antony Chazapis
    except ValueError:
178 2d8da097 Antony Chazapis
        pass
179 65e57f32 Giorgos Verigakis
    user.save()
180 65e57f32 Giorgos Verigakis
    return redirect(users_info, user.id)
181 65e57f32 Giorgos Verigakis
182 65e57f32 Giorgos Verigakis
183 65e57f32 Giorgos Verigakis
@requires_admin
184 65e57f32 Giorgos Verigakis
def users_delete(request, user_id):
185 7e392d16 Antony Chazapis
    user = User.objects.get(id=user_id)
186 65e57f32 Giorgos Verigakis
    user.delete()
187 65e57f32 Giorgos Verigakis
    return redirect(users_list)
188 93f046ab Giorgos Verigakis
189 93f046ab Giorgos Verigakis
190 93f046ab Giorgos Verigakis
def generate_invitation_code():
191 390c4b88 Giorgos Verigakis
    while True:
192 390c4b88 Giorgos Verigakis
        code = randint(1, 2L**63 - 1)
193 390c4b88 Giorgos Verigakis
        try:
194 390c4b88 Giorgos Verigakis
            Invitation.objects.get(code=code)
195 390c4b88 Giorgos Verigakis
            # An invitation with this code already exists, try again
196 390c4b88 Giorgos Verigakis
        except Invitation.DoesNotExist:
197 390c4b88 Giorgos Verigakis
            return code
198 93f046ab Giorgos Verigakis
199 93f046ab Giorgos Verigakis
200 93f046ab Giorgos Verigakis
def send_invitation(inv):
201 93f046ab Giorgos Verigakis
    url = settings.INVITATION_LOGIN_TARGET % inv.code
202 93f046ab Giorgos Verigakis
    subject = _('Invitation to Pithos')
203 93f046ab Giorgos Verigakis
    message = render_to_string('invitation.txt', {
204 93f046ab Giorgos Verigakis
                'invitation': inv,
205 bee5ffa6 Sofia Papagiannaki
                'url': url,
206 bee5ffa6 Sofia Papagiannaki
                'baseurl': settings.BASE_URL,
207 bee5ffa6 Sofia Papagiannaki
                'service': settings.SERVICE_NAME,
208 bee5ffa6 Sofia Papagiannaki
                'support': settings.SUPPORT_EMAIL})
209 93f046ab Giorgos Verigakis
    sender = settings.DEFAULT_FROM_EMAIL
210 93f046ab Giorgos Verigakis
    send_mail(subject, message, sender, [inv.uniq])
211 93f046ab Giorgos Verigakis
    logging.info('Sent invitation %s', inv)
212 93f046ab Giorgos Verigakis
213 93f046ab Giorgos Verigakis
214 93f046ab Giorgos Verigakis
@requires_login
215 d3205c49 Giorgos Verigakis
def invite(request):
216 93f046ab Giorgos Verigakis
    status = None
217 93f046ab Giorgos Verigakis
    message = None
218 390c4b88 Giorgos Verigakis
    inviter = request.user
219 93f046ab Giorgos Verigakis
220 93f046ab Giorgos Verigakis
    if request.method == 'POST':
221 390c4b88 Giorgos Verigakis
        uniq = request.POST.get('uniq')
222 390c4b88 Giorgos Verigakis
        realname = request.POST.get('realname')
223 390c4b88 Giorgos Verigakis
        
224 390c4b88 Giorgos Verigakis
        if inviter.invitations > 0:
225 93f046ab Giorgos Verigakis
            code = generate_invitation_code()
226 390c4b88 Giorgos Verigakis
            invitation, created = Invitation.objects.get_or_create(
227 390c4b88 Giorgos Verigakis
                inviter=inviter,
228 390c4b88 Giorgos Verigakis
                uniq=uniq,
229 390c4b88 Giorgos Verigakis
                defaults={'code': code, 'realname': realname})
230 93f046ab Giorgos Verigakis
            
231 93f046ab Giorgos Verigakis
            try:
232 93f046ab Giorgos Verigakis
                send_invitation(invitation)
233 390c4b88 Giorgos Verigakis
                if created:
234 390c4b88 Giorgos Verigakis
                    inviter.invitations = max(0, inviter.invitations - 1)
235 390c4b88 Giorgos Verigakis
                    inviter.save()
236 93f046ab Giorgos Verigakis
                status = 'success'
237 390c4b88 Giorgos Verigakis
                message = _('Invitation sent to %s' % uniq)
238 93f046ab Giorgos Verigakis
            except (SMTPException, socket.error) as e:
239 93f046ab Giorgos Verigakis
                status = 'error'
240 39fc9e8d Antony Chazapis
                message = getattr(e, 'strerror', '')
241 93f046ab Giorgos Verigakis
        else:
242 93f046ab Giorgos Verigakis
            status = 'error'
243 93f046ab Giorgos Verigakis
            message = _('No invitations left')
244 93f046ab Giorgos Verigakis
245 93f046ab Giorgos Verigakis
    if request.GET.get('format') == 'json':
246 390c4b88 Giorgos Verigakis
        sent = [{'email': inv.uniq,
247 390c4b88 Giorgos Verigakis
                 'realname': inv.realname,
248 390c4b88 Giorgos Verigakis
                 'is_accepted': inv.is_accepted}
249 390c4b88 Giorgos Verigakis
                    for inv in inviter.invitations_sent.all()]
250 390c4b88 Giorgos Verigakis
        rep = {'invitations': inviter.invitations, 'sent': sent}
251 93f046ab Giorgos Verigakis
        return HttpResponse(json.dumps(rep))
252 93f046ab Giorgos Verigakis
    
253 93f046ab Giorgos Verigakis
    html = render_to_string('invitations.html', {
254 390c4b88 Giorgos Verigakis
            'user': inviter,
255 93f046ab Giorgos Verigakis
            'status': status,
256 93f046ab Giorgos Verigakis
            'message': message})
257 93f046ab Giorgos Verigakis
    return HttpResponse(html)
258 bee5ffa6 Sofia Papagiannaki
259 bee5ffa6 Sofia Papagiannaki
def send_verification(user):
260 bee5ffa6 Sofia Papagiannaki
    url = settings.ACTIVATION_LOGIN_TARGET % quote(user.auth_token)
261 bee5ffa6 Sofia Papagiannaki
    message = render_to_string('activation.txt', {
262 bee5ffa6 Sofia Papagiannaki
            'user': user,
263 bee5ffa6 Sofia Papagiannaki
            'url': url,
264 bee5ffa6 Sofia Papagiannaki
            'baseurl': settings.BASE_URL,
265 bee5ffa6 Sofia Papagiannaki
            'service': settings.SERVICE_NAME,
266 bee5ffa6 Sofia Papagiannaki
            'support': settings.SUPPORT_EMAIL})
267 bee5ffa6 Sofia Papagiannaki
    sender = settings.DEFAULT_FROM_EMAIL
268 bee5ffa6 Sofia Papagiannaki
    send_mail('Pithos account activation', message, sender, [user.email])
269 bee5ffa6 Sofia Papagiannaki
    logging.info('Sent activation %s', user)
270 bee5ffa6 Sofia Papagiannaki
271 bee5ffa6 Sofia Papagiannaki
def local_create(request):
272 bee5ffa6 Sofia Papagiannaki
    if request.method == 'GET':
273 bee5ffa6 Sofia Papagiannaki
        return render_response('local_create.html')
274 bee5ffa6 Sofia Papagiannaki
    elif request.method == 'POST':
275 bee5ffa6 Sofia Papagiannaki
        username = request.POST.get('uniq')
276 bee5ffa6 Sofia Papagiannaki
        realname = request.POST.get('realname')
277 bee5ffa6 Sofia Papagiannaki
        email = request.POST.get('email')
278 bee5ffa6 Sofia Papagiannaki
        password = request.POST.get('password')
279 bee5ffa6 Sofia Papagiannaki
        status = 'success'
280 bee5ffa6 Sofia Papagiannaki
        if not username:
281 bee5ffa6 Sofia Papagiannaki
            status = 'error'
282 bee5ffa6 Sofia Papagiannaki
            message = 'No username provided'
283 bee5ffa6 Sofia Papagiannaki
        elif not password:
284 bee5ffa6 Sofia Papagiannaki
            status = 'error'
285 bee5ffa6 Sofia Papagiannaki
            message = 'No password provided'
286 bee5ffa6 Sofia Papagiannaki
        elif not email:
287 bee5ffa6 Sofia Papagiannaki
            status = 'error'
288 bee5ffa6 Sofia Papagiannaki
            message = 'No email provided'
289 bee5ffa6 Sofia Papagiannaki
        
290 bee5ffa6 Sofia Papagiannaki
        if status == 'success':
291 bee5ffa6 Sofia Papagiannaki
            username = '%s@local' % username
292 bee5ffa6 Sofia Papagiannaki
            try:
293 bee5ffa6 Sofia Papagiannaki
                user = User.objects.get(uniq=username)
294 bee5ffa6 Sofia Papagiannaki
                status = 'error'
295 bee5ffa6 Sofia Papagiannaki
                message = 'Username is not available'
296 bee5ffa6 Sofia Papagiannaki
            except User.DoesNotExist:
297 bee5ffa6 Sofia Papagiannaki
                user = User()
298 bee5ffa6 Sofia Papagiannaki
                user.uniq = username 
299 bee5ffa6 Sofia Papagiannaki
                user.realname = realname
300 bee5ffa6 Sofia Papagiannaki
                user.email = request.POST.get('email')
301 bee5ffa6 Sofia Papagiannaki
                user.password = request.POST.get('password')
302 bee5ffa6 Sofia Papagiannaki
                user.is_admin = False
303 bee5ffa6 Sofia Papagiannaki
                user.quota = 0
304 bee5ffa6 Sofia Papagiannaki
                user.state = 'UNVERIFIED'
305 bee5ffa6 Sofia Papagiannaki
                user.level = 1
306 bee5ffa6 Sofia Papagiannaki
                user.renew_token()
307 bee5ffa6 Sofia Papagiannaki
                try:
308 bee5ffa6 Sofia Papagiannaki
                    send_verification(user)
309 bee5ffa6 Sofia Papagiannaki
                    message = _('Verification sent to %s' % user.email)
310 bee5ffa6 Sofia Papagiannaki
                    user.save()
311 bee5ffa6 Sofia Papagiannaki
                except (SMTPException, socket.error) as e:
312 bee5ffa6 Sofia Papagiannaki
                    status = 'error'
313 bee5ffa6 Sofia Papagiannaki
                    name = 'strerror'
314 bee5ffa6 Sofia Papagiannaki
                    message = getattr(e, name) if hasattr(e, name) else e
315 bee5ffa6 Sofia Papagiannaki
        
316 bee5ffa6 Sofia Papagiannaki
        html = render_to_string('local_create.html', {
317 bee5ffa6 Sofia Papagiannaki
                'status': status,
318 bee5ffa6 Sofia Papagiannaki
                'message': message})
319 bee5ffa6 Sofia Papagiannaki
        return HttpResponse(html)
320 bee5ffa6 Sofia Papagiannaki
321 bee5ffa6 Sofia Papagiannaki
def send_password(user):
322 bee5ffa6 Sofia Papagiannaki
    url = settings.PASSWORD_RESET_TARGET % quote(user.auth_token)
323 bee5ffa6 Sofia Papagiannaki
    message = render_to_string('password.txt', {
324 bee5ffa6 Sofia Papagiannaki
            'user': user,
325 bee5ffa6 Sofia Papagiannaki
            'url': url,
326 bee5ffa6 Sofia Papagiannaki
            'baseurl': settings.BASE_URL,
327 bee5ffa6 Sofia Papagiannaki
            'service': settings.SERVICE_NAME,
328 bee5ffa6 Sofia Papagiannaki
            'support': settings.SUPPORT_EMAIL})
329 bee5ffa6 Sofia Papagiannaki
    sender = settings.DEFAULT_FROM_EMAIL
330 bee5ffa6 Sofia Papagiannaki
    send_mail('Pithos password recovering', message, sender, [user.email])
331 bee5ffa6 Sofia Papagiannaki
    logging.info('Sent password %s', user)
332 bee5ffa6 Sofia Papagiannaki
333 bee5ffa6 Sofia Papagiannaki
def reclaim_password(request):
334 bee5ffa6 Sofia Papagiannaki
    if request.method == 'GET':
335 bee5ffa6 Sofia Papagiannaki
        return render_response('reclaim.html')
336 bee5ffa6 Sofia Papagiannaki
    elif request.method == 'POST':
337 bee5ffa6 Sofia Papagiannaki
        username = request.POST.get('uniq')
338 bee5ffa6 Sofia Papagiannaki
        username = '%s@local' % username
339 bee5ffa6 Sofia Papagiannaki
        try:
340 bee5ffa6 Sofia Papagiannaki
            user = User.objects.get(uniq=username)
341 bee5ffa6 Sofia Papagiannaki
            try:
342 bee5ffa6 Sofia Papagiannaki
                send_password(user)
343 bee5ffa6 Sofia Papagiannaki
                status = 'success'
344 bee5ffa6 Sofia Papagiannaki
                message = _('Password reset sent to %s' % user.email)
345 bee5ffa6 Sofia Papagiannaki
                user.save()
346 bee5ffa6 Sofia Papagiannaki
            except (SMTPException, socket.error) as e:
347 bee5ffa6 Sofia Papagiannaki
                status = 'error'
348 bee5ffa6 Sofia Papagiannaki
                name = 'strerror'
349 bee5ffa6 Sofia Papagiannaki
                message = getattr(e, name) if hasattr(e, name) else e
350 bee5ffa6 Sofia Papagiannaki
        except User.DoesNotExist:
351 bee5ffa6 Sofia Papagiannaki
            status = 'error'
352 bee5ffa6 Sofia Papagiannaki
            message = 'Username does not exist'
353 bee5ffa6 Sofia Papagiannaki
        
354 bee5ffa6 Sofia Papagiannaki
        html = render_to_string('reclaim.html', {
355 bee5ffa6 Sofia Papagiannaki
                'status': status,
356 bee5ffa6 Sofia Papagiannaki
                'message': message})
357 bee5ffa6 Sofia Papagiannaki
        return HttpResponse(html)
358 bee5ffa6 Sofia Papagiannaki
359 bee5ffa6 Sofia Papagiannaki
def reset_password(request):
360 bee5ffa6 Sofia Papagiannaki
    if request.method == 'GET':
361 bee5ffa6 Sofia Papagiannaki
        token = request.GET.get('auth')
362 bee5ffa6 Sofia Papagiannaki
        next = request.GET.get('next')
363 bee5ffa6 Sofia Papagiannaki
        kwargs = {'auth': token,
364 bee5ffa6 Sofia Papagiannaki
                  'next': next}
365 bee5ffa6 Sofia Papagiannaki
        if not token:
366 bee5ffa6 Sofia Papagiannaki
            kwargs.update({'status': 'error',
367 bee5ffa6 Sofia Papagiannaki
                           'message': 'Missing token'})
368 bee5ffa6 Sofia Papagiannaki
        html = render_to_string('reset.html', kwargs)
369 bee5ffa6 Sofia Papagiannaki
        return HttpResponse(html)
370 bee5ffa6 Sofia Papagiannaki
    elif request.method == 'POST':
371 bee5ffa6 Sofia Papagiannaki
        token = request.POST.get('auth')
372 bee5ffa6 Sofia Papagiannaki
        password = request.POST.get('password')
373 bee5ffa6 Sofia Papagiannaki
        url = request.POST.get('next')
374 bee5ffa6 Sofia Papagiannaki
        if not token:
375 bee5ffa6 Sofia Papagiannaki
            status = 'error'
376 bee5ffa6 Sofia Papagiannaki
            message = 'Bad Request: missing token'
377 bee5ffa6 Sofia Papagiannaki
        try:
378 bee5ffa6 Sofia Papagiannaki
            user = User.objects.get(auth_token=token)
379 bee5ffa6 Sofia Papagiannaki
            user.password = password
380 bee5ffa6 Sofia Papagiannaki
            user.save()
381 bee5ffa6 Sofia Papagiannaki
            if url:
382 bee5ffa6 Sofia Papagiannaki
                return HttpResponseRedirect(url)
383 bee5ffa6 Sofia Papagiannaki
        except User.DoesNotExist:
384 bee5ffa6 Sofia Papagiannaki
            status = 'error'
385 bee5ffa6 Sofia Papagiannaki
            message = 'Bad Request: invalid token'
386 bee5ffa6 Sofia Papagiannaki
            
387 bee5ffa6 Sofia Papagiannaki
        html = render_to_string('reset.html', {
388 bee5ffa6 Sofia Papagiannaki
                'status': status,
389 bee5ffa6 Sofia Papagiannaki
                'message': message})
390 bee5ffa6 Sofia Papagiannaki
        return HttpResponse(html)