Adding better login rest actions
parent
8654db4ab8
commit
4441ed8951
|
@ -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)
|
|
@ -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'),
|
||||||
|
))
|
|
@ -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)
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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')),
|
||||||
|
|
Loading…
Reference in New Issue