friwall/web/auth.py

69 lines
2.2 KiB
Python
Raw Normal View History

2023-09-06 12:28:06 +00:00
import authlib.integrations.flask_client
2022-01-03 10:33:02 +00:00
import flask
import flask_login
2023-09-06 12:28:06 +00:00
import urllib.parse
2022-01-03 10:33:02 +00:00
from . import db
2023-09-06 12:28:06 +00:00
login_manager = None
auth = None
users = {}
2022-01-03 10:33:02 +00:00
class User(flask_login.UserMixin):
def __init__(self, info):
self.username = info.get('preferred_username', '')
self.groups = set(info.get('groups', ()))
self.data = info # for debugging really
2022-01-03 10:33:02 +00:00
try:
2023-09-06 12:28:06 +00:00
self.is_admin = db.load('settings').get('admin_group') in self.groups
2022-01-03 10:33:02 +00:00
except:
self.is_admin = False
def __repr__(self):
2023-09-06 12:28:06 +00:00
return f'{self.username} {self.groups}'
2022-01-03 10:33:02 +00:00
def get_id(self):
2023-09-06 12:28:06 +00:00
return self.username
2022-01-03 10:33:02 +00:00
def init_app(app, settings):
2023-09-06 12:28:06 +00:00
login_manager = flask_login.LoginManager(app)
oauth = authlib.integrations.flask_client.OAuth(app)
oauth.register(
name='default',
server_metadata_url=settings.get('oidc_server'),
client_id=settings.get('oidc_client_id'),
client_secret=settings.get('oidc_client_secret'),
2023-09-06 12:28:06 +00:00
client_kwargs={'scope': 'openid profile email'})
metadata = oauth.default.load_server_metadata()
app.config['OIDC_CLIENT_ID'] = settings.get('OIDC_CLIENT_ID')
app.config['OIDC_END_SESSION_ENDPOINT'] = metadata.get('end_session_endpoint')
2023-09-06 12:28:06 +00:00
@login_manager.user_loader
def load_user(username):
return users.get(username)
@login_manager.unauthorized_handler
def unauth_handler():
return flask.redirect(flask.url_for('login', next=flask.request.endpoint))
2022-01-03 10:33:02 +00:00
2023-09-06 12:28:06 +00:00
@app.route('/login')
def login():
return oauth.default.authorize_redirect(flask.url_for('authorize', _external=True))
2023-09-06 12:28:06 +00:00
2023-09-11 13:14:36 +00:00
@app.route('/authorize')
def authorize():
token = oauth.default.authorize_access_token()
user = users[user.username] = User(token.get('userinfo', {}))
2023-09-06 12:28:06 +00:00
flask_login.login_user(user)
return flask.redirect('/')
2022-01-03 10:33:02 +00:00
2023-09-06 12:28:06 +00:00
@app.route('/logout')
def logout():
flask_login.logout_user()
if oidc_logout_url := flask.current_app.config.get('OIDC_END_SESSION_ENDPOINT'):
return flask.redirect(oidc_logout_url + '?'
+ urllib.parse.urlencode({'client_id': flask.current_app.config.get('OIDC_CLIENT_ID')}))
else:
return flask.redirect('/')