├── .env(example) ├── .gitignore ├── README.md ├── backend ├── __init__.py ├── settings.py ├── urls.py └── wsgi.py ├── core_auth ├── __init__.py ├── adapter.py ├── admin.py ├── apps.py ├── migrations │ ├── 0001_initial.py │ ├── __init__.py │ └── __pycache__ │ │ ├── 0001_initial.cpython-35.pyc │ │ └── __init__.cpython-35.pyc ├── models.py ├── permissions.py ├── serializers.py ├── templates │ ├── account │ │ ├── account_inactive.html │ │ ├── base.html │ │ ├── email.html │ │ ├── email │ │ │ ├── email_confirmation_message.txt │ │ │ ├── email_confirmation_signup_message.txt │ │ │ ├── email_confirmation_signup_subject.txt │ │ │ ├── email_confirmation_subject.txt │ │ │ ├── password_reset_key_message.txt │ │ │ └── password_reset_key_subject.txt │ │ ├── email_confirm.html │ │ ├── login.html │ │ ├── logout.html │ │ ├── messages │ │ │ ├── cannot_delete_primary_email.txt │ │ │ ├── email_confirmation_sent.txt │ │ │ ├── email_confirmed.txt │ │ │ ├── email_deleted.txt │ │ │ ├── logged_in.txt │ │ │ ├── logged_out.txt │ │ │ ├── password_changed.txt │ │ │ ├── password_set.txt │ │ │ ├── primary_email_set.txt │ │ │ └── unverified_primary_email.txt │ │ ├── password_change.html │ │ ├── password_reset.html │ │ ├── password_reset_done.html │ │ ├── password_reset_from_key.html │ │ ├── password_reset_from_key_done.html │ │ ├── password_set.html │ │ ├── signup.html │ │ ├── signup_closed.html │ │ ├── snippets │ │ │ └── already_logged_in.html │ │ ├── verification_sent.html │ │ └── verified_email_required.html │ ├── base.html │ ├── openid │ │ ├── base.html │ │ └── login.html │ └── socialaccount │ │ ├── authentication_error.html │ │ ├── base.html │ │ ├── connections.html │ │ ├── login_cancelled.html │ │ ├── messages │ │ ├── account_connected.txt │ │ ├── account_connected_other.txt │ │ └── account_disconnected.txt │ │ ├── signup.html │ │ └── snippets │ │ ├── login_extra.html │ │ └── provider_list.html ├── urls.py └── views.py ├── manage.py ├── requirements.txt └── test_app ├── __init__.py ├── admin.py ├── apps.py ├── migrations └── __init__.py ├── models.py ├── serializers.py ├── tests.py ├── urls.py └── views.py /.env(example): -------------------------------------------------------------------------------- 1 | SECRET_KEY=secret_key 2 | 3 | DEBUG=True 4 | 5 | DJANGO_ADMIN_URL=my_admin_panel/ 6 | # EMAIL_URL=smtp+tls://example@gmail.com:password@smtp.gmail.com:587 7 | 8 | ALLOWED_HOSTS=*,localhost:3000 9 | CORS_ORIGIN_WHITELIST=localhost:3000,127.0.0.1:3000 10 | 11 | # DATABASE_URL=psql://urser:un-githubbedpassword@127.0.0.1:8458/database 12 | DATABASE_URL=sqlite:///db.sqlite3 13 | 14 | LANGUAGE_CODE=ru 15 | # LANGUAGE_CODE=en-us 16 | 17 | SITE_ID=1 18 | 19 | ACCOUNT_EMAIL_VERIFICATION=mandatory 20 | ACCOUNT_AUTHENTICATION_METHOD=username_email 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | MANIFEST 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | .pytest_cache/ 49 | 50 | # Translations 51 | *.mo 52 | *.pot 53 | 54 | # Django stuff: 55 | *.log 56 | local_settings.py 57 | db.sqlite3 58 | 59 | # Flask stuff: 60 | instance/ 61 | .webassets-cache 62 | 63 | # Scrapy stuff: 64 | .scrapy 65 | 66 | # Sphinx documentation 67 | docs/_build/ 68 | 69 | # PyBuilder 70 | target/ 71 | 72 | # Jupyter Notebook 73 | .ipynb_checkpoints 74 | 75 | # pyenv 76 | .python-version 77 | 78 | # celery beat schedule file 79 | celerybeat-schedule 80 | 81 | # SageMath parsed files 82 | *.sage.py 83 | 84 | # Environments 85 | .env 86 | .venv 87 | env/ 88 | venv/ 89 | ENV/ 90 | env.bak/ 91 | venv.bak/ 92 | 93 | # Spyder project settings 94 | .spyderproject 95 | .spyproject 96 | 97 | # Rope project settings 98 | .ropeproject 99 | 100 | # mkdocs documentation 101 | /site 102 | 103 | # mypy 104 | .mypy_cache/ 105 | 106 | 107 | .idea 108 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # nuxt-drf 2 | 3 | > Django REST project 4 | 5 | ## Build Setup 6 | 7 | ``` bash 8 | # (optional) Install python3.7 9 | $ apt install python3.7 python3.7-venv 10 | # 11 | # Make virtual env 12 | $ python3.7 -m venv venv 13 | # 14 | # Activate virtual env 15 | $ source venv/bin/activate 16 | # 17 | # Upgrade pip 18 | $ pip install pip --upgrade 19 | # 20 | # Install dependencies 21 | $ pip install -r requirements.txt 22 | # 23 | # Then you need rename or copy .env(example) file to file with name .env 24 | $ cp .env\(example\) .env 25 | # 26 | # Migrate 27 | $ python3 manage.py migrate 28 | # 29 | # Create superuser 30 | $ python manage.py createsuperuser 31 | # 32 | # Run server 33 | $ python3 manage.py runserver 34 | # 35 | # Then you need to edit default django site (/admin/sites/site/1/change/). 36 | # This is to ensure that in the account confirmation email was the correct path to your frontend. 37 | # By default settings in "Domain name" field must be "localhost:3000". 38 | # Note: if your site ID changes and is not equal to "1", do not forget to change the "SITE_ID" variable value in the environment variables file (.env). 39 | ``` 40 | 41 | Frontend (Nuxt.js) (https://github.com/rafizz/nuxt-drf-frontend). 42 | -------------------------------------------------------------------------------- /backend/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbikbov/nuxt-drf-backend/c33732551c87cf423f557806b6043ac438f4cfc2/backend/__init__.py -------------------------------------------------------------------------------- /backend/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for backend project. 3 | 4 | Generated by 'django-admin startproject' using Django 2.1.5. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/2.1/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/2.1/ref/settings/ 11 | """ 12 | 13 | import os 14 | import environ 15 | 16 | root = environ.Path(__file__) - 2 # three folder back (/a/b/c/ - 3 = /) 17 | env = environ.Env(DEBUG=(bool, False),) # set default values and casting 18 | # environ.Env.read_env() # reading .env file 19 | environ.Env.read_env('%s/.env' % root) # reading .env file 20 | 21 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 22 | BASE_DIR = root() 23 | 24 | 25 | # Quick-start development settings - unsuitable for production 26 | # See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/ 27 | 28 | # SECURITY WARNING: keep the secret key used in production secret! 29 | SECRET_KEY = env('SECRET_KEY') 30 | 31 | # SECURITY WARNING: don't run with debug turned on in production! 32 | DEBUG = env.bool('DEBUG', default=False) 33 | 34 | ALLOWED_HOSTS = env.list('ALLOWED_HOSTS') 35 | 36 | 37 | # Application definition 38 | 39 | INSTALLED_APPS = [ 40 | 'django.contrib.admin', 41 | 'django.contrib.auth', 42 | 'django.contrib.contenttypes', 43 | 'django.contrib.sessions', 44 | 'django.contrib.messages', 45 | 'django.contrib.staticfiles', 46 | 'django.contrib.sites', 47 | 48 | 'corsheaders', 49 | 50 | 'core_auth', 51 | 52 | 'rest_framework', 53 | 'rest_framework.authtoken', 54 | 55 | 'rest_auth', 56 | 'rest_auth.registration', 57 | 58 | 'allauth', 59 | 'allauth.account', 60 | 61 | 'allauth.socialaccount', 62 | 'allauth.socialaccount.providers.facebook', 63 | 'allauth.socialaccount.providers.vk', 64 | 65 | 'django_filters', 66 | ] 67 | 68 | MIDDLEWARE = [ 69 | 'django.middleware.security.SecurityMiddleware', 70 | 'django.contrib.sessions.middleware.SessionMiddleware', 71 | 'corsheaders.middleware.CorsMiddleware', 72 | 'django.middleware.common.CommonMiddleware', 73 | 'django.middleware.csrf.CsrfViewMiddleware', 74 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 75 | 'django.contrib.messages.middleware.MessageMiddleware', 76 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 77 | ] 78 | 79 | ROOT_URLCONF = 'backend.urls' 80 | 81 | TEMPLATES = [ 82 | { 83 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 84 | 'DIRS': [], 85 | 'APP_DIRS': True, 86 | 'OPTIONS': { 87 | 'context_processors': [ 88 | 'django.template.context_processors.debug', 89 | 'django.template.context_processors.request', 90 | 'django.contrib.auth.context_processors.auth', 91 | 'django.contrib.messages.context_processors.messages', 92 | ], 93 | }, 94 | }, 95 | ] 96 | 97 | WSGI_APPLICATION = 'backend.wsgi.application' 98 | 99 | 100 | # Database 101 | # https://docs.djangoproject.com/en/2.1/ref/settings/#databases 102 | 103 | DATABASES = { 104 | 'default': env.db(), # Raises ImproperlyConfigured exception if DATABASE_URL not in os.environ 105 | 'extra': env.db('SQLITE_URL', default='sqlite:///db.sqlite3') 106 | } 107 | 108 | 109 | # Password validation 110 | # https://docs.djangoproject.com/en/2.1/ref/settings/#auth-password-validators 111 | 112 | AUTH_PASSWORD_VALIDATORS = [ 113 | { 114 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 115 | }, 116 | { 117 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 118 | }, 119 | { 120 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 121 | }, 122 | { 123 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 124 | }, 125 | ] 126 | 127 | 128 | # Internationalization 129 | # https://docs.djangoproject.com/en/2.1/topics/i18n/ 130 | 131 | LANGUAGE_CODE = env('LANGUAGE_CODE', default='en-us') 132 | 133 | TIME_ZONE = 'UTC' 134 | 135 | USE_I18N = True 136 | 137 | USE_L10N = True 138 | 139 | USE_TZ = True 140 | 141 | 142 | # Static files (CSS, JavaScript, Images) 143 | # https://docs.djangoproject.com/en/2.1/howto/static-files/ 144 | 145 | STATIC_URL = '/static/' 146 | 147 | 148 | # Redefine "/admin" URI ot admin panel in ".env" file if you need 149 | ADMIN_URL = env('DJANGO_ADMIN_URL', default='admin/') 150 | 151 | 152 | # django-cors-headers settings 153 | # https://github.com/ottoyiu/django-cors-headers 154 | CORS_ORIGIN_WHITELIST = env.tuple('CORS_ORIGIN_WHITELIST') 155 | 156 | 157 | EMAIL_CONFIG = env.email_url('EMAIL_URL', default='consolemail://') 158 | vars().update(EMAIL_CONFIG) 159 | SERVER_EMAIL = env('DJANGO_SERVER_EMAIL', default=EMAIL_CONFIG['EMAIL_HOST_USER']) 160 | DEFAULT_FROM_EMAIL = env('DJANGO_DEFAULT_FROM_EMAIL', default=EMAIL_CONFIG['EMAIL_HOST_USER']) 161 | 162 | 163 | # django-rest-auth settings 164 | # https://django-rest-auth.readthedocs.io/en/latest/configuration.html 165 | REST_SESSION_LOGIN = True 166 | SITE_ID = env('SITE_ID') 167 | 168 | 169 | # django-allauth settings 170 | # https://django-allauth.readthedocs.io/en/latest/configuration.html 171 | # for the correct link in the account confirmation email 172 | ACCOUNT_ADAPTER = 'core_auth.adapter.CustomAccountAdapter' 173 | 174 | ACCOUNT_EMAIL_REQUIRED = True 175 | ACCOUNT_AUTHENTICATION_METHOD = env('ACCOUNT_AUTHENTICATION_METHOD', default='username_email') 176 | # ACCOUNT_EMAIL_VERIFICATION = 'optional' # user will login automaticly after registration 177 | # ACCOUNT_EMAIL_VERIFICATION = 'mandatory' # user can't login until confirm the account 178 | ACCOUNT_EMAIL_VERIFICATION = env('ACCOUNT_EMAIL_VERIFICATION', default='mandatory') 179 | ACCOUNT_LOGOUT_ON_GET = True 180 | CONFIRM_EMAIL_ON_GET = True 181 | OLD_PASSWORD_FIELD_ENABLED = True 182 | LOGOUT_ON_PASSWORD_CHANGE = False 183 | # ACCOUNT_EMAIL_SUBJECT_PREFIX (=”[Site] ”) 184 | # Subject-line prefix to use for email messages sent. By default, the name of the current Site (django.contrib.sites) is used. 185 | # ACCOUNT_DEFAULT_HTTP_PROTOCOL (=”http”) 186 | # The default protocol used for when generating URLs, e.g. for the password forgotten procedure. Note that this is a default only – see the section on HTTPS for more information. 187 | 188 | 189 | # DRF settings 190 | # https://www.django-rest-framework.org/api-guide/settings/ 191 | REST_FRAMEWORK = { 192 | 'DEFAULT_AUTHENTICATION_CLASSES': ( 193 | 'rest_framework.authentication.SessionAuthentication', 194 | 'rest_framework.authentication.TokenAuthentication', 195 | ), 196 | 'DEFAULT_PERMISSION_CLASSES': ( 197 | 'core_auth.permissions.IsSuperuserOrReadOnly', 198 | ), 199 | 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', 200 | 'PAGE_SIZE': env.int('PAGE_SIZE', default=5), 201 | 'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',) 202 | 203 | } 204 | 205 | REST_AUTH_SERIALIZERS = { 206 | 'USER_DETAILS_SERIALIZER': 'core_auth.serializers.UserSerializer', 207 | 'PASSWORD_RESET_SERIALIZER': 'core_auth.serializers.CustomPasswordResetSerializer', 208 | } 209 | 210 | 211 | # Customizing user model 212 | # https://docs.djangoproject.com/en/2.1/topics/auth/customizing/#substituting-a-custom-user-model 213 | AUTH_USER_MODEL = 'core_auth.User' 214 | 215 | 216 | # https://docs.djangoproject.com/en/2.1/ref/settings/#authentication-backends 217 | # https://django-allauth.readthedocs.io/en/latest/installation.html 218 | AUTHENTICATION_BACKENDS = ( 219 | # `allauth` specific authentication methods, such as login by e-mail 220 | "allauth.account.auth_backends.AuthenticationBackend", 221 | ) 222 | -------------------------------------------------------------------------------- /backend/urls.py: -------------------------------------------------------------------------------- 1 | """backend URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/2.1/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: path('', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.urls import include, path 14 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 15 | """ 16 | from django.contrib import admin 17 | from django.urls import path, include 18 | from django.conf import settings 19 | 20 | urlpatterns = [ 21 | path(settings.ADMIN_URL, admin.site.urls), 22 | path('', include('core_auth.urls')), 23 | path('', include('test_app.urls')), 24 | ] 25 | -------------------------------------------------------------------------------- /backend/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for backend project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/2.1/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'backend.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /core_auth/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbikbov/nuxt-drf-backend/c33732551c87cf423f557806b6043ac438f4cfc2/core_auth/__init__.py -------------------------------------------------------------------------------- /core_auth/adapter.py: -------------------------------------------------------------------------------- 1 | from allauth.account.adapter import DefaultAccountAdapter 2 | from allauth.utils import build_absolute_uri 3 | from django.urls import reverse 4 | 5 | 6 | class CustomAccountAdapter(DefaultAccountAdapter): 7 | 8 | def get_email_confirmation_url(self, request, emailconfirmation): 9 | """Redefined for correct link to frontend in the account confirmation 10 | email. 11 | """ 12 | url = reverse( 13 | "account_confirm_email_frontend", 14 | args=[emailconfirmation.key]) 15 | ret = build_absolute_uri( 16 | None, 17 | url) 18 | return ret 19 | -------------------------------------------------------------------------------- /core_auth/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django.contrib.auth import get_user_model 3 | from django.contrib.auth.admin import UserAdmin 4 | 5 | UserModel = get_user_model() 6 | 7 | admin.site.register(UserModel, UserAdmin) 8 | -------------------------------------------------------------------------------- /core_auth/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class AuthCoreConfig(AppConfig): 5 | name = 'core_auth' 6 | -------------------------------------------------------------------------------- /core_auth/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.5 on 2017-09-29 18:27 3 | from __future__ import unicode_literals 4 | 5 | import django.contrib.auth.validators 6 | from django.db import migrations, models 7 | import django.utils.timezone 8 | 9 | 10 | class Migration(migrations.Migration): 11 | 12 | initial = True 13 | 14 | dependencies = [ 15 | ('auth', '0008_alter_user_username_max_length'), 16 | ] 17 | 18 | operations = [ 19 | migrations.CreateModel( 20 | name='User', 21 | fields=[ 22 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 23 | ('password', models.CharField(max_length=128, verbose_name='password')), 24 | ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), 25 | ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), 26 | ('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')), 27 | ('first_name', models.CharField(blank=True, max_length=30, verbose_name='first name')), 28 | ('last_name', models.CharField(blank=True, max_length=30, verbose_name='last name')), 29 | ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')), 30 | ('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')), 31 | ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')), 32 | ('email', models.EmailField(max_length=254, unique=True, verbose_name='email address')), 33 | ('bio', models.TextField(blank=True, max_length=500, verbose_name='о себе')), 34 | ('location', models.CharField(blank=True, max_length=30, verbose_name='место жительства')), 35 | ('date_of_birth', models.DateField(blank=True, null=True, verbose_name='дата рождения')), 36 | ('avatar_url', models.CharField(blank=True, max_length=255, verbose_name='аватар')), 37 | ('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')), 38 | ('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')), 39 | ], 40 | options={ 41 | 'verbose_name_plural': 'users', 42 | 'verbose_name': 'user', 43 | 'abstract': False, 44 | }, 45 | ), 46 | ] 47 | -------------------------------------------------------------------------------- /core_auth/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbikbov/nuxt-drf-backend/c33732551c87cf423f557806b6043ac438f4cfc2/core_auth/migrations/__init__.py -------------------------------------------------------------------------------- /core_auth/migrations/__pycache__/0001_initial.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbikbov/nuxt-drf-backend/c33732551c87cf423f557806b6043ac438f4cfc2/core_auth/migrations/__pycache__/0001_initial.cpython-35.pyc -------------------------------------------------------------------------------- /core_auth/migrations/__pycache__/__init__.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbikbov/nuxt-drf-backend/c33732551c87cf423f557806b6043ac438f4cfc2/core_auth/migrations/__pycache__/__init__.cpython-35.pyc -------------------------------------------------------------------------------- /core_auth/models.py: -------------------------------------------------------------------------------- 1 | from django.contrib.auth.base_user import BaseUserManager 2 | from django.utils.translation import ugettext_lazy as _ 3 | from django.db import models 4 | from django.contrib.auth.models import AbstractUser 5 | from allauth.account.models import EmailAddress 6 | 7 | 8 | class UserManager(BaseUserManager): 9 | 10 | def create_user(self, email, password=None, **extra_fields): 11 | """ 12 | Creates and saves a user with the given email and password. 13 | """ 14 | if not email: 15 | raise ValueError('Users must have an email address') 16 | 17 | user = self.model( 18 | email=self.normalize_email(email), 19 | **extra_fields 20 | ) 21 | 22 | user.set_password(password) 23 | user.save(using=self._db) 24 | return user 25 | 26 | def create_superuser(self, email, password, **extra_fields): 27 | """ 28 | Creates and saves a superuser with the given email and password. 29 | """ 30 | user = self.create_user( 31 | email, 32 | password=password, 33 | **extra_fields, 34 | ) 35 | user.is_superuser = True 36 | user.is_staff = True 37 | user.save(using=self._db) 38 | 39 | new_allauth_email = EmailAddress() 40 | new_allauth_email.user = user 41 | new_allauth_email.email = email 42 | new_allauth_email.verified = True 43 | new_allauth_email.primary = True 44 | new_allauth_email.save() 45 | 46 | return user 47 | 48 | 49 | class User(AbstractUser): 50 | email = models.EmailField(_('email address'), unique=True) 51 | bio = models.TextField(_('biography'), max_length=500, blank=True) 52 | location = models.CharField(_('location'), max_length=30, blank=True) 53 | date_of_birth = models.DateField(_('date of birth'), blank=True, null=True) 54 | avatar_url = models.CharField(_('avatar'), max_length=255, blank=True) 55 | 56 | objects = UserManager() 57 | 58 | USERNAME_FIELD = 'email' 59 | REQUIRED_FIELDS = ['username'] 60 | -------------------------------------------------------------------------------- /core_auth/permissions.py: -------------------------------------------------------------------------------- 1 | from rest_framework.permissions import BasePermission, SAFE_METHODS 2 | 3 | 4 | class IsUserOrReadOnly(BasePermission): 5 | 6 | def has_object_permission(self, request, view, user): 7 | if request.method in SAFE_METHODS: 8 | return True 9 | return request.user is user 10 | 11 | 12 | class IsOwnerOrReadOnly(BasePermission): 13 | 14 | def has_object_permission(self, request, view, obj): 15 | if request.method in SAFE_METHODS: 16 | return True 17 | return obj.owner is request.user 18 | 19 | 20 | class IsSuperuserOrReadOnly(BasePermission): 21 | 22 | def has_object_permission(self, request, view, obj): 23 | if request.method in SAFE_METHODS: 24 | return True 25 | return request.user.is_superuser 26 | 27 | 28 | -------------------------------------------------------------------------------- /core_auth/serializers.py: -------------------------------------------------------------------------------- 1 | from django.contrib.auth import get_user_model 2 | from django.contrib.auth.models import Group 3 | from rest_auth.serializers import PasswordResetSerializer 4 | from rest_framework import serializers 5 | from django.utils.translation import ugettext_lazy as _ 6 | 7 | UserModel = get_user_model() 8 | 9 | 10 | class GroupSerializer(serializers.ModelSerializer): 11 | class Meta: 12 | model = Group 13 | fields = ('name',) 14 | 15 | 16 | class UserSerializer(serializers.ModelSerializer): 17 | groups = GroupSerializer(many=True, read_only=True) 18 | 19 | class Meta: 20 | model = UserModel 21 | fields = ( 22 | 'id', 23 | 'username', 24 | 'email', 25 | 'first_name', 26 | 'last_name', 27 | 'groups', 28 | 'bio', 29 | 'location', 30 | 'date_of_birth', 31 | 'avatar_url', 32 | ) 33 | read_only_fields = ('id', 'email',) 34 | 35 | 36 | class CustomPasswordResetSerializer(PasswordResetSerializer): 37 | def validate_email(self, value): 38 | self.reset_form = self.password_reset_form_class(data=self.initial_data) 39 | if not self.reset_form.is_valid(): 40 | raise serializers.ValidationError(self.reset_form.errors) 41 | 42 | if not UserModel.objects.filter(email__iexact=value).exists(): 43 | raise serializers.ValidationError(_('Электронная почта не найдена')) 44 | 45 | return value 46 | -------------------------------------------------------------------------------- /core_auth/templates/account/account_inactive.html: -------------------------------------------------------------------------------- 1 | {% extends "account/base.html" %} 2 | 3 | {% load i18n %} 4 | 5 | {% block head_title %}{% trans "Account Inactive" %}{% endblock %} 6 | 7 | {% block content %} 8 |

