Holger Frey
5 years ago
7 changed files with 153 additions and 12 deletions
@ -0,0 +1,68 @@ |
|||||||
|
from passlib.hash import argon2 |
||||||
|
from pyramid.view import view_config, forbidden_view_config |
||||||
|
from pyramid.security import forget, remember |
||||||
|
from pyramid.authorization import ACLAuthorizationPolicy |
||||||
|
from pyramid.authentication import AuthTktAuthenticationPolicy |
||||||
|
from pyramid.httpexceptions import HTTPFound |
||||||
|
|
||||||
|
from . import Root |
||||||
|
|
||||||
|
AUTHENTICATED_USER_ID = "authenticated" |
||||||
|
|
||||||
|
|
||||||
|
class MyAuthenticationPolicy(AuthTktAuthenticationPolicy): |
||||||
|
def authenticated_userid(self, request): |
||||||
|
user = request.user |
||||||
|
if user is not None: |
||||||
|
return AUTHENTICATED_USER_ID |
||||||
|
|
||||||
|
|
||||||
|
def get_user(request): |
||||||
|
return request.unauthenticated_userid |
||||||
|
|
||||||
|
|
||||||
|
@forbidden_view_config( |
||||||
|
renderer="superx_budget:pyramid/templates/login.jinja2", |
||||||
|
) |
||||||
|
def forbidden_view(request): |
||||||
|
return {"error": False} |
||||||
|
|
||||||
|
|
||||||
|
@view_config( |
||||||
|
context=Root, |
||||||
|
name="login", |
||||||
|
request_method="POST", |
||||||
|
permission="login", |
||||||
|
renderer="superx_budget:pyramid/templates/login.jinja2", |
||||||
|
) |
||||||
|
def login(request): |
||||||
|
if request.check_password(): |
||||||
|
headers = remember(request, AUTHENTICATED_USER_ID, max_age=3600) |
||||||
|
return HTTPFound("/", headers=headers) |
||||||
|
return {"error": True} |
||||||
|
|
||||||
|
|
||||||
|
@view_config( |
||||||
|
context=Root, name="logout", permission="login", |
||||||
|
) |
||||||
|
def logout(request): |
||||||
|
headers = forget(request) |
||||||
|
return HTTPFound("/", headers=headers) |
||||||
|
|
||||||
|
|
||||||
|
def includeme(config): |
||||||
|
settings = config.get_settings() |
||||||
|
authn_policy = MyAuthenticationPolicy( |
||||||
|
settings["auth.secret"], hashalg="sha512", |
||||||
|
) |
||||||
|
config.set_authentication_policy(authn_policy) |
||||||
|
config.set_authorization_policy(ACLAuthorizationPolicy()) |
||||||
|
|
||||||
|
hashes = [hash for hash in settings["pwd.db"].splitlines() if hash] |
||||||
|
|
||||||
|
def check_password(request): |
||||||
|
password = request.POST.get("password", "") |
||||||
|
return any(argon2.verify(password, hash) for hash in hashes) |
||||||
|
|
||||||
|
config.add_request_method(check_password, "check_password") |
||||||
|
config.add_request_method(get_user, "user", reify=True) |
@ -0,0 +1,56 @@ |
|||||||
|
<!DOCTYPE html> |
||||||
|
<html lang="en"> |
||||||
|
<head> |
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> |
||||||
|
|
||||||
|
<title>SuperX -> Budget Overview</title> |
||||||
|
|
||||||
|
<link href="{{request.static_url('superx_budget.pyramid:static/img/favicon.ico')}}" type="image/x-icon" rel="shortcut icon"> |
||||||
|
|
||||||
|
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous"> |
||||||
|
<link rel="stylesheet" href="{{request.static_url('superx_budget.pyramid:static/style.css')}}" type="text/css" media="screen" /> |
||||||
|
</head> |
||||||
|
<body> |
||||||
|
<div class="container"> |
||||||
|
|
||||||
|
<div class="row mb-4"> |
||||||
|
<div class="col"> |
||||||
|
<header> |
||||||
|
<nav class="navbar navbar-expand navbar-light bg-light"> |
||||||
|
<span class="navbar-brand bg-info p-3 rounded">Budget Overview From SuperX</span> |
||||||
|
</nav> |
||||||
|
</header> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="row"> |
||||||
|
<div class="col"> |
||||||
|
<h2 class="mt-3 mb-4">Please Log In</h2> |
||||||
|
<form class="form" method="POST" action="/login"> |
||||||
|
<p> |
||||||
|
<div class="input-group"> |
||||||
|
<label for="password" class="sr-only">Password:</label> |
||||||
|
<input type="passwort" id="password" name="password" class="form-control {% if error %}is-invalid{% endif %}" required="required" placeholder="Password"> |
||||||
|
<div class="invalid-feedback">Password is invalid</div> |
||||||
|
</div> |
||||||
|
</p> |
||||||
|
<p> |
||||||
|
<button type="submit" name="submit" value="login" class="btn btn-primary">log in</button> |
||||||
|
</p> |
||||||
|
</form> |
||||||
|
</div> |
||||||
|
<div class="col"></div> |
||||||
|
<div class="col"></div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="row mt-3"> |
||||||
|
<div class="col"> |
||||||
|
<footer> |
||||||
|
<p class="bg-light p-3">Any problems or questions? Please contact <a href="https://wiki.cpi.imtek.uni-freiburg.de/HolgerFrey">Holgi</a>.</p> |
||||||
|
</footer> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
</div></div></div> |
||||||
|
</body> |
||||||
|
</html> |
Loading…
Reference in new issue