Merge branch 'develop' into 'master'

Develop

See merge request !52
This commit is contained in:
Jan Tuomi
2017-09-26 15:39:43 +03:00
12 changed files with 130 additions and 7 deletions
-1
View File
@@ -11,7 +11,6 @@ from django.conf import settings
def coffee_view(request):
logging.info('User navigated to coffee page!')
return render(request, 'coffee.html')
View File
@@ -0,0 +1,30 @@
from django.core.management.base import BaseCommand, CommandError
from django.contrib.auth.models import User, Permission
from rest_framework.authtoken.models import Token
class Command(BaseCommand):
user_name = "sahkopiikki"
password = User.objects.make_random_password()
def handle(self, *args, **options):
if User.objects.filter(username=self.user_name).exists():
self.stdout.write("Sahkopiikki user already exists. Skipping.")
user = User.objects.get(username=self.user_name)
token = Token.objects.get(user=user)
self.stdout.write("Token: {}".format(token))
return
u = User(username=self.user_name)
u.set_password(self.password)
u.save()
permission = Permission.objects.get(codename='check_by_email')
u.user_permissions.add(permission)
token = Token.objects.create(user=u)
self.stdout.write("Created sahkopiikki user '{}' with password '{}' and token '{}'.".format(
self.user_name, self.password, token
))
@@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2017-09-26 10:16
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('members', '0016_auto_20170925_1924'),
]
operations = [
migrations.AlterModelOptions(
name='member',
options={'permissions': (('check_by_email', 'Can check if user exists by email'),)},
),
]
+5
View File
@@ -85,6 +85,11 @@ class Member(BaseMember):
created = models.DateTimeField(_('Created'), default=timezone.now)
class Meta:
permissions = (
('check_by_email', 'Can check if user exists by email'),
)
def last_paid(self):
"""Return member's last payment."""
try:
+8
View File
@@ -0,0 +1,8 @@
from rest_framework.permissions import BasePermission
import logging
class CheckByEmailPermission(BasePermission):
def has_permission(self, request, view):
return request.user.has_perm('members.check_by_email')
+38 -1
View File
@@ -2,8 +2,11 @@
from django.test import TestCase, Client
from django.contrib.auth.models import User
from members.management.commands.createsahkopiikkiuser import Command as SahkopiikkiCommand
from members.models import Member
from rest_framework.authtoken.models import Token
import logging
class MemberRegisterTestCase(TestCase):
@@ -18,6 +21,9 @@ class MemberRegisterTestCase(TestCase):
self.c = Client()
self.c.login(username=username, password=password)
sc = SahkopiikkiCommand()
sc.handle()
def test_member_created(self):
"""Test member creation."""
exists = Member.objects.filter(first_name="Tidus").exists()
@@ -50,3 +56,34 @@ class MemberRegisterTestCase(TestCase):
response = self.c.get('/members/member-autocomplete?q={}'.format(search_terms), follow=True)
results = response.json()['results']
self.assertEqual(len(results), 0)
def test_sahkopiikki_check_by_email_not_found(self):
"""Test if sähköpiikki auth and search work"""
email = 'teppo@tulppu.fi'
wrong_email = 'asd@asd.fi'
Member.objects.create(email=email, first_name='Teppo', last_name='Tulppu')
token = Token.objects.get(user__username='sahkopiikki').key
self.c.defaults['HTTP_AUTHORIZATION'] = 'Token ' + token
response = self.c.get('/members/check?email={}'.format(wrong_email), follow=True)
self.assertEqual(response.json()['exists'], False)
def test_sahkopiikki_check_by_email_found(self):
"""Test if sähköpiikki auth and search work"""
email = 'teppo@tulppu.fi'
Member.objects.create(email=email, first_name='Teppo', last_name='Tulppu')
token = Token.objects.get(user__username='sahkopiikki').key
self.c.defaults['HTTP_AUTHORIZATION'] = 'Token ' + token
response = self.c.get('/members/check?email={}'.format(email), follow=True)
self.assertEqual(response.json()['exists'], True)
def test_sahkopiikki_check_by_email_forbidden(self):
"""Test if sähköpiikki auth and search work"""
email = 'teppo@tulppu.fi'
Member.objects.create(email=email, first_name='Teppo', last_name='Tulppu')
token = Token.objects.get(user__username='sahkopiikki').key
self.c.defaults['HTTP_AUTHORIZATION'] = 'Token ' + token + 'DERP'
response = self.c.get('/members/check?email={}'.format(email), follow=True)
self.assertEqual(response.status_code, 401)
+3 -1
View File
@@ -25,7 +25,8 @@ from members.views import add_many_confirm
from members.views import MemberAutoComplete
# rest api
from members.views import MemberDetail
from members.views import MemberDetail, CheckByEmail
from rest_framework.authtoken import views
# application
from members.views import application_form
@@ -125,4 +126,5 @@ urlpatterns = [
name='member-autocomplete',
),
url(r'^check', CheckByEmail.as_view())
]
+19 -1
View File
@@ -3,7 +3,7 @@ from django.contrib.auth.decorators import permission_required
from django.utils.decorators import method_decorator
from django.views.decorators.http import require_http_methods
from django.views.decorators.csrf import ensure_csrf_cookie
from django.http import HttpResponse, HttpResponseRedirect
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse, HttpResponseForbidden
from django.core.mail import send_mail
from django.conf import settings
from django.utils.translation import ugettext as _
@@ -13,6 +13,11 @@ from dal import autocomplete
import logging
import html
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import authentication, permissions
from members.permissions import CheckByEmailPermission
from members.models import Member, Request, Payment
from members.forms import MemberForm, CSVValidationError
from members.tables import MemberTable
@@ -199,3 +204,16 @@ class MemberAutoComplete(autocomplete.Select2QuerySetView):
qs = Member.find_members_by_name(self.q)
return qs
class CheckByEmail(APIView):
"""Check by email"""
authentication_classes = (authentication.TokenAuthentication,)
permission_classes = (CheckByEmailPermission,)
def get(self, request, format=None):
email = request.query_params.get('email')
exists = bool(email and Member.objects.filter(email=email).exists())
resp = {'exists': exists}
return JsonResponse(resp)
+4 -3
View File
@@ -13,9 +13,10 @@ import csv
# REST framework
from members.serializers import MemberSerializer
from members.throttles import BurstRateThrottle, SustainedRateThrottle
from rest_framework import generics
from rest_framework import permissions
from rest_framework.throttling import UserRateThrottle, AnonRateThrottle
from members.models import Member, Request, Payment
from members.forms import MemberForm, PaymentForm, ApplicationForm, CSVValidationError
@@ -28,8 +29,8 @@ class MemberDetail(generics.RetrieveAPIView):
queryset = Member.objects.all()
serializer_class = MemberSerializer
permission_classes = (permissions.IsAdminUser, )
throttle_classes = (UserRateThrottle, AnonRateThrottle, )
permission_classes = (permissions.DjangoModelPermissions, )
throttle_classes = (BurstRateThrottle, SustainedRateThrottle, )
def error_view(request, message):
+4
View File
@@ -72,6 +72,7 @@ INSTALLED_APPS = [
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework.authtoken',
'corsheaders',
'webapp',
'members',
@@ -192,6 +193,9 @@ REST_FRAMEWORK = {
'rest_framework.permissions.DjangoModelPermissions',
'rest_framework.permissions.IsAdminUser',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
),
'DEFAULT_THROTTLE_CLASSES': (
'members.throttles.BurstRateThrottle',
'members.throttles.SustainedRateThrottle'