{% trans "Account Inactive" %}

9 | 10 |

{% trans "This account is inactive." %}

11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /core_auth/templates/account/base.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | -------------------------------------------------------------------------------- /core_auth/templates/account/email.html: -------------------------------------------------------------------------------- 1 | {% extends "account/base.html" %} 2 | 3 | {% load i18n %} 4 | 5 | {% block head_title %}{% trans "Account" %}{% endblock %} 6 | 7 | {% block content %} 8 |

{% trans "E-mail Addresses" %}

9 | {% if user.emailaddress_set.all %} 10 |

{% trans 'The following e-mail addresses are associated with your account:' %}

11 | 12 |
13 | {% csrf_token %} 14 |
15 | 16 | {% for emailaddress in user.emailaddress_set.all %} 17 |
18 | 30 |
31 | {% endfor %} 32 | 33 |
34 | 35 | 36 | 37 |
38 | 39 |
40 |
41 | 42 | {% else %} 43 |

{% trans 'Warning:'%} {% trans "You currently do not have any e-mail address set up. You should really add an e-mail address so you can receive notifications, reset your password, etc." %}

44 | 45 | {% endif %} 46 | 47 | 48 |

{% trans "Add E-mail Address" %}

49 | 50 |
51 | {% csrf_token %} 52 | {{ form.as_p }} 53 | 54 |
55 | 56 | {% endblock %} 57 | 58 | 59 | {% block extra_body %} 60 | 73 | {% endblock %} 74 | -------------------------------------------------------------------------------- /core_auth/templates/account/email/email_confirmation_message.txt: -------------------------------------------------------------------------------- 1 | {% load account %} 2 | {% user_display user as user_display %} 3 | {% load i18n %} 4 | {% autoescape off %} 5 | {% blocktrans with site_name=current_site.name site_domain=current_site.domain %} 6 | Добро пожаловать на {{ site_name }}! 7 | 8 | Вы получили это письмо потому, что пользователь {{ user_display }} указал его для своего аккаунта. 9 | Если это не Вы не переходите по ссылке. 10 | 11 | Чтобы подтвердить, что {{ user_display }} это вы, пройдите по это ссылке {{ activate_url }} 12 | {% endblocktrans %} 13 | {% endautoescape %} 14 | {% blocktrans with site_name=current_site.name site_domain=current_site.domain %} 15 | Спасибо, что используете наш сайт! 16 | 17 | Команда сайта {{ site_name }} 18 | {% endblocktrans %} 19 | -------------------------------------------------------------------------------- /core_auth/templates/account/email/email_confirmation_signup_message.txt: -------------------------------------------------------------------------------- 1 | {% include "account/email/email_confirmation_message.txt" %} 2 | -------------------------------------------------------------------------------- /core_auth/templates/account/email/email_confirmation_signup_subject.txt: -------------------------------------------------------------------------------- 1 | {% include "account/email/email_confirmation_subject.txt" %} 2 | -------------------------------------------------------------------------------- /core_auth/templates/account/email/email_confirmation_subject.txt: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | {% autoescape off %} 3 | {% blocktrans %}Пожалуйста, подтвердите Вашу электронную почту{% endblocktrans %} 4 | {% endautoescape %} 5 | -------------------------------------------------------------------------------- /core_auth/templates/account/email/password_reset_key_message.txt: -------------------------------------------------------------------------------- 1 | {% load i18n %}{% blocktrans with site_name=current_site.name site_domain=current_site.domain %}Hello from {{ site_name }}! 2 | 3 | You're receiving this e-mail because you or someone else has requested a password for your user account. 4 | It can be safely ignored if you did not request a password reset. Click the link below to reset your password.{% endblocktrans %} 5 | 6 | {{ password_reset_url }} 7 | 8 | {% if username %}{% blocktrans %}In case you forgot, your username is {{ username }}.{% endblocktrans %} 9 | 10 | {% endif %}{% blocktrans with site_name=current_site.name site_domain=current_site.domain %}Thank you for using {{ site_name }}! 11 | {{ site_domain }}{% endblocktrans %} 12 | -------------------------------------------------------------------------------- /core_auth/templates/account/email/password_reset_key_subject.txt: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | {% autoescape off %} 3 | {% blocktrans %}Password Reset E-mail{% endblocktrans %} 4 | {% endautoescape %} 5 | -------------------------------------------------------------------------------- /core_auth/templates/account/email_confirm.html: -------------------------------------------------------------------------------- 1 | {% extends "account/base.html" %} 2 | 3 | {% load i18n %} 4 | {% load account %} 5 | 6 | {% block head_title %}{% trans "Confirm E-mail Address" %}{% endblock %} 7 | 8 | 9 | {% block content %} 10 |

