using Inversion; using Invercargill.DataStructures; using InvercargillJson; using Spry; using Spry.Authentication; using Statum; namespace {{NS}} { /** One row of the users table, serialised into the users slot's JSON array. */ public class UserRow : Object { public string id { get; set; default = ""; } public string username { get; set; default = ""; } public string email { get; set; default = ""; } public bool enabled { get; set; } public string[] permissions { get; set; } public Statum.Model.ActionDto set_enabled { get; set; } public Statum.Model.ActionDto grant { get; set; } public Statum.Model.ActionDto revoke { get; set; } public Statum.Model.ActionDto delete { get; set; } } /** * Entrypoint for /users: admin-guarded. Loads every user (with * permissions) from the UserService into the `users` slot as a JSON array * of rows, each carrying enable/grant/revoke/delete action references * sealed with the row's user_id (Spry.Actions.UserActionPrivate) under * the base Spry action types — the shipped actions decrypt the blob * themselves, so no subclasses are needed. */ public class UserManagementEntrypoint : StatumEntrypoint { private UserService users = inject(); public override async DirectiveBuilder handle() throws GLib.Error { var guard = yield SpryAuth.require_permission(directives(), request, users, SpryAuth.ADMIN_PERMISSION); if (guard != null) { return (!)guard; } var rows = new Series(); foreach (var user in yield users.list_users(0, 200)) { var sealed = new Spry.Actions.UserActionPrivate(); sealed.user_id = user.id; var row = new UserRow(); row.id = user.id.to_string(); row.username = user.username; row.email = user.email ?? ""; row.enabled = user.enabled; row.permissions = user.permissions.any() ? user.permissions.to_array() : new string[0]; row.set_enabled = action_registry.author_private(sealed); row.grant = action_registry.author_private(sealed); row.revoke = action_registry.author_private(sealed); row.delete = action_registry.author_private(sealed); rows.add(row); } var array = new JsonArray(); foreach (var row in rows) { array.add(new JsonElement.from_properties(GObjectMapping.to_properties(row))); } var public_data = new PropertyDictionary(); public_data["users"] = new JsonElement.from_elements(array); var slot = state_service.new_slot(Statum.Scope.PAGE, new Statum.State() { type_name = "users", public_data = public_data, private_data = new PropertyDictionary() }); return directives().set(slot); } } }