Commit b5c6bf51 authored by Wietse Kuipers's avatar Wietse Kuipers

Offer same API as old site

Wolktm can't be deprecated because Django doesn't do longpolling
parent f4c3bbfd
from django.apps import AppConfig
class ThaliappConfig(AppConfig):
name = 'thaliapp'
# -*- coding: utf-8 -*-
# Generated by Django 1.10.2 on 2016-11-03 14:03
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Tokens',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('token', models.CharField(max_length=64)),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.10.2 on 2016-11-03 14:18
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('thaliapp', '0001_initial'),
]
operations = [
migrations.RenameModel(
old_name='Tokens',
new_name='Token',
),
]
from django.db import models
from django.conf import settings
from django.utils.crypto import get_random_string
from django.contrib.auth.models import User
from hashlib import sha256
class Token(models.Model):
"""This class contains an authentication token for an user
An user may have multiple tokens"""
user = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)
token = models.CharField(max_length=64)
@classmethod
def create_token(cls, user):
# Post quantum approved
token = get_random_string(length=64)
hashed_token = sha256(
''.join([user.username, token]).encode()).hexdigest()
t = cls(user=user, token=hashed_token)
t.save()
return token
@classmethod
def authenticate(cls, username, token):
hashed_token = sha256(''.join([username, token]).encode()).hexdigest()
try:
user = User.objects.get(username=username,
token__token=hashed_token)
except User.DoesNotExist:
return None
return user
from django.conf.urls import url
from . import views
app_name = "thaliapp"
urlpatterns = [
url(r'^login', views.login,
name='thaliapp-login'),
url(r'^app', views.app,
name='thaliapp-app'),
]
from django.conf import settings
from django.http import (JsonResponse, HttpResponseBadRequest,
HttpResponseForbidden)
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST
from django.contrib.auth import authenticate
from django.contrib.staticfiles.finders import find as find_static_file
from django.core.cache import cache
from thaliapp.models import Token
from hashlib import sha256
import base64
import datetime
def get_photo(user):
if user.member.photo:
photo = ''.join(['data:image/jpeg;base64,',
base64.b64encode(
user.member.photo.file.read()).decode()
])
else:
filename = find_static_file('members/images/default-avatar.jpg')
with open(filename, 'rb') as f:
photo = ''.join(['data:image/jpeg;base64,',
base64.b64encode(f.read()).decode()
])
return photo
@csrf_exempt
@require_POST
def login(request):
if (sha256(request.POST.get('apikey', '').encode('ascii')).hexdigest() !=
settings.THALIAPP_API_KEY):
return HttpResponseForbidden()
user = request.POST.get('username')
password = request.POST.get('password')
if user is None or password is None:
return HttpResponseBadRequest(
'{"status":"error","msg":"Missing username or password"}',
content_type='application/json')
user = authenticate(username=user, password=password)
if user is not None:
token = Token.create_token(user)
photo = get_photo(user)
return JsonResponse({'status': 'ok',
'username': user.username,
'token': token,
'profile_image': photo,
})
return JsonResponse({'status': 'error',
'msg': 'Authentication Failed'},
status_code=403)
@csrf_exempt
@require_POST
def app(request):
username = request.POST.get('username')
token = request.POST.get('token')
if (sha256(request.POST.get('apikey', '').encode('ascii')).hexdigest() !=
settings.WOLKTM_API_KEY):
return HttpResponseForbidden()
if username is None or token is None:
return HttpResponseBadRequest()
user = Token.authenticate(username, token)
if user is None:
return JsonResponse({'status': 'error',
'msg': 'Authentication Failed'},
status_code=403)
today = datetime.date.today()
eightteen_years_ago = today.replace(year=today.year - 18)
over18 = str(user.member.birthday <= eightteen_years_ago)
membership = user.member.current_membership
if membership:
membership_type = membership.type
is_member = 'True'
else:
membership_type = 'Expired'
is_member = 'False'
return JsonResponse({'status': 'ok',
'real_name': user.member.get_full_name(),
'display_name': user.member.display_name(),
'birthday': str(user.member.birthday),
'over18': over18,
'membership_type': membership_type,
'is_thalia_member': is_member,
'profile_image': get_photo(user),
})
@csrf_exempt
@require_POST
def scan(request):
"""Not used until wolktm is deprecated"""
username = request.POST.get('username')
token = request.POST.get('token')
qrtoken = request.POST.get('qrToken')
if username is None or token is None or qrtoken is None:
return HttpResponseBadRequest()
user = Token.authenticate(username, token)
if user is None:
return JsonResponse({'status': 'error',
'msg': 'Authentication Failed'},
status_code=403)
cache.set(''.join([qrtoken]), user, 300)
return JsonResponse({'status': 'ok'})
......@@ -51,6 +51,7 @@ INSTALLED_APPS = [
'django_template_check', # This is only necessary in development
'rest_framework',
'compressor',
'corsheaders',
# Our apps
'thaliawebsite', # include for admin settings
'members',
......@@ -66,11 +67,13 @@ INSTALLED_APPS = [
'pizzas',
'newsletters',
'education',
'thaliapp',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
......@@ -207,3 +210,13 @@ PHOTO_UPLOAD_SIZE = 1920, 1080
# API key for wiki
WIKI_API_KEY = 'debug'
# API key for thaliapp related stuff
# SHA256 hash so it does not need replacement in production
THALIAPP_API_KEY = ('5b2bff55b74f74678dd578f8f669e959'
'09f356aa05548ecdf418e678af334844')
WOLKTM_API_KEY = 'vulditin'
# CORS config
CORS_ORIGIN_ALLOW_ALL = True
CORS_URLS_REGEX = r'^/api/.*$'
CORS_ALLOW_METHODS = ('GET', 'POST')
......@@ -83,6 +83,7 @@ urlpatterns = [
url(r'^', include('events.api.urls')),
url(r'^', include('members.api.urls')),
url(r'^', include('partners.api.urls')),
url(r'^', include('thaliapp.urls')),
url(r'wikilogin', views.wiki_login),
])),
url(r'^education/', include('education.urls', namespace='education')),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment