start rewrite

This commit is contained in:
mahdavi 2022-09-02 12:12:14 +04:30
parent 2f5e5f05b6
commit 29b7ac6f39
24 changed files with 188 additions and 443 deletions

9
Dockerfile Normal file
View file

@ -0,0 +1,9 @@
FROM python:3.9
ENV PYTHONUNBUFFERED 1
WORKDIR /app
RUN apt update
RUN apt install libmysqlclient-dev libssl-dev libcrypto++-dev lsb-release -y
COPY requirements.txt /app/requirements.txt
RUN pip install -r requirements.txt
COPY . /app
RUN python manage.py migrate

View file

@ -58,6 +58,7 @@ MIDDLEWARE = [
]
# Tell Django OAuth Toolkit to use the Gooyal Application model
OAUTH2_PROVIDER_ID_TOKEN_MODEL = 'gooyal_oauth2.IDToken'
OAUTH2_PROVIDER_APPLICATION_MODEL = 'gooyal_oauth2.Application'
OAUTH2_PROVIDER_ACCESS_TOKEN_MODEL = 'gooyal_oauth2.AccessToken'
OAUTH2_PROVIDER_GRANT_MODEL = 'gooyal_oauth2.Grant'
@ -71,7 +72,7 @@ OAUTH2_PROVIDER = {
'groups': 'Access to your groups',
'introspection': 'Introspect token scope'},
'OAUTH2_VALIDATOR_CLASS': 'apps.gooyal_oauth2.validators.OAuth2Validator',
"INTROSPECTION_USER_CREATE_METHOD": 'apps.users.models.create_user_in_introspection',
# "INTROSPECTION_USER_CREATE_METHOD": 'apps.users.models.create_user_in_introspection',
}
# GOOYAL_DYNAMIC_SCOPES
@ -87,9 +88,19 @@ REST_FRAMEWORK = {
'rest_framework.permissions.IsAuthenticated',
),
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 10
'PAGE_SIZE': 10,
"DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
}
SPECTACULAR_SETTINGS = {
'TITLE': 'accounts',
'DESCRIPTION': 'accounts api reference',
'VERSION': '1.0.0',
'SERVE_INCLUDE_SCHEMA': False,
# OTHER SETTINGS
}
ROOT_URLCONF = 'accounts.urls'
TEMPLATES = [
@ -178,8 +189,8 @@ MEDIA_URL = "/media/"
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATIC_URL = '/static/'
BASE_NOTIFICATION_URL = config('BASE_NOTIFICATION_URL')
CLIENT_ID = config('CLIENT_ID')
CLIENT_SECRET = config('CLIENT_SECRET')
# BASE_NOTIFICATION_URL = config('BASE_NOTIFICATION_URL')
# CLIENT_ID = config('CLIENT_ID')
# CLIENT_SECRET = config('CLIENT_SECRET')
CELERY_BROKER_URL = config('CELERY_BROKER_URL')

View file

@ -14,7 +14,7 @@ Including another URLconf
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.conf import settings
from django.conf.urls import url
# from django.conf.urls import url
from django.conf.urls.static import static
from django.contrib.auth.views import LogoutView
from django.urls import path, include

View file

@ -0,0 +1,92 @@
# Generated by Django 4.1 on 2022-08-17 19:05
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
('gooyal_oauth2', '0001_initial'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.AddField(
model_name='resource',
name='user',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='resources', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='refreshtoken',
name='access_token',
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='refresh_token', to=settings.OAUTH2_PROVIDER_ACCESS_TOKEN_MODEL),
),
migrations.AddField(
model_name='refreshtoken',
name='application',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='refresh_tokens', to=settings.OAUTH2_PROVIDER_APPLICATION_MODEL),
),
migrations.AddField(
model_name='refreshtoken',
name='user',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(app_label)s_%(class)s', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='idtoken',
name='application',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.OAUTH2_PROVIDER_APPLICATION_MODEL),
),
migrations.AddField(
model_name='idtoken',
name='user',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(app_label)s_%(class)s', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='grant',
name='application',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='grants', to=settings.OAUTH2_PROVIDER_APPLICATION_MODEL),
),
migrations.AddField(
model_name='grant',
name='user',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(app_label)s_%(class)s', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='application',
name='resource',
field=models.OneToOneField(blank=True, help_text='The resource of application.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='application', to='gooyal_oauth2.resource'),
),
migrations.AddField(
model_name='application',
name='user',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='%(app_label)s_%(class)s', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='accesstoken',
name='application',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='access_tokens', to=settings.OAUTH2_PROVIDER_APPLICATION_MODEL),
),
migrations.AddField(
model_name='accesstoken',
name='id_token',
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='access_token', to=settings.OAUTH2_PROVIDER_ID_TOKEN_MODEL),
),
migrations.AddField(
model_name='accesstoken',
name='source_refresh_token',
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='refreshed_access_token', to=settings.OAUTH2_PROVIDER_REFRESH_TOKEN_MODEL),
),
migrations.AddField(
model_name='accesstoken',
name='user',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(app_label)s_%(class)s', to=settings.AUTH_USER_MODEL),
),
migrations.AlterUniqueTogether(
name='refreshtoken',
unique_together={('token', 'revoked')},
),
]

