from time import time, mktime
from urllib import quote
from urlparse import urlparse
+ from collections import defaultdict
from django.conf import settings
from django.http import HttpResponse
from django.utils import simplejson as json
from django.core.urlresolvers import reverse
- from astakos.im.faults import BadRequest, Unauthorized, InternalServerError, Fault
- from astakos.im.models import AstakosUser
- from astakos.im.settings import CLOUD_SERVICES, INVITATIONS_ENABLED, COOKIE_NAME
+ from astakos.im.api.faults import *
+ from astakos.im.models import AstakosUser, Service
+ from astakos.im.settings import INVITATIONS_ENABLED, COOKIE_NAME, EMAILCHANGE_ENABLED
from astakos.im.util import epoch
+ from astakos.im.api import _get_user_by_email, _get_user_by_username
logger = logging.getLogger(__name__)
+ format = ('%a, %d %b %Y %H:%M:%S GMT')
def render_fault(request, fault):
if isinstance(fault, InternalServerError) and settings.DEBUG:
response['Content-Length'] = len(response.content)
return response
- def api_method(http_method=None, token_required=False, perms=[]):
+ def api_method(http_method=None, token_required=False, perms=None):
"""Decorator function for views that implement an API method."""
+ if not perms:
+ perms = []
def decorator(func):
@wraps(func)
raise Unauthorized('Access denied')
try:
user = AstakosUser.objects.get(auth_token=x_auth_token)
+ ## Check if the token has expired.
+ #if (time() - mktime(user.auth_token_expires.timetuple())) > 0:
+ # raise Unauthorized('Authentication expired')
if not user.has_perms(perms):
- raise Unauthorized('Unauthorized request')
+ raise Forbidden('Unauthorized request')
except AstakosUser.DoesNotExist, e:
raise Unauthorized('Invalid X-Auth-Token')
kwargs['user'] = user
'auth_token_created':user.auth_token_created.isoformat(),
'auth_token_expires':user.auth_token_expires.isoformat(),
'has_credits':user.has_credits,
- 'has_signed_terms':user.signed_terms()}
+ 'has_signed_terms':user.signed_terms(),
+ 'groups':[g.name for g in user.groups.all()]}
response.content = json.dumps(user_info)
response['Content-Type'] = 'application/json; charset=UTF-8'
response['Content-Length'] = len(response.content)
@api_method(http_method='GET')
def get_services(request):
callback = request.GET.get('callback', None)
- data = json.dumps(CLOUD_SERVICES)
+ services = Service.objects.all()
+ data = tuple({'name':s.name, 'url':s.url, 'icon':s.icon} for s in services)
+ data = json.dumps(data)
mimetype = 'application/json'
if callback:
@api_method()
def get_menu(request, with_extra_links=False, with_signout=True):
- exclude = []
index_url = reverse('index')
absolute = lambda (url): request.build_absolute_uri(url)
l = [{ 'url': absolute(index_url), 'name': "Sign in"}]
if user.has_usable_password():
l.append({ 'url': absolute(reverse('password_change')),
'name': "Change password" })
+ if EMAILCHANGE_ENABLED:
+ l.append({'url':absolute(reverse('email_change')),
+ 'name': "Change email"})
if INVITATIONS_ENABLED:
l.append({ 'url': absolute(reverse('astakos.im.views.invite')),
'name': "Invitations" })
return HttpResponse(content=data, mimetype=mimetype)
- @api_method(http_method='GET', token_required=True, perms=['astakos.im.can_find_userid'])
- def find_userid(request):
- # Normal Response Codes: 204
+ @api_method(http_method='GET', token_required=True, perms=['im.can_access_userinfo'])
+ def get_user_by_email(request, user=None):
+ # Normal Response Codes: 200
# Error Response Codes: internalServerError (500)
# badRequest (400)
# unauthorised (401)
- email = request.GET.get('email')
- if not email:
- raise BadRequest('Email missing')
- try:
- user = AstakosUser.objects.get(email = email, is_active=True)
- except AstakosUser.DoesNotExist, e:
- raise BadRequest('Invalid email')
- else:
- response = HttpResponse()
- response.status=204
- user_info = {'userid':user.username}
- response.content = json.dumps(user_info)
- response['Content-Type'] = 'application/json; charset=UTF-8'
- response['Content-Length'] = len(response.content)
- return response
-
- @api_method(http_method='GET', token_required=True, perms=['astakos.im.can_find_email'])
- def find_email(request):
- # Normal Response Codes: 204
+ # forbidden (403)
+ # itemNotFound (404)
+ email = request.GET.get('name')
+ return _get_user_by_email(email)
+
+ @api_method(http_method='GET', token_required=True, perms=['im.can_access_userinfo'])
+ def get_user_by_username(request, user_id, user=None):
+ # Normal Response Codes: 200
# Error Response Codes: internalServerError (500)
# badRequest (400)
# unauthorised (401)
- userid = request.GET.get('userid')
- if not userid:
- raise BadRequest('Userid missing')
- try:
- user = AstakosUser.objects.get(username = userid)
- except AstakosUser.DoesNotExist, e:
- raise BadRequest('Invalid userid')
- else:
- response = HttpResponse()
- response.status=204
- user_info = {'userid':user.email}
- response.content = json.dumps(user_info)
- response['Content-Type'] = 'application/json; charset=UTF-8'
- response['Content-Length'] = len(response.content)
- return response
+ # forbidden (403)
+ # itemNotFound (404)
- return _get_user_by_username(user_id)
++ return _get_user_by_username(user_id)
from django.core.mail import send_mail
from django.core.urlresolvers import reverse
from django.core.exceptions import ValidationError
+ from django.template import Context, loader
+ from django.contrib.auth import login as auth_login, logout as auth_logout
+ from django.http import HttpRequest
from urllib import quote
from urlparse import urljoin
from smtplib import SMTPException
+ from datetime import datetime
+ from functools import wraps
- from astakos.im.settings import DEFAULT_CONTACT_EMAIL, DEFAULT_FROM_EMAIL, SITENAME, BASEURL, DEFAULT_ADMIN_EMAIL
+ from astakos.im.settings import DEFAULT_CONTACT_EMAIL, DEFAULT_FROM_EMAIL, \
+ SITENAME, BASEURL, DEFAULT_ADMIN_EMAIL, LOGGING_LEVEL
from astakos.im.models import Invitation, AstakosUser
logger = logging.getLogger(__name__)
+ def logged(func, msg):
+ @wraps(func)
+ def with_logging(*args, **kwargs):
+ email = ''
+ user = None
+ if len(args) == 2 and isinstance(args[1], AstakosUser):
+ user = args[1]
+ elif len(args) == 1 and isinstance(args[0], HttpRequest):
+ request = args[0]
+ user = request.user
+ email = user.email if user and user.is_authenticated() else ''
+ r = func(*args, **kwargs)
+ if LOGGING_LEVEL:
+ logger._log(LOGGING_LEVEL, msg % email, [])
+ return r
+ return with_logging
+
+ login = logged(auth_login, '%s logged in.')
+ logout = logged(auth_logout, '%s logged out.')
+
def send_verification(user, template_name='im/activation_email.txt'):
"""
Send email to user to verify his/her email and activate his/her account.
"""
url = '%s?auth=%s&next=%s' % (urljoin(BASEURL, reverse('astakos.im.views.activate')),
quote(user.auth_token),
- quote(BASEURL))
+ quote(urljoin(BASEURL, reverse('astakos.im.views.index'))))
message = render_to_string(template_name, {
'user': user,
'url': url,
logger.exception(e)
raise SendVerificationError()
else:
- logger.info('Sent activation %s', user)
+ msg = 'Sent activation %s' % user.email
+ logger._log(LOGGING_LEVEL, msg, [])
+
+ def send_activation(user, template_name='im/activation_email.txt'):
+ send_verification(user, template_name)
+ user.activation_sent = datetime.now()
+ user.save()
def send_admin_notification(user, template_name='im/admin_notification.txt'):
"""
logger.exception(e)
raise SendNotificationError()
else:
- logger.info('Sent admin notification for user %s', user)
+ msg = 'Sent admin notification for user %s' % user.email
+ logger._log(LOGGING_LEVEL, msg, [])
def send_invitation(invitation, template_name='im/invitation.txt'):
"""
logger.exception(e)
raise SendInvitationError()
else:
- logger.info('Sent invitation %s', invitation)
+ msg = 'Sent invitation %s' % invitation
+ logger._log(LOGGING_LEVEL, msg, [])
def send_greeting(user, email_template_name='im/welcome_email.txt'):
"""
logger.exception(e)
raise SendGreetingError()
else:
- logger.info('Sent greeting %s', user)
+ msg = 'Sent greeting %s' % user.email
+ logger._log(LOGGING_LEVEL, msg, [])
def send_feedback(msg, data, user, email_template_name='im/feedback_mail.txt'):
subject = _("Feedback from %s alpha2 testing" % SITENAME)
logger.exception(e)
raise SendFeedbackError()
else:
- logger.info('Sent feedback from %s', user.email)
+ msg = 'Sent feedback from %s' % user.email
+ logger._log(LOGGING_LEVEL, msg, [])
+
+ def send_change_email(ec, request, email_template_name='registration/email_change_email.txt'):
+ try:
+ url = reverse('email_change_confirm',
+ kwargs={'activation_key':ec.activation_key})
+ url = request.build_absolute_uri(url)
+ t = loader.get_template(email_template_name)
+ c = {'url': url, 'site_name': SITENAME}
+ from_email = DEFAULT_FROM_EMAIL
+ send_mail(_("Email change on %s alpha2 testing") % SITENAME,
+ t.render(Context(c)), from_email, [ec.new_email_address])
+ except (SMTPException, socket.error) as e:
+ logger.exception(e)
+ raise ChangeEmailError()
+ else:
+ msg = 'Sent change email for %s' % ec.user.email
+ logger._log(LOGGING_LEVEL, msg, [])
def activate(user, email_template_name='im/welcome_email.txt'):
"""
class SendFeedbackError(SendMailError):
def __init__(self):
self.message = _('Failed to send feedback')
- super(SendFeedbackError, self).__init__()
+ super(SendFeedbackError, self).__init__()
+
+ class ChangeEmailError(SendMailError):
+ def __init__(self):
+ self.message = _('Failed to send change email')
- super(ChangeEmailError, self).__init__()
++ super(ChangeEmailError, self).__init__()