using Statum; using Invercargill; using Invercargill.DataStructures; namespace Example { /** * `POST /login` — creates a session-scoped `auth` slot from the submitted * name and redirects the client home. The `is_admin` flag is kept in the * slot's (encrypted, server-only) private data. */ public class LoginAction : StatumAction { public override async Lot handle() throws GLib.Error { var name = "guest"; if (request.form != null) { var submitted = request.form.get_field("name"); if (submitted != null && ((!)submitted).length > 0) { name = (!)submitted; } } var is_admin = name == "admin"; var auth_public = new PropertyDictionary(); auth_public.set_native("name", name); auth_public.set_native("role", is_admin ? "admin" : "member"); var auth_private = new PropertyDictionary(); auth_private.set_native("is_admin", is_admin); var state = new State() { type_name = "auth", public_data = auth_public, private_data = auth_private }; var slot = state_service.new_slot(Scope.SESSION, state); var frame = state_service.sign_slot(slot.id); var directives = new Series(); directives.add(new Model.SetDirectiveDto.with_frame((!)frame)); directives.add(new Model.NavigateDirectiveDto.with_uri("/")); return directives; } } /** * `POST /logout` — clears the held `auth` slot and redirects home. */ public class LogoutAction : StatumAction { public override async Lot handle() throws GLib.Error { var directives = new Series(); HeldSlot auth; if (request.held.try_get("auth", out auth)) { yield state_service.clear_slot(auth.key); directives.add(new Model.ClearDirectiveDto.with_key(auth.key)); } directives.add(new Model.NavigateDirectiveDto.with_uri("/")); return directives; } } }