View file

@ -1,25 +0,0 @@
# Generated by Django 3.0.6 on 2020-06-09 17:25
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('gooyal_oauth2', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='Scope',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(help_text='The name of the scope.', max_length=255, unique=True)),
('description', models.TextField(help_text='A brief description of the scope. This text is displayed to users when authorising access for the scope.')),
('is_default', models.BooleanField(default=False, help_text='Indicates if this scope should be included in the default scopes.')),
('application', models.ForeignKey(blank=True, help_text='The application to which the scope belongs.', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='scopes', to=settings.OAUTH2_PROVIDER_APPLICATION_MODEL)),
],
),
]

View file

@ -1,37 +0,0 @@
# Generated by Django 3.0.6 on 2020-06-11 08:28
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import uuid
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('gooyal_oauth2', '0002_scope'),
]
operations = [
migrations.AlterField(
model_name='application',
name='user',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='gooyal_oauth2_application', to=settings.AUTH_USER_MODEL),
),
migrations.CreateModel(
name='Resource',
fields=[
('created', models.DateTimeField(auto_now_add=True)),
('updated', models.DateTimeField(auto_now=True)),
('uuid', models.UUIDField(db_index=True, default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)),
('name', models.CharField(blank=True, max_length=255)),
('expires', models.DateTimeField()),
('token', models.CharField(max_length=255, unique=True)),
('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='resources', to=settings.AUTH_USER_MODEL)),
],
options={
'abstract': False,
},
),
]

View file

@ -1,75 +0,0 @@
# Generated by Django 3.0.8 on 2020-07-12 11:40
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
from django.db.models import JSONField
class Migration(migrations.Migration):
initial = True
run_before = [
('oauth2_provider', '0001_initial'),
]
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('gooyal_oauth2', '0003_auto_20200611_0828'),
]
operations = [
migrations.CreateModel(
name='Grant',
fields=[
('id', models.BigAutoField(primary_key=True, serialize=False)),
('code', models.CharField(max_length=255, unique=True)),
('expires', models.DateTimeField()),
('redirect_uri', models.CharField(max_length=255)),
('scope', models.TextField(blank=True)),
('created', models.DateTimeField(auto_now_add=True)),
('updated', models.DateTimeField(auto_now=True)),
('code_challenge', models.CharField(blank=True, default='', max_length=128)),
('code_challenge_method', models.CharField(blank=True, choices=[('plain', 'plain'), ('S256', 'S256')], default='', max_length=10)),
('application', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='grants', to=settings.OAUTH2_PROVIDER_APPLICATION_MODEL)),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='gooyal_oauth2_grant', to=settings.AUTH_USER_MODEL)),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='AccessToken',
fields=[
('id', models.BigAutoField(primary_key=True, serialize=False)),
('token', models.CharField(max_length=255, unique=True)),
('expires', models.DateTimeField()),
('scope', models.TextField(blank=True)),
('created', models.DateTimeField(auto_now_add=True)),
('updated', models.DateTimeField(auto_now=True)),
('detail', JSONField(blank=True, default=dict, null=True)),
('application', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='access_tokens', to=settings.OAUTH2_PROVIDER_APPLICATION_MODEL)),
('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='gooyal_oauth2_accesstoken', to=settings.AUTH_USER_MODEL)),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='RefreshToken',
fields=[
('id', models.BigAutoField(primary_key=True, serialize=False)),
('token', models.CharField(max_length=255)),
('created', models.DateTimeField(auto_now_add=True)),
('updated', models.DateTimeField(auto_now=True)),
('revoked', models.DateTimeField(null=True)),
('application', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='refresh_tokens', to=settings.OAUTH2_PROVIDER_APPLICATION_MODEL)),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='gooyal_oauth2_refreshtoken', to=settings.AUTH_USER_MODEL)),
],
options={
'abstract': False,
'unique_together': {('token', 'revoked')},
},
),
]

View file