{% trans "Confirm E-mail Address" %}

11 | 12 | {% if confirmation %} 13 | 14 | {% user_display confirmation.email_address.user as user_display %} 15 | 16 |

{% blocktrans with confirmation.email_address.email as email %}Please confirm that {{ email }} is an e-mail address for user {{ user_display }}.{% endblocktrans %}

17 | 18 |
19 | {% csrf_token %} 20 | 21 |
22 | 23 | {% else %} 24 | 25 | {% url 'account_email' as email_url %} 26 | 27 |

{% blocktrans %}This e-mail confirmation link expired or is invalid. Please issue a new e-mail confirmation request.{% endblocktrans %}

28 | 29 | {% endif %} 30 | 31 | {% endblock %} 32 | -------------------------------------------------------------------------------- /core_auth/templates/account/login.html: -------------------------------------------------------------------------------- 1 | {% extends "account/base.html" %} 2 | 3 | {% load i18n %} 4 | {% load account socialaccount %} 5 | 6 | {% block head_title %}{% trans "Sign In" %}{% endblock %} 7 | 8 | {% block content %} 9 | 10 |

{% trans "Sign In" %}

11 | 12 | {% get_providers as socialaccount_providers %} 13 | 14 | {% if socialaccount_providers %} 15 |

{% blocktrans with site.name as site_name %}Please sign in with one 16 | of your existing third party accounts. Or, sign up 17 | for a {{ site_name }} account and sign in below:{% endblocktrans %}

