-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
#44 Login implementado #84
Changes from 15 commits
ddaba69
9091f12
c555fd4
c873fd9
6e17495
d2ad68c
b53bcfa
fd1b38d
e9a08b0
41de6d0
b63b7ea
7363665
69a15ce
faeb747
023a4b9
cdcb181
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,3 +6,6 @@ __pycache__/ | |
local_settings.py | ||
db.sqlite3 | ||
media | ||
.vscode/ | ||
env/ | ||
migrations/ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,8 @@ | ||
Django==2.2.4 | ||
djangorestframework==3.10.0 | ||
Django==2.2 | ||
djangorestframework==3.10 | ||
django-phonenumber-field==3.0 | ||
phonenumbers==8.10 | ||
djangorestframework_simplejwt | ||
django-cors-headers | ||
psycopg2==2.8.3 | ||
coverage | ||
coverage |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# default superuser | ||
# email: 'admin@admin.com' | ||
# password: 'password' | ||
echo " | ||
from django.contrib.auth import get_user_model; | ||
User = get_user_model(); | ||
|
||
if not len(User.objects.all()): | ||
User.objects.create_superuser(username='admin', email='admin@admin.com', password='password')" | python manage.py shell |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import importlib | ||
import os | ||
import time | ||
|
||
import logging | ||
|
||
SERVICES_STARTED = False | ||
|
||
log = logging.getLogger('ej') | ||
|
||
|
||
def start_services(): | ||
global SERVICES_STARTED | ||
|
||
if SERVICES_STARTED: | ||
return | ||
|
||
start_postgres() | ||
|
||
SERVICES_STARTED = True | ||
|
||
|
||
|
||
log = logging.getLogger('ej') | ||
|
||
|
||
def start_postgres(): | ||
settings_path = os.environ['DJANGO_SETTINGS_MODULE'] | ||
settings = importlib.import_module(settings_path) | ||
|
||
db = settings.DATABASES['default'] | ||
dbname = db['NAME'] | ||
user = db['USER'] | ||
host = db['HOST'] | ||
|
||
for _ in range(100): | ||
if can_connect(dbname, user, host): | ||
log.info("Postgres is available. Continuing...") | ||
return | ||
log.warning('Postgres is unavailable. Retrying in 0.5 seconds') | ||
time.sleep(0.5) | ||
|
||
log.critical('Maximum number of attempts connecting to postgres database') | ||
raise RuntimeError('could not connect to database') | ||
|
||
|
||
def can_connect(dbname, user, host): | ||
import psycopg2 | ||
|
||
try: | ||
psycopg2.connect( | ||
dbname=dbname, | ||
user=user, | ||
host=host | ||
) | ||
|
||
except psycopg2.OperationalError: | ||
return False | ||
|
||
return True |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
from django.contrib import admin | ||
from .models import User | ||
|
||
class UserAdmin(admin.ModelAdmin): | ||
list_display = ( | ||
'email', | ||
'phone_number', | ||
'birth', | ||
'email', | ||
'username', | ||
) | ||
|
||
search_fields = ('email',) | ||
|
||
admin.site.register(User, UserAdmin) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
from django.apps import AppConfig | ||
|
||
|
||
class UsersConfig(AppConfig): | ||
name = 'users' |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# Generated by Django 2.2.4 on 2019-09-24 19:30 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @vitorcx @shayanealcantara talvez devessemos criar uma issue futura pra gerenciarmos migrações (até então não vai dar problema, mas pode dar no futuro, quando estivermos trabalhando em várias funcinoalidades e branchs, pois elas são geradas sequenciamente e commitá-las pode dar algum problema There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Eu pensei em não criar commits em nenhuma migração. Eu acho que enquanto o nosso banco de dados não estiver em produção, não tem problema ficarmos zerando o banco e criando todas as migrações do zero. |
||
|
||
import django.contrib.auth.models | ||
import django.contrib.auth.validators | ||
from django.db import migrations, models | ||
import django.utils.timezone | ||
import phonenumber_field.modelfields | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
initial = True | ||
|
||
dependencies = [ | ||
('auth', '0011_update_proxy_permissions'), | ||
] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name='User', | ||
fields=[ | ||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
('password', models.CharField(max_length=128, verbose_name='password')), | ||
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), | ||
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), | ||
('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')), | ||
('first_name', models.CharField(blank=True, max_length=30, verbose_name='first name')), | ||
('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')), | ||
('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')), | ||
('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')), | ||
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')), | ||
('email', models.EmailField(max_length=254, unique=True, verbose_name='email address')), | ||
('phone_number', phonenumber_field.modelfields.PhoneNumberField(blank=True, max_length=128, region=None)), | ||
('bio', models.TextField(blank=True)), | ||
('birth', models.DateField(blank=True, null=True)), | ||
('speaks_french', models.BooleanField(default=False, help_text='Designates If the user speaks French.', verbose_name='speaks french')), | ||
('speaks_english', models.BooleanField(default=False, help_text='Designates If the user speaks English.', verbose_name='speaks english')), | ||
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')), | ||
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')), | ||
], | ||
options={ | ||
'verbose_name': 'user', | ||
'verbose_name_plural': 'users', | ||
'abstract': False, | ||
}, | ||
managers=[ | ||
('objects', django.contrib.auth.models.UserManager()), | ||
], | ||
), | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
from django.db import models | ||
from django.contrib.auth.models import AbstractUser | ||
from django.utils.translation import gettext_lazy as _ | ||
from phonenumber_field.modelfields import PhoneNumberField | ||
|
||
|
||
class User(AbstractUser): | ||
|
||
email = models.EmailField( | ||
_('email address'), | ||
unique=True, | ||
blank=False, | ||
error_messages={ | ||
'unique': 'A user with that email already exists.', | ||
} | ||
) | ||
|
||
phone_number = PhoneNumberField(blank=True, null=True) | ||
bio = models.TextField(blank=True, null=True) | ||
birth = models.DateField(blank=True, null=True) | ||
|
||
is_verified = models.BooleanField( | ||
'verified', | ||
default=True, | ||
help_text=( | ||
'Set to true when the user have verified its email address.' | ||
) | ||
) | ||
|
||
speaks_french = models.BooleanField( | ||
_('speaks french'), | ||
default=False, | ||
help_text=_('Designates If the user speaks French.'), | ||
) | ||
|
||
speaks_english = models.BooleanField( | ||
_('speaks english'), | ||
default=False, | ||
help_text=_('Designates If the user speaks English.'), | ||
) | ||
|
||
EMAIL_FIELD = 'email' | ||
USERNAME_FIELD = 'email' | ||
REQUIRED_FIELDS = ['username'] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Username como campo obrigatório, existe algum motivo? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sim! O Django. Eu tirei ele durante alguns teste, mas quando tento entrar no painel do admin do django a aplicação quebra. Aparentemente os templates do django admin usam a variável {{user.username}}, e se ela não existir quebra tudo. Uma solução seria sobrescrever esse template, mas eu não achei que seria uma boa ideia... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. teria uma solução mais interessante, mas fica pra outra sprint, criar com lambda, a partir do email do usuário um username |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Usando ModelAdmin ele coloca a hash na senha? (Como faz o UserAdmin do django.contrib.auth.admin?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Essa classe User que criamos está usando os mecanismos de senha do user padrão do Django, esses mecanismos vem da herança no AbstractUser, lá no arquivo models.py
Essa classe UserAdmin foi criada para podermos acessar o painel do admin do django ( /admin/ ). Já que não estamos usando o User nativo do django é preciso explicitar os campos que irão aparecer no painel.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
só pra esclarecer, o useradmin é um tipo de modeladmin mais adequado, mas ok