Skip to content

Commit 61c948d

Browse files
committed
chore(passport): make user email unique
1 parent 2aa12d4 commit 61c948d

9 files changed

Lines changed: 98 additions & 15 deletions

File tree

rootfs/api/admin.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from django.contrib import admin
2+
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
3+
4+
from .models import User
5+
6+
class UserAdmin(BaseUserAdmin):
7+
add_fieldsets = (
8+
(None, {
9+
'classes': ('wide',),
10+
'fields': ('username', 'password1', 'password2', 'email'),
11+
}),
12+
)
13+
14+
15+
admin.site.register(User, UserAdmin)

rootfs/api/management/commands/create_oauth2_application.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import os
2-
from django.contrib.auth.models import User
2+
from django.contrib.auth import get_user_model
33
from django.core.management.base import BaseCommand
44
from oauth2_provider.models import Application
55

6+
User = get_user_model()
7+
68

79
class Command(BaseCommand):
810
"""Management command for create Oauth2 application"""
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Generated by Django 3.2.5 on 2021-12-16 03:45
2+
3+
import django.contrib.auth.models
4+
import django.contrib.auth.validators
5+
from django.db import migrations, models
6+
import django.utils.timezone
7+
8+
9+
class Migration(migrations.Migration):
10+
11+
initial = True
12+
13+
dependencies = [
14+
('auth', '0012_alter_user_first_name_max_length'),
15+
]
16+
17+
operations = [
18+
migrations.CreateModel(
19+
name='User',
20+
fields=[
21+
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
22+
('password', models.CharField(max_length=128, verbose_name='password')),
23+
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
24+
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
25+
('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')),
26+
('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')),
27+
('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')),
28+
('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
29+
('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')),
30+
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
31+
('email', models.EmailField(max_length=254, unique=True, verbose_name='email address')),
32+
('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')),
33+
('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')),
34+
],
35+
options={
36+
'verbose_name': 'user',
37+
'verbose_name_plural': 'users',
38+
'abstract': False,
39+
},
40+
managers=[
41+
('objects', django.contrib.auth.models.UserManager()),
42+
],
43+
),
44+
]

rootfs/api/migrations/__init__.py

Whitespace-only changes.

rootfs/api/models.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from django.db import models
2+
from django.contrib.auth.models import AbstractUser
3+
from django.utils.translation import gettext_lazy as _
4+
5+
6+
class User(AbstractUser):
7+
email = models.EmailField(_('email address'), unique=True)

rootfs/api/serializers.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@
55

66
from django.contrib.admin.models import LogEntry
77
from django.contrib.auth.forms import UserCreationForm
8-
from django.contrib.auth.models import User
8+
from django.contrib.auth import get_user_model
99
from oauth2_provider.models import Grant, AccessToken
1010
from oauth2_provider.oauth2_validators import OAuth2Validator
1111
from rest_framework import serializers
1212

1313
from api.utils import timestamp2datetime
1414

15+
User = get_user_model()
1516
logger = logging.getLogger(__name__)
1617

1718

rootfs/api/settings/production.py

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
1616
# SECURITY WARNING: don't run with debug turned on in production!
17-
DEBUG = bool(os.environ.get('DRYCC_DEBUG', False))
17+
DEBUG = os.environ.get('DRYCC_DEBUG', 'false').lower() != 'false'
1818

1919
# If set to True, Django's normal exception handling of view functions
2020
# will be suppressed, and exceptions will propagate upwards
@@ -29,7 +29,8 @@
2929
# https://docs.djangoproject.com/en/2.2/ref/checks/#security
3030
SILENCED_SYSTEM_CHECKS = [
3131
'security.W004',
32-
'security.W008'
32+
'security.W008',
33+
'security.W012',
3334
]
3435

3536
CONN_MAX_AGE = 60 * 3
@@ -111,6 +112,9 @@
111112
'api'
112113
)
113114