18 | 19 |
20 | 21 | 24 | 25 |
{% trans 'or' %}
26 | 27 |
28 | 29 | {% include "socialaccount/snippets/login_extra.html" %} 30 | 31 | {% else %} 32 |

{% blocktrans %}If you have not created an account yet, then please 33 | sign up first.{% endblocktrans %}

34 | {% endif %} 35 | 36 |
37 | {% csrf_token %} 38 | {{ form.as_p }} 39 | {% if redirect_field_value %} 40 | 41 | {% endif %} 42 | {% trans "Forgot Password?" %} 43 | 44 |
45 | 46 | {% endblock %} 47 | -------------------------------------------------------------------------------- /core_auth/templates/account/logout.html: -------------------------------------------------------------------------------- 1 | {% extends "account/base.html" %} 2 | 3 | {% load i18n %} 4 | 5 | {% block head_title %}{% trans "Sign Out" %}{% endblock %} 6 | 7 | {% block content %} 8 |

{% trans "Sign Out" %}

9 | 10 |

{% trans 'Are you sure you want to sign out?' %}

11 | 12 |
13 | {% csrf_token %} 14 | {% if redirect_field_value %} 15 | 16 | {% endif %} 17 | 18 |
19 | 20 | 21 | {% endblock %} 22 | -------------------------------------------------------------------------------- /core_auth/templates/account/messages/cannot_delete_primary_email.txt: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | {% blocktrans %}You cannot remove your primary e-mail address ({{email}}).{% endblocktrans %} 3 | -------------------------------------------------------------------------------- /core_auth/templates/account/messages/email_confirmation_sent.txt: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | {% blocktrans %}Confirmation e-mail sent to {{email}}.{% endblocktrans %} 3 | -------------------------------------------------------------------------------- /core_auth/templates/account/messages/email_confirmed.txt: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | {% blocktrans %}You have confirmed {{email}}.{% endblocktrans %} 3 | -------------------------------------------------------------------------------- /core_auth/templates/account/messages/email_deleted.txt: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | {% blocktrans %}Removed e-mail address {{email}}.{% endblocktrans %} 3 | -------------------------------------------------------------------------------- /core_auth/templates/account/messages/logged_in.txt: -------------------------------------------------------------------------------- 1 | {% load account %} 2 | {% load i18n %} 3 | {% user_display user as name %} 4 | {% blocktrans %}Successfully signed in as {{name}}.{% endblocktrans %} 5 | -------------------------------------------------------------------------------- /core_auth/templates/account/messages/logged_out.txt: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | {% blocktrans %}You have signed out.{% endblocktrans %} 3 | -------------------------------------------------------------------------------- /core_auth/templates/account/messages/password_changed.txt: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | {% blocktrans %}Password successfully changed.{% endblocktrans %} 3 | -------------------------------------------------------------------------------- /core_auth/templates/account/messages/password_set.txt: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | {% blocktrans %}Password successfully set.{% endblocktrans %} 3 | -------------------------------------------------------------------------------- /core_auth/templates/account/messages/primary_email_set.txt: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | {% blocktrans %}Primary e-mail address set.{% endblocktrans %} 3 | -------------------------------------------------------------------------------- /core_auth/templates/account/messages/unverified_primary_email.txt: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | {% blocktrans %}Your primary e-mail address must be verified.{% endblocktrans %} 3 | -------------------------------------------------------------------------------- /core_auth/templates/account/password_change.html: -------------------------------------------------------------------------------- 1 | {% extends "account/base.html" %} 2 | 3 | {% load i18n %} 4 | 5 | {% block head_title %}{% trans "Change Password" %}{% endblock %} 6 | 7 | {% block content %} 8 |

