Add tests for token mechanism

This commit is contained in:
Lauri Võsandi 2017-04-26 09:13:41 +03:00
parent c3477ef635
commit 9aab212647
3 changed files with 36 additions and 9 deletions

View File

@ -37,11 +37,11 @@ class TokenResource(object):
margin = 300 # Tolerate 5 minute clock skew as Kerberos does
if csum.hexdigest() != req.get_param("c", required=True):
raise falcon.HTTPUnauthorized("Forbidden", "Invalid token supplied, did you copy-paste link correctly?")
raise falcon.HTTPForbidden("Forbidden", "Invalid token supplied, did you copy-paste link correctly?")
if now < timestamp - margin:
raise falcon.HTTPUnauthorized("Forbidden", "Token not valid yet, are you sure server clock is correct?")
raise falcon.HTTPForbidden("Forbidden", "Token not valid yet, are you sure server clock is correct?")
if now > timestamp + margin + config.TOKEN_LIFETIME:
raise falcon.HTTPUnauthorized("Forbidden", "Token expired")
raise falcon.HTTPForbidden("Forbidden", "Token expired")
# At this point consider token to be legitimate
@ -88,9 +88,12 @@ class TokenResource(object):
# Token lifetime in local time, to select timezone: dpkg-reconfigure tzdata
token_created = datetime.fromtimestamp(timestamp)
token_expires = datetime.fromtimestamp(timestamp + config.TOKEN_LIFETIME)
with open("/etc/timezone") as fh:
token_timezone = fh.read().strip()
try:
with open("/etc/timezone") as fh:
token_timezone = fh.read().strip()
except EnvironmentError:
token_timezone = None
context = globals()
context.update(locals())
mailer.send("token.md", to=user, **context)
resp.body = args

View File

@ -15,5 +15,5 @@ To set up OpenVPN for your device:
{% endif %}
Click [here]({{ config.TOKEN_URL }}?{{ args }}) to claim the token.
Token is usable until {{ token_expires }} ({{ token_timezone }} time).
Token is usable until {{ token_expires }}{% if token_timezone %} ({{ token_timezone }} time){% endif %}.

View File

@ -258,11 +258,9 @@ def test_cli_setup_authority():
# Test static
r = client().simulate_delete("/nonexistant.html")
assert r.status_code == 404
r = client().simulate_delete("/index.html")
assert r.status_code == 200
# Log can be read only by admin
r = client().simulate_get("/api/log/")
assert r.status_code == 401
@ -273,3 +271,29 @@ def test_cli_setup_authority():
headers={"Authorization":admintoken})
assert r.status_code == 200
assert r.headers.get('content-type') == "application/json; charset=UTF-8"
# Test token mech
r = client().simulate_post("/api/token/")
assert r.status_code == 404
config.BUNDLE_FORMAT = "ovpn"
config.USER_ENROLLMENT_ALLOWED = True
r = client().simulate_post("/api/token/")
assert r.status_code == 401 # needs auth
r = client().simulate_post("/api/token/",
headers={"Authorization":usertoken})
assert r.status_code == 403 # regular user forbidden
r = client().simulate_post("/api/token/",
body="user=userbot", # TODO: test nonexistant user
headers={"content-type": "application/x-www-form-urlencoded", "Authorization":admintoken})
assert r.status_code == 200 # token generated by admin
r2 = client().simulate_get("/api/token/",
query_string="u=userbot&t=1493184342&c=ac9b71421d5741800c5a4905b20c1072594a2df863e60ba836464888786bf2a6",
headers={"content-type": "application/x-www-form-urlencoded", "Authorization":admintoken})
assert r2.status_code == 403 # invalid checksum/timestamp
r2 = client().simulate_get("/api/token/", query_string=r.content,
headers={"User-Agent":"Mozilla/5.0 (X11; Fedora; Linux x86_64) "
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36"})
assert r2.status_code == 200 # token consumed by anyone