@ -1,25 +0,0 @@
# Generated by Django 3.0.8 on 2020-07-12 12:19
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('gooyal_oauth2', '0004_tokens'),
]
operations = [
migrations.AddField(
model_name='accesstoken',
name='source_refresh_token',
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='refreshed_access_token', to=settings.OAUTH2_PROVIDER_REFRESH_TOKEN_MODEL),
),
migrations.AddField(
model_name='refreshtoken',
name='access_token',
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='refresh_token', to=settings.OAUTH2_PROVIDER_ACCESS_TOKEN_MODEL),
),
]

View file

@ -1,48 +0,0 @@
# Generated by Django 3.0.8 on 2020-08-25 06:15
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('gooyal_oauth2', '0005_auto_20200712_1219'),
]
operations = [
migrations.RemoveField(
model_name='resource',
name='created',
),
migrations.RemoveField(
model_name='resource',
name='token',
),
migrations.RemoveField(
model_name='resource',
name='updated',
),
migrations.AddField(
model_name='application',
name='resource',
field=models.OneToOneField(blank=True, help_text='The resource of application.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='application', to='gooyal_oauth2.Resource'),
),
migrations.AddField(
model_name='scope',
name='resource',
field=models.ForeignKey(blank=True, help_text='The resource of scope.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='scopes', to='gooyal_oauth2.Resource'),
),
migrations.AlterField(
model_name='application',
name='user',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='gooyal_oauth2_application', to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='resource',
name='name',
field=models.CharField(max_length=255),
),
]

View file

@ -1,18 +0,0 @@
# Generated by Django 3.1.1 on 2020-09-26 05:25
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('gooyal_oauth2', '0006_auto_20200825_0615'),
]
operations = [
migrations.AlterField(
model_name='accesstoken',
name='detail',
field=models.JSONField(blank=True, null=True),
),
]

View file

@ -2,7 +2,8 @@ import requests
from django.conf import settings
from django.db import models
from django.db.models import JSONField
from oauth2_provider.models import AbstractApplication, AbstractAccessToken, AbstractGrant, AbstractRefreshToken
from oauth2_provider.models import AbstractApplication, AbstractAccessToken, AbstractGrant, AbstractRefreshToken, \
AbstractIDToken
from oauth2_provider.scopes import get_scopes_backend
from oauth2_provider.settings import oauth2_settings
import uuid
@ -161,3 +162,7 @@ class AccessToken(AbstractAccessToken):
application = models.ForeignKey(
oauth2_settings.APPLICATION_MODEL, on_delete=models.CASCADE, blank=True, null=True, related_name='access_tokens'
)
class IDToken(AbstractIDToken):
pass

View file

@ -3,7 +3,7 @@ import logging
from datetime import datetime, timedelta
import requests
import service_clients
# import service_clients
from django.contrib.auth import get_user_model
from django.utils.timezone import make_aware
from oauth2_provider.models import get_access_token_model
@ -166,45 +166,45 @@ class OAuth2Validator(BaseOAuth2Validator): # pylint: disable=w0223
return access_token
def validate_bearer_token(self, token, scopes, request):
"""
When users try to access resources, check that provided token is valid
"""
if not token:
return False
introspection_url = oauth2_settings.RESOURCE_SERVER_INTROSPECTION_URL
introspection_token = oauth2_settings.RESOURCE_SERVER_AUTH_TOKEN
introspection_credentials = oauth2_settings.RESOURCE_SERVER_INTROSPECTION_CREDENTIALS
introspection_client_id = oauth2_settings.RESOURCE_SERVER_CLIENT_ID
introspection_client_secret = oauth2_settings.RESOURCE_SERVER_CLIENT_SECRET
try:
access_token = AccessTokenModel.objects.select_related("application", "user").get(token=token)
except AccessTokenModel.DoesNotExist:
access_token = None
# if there is no token or it's invalid then introspect the token if there's an external OAuth server
if not access_token or not access_token.is_valid(scopes):
if introspection_url and (introspection_token or introspection_credentials or (introspection_client_id and
introspection_client_secret)):
access_token = self._get_token_from_gooyal_authentication_server(
token,
introspection_url,
introspection_token,
introspection_credentials,
introspection_client_id,
introspection_client_secret
)
if access_token and access_token.is_valid(scopes):
request.client = access_token.application
request.user = access_token.user
request.scopes = scopes
# this is needed by django rest framework
request.access_token = access_token
return True
else:
self._set_oauth2_error_on_request(request, access_token, scopes)
return False
# def validate_bearer_token(self, token, scopes, request):
# """
# When users try to access resources, check that provided token is valid
# """
# if not token:
# return False
#
# introspection_url = oauth2_settings.RESOURCE_SERVER_INTROSPECTION_URL
# introspection_token = oauth2_settings.RESOURCE_SERVER_AUTH_TOKEN
# introspection_credentials = oauth2_settings.RESOURCE_SERVER_INTROSPECTION_CREDENTIALS
# introspection_client_id = oauth2_settings.RESOURCE_SERVER_CLIENT_ID
# introspection_client_secret = oauth2_settings.RESOURCE_SERVER_CLIENT_SECRET
#
# try:
# access_token = AccessTokenModel.objects.select_related("application", "user").get(token=token)
# except AccessTokenModel.DoesNotExist:
# access_token = None
#
# # if there is no token or it's invalid then introspect the token if there's an external OAuth server
# if not access_token or not access_token.is_valid(scopes):
# if introspection_url and (introspection_token or introspection_credentials or (introspection_client_id and
# introspection_client_secret)):
# access_token = self._get_token_from_gooyal_authentication_server(
# token,
# introspection_url,
# introspection_token,
# introspection_credentials,
# introspection_client_id,
# introspection_client_secret
# )
#
# if access_token and access_token.is_valid(scopes):
# request.client = access_token.application
# request.user = access_token.user
# request.scopes = scopes
#
# # this is needed by django rest framework
# request.access_token = access_token
# return True
# else:
# self._set_oauth2_error_on_request(request, access_token, scopes)
# return False

View file

@ -1,4 +1,4 @@
# Generated by Django 3.0 on 2020-03-08 11:13
# Generated by Django 4.1 on 2022-08-17 19:05
from django.db import migrations, models
import uuid
@ -16,13 +16,12 @@ class Migration(migrations.Migration):
name='Transaction',
fields=[
('uuid', models.UUIDField(db_index=True, default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)),
('code', models.IntegerField(db_index=True, unique=True, verbose_name='code')),
('amount', models.IntegerField(verbose_name='amount')),
('delay', models.IntegerField(blank=True, default=0)),
('state', models.IntegerField(choices=[(1, 'created'), (2, 'delayed'), (3, 'pending'), (4, 'failed'), (5, 'success')], default=1)),
('state', models.IntegerField(choices=[(1, 'created'), (2, 'delayed'), (3, 'pending'), (4, 'incomplete'), (5, 'success'), (6, 'failed'), (7, 'expected_failure')], default=1)),
('create', models.DateTimeField(auto_now=True, null=True, verbose_name='create')),
('last_update', models.DateTimeField(auto_now=True, null=True, verbose_name='last update')),
('application_id', models.IntegerField(blank=True, null=True, verbose_name='application ID')),
('application_client_id', models.CharField(db_index=True, max_length=100, null=True)),
('detail_id', models.IntegerField(blank=True, null=True)),
],
),

