This is an old revision of the document!
Member Portal V2
This is a project driven by @samp20 to build a new member portal to provide Single-Sign-On (SSO) to other Hackspace services.
Architecture
The current proposed architecture is a Python Flask application with PostgreSQL as the backend database.
Tasks
| Description | Depends on | Assigned to |
|---|---|---|
| Copy across skeleton from storage project | samp20 | |
| Implement Session management | samp20 | |
| Initial OAuth implementation | Session management | - |
| JSON Web Keys implementation | - |
Project layout
portal/: The whole application.forms/: WTForms.static/: Static files, e.g. css.systems/: Core systems, e.g. Session, OAuth, JWK.templates/: Jinja templates.views/: Flask Blueprints with routes. Glue between templates and systems.init.py: Application entrypoint.extensions.py: Instantiate extensions and systems.models.py: SQLAlchemy models.
tests/: Tests. Mainly for systems.
Systems
Systems will follow a similar style to Flask extensions. Flask requires that extensions don't store state directly on the class itself, but instead obtain it from the current_app. This allows multiple applications to be instantiated, for example when unit testing.
class _State: def __init__(self, app: Flask): self.greeting: str = app.config["MYSYSTEM_GREETING"] class MySystem: def __init__(self, other: OtherSystem, app: Flask|None): self.other = other if app is not None: self.init_app(app) def init_app(self, app: Flask): state = _State(app) app.extensions["hs.portal.my_system"] = state @property def _state(self) -> _State: state = current_app.extensions["hs.portal.my_system"] return state def get_greeting(self) -> str: return self._state.greeting