from django.template.loader import render_to_string
from django.utils.http import urlencode
from django.utils.translation import ugettext as _
+from django.core.urlresolvers import reverse
+
+from urllib import quote
from pithos.im.models import User, Invitation
from pithos.im.util import isoformat
if not settings.BYPASS_ADMIN_AUTH:
if not request.user:
next = urlencode({'next': request.build_absolute_uri()})
- login_uri = settings.LOGIN_URL + '?' + next
+ login_uri = reverse(index) + '?' + next
return HttpResponseRedirect(login_uri)
return func(request, *args)
return wrapper
if not settings.BYPASS_ADMIN_AUTH:
if not request.user:
next = urlencode({'next': request.build_absolute_uri()})
- login_uri = settings.LOGIN_URL + '?' + next
+ login_uri = reverse(index) + '?' + next
return HttpResponseRedirect(login_uri)
- if not request.user_obj.is_admin:
+ if not request.user.is_admin:
return HttpResponse('Forbidden', status=403)
return func(request, *args)
return wrapper
def index(request):
- # TODO: Get and pass on next variable.
- return render_response('index.html')
+ return render_response('index.html', next=request.GET.get('next', ''))
@requires_admin
page=page,
prev=prev,
next=next)
-
-
+
@requires_admin
def users_create(request):
if request.method == 'GET':
user.save()
return redirect(users_info, user.id)
-
@requires_admin
def users_info(request, user_id):
user = User.objects.get(id=user_id)
def generate_invitation_code():
- return randint(1, 2L**63 - 1)
+ while True:
+ code = randint(1, 2L**63 - 1)
+ try:
+ Invitation.objects.get(code=code)
+ # An invitation with this code already exists, try again
+ except Invitation.DoesNotExist:
+ return code
def send_invitation(inv):
subject = _('Invitation to Pithos')
message = render_to_string('invitation.txt', {
'invitation': inv,
- 'url': url})
+ 'url': url,
+ 'baseurl': settings.BASE_URL,
+ 'service': settings.SERVICE_NAME,
+ 'support': settings.SUPPORT_EMAIL})
sender = settings.DEFAULT_FROM_EMAIL
send_mail(subject, message, sender, [inv.uniq])
- inv.inviter.invitations = max(0, inv.inviter.invitations - 1)
- inv.inviter.save()
logging.info('Sent invitation %s', inv)
def invite(request):
status = None
message = None
+ inviter = request.user
if request.method == 'POST':
- if request.user_obj.invitations > 0:
+ uniq = request.POST.get('uniq')
+ realname = request.POST.get('realname')
+
+ if inviter.invitations > 0:
code = generate_invitation_code()
- invitation, created = Invitation.objects.get_or_create(code=code)
- invitation.inviter=request.user_obj
- invitation.realname=request.POST.get('realname')
- invitation.uniq=request.POST.get('uniq')
- invitation.save()
+ invitation, created = Invitation.objects.get_or_create(
+ inviter=inviter,
+ uniq=uniq,
+ defaults={'code': code, 'realname': realname})
try:
send_invitation(invitation)
+ if created:
+ inviter.invitations = max(0, inviter.invitations - 1)
+ inviter.save()
status = 'success'
- message = _('Invitation sent to %s' % invitation.uniq)
+ message = _('Invitation sent to %s' % uniq)
except (SMTPException, socket.error) as e:
status = 'error'
- message = e.strerror
+ message = getattr(e, 'strerror', '')
else:
status = 'error'
message = _('No invitations left')
if request.GET.get('format') == 'json':
- rep = {'invitations': request.user_obj.invitations}
+ sent = [{'email': inv.uniq,
+ 'realname': inv.realname,
+ 'is_accepted': inv.is_accepted}
+ for inv in inviter.invitations_sent.all()]
+ rep = {'invitations': inviter.invitations, 'sent': sent}
return HttpResponse(json.dumps(rep))
html = render_to_string('invitations.html', {
- 'user': request.user_obj,
+ 'user': inviter,
'status': status,
'message': message})
return HttpResponse(html)
+
+def send_verification(user):
+ url = settings.ACTIVATION_LOGIN_TARGET % quote(user.auth_token)
+ message = render_to_string('activation.txt', {
+ 'user': user,
+ 'url': url,
+ 'baseurl': settings.BASE_URL,
+ 'service': settings.SERVICE_NAME,
+ 'support': settings.SUPPORT_EMAIL})
+ sender = settings.DEFAULT_FROM_EMAIL
+ send_mail('Pithos account activation', message, sender, [user.email])
+ logging.info('Sent activation %s', user)
+
+def local_create(request):
+ if request.method == 'GET':
+ return render_response('local_create.html')
+ elif request.method == 'POST':
+ username = request.POST.get('uniq')
+ realname = request.POST.get('realname')
+ email = request.POST.get('email')
+ password = request.POST.get('password')
+ status = 'success'
+ if not username:
+ status = 'error'
+ message = 'No username provided'
+ elif not password:
+ status = 'error'
+ message = 'No password provided'
+ elif not email:
+ status = 'error'
+ message = 'No email provided'
+
+ if status == 'success':
+ username = '%s@local' % username
+ try:
+ user = User.objects.get(uniq=username)
+ status = 'error'
+ message = 'Username is not available'
+ except User.DoesNotExist:
+ user = User()
+ user.uniq = username
+ user.realname = realname
+ user.email = request.POST.get('email')
+ user.password = request.POST.get('password')
+ user.is_admin = False
+ user.quota = 0
+ user.state = 'UNVERIFIED'
+ user.level = 1
+ user.renew_token()
+ try:
+ send_verification(user)
+ message = _('Verification sent to %s' % user.email)
+ user.save()
+ except (SMTPException, socket.error) as e:
+ status = 'error'
+ name = 'strerror'
+ message = getattr(e, name) if hasattr(e, name) else e
+
+ html = render_to_string('local_create.html', {
+ 'status': status,
+ 'message': message})
+ return HttpResponse(html)
+
+def send_password(user):
+ url = settings.PASSWORD_RESET_TARGET % quote(user.auth_token)
+ message = render_to_string('password.txt', {
+ 'user': user,
+ 'url': url,
+ 'baseurl': settings.BASE_URL,
+ 'service': settings.SERVICE_NAME,
+ 'support': settings.SUPPORT_EMAIL})
+ sender = settings.DEFAULT_FROM_EMAIL
+ send_mail('Pithos password recovering', message, sender, [user.email])
+ logging.info('Sent password %s', user)
+
+def reclaim_password(request):
+ if request.method == 'GET':
+ return render_response('reclaim.html')
+ elif request.method == 'POST':
+ username = request.POST.get('uniq')
+ username = '%s@local' % username
+ try:
+ user = User.objects.get(uniq=username)
+ try:
+ send_password(user)
+ status = 'success'
+ message = _('Password reset sent to %s' % user.email)
+ user.save()
+ except (SMTPException, socket.error) as e:
+ status = 'error'
+ name = 'strerror'
+ message = getattr(e, name) if hasattr(e, name) else e
+ except User.DoesNotExist:
+ status = 'error'
+ message = 'Username does not exist'
+
+ html = render_to_string('reclaim.html', {
+ 'status': status,
+ 'message': message})
+ return HttpResponse(html)
+
+def reset_password(request):
+ if request.method == 'GET':
+ token = request.GET.get('auth')
+ next = request.GET.get('next')
+ kwargs = {'auth': token,
+ 'next': next}
+ if not token:
+ kwargs.update({'status': 'error',
+ 'message': 'Missing token'})
+ html = render_to_string('reset.html', kwargs)
+ return HttpResponse(html)
+ elif request.method == 'POST':
+ token = request.POST.get('auth')
+ password = request.POST.get('password')
+ url = request.POST.get('next')
+ if not token:
+ status = 'error'
+ message = 'Bad Request: missing token'
+ try:
+ user = User.objects.get(auth_token=token)
+ user.password = password
+ user.save()
+ if url:
+ return HttpResponseRedirect(url)
+ except User.DoesNotExist:
+ status = 'error'
+ message = 'Bad Request: invalid token'
+
+ html = render_to_string('reset.html', {
+ 'status': status,
+ 'message': message})
+ return HttpResponse(html)