|
|
- from functools import wraps
- import secrets
-
- from django.core.signing import TimestampSigner, SignatureExpired
- from django.shortcuts import redirect, render
- from hc.api.models import TokenBucket
- from hc.lib import emails
-
-
- def _session_unsign(request, key, max_age):
- if key not in request.session:
- return None
-
- try:
- return TimestampSigner().unsign(request.session[key], max_age=max_age)
- except SignatureExpired:
- pass
-
-
- def require_sudo_mode(f):
- @wraps(f)
- def wrapper(request, *args, **kwds):
- assert request.user.is_authenticated
-
- # is sudo mode active and has not expired yet?
- if _session_unsign(request, "sudo", 1800) == "active":
- return f(request, *args, **kwds)
-
- if not TokenBucket.authorize_sudo_code(request.user):
- return render(request, "try_later.html")
-
- # has the user submitted a code to enter sudo mode?
- if "sudo_code" in request.POST:
- ours = _session_unsign(request, "sudo_code", 900)
- if ours and ours == request.POST["sudo_code"]:
- request.session.pop("sudo_code")
- request.session["sudo"] = TimestampSigner().sign("active")
- return redirect(request.path)
-
- if not _session_unsign(request, "sudo_code", 900):
- code = "%06d" % secrets.randbelow(1000000)
- request.session["sudo_code"] = TimestampSigner().sign(code)
- emails.sudo_code(request.user.email, {"sudo_code": code})
-
- ctx = {}
- if "sudo_code" in request.POST:
- ctx["wrong_code"] = True
-
- return render(request, "accounts/sudo.html", ctx)
-
- return wrapper
|