Add Discourse login

master
Alice 8 years ago
parent fc6108f214
commit 957737be1a

@ -155,6 +155,10 @@ SECURE_SSL_REDIRECT = False
SECURE_HSTS_SECONDS = 3600
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
# Enable Discourse SSO
DISCOURSE_SSO = False
DISCOURSE_SECRET = '...'
DISCOURSE_URL = 'https://forum.ccrypto.org/'
# OpenVPN CA Certificate
with open(BASE_DIR + '/ccvpn/ca.crt') as ca_file:

@ -54,3 +54,11 @@ class SignupForm(forms.Form, FormPureRender):
raise forms.ValidationError(_("Passwords are not the same"))
return self.data['password']
class ReqEmailForm(forms.Form, FormPureRender):
email = forms.EmailField(
label=_("E-Mail"),
widget=forms.EmailInput(attrs={'placeholder': _("E-Mail")}),
)

@ -5,6 +5,7 @@ from . import views
urlpatterns = [
url(r'^login$', auth_views.login, name='login'),
url(r'^discourse_login', views.discourse_login, name='discourse_login'),
url(r'^logout$', views.logout, name='logout'),
url(r'^signup$', views.signup, name='signup'),

@ -1,11 +1,17 @@
import requests
import io
import zipfile
from urllib.parse import urlencode
import hmac
import base64
from hashlib import sha256
from urllib.parse import urlencode, parse_qsl
from datetime import timedelta, datetime
from django.http import HttpResponse, HttpResponseNotFound, HttpResponseForbidden
from django.http import JsonResponse
from django.http import (
HttpResponse, JsonResponse,
HttpResponseRedirect,
HttpResponseNotFound, HttpResponseForbidden
)
from django.shortcuts import render, redirect
from django.contrib.auth import authenticate
from django.contrib.auth.decorators import login_required, user_passes_test
@ -21,7 +27,7 @@ from django.contrib.auth.models import User
from django_countries import countries
from payments.models import ACTIVE_BACKENDS
from .forms import SignupForm
from .forms import SignupForm, ReqEmailForm
from .models import GiftCode, VPNUser
from .core import core_api
from . import core
@ -85,6 +91,58 @@ def signup(request):
return redirect('account:index')
@login_required
def discourse_login(request):
sso_secret = project_settings.DISCOURSE_SECRET
discourse_url = project_settings.DISCOURSE_URL
if project_settings.DISCOURSE_SSO is not True:
return HttpResponseNotFound()
payload = request.GET.get('sso', '')
signature = request.GET.get('sig', '')
expected_signature = hmac.new(sso_secret.encode('utf-8'),
payload.encode('utf-8'),
sha256).hexdigest()
if signature != expected_signature:
return HttpResponseNotFound()
if request.method == 'POST' and 'email' in request.POST:
form = ReqEmailForm(request.POST)
if not form.is_valid():
return render(request, 'ccvpn/require_email.html', dict(form=form))
request.user.email = form.cleaned_data['email']
request.user.save()
if not request.user.email:
form = ReqEmailForm()
return render(request, 'ccvpn/require_email.html', dict(form=form))
try:
payload = base64.b64decode(payload).decode('utf-8')
payload_data = dict(parse_qsl(payload))
except (TypeError, ValueError):
return HttpResponseNotFound()
payload_data.update({
'external_id': request.user.id,
'username': request.user.username,
'email': request.user.email,
'require_activation': 'true',
})
payload = urlencode(payload_data)
payload = base64.b64encode(payload.encode('utf-8'))
signature = hmac.new(sso_secret.encode('utf-8'), payload, sha256).hexdigest()
redirect_query = urlencode(dict(sso=payload, sig=signature))
redirect_path = '/session/sso_login?' + redirect_query
return HttpResponseRedirect(discourse_url + redirect_path)
@login_required
def index(request):
ref_url = project_settings.ROOT_URL + '?ref=' + str(request.user.id)

@ -2,7 +2,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-07-07 17:43+0000\n"
"POT-Creation-Date: 2016-09-01 03:18+0000\n"
"PO-Revision-Date: 2016-04-07 01:32+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
@ -27,39 +27,39 @@ msgstr ""
msgid "hash"
msgstr ""
#: lambdainst/admin.py:17
#: lambdainst/admin.py:22
msgid "Code must be [a-zA-Z0-9]"
msgstr ""
#: lambdainst/admin.py:19
#: lambdainst/admin.py:24
msgid "Code must be between 1 and 32 characters"
msgstr ""
#: lambdainst/admin.py:39
#: lambdainst/admin.py:43
msgid "(rewarded)"
msgstr ""
#: lambdainst/admin.py:41
#: lambdainst/admin.py:45
msgid "(not rewarded)"
msgstr ""
#: lambdainst/admin.py:43
#: lambdainst/admin.py:48
msgid "Referrer"
msgstr ""
#: lambdainst/admin.py:48 lambdainst/admin.py:92
#: lambdainst/admin.py:53 lambdainst/admin.py:96
msgid "Is paid?"
msgstr "Est payé?"
#: lambdainst/admin.py:83
#: lambdainst/admin.py:87
msgid "Important dates"
msgstr "Dates importantes"
#: lambdainst/admin.py:84
#: lambdainst/admin.py:88
msgid "Permissions"
msgstr "Permissions"
#: lambdainst/admin.py:116 tickets/admin.py:52
#: lambdainst/admin.py:133 tickets/admin.py:52
msgid "Comment"
msgstr "Notes"
@ -87,8 +87,9 @@ msgstr "Répétez"
msgid "Same Anything"
msgstr "La même chose"
#: lambdainst/forms.py:47 lambdainst/forms.py:48 templates/ccvpn/signup.html:30
#: templates/lambdainst/settings.html.py:22
#: lambdainst/forms.py:47 lambdainst/forms.py:48 lambdainst/forms.py:60
#: lambdainst/forms.py:61 templates/ccvpn/require_email.html.py:13
#: templates/ccvpn/signup.html:30 templates/lambdainst/settings.html.py:22
#: templates/registration/password_reset_form.html:11
msgid "E-Mail"
msgstr "E-Mail"
@ -97,27 +98,27 @@ msgstr "E-Mail"
msgid "Passwords are not the same"
msgstr "Les mots de passe de correspondent pas"
#: lambdainst/models.py:24
#: lambdainst/models.py:25
msgid "VPN User"
msgstr "VPN User"
#: lambdainst/models.py:25
#: lambdainst/models.py:26
msgid "VPN Users"
msgstr "VPN Users"
#: lambdainst/models.py:92
#: lambdainst/models.py:97
msgid "Gift Code"
msgstr "Code cadeau"
#: lambdainst/models.py:93
#: lambdainst/models.py:98
msgid "Gift Codes"
msgstr "Codes cadeau"
#: lambdainst/models.py:138
#: lambdainst/models.py:143
msgid "Gift Code User"
msgstr "Utilisateur de codes"
#: lambdainst/models.py:139
#: lambdainst/models.py:144
msgid "Gift Code Users"
msgstr "Utilisateurs de codes"
@ -200,50 +201,50 @@ msgstr ""
msgid "%s Pbps"
msgstr ""
#: lambdainst/views.py:91
#: lambdainst/views.py:152
msgid "Awesome VPN! 3€ per month, with a free 7 days trial!"
msgstr ""
#: lambdainst/views.py:98 templates/account_layout.html.py:9
#: lambdainst/views.py:159 templates/account_layout.html.py:9
#: templates/account_layout.html:11 templates/lambdainst/account.html.py:10
msgid "Account"
msgstr "Compte"
#: lambdainst/views.py:137 lambdainst/views.py:180
#: lambdainst/views.py:198 lambdainst/views.py:221 lambdainst/views.py:246
msgid "OK!"
msgstr "OK!"
#: lambdainst/views.py:139
#: lambdainst/views.py:200
msgid "Invalid captcha"
msgstr "Captcha invalide"
#: lambdainst/views.py:153
#: lambdainst/views.py:214
msgid "Passwords do not match"
msgstr "Les mots de passe ne correspondent pas"
#: lambdainst/views.py:165 templates/account_layout.html.py:13
#: lambdainst/views.py:231 templates/account_layout.html.py:13
#: templates/lambdainst/settings.html:6
msgid "Settings"
msgstr "Options"
#: lambdainst/views.py:176
#: lambdainst/views.py:242
msgid "Gift code not found or already used."
msgstr "Code inconnu ou déjà utilisé."
#: lambdainst/views.py:178
#: lambdainst/views.py:244
msgid "Gift code only available to free accounts."
msgstr "Code uniquement disponible pour les nouveaux comptes."
#: lambdainst/views.py:200 templates/account_layout.html.py:15
#: lambdainst/views.py:266 templates/account_layout.html.py:15
#: templates/lambdainst/logs.html:6
msgid "Logs"
msgstr "Logs"
#: lambdainst/views.py:207 templates/lambdainst/config.html.py:7
#: lambdainst/views.py:273 templates/lambdainst/config.html.py:7
msgid "Config"
msgstr "Config"
#: lambdainst/views.py:296 payments/backends.py:120 payments/backends.py:122
#: lambdainst/views.py:377 payments/backends.py:120 payments/backends.py:122
#: templates/admin/index.html:53 templates/admin/index.html.py:56
#: templates/lambdainst/admin_ref.html:16
#: templates/lambdainst/admin_status.html:16 templates/payments/list.html:13
@ -555,6 +556,18 @@ msgstr "Installation"
msgid "GNU/Linux"
msgstr "GNU/Linux"
#: templates/ccvpn/require_email.html:8
msgid "E-mail Confirmation"
msgstr "Confirmation de l'adresse e-mail"
#: templates/ccvpn/require_email.html:16
msgid "Required to use the forums. A confirmation will be sent."
msgstr "Nécessaire pour les forums. Une confirmation sera envoyée."
#: templates/ccvpn/require_email.html:19
msgid "Continue"
msgstr "Continuer"
#: templates/ccvpn/signup.html:8 templates/ccvpn/signup.html.py:37
#: templates/layout.html:34
msgid "Sign up"

@ -0,0 +1,25 @@
{% extends 'layout.html' %}
{% load i18n %}
{% load staticfiles %}
{% block content %}
<div class="content formpage signuppage pure-g">
<div class="pure-u-1 pure-u-sm-1-2 pure-u-xl-1-3">
<h1>{% trans 'E-mail Confirmation' %}</h1>
<form class="pure-form pure-form-stacked" action="" method="post">
{% csrf_token %}
{{ form.email.errors }}
<label for="email">{% trans 'E-Mail' %}</label>
<input type="email" id="email" name="email" value="{{email}}" />
<p class="inputhelp">
<b>{% trans 'Required to use the forums. A confirmation will be sent.' %}</b>
</p>
<input type="submit" class="pure-button pure-button-primary" value="{% trans 'Continue' %}" />
</form>
</div>
</div>
{% endblock %}
Loading…
Cancel
Save