{% trans "Change Password" %}

9 | 10 |
11 | {% csrf_token %} 12 | {{ form.as_p }} 13 | 14 |
15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /core_auth/templates/account/password_reset.html: -------------------------------------------------------------------------------- 1 | {% extends "account/base.html" %} 2 | 3 | {% load i18n %} 4 | {% load account %} 5 | 6 | {% block head_title %}{% trans "Password Reset" %}{% endblock %} 7 | 8 | {% block content %} 9 | 10 |

{% trans "Password Reset" %}

11 | {% if user.is_authenticated %} 12 | {% include "account/snippets/already_logged_in.html" %} 13 | {% endif %} 14 | 15 |

{% trans "Forgotten your password? Enter your e-mail address below, and we'll send you an e-mail allowing you to reset it." %}

16 | 17 |
18 | {% csrf_token %} 19 | {{ form.as_p }} 20 | 21 |
22 | 23 |

{% blocktrans %}Please contact us if you have any trouble resetting your password.{% endblocktrans %}

24 | {% endblock %} 25 | -------------------------------------------------------------------------------- /core_auth/templates/account/password_reset_done.html: -------------------------------------------------------------------------------- 1 | {% extends "account/base.html" %} 2 | 3 | {% load i18n %} 4 | {% load account %} 5 | 6 | {% block head_title %}{% trans "Password Reset" %}{% endblock %} 7 | 8 | {% block content %} 9 |