115+
AUTH_USER_MODEL = "api.User"
116+
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
117+
114118
AUTHENTICATION_BACKENDS = (
115119
"django.contrib.auth.backends.ModelBackend",
116120
"guardian.backends.ObjectPermissionBackend",
@@ -155,8 +159,8 @@
155159
CSRF_COOKIE_SAMESITE = None
156160
SECURE_CONTENT_TYPE_NOSNIFF = True
157161
SECURE_BROWSER_XSS_FILTER = True
158-
CSRF_COOKIE_SECURE = bool(os.environ.get('CSRF_COOKIE_SECURE', False))
159-
SESSION_COOKIE_SECURE = bool(os.environ.get('SESSION_COOKIE_SECURE', False))
162+
CSRF_COOKIE_SECURE = os.environ.get('CSRF_COOKIE_SECURE', 'true').lower() != 'false'
163+
SESSION_COOKIE_SECURE = os.environ.get('SESSION_COOKIE_SECURE', 'false').lower() != 'false'
160164

161165
# Honor HTTPS from a trusted proxy
162166
# see https://docs.djangoproject.com/en/2.2/ref/settings/#secure-proxy-ssl-header
@@ -255,7 +259,7 @@
255259
SECRET_KEY = os.environ.get('DRYCC_SECRET_KEY', random_secret)
256260

257261
# database setting
258-
DRYCC_DATABASE_URL = os.environ.get('DRYCC_DATABASE_URL', 'postgres://:@:5432/passport') # noqa
262+
DRYCC_DATABASE_URL = os.environ.get('DRYCC_DATABASE_URL', 'postgres://postgres:123456@49.232.207.93:5432/drycc_passport') # noqa
259263
DATABASES = {
260264
'default': dj_database_url.config(default=DRYCC_DATABASE_URL,
261265
conn_max_age=600)
@@ -269,9 +273,16 @@
269273

270274
# Avatar URL
271275
AVATAR_URL = "https://cravatar.cn/avatar/"
276+
272277
# see: https://django-oauth-toolkit.readthedocs.io/en/latest/oidc.html?highlight=oidc.key#creating-rsa-private-key # noqa
273-
with open('/var/run/secrets/drycc/passport/oidc-rsa-private-key') as f:
274-
OIDC_RSA_PRIVATE_KEY = f.read()
278+
OIDC_ENABLED = False
279+
OIDC_RSA_PRIVATE_KEY = None
280+
OIDC_RSA_PRIVATE_KEY_FILE = '/var/run/secrets/drycc/passport/oidc-rsa-private-key'
281+
if os.path.exists(OIDC_RSA_PRIVATE_KEY_FILE):
282+
with open('/var/run/secrets/drycc/passport/oidc-rsa-private-key') as f:
283+
OIDC_RSA_PRIVATE_KEY = f.read()
284+
OIDC_ENABLED = True
285+
275286
OAUTH2_PROVIDER = {
276287
"OIDC_ENABLED": True,
277288
"OIDC_RSA_PRIVATE_KEY": OIDC_RSA_PRIVATE_KEY,

rootfs/api/urls.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
re_path(r'update/(?P<uidb64>.+)/(?P<token>.+)/?$',
1414
views.UpdateAccount.as_view(), name='user_update_account'),
1515
re_path(r'^avatar/(?P<username>[-_\w]+)/?$',
16-
views.UserAvatarViewSet.as_view({'get': 'avatar'})),
16+
views.UserAvatarViewSet.as_view({'get': 'avatar'})),
1717
re_path(r'registration/?$', views.RegistrationView.as_view(), name='registration'),
1818
re_path(r'activate/(?P<uidb64>.+)/(?P<token>.+)/?$',
1919
views.ActivateAccount.as_view(), name='user_activate_account'),

rootfs/api/views.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
from django.views.decorators.cache import cache_page
77
from django.contrib import messages, auth
88
from django.contrib.auth import login
9-
from django.contrib.auth.models import User
109
from django.contrib.auth import views
10+
from django.contrib.auth import get_user_model
1111
from django.db.models import Q
1212
from django.shortcuts import redirect, get_object_or_404, render
1313
from django.template.loader import render_to_string
@@ -30,6 +30,7 @@
3030
from api.utils import token_generator, get_local_host
3131
from api.viewset import NormalUserViewSet
3232

33+
User = get_user_model()
3334
logger = logging.getLogger(__name__)
3435

3536

@@ -153,9 +154,11 @@ def get_object(self):
153154
return self.request.user
154155

155156
def update(self, request, *args, **kwargs):
156-
user_serializer = self.serializer_class(data=request.data,
157-
instance=request.user,
158-
partial=True)
157+
user_serializer = self.serializer_class(
158+
data=request.data,
159+
instance=request.user,
160+
partial=True
161+
)
159162
if user_serializer.is_valid():
160163
if settings.EMAIL_HOST:
161164
user = self.get_object()
@@ -204,7 +207,7 @@ def avatar(self, request, *args, **kwargs):
204207
md5 = hashlib.md5()
205208
if user:
206209
md5.update(user.email.encode("utf8"))
207-
return HttpResponseRedirect(settings.AVATAR_URL + md5.hexdigest() + "?s=" + size)
210+
return HttpResponseRedirect(settings.AVATAR_URL + md5.hexdigest() + "?s=" + size)
208211

209212

210213
class UserEmailView(NormalUserViewSet):

0 commit comments

Comments
 (0)