View file

@ -1,4 +1,4 @@
# Generated by Django 3.0 on 2020-03-08 11:13
# Generated by Django 4.1 on 2022-08-17 19:05
from django.conf import settings
from django.db import migrations, models
@ -25,8 +25,4 @@ class Migration(migrations.Migration):
name='payer',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='payments', to=settings.AUTH_USER_MODEL),
),
migrations.AlterUniqueTogether(
name='transaction',
unique_together={('application_id', 'detail_id')},
),
]

View file

@ -1,17 +0,0 @@
# Generated by Django 3.0.4 on 2020-04-04 06:53
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('transactions', '0002_auto_20200308_1113'),
]
operations = [
migrations.RemoveField(
model_name='transaction',
name='code',
),
]

View file

@ -1,22 +0,0 @@
# Generated by Django 3.0.4 on 2020-04-04 09:42
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('transactions', '0003_remove_transaction_code'),
]
operations = [
migrations.RenameField(
model_name='transaction',
old_name='application_id',
new_name='application_client_id',
),
migrations.AlterUniqueTogether(
name='transaction',
unique_together=set(),
),
]

View file

@ -1,18 +0,0 @@
# Generated by Django 3.0.4 on 2020-04-04 09:42
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('transactions', '0004_auto_20200404_0942'),
]
operations = [
migrations.AlterField(
model_name='transaction',
name='application_client_id',
field=models.CharField(db_index=True, max_length=100, null=True),
),
]

View file

@ -1,18 +0,0 @@
# Generated by Django 3.0.4 on 2020-04-20 05:38
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('transactions', '0005_auto_20200404_0942'),
]
operations = [
migrations.AlterField(
model_name='transaction',
name='state',
field=models.IntegerField(choices=[(1, 'created'), (2, 'delayed'), (3, 'pending'), (4, 'incomplete'), (5, 'success'), (6, 'failed'), (7, 'incomplete')], default=1),
),
]

View file

@ -1,18 +0,0 @@
# Generated by Django 3.0.4 on 2020-05-19 23:24
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('transactions', '0006_auto_20200420_0538'),
]
operations = [
migrations.AlterField(
model_name='transaction',
name='state',
field=models.IntegerField(choices=[(1, 'created'), (2, 'delayed'), (3, 'pending'), (4, 'incomplete'), (5, 'success'), (6, 'failed'), (7, 'expected_failure')], default=1),
),
]

View file

@ -1,4 +1,4 @@
# Generated by Django 3.0 on 2020-03-08 11:13
# Generated by Django 4.1 on 2022-08-17 19:05
import apps.users.models
import django.contrib.auth.validators
@ -12,7 +12,7 @@ class Migration(migrations.Migration):
initial = True
dependencies = [
('auth', '0011_update_proxy_permissions'),
('auth', '0012_alter_user_first_name_max_length'),
]
operations = [
@ -25,6 +25,10 @@ class Migration(migrations.Migration):
('first_name', models.CharField(blank=True, max_length=30, verbose_name='first name')),
('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')),
('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')),
('province', models.IntegerField(blank=True, null=True, verbose_name='Province')),
('city', models.IntegerField(blank=True, null=True, verbose_name='City')),
('postal_code', models.CharField(blank=True, max_length=20, null=True, verbose_name='postal_code')),
('address', models.TextField(blank=True, null=True, verbose_name='address')),
('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
('password', models.CharField(max_length=128, verbose_name='password')),
@ -38,12 +42,11 @@ class Migration(migrations.Migration):
('iban', models.CharField(blank=True, max_length=30, null=True)),
('iban_verified', models.BooleanField(null=True)),
('avatar', models.ImageField(blank=True, null=True, upload_to='avatars')),
('code', models.IntegerField(db_index=True, null=True, unique=True, verbose_name='code')),
('last_update', models.DateTimeField(auto_now=True, max_length=30, null=True, verbose_name='last update')),
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')),
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')),
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')),
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')),
],
options={
'verbose_name': 'user',

View file

@ -1,17 +0,0 @@
# Generated by Django 3.0 on 2020-03-08 11:31
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('users', '0001_initial'),
]
operations = [
migrations.RemoveField(
model_name='user',
name='code',
),
]

View file

@ -1,33 +0,0 @@
# Generated by Django 3.1.3 on 2020-11-15 09:48
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('users', '0002_remove_user_code'),
]
operations = [
migrations.AddField(
model_name='user',
name='address',
field=models.TextField(blank=True, null=True, verbose_name='address'),
),
migrations.AddField(
model_name='user',
name='city',
field=models.IntegerField(blank=True, null=True, verbose_name='City'),
),
migrations.AddField(
model_name='user',
name='postal_code',
field=models.CharField(blank=True, max_length=20, null=True, verbose_name='postal_code'),
),
migrations.AddField(
model_name='user',
name='province',
field=models.IntegerField(blank=True, null=True, verbose_name='Province'),
),
]

View file

@ -1,7 +1,7 @@
import random
from datetime import timedelta
import service_clients
# import service_clients
from django.conf import settings
from django.contrib.auth.base_user import BaseUserManager
from django.contrib.auth.models import AbstractUser
@ -21,7 +21,7 @@ class UserManager(BaseUserManager):
use_in_migrations = True
def _create_user(self, phone_number=None, username=None, email=None, password=None, **extra_fields):
if not phone_number and not email:
if not phone_number and not email and not username:
raise ValueError('The given phone_number or email must be set')
email = self.normalize_email(email)
@ -177,6 +177,7 @@ class User(AbstractUser):
return result
def send_otp(self):
print(self.otp)
self.notify(body=str(self.otp), title='OTP')
def notify(self, body, title=None, notification_type='sms'):

View file

@ -1,12 +1,12 @@
from celery import shared_task
from django.conf import settings
from service_clients import Client, AccountsClient
# from service_clients import Client, AccountsClient
SCOPES = ['notifications.notification:submit']
client = Client(client_id=settings.CLIENT_ID,
client_secret=settings.CLIENT_SECRET,
scopes=SCOPES,
grant_type=AccountsClient.GRANT_CLIENT_CREDENTIALS)
# SCOPES = ['notifications.notification:submit']
# client = Client(client_id=settings.CLIENT_ID,
# client_secret=settings.CLIENT_SECRET,
# scopes=SCOPES,
# grant_type=AccountsClient.GRANT_CLIENT_CREDENTIALS)
@shared_task
def send_notification(phone_number=None,