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 -*- # -*- 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 import logout, login, authenticate
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.utils.functional import Promise from django.contrib.auth.views import login as auth_login, logout as auth_logout
from django.utils.encoding import force_text
from django.utils.decorators import method_decorator
from django.utils import timezone
from django import http from django import http
from rest_framework.decorators import api_view from rest_framework.renderers import JSONRenderer
from rest_framework.response import Response from rest_framework.parsers import JSONParser
from rest_framework.reverse import reverse 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',)) class ApiRoot(APIView):
def api_root(request, format=None): def get(self, request, format=None):
return Response({ return Response({
'projects': reverse('project-list', request=request, format=format), 'login': reverse('login', request=request, format=format),
'milestones': reverse('milestone-list', request=request, format=format), 'logout': reverse('logout', request=request, format=format),
'user-stories': reverse('user-story-list', request=request, format=format), 'projects': reverse('project-list', request=request, format=format),
'changes': reverse('change-list', request=request, format=format), 'milestones': reverse('milestone-list', request=request, format=format),
'change-attachments': reverse('change-attachment-list', request=request, format=format), 'user-stories': reverse('user-story-list', request=request, format=format),
'tasks': reverse('task-list', request=request, format=format), 'changes': reverse('change-list', request=request, format=format),
'severities': reverse('severity-list', request=request, format=format), 'change-attachments': reverse('change-attachment-list', request=request, format=format),
'issue-status': reverse('issue-status-list', request=request, format=format), 'tasks': reverse('task-list', request=request, format=format),
'task-status': reverse('task-status-list', request=request, format=format), 'severities': reverse('severity-list', request=request, format=format),
'user-story-status': reverse('user-story-status-list', request=request, format=format), 'issue-status': reverse('issue-status-list', request=request, format=format),
'priorities': reverse('priority-list', request=request, format=format), 'task-status': reverse('task-status-list', request=request, format=format),
'issue-types': reverse('issue-type-list', request=request, format=format), 'user-story-status': reverse('user-story-status-list', request=request, format=format),
'points': reverse('points-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): class Login(APIView):
""" def post(self, request, format=None):
JSON encoder class for encode correctly traduction strings. username = request.DATA.get('username', None)
Is for ajax response encode. password = request.DATA.get('password', None)
"""
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)
try: try:
user = User.objects.get(username=username) user = User.objects.get(username=username)
if user.check_password(password): if user.check_password(password):
user = authenticate(username=username, password=password) user = authenticate(username=username, password=password)
login(request, user) 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: except User.DoesNotExist:
pass pass
return http.HttpResponseBadRequest() return http.HttpResponseBadRequest()
@method_decorator(csrf_exempt)
def dispatch(self, *args, **kwargs):
return super(Login, self).dispatch(*args, **kwargs)
class Logout(APIView):
class Logout(View): def post(self, request, format=None):
def post(self, request):
logout(request) logout(request)
return http.HttpResponse() 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) Points.objects.create(project=instance, name=name, order=order)
# Email alerts signals handlers # Email alerts signals handlers
# TODO: temporary commented (Pending refactor) # TODO: temporary commented (Pending refactor)
# from . import sigdispatch # from . import sigdispatch

View File

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