Add user authentication and management features
- Introduce user authentication with form-based login, including a default admin user. - Implement UserEntity, UserRepository, and UserService for user management. - Create RESTful endpoints for user listing and creation, restricted to admin role. - Enhance OpenAPI specification to document new authentication and user management endpoints. - Add frontend components for login and user management, including protected routes. - Implement context and hooks for managing authentication state in the React application. - Include unit tests for user service and authentication logic.
This commit is contained in:
@@ -3,6 +3,23 @@ quarkus:
|
||||
name: roleplay
|
||||
http:
|
||||
root-path: /
|
||||
# Form-based auth: SPA mode (no redirects; 200/401). Session in encrypted cookie.
|
||||
auth:
|
||||
form:
|
||||
enabled: true
|
||||
login-page: ""
|
||||
landing-page: ""
|
||||
error-page: ""
|
||||
http-only-cookie: false
|
||||
session:
|
||||
encryption-key: roleplay-session-secret-key-min-16chars
|
||||
permission:
|
||||
form-login:
|
||||
paths: /j_security_check
|
||||
policy: permit
|
||||
api:
|
||||
paths: /api/v1/*
|
||||
policy: authenticated
|
||||
datasource:
|
||||
db-kind: h2
|
||||
jdbc:
|
||||
@@ -28,3 +45,10 @@ quarkus:
|
||||
level: DEBUG
|
||||
"org.jboss.resteasy.reactive.client.logging":
|
||||
level: DEBUG
|
||||
# Login debugging: form auth and security identity
|
||||
"io.quarkus.vertx.http.runtime.security":
|
||||
level: DEBUG
|
||||
"io.quarkus.security":
|
||||
level: DEBUG
|
||||
"de.neitzel.roleplay":
|
||||
level: INFO
|
||||
|
||||
@@ -6,5 +6,6 @@
|
||||
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.24.xsd">
|
||||
|
||||
<include file="db/migration/v001__scenarios_and_characters.xml"/>
|
||||
<include file="db/migration/v002__users_and_roles.xml"/>
|
||||
</databaseChangeLog>
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<databaseChangeLog
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
|
||||
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.24.xsd">
|
||||
|
||||
<changeSet id="002-1-create-rp-user-table" author="roleplay">
|
||||
<createTable tableName="rp_user">
|
||||
<column name="id" type="uuid">
|
||||
<constraints primaryKey="true" nullable="false"/>
|
||||
</column>
|
||||
<column name="username" type="varchar(255)">
|
||||
<constraints nullable="false" unique="true"/>
|
||||
</column>
|
||||
<column name="password" type="varchar(255)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="role" type="varchar(50)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
<comment>Stores application users for form-based auth. Default login: admin / changeme.</comment>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="002-2-seed-admin-user" author="roleplay">
|
||||
<insert tableName="rp_user">
|
||||
<column name="id" value="11111111-1111-1111-1111-111111111111"/>
|
||||
<column name="username" value="admin"/>
|
||||
<column name="password" value="$2a$10$dFA336yJOw3.pogwU.vXVu3BRRfBr1yjhGC6O6nfC2qGFA5e29.cO"/>
|
||||
<column name="role" value="admin"/>
|
||||
</insert>
|
||||
<rollback>
|
||||
<delete tableName="rp_user">
|
||||
<where>id = '11111111-1111-1111-1111-111111111111'</where>
|
||||
</delete>
|
||||
</rollback>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
@@ -23,6 +23,10 @@ tags:
|
||||
description: List and retrieve saved scenario templates
|
||||
- name: characters
|
||||
description: List and retrieve saved character templates
|
||||
- name: auth
|
||||
description: Authentication (current user, logout)
|
||||
- name: users
|
||||
description: User management (admin only)
|
||||
|
||||
paths:
|
||||
|
||||
@@ -411,6 +415,84 @@ paths:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
|
||||
/auth/me:
|
||||
get:
|
||||
operationId: getAuthMe
|
||||
summary: Current user info
|
||||
description: Returns the authenticated user's username and roles. Requires session cookie.
|
||||
tags:
|
||||
- auth
|
||||
responses:
|
||||
"200":
|
||||
description: Current user.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/AuthMeResponse'
|
||||
"401":
|
||||
description: Not authenticated.
|
||||
|
||||
/auth/logout:
|
||||
post:
|
||||
operationId: logout
|
||||
summary: Log out
|
||||
description: Clears the session cookie. Requires authenticated user.
|
||||
tags:
|
||||
- auth
|
||||
responses:
|
||||
"204":
|
||||
description: Logged out.
|
||||
"401":
|
||||
description: Not authenticated.
|
||||
|
||||
/admin/users:
|
||||
get:
|
||||
operationId: listUsers
|
||||
summary: List users (admin only)
|
||||
description: Returns all users (id, username, role). Admin role required.
|
||||
tags:
|
||||
- users
|
||||
responses:
|
||||
"200":
|
||||
description: List of users.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/UserListResponse'
|
||||
"401":
|
||||
description: Not authenticated.
|
||||
"403":
|
||||
description: Forbidden (admin only).
|
||||
post:
|
||||
operationId: createUser
|
||||
summary: Create user (admin only)
|
||||
description: Creates a new user with the given username, password, and role.
|
||||
tags:
|
||||
- users
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/CreateUserRequest'
|
||||
responses:
|
||||
"201":
|
||||
description: User created.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/UserSummary'
|
||||
"400":
|
||||
description: Invalid request (e.g. username already exists).
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
"401":
|
||||
description: Not authenticated.
|
||||
"403":
|
||||
description: Forbidden (admin only).
|
||||
|
||||
components:
|
||||
|
||||
parameters:
|
||||
@@ -1017,6 +1099,70 @@ components:
|
||||
- type
|
||||
- title
|
||||
|
||||
# ─── Auth and users ───────────────────────────────────────────────────────
|
||||
|
||||
AuthMeResponse:
|
||||
type: object
|
||||
description: Current authenticated user.
|
||||
properties:
|
||||
username:
|
||||
type: string
|
||||
description: Login name.
|
||||
roles:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
description: Assigned roles (e.g. admin, user).
|
||||
required:
|
||||
- username
|
||||
- roles
|
||||
|
||||
UserSummary:
|
||||
type: object
|
||||
description: User without password (for list and create response).
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
description: User UUID.
|
||||
username:
|
||||
type: string
|
||||
description: Login name.
|
||||
role:
|
||||
type: string
|
||||
description: Role (admin or user).
|
||||
required:
|
||||
- id
|
||||
- username
|
||||
- role
|
||||
|
||||
UserListResponse:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/UserSummary'
|
||||
description: List of users (admin only).
|
||||
|
||||
CreateUserRequest:
|
||||
type: object
|
||||
description: Request to create a new user (admin only).
|
||||
properties:
|
||||
username:
|
||||
type: string
|
||||
description: Login name.
|
||||
password:
|
||||
type: string
|
||||
description: Plain-text password (hashed on server).
|
||||
role:
|
||||
type: string
|
||||
enum:
|
||||
- admin
|
||||
- user
|
||||
description: Role to assign.
|
||||
required:
|
||||
- username
|
||||
- password
|
||||
- role
|
||||
|
||||
# ─── Error ────────────────────────────────────────────────────────────────
|
||||
|
||||
ErrorResponse:
|
||||
|
||||
Reference in New Issue
Block a user