Commit d8dbb1ccdcff6aef455533463a192c5ddadefb02

Authored by Andrew Buss
1 parent 9bd8c31d05
Exists in master

fixed signup, login - was not passing in password to create_user

Showing 2 changed files with 22 additions and 19 deletions Inline Diff

flashcards/api.py View file @ d8dbb1c
from django.contrib.auth import login, authenticate 1
from django.core.mail import send_mail 2 1 from django.core.mail import send_mail
from django.contrib.auth import authenticate, login 3 2 from django.contrib.auth import authenticate, login
from django.contrib.auth.tokens import default_token_generator 4 3 from django.contrib.auth.tokens import default_token_generator
from rest_framework.views import APIView 5 4 from rest_framework.views import APIView
from rest_framework.response import Response 6 5 from rest_framework.response import Response
from rest_framework import status 7 6 from rest_framework import status
from rest_framework.exceptions import ValidationError, NotFound 8 7 from rest_framework.exceptions import ValidationError, NotFound
from flashcards.serializers import * 9 8 from flashcards.serializers import *
10 9
11 10
class UserDetail(APIView): 12 11 class UserDetail(APIView):
def patch(self, request, format=None): 13 12 def patch(self, request, format=None):
""" 14 13 """
Updates a user's password after they enter a valid old password. 15 14 Updates a user's password after they enter a valid old password.
TODO: email verification 16 15 TODO: email verification
""" 17 16 """
18 17
if 'old_password' not in request.data: 19 18 if 'old_password' not in request.data:
raise ValidationError('Old password is required') 20 19 raise ValidationError('Old password is required')
if 'new_password' not in request.data: 21 20 if 'new_password' not in request.data:
raise ValidationError('New password is required') 22 21 raise ValidationError('New password is required')
if not request.data['new_password']: 23 22 if not request.data['new_password']:
raise ValidationError('Password cannot be blank') 24 23 raise ValidationError('Password cannot be blank')
25 24
currentuser = request.user 26 25 currentuser = request.user
27 26
if not currentuser.check_password(request.data['old_password']): 28 27 if not currentuser.check_password(request.data['old_password']):
raise ValidationError('Invalid old password') 29 28 raise ValidationError('Invalid old password')
30 29
currentuser.set_password(request.data['new_password']) 31 30 currentuser.set_password(request.data['new_password'])
currentuser.save() 32 31 currentuser.save()
33 32
return Response(status=status.HTTP_204_NO_CONTENT) 34 33 return Response(status=status.HTTP_204_NO_CONTENT)
35 34
def get(self, request, format=None): 36 35 def get(self, request, format=None):
serializer = UserSerializer(request.user) 37 36 serializer = UserSerializer(request.user)
return Response(serializer.data) 38 37 return Response(serializer.data)
39 38
def post(self, request, format=None): 40 39 def post(self, request, format=None):
if 'email' not in request.data: 41 40 if 'email' not in request.data:
raise ValidationError('Email is required') 42 41 raise ValidationError('Email is required')
if 'password' not in request.data: 43 42 if 'password' not in request.data:
raise ValidationError('Password is required') 44 43 raise ValidationError('Password is required')
45 44
email = request.data['email'] 46 45 email = request.data['email']
user = User.objects.create_user(email, email=email) 47 46 user = User.objects.create_user(email, email=email, password=request.data['password'])
user.confirm_email(user.confirmation_key) 48 47
body = ''' 49 48 body = '''
Visit the following link to confirm your email address: 50 49 Visit the following link to confirm your email address:
http://flashy.cards/app/verify_email/%s 51 50 http://flashy.cards/app/verify_email/%s
52 51
If you did not register for Flashy, no action is required. 53 52 If you did not register for Flashy, no action is required.
''' 54 53 '''
55 54
send_mail("Please verify your Flashy account", 56 55 send_mail("Please verify your Flashy account",
body % user.confirmation_key, 57 56 body % user.confirmation_key,
"noreply@flashy.cards", 58 57 "noreply@flashy.cards",
[user.email]) 59 58 [user.email])
user = authenticate(username=email, password=request.data['password']) 60
print user 61
login(request, user) 62
63 59
60 user = authenticate(email=email, password=request.data['password'])
61 login(request, user)
return Response(UserSerializer(User).data) 64 62 return Response(UserSerializer(User).data)
65 63
def delete(self, request, format=None): 66 64 def delete(self, request, format=None):
request.user.delete() 67 65 request.user.delete()
return Response(status=status.HTTP_204_NO_CONTENT) 68 66 return Response(status=status.HTTP_204_NO_CONTENT)
69 67
68
class UserLogin(APIView): 70 69 class UserLogin(APIView):
""" 71 70 """
Authenticates user and returns user data if valid. Handles invalid 72 71 Authenticates user and returns user data if valid. Handles invalid
users. 73 72 users.
""" 74 73 """
def post(self, request, format=None): 75 74
75 def post(self, request, format=None):
""" 76 76 """
Returns user data if valid. 77 77 Returns user data if valid.
""" 78 78 """
if 'email' not in request.data: 79 79 if 'email' not in request.data:
raise ValidationError('Email is required') 80 80 raise ValidationError('Email is required')
if 'password' not in request.data: 81 81 if 'password' not in request.data:
raise ValidationError('Password is required') 82 82 raise ValidationError('Password is required')
83 83
email = request.data['email'] 84 84 email = request.data['email']
password = request.data['password'] 85 85 password = request.data['password']
user = authenticate(username=email, password=password) 86 86 user = authenticate(username=email, password=password)
87 87
if user is not None: 88 88 if user is None:
if user.is_active: 89
login(request, user) 90
return Response(UserSerializer(User).data) 91
else: 92
raise ValidationError('Account is disabled') 93
else: 94
raise ValidationError('Invalid email or password') 95 89 raise ValidationError('Invalid email or password')
90 if not user.is_active:
91 raise ValidationError('Account is disabled')
92 login(request, user)
93 return Response(UserSerializer(User).data)
96 94
95
class PasswordReset(APIView): 97 96 class PasswordReset(APIView):
""" 98 97 """
Allows user to reset their password. 99 98 Allows user to reset their password.
""" 100 99 """
100
def post(self, request, format=None): 101 101 def post(self, request, format=None):
""" 102 102 """
Send a password reset token/link to the provided email. 103 103 Send a password reset token/link to the provided email.
""" 104 104 """
if 'email' not in request.data: 105 105 if 'email' not in request.data:
raise ValidationError('Email is required') 106 106 raise ValidationError('Email is required')
107 107
email = request.data['email'] 108 108 email = request.data['email']
109 109
# Find the user since they are not logged in. 110 110 # Find the user since they are not logged in.
try: 111 111 try:
user = User.objects.get(email=email) 112 112 user = User.objects.get(email=email)
except User.DoesNotExist: 113 113 except User.DoesNotExist:
raise NotFound('Email does not exist') 114 114 raise NotFound('Email does not exist')
115 115
token = default_token_generator.make_token(user) 116 116 token = default_token_generator.make_token(user)
117 117
body = ''' 118 118 body = '''
Visit the following link to reset your password: 119 119 Visit the following link to reset your password:
http://flashy.cards/app/reset_password/%d/%s 120 120 http://flashy.cards/app/reset_password/%d/%s
121 121
If you did not request a password reset, no action is required. 122 122 If you did not request a password reset, no action is required.
''' 123 123 '''
124 124
send_mail("Please verify your Flashy account", 125 125 send_mail("Flashy password reset",
body % (user.pk, token), 126 126 body % (user.pk, token),
"noreply@flashy.cards", 127 127 "noreply@flashy.cards",
flashy/settings.py View file @ d8dbb1c
""" 1 1 """
Django settings for flashy project. 2 2 Django settings for flashy project.
3 3
Generated by 'django-admin startproject' using Django 1.8. 4 4 Generated by 'django-admin startproject' using Django 1.8.
5 5
For more information on this file, see 6 6 For more information on this file, see
https://docs.djangoproject.com/en/1.8/topics/settings/ 7 7 https://docs.djangoproject.com/en/1.8/topics/settings/
8 8
For the full list of settings and their values, see 9 9 For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.8/ref/settings/ 10 10 https://docs.djangoproject.com/en/1.8/ref/settings/
""" 11 11 """
12 12
# Build paths inside the project like this: os.path.join(BASE_DIR, ...) 13 13 # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os 14 14 import os
15 15
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 16 16 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
17 17
# SECURITY WARNING: don't run with debug turned on in production! 18 18 # SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True 19 19 DEBUG = True
20 20
ALLOWED_HOSTS = [] 21 21 ALLOWED_HOSTS = []
22 22
AUTH_USER_MODEL = 'flashcards.User' 23 23 AUTH_USER_MODEL = 'flashcards.User'
# Application definition 24 24 # Application definition
25 25
INSTALLED_APPS = ( 26 26 INSTALLED_APPS = (
'simple_email_confirmation', 27 27 'simple_email_confirmation',
'flashcards', 28 28 'flashcards',
'django.contrib.admin', 29 29 'django.contrib.admin',
'django.contrib.admindocs', 30 30 'django.contrib.admindocs',
'django.contrib.auth', 31 31 'django.contrib.auth',
'django.contrib.contenttypes', 32 32 'django.contrib.contenttypes',
'django.contrib.sessions', 33 33 'django.contrib.sessions',
'django.contrib.messages', 34 34 'django.contrib.messages',
'django.contrib.staticfiles', 35 35 'django.contrib.staticfiles',
'django_ses', 36 36 'django_ses',
'rest_framework', 37 37 'rest_framework',
38 38
39 39
) 40 40 )
41 41
REST_FRAMEWORK = { 42 42 REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.CursorPagination', 43 43 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.CursorPagination',
'PAGE_SIZE': 20 44 44 'PAGE_SIZE': 20
} 45 45 }
46 46
MIDDLEWARE_CLASSES = ( 47 47 MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware', 48 48 'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware', 49 49 'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware', 50 50 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware', 51 51 'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 52 52 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware', 53 53 'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware', 54 54 'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware', 55 55 'django.middleware.security.SecurityMiddleware',
) 56 56 )
57 57
ROOT_URLCONF = 'flashy.urls' 58 58 ROOT_URLCONF = 'flashy.urls'
# Authentication backends 59 59 # Authentication backends
AUTHENTICATION_BACKENDS = ( 60 60 AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend', 61 61 'django.contrib.auth.backends.ModelBackend',
) 62 62 )
63
TEMPLATES = [ 63 64 TEMPLATES = [
{ 64 65 {
'BACKEND': 'django.template.backends.django.DjangoTemplates', 65 66 'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': ['templates/'], 66 67 'DIRS': ['templates/'],
'APP_DIRS': True, 67 68 'APP_DIRS': True,
'OPTIONS': { 68 69 'OPTIONS': {
'context_processors': [ 69 70 'context_processors': [
'django.template.context_processors.debug', 70 71 'django.template.context_processors.debug',
'django.template.context_processors.request', 71 72 'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth', 72 73 'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages', 73 74 'django.contrib.messages.context_processors.messages',
], 74 75 ],
}, 75 76 },
}, 76 77 },
] 77 78 ]
78 79
WSGI_APPLICATION = 'flashy.wsgi.application' 79 80 WSGI_APPLICATION = 'flashy.wsgi.application'
80 81
81 82
# Database 82 83 # Database
# https://docs.djangoproject.com/en/1.8/ref/settings/#databases 83 84 # https://docs.djangoproject.com/en/1.8/ref/settings/#databases
84 85
DATABASES = { 85 86 DATABASES = {
'default': { 86 87 'default': {
'ENGINE': 'django.db.backends.sqlite3', 87 88 'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 88 89 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
} 89 90 }
} 90 91 }
91 92