From 6fc132df2d49eb164f54094d50c8f36afac63f48 Mon Sep 17 00:00:00 2001 From: vk Date: Thu, 26 Mar 2020 19:38:15 +0300 Subject: [PATCH 1/4] Fixed models in admin panel --- ...20200310_1809.py => 0012_profile_photo.py} | 7 +--- portfolio/admin.py | 36 ++++++++++++++----- portfolio/models.py | 3 ++ 3 files changed, 32 insertions(+), 14 deletions(-) rename accounts/migrations/{0012_auto_20200310_1809.py => 0012_profile_photo.py} (57%) diff --git a/accounts/migrations/0012_auto_20200310_1809.py b/accounts/migrations/0012_profile_photo.py similarity index 57% rename from accounts/migrations/0012_auto_20200310_1809.py rename to accounts/migrations/0012_profile_photo.py index 18fd30d..a7e29ab 100644 --- a/accounts/migrations/0012_auto_20200310_1809.py +++ b/accounts/migrations/0012_profile_photo.py @@ -1,4 +1,4 @@ -# Generated by Django 2.1.2 on 2020-03-10 15:09 +# Generated by Django 2.1.2 on 2020-03-20 11:34 from django.db import migrations, models @@ -10,11 +10,6 @@ class Migration(migrations.Migration): ] operations = [ - migrations.AddField( - model_name='profile', - name='gender', - field=models.CharField(blank=True, choices=[('m', 'Мужской'), ('w', 'Женский')], max_length=1, null=True, verbose_name='Пол'), - ), migrations.AddField( model_name='profile', name='photo', diff --git a/portfolio/admin.py b/portfolio/admin.py index 412e717..91498fa 100644 --- a/portfolio/admin.py +++ b/portfolio/admin.py @@ -5,26 +5,46 @@ # Register your models here. @admin.register(Project) class ProjectAdmin(admin.ModelAdmin): - pass + list_display = ['name', 'is_visible', 'status_project', 'published'] + list_display_links = ['name', 'is_visible', 'status_project', 'published'] + search_fields = ['name', 'is_visible', 'status_project'] + list_filter = ['is_visible', 'status_project'] + list_per_page = 20 @admin.register(Assessment) class AssessmentAdmin(admin.ModelAdmin): - list_display = ['id', 'profile_id', 'skill_id', 'rate'] + list_display = ['profile_id', 'skill_id', 'rate'] search_fields = ['profile_id', 'skill_id', 'rate'] list_filter = ['skill_id'] - list_per_page = 10 + list_per_page = 20 -@admin.register(Relationships, TypeRelationship) +@admin.register(Relationships) class RelationshipsAdmin(admin.ModelAdmin): - pass + list_filter = ['type_relationship'] + list_per_page = 20 -@admin.register(Skills, TypeSkill) +@admin.register(TypeRelationship) +class RelationshipsTypeAdmin(admin.ModelAdmin): + search_fields = ['title'] + list_per_page = 20 + + +@admin.register(Skills) class SkillsAdmin(admin.ModelAdmin): - list_display = ['name'] - list_per_page = 10 + list_display = ['name', 'approved', 'type_skill'] + list_display_links = ['name', 'approved', 'type_skill'] + search_fields = ['name', 'type_skill'] + list_filter = ['name', 'approved'] + list_per_page = 20 + + +@admin.register(TypeSkill) +class TypeSkillsAdmin(admin.ModelAdmin): + list_display = ['title'] + list_per_page = 20 @admin.register(SkillProfile) diff --git a/portfolio/models.py b/portfolio/models.py index 5491ee4..46a2552 100644 --- a/portfolio/models.py +++ b/portfolio/models.py @@ -116,6 +116,9 @@ class Relationships(models.Model): on_delete=models.CASCADE, verbose_name='Тип связи') + def __str__(self): + return self.type_relationship + class Meta: verbose_name = 'Связь' verbose_name_plural = 'Связи' From add1208b26acdc83585683265da54de5fd9c9762 Mon Sep 17 00:00:00 2001 From: vk Date: Thu, 28 May 2020 18:58:02 +0300 Subject: [PATCH 2/4] Adding a models to the admin panel --- portfolio/admin.py | 36 ++++++++++++++----- visits/migrations/0004_merge_20191209_1423.py | 3 +- visits/migrations/0005_auto_20200319_2126.py | 3 +- 3 files changed, 32 insertions(+), 10 deletions(-) diff --git a/portfolio/admin.py b/portfolio/admin.py index 652c579..bec7531 100644 --- a/portfolio/admin.py +++ b/portfolio/admin.py @@ -5,26 +5,46 @@ # Register your models here. @admin.register(Project) class ProjectAdmin(admin.ModelAdmin): - pass + list_display = ['name', 'is_visible', 'status_project', 'published'] + list_display_links = ['name', 'is_visible', 'status_project', 'published'] + search_fields = ['name', 'is_visible', 'status_project'] + list_filter = ['is_visible', 'status_project'] + list_per_page = 20 @admin.register(Assessment) class AssessmentAdmin(admin.ModelAdmin): - list_display = ['id', 'profile_id', 'skill_id', 'rate'] + list_display = ['profile_id', 'skill_id', 'rate'] search_fields = ['profile_id', 'skill_id', 'rate'] list_filter = ['skill_id'] - list_per_page = 10 + list_per_page = 20 -@admin.register(Relationships, TypeRelationship) +@admin.register(Relationships) class RelationshipsAdmin(admin.ModelAdmin): - pass + list_filter = ['type_relationship'] + list_per_page = 20 -@admin.register(Skills, TypeSkill) +@admin.register(TypeRelationship) +class RelationshipsTypeAdmin(admin.ModelAdmin): + search_fields = ['title'] + list_per_page = 20 + + +@admin.register(Skills) class SkillsAdmin(admin.ModelAdmin): - # list_display = ['name'] - list_per_page = 10 + list_display = ['name', 'approved', 'type_skill'] + list_display_links = ['name', 'approved', 'type_skill'] + search_fields = ['name', 'type_skill'] + list_filter = ['approved'] + list_per_page = 20 + + +@admin.register(TypeSkill) +class TypeSkillsAdmin(admin.ModelAdmin): + list_display = ['title'] + list_per_page = 20 @admin.register(SkillProfile) diff --git a/visits/migrations/0004_merge_20191209_1423.py b/visits/migrations/0004_merge_20191209_1423.py index 70bbc2d..643878f 100644 --- a/visits/migrations/0004_merge_20191209_1423.py +++ b/visits/migrations/0004_merge_20191209_1423.py @@ -6,7 +6,8 @@ class Migration(migrations.Migration): dependencies = [ - ('visits', '0003_auto_20191112_2022'), + # ('visits', '0003_auto_20191112_2022'), + # ('visits', '0003_auto_20191105_1931'), ('visits', '0003_auto_20191105_1931'), ] diff --git a/visits/migrations/0005_auto_20200319_2126.py b/visits/migrations/0005_auto_20200319_2126.py index f261ebe..88d2254 100644 --- a/visits/migrations/0005_auto_20200319_2126.py +++ b/visits/migrations/0005_auto_20200319_2126.py @@ -6,7 +6,8 @@ class Migration(migrations.Migration): dependencies = [ - ('visits', '0003_auto_20191105_1931'), + # ('visits', '0003_auto_20191105_1931'), + ('visits', '0004_merge_20191209_1423'), ] operations = [ From 0f682a7de762a92bcd873e205f8c72296e173486 Mon Sep 17 00:00:00 2001 From: vk Date: Thu, 28 May 2020 19:02:50 +0300 Subject: [PATCH 3/4] Added JWT auth --- api/views.py | 65 ++++++++++++++++++++++++++++++++--- api_core/urls.py | 15 +++++++- olimp_inside/settings/base.py | 21 +++++++++++ requirements.txt | 3 +- 4 files changed, 98 insertions(+), 6 deletions(-) diff --git a/api/views.py b/api/views.py index b86b3b5..8fa79aa 100644 --- a/api/views.py +++ b/api/views.py @@ -1,19 +1,22 @@ +import jwt +from django.conf import settings +from django.contrib.auth import user_logged_in from django.shortcuts import render -from rest_framework.generics import ListAPIView +from rest_framework.generics import ListAPIView, RetrieveUpdateAPIView from rest_framework.response import Response from rest_framework.views import APIView from rest_framework import status -from rest_framework.permissions import IsAuthenticated +from rest_framework.permissions import IsAuthenticated, AllowAny from .models import MacModelUser from api.serializers import ( API_Serializer, VisitDataSerializer, - MACAddressSerializer + MACAddressSerializer, ) from visits.models import Visit, UserAccount from django.utils import timezone from rest_framework.pagination import LimitOffsetPagination -from django.core.exceptions import ValidationError +from django.core.exceptions import ValidationError, ObjectDoesNotExist import datetime from rest_framework.filters import SearchFilter # import logging @@ -23,6 +26,60 @@ # logging.basicConfig(level=logging.DEBUG, ) # {"mac_address": "00:26:57:00:1f:02"} +class AuthentificationTokenView(APIView): + permission_classes = [AllowAny, ] + + def get(self, request): + res = {'status': 'Authentification Token View'} + return Response(res, status=status.HTTP_200_OK) + + def post(self, request): + try: + email = request.data['email'] + password = request.data['password'] + + user = UserAccount.objects.get(email=email) + if user: + try: + payload = { + 'email': user.email, + 'name': user.get_short_name(), + # 'photo': user.profile.photo, + } + token = jwt.encode(payload, settings.SECRET_KEY) + + user_details = { + 'name': user.get_full_name(), + 'token': token, + } + return Response(user_details, status=status.HTTP_200_OK) + except Exception as err: + raise err + else: + res = {'error': 'can not authenticate with the given credentials or the account has been deactivated'} + return Response(res, status=status.HTTP_403_FORBIDDEN) + except ObjectDoesNotExist: + res = {'error': 'please provide a email and a password', + 'email': email, + 'password': password} + return Response(res, status=status.HTTP_204_NO_CONTENT) + + +class UserRetrieveUpdateAPIView(RetrieveUpdateAPIView): + permission_classes = (IsAuthenticated,) + serializer_class = VisitDataSerializer + + def get(self, request): + serializer = self.serializer_class(request.user) + return Response(serializer.data, status=status.HTTP_200_OK) + + def put(self, request, *args, **kwargs): + serializer_data = request.data.get('user', {}) + + serializer = VisitDataSerializer(request.user, data=serializer_data, partial=True) + serializer.is_valid(raise_exception=True) + return Response(serializer.data, status=status.HTTP_200_OK) + class ApiCreateView(APIView): permission_classes = (IsAuthenticated,) diff --git a/api_core/urls.py b/api_core/urls.py index 6ae3595..08b97b5 100644 --- a/api_core/urls.py +++ b/api_core/urls.py @@ -1,9 +1,13 @@ from django.urls import re_path, include, path from rest_framework.routers import DefaultRouter +from rest_framework_jwt.views import obtain_jwt_token, refresh_jwt_token, verify_jwt_token + from api.urls import visits_api_urls -from api.views import ApiCreateView +from api.views import ApiCreateView, AuthentificationTokenView, UserRetrieveUpdateAPIView from knowledges.api.viewsets import ArticleViewSet + + api_router = DefaultRouter() api_router.register('posts', ArticleViewSet) @@ -14,4 +18,13 @@ re_path(r'^api-auth/', include('rest_framework.urls')), path('visits/', include((visits_api_urls, 'visits'))), path('mac_addr/create', ApiCreateView.as_view()), + + # Auth with handler generation + path(r'authorisation/', AuthentificationTokenView.as_view()), + path('update/', UserRetrieveUpdateAPIView.as_view()), + + # Auth with rest_framework_jwt + re_path(r'api-token-auth/', obtain_jwt_token), + re_path(r'^api-token-refresh/', refresh_jwt_token), + re_path(r'^api-token-verify/', verify_jwt_token), ] \ No newline at end of file diff --git a/olimp_inside/settings/base.py b/olimp_inside/settings/base.py index 5dc01db..4a44d4c 100644 --- a/olimp_inside/settings/base.py +++ b/olimp_inside/settings/base.py @@ -12,6 +12,7 @@ import os import environ +import datetime from django.urls.base import reverse_lazy @@ -144,3 +145,23 @@ EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' LOGIN_REDIRECT_URL = reverse_lazy('visits:people_inside') + +# JWT AUTHENTICATION +REST_FRAMEWORK = { + 'DEFAULT_AUTHENTICATION_CLASSES': ( + 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', + ), + 'DEFAULT_AUTHENTICATION_CLASSES': ( + 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', + 'rest_framework.authentication.SessionAuthentication', + 'rest_framework.authentication.BasicAuthentication', + ), +} + +JWT_AUTH = { + 'JWT_VERIFY': True, + 'JWT_VERIFY_EXPIRATION': True, + 'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=3000), + 'JWT_AUTH_HEADER_PREFIX': 'Bearer', + 'JWT_ALLOW_REFRESH': True, +} diff --git a/requirements.txt b/requirements.txt index 0ef16ea..54a13f0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,9 +2,10 @@ Django==2.1.2 django-environ==0.4.5 django-object-actions==1.1.0 djangorestframework==3.10.3 +djangorestframework-jwt==1.11.0 Markdown==3.1.1 Pillow==7.0.0 -pkg-resources==0.0.0 psycopg2==2.7.5 psycopg2-binary==2.7.5 +PyJWT==1.7.1 pytz==2018.7 From bb3b2f64568262a2fbacb1bdc970ebe722332403 Mon Sep 17 00:00:00 2001 From: vk Date: Thu, 28 May 2020 19:43:14 +0300 Subject: [PATCH 4/4] Fixed merge branch --- accounts/migrations/0013_auto_20200324_2012.py | 2 +- portfolio/migrations/0001_initial.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/accounts/migrations/0013_auto_20200324_2012.py b/accounts/migrations/0013_auto_20200324_2012.py index b4fc0ec..ec935b4 100644 --- a/accounts/migrations/0013_auto_20200324_2012.py +++ b/accounts/migrations/0013_auto_20200324_2012.py @@ -7,7 +7,7 @@ class Migration(migrations.Migration): dependencies = [ - ('accounts', '0012_auto_20200310_1809'), + ('accounts', '0012_profile_photo'), ] operations = [ diff --git a/portfolio/migrations/0001_initial.py b/portfolio/migrations/0001_initial.py index 9c7aa35..c6d59db 100644 --- a/portfolio/migrations/0001_initial.py +++ b/portfolio/migrations/0001_initial.py @@ -12,7 +12,7 @@ class Migration(migrations.Migration): dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('accounts', '0012_auto_20200310_1809'), + ('accounts', '0012_profile_photo'), ] operations = [