{% trans "Password Reset" %}

10 | 11 | {% if user.is_authenticated %} 12 | {% include "account/snippets/already_logged_in.html" %} 13 | {% endif %} 14 | 15 |

{% blocktrans %}We have sent you an e-mail. Please contact us if you do not receive it within a few minutes.{% endblocktrans %}

16 | {% endblock %} 17 | -------------------------------------------------------------------------------- /core_auth/templates/account/password_reset_from_key.html: -------------------------------------------------------------------------------- 1 | {% extends "account/base.html" %} 2 | 3 | {% load i18n %} 4 | {% block head_title %}{% trans "Change Password" %}{% endblock %} 5 | 6 | {% block content %} 7 |

{% if token_fail %}{% trans "Bad Token" %}{% else %}{% trans "Change Password" %}{% endif %}

8 | 9 | {% if token_fail %} 10 | {% url 'account_reset_password' as passwd_reset_url %} 11 |

{% blocktrans %}The password reset link was invalid, possibly because it has already been used. Please request a new password reset.{% endblocktrans %}

12 | {% else %} 13 | {% if form %} 14 |
15 | {% csrf_token %} 16 | {{ form.as_p }} 17 | 18 |
19 | {% else %} 20 |

{% trans 'Your password is now changed.' %}

21 | {% endif %} 22 | {% endif %} 23 | {% endblock %} 24 | -------------------------------------------------------------------------------- /core_auth/templates/account/password_reset_from_key_done.html: -------------------------------------------------------------------------------- 1 | {% extends "account/base.html" %} 2 | 3 | {% load i18n %} 4 | {% block head_title %}{% trans "Change Password" %}{% endblock %} 5 | 6 | {% block content %} 7 |

{% trans "Change Password" %}

8 |

{% trans 'Your password is now changed.' %}

9 | {% endblock %} 10 | -------------------------------------------------------------------------------- /core_auth/templates/account/password_set.html: -------------------------------------------------------------------------------- 1 | {% extends "account/base.html" %} 2 | 3 | {% load i18n %} 4 | 5 | {% block head_title %}{% trans "Set Password" %}{% endblock %} 6 | 7 | {% block content %} 8 |

{% trans "Set Password" %}

9 | 10 |
11 | {% csrf_token %} 12 | {{ form.as_p }} 13 | 14 |
15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /core_auth/templates/account/signup.html: -------------------------------------------------------------------------------- 1 | {% extends "account/base.html" %} 2 | 3 | {% load i18n %} 4 | 5 | {% block head_title %}{% trans "Signup" %}{% endblock %} 6 | 7 | {% block content %} 8 |

{% trans "Sign Up" %}

9 | 10 |

{% blocktrans %}Already have an account? Then please sign in.{% endblocktrans %}

11 | 12 |
13 | {% csrf_token %} 14 | {{ form.as_p }} 15 | {% if redirect_field_value %} 16 | 17 | {% endif %} 18 | 19 |
20 | 21 | {% endblock %} 22 | -------------------------------------------------------------------------------- /core_auth/templates/account/signup_closed.html: -------------------------------------------------------------------------------- 1 | {% extends "account/base.html" %} 2 | 3 | {% load i18n %} 4 | 5 | {% block head_title %}{% trans "Sign Up Closed" %}{% endblock %} 6 | 7 | {% block content %} 8 |

{% trans "Sign Up Closed" %}

9 | 10 |

{% trans "We are sorry, but the sign up is currently closed." %}

11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /core_auth/templates/account/snippets/already_logged_in.html: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | {% load account %} 3 | 4 | {% user_display user as user_display %} 5 |

{% trans "Note" %}: {% blocktrans %}you are already logged in as {{ user_display }}.{% endblocktrans %}

6 | -------------------------------------------------------------------------------- /core_auth/templates/account/verification_sent.html: -------------------------------------------------------------------------------- 1 | {% extends "account/base.html" %} 2 | 3 | {% load i18n %} 4 | 5 | {% block head_title %}{% trans "Verify Your E-mail Address" %}{% endblock %} 6 | 7 | {% block content %} 8 |

{% trans "Verify Your E-mail Address" %}

9 | 10 |

{% blocktrans %}We have sent an e-mail to you for verification. Follow the link provided to finalize the signup process. Please contact us if you do not receive it within a few minutes.{% endblocktrans %}

11 | 12 | {% endblock %} 13 | -------------------------------------------------------------------------------- /core_auth/templates/account/verified_email_required.html: -------------------------------------------------------------------------------- 1 | {% extends "account/base.html" %} 2 | 3 | {% load i18n %} 4 | 5 | {% block head_title %}{% trans "Verify Your E-mail Address" %}{% endblock %} 6 | 7 | {% block content %} 8 |

{% trans "Verify Your E-mail Address" %}

9 | 10 | {% url 'account_email' as email_url %} 11 | 12 |

{% blocktrans %}This part of the site requires us to verify that 13 | you are who you claim to be. For this purpose, we require that you 14 | verify ownership of your e-mail address. {% endblocktrans %}

