sso: Fixes for regressions after adding captcha and axes

- Change sso refresh url to refresh-pubtkt since refresh was conflicting with
  captcha's image refresh url.
- Fix datetime.timedelta calculation for refresh interval. Now validity of
  ticket is 30 seconds as it was intended to be. It was wrongly set to 30 days
  earlier.

Signed-off-by: Joseph Nuthalapati <njoseph@thoughtworks.com>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
Joseph Nuthalapati 2017-11-07 19:09:44 +05:30 committed by James Valleroy
parent 1fe9bb317a
commit 111f8f9145
No known key found for this signature in database
GPG Key ID: 77C0C75E7B650808
5 changed files with 41 additions and 25 deletions

View File

@ -89,18 +89,21 @@ def subcommand_create_key_pair(_):
os.chmod(fil, 0o440)
def create_ticket(pkey, uid, validuntil, ip=None, tokens=None,
udata=None, graceperiod=None, extra_fields=None):
def create_ticket(pkey,
uid,
validuntil,
ip=None,
tokens=None,
udata=None,
graceperiod=None,
extra_fields=None):
"""Create and return a signed mod_auth_pubtkt ticket."""
fields = [
'uid={}'.format(uid),
'validuntil={}'.format(validuntil, type='d'),
ip and 'cip={}'.format(ip),
tokens and 'tokens={}'.format(tokens),
graceperiod and 'graceperiod={}'.format(graceperiod, type='d'),
udata and 'udata={}'.format(udata),
extra_fields and ';'.join(
['{}={}'.format(k, v) for k, v in extra_fields])
'uid={}'.format(uid), 'validuntil={}'.format(validuntil, type='d'), ip
and 'cip={}'.format(ip), tokens and 'tokens={}'.format(tokens),
graceperiod and 'graceperiod={}'.format(graceperiod, type='d'), udata
and 'udata={}'.format(udata), extra_fields
and ';'.join(['{}={}'.format(k, v) for k, v in extra_fields])
]
data = ';'.join(filter(None, fields))
signature = 'sig={}'.format(sign(pkey, data))
@ -120,15 +123,22 @@ def subcommand_generate_ticket(arguments):
tokens = arguments.tokens
with open(private_key_file, 'r') as fil:
pkey = crypto.load_privatekey(crypto.FILETYPE_PEM, fil.read().encode())
valid_until = minutes_from_now(30)
grace_period = minutes_from_now(25)
valid_until = seconds_from_now(30)
grace_period = seconds_from_now(25)
print(create_ticket(
pkey, uid, valid_until, tokens=tokens, graceperiod=grace_period))
def minutes_from_now(minutes):
"""Return a timestamp at the given number of minutes from now."""
return (datetime.datetime.now() + datetime.timedelta(minutes)).timestamp()
# def minutes_from_now(minutes):
# """Return a timestamp at the given number of minutes from now."""
# return (datetime.datetime.now() + datetime.timedelta(
# 0, minutes * 60)).timestamp()
def seconds_from_now(seconds):
"""Return a timestamp at the given number of seconds from now."""
return (
datetime.datetime.now() + datetime.timedelta(0, seconds)).timestamp()
def main():

View File

@ -3,7 +3,7 @@
TKTAuthLoginURL /plinth/accounts/sso/login/
TKTAuthBackArgName next
TKTAuthDigest SHA512
TKTAuthRefreshURL /plinth/accounts/sso/refresh/
TKTAuthRefreshURL /plinth/accounts/sso/refresh-pubtkt/
TKTAuthUnauthURL /plinth
AuthType mod_auth_pubtkt
AuthName "FreedomBox Single Sign On"

View File

@ -20,11 +20,15 @@ URLs for the Single Sign On module.
from django.conf.urls import url
from .views import SSOLoginView, refresh
from stronghold.decorators import public
from plinth.utils import non_admin_view
urlpatterns = [
url(r'^accounts/sso/login/$', public(SSOLoginView.as_view()), name='sso-login'),
url(r'^accounts/sso/refresh/$', refresh, name='sso-refresh'),
url(r'^accounts/sso/login/$',
public(SSOLoginView.as_view()),
name='sso-login'),
url(r'^accounts/sso/refresh-pubtkt/$',
non_admin_view(refresh),
name='sso-refresh'),
]

View File

@ -23,7 +23,6 @@ import os
import urllib
from django.contrib.auth import REDIRECT_FIELD_NAME
from django.contrib.auth.decorators import login_required
from django.contrib.auth.views import LoginView, LogoutView
from django.http import HttpResponseRedirect
@ -112,10 +111,11 @@ class SSOLogoutView(LogoutView):
return response
@login_required
def refresh(request):
"""Simulate cookie refresh - redirect logged in user with a new cookie"""
redirect_url = request.GET.get(REDIRECT_FIELD_NAME, '')
response = HttpResponseRedirect(redirect_url)
response.delete_cookie(SSO_COOKIE_NAME)
# Redirect with cookie doesn't work with 300 series
response.status_code = 200
return set_ticket_cookie(request.user, response)

View File

@ -34,11 +34,13 @@ urlpatterns = [
# captcha urls are public
url(r'image/(?P<key>\w+)/$',
public(cviews.captcha_image), name='captcha-image',
kwargs={'scale': 1}),
public(cviews.captcha_image), name='captcha-image', kwargs={
'scale': 1
}),
url(r'image/(?P<key>\w+)@2/$',
public(cviews.captcha_image), name='captcha-image-2x',
kwargs={'scale': 2}),
public(cviews.captcha_image), name='captcha-image-2x', kwargs={
'scale': 2
}),
url(r'audio/(?P<key>\w+)/$',
public(cviews.captcha_audio), name='captcha-audio'),
url(r'refresh/$', public(cviews.captcha_refresh), name='captcha-refresh'),