version 0.0.5.1: added integration with facebook, refactored a lot
This commit is contained in:
parent
2101a5ae5e
commit
22f2de94f2
|
|
@ -19,6 +19,11 @@ class UserAdmin(BaseUserAdmin):
|
|||
(None, {'fields': ('email', 'password',)}),
|
||||
(_('Personal info'), {
|
||||
'fields': ('username', 'first_name', 'last_name', )}),
|
||||
(_('Subscription'), {
|
||||
'fields': (
|
||||
'newsletter',
|
||||
)
|
||||
}),
|
||||
(_('Important dates'), {'fields': ('last_login', 'date_joined')}),
|
||||
(_('Permissions'), {
|
||||
'fields': (
|
||||
|
|
|
|||
18
apps/account/migrations/0002_user_newsletter.py
Normal file
18
apps/account/migrations/0002_user_newsletter.py
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 2.2.4 on 2019-08-08 08:37
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('account', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='user',
|
||||
name='newsletter',
|
||||
field=models.NullBooleanField(default=True),
|
||||
),
|
||||
]
|
||||
|
|
@ -10,6 +10,18 @@ class UserManager(BaseUserManager):
|
|||
|
||||
use_in_migrations = False
|
||||
|
||||
def make(self, username: str, email: str,
|
||||
password: str, newsletter: bool) -> object:
|
||||
"""Register new user"""
|
||||
obj = self.model(
|
||||
email=email,
|
||||
username=username,
|
||||
password=password,
|
||||
newsletter=newsletter
|
||||
)
|
||||
obj.save()
|
||||
return obj
|
||||
|
||||
|
||||
class UserQuerySet(models.QuerySet):
|
||||
"""Extended queryset for User model."""
|
||||
|
|
@ -23,6 +35,7 @@ class User(ImageMixin, AbstractUser):
|
|||
"""Base user model."""
|
||||
email = models.EmailField(_('email address'), blank=True,
|
||||
null=True, default=None)
|
||||
newsletter = models.NullBooleanField(default=True)
|
||||
|
||||
EMAIL_FIELD = 'email'
|
||||
USERNAME_FIELD = 'username'
|
||||
|
|
|
|||
0
apps/account/serializers/__init__.py
Normal file
0
apps/account/serializers/__init__.py
Normal file
|
|
@ -1,7 +0,0 @@
|
|||
from modeltranslation.translator import TranslationOptions, register
|
||||
from .models import User
|
||||
|
||||
|
||||
@register(User)
|
||||
class UserModelTranslation(TranslationOptions):
|
||||
"""Translation for mode User"""
|
||||
0
apps/account/urls/__init__.py
Normal file
0
apps/account/urls/__init__.py
Normal file
|
|
@ -1,11 +1,12 @@
|
|||
"""Account app urlconf."""
|
||||
from django.urls import path
|
||||
|
||||
from account import views
|
||||
from account.views import web as views
|
||||
|
||||
app_name = 'account'
|
||||
|
||||
urlpatterns = [
|
||||
path('user/', views.UserView.as_view(), name='user_get_update'),
|
||||
path('device/', views.FCMDeviceViewSet.as_view(), name='fcm_device_create'),
|
||||
# path('reset-password/', views.ResetPasswordView.as_view(), name='reset-password'),
|
||||
]
|
||||
0
apps/account/views/__init__.py
Normal file
0
apps/account/views/__init__.py
Normal file
|
|
@ -4,7 +4,7 @@ from rest_framework import permissions
|
|||
from rest_framework.response import Response
|
||||
|
||||
from account import models
|
||||
from account import serializers
|
||||
from account.serializers import web as serializers
|
||||
|
||||
|
||||
class UserView(generics.RetrieveUpdateAPIView):
|
||||
1
apps/authorization/__init__.py
Normal file
1
apps/authorization/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
default_app_config = 'authorization.apps.AuthorizationConfig'
|
||||
3
apps/authorization/admin.py
Normal file
3
apps/authorization/admin.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
||||
8
apps/authorization/apps.py
Normal file
8
apps/authorization/apps.py
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
"""Authorization app config."""
|
||||
from django.apps import AppConfig
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class AuthorizationConfig(AppConfig):
|
||||
name = 'authorization'
|
||||
verbose_name = _('Authorization')
|
||||
39
apps/authorization/migrations/0001_initial.py
Normal file
39
apps/authorization/migrations/0001_initial.py
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
# Generated by Django 2.2.4 on 2019-08-09 05:47
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import oauth2_provider.generators
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Application',
|
||||
fields=[
|
||||
('id', models.BigAutoField(primary_key=True, serialize=False)),
|
||||
('client_id', models.CharField(db_index=True, default=oauth2_provider.generators.generate_client_id, max_length=100, unique=True)),
|
||||
('redirect_uris', models.TextField(blank=True, help_text='Allowed URIs list, space separated')),
|
||||
('client_type', models.CharField(choices=[('confidential', 'Confidential'), ('public', 'Public')], max_length=32)),
|
||||
('authorization_grant_type', models.CharField(choices=[('authorization-code', 'Authorization code'), ('implicit', 'Implicit'), ('password', 'Resource owner password-based'), ('client-credentials', 'Client credentials')], max_length=32)),
|
||||
('client_secret', models.CharField(blank=True, db_index=True, default=oauth2_provider.generators.generate_client_secret, max_length=255)),
|
||||
('name', models.CharField(blank=True, max_length=255)),
|
||||
('skip_authorization', models.BooleanField(default=False)),
|
||||
('created', models.DateTimeField(auto_now_add=True)),
|
||||
('updated', models.DateTimeField(auto_now=True)),
|
||||
('source', models.PositiveSmallIntegerField(choices=[(0, 'Mobile'), (1, 'Web')], default=0, verbose_name='Source')),
|
||||
('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='authorization_application', to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
'swappable': 'OAUTH2_PROVIDER_APPLICATION_MODEL',
|
||||
},
|
||||
),
|
||||
]
|
||||
0
apps/authorization/migrations/__init__.py
Normal file
0
apps/authorization/migrations/__init__.py
Normal file
39
apps/authorization/models.py
Normal file
39
apps/authorization/models.py
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
from django.db import models
|
||||
from oauth2_provider.models import AbstractApplication
|
||||
from oauth2_provider import models as oauth2_models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
# Create your models here.
|
||||
class ApplicationQuerySet(models.QuerySet):
|
||||
"""Application queryset"""
|
||||
def get_by_natural_key(self, client_id):
|
||||
return self.get(client_id=client_id)
|
||||
|
||||
def by_source(self, source: int):
|
||||
"""Filter by source parameter"""
|
||||
return self.filter(source=source)
|
||||
|
||||
|
||||
class ApplicationManager(oauth2_models.ApplicationManager):
|
||||
"""Application manager"""
|
||||
|
||||
|
||||
class Application(AbstractApplication):
|
||||
"""Custom oauth2 application model"""
|
||||
MOBILE = 0
|
||||
WEB = 1
|
||||
|
||||
SOURCES = (
|
||||
(MOBILE, _('Mobile')),
|
||||
(WEB, _('Web')),
|
||||
)
|
||||
source = models.PositiveSmallIntegerField(choices=SOURCES, default=MOBILE,
|
||||
verbose_name=_('Source'))
|
||||
objects = ApplicationManager.from_queryset(ApplicationQuerySet)()
|
||||
|
||||
class Meta(AbstractApplication.Meta):
|
||||
swappable = "OAUTH2_PROVIDER_APPLICATION_MODEL"
|
||||
|
||||
def natural_key(self):
|
||||
return (self.client_id,)
|
||||
0
apps/authorization/serializers/__init__.py
Normal file
0
apps/authorization/serializers/__init__.py
Normal file
10
apps/authorization/serializers/common.py
Normal file
10
apps/authorization/serializers/common.py
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
"""Common serializer for application authorization"""
|
||||
from rest_framework import serializers
|
||||
from authorization.models import Application
|
||||
|
||||
|
||||
class SocialSignUpSerialzier(serializers.Serializer):
|
||||
"""Serializer for signing up"""
|
||||
|
||||
source = serializers.ChoiceField(choices=Application.SOURCES)
|
||||
token = serializers.CharField(max_length=255)
|
||||
81
apps/authorization/serializers/web.py
Normal file
81
apps/authorization/serializers/web.py
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
"""Serializers for application authorization"""
|
||||
from rest_framework import serializers
|
||||
from rest_framework.authentication import authenticate
|
||||
from rest_framework import validators as rest_validators
|
||||
from account import models as account_models
|
||||
from django.contrib.auth import password_validation as password_validators
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class AuthTokenClassicSerializer(serializers.Serializer):
|
||||
username = serializers.CharField(
|
||||
label=_('Username'),
|
||||
required=False
|
||||
)
|
||||
password = serializers.CharField(
|
||||
label=_("Password"),
|
||||
style={'input_type': 'password'},
|
||||
trim_whitespace=False
|
||||
)
|
||||
email = serializers.EmailField(
|
||||
label=_("Email"),
|
||||
required=False
|
||||
)
|
||||
|
||||
def validate(self, attrs):
|
||||
username = attrs.get('username')
|
||||
password = attrs.get('password')
|
||||
email = attrs.get('email')
|
||||
|
||||
if username and password:
|
||||
user = authenticate(request=self.context.get('request'),
|
||||
username=username, password=password)
|
||||
elif email and password:
|
||||
user = authenticate(request=self.context.get('request'),
|
||||
email=email, password=password)
|
||||
else:
|
||||
msg = _('Must include "phone" and "password".')
|
||||
raise serializers.ValidationError(msg, code='authorization')
|
||||
if user:
|
||||
# From Django 1.10 onwards the `authenticate` call simply
|
||||
# returns `None` for is_active=False users.
|
||||
# (Assuming the default `ModelBackend` authentication backend.)
|
||||
if not user.is_active:
|
||||
msg = _('User account is disabled.')
|
||||
raise serializers.ValidationError(msg, code='authorization')
|
||||
attrs['user'] = user
|
||||
return attrs
|
||||
|
||||
|
||||
class SignUpSerializer(serializers.ModelSerializer):
|
||||
"""Serializer for signing up user"""
|
||||
email = serializers.CharField(
|
||||
validators=(rest_validators.UniqueValidator(queryset=account_models.User.objects.all()), ),
|
||||
write_only=True
|
||||
)
|
||||
username = serializers.CharField(
|
||||
validators=(rest_validators.UniqueValidator(queryset=account_models.User.objects.all()), ),
|
||||
write_only=True
|
||||
)
|
||||
password = serializers.CharField(write_only=True)
|
||||
newsletter = serializers.BooleanField()
|
||||
|
||||
class Meta:
|
||||
"""Meta-class"""
|
||||
model = account_models.User
|
||||
fields = ('email', 'username',
|
||||
'newsletter', 'password')
|
||||
|
||||
def validate_password(self, data):
|
||||
"""Custom password validation"""
|
||||
try:
|
||||
password_validators.validate_password(password=data)
|
||||
except serializers.ValidationError as e:
|
||||
raise serializers.ValidationError(e)
|
||||
else:
|
||||
return data
|
||||
|
||||
def create(self, validated_data):
|
||||
"""Override create method"""
|
||||
obj = account_models.User.objects.make(**validated_data)
|
||||
return obj
|
||||
3
apps/authorization/tests.py
Normal file
3
apps/authorization/tests.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
0
apps/authorization/tests/__init__.py
Normal file
0
apps/authorization/tests/__init__.py
Normal file
3
apps/authorization/tests/tests.py
Normal file
3
apps/authorization/tests/tests.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
0
apps/authorization/urls/__init__.py
Normal file
0
apps/authorization/urls/__init__.py
Normal file
46
apps/authorization/urls/common.py
Normal file
46
apps/authorization/urls/common.py
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
"""Common url routing for application authorization"""
|
||||
from django.conf import settings
|
||||
from django.conf.urls import url, include
|
||||
from django.urls import path
|
||||
from oauth2_provider.views import AuthorizationView
|
||||
from rest_framework_social_oauth2.views import (ConvertTokenView, TokenView,
|
||||
RevokeTokenView, invalidate_sessions)
|
||||
from social_core.utils import setting_name
|
||||
from social_django import views as social_django_views
|
||||
|
||||
from authorization.views import web as views
|
||||
|
||||
extra = getattr(settings, setting_name('TRAILING_SLASH'), True) and '/' or ''
|
||||
|
||||
|
||||
app_name = 'social'
|
||||
|
||||
urlpatterns_social_django = [
|
||||
# authentication / association
|
||||
url(r'^login/(?P<backend>[^/]+){0}$'.format(extra), social_django_views.auth,
|
||||
name='begin'),
|
||||
url(r'^complete/(?P<backend>[^/]+){0}$'.format(extra), social_django_views.complete,
|
||||
name='complete'),
|
||||
# disconnection
|
||||
url(r'^disconnect/(?P<backend>[^/]+){0}$'.format(extra), social_django_views.disconnect,
|
||||
name='disconnect'),
|
||||
url(r'^disconnect/(?P<backend>[^/]+)/(?P<association_id>\d+){0}$'
|
||||
.format(extra), social_django_views.disconnect, name='disconnect_individual'),
|
||||
]
|
||||
|
||||
urlpatterns_rest_framework_social_oauth2 = [
|
||||
url(r'^authorize/?$', AuthorizationView.as_view(), name="authorize"),
|
||||
url(r'^token/?$', TokenView.as_view(), name="token"),
|
||||
url('', include('social_django.urls', namespace="social")),
|
||||
url(r'^convert-token/?$', ConvertTokenView.as_view(), name="convert_token"),
|
||||
url(r'^revoke-token/?$', RevokeTokenView.as_view(), name="revoke_token"),
|
||||
url(r'^invalidate-sessions/?$', invalidate_sessions, name="invalidate_sessions")
|
||||
]
|
||||
|
||||
urlpatterns_api = [
|
||||
path('social/signup/', views.SocialSignUpView.as_view(), name='signup'),
|
||||
]
|
||||
|
||||
urlpatterns = urlpatterns_api + \
|
||||
urlpatterns_social_django + \
|
||||
urlpatterns_rest_framework_social_oauth2
|
||||
6
apps/authorization/urls/web.py
Normal file
6
apps/authorization/urls/web.py
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
"""Url routing for application authorization"""
|
||||
|
||||
app_name = 'auth'
|
||||
|
||||
urlpatterns = [
|
||||
]
|
||||
3
apps/authorization/views.py
Normal file
3
apps/authorization/views.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
from django.shortcuts import render
|
||||
|
||||
# Create your views here.
|
||||
0
apps/authorization/views/__init__.py
Normal file
0
apps/authorization/views/__init__.py
Normal file
6
apps/authorization/views/common.py
Normal file
6
apps/authorization/views/common.py
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
"""Common views for application authorization"""
|
||||
from django.shortcuts import render
|
||||
from rest_framework import views as rest_views
|
||||
|
||||
|
||||
# Create your views here.
|
||||
82
apps/authorization/views/web.py
Normal file
82
apps/authorization/views/web.py
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
"""Views for application Account"""
|
||||
import json
|
||||
|
||||
from braces.views import CsrfExemptMixin
|
||||
from oauth2_provider.settings import oauth2_settings
|
||||
from oauth2_provider.views.mixins import OAuthLibMixin
|
||||
from rest_framework import permissions
|
||||
from authorization.models import Application
|
||||
from django.conf import settings
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.generics import GenericAPIView
|
||||
from rest_framework_social_oauth2.oauth2_backends import KeepRequestCore
|
||||
from rest_framework_social_oauth2.oauth2_endpoints import SocialTokenServer
|
||||
from authorization.serializers import common as serializers
|
||||
from utils import exceptions as utils_exceptions
|
||||
|
||||
|
||||
# Create your views here.
|
||||
class SocialSignUpView(CsrfExemptMixin, OAuthLibMixin, GenericAPIView):
|
||||
"""
|
||||
Implements an endpoint to convert a provider token to an access token
|
||||
|
||||
The endpoint is used in the following flows:
|
||||
|
||||
* Authorization code
|
||||
* Client credentials
|
||||
"""
|
||||
server_class = SocialTokenServer
|
||||
validator_class = oauth2_settings.OAUTH2_VALIDATOR_CLASS
|
||||
oauthlib_backend_class = KeepRequestCore
|
||||
permission_classes = (permissions.AllowAny,)
|
||||
serializer_class = serializers.SocialSignUpSerialzier
|
||||
|
||||
def get_client_id(self, source) -> str:
|
||||
"""Get application client id"""
|
||||
qs = Application.objects.by_source(source=source)
|
||||
if qs.exists():
|
||||
return qs.first().client_id
|
||||
else:
|
||||
raise utils_exceptions.SerivceError(data=_('Application is not found'))
|
||||
|
||||
def get_client_secret(self, source) -> str:
|
||||
"""Get application client id"""
|
||||
if source == Application.MOBILE:
|
||||
qs = Application.objects.by_source(source=source)
|
||||
if qs.exists:
|
||||
return qs.first().client_secret
|
||||
else:
|
||||
raise utils_exceptions.SerivceError(
|
||||
data=_('Not found an application with this source'))
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
"""Override POST method"""
|
||||
# Serialize POST-data
|
||||
serializer = self.get_serializer(data=request.data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
# Set attributes
|
||||
source = serializer.validated_data.get('source')
|
||||
token = serializer.validated_data.get('token')
|
||||
# Set OAuth2 request parameters
|
||||
request_data = {
|
||||
'grant_type': settings.OAUTH2_SOCIAL_AUTH_GRANT_TYPE,
|
||||
'backend': settings.OAUTH2_SOCIAL_AUTH_BACKEND_NAME,
|
||||
'token': token,
|
||||
'client_id': self.get_client_id(source)
|
||||
}
|
||||
# Fill client secret parameter by platform
|
||||
if source == Application.MOBILE:
|
||||
request_data['client_secret'] = self.get_client_secret(source)
|
||||
|
||||
# Use the rest framework `.data` to fake the post body of the django request.
|
||||
request._request.POST = request._request.POST.copy()
|
||||
for key, value in request_data.items():
|
||||
request._request.POST[key] = value
|
||||
|
||||
url, headers, body, status = self.create_token_response(request._request)
|
||||
response = Response(data=json.loads(body), status=status)
|
||||
|
||||
for k, v in headers.items():
|
||||
response[k] = v
|
||||
return response
|
||||
15
apps/utils/exceptions.py
Normal file
15
apps/utils/exceptions.py
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework import exceptions, status
|
||||
|
||||
|
||||
class SerivceError(exceptions.APIException):
|
||||
"""Service error."""
|
||||
status_code = status.HTTP_503_SERVICE_UNAVAILABLE
|
||||
default_detail = _('Service is temporarily unavailable')
|
||||
|
||||
def __init__(self, data=None):
|
||||
if data:
|
||||
self.default_detail = {
|
||||
**data
|
||||
}
|
||||
super().__init__()
|
||||
|
|
@ -24,6 +24,14 @@ class ProjectBaseMixin(models.Model):
|
|||
abstract = True
|
||||
|
||||
|
||||
class OAuthProjectMixin:
|
||||
"""OAuth2 mixin for project GM"""
|
||||
|
||||
def get_source(self):
|
||||
"""Method to get of platform"""
|
||||
return NotImplemented
|
||||
|
||||
|
||||
basemixin_fields = ['created', 'modified']
|
||||
|
||||
|
||||
|
|
|
|||
36
apps/utils/oauth2.py
Normal file
36
apps/utils/oauth2.py
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
from rest_framework_social_oauth2.backends import DjangoOAuth2
|
||||
from oauth2_provider.models import AccessToken
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
|
||||
class GMOAuth2(DjangoOAuth2):
|
||||
|
||||
def get_user_details(self, response):
|
||||
if response.get(self.ID_KEY, None):
|
||||
user = User.objects.get(pk=response[self.ID_KEY])
|
||||
return {'username': user.username,
|
||||
'email': user.email,
|
||||
'fullname': user.get_full_name(),
|
||||
'first_name': user.first_name,
|
||||
'last_name': user.last_name
|
||||
}
|
||||
return {}
|
||||
|
||||
def user_data(self, access_token, *args, **kwargs):
|
||||
try:
|
||||
user_id = AccessToken.objects.get(token=access_token).user.pk
|
||||
return {self.ID_KEY: user_id}
|
||||
except AccessToken.DoesNotExist:
|
||||
return None
|
||||
|
||||
def do_auth(self, access_token, *args, **kwargs):
|
||||
"""Finish the auth process once the access_token was retrieved"""
|
||||
data = self.user_data(access_token, *args, **kwargs)
|
||||
response = kwargs.get('response') or {}
|
||||
response.update(data or {})
|
||||
kwargs.update({'response': response, 'backend': self})
|
||||
if response.get(self.ID_KEY, None):
|
||||
user = User.objects.get(pk=response[self.ID_KEY])
|
||||
return user
|
||||
else:
|
||||
return None
|
||||
|
|
@ -52,7 +52,7 @@ CONTRIB_APPS = [
|
|||
|
||||
PROJECT_APPS = [
|
||||
'account.apps.AccountConfig',
|
||||
'location.apps.LocationConfig',
|
||||
'authorization.apps.AuthorizationConfig',
|
||||
|
||||
]
|
||||
|
||||
|
|
@ -225,7 +225,7 @@ AUTHENTICATION_BACKENDS = (
|
|||
'social_core.backends.facebook.FacebookOAuth2',
|
||||
|
||||
# django-rest-framework-social-oauth2
|
||||
'rest_framework_social_oauth2.backends.DjangoOAuth2',
|
||||
'utils.oauth2.GMOAuth2',
|
||||
|
||||
# Django
|
||||
'django.contrib.auth.backends.ModelBackend',
|
||||
|
|
@ -236,6 +236,12 @@ OAUTH2_PROVIDER = {
|
|||
'SCOPES': {'read': 'Read scope', 'write': 'Write scope', 'groups': 'Access to your groups'}
|
||||
}
|
||||
|
||||
# Override default OAuth2 namespace
|
||||
DRFSO2_URL_NAMESPACE = 'oauth2'
|
||||
OAUTH2_SOCIAL_AUTH_BACKEND_NAME = 'facebook'
|
||||
OAUTH2_SOCIAL_AUTH_GRANT_TYPE = 'convert_token'
|
||||
OAUTH2_PROVIDER_APPLICATION_MODEL = 'authorization.Application'
|
||||
|
||||
# SMS Settings
|
||||
SMS_EXPIRATION = 5
|
||||
SMS_SEND_DELAY = 30
|
||||
|
|
|
|||
|
|
@ -18,10 +18,13 @@ from django.conf.urls.static import static
|
|||
from django.contrib import admin
|
||||
from django.urls import path, include, re_path
|
||||
from drf_yasg import openapi
|
||||
from django.conf.urls import url
|
||||
from drf_yasg.views import get_schema_view
|
||||
from rest_framework import permissions
|
||||
|
||||
# URL platform patterns
|
||||
from project.urls import web as web_urlpatterns
|
||||
|
||||
|
||||
schema_view = get_schema_view(
|
||||
openapi.Info(
|
||||
title="G&M API",
|
||||
|
|
@ -48,26 +51,18 @@ urlpatterns_doc = [
|
|||
|
||||
]
|
||||
|
||||
urlpatterns_oauth2 = [
|
||||
url(r'^auth/', include('rest_framework_social_oauth2.urls')),
|
||||
urlpatterns_social = [
|
||||
path('api/oauth2/', include('authorization.urls.common', namespace='oauth2')),
|
||||
]
|
||||
|
||||
|
||||
urlpatterns_api = [
|
||||
path('account/', include('account.urls'), name='account'),
|
||||
|
||||
]
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
path('admin/', admin.site.urls),
|
||||
path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
|
||||
path('api/', include(urlpatterns_api)),
|
||||
path('api/web/', include(web_urlpatterns)),
|
||||
]
|
||||
|
||||
urlpatterns = urlpatterns + \
|
||||
static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) + \
|
||||
urlpatterns_oauth2
|
||||
urlpatterns_social + \
|
||||
static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||
|
||||
|
||||
if settings.DEBUG:
|
||||
22
project/urls/web.py
Normal file
22
project/urls/web.py
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
"""project URL Configuration
|
||||
|
||||
The `urlpatterns` list routes URLs to views. For more information please see:
|
||||
https://docs.djangoproject.com/en/2.2/topics/http/urls/
|
||||
Examples:
|
||||
Function views
|
||||
1. Add an import: from my_app import views
|
||||
2. Add a URL to urlpatterns: path('', views.home, name='home')
|
||||
Class-based views
|
||||
1. Add an import: from other_app.views import Home
|
||||
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
|
||||
Including another URLconf
|
||||
1. Import the include() function: from django.urls import include, path
|
||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||
"""
|
||||
from django.urls import path, include
|
||||
|
||||
app_name = 'web'
|
||||
|
||||
urlpatterns = [
|
||||
path('account/', include('account.urls.web')),
|
||||
]
|
||||
Loading…
Reference in New Issue
Block a user