|
|
@@ -9,19 +9,50 @@ namespace Spry.Authentication {
|
|
|
public string authorisation_permission { get; set; default = "spry.admin"; }
|
|
|
public bool authorised { get; set; }
|
|
|
public const int64 users_per_page = 20;
|
|
|
+ public string? error_message { get; set; }
|
|
|
+ public string? success_message { get; set; }
|
|
|
|
|
|
public override string markup { get { return """
|
|
|
<spry-context property="page_number" />
|
|
|
<spry-context property="authorisation_permission" />
|
|
|
+ <spry-context property="error_message" />
|
|
|
+ <spry-context property="success_message" />
|
|
|
<div spry-if="!this.authorised">
|
|
|
<strong>You must have the permission <code content-expr="this.authorisation_permission"></code> to access this content.</strong>
|
|
|
</div>
|
|
|
- <div spry-else sid="container" style="gap: 1em;">
|
|
|
+ <div spry-else sid="container" style="gap: 1em; padding: 1em;">
|
|
|
<spry-outlet sid="outlet" />
|
|
|
+ <details>
|
|
|
+ <summary><strong>Create New User</strong></summary>
|
|
|
+ <form spry-action=":create" spry-target="container" spry-method="post" hx-disabled-elt="find input, find button" hx-indicator="find button" hx-swap="outerHTML">
|
|
|
+ <div style="display: grid; grid-template-columns: max-content auto; column-gap: 3em; row-gap: 1em;">
|
|
|
+ <label for="username">Username:</label>
|
|
|
+ <input type="text" id="username" name="username" required />
|
|
|
+ <label for="email">Email:</label>
|
|
|
+ <input type="email" id="email" name="email" required />
|
|
|
+ <label for="forename">Forename:</label>
|
|
|
+ <input type="text" id="forename" name="forename" required />
|
|
|
+ <label for="surname">Surname:</label>
|
|
|
+ <input type="text" id="surname" name="surname" required />
|
|
|
+ <label for="date_of_birth">Date of Birth:</label>
|
|
|
+ <input type="date" id="date_of_birth" name="date_of_birth" required />
|
|
|
+ <label for="password">Password:</label>
|
|
|
+ <input type="password" id="password" name="password" required />
|
|
|
+ <div></div>
|
|
|
+ <button type="submit">Create User</button>
|
|
|
+ </div>
|
|
|
+ </form>
|
|
|
+ </details>
|
|
|
+ <div spry-if="this.error_message != null" style="color: red;">
|
|
|
+ <strong content-expr="this.error_message"></strong>
|
|
|
+ </div>
|
|
|
+ <div spry-if="this.success_message != null" style="color: green;">
|
|
|
+ <strong content-expr="this.success_message"></strong>
|
|
|
+ </div>
|
|
|
<div>
|
|
|
- <button spry-action=":previous" spry-target="container">Previous</button>
|
|
|
+ <button spry-action=":previous" spry-target="container" hx-swap="outerHTML">Previous</button>
|
|
|
<span>Page <strong content-expr="stringify(this.page_number + 1)"></strong></span>
|
|
|
- <button spry-action=":next" spry-target="container">Next</button>
|
|
|
+ <button spry-action=":next" spry-target="container" hx-swap="outerHTML">Next</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
"""; }}
|
|
|
@@ -29,6 +60,7 @@ namespace Spry.Authentication {
|
|
|
private UserService user_service = inject<UserService>();
|
|
|
private AuthorisationContext authorisation_context = inject<AuthorisationContext>();
|
|
|
private ComponentFactory component_factory = inject<ComponentFactory>();
|
|
|
+ private HttpContext http_context = inject<HttpContext>();
|
|
|
|
|
|
public async override void prepare () throws Error {
|
|
|
if(authorisation_context.is_anonymous() || !authorisation_context.has_permission (authorisation_permission)) {
|
|
|
@@ -56,8 +88,45 @@ namespace Spry.Authentication {
|
|
|
if(action == "next") {
|
|
|
page_number ++;
|
|
|
}
|
|
|
+ if(action == "create") {
|
|
|
+ try {
|
|
|
+ var form = yield Astralis.FormDataParser.parse(http_context.request.request_body, http_context.request.content_type);
|
|
|
+
|
|
|
+ var username = form.get_field("username");
|
|
|
+ var email = form.get_field("email");
|
|
|
+ var forename = form.get_field("forename");
|
|
|
+ var surname = form.get_field("surname");
|
|
|
+ var date_of_birth_str = form.get_field("date_of_birth");
|
|
|
+ var password = form.get_field("password");
|
|
|
+
|
|
|
+ if (username == null || email == null || forename == null || surname == null || date_of_birth_str == null || password == null) {
|
|
|
+ error_message = "All fields are required.";
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ var date_parts = date_of_birth_str.split("-");
|
|
|
+ if (date_parts.length != 3) {
|
|
|
+ error_message = "Invalid date format. Use YYYY-MM-DD.";
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ var year = int.parse(date_parts[0]);
|
|
|
+ var month = int.parse(date_parts[1]);
|
|
|
+ var day = int.parse(date_parts[2]);
|
|
|
+
|
|
|
+ var date_of_birth = new DateTime.utc(year, month, day, 0, 0, 0);
|
|
|
+
|
|
|
+ yield user_service.register_user(username, email, forename, surname, date_of_birth, password);
|
|
|
+
|
|
|
+ success_message = "User created successfully.";
|
|
|
+ error_message = null;
|
|
|
+ } catch (Error e) {
|
|
|
+ error_message = "Failed to create user: %s".printf(e.message);
|
|
|
+ success_message = null;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
-}
|
|
|
+}
|