Skip to content

Commit

Permalink
Revert "remove discourse"
Browse files Browse the repository at this point in the history
This reverts commit 0032eaf.
  • Loading branch information
madprime committed Jan 22, 2020
1 parent d29ec0a commit 4f37fb7
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 0 deletions.
Empty file added discourse/__init__.py
Empty file.
5 changes: 5 additions & 0 deletions discourse/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from django.conf.urls import url

from .views import single_sign_on

urlpatterns = [url(r"^sso/$", single_sign_on)]
79 changes: 79 additions & 0 deletions discourse/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import base64
import hmac
import hashlib
import urllib

from urlparse import parse_qs

from django.contrib.auth.decorators import login_required
from django.http import HttpResponseBadRequest, HttpResponseRedirect
from django.conf import settings


@login_required
def single_sign_on(request):
"""
Support Discourse single sign-on.
"""
payload = request.GET.get("sso")
signature = request.GET.get("sig")

if None in [payload, signature]:
return HttpResponseBadRequest(
"No SSO payload or signature. Please "
"contact support if this problem "
"persists."
)

# Validate the payload
try:
payload = urllib.unquote(payload)
decoded = base64.decodestring(payload)

assert "nonce" in decoded
assert len(payload) > 0
except AssertionError:
return HttpResponseBadRequest(
"Invalid payload. Please contact " "support if this problem persists."
)

key = str(settings.DISCOURSE_SSO_SECRET)
h = hmac.new(key, payload, digestmod=hashlib.sha256)
this_signature = h.hexdigest()

if this_signature != signature:
return HttpResponseBadRequest(
"Invalid payload. Please contact " "support if this problem persists."
)

# Build the return payload
qs = parse_qs(decoded)

if not request.user.member.primary_email.verified:
return HttpResponseBadRequest(
"Please verify your Open Humans email " "address."
)

params = {
"nonce": qs["nonce"][0],
"name": request.user.member.name,
"email": request.user.member.primary_email.email,
"external_id": request.user.id,
"username": request.user.username,
}

try:
params["avatar_url"] = request.user.member.profile_image.url
params["avatar_force_update"] = "true"
except ValueError:
pass

return_payload = base64.encodestring(urllib.urlencode(params))
h = hmac.new(key, return_payload, digestmod=hashlib.sha256)

query_string = urllib.urlencode({"sso": return_payload, "sig": h.hexdigest()})

# Redirect back to Discourse
url = "%s/session/sso_login" % settings.DISCOURSE_BASE_URL

return HttpResponseRedirect("%s?%s" % (url, query_string))
4 changes: 4 additions & 0 deletions env.example
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,9 @@ PORT=
RECAPTCHA_PUBLIC_KEY=""
RECAPTCHA_PRIVATE_KEY=""

# The SSO secret from
# http://forum.openhumans.org/admin/site_settings/category/login
DISCOURSE_SSO_SECRET=""

# A key used to communicate with data-processing; must be set in both sites
PRE_SHARED_KEY=""
5 changes: 5 additions & 0 deletions open_humans/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ def to_bool(env, default="false"):
"data_import",
"private_sharing",
"public_data",
"discourse",
# gulp integration
"django_gulp",
# Django built-ins
Expand Down Expand Up @@ -490,6 +491,10 @@ def to_bool(env, default="false"):

ZAPIER_WEBHOOK_URL = os.getenv("ZAPIER_WEBHOOK_URL")

DISCOURSE_BASE_URL = os.getenv("DISCOURSE_BASE_URL", "https://forums.openhumans.org")

DISCOURSE_SSO_SECRET = os.getenv("DISCOURSE_SSO_SECRET")

MAX_UNAPPROVED_MEMBERS = int(os.getenv("MAX_UNAPPROVED_MEMBERS", "20"))

# Highlighted projects
Expand Down
3 changes: 3 additions & 0 deletions open_humans/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from django.views.generic import RedirectView, TemplateView

import data_import.urls
import discourse.urls
import private_sharing.api_urls
import private_sharing.urls
import public_data.urls
Expand All @@ -21,6 +22,8 @@
"admin/",
include((admin.site.urls[0], admin.site.urls[1]), namespace=admin.site.urls[2]),
),
# Include Discourse SSO
path(r"discourse/", include(discourse.urls)),
# Include the various APIs here
path("api/", include(api_urls)),
path("api/direct-sharing/", include(private_sharing.api_urls)),
Expand Down

0 comments on commit 4f37fb7

Please sign in to comment.