From ba6d18d20249cd57726d06f324815090043e2e68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=B8=D0=BA=D1=82=D0=BE=D1=80=20=D0=93=D0=BB=D0=B0?= =?UTF-8?q?=D0=B4=D0=BA=D0=B8=D1=85?= Date: Thu, 7 Nov 2019 17:01:26 +0300 Subject: [PATCH 1/7] Fix account migration --- .../management/commands/add_account.py | 38 ++++++++++++++ .../account/management/commands/add_social.py | 50 +++++++++++++++++++ .../management/commands/add_position.py | 1 - project/settings/local.py | 22 ++++++++ requirements/development.txt | 3 +- 5 files changed, 112 insertions(+), 2 deletions(-) create mode 100644 apps/account/management/commands/add_account.py create mode 100644 apps/account/management/commands/add_social.py diff --git a/apps/account/management/commands/add_account.py b/apps/account/management/commands/add_account.py new file mode 100644 index 00000000..808f661e --- /dev/null +++ b/apps/account/management/commands/add_account.py @@ -0,0 +1,38 @@ +from django.core.management.base import BaseCommand +from django.db import connections +from django.db.models import Q +from establishment.management.commands.add_position import namedtuplefetchall +from account.models import User + + +class Command(BaseCommand): + help = 'Add account from old db to new db' + + def account_sql(self): + with connections['legacy'].cursor() as cursor: + cursor.execute(''' + select a.email, a.id as account_id + from accounts as a + where a.email is not null + and a.email not in ('cyril@tomatic.net', + 'cyril2@tomatic.net', + 'd.sadykova@id-east.ru', + 'd.sadykova@octopod.ru', + 'n.yurchenko@id-east.ru' + ) + and a.confirmed_at is not null + ''') + return namedtuplefetchall(cursor) + + def handle(self, *args, **kwargs): + objects = [] + for a in self.account_sql(): + count = User.objects.filter(Q(email=a.email) | Q(old_id=a.account_id)).count() + if count == 0: + objects.append(User(email=a.email, + unconfirmed_email=False, + email_confirmed=True, + old_id=a.account_id + )) + User.objects.bulk_create(objects) + self.stdout.write(self.style.WARNING(f'Created accounts objects.')) \ No newline at end of file diff --git a/apps/account/management/commands/add_social.py b/apps/account/management/commands/add_social.py new file mode 100644 index 00000000..1554e255 --- /dev/null +++ b/apps/account/management/commands/add_social.py @@ -0,0 +1,50 @@ +from django.core.management.base import BaseCommand +from django.db import connections +from django.db.models import Q +from social_django.models import UserSocialAuth +from establishment.management.commands.add_position import namedtuplefetchall +from account.models import User + + +class Command(BaseCommand): + help = 'Add account from old db to new db' + + def social_sql(self): + with connections['legacy'].cursor() as cursor: + cursor.execute(''' + select + DISTINCT + i.account_id, i.provider, i.uid + from + ( + select a.email, a.id as account_id + from accounts as a + where a.email is not null + and a.email not in ('cyril@tomatic.net', + 'cyril2@tomatic.net', + 'd.sadykova@id-east.ru', + 'd.sadykova@octopod.ru', + 'n.yurchenko@id-east.ru' + ) + and a.confirmed_at is not null + ) t + join identities i on i.account_id = t.account_id + ''') + return namedtuplefetchall(cursor) + + def handle(self, *args, **kwargs): + objects = [] + for s in self.social_sql(): + user = User.objects.filter(old_id=s.account_id) + if user.count() > 0: + social = UserSocialAuth.objects.filter(user=user.first(), + provider=s.provider, + uid=s.uid) + if social.count() == 0: + objects.append(UserSocialAuth(user=user.first(), provider=s.provider, + uid=s.uid) + ) + print('INSERT') + + UserSocialAuth.objects.bulk_create(objects) + self.stdout.write(self.style.WARNING(f'Created social objects.')) \ No newline at end of file diff --git a/apps/establishment/management/commands/add_position.py b/apps/establishment/management/commands/add_position.py index 0a456a69..18e8f05c 100644 --- a/apps/establishment/management/commands/add_position.py +++ b/apps/establishment/management/commands/add_position.py @@ -24,7 +24,6 @@ class Command(BaseCommand): return namedtuplefetchall(cursor) def handle(self, *args, **kwargs): - objects = [] for p in self.position_sql(): count = Position.objects.filter(name={"en-GB": p.position_name}).count() diff --git a/project/settings/local.py b/project/settings/local.py index e87b99f6..b1775ebd 100644 --- a/project/settings/local.py +++ b/project/settings/local.py @@ -73,6 +73,28 @@ LOGGING = { } + +DATABASES = { + 'default': { + 'ENGINE': 'django.contrib.gis.db.backends.postgis', + 'NAME': os.environ.get('DB_NAME'), + 'USER': os.environ.get('DB_USERNAME'), + 'PASSWORD': os.environ.get('DB_PASSWORD'), + 'HOST': os.environ.get('DB_HOSTNAME'), + 'PORT': os.environ.get('DB_PORT'), + }, + 'legacy': { + 'ENGINE': 'django.db.backends.mysql', + # 'HOST': '172.17.0.1', + # 'HOST': '172.23.0.1', + 'HOST': 'mysql_db', + 'PORT': 3306, + 'NAME': 'dev', + 'USER': 'dev', + 'PASSWORD': 'octosecret123' + } +} + # ELASTICSEARCH SETTINGS ELASTICSEARCH_DSL = { 'default': { diff --git a/requirements/development.txt b/requirements/development.txt index 21f7ead9..77c3d73c 100644 --- a/requirements/development.txt +++ b/requirements/development.txt @@ -1,3 +1,4 @@ -r base.txt ipdb -ipython \ No newline at end of file +ipython +mysqlclient==1.4.4 \ No newline at end of file From 37ba1a1c393b07968c65367f1862c9366d2ce3d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=B8=D0=BA=D1=82=D0=BE=D1=80=20=D0=93=D0=BB=D0=B0?= =?UTF-8?q?=D0=B4=D0=BA=D0=B8=D1=85?= Date: Thu, 7 Nov 2019 17:03:14 +0300 Subject: [PATCH 2/7] Edit help message --- apps/account/management/commands/add_social.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/account/management/commands/add_social.py b/apps/account/management/commands/add_social.py index 1554e255..c7894c32 100644 --- a/apps/account/management/commands/add_social.py +++ b/apps/account/management/commands/add_social.py @@ -7,7 +7,8 @@ from account.models import User class Command(BaseCommand): - help = 'Add account from old db to new db' + help = '''Add account social networks from old db to new db. + Run after add_account!!!''' def social_sql(self): with connections['legacy'].cursor() as cursor: From 251d29c4613ab65f0c5f19e0271ad281bd3c5ca3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=B8=D0=BA=D1=82=D0=BE=D1=80=20=D0=93=D0=BB=D0=B0?= =?UTF-8?q?=D0=B4=D0=BA=D0=B8=D1=85?= Date: Fri, 8 Nov 2019 11:29:45 +0300 Subject: [PATCH 3/7] Add image url --- apps/account/management/commands/add_image.py | 41 +++++++++++++++++++ .../migrations/0019_auto_20191108_0827.py | 18 ++++++++ apps/account/models.py | 3 +- 3 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 apps/account/management/commands/add_image.py create mode 100644 apps/account/migrations/0019_auto_20191108_0827.py diff --git a/apps/account/management/commands/add_image.py b/apps/account/management/commands/add_image.py new file mode 100644 index 00000000..e6f5d88d --- /dev/null +++ b/apps/account/management/commands/add_image.py @@ -0,0 +1,41 @@ +from django.core.management.base import BaseCommand +from django.db import connections +from django.db.models import Q +from establishment.management.commands.add_position import namedtuplefetchall +from account.models import User + + +class Command(BaseCommand): + help = 'Update accounts image from old db to new db' + + def account_sql(self): + with connections['legacy'].cursor() as cursor: + cursor.execute(''' + select REPLACE(p.image_url, 'original.png', p.attachment_file_name) as image_url, + p.attachment_file_name, + p.account_id + from + ( + select + REPLACE( + REPLACE(t.url, 'original.jpg', t.attachment_file_name), + 'original.jpeg', t.attachment_file_name + ) as image_url, + t.attachment_file_name, + t.account_id + from + ( + select a.account_id, a.attachment_file_name, + LOWER(trim(CONCAT(u.url, a.attachment_suffix_url))) as url + from account_pictures a, + (select 'https://s3.eu-central-1.amazonaws.com/gm-test.com/media/' url) u + ) t + ) p + ''') + return namedtuplefetchall(cursor) + + def handle(self, *args, **kwargs): + for a in self.account_sql(): + users = User.objects.filter(old_id=a.account_id) + users.update(image_url= a.image_url) + self.stdout.write(self.style.WARNING(f'Update accounts image url.')) \ No newline at end of file diff --git a/apps/account/migrations/0019_auto_20191108_0827.py b/apps/account/migrations/0019_auto_20191108_0827.py new file mode 100644 index 00000000..1a3bb2ac --- /dev/null +++ b/apps/account/migrations/0019_auto_20191108_0827.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.4 on 2019-11-08 08:27 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('account', '0018_user_old_id'), + ] + + operations = [ + migrations.AlterField( + model_name='user', + name='image_url', + field=models.URLField(blank=True, default=None, max_length=500, null=True, verbose_name='Image URL path'), + ), + ] diff --git a/apps/account/models.py b/apps/account/models.py index e06727f2..9573c92e 100644 --- a/apps/account/models.py +++ b/apps/account/models.py @@ -89,7 +89,8 @@ class UserQuerySet(models.QuerySet): class User(AbstractUser): """Base user model.""" image_url = models.URLField(verbose_name=_('Image URL path'), - blank=True, null=True, default=None) + blank=True, null=True, default=None, + max_length=500) cropped_image_url = models.URLField(verbose_name=_('Cropped image URL path'), blank=True, null=True, default=None) email = models.EmailField(_('email address'), unique=True, From be0412ffaeb55a16f6b827a4b5becacf42088736 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=B8=D0=BA=D1=82=D0=BE=D1=80=20=D0=93=D0=BB=D0=B0?= =?UTF-8?q?=D0=B4=D0=BA=D0=B8=D1=85?= Date: Fri, 8 Nov 2019 11:42:40 +0300 Subject: [PATCH 4/7] Fix url --- apps/account/management/commands/add_image.py | 32 +++++++------------ 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/apps/account/management/commands/add_image.py b/apps/account/management/commands/add_image.py index e6f5d88d..07efe53b 100644 --- a/apps/account/management/commands/add_image.py +++ b/apps/account/management/commands/add_image.py @@ -11,27 +11,17 @@ class Command(BaseCommand): def account_sql(self): with connections['legacy'].cursor() as cursor: cursor.execute(''' - select REPLACE(p.image_url, 'original.png', p.attachment_file_name) as image_url, - p.attachment_file_name, - p.account_id - from - ( - select - REPLACE( - REPLACE(t.url, 'original.jpg', t.attachment_file_name), - 'original.jpeg', t.attachment_file_name - ) as image_url, - t.attachment_file_name, - t.account_id - from - ( - select a.account_id, a.attachment_file_name, - LOWER(trim(CONCAT(u.url, a.attachment_suffix_url))) as url - from account_pictures a, - (select 'https://s3.eu-central-1.amazonaws.com/gm-test.com/media/' url) u - ) t - ) p - ''') + select + url as image_url, + t.account_id + from + ( + select a.account_id, a.attachment_file_name, + trim(CONCAT(u.url, a.attachment_suffix_url)) as url + from account_pictures a, + (select 'https://s3.eu-central-1.amazonaws.com/gm-test.com/media/' as url) u + ) t + ''') return namedtuplefetchall(cursor) def handle(self, *args, **kwargs): From d9e14194c3b4e87c4bc325d361fb261cd8bde9cd Mon Sep 17 00:00:00 2001 From: Semyon Yekhmenin Date: Fri, 8 Nov 2019 10:54:50 +0000 Subject: [PATCH 5/7] Removed pagination from back regions list view --- apps/location/views/back.py | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/location/views/back.py b/apps/location/views/back.py index bb64ff72..a4eee929 100644 --- a/apps/location/views/back.py +++ b/apps/location/views/back.py @@ -38,6 +38,7 @@ class CityRUDView(common.CityViewMixin, generics.RetrieveUpdateDestroyAPIView): # Region class RegionListCreateView(common.RegionViewMixin, generics.ListCreateAPIView): """Create view for model Region""" + pagination_class = None serializer_class = serializers.RegionSerializer permission_classes = [IsAuthenticatedOrReadOnly|IsCountryAdmin] From b02ccb3b08efd459f105dfa620d59f7e797ec46a Mon Sep 17 00:00:00 2001 From: evgeniy-st Date: Fri, 8 Nov 2019 16:12:43 +0300 Subject: [PATCH 6/7] Bcrypt support --- project/settings/base.py | 8 ++++++++ requirements/base.txt | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/project/settings/base.py b/project/settings/base.py index d5259550..4352590f 100644 --- a/project/settings/base.py +++ b/project/settings/base.py @@ -188,6 +188,14 @@ AUTH_PASSWORD_VALIDATORS = [ }, ] +PASSWORD_HASHERS = [ + 'django.contrib.auth.hashers.PBKDF2PasswordHasher', + 'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher', + 'django.contrib.auth.hashers.Argon2PasswordHasher', + 'django.contrib.auth.hashers.BCryptPasswordHasher', + 'django.contrib.auth.hashers.BCryptSHA256PasswordHasher', +] + # Account settings AUTH_USER_MODEL = 'account.User' LOGIN_URL = 'admin:login' diff --git a/requirements/base.txt b/requirements/base.txt index e492e114..38c68179 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -1,4 +1,4 @@ -Django==2.2.4 +Django[bcrypt]==2.2.7 psycopg2-binary==2.8.3 pytz==2019.1 sqlparse==0.3.0 From b8d9a1344be9968c8505ee230bfcff35d84a6e0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=B8=D0=BA=D1=82=D0=BE=D1=80=20=D0=93=D0=BB=D0=B0?= =?UTF-8?q?=D0=B4=D0=BA=D0=B8=D1=85?= Date: Fri, 8 Nov 2019 16:31:43 +0300 Subject: [PATCH 7/7] Add hash password --- apps/account/management/commands/add_account.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/apps/account/management/commands/add_account.py b/apps/account/management/commands/add_account.py index 808f661e..2b72767c 100644 --- a/apps/account/management/commands/add_account.py +++ b/apps/account/management/commands/add_account.py @@ -11,7 +11,7 @@ class Command(BaseCommand): def account_sql(self): with connections['legacy'].cursor() as cursor: cursor.execute(''' - select a.email, a.id as account_id + select a.email, a.id as account_id, a.encrypted_password from accounts as a where a.email is not null and a.email not in ('cyril@tomatic.net', @@ -20,7 +20,7 @@ class Command(BaseCommand): 'd.sadykova@octopod.ru', 'n.yurchenko@id-east.ru' ) - and a.confirmed_at is not null + and a.confirmed_at is not null ''') return namedtuplefetchall(cursor) @@ -32,7 +32,12 @@ class Command(BaseCommand): objects.append(User(email=a.email, unconfirmed_email=False, email_confirmed=True, - old_id=a.account_id + old_id=a.account_id, + password='bcrypt$'+a.encrypted_password )) + else: + user = User.objects.filter(Q(email=a.email) | Q(old_id=a.account_id)) + user.update(password='bcrypt$'+a.encrypted_password) + User.objects.bulk_create(objects) self.stdout.write(self.style.WARNING(f'Created accounts objects.')) \ No newline at end of file