15 | 16 |

{% blocktrans %}We have sent an e-mail to you for 17 | verification. Please click on the link inside this e-mail. Please 18 | contact us if you do not receive it within a few minutes.{% endblocktrans %}

19 | 20 |

{% blocktrans %}Note: you can still change your e-mail address.{% endblocktrans %}

21 | 22 | 23 | {% endblock %} 24 | -------------------------------------------------------------------------------- /core_auth/templates/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {% block head_title %}{% endblock %} 5 | {% block extra_head %} 6 | {% endblock %} 7 | 8 | 9 | {% block body %} 10 | 11 | {% if messages %} 12 |
13 | Messages: 14 | 19 |
20 | {% endif %} 21 | 22 |
23 | Menu: 24 | 33 |
34 | {% block content %} 35 | {% endblock %} 36 | {% endblock %} 37 | {% block extra_body %} 38 | {% endblock %} 39 | 40 | 41 | -------------------------------------------------------------------------------- /core_auth/templates/openid/base.html: -------------------------------------------------------------------------------- 1 | {% extends "socialaccount/base.html" %} 2 | -------------------------------------------------------------------------------- /core_auth/templates/openid/login.html: -------------------------------------------------------------------------------- 1 | {% extends "openid/base.html" %} 2 | 3 | {% load i18n %} 4 | 5 | {% block head_title %}OpenID Sign In{% endblock %} 6 | 7 | {% block content %} 8 | 9 |

{% trans 'OpenID Sign In' %}

10 | 11 | 12 |
13 | {% csrf_token %} 14 | {{form.as_p}} 15 | 16 |
17 | 18 | {% endblock %} 19 | -------------------------------------------------------------------------------- /core_auth/templates/socialaccount/authentication_error.html: -------------------------------------------------------------------------------- 1 | {% extends "socialaccount/base.html" %} 2 | 3 | {% load i18n %} 4 | 5 | {% block head_title %}{% trans "Social Network Login Failure" %}{% endblock %} 6 | 7 | {% block content %} 8 |

{% trans "Social Network Login Failure" %}

9 | 10 |

{% trans "An error occurred while attempting to login via your social network account." %}

11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /core_auth/templates/socialaccount/base.html: -------------------------------------------------------------------------------- 1 | {% extends "account/base.html" %} 2 | -------------------------------------------------------------------------------- /core_auth/templates/socialaccount/connections.html: -------------------------------------------------------------------------------- 1 | {% extends "socialaccount/base.html" %} 2 | 3 | {% load i18n %} 4 | 5 | {% block head_title %}{% trans "Account Connections" %}{% endblock %} 6 | 7 | {% block content %} 8 |

{% trans "Account Connections" %}

9 | 10 | {% if form.accounts %} 11 |

{% blocktrans %}You can sign in to your account using any of the following third party accounts:{% endblocktrans %}

12 | 13 | 14 |
15 | {% csrf_token %} 16 | 17 |
18 | {% if form.non_field_errors %} 19 |
{{ form.non_field_errors }}
20 | {% endif %} 21 | 22 | {% for base_account in form.accounts %} 23 | {% with base_account.get_provider_account as account %} 24 |
25 | 30 |
31 | {% endwith %} 32 | {% endfor %} 33 | 34 |
35 | 36 |
37 | 38 |
39 | 40 |
41 | 42 | {% else %} 43 |

{% trans 'You currently have no social network accounts connected to this account.' %}

44 | {% endif %} 45 | 46 |

{% trans 'Add a 3rd Party Account' %}

47 | 48 | 51 | 52 | {% include "socialaccount/snippets/login_extra.html" %} 53 | 54 | {% endblock %} 55 | -------------------------------------------------------------------------------- /core_auth/templates/socialaccount/login_cancelled.html: -------------------------------------------------------------------------------- 1 | {% extends "socialaccount/base.html" %} 2 | 3 | {% load i18n %} 4 | 5 | {% block head_title %}{% trans "Login Cancelled" %}{% endblock %} 6 | 7 | {% block content %} 8 | 9 |

{% trans "Login Cancelled" %}

10 | 11 | {% url 'account_login' as login_url %} 12 | 13 |

{% blocktrans %}You decided to cancel logging in to our site using one of your existing accounts. If this was a mistake, please proceed to sign in.{% endblocktrans %}

14 | 15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /core_auth/templates/socialaccount/messages/account_connected.txt: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | {% blocktrans %}The social account has been connected.{% endblocktrans %} 3 | -------------------------------------------------------------------------------- /core_auth/templates/socialaccount/messages/account_connected_other.txt: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | {% blocktrans %}The social account is already connected to a different account.{% endblocktrans %} 3 | -------------------------------------------------------------------------------- /core_auth/templates/socialaccount/messages/account_disconnected.txt: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | {% blocktrans %}The social account has been disconnected.{% endblocktrans %} 3 | -------------------------------------------------------------------------------- /core_auth/templates/socialaccount/signup.html: -------------------------------------------------------------------------------- 1 | {% extends "socialaccount/base.html" %} 2 | 3 | {% load i18n %} 4 | 5 | {% block head_title %}{% trans "Signup" %}{% endblock %} 6 | 7 | {% block content %} 8 |

{% trans "Sign Up" %}

9 | 10 |

{% blocktrans with provider_name=account.get_provider.name site_name=site.name %}You are about to use your {{provider_name}} account to login to 11 | {{site_name}}. As a final step, please complete the following form:{% endblocktrans %}

