Commit 03989039 authored by Sofia Papagiannaki's avatar Sofia Papagiannaki

Fix code formatting to conform to the PEP 8 style guide

parent d30a7346
# Copyright (c) Django Software Foundation and individual contributors.
# All rights reserved.
#
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
#
# 3. Neither the name of Django nor the names of its contributors may be used
# to endorse or promote products derived from this software without
# specific prior written permission.
#
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
......@@ -28,6 +28,7 @@
VERSION = (0, 3, 0, 'alpha', 0)
def get_version():
version = '%s.%s' % (VERSION[0], VERSION[1])
if VERSION[2]:
......
......@@ -47,6 +47,7 @@ import re
logger = logging.getLogger(__name__)
def get_backend(request):
"""
Returns an instance of an activation backend,
......@@ -59,34 +60,36 @@ def get_backend(request):
"""
module = 'astakos.im.activation_backends'
prefix = 'Invitations' if INVITATIONS_ENABLED else 'Simple'
backend_class_name = '%sBackend' %prefix
backend_class_name = '%sBackend' % prefix
try:
mod = import_module(module)
except ImportError, e:
raise ImproperlyConfigured('Error loading activation backend %s: "%s"' % (module, e))
raise ImproperlyConfigured(
'Error loading activation backend %s: "%s"' % (module, e))
try:
backend_class = getattr(mod, backend_class_name)
except AttributeError:
raise ImproperlyConfigured('Module "%s" does not define a activation backend named "%s"' % (module, backend_class_name))
return backend_class(request)
class ActivationBackend(object):
def __init__(self, request):
self.request = request
def _is_preaccepted(self, user):
# return True if user email matches specific patterns
for pattern in RE_USER_EMAIL_PATTERNS:
if re.match(pattern, user.email):
return True
return False
def get_signup_form(self, provider='local', instance=None):
"""
Returns a form instance of the relevant class
"""
main = provider.capitalize() if provider == 'local' else 'ThirdParty'
suffix = 'UserCreationForm'
suffix = 'UserCreationForm'
formclass = '%s%s' % (main, suffix)
request = self.request
initial_data = None
......@@ -94,11 +97,11 @@ class ActivationBackend(object):
if provider == request.POST.get('provider', ''):
initial_data = request.POST
return globals()[formclass](initial_data, instance=instance, request=request)
def handle_activation(self, user, \
activation_template_name='im/activation_email.txt', \
greeting_template_name='im/welcome_email.txt', \
admin_email_template_name='im/account_notification.txt', \
def handle_activation(self, user,
activation_template_name='im/activation_email.txt',
greeting_template_name='im/welcome_email.txt',
admin_email_template_name='im/account_notification.txt',
switch_accounts_email_template_name='im/switch_accounts_email.txt'):
"""
If the user is already active returns immediately.
......@@ -117,7 +120,7 @@ class ActivationBackend(object):
if user.conflicting_email():
send_verification(user, switch_accounts_email_template_name)
return SwitchAccountsVerificationSent(user.email)
if self._is_preaccepted(user):
if user.email_verified:
activate(user, greeting_template_name)
......@@ -128,7 +131,7 @@ class ActivationBackend(object):
else:
send_admin_notification(
template_name=admin_email_template_name,
dictionary={'user':user, 'group_creation':True},
dictionary={'user': user, 'group_creation': True},
subject='%s alpha2 testing account notification' % SITENAME
)
return NotificationSent()
......@@ -136,6 +139,7 @@ class ActivationBackend(object):
logger.exception(e)
raise e
class InvitationsBackend(ActivationBackend):
"""
A activation backend which implements the following workflow: a user
......@@ -148,7 +152,7 @@ class InvitationsBackend(ActivationBackend):
def get_signup_form(self, provider='local', instance=None):
"""
Returns a form instance of the relevant class
raises Invitation.DoesNotExist and ValueError if invitation is consumed
or invitation username is reserved.
"""
......@@ -157,7 +161,7 @@ class InvitationsBackend(ActivationBackend):
initial_data = self.get_signup_initial_data(provider)
prefix = 'Invited' if invitation else ''
main = provider.capitalize()
suffix = 'UserCreationForm'
suffix = 'UserCreationForm'
formclass = '%s%s%s' % (prefix, main, suffix)
return globals()[formclass](initial_data, instance=instance, request=self.request)
......@@ -174,12 +178,12 @@ class InvitationsBackend(ActivationBackend):
if invitation:
# create a tmp user with the invitation realname
# to extract first and last name
u = AstakosUser(realname = invitation.realname)
initial_data = {'email':invitation.username,
'inviter':invitation.inviter.realname,
'first_name':u.first_name,
'last_name':u.last_name,
'provider':provider}
u = AstakosUser(realname=invitation.realname)
initial_data = {'email': invitation.username,
'inviter': invitation.inviter.realname,
'first_name': u.first_name,
'last_name': u.last_name,
'provider': provider}
else:
if provider == request.POST.get('provider', ''):
initial_data = request.POST
......@@ -200,6 +204,7 @@ class InvitationsBackend(ActivationBackend):
return True
return False
class SimpleBackend(ActivationBackend):
"""
A activation backend which implements the following workflow: a user
......@@ -213,15 +218,18 @@ class SimpleBackend(ActivationBackend):
return False
return True
class ActivationResult(object):
def __init__(self, message):
self.message = message
class VerificationSent(ActivationResult):
def __init__(self):
message = _('Verification sent.')
super(VerificationSent, self).__init__(message)
class SwitchAccountsVerificationSent(ActivationResult):
def __init__(self, email):
message = _('This email is already associated with another \
......@@ -230,6 +238,7 @@ class SwitchAccountsVerificationSent(ActivationResult):
to %s. Otherwise just ignore it.' % email)
super(SwitchAccountsVerificationSent, self).__init__(message)
class NotificationSent(ActivationResult):
def __init__(self):
message = _('Your request for an account was successfully received and is now pending \
......@@ -237,7 +246,8 @@ class NotificationSent(ActivationResult):
your interest in ~okeanos! The GRNET team.')
super(NotificationSent, self).__init__(message)
class RegistationCompleted(ActivationResult):
def __init__(self):
message = _('Registration completed. You can now login.')
super(RegistationCompleted, self).__init__(message)
\ No newline at end of file
super(RegistationCompleted, self).__init__(message)
......@@ -51,6 +51,7 @@ format = ('%a, %d %b %Y %H:%M:%S GMT')
absolute = lambda request, url: request.build_absolute_uri(url)
def render_fault(request, fault):
if isinstance(fault, InternalServerError) and settings.DEBUG:
fault.details = format_exc(fault)
......@@ -63,6 +64,7 @@ def render_fault(request, fault):
response['Content-Length'] = len(response.content)
return response
def api_method(http_method=None):
"""Decorator function for views that implement an API method."""
def decorator(func):
......@@ -82,61 +84,65 @@ def api_method(http_method=None):
return wrapper
return decorator
def _get_user_by_username(user_id):
try:
user = AstakosUser.objects.get(username = user_id)
user = AstakosUser.objects.get(username=user_id)
except AstakosUser.DoesNotExist:
raise ItemNotFound('Invalid userid')
else:
response = HttpResponse()
response.status=200
user_info = {'id':user.id,
'username':user.username,
'email':[user.email],
'name':user.realname,
'auth_token_created':user.auth_token_created.strftime(format),
'auth_token_expires':user.auth_token_expires.strftime(format),
'has_credits':user.has_credits,
'enabled':user.is_active,
'groups':[g.name for g in user.groups.all()]}
response.status = 200
user_info = {'id': user.id,
'username': user.username,
'email': [user.email],
'name': user.realname,
'auth_token_created': user.auth_token_created.strftime(format),
'auth_token_expires': user.auth_token_expires.strftime(format),
'has_credits': user.has_credits,
'enabled': user.is_active,
'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)
return response
def _get_user_by_email(email):
if not email:
raise BadRequest('Email missing')
try:
user = AstakosUser.objects.get(email = email)
user = AstakosUser.objects.get(email=email)
except AstakosUser.DoesNotExist:
raise ItemNotFound('Invalid email')
if not user.is_active:
raise ItemNotFound('Inactive user')
else:
response = HttpResponse()
response.status=200
user_info = {'id':user.id,
'username':user.username,
'email':[user.email],
'enabled':user.is_active,
'name':user.realname,
'auth_token_created':user.auth_token_created.strftime(format),
'auth_token_expires':user.auth_token_expires.strftime(format),
'has_credits':user.has_credits,
'groups':[g.name for g in user.groups.all()],
'user_permissions':[p.codename for p in user.user_permissions.all()]}
response.status = 200
user_info = {'id': user.id,
'username': user.username,
'email': [user.email],
'enabled': user.is_active,
'name': user.realname,
'auth_token_created': user.auth_token_created.strftime(format),
'auth_token_expires': user.auth_token_expires.strftime(format),
'has_credits': user.has_credits,
'groups': [g.name for g in user.groups.all()],
'user_permissions': [p.codename for p in user.user_permissions.all()]}
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')
def get_services(request):
callback = request.GET.get('callback', None)
services = Service.objects.all()
data = tuple({'id':s.pk, 'name':s.name, 'url':s.url, 'icon':s.icon} for s in services)
data = tuple({'id': s.pk, 'name': s.name, 'url': s.url, 'icon':
s.icon} for s in services)
data = json.dumps(data)
mimetype = 'application/json'
......@@ -146,6 +152,7 @@ def get_services(request):
return HttpResponse(content=data, mimetype=mimetype)
@api_method()
def get_menu(request, with_extra_links=False, with_signout=True):
user = request.user
......@@ -159,7 +166,7 @@ def get_menu(request, with_extra_links=False, with_signout=True):
pass
if not isinstance(user, AstakosUser):
index_url = reverse('index')
l = [{ 'url': absolute(request, index_url), 'name': "Sign in"}]
l = [{'url': absolute(request, index_url), 'name': "Sign in"}]
else:
l = []
append = l.append
......@@ -216,8 +223,8 @@ def get_menu(request, with_extra_links=False, with_signout=True):
),
item(
url=absolute(request,
reverse('group_create_list')
),
reverse('group_create_list')
),
name="Create"
),
item(
......@@ -246,7 +253,7 @@ def get_menu(request, with_extra_links=False, with_signout=True):
name="Sign out"
)
)
callback = request.GET.get('callback', None)
data = json.dumps(tuple(l))
mimetype = 'application/json'
......@@ -257,19 +264,20 @@ def get_menu(request, with_extra_links=False, with_signout=True):
return HttpResponse(content=data, mimetype=mimetype)
class MenuItem(dict):
current_path = ''
def __init__(self, *args, **kwargs):
super(MenuItem, self).__init__(*args, **kwargs)
if kwargs.get('url') or kwargs.get('submenu'):
self.__set_is_active__()
def __setitem__(self, key, value):
super(MenuItem, self).__setitem__(key, value)
if key in ('url', 'submenu'):
self.__set_is_active__()
def __set_is_active__(self):
if self.get('is_active'):
return
......@@ -285,8 +293,8 @@ class MenuItem(dict):
self.__setitem__('is_active', True)
except StopIteration:
return
def __setattribute__(self, name, value):
super(MenuItem, self).__setattribute__(name, value)
if name == 'current_path':
self.__set_is_active__()
\ No newline at end of file
self.__set_is_active__()
......@@ -39,7 +39,8 @@ from time import time, mktime
from django.http import HttpResponse
from django.utils import simplejson as json
from astakos.im.api.faults import (Fault, Unauthorized, InternalServerError, BadRequest,
from astakos.im.api.faults import (
Fault, Unauthorized, InternalServerError, BadRequest,
Forbidden)
from astakos.im.api import render_fault, _get_user_by_email, _get_user_by_username
from astakos.im.models import AstakosUser
......@@ -48,6 +49,7 @@ from astakos.im.util import epoch
logger = logging.getLogger(__name__)
format = ('%a, %d %b %Y %H:%M:%S GMT')
def api_method(http_method=None, token_required=False, perms=None):
"""Decorator function for views that implement an API method."""
if not perms:
......@@ -81,6 +83,7 @@ def api_method(http_method=None, token_required=False, perms=None):
return wrapper
return decorator
@api_method(http_method='GET', token_required=True)
def authenticate_old(request, user=None):
# Normal Response Codes: 204
......@@ -102,20 +105,21 @@ def authenticate_old(request, user=None):
raise Unauthorized('Pending approval terms')
response = HttpResponse()
response.status=204
user_info = {'username':user.username,
'uniq':user.email,
'auth_token':user.auth_token,
'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,
'groups':[g.name for g in user.groups.all()]}
response.status = 204
user_info = {'username': user.username,
'uniq': user.email,
'auth_token': user.auth_token,
'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,
'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)
return response
@api_method(http_method='GET', token_required=True)
def authenticate(request, user=None):
# Normal Response Codes: 204
......@@ -137,21 +141,22 @@ def authenticate(request, user=None):
raise Unauthorized('Pending approval terms')
response = HttpResponse()
response.status=204
user_info = {'userid':user.username,
'email':[user.email],
'name':user.realname,
'auth_token':user.auth_token,
'auth_token_created':epoch(user.auth_token_created),
'auth_token_expires':epoch(user.auth_token_expires),
'has_credits':user.has_credits,
'is_active':user.is_active,
'groups':[g.name for g in user.groups.all()]}
response.status = 204
user_info = {'userid': user.username,
'email': [user.email],
'name': user.realname,
'auth_token': user.auth_token,
'auth_token_created': epoch(user.auth_token_created),
'auth_token_expires': epoch(user.auth_token_expires),
'has_credits': user.has_credits,
'is_active': user.is_active,
'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)
return response
@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
......@@ -163,6 +168,7 @@ def get_user_by_email(request, user=None):
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
......
# Copyright 2011-2012 GRNET S.A. All rights reserved.
#
#
# Redistribution and use in source and binary forms, with or
# without modification, are permitted provided that the following
# conditions are met:
#
#
# 1. Redistributions of source code must retain the above
# copyright notice, this list of conditions and the following
# disclaimer.
#
#
# 2. Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials
# provided with the distribution.
#
#
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
......@@ -25,15 +25,17 @@
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
#
# The views and conclusions contained in the software and
# documentation are those of the authors and should not be
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
def camelCase(s):
return s[0].lower() + s[1:]
class Fault(Exception):
def __init__(self, message='', details='', name=''):
Exception.__init__(self, message, details, name)
......@@ -41,17 +43,22 @@ class Fault(Exception):
self.details = details
self.name = name or camelCase(self.__class__.__name__)
class BadRequest(Fault):
code = 400
class Unauthorized(Fault):
code = 401
class InternalServerError(Fault):
code = 500
class Forbidden(Fault):
code = 403
class ItemNotFound(Fault):
code = 404
\ No newline at end of file
code = 404
......@@ -47,6 +47,7 @@ from astakos.im.functions import send_feedback as send_feedback_func
logger = logging.getLogger(__name__)
def api_method(http_method=None, token_required=False):
"""Decorator function for views that implement an API method."""
def decorator(func):
......@@ -61,7 +62,7 @@ def api_method(http_method=None, token_required=False):
raise Unauthorized('Access denied')
try:
service = Service.objects.get(auth_token=x_auth_token)
# Check if the token has expired.
if (time() - mktime(service.auth_token_expires.timetuple())) > 0:
raise Unauthorized('Authentication expired')
......@@ -78,6 +79,7 @@ def api_method(http_method=None, token_required=False):
return wrapper
return decorator
@api_method(http_method='GET', token_required=True)
def get_user_by_email(request, user=None):
# Normal Response Codes: 200
......@@ -89,6 +91,7 @@ def get_user_by_email(request, user=None):
email = request.GET.get('name')
return _get_user_by_email(email)
@api_method(http_method='GET', token_required=True)
def get_user_by_username(request, user_id, user=None):
# Normal Response Codes: 200
......@@ -99,6 +102,7 @@ def get_user_by_username(request, user_id, user=None):
# itemNotFound (404)
return _get_user_by_username(user_id)
@csrf_exempt
@api_method(http_method='POST', token_required=True)