add full authorization

develop
TBS093A 2020-06-20 17:16:55 +02:00
parent 08f29d5cc6
commit 88b75e1e9c
10 changed files with 88 additions and 33 deletions

View File

@ -1,10 +1,8 @@
from django.db import models
from django.http import HttpResponse
from django.contrib.auth.models import User
from django.contrib.auth import authenticate
from rest_framework.response import Response
from rest_framework.authtoken.models import Token
from rest_framework import serializers
@ -12,18 +10,29 @@ class AbstractUser(models.Model):
city = models.CharField(verbose_name='City', max_length=255)
country = models.CharField(verbose_name='Country', max_length=255)
ip = models.CharField(verbose_name='IP', max_length=15)
def fromDict(self, dict):
self.__dict__.update(dict)
class Meta:
abstract = True
class Account(User, AbstractUser):
def fromDict(self, dict):
self.__dict__.update(dict)
def toDict(self) -> dict:
return {
'id': self.id,
'username': self.username,
'password': None,
'email': self.email,
'ip': self.ip,
'city': self.city,
'country': self.country
}
@staticmethod
def register(userDict) -> object:
def register(userDict) -> dict:
account = Account.objects.create_user(
userDict['username'],
userDict['email'],
@ -33,26 +42,15 @@ class Account(User, AbstractUser):
account.city = userDict['city'],
account.country = userDict['country']
account.save()
return account
return account.toDict()
def login(self, username, password) -> dict:
tryLogin = authenticate(username = username, password = password)
if tryLogin is not None:
user = Account.objects.get(username = username)
token = Token.objects.create(user = user)
return token.__dict__
else:
return { 'error': 'login failed'}
def logout(self):
pass
def update(self, userDict):
def update(self, userDict) -> dict:
if 'password' in userDict:
password = userDict.pop('password')
self.set_password(password)
self.fromDict(userDict)
self.save()
self.save()
return self.toDict()
def set_password(self, raw_password):
return super().set_password(raw_password)

View File

@ -1,6 +1,9 @@
from .models import Account, Guest
from rest_framework import serializers
from rest_framework import serializers
from rest_framework.authtoken.models import Token
from django.contrib.auth import authenticate, logout
from django.core.paginator import Paginator
from django.http import JsonResponse
@ -25,12 +28,40 @@ class AccountSerializer(AccountGetSerializer):
return Account.register(validated_data)
def update(self, instance, validated_data):
return instance.update(instance, **validated_data)
return instance.update(validated_data)
class Meta:
model = Account
fields = ['id', 'username', 'password', 'email', 'ip', 'city', 'country']
class AccountAuthSerializer(serializers.ModelSerializer):
username = serializers.CharField(max_length = 100)
password = serializers.CharField(max_length = 100)
@staticmethod
def login(username, password) -> dict:
tryLogin = authenticate(username = username, password = password)
if tryLogin is not None:
user = Account.objects.get(username = username)
try:
token = Token.objects.get(user = user)
except:
token = Token.objects.create(user = user)
return { 'token': token.key, 'user': user.toDict() }
else:
return { 'error': 'login failed'}
@staticmethod
def logout(request, format=None):
tokenStr = request.headers['Authorization'].split(' ')[1]
token = Token.objects.get(key = tokenStr)
token.delete()
return { 'info': 'logout' }
class Meta:
model = Account
fields = ['username', 'password']
class GuestSerializer(serializers.HyperlinkedModelSerializer):
id = serializers.IntegerField(read_only = True)

View File

@ -1,4 +1,5 @@
from rest_framework import viewsets
from rest_framework import viewsets, mixins, permissions
from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.response import Response
from drf_yasg.utils import swagger_auto_schema
@ -6,13 +7,14 @@ from django.core.paginator import Paginator
from django.shortcuts import get_object_or_404
from .models import Account, Guest
from .serializers import AccountSerializer, GuestSerializer, AccountGetSerializer
from .serializers import *
class AccountViewSet(viewsets.ModelViewSet):
queryset = Account.objects.all()
serializer_class = AccountSerializer
permission_classes = [permissions.IsAuthenticated]
@swagger_auto_schema(responses={ 200: AccountGetSerializer })
def retrieve(self, request, pk=None):
@ -27,6 +29,27 @@ class AccountViewSet(viewsets.ModelViewSet):
return Response(serializer.data)
class AccountAuth(ObtainAuthToken):
queryset = Account.objects.all()
serializer_class = AccountAuthSerializer
@swagger_auto_schema(
responses={ 200: '{ Token: Authorize }' },
request_body=AccountAuthSerializer
)
def post(self, request, *args, **kwargs):
serializer = self.serializer_class(data=request.data, context={'request': request})
serializer.is_valid(raise_exception=True)
username = serializer.validated_data['username']
password = serializer.validated_data['password']
return Response(AccountAuthSerializer.login(username, password))
@swagger_auto_schema(responses={ 200: '{ info: logout }' })
def delete(self, request, *args, **kwargs):
return Response(self.serializer_class.logout(request))
class GuestViewSet(viewsets.ModelViewSet):
queryset = Guest.objects.all()
serializer_class = GuestSerializer

View File

@ -57,11 +57,13 @@ REST_FRAMEWORK = {
# Use Django's standard `django.contrib.auth` permissions,
# or allow read-only access for unauthenticated users.
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
# 'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly',
'rest_framework.permissions.IsAdminUser'
],
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.BasicAuthentication',
# 'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication',
]
}

View File

@ -14,13 +14,12 @@ Including another URLconf
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, re_path, include
from django.conf.urls.static import static
from django.urls import path, include, re_path
from drf_yasg import openapi
from drf_yasg.views import get_schema_view
from rest_framework import routers, permissions
from rest_framework_swagger.views import get_swagger_view
from rest_framework.authtoken import views as authViews
from portfolio import settings
from .account import views
@ -40,18 +39,20 @@ schema_view = get_schema_view(
router = routers.DefaultRouter()
router.register(r'users', views.AccountViewSet, basename='user')
# router.register(r'users/auth', views.AccountAuth, basename='user auth')
router.register(r'guests', views.GuestViewSet)
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(router.urls)),
path('api-auth/', include('rest_framework.urls', namespace='rest_framework'))
# path('api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]
if settings.DEBUG:
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(router.urls)),
path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
re_path(r'users/auth', views.AccountAuth.as_view()),
# path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
path('swagger/', schema_view.with_ui('swagger', cache_timeout=0))
]