Adding better login rest actions

remotes/origin/enhancement/email-actions
Jesús Espino 2013-03-27 18:47:08 +01:00
parent 8654db4ab8
commit 4441ed8951
5 changed files with 91 additions and 77 deletions

View File

@ -0,0 +1,34 @@
from rest_framework import serializers
class UserLogged(object):
def __init__(self, token, username, first_name, last_name, email, last_login):
self.token = token
self.username = username
self.first_name = first_name
self.last_name = last_name
self.email = email
self.last_login = last_login
class LoginSerializer(serializers.Serializer):
token = serializers.CharField(max_length=40)
username = serializers.CharField(max_length=30)
first_name = serializers.CharField(max_length=30)
last_name = serializers.CharField(max_length=30)
email = serializers.EmailField()
last_login = serializers.DateTimeField()
def restore_object(self, attrs, instance=None):
"""
Given a dictionary of deserialized field values, either update
an existing model instance, or create a new model instance.
"""
if instance is not None:
instance.token = attrs.get('token', None)
instance.username = attrs.get('username', instance.username)
instance.first_name = attrs.get('first_name', instance.first_name)
instance.last_name = attrs.get('last_name', instance.last_name)
instance.email = attrs.get('email', instance.email)
instance.last_login = attrs.get('last_login', instance.last_login)
return instance
return UserLogged(**attrs)

10
greenmine/base/urls.py Normal file
View File

@ -0,0 +1,10 @@
from django.conf.urls import patterns, url
from rest_framework.urlpatterns import format_suffix_patterns
from greenmine.base.views import Login, Logout, ApiRoot
urlpatterns = format_suffix_patterns(patterns('',
url(r'^auth/login/$', Login.as_view(), name='login'),
url(r'^auth/logout/$', Logout.as_view(), name='logout'),
url(r'^$', ApiRoot.as_view(), name='api_root'),
))

View File

@ -1,97 +1,70 @@
# -*- coding: utf-8 -*-
import datetime
import json
from django.core.serializers.json import DjangoJSONEncoder
from django.views.generic.base import View
from django.views.decorators.csrf import csrf_exempt
from django.contrib.auth import logout, login, authenticate
from django.contrib.auth.models import User
from django.utils.functional import Promise
from django.utils.encoding import force_text
from django.utils.decorators import method_decorator
from django.utils import timezone
from django.contrib.auth.views import login as auth_login, logout as auth_logout
from django import http
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.renderers import JSONRenderer
from rest_framework.parsers import JSONParser
from rest_framework.reverse import reverse
from rest_framework.views import APIView
from rest_framework.response import Response
from greenmine.base.serializers import LoginSerializer, UserLogged
@api_view(('GET',))
def api_root(request, format=None):
return Response({
'projects': reverse('project-list', request=request, format=format),
'milestones': reverse('milestone-list', request=request, format=format),
'user-stories': reverse('user-story-list', request=request, format=format),
'changes': reverse('change-list', request=request, format=format),
'change-attachments': reverse('change-attachment-list', request=request, format=format),
'tasks': reverse('task-list', request=request, format=format),
'severities': reverse('severity-list', request=request, format=format),
'issue-status': reverse('issue-status-list', request=request, format=format),
'task-status': reverse('task-status-list', request=request, format=format),
'user-story-status': reverse('user-story-status-list', request=request, format=format),
'priorities': reverse('priority-list', request=request, format=format),
'issue-types': reverse('issue-type-list', request=request, format=format),
'points': reverse('points-list', request=request, format=format),
})
class ApiRoot(APIView):
def get(self, request, format=None):
return Response({
'login': reverse('login', request=request, format=format),
'logout': reverse('logout', request=request, format=format),
'projects': reverse('project-list', request=request, format=format),
'milestones': reverse('milestone-list', request=request, format=format),
'user-stories': reverse('user-story-list', request=request, format=format),
'changes': reverse('change-list', request=request, format=format),
'change-attachments': reverse('change-attachment-list', request=request, format=format),
'tasks': reverse('task-list', request=request, format=format),
'severities': reverse('severity-list', request=request, format=format),
'issue-status': reverse('issue-status-list', request=request, format=format),
'task-status': reverse('task-status-list', request=request, format=format),
'user-story-status': reverse('user-story-status-list', request=request, format=format),
'priorities': reverse('priority-list', request=request, format=format),
'issue-types': reverse('issue-type-list', request=request, format=format),
'points': reverse('points-list', request=request, format=format),
})
class LazyEncoder(DjangoJSONEncoder):
"""
JSON encoder class for encode correctly traduction strings.
Is for ajax response encode.
"""
def default(self, obj):
if isinstance(obj, Promise):
return force_text(obj)
elif isinstance(obj, datetime.datetime):
obj = timezone.localtime(obj)
return super(LazyEncoder, self).default(obj)
def request_json_to_dict(request):
try:
body = request.body.decode('utf-8')
return json.loads(body)
except Exception:
return {}
def to_json(data):
return json.dumps(data)
class Login(View):
def post(self, request):
data = request_json_to_dict(request)
username = data.get('username', None)
password = data.get('password', None)
class Login(APIView):
def post(self, request, format=None):
username = request.DATA.get('username', None)
password = request.DATA.get('password', None)
try:
user = User.objects.get(username=username)
if user.check_password(password):
user = authenticate(username=username, password=password)
login(request, user)
return http.HttpResponse(to_json({'token': request.session.session_key}))
return_data = LoginSerializer(UserLogged(**{
'token': request.session.session_key,
'username': request.user.username,
'first_name': request.user.first_name,
'last_name': request.user.last_name,
'email': request.user.email,
'last_login': request.user.last_login,
}))
return http.HttpResponse(JSONRenderer().render(return_data.data),
content_type="application/json",
status=201)
except User.DoesNotExist:
pass
return http.HttpResponseBadRequest()
@method_decorator(csrf_exempt)
def dispatch(self, *args, **kwargs):
return super(Login, self).dispatch(*args, **kwargs)
class Logout(View):
def post(self, request):
class Logout(APIView):
def post(self, request, format=None):
logout(request)
return http.HttpResponse()
@method_decorator(csrf_exempt)
def dispatch(self, *args, **kwargs):
return super(Login, self).dispatch(*args, **kwargs)

View File

@ -433,7 +433,6 @@ def project_post_save(sender, instance, created, **kwargs):
Points.objects.create(project=instance, name=name, order=order)
# Email alerts signals handlers
# TODO: temporary commented (Pending refactor)
# from . import sigdispatch

View File

@ -3,12 +3,10 @@ from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
from greenmine.base.views import Login, Logout
from greenmine.base.views import ApiRoot
urlpatterns = patterns('',
url(r'^api/auth/login/$', Login.as_view(), name='api-login'),
url(r'^api/auth/logout/$', Logout.as_view(), name='api-logout'),
url(r'^api/$', 'greenmine.base.views.api_root'),
url(r'^api/', include('greenmine.base.urls')),
url(r'^api/scrum/', include('greenmine.scrum.urls')),
url(r'^admin/', include(admin.site.urls)),
url(r'^grappelli/', include('grappelli.urls')),