From cff8033bdd72764d183e1a87f0cd948e69dfc75d Mon Sep 17 00:00:00 2001 From: Mukhtar Date: Mon, 11 Jul 2016 10:07:44 +0300 Subject: [PATCH] #ARC-2 Add backend for authentication with username and email --- archilance/settings/base.py | 31 +++++++------ archilance/settings/dev.py | 2 +- archilance/urls.py | 4 +- templates/home.html | 1 + templates/partials/base.html | 5 ++ templates/password_reset/base.html | 1 + templates/password_reset/recovery_done.html | 20 ++++++++ templates/password_reset/recovery_email.txt | 9 ++++ templates/password_reset/recovery_form.html | 29 ++++++++++++ templates/password_reset/reset.html | 46 +++++++++++++++++++ templates/password_reset/reset_sent.html | 28 +++++++++++ templates/registration/registration_form.html | 10 +++- users/backend.py | 25 ++++++++++ users/migrations/0019_auto_20160710_1950.py | 20 ++++++++ users/models.py | 2 +- users/templates/contractor_profile.html | 2 +- users/urls.py | 2 + users/views.py | 6 +-- work_sell/templates/upload.html | 41 +++++++++++++++++ 19 files changed, 259 insertions(+), 25 deletions(-) create mode 100644 templates/password_reset/base.html create mode 100644 templates/password_reset/recovery_done.html create mode 100644 templates/password_reset/recovery_email.txt create mode 100644 templates/password_reset/recovery_form.html create mode 100644 templates/password_reset/reset.html create mode 100644 templates/password_reset/reset_sent.html create mode 100644 users/backend.py create mode 100644 users/migrations/0019_auto_20160710_1950.py diff --git a/archilance/settings/base.py b/archilance/settings/base.py index 01a76d4..716584e 100644 --- a/archilance/settings/base.py +++ b/archilance/settings/base.py @@ -15,11 +15,11 @@ DEBUG = True ALLOWED_HOSTS = [] - # Application definition DJANGO_APPS = [ 'django.contrib.admin', + 'registration', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', @@ -33,9 +33,10 @@ THIRD_PARTY_APPS = [ 'django_extensions', 'social.apps.django_app.default', 'mptt', - 'registration', 'rest_framework', 'sorl.thumbnail', + 'compressor', + 'password_reset', ] LOCAL_APPS = [ @@ -47,11 +48,9 @@ LOCAL_APPS = [ 'specializations', 'users', 'reviews', - 'chat', ] - INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS MIDDLEWARE_CLASSES = [ @@ -85,7 +84,6 @@ TEMPLATES = [ WSGI_APPLICATION = 'archilance.wsgi.application' - # Database # https://docs.djangoproject.com/en/1.9/ref/settings/#databases @@ -107,7 +105,6 @@ DATABASES = { } } - # Password validation # https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators @@ -118,14 +115,14 @@ AUTH_PASSWORD_VALIDATORS = [ {'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator'}, ] - AUTHENTICATION_BACKENDS = ( 'social.backends.facebook.FacebookOAuth2', 'social.backends.google.GoogleOAuth2', 'social.backends.twitter.TwitterOAuth', 'social.backends.vk.VKOAuth2', 'social.backends.odnoklassniki.OdnoklassnikiOAuth2', - 'django.contrib.auth.backends.ModelBackend', + # 'django.contrib.auth.backends.ModelBackend', + 'users.backend.EmailOrUsernameModelBackend', ) # SOCIAL_AUTH_FACEBOOK_KEY = '222531191461451' @@ -158,7 +155,6 @@ SOCIAL_AUTH_VK_OAUTH2_SCOPE = [ 'email', ] - SOCIAL_AUTH_LOGIN_REDIRECT_URL = '/' SOCIAL_AUTH_NEW_USER_REDIRECT_URL = '/' SOCIAL_AUTH_NEW_ASSOCIATION_REDIRECT_URL = '/' @@ -193,14 +189,13 @@ USE_L10N = True USE_TZ = True - # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/1.9/howto/static-files/ STATIC_URL = '/static/' MEDIA_URL = '/media/' -STATIC_ROOT=os.path.join(ROOT_DIR, 'static') +STATIC_ROOT = os.path.join(ROOT_DIR, 'static') MEDIA_ROOT = os.path.join(ROOT_DIR, 'media') STATICFILES_DIRS = ( @@ -212,11 +207,9 @@ ACCOUNT_ACTIVATION_DAYS = 7 REGISTRATION_AUTO_LOGIN = True LOGIN_REDIRECT_URL = '/projects/' - if DEBUG: EMAIL_BACKEND = 'django.core.mail.backends.dummy.EmailBackend' - REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework.authentication.BasicAuthentication', @@ -229,7 +222,17 @@ REST_FRAMEWORK = { 'PAGE_SIZE': 10, - 'DEFAULT_FILTER_BACKENDS': ('rest_framework_filters.backends.DjangoFilterBackend',), # djangorestframework-filters + 'DEFAULT_FILTER_BACKENDS': ('rest_framework_filters.backends.DjangoFilterBackend',), # djangorestframework-filters } SITE_ID = 1 + +EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' +EMAIL_HOST = 'localhost' +EMAIL_HOST_PASSWORD = '' +EMAIL_HOST_USER = '' +EMAIL_PORT = 25 +EMAIL_USE_TLS = False +EMAIL_USE_SSL = False +EMAIL_TIMEOUT = 60 +EMAIL_DEFAULT = 'noreply@archilance.ru' diff --git a/archilance/settings/dev.py b/archilance/settings/dev.py index 0ad6f0c..9603670 100644 --- a/archilance/settings/dev.py +++ b/archilance/settings/dev.py @@ -1,6 +1,6 @@ from .base import * -AUTH_PASSWORD_VALIDATORS = [] +# AUTH_PASSWORD_VALIDATORS = [] # INSTALLED_APPS += ['debug_toolbar',] diff --git a/archilance/urls.py b/archilance/urls.py index a3f1c9e..5a4f83b 100644 --- a/archilance/urls.py +++ b/archilance/urls.py @@ -16,9 +16,9 @@ urlpatterns = [ url(r'^projects/', include('projects.urls')), url(r'^chat/', include('chat.urls')), url(r'^specializations/', include('specializations.urls')), - - url(r'^users/', include('registration.backends.default.urls')), url(r'^users/', include('users.urls')), + url(r'^users/', include('registration.backends.default.urls')), + url(r'^admin/', admin.site.urls), url(r'^api/', include('api.urls')), ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/templates/home.html b/templates/home.html index f48d84e..ce3ac94 100644 --- a/templates/home.html +++ b/templates/home.html @@ -6,6 +6,7 @@ {% include 'partials/header.html' %}
+{# {% url "password_reset_recover" %}#}

Основная задача сайта

diff --git a/templates/partials/base.html b/templates/partials/base.html index 61e7dfd..951b64f 100644 --- a/templates/partials/base.html +++ b/templates/partials/base.html @@ -9,7 +9,9 @@ Archilance +{% load compress %} +{% compress css %} @@ -23,6 +25,9 @@ + + + {% endcompress %} diff --git a/templates/password_reset/base.html b/templates/password_reset/base.html new file mode 100644 index 0000000..6c1aa84 --- /dev/null +++ b/templates/password_reset/base.html @@ -0,0 +1 @@ +{% extends 'partials/base.html' %} diff --git a/templates/password_reset/recovery_done.html b/templates/password_reset/recovery_done.html new file mode 100644 index 0000000..6d79be5 --- /dev/null +++ b/templates/password_reset/recovery_done.html @@ -0,0 +1,20 @@ +{% extends "password_reset/base.html" %}{% load i18n %} + +{% block title %}{% trans "New password set" %}{% endblock %} + +{% block content %} + +

+
+
+ + +
+ +
+
Успех
+ {% trans "Your password has successfully been reset. You can use it right now on the login page." %} +
+
+ +{% endblock %} diff --git a/templates/password_reset/recovery_email.txt b/templates/password_reset/recovery_email.txt new file mode 100644 index 0000000..f7a509c --- /dev/null +++ b/templates/password_reset/recovery_email.txt @@ -0,0 +1,9 @@ +{% load i18n %}{% blocktrans %}Dear {{ username }},{% endblocktrans %} + +{% blocktrans with domain=site.domain %}You -- or someone pretending to be you -- has requested a password reset on {{ domain }}.{% endblocktrans %} + +{% trans "You can set your new password by following this link:" %} + +http{% if secure %}s{% endif %}://{{ site.domain }} + +{% trans "If you don't want to reset your password, simply ignore this email and it will stay unchanged." %} diff --git a/templates/password_reset/recovery_form.html b/templates/password_reset/recovery_form.html new file mode 100644 index 0000000..927426c --- /dev/null +++ b/templates/password_reset/recovery_form.html @@ -0,0 +1,29 @@ +{% extends "password_reset/base.html" %} +{% load i18n %} + +{% block title %}{% trans "Password recovery" %}{% endblock %} + +{% block content %} + {% include 'partials/header.html' %} + +
+

Восстановление пароля

+
+
+
+ {% csrf_token %} + +
+ +

{{ form.username_or_email.errors.as_text }}

+
+ +
+ +
+
+
+{% endblock %} diff --git a/templates/password_reset/reset.html b/templates/password_reset/reset.html new file mode 100644 index 0000000..c0322b8 --- /dev/null +++ b/templates/password_reset/reset.html @@ -0,0 +1,46 @@ +{% extends "password_reset/base.html" %}{% load i18n %} + +{% block content %} +
+
+
+ + +
+ +
+
Сброс пароля
+ + {% if invalid %}{% url "password_reset_recover" as recovery_url %} + {% blocktrans %}Sorry, this password reset link is invalid. You can still + request a new one.{% endblocktrans %} + {% else %} + + {% blocktrans %}Hi, {{ username }}. Please choose your new password.{% endblocktrans %} + + +
+ {% csrf_token %} + +
+ +

{{ form.password1.errors.as_text }}

+
+
+ +

{{ form.password2.errors.as_text }}

+
+ +
+ +
+
+ {% endif %} +
+
+ +{% endblock %} diff --git a/templates/password_reset/reset_sent.html b/templates/password_reset/reset_sent.html new file mode 100644 index 0000000..8f240c1 --- /dev/null +++ b/templates/password_reset/reset_sent.html @@ -0,0 +1,28 @@ +{% extends "password_reset/base.html" %} +{% load i18n %} + +{% block title %}{% trans "Password recovery sent" %}{% endblock %} + +{#{% block content %}#} +{#

#} +{#{% endblock %}#} + + +{% block content %} + +
+
+
+ + +
+ +
+
Письмо отправлено
+{#
#} + {% blocktrans with ago=timestamp|timesince %}An email was sent to {{ email }} {{ ago }} ago. Use the link in it to set a new password.{% endblocktrans %} +
+{#
#} +
+ +{% endblock %} diff --git a/templates/registration/registration_form.html b/templates/registration/registration_form.html index b9ccc5f..c972e3e 100644 --- a/templates/registration/registration_form.html +++ b/templates/registration/registration_form.html @@ -10,8 +10,16 @@
{% if request.GET.type == 'customer' %} - {% else %} + {% elif request.GET.type == 'contractor' %} + {% else %} +
+ +
{% endif %}
diff --git a/users/backend.py b/users/backend.py new file mode 100644 index 0000000..7f74afe --- /dev/null +++ b/users/backend.py @@ -0,0 +1,25 @@ +from django.conf import settings +from django.contrib.auth import get_user_model + +from .models import User + + +class EmailOrUsernameModelBackend(object): + + def authenticate(self, username=None, password=None): + if '@' in username: + kwargs = {'email': username} + else: + kwargs = {'username': username} + try: + user = get_user_model().objects.get(**kwargs) + if user.check_password(password): + return user + except User.DoesNotExist: + return None + + def get_user(self, username): + try: + return get_user_model().objects.get(pk=username) + except get_user_model().DoesNotExist: + return None diff --git a/users/migrations/0019_auto_20160710_1950.py b/users/migrations/0019_auto_20160710_1950.py new file mode 100644 index 0000000..6472505 --- /dev/null +++ b/users/migrations/0019_auto_20160710_1950.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.6 on 2016-07-10 16:50 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0018_auto_20160710_1838'), + ] + + operations = [ + migrations.RenameField( + model_name='user', + old_name='data_joined', + new_name='date_joined', + ), + ] diff --git a/users/models.py b/users/models.py index 62b9833..47293d7 100644 --- a/users/models.py +++ b/users/models.py @@ -90,7 +90,7 @@ class User(AbstractBaseUser, PermissionsMixin): email = models.EmailField(max_length=255, unique=True, db_index=True) is_active = models.BooleanField(default=True) created = models.DateTimeField(default=timezone.now) - data_joined = models.DateTimeField(default=timezone.now) + date_joined = models.DateTimeField(default=timezone.now) last_time_visit = models.DateTimeField(default=timezone.now) contractor_specializations = TreeManyToManyField(Specialization, related_name='contractors', blank=True) contractor_status = models.CharField(default='free', max_length=20, choices=STATUSES) diff --git a/users/templates/contractor_profile.html b/users/templates/contractor_profile.html index 9c643a0..8ae75fa 100644 --- a/users/templates/contractor_profile.html +++ b/users/templates/contractor_profile.html @@ -54,7 +54,7 @@

- {{ contractor.get_full_name }}[ivanov_petr] + {{ contractor.get_full_name }}[{{ contractor.username }}]

Россия, Москва

diff --git a/users/urls.py b/users/urls.py index 1c6ed27..bc865d1 100755 --- a/users/urls.py +++ b/users/urls.py @@ -1,4 +1,5 @@ from django.conf import urls +from django.conf.urls import include from django.contrib.auth.views import login, logout from .views import ( @@ -23,6 +24,7 @@ from .views import ( app_name = 'users' urlpatterns = [ + urls.url(r'^password/', include('password_reset.urls')), urls.url(r'^customers/(?P\d+)/$', CustomerProfileOpenProjectsView.as_view(), name='customer-profile-open-projects'), urls.url(r'^customers/(?P\d+)/trashed-projects/$', CustomerProfileTrashedProjectsView.as_view(), name='customer-profile-trashed-projects'), urls.url(r'^customers/(?P\d+)/current-projects/$', CustomerProfileCurrentProjectsView.as_view(), name='customer-profile-current-projects'), diff --git a/users/views.py b/users/views.py index 70d64ef..e7bfc22 100644 --- a/users/views.py +++ b/users/views.py @@ -19,11 +19,7 @@ from django.core.mail import send_mail def send_mail_test(request): - send_mail( - 'Subject here', - 'Here is the message.', - 'magomed-gadzhiev-1984@mail.ru', - ['dagdahzub@mail.ru'], ) + send_mail('Subject here', 'Here is the message.Mukhtar hello ', '', ['muhtarzubanchi05@gmail.com'], fail_silently=False) return HttpResponse("Mail send") diff --git a/work_sell/templates/upload.html b/work_sell/templates/upload.html index 2ffa6c3..e1da566 100644 --- a/work_sell/templates/upload.html +++ b/work_sell/templates/upload.html @@ -1,6 +1,47 @@ {% extends 'partials/base.html' %} {% block content %} +

Upload Files

+
+ +
+ + + + Add files... + + + + + + +
+ +
+ +{% endblock %} +{% block js_block %} + {% endblock %}