12 | 13 |
14 | {% csrf_token %} 15 | {{ form.as_p }} 16 | {% if redirect_field_value %} 17 | 18 | {% endif %} 19 | 20 |
21 | 22 | {% endblock %} 23 | -------------------------------------------------------------------------------- /core_auth/templates/socialaccount/snippets/login_extra.html: -------------------------------------------------------------------------------- 1 | {% load socialaccount %} 2 | 3 | {% providers_media_js %} 4 | -------------------------------------------------------------------------------- /core_auth/templates/socialaccount/snippets/provider_list.html: -------------------------------------------------------------------------------- 1 | {% load socialaccount %} 2 | 3 | {% get_providers as socialaccount_providers %} 4 | 5 | {% for provider in socialaccount_providers %} 6 | {% if provider.id == "openid" %} 7 | {% for brand in provider.get_brands %} 8 |
  • 9 | {{brand.name}} 13 |
  • 14 | {% endfor %} 15 | {% endif %} 16 |
  • 17 | {{provider.name}} 19 |
  • 20 | {% endfor %} 21 | -------------------------------------------------------------------------------- /core_auth/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import url, include 2 | from django.views.generic import RedirectView, TemplateView 3 | 4 | from . import views 5 | 6 | urlpatterns = [ 7 | # intercepts access to the URL, because it is not needed 8 | url(r'^auth/registration/account-confirm-email/([-:\w]+)/$', 9 | RedirectView.as_view(url='/', permanent=True)), 10 | 11 | 12 | # so that there is no error when registering and trying to send an email 13 | url(r'^confirm-email/$', 14 | RedirectView.as_view(url='/', permanent=True), 15 | name='account_email_verification_sent'), 16 | 17 | 18 | # url to generate the correct link in the email 19 | # to the frontend password reset confirmation page 20 | url(r'^auth/password/reset/confirm/(?P[0-9A-Za-z_\-]+)/(?P[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$', 21 | RedirectView.as_view(url='/', permanent=True), 22 | name='password_reset_confirm'), 23 | 24 | # url to generate the correct link in the email 25 | # to the frontend email confirmation page 26 | url(r'^auth/registration/confirm-email/(?P[-:\w]+)/$', 27 | RedirectView.as_view(url='/', permanent=True), 28 | name='account_confirm_email_frontend'), 29 | 30 | url(r'^api/v1/auth/', include('rest_auth.urls')), 31 | url(r'^api/v1/auth/registration/', include('rest_auth.registration.urls')), 32 | url(r'^api/v1/auth/check/', views.checkExists), 33 | ] 34 | -------------------------------------------------------------------------------- /core_auth/views.py: -------------------------------------------------------------------------------- 1 | from django.contrib.auth import get_user_model 2 | from django.contrib.auth.middleware import get_user 3 | from rest_framework.permissions import AllowAny 4 | from rest_framework.response import Response 5 | from rest_framework.decorators import api_view, permission_classes 6 | 7 | UserModel = get_user_model() 8 | 9 | 10 | @api_view(['GET',]) 11 | @permission_classes((AllowAny, )) 12 | def checkExists(request): 13 | # user = UserModel.objects.get(id=3) 14 | # print(user._meta.get_fields()) 15 | # print(get_user(request)) 16 | if request.method == 'GET': 17 | username = request.GET.get('username') 18 | email = request.GET.get('email') 19 | valid = True 20 | message = None 21 | 22 | if username and UserModel.objects.filter(username=username).exists(): 23 | valid = False 24 | message = 'Пользователь "%s" уже существует.' % username 25 | 26 | if email and UserModel.objects.filter(email=email).exists(): 27 | valid = False 28 | message = 'Пользователь с e-mail адресом "%s" уже зарегистрирован.' % email 29 | 30 | response = Response({'valid': valid, 'message': message}) 31 | response['Access-Control-Allow-Credentials'] = 'true' 32 | return response 33 | 34 | 35 | # отправка токена при подтверждении email 36 | # class CustomVerifyEmailView(VerifyEmailView): 37 | # def post(self, request, *args, **kwargs): 38 | # serializer = self.get_serializer(data=request.data) 39 | # serializer.is_valid(raise_exception=True) 40 | # self.kwargs['key'] = serializer.validated_data['key'] 41 | # confirmation = self.get_object() 42 | # confirmation.confirm(self.request) 43 | # token = TokenModel.objects.get(user_id=confirmation.email_address.user) 44 | # return Response({'key': token.key}, status=status.HTTP_200_OK) -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == '__main__': 6 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'backend.settings') 7 | try: 8 | from django.core.management import execute_from_command_line 9 | except ImportError as exc: 10 | raise ImportError( 11 | "Couldn't import Django. Are you sure it's installed and " 12 | "available on your PYTHONPATH environment variable? Did you " 13 | "forget to activate a virtual environment?" 14 | ) from exc 15 | execute_from_command_line(sys.argv) 16 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Django==2.1.5 2 | django-allauth==0.38.0 3 | django-cors-headers==2.4.0 4 | django-environ==0.4.5 5 | django-filter==2.0.0 6 | django-rest-auth==0.9.3 7 | djangorestframework==3.9.1 8 | psycopg2-binary-2.7.6.1 9 | -------------------------------------------------------------------------------- /test_app/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbikbov/nuxt-drf-backend/c33732551c87cf423f557806b6043ac438f4cfc2/test_app/__init__.py -------------------------------------------------------------------------------- /test_app/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /test_app/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class TestAppConfig(AppConfig): 5 | name = 'test_app' 6 | -------------------------------------------------------------------------------- /test_app/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbikbov/nuxt-drf-backend/c33732551c87cf423f557806b6043ac438f4cfc2/test_app/migrations/__init__.py -------------------------------------------------------------------------------- /test_app/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | -------------------------------------------------------------------------------- /test_app/serializers.py: -------------------------------------------------------------------------------- 1 | from django.contrib.auth import get_user_model 2 | from django.contrib.auth.models import Group 3 | from rest_framework import serializers 4 | 5 | UserModel = get_user_model() 6 | 7 | 8 | class GroupSerializer(serializers.ModelSerializer): 9 | class Meta: 10 | model = Group 11 | fields = ('id', 'name',) 12 | 13 | 14 | class UserSerializer(serializers.ModelSerializer): 15 | groups = GroupSerializer(many=True, read_only=True) 16 | 17 | class Meta: 18 | model = UserModel 19 | fields = ( 20 | 'id', 21 | 'email', 22 | 'username', 23 | 'first_name', 24 | 'last_name', 25 | 'last_name', 26 | 'bio', 27 | 'location', 28 | 'date_of_birth', 29 | 'avatar_url', 30 | 'groups', 31 | ) 32 | read_only_fields = ('id',) 33 | -------------------------------------------------------------------------------- /test_app/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /test_app/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import url, include 2 | from rest_framework import routers 3 | from . import views 4 | 5 | router = routers.DefaultRouter() 6 | router.register(r'users', views.UserViewSet) 7 | router.register(r'groups', views.GroupViewSet) 8 | 9 | urlpatterns = [ 10 | url(r'^api/v1/', include(router.urls)), 11 | ] 12 | -------------------------------------------------------------------------------- /test_app/views.py: -------------------------------------------------------------------------------- 1 | from django.contrib.auth import get_user_model 2 | from django.contrib.auth.models import Group 3 | from rest_framework import viewsets, filters 4 | 5 | from core_auth.serializers import GroupSerializer 6 | from .serializers import UserSerializer 7 | 8 | UserModel = get_user_model() 9 | 10 | class UserViewSet(viewsets.ModelViewSet): 11 | queryset = UserModel.objects.all() 12 | serializer_class = UserSerializer 13 | filter_backends = (filters.SearchFilter,) 14 | search_fields = ('username', 'email', 'first_name') 15 | 16 | 17 | class GroupViewSet(viewsets.ModelViewSet): 18 | queryset = Group.objects.all() 19 | serializer_class = GroupSerializer 20 | --------------------------------------------------------------------------------