Holger Frey
5 years ago
7 changed files with 153 additions and 12 deletions
@ -0,0 +1,68 @@
@@ -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 @@
@@ -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