diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..1b1ed24 --- /dev/null +++ b/Dockerfile @@ -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 \ No newline at end of file diff --git a/accounts/settings.py b/accounts/settings.py index 4b77c92..eda9c0a 100644 --- a/accounts/settings.py +++ b/accounts/settings.py @@ -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') diff --git a/accounts/urls.py b/accounts/urls.py index 87faf6a..320a055 100644 --- a/accounts/urls.py +++ b/accounts/urls.py @@ -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 diff --git a/apps/gooyal_oauth2/migrations/0002_initial.py b/apps/gooyal_oauth2/migrations/0002_initial.py new file mode 100644 index 0000000..933612f --- /dev/null +++ b/apps/gooyal_oauth2/migrations/0002_initial.py @@ -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')}, + ), + ] diff --git a/apps/gooyal_oauth2/migrations/0002_scope.py b/apps/gooyal_oauth2/migrations/0002_scope.py deleted file mode 100644 index ff2a9f6..0000000 --- a/apps/gooyal_oauth2/migrations/0002_scope.py +++ /dev/null @@ -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)), - ], - ), - ] diff --git a/apps/gooyal_oauth2/migrations/0003_auto_20200611_0828.py b/apps/gooyal_oauth2/migrations/0003_auto_20200611_0828.py deleted file mode 100644 index 5be1212..0000000 --- a/apps/gooyal_oauth2/migrations/0003_auto_20200611_0828.py +++ /dev/null @@ -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, - }, - ), - ] diff --git a/apps/gooyal_oauth2/migrations/0004_tokens.py b/apps/gooyal_oauth2/migrations/0004_tokens.py deleted file mode 100644 index af39bf8..0000000 --- a/apps/gooyal_oauth2/migrations/0004_tokens.py +++ /dev/null @@ -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')}, - }, - ), - ] diff --git a/apps/gooyal_oauth2/migrations/0005_auto_20200712_1219.py b/apps/gooyal_oauth2/migrations/0005_auto_20200712_1219.py deleted file mode 100644 index c4d79f1..0000000 --- a/apps/gooyal_oauth2/migrations/0005_auto_20200712_1219.py +++ /dev/null @@ -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), - ), - ] diff --git a/apps/gooyal_oauth2/migrations/0006_auto_20200825_0615.py b/apps/gooyal_oauth2/migrations/0006_auto_20200825_0615.py deleted file mode 100644 index 37d5a9f..0000000 --- a/apps/gooyal_oauth2/migrations/0006_auto_20200825_0615.py +++ /dev/null @@ -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), - ), - ] diff --git a/apps/gooyal_oauth2/migrations/0007_auto_20200926_0855.py b/apps/gooyal_oauth2/migrations/0007_auto_20200926_0855.py deleted file mode 100644 index 388199c..0000000 --- a/apps/gooyal_oauth2/migrations/0007_auto_20200926_0855.py +++ /dev/null @@ -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), - ), - ] diff --git a/apps/gooyal_oauth2/models.py b/apps/gooyal_oauth2/models.py index 918da77..471587e 100644 --- a/apps/gooyal_oauth2/models.py +++ b/apps/gooyal_oauth2/models.py @@ -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 \ No newline at end of file diff --git a/apps/gooyal_oauth2/validators.py b/apps/gooyal_oauth2/validators.py index 93fd423..b50511d 100755 --- a/apps/gooyal_oauth2/validators.py +++ b/apps/gooyal_oauth2/validators.py @@ -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 diff --git a/apps/transactions/migrations/0001_initial.py b/apps/transactions/migrations/0001_initial.py index 9b2f357..3b5b376 100644 --- a/apps/transactions/migrations/0001_initial.py +++ b/apps/transactions/migrations/0001_initial.py @@ -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)), ], ), diff --git a/apps/transactions/migrations/0002_auto_20200308_1113.py b/apps/transactions/migrations/0002_initial.py similarity index 81% rename from apps/transactions/migrations/0002_auto_20200308_1113.py rename to apps/transactions/migrations/0002_initial.py index 217d6e4..51d3e00 100644 --- a/apps/transactions/migrations/0002_auto_20200308_1113.py +++ b/apps/transactions/migrations/0002_initial.py @@ -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')}, - ), ] diff --git a/apps/transactions/migrations/0003_remove_transaction_code.py b/apps/transactions/migrations/0003_remove_transaction_code.py deleted file mode 100644 index b860851..0000000 --- a/apps/transactions/migrations/0003_remove_transaction_code.py +++ /dev/null @@ -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', - ), - ] diff --git a/apps/transactions/migrations/0004_auto_20200404_0942.py b/apps/transactions/migrations/0004_auto_20200404_0942.py deleted file mode 100644 index 339a289..0000000 --- a/apps/transactions/migrations/0004_auto_20200404_0942.py +++ /dev/null @@ -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(), - ), - ] diff --git a/apps/transactions/migrations/0005_auto_20200404_0942.py b/apps/transactions/migrations/0005_auto_20200404_0942.py deleted file mode 100644 index 0da4d64..0000000 --- a/apps/transactions/migrations/0005_auto_20200404_0942.py +++ /dev/null @@ -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), - ), - ] diff --git a/apps/transactions/migrations/0006_auto_20200420_0538.py b/apps/transactions/migrations/0006_auto_20200420_0538.py deleted file mode 100644 index 57346cd..0000000 --- a/apps/transactions/migrations/0006_auto_20200420_0538.py +++ /dev/null @@ -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), - ), - ] diff --git a/apps/transactions/migrations/0007_auto_20200519_2324.py b/apps/transactions/migrations/0007_auto_20200519_2324.py deleted file mode 100644 index 67dfd27..0000000 --- a/apps/transactions/migrations/0007_auto_20200519_2324.py +++ /dev/null @@ -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), - ), - ] diff --git a/apps/users/migrations/0001_initial.py b/apps/users/migrations/0001_initial.py index c072c95..91e2693 100644 --- a/apps/users/migrations/0001_initial.py +++ b/apps/users/migrations/0001_initial.py @@ -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', diff --git a/apps/users/migrations/0002_remove_user_code.py b/apps/users/migrations/0002_remove_user_code.py deleted file mode 100644 index 50553c9..0000000 --- a/apps/users/migrations/0002_remove_user_code.py +++ /dev/null @@ -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', - ), - ] diff --git a/apps/users/migrations/0003_auto_20201115_0948.py b/apps/users/migrations/0003_auto_20201115_0948.py deleted file mode 100644 index c7ff24a..0000000 --- a/apps/users/migrations/0003_auto_20201115_0948.py +++ /dev/null @@ -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'), - ), - ] diff --git a/apps/users/models.py b/apps/users/models.py index 3ab09a1..ea49b61 100644 --- a/apps/users/models.py +++ b/apps/users/models.py @@ -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'): diff --git a/apps/users/tasks.py b/apps/users/tasks.py index a82f7d3..000225c 100644 --- a/apps/users/tasks.py +++ b/apps/users/tasks.py @@ -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,