feat: update specs and add auth service test
This commit is contained in:
@@ -7,28 +7,34 @@
|
||||
## Overview
|
||||
|
||||
MySQL is the project data layer. DAO classes perform CRUD and query operations
|
||||
against MySQL. Application source and schema files are not present yet, so table
|
||||
and class names here are illustrative conventions for future implementation.
|
||||
against MySQL. The initial scaffold schema exists at
|
||||
`src/main/resources/db/schema.sql`; future module tables should follow the same
|
||||
DDL style and DAO boundaries.
|
||||
|
||||
---
|
||||
|
||||
## Core Tables
|
||||
|
||||
Use primary keys for every table and foreign keys for cross-entity integrity.
|
||||
Illustrative table names:
|
||||
|
||||
Implemented scaffold tables:
|
||||
|
||||
- `roles`: administrator, librarian, reader, and future role definitions.
|
||||
- `permissions`: permission definitions for protected actions.
|
||||
- `role_permissions`: role-to-permission mapping.
|
||||
- `users`: login accounts for administrator, librarian, and reader roles.
|
||||
- `system_logs`: key operation logs, backup events, and exception traces.
|
||||
|
||||
Planned module tables:
|
||||
|
||||
- `books`: book information, inventory count/status, category reference.
|
||||
- `book_categories`: category names and descriptions.
|
||||
- `readers`: reader profiles, borrowing eligibility, contact information.
|
||||
- `borrow_records`: book-reader borrowing, return, renew, and overdue data.
|
||||
- `administrators`: administrator/librarian login and profile data.
|
||||
- `roles`: administrator, librarian, reader, and future role definitions.
|
||||
- `permissions`: permission definitions for protected actions.
|
||||
- `role_permissions`: role-to-permission mapping.
|
||||
- `system_logs`: key operation logs, backup events, and exception traces.
|
||||
|
||||
When schema files are introduced, record the actual path, DDL style, and exact
|
||||
table names here.
|
||||
Record new schema changes in `src/main/resources/db/schema.sql` and update this
|
||||
spec with exact table names, key columns, and DAO/service contracts.
|
||||
|
||||
---
|
||||
|
||||
@@ -42,8 +48,9 @@ table names here.
|
||||
inventory status.
|
||||
- Return entities or small query result objects to services, not HTML or
|
||||
servlet response objects.
|
||||
- Keep MySQL connection details in a shared configuration/helper once one
|
||||
exists, for example `JdbcUtil` plus `db.properties`.
|
||||
- Keep MySQL connection details in `src/main/resources/db.properties` loaded by
|
||||
`JdbcUtil`. The required keys are `db.driver`, `db.url`, `db.username`, and
|
||||
`db.password`.
|
||||
|
||||
---
|
||||
|
||||
@@ -66,6 +73,9 @@ table names here.
|
||||
- `borrow_records.reader_id` should reference `readers`.
|
||||
- Administrator-role and role-permission mapping tables should use foreign keys
|
||||
to preserve authorization integrity.
|
||||
- `users.role_code` must reference `roles.code`.
|
||||
- `role_permissions.role_code` must reference `roles.code`.
|
||||
- `role_permissions.permission_code` must reference `permissions.code`.
|
||||
- Prefer explicit status columns/enums for inventory and borrowing states, then
|
||||
document the chosen values once code exists.
|
||||
|
||||
@@ -83,6 +93,12 @@ table names here.
|
||||
- DAO signature: `UserDao.findActiveByUsername(String username)`.
|
||||
- Service signature: `AuthService.authenticate(String username, String password)`.
|
||||
- Permission signature: `AuthService.hasPermission(AuthenticatedUser user, Permission permission)`.
|
||||
- Servlet route: `POST /login` with `username`, `password`, and optional
|
||||
same-application `redirect`.
|
||||
- Protected routes: `/dashboard`, `/admin/home`, `/librarian/home`, and
|
||||
`/reader/home`.
|
||||
- Session keys: `authenticatedUser`, `userRole`, and `userPermissions`.
|
||||
- DB config keys: `db.driver`, `db.url`, `db.username`, and `db.password`.
|
||||
- Login tables: `roles`, `permissions`, `role_permissions`, `users`, and
|
||||
`system_logs`.
|
||||
|
||||
@@ -93,9 +109,16 @@ table names here.
|
||||
`pbkdf2_sha256$iterations$saltBase64$hashBase64` format.
|
||||
- `users.role_code`: foreign key to `roles.code`; supported scaffold values
|
||||
are `administrator`, `librarian`, and `reader`.
|
||||
- `users.active`: only rows with `active = 1` can authenticate.
|
||||
- `roles.code`, `permissions.code`, and `role_permissions` must match the Java
|
||||
`Role` and `Permission` enum codes exactly.
|
||||
- `db.properties` must be local configuration. Commit
|
||||
`db.properties.example`, but do not commit real credentials.
|
||||
- Session state stores an `AuthenticatedUser` snapshot, role code, and
|
||||
permission-code set. It must not store raw passwords or DAO result objects
|
||||
with password hashes.
|
||||
- Login redirects must stay inside the current application context. Reject
|
||||
values that do not start with a single `/` or that contain CR/LF characters.
|
||||
|
||||
### 4. Validation & Error Matrix
|
||||
|
||||
@@ -103,6 +126,7 @@ table names here.
|
||||
`Username and password are required.`
|
||||
- Unknown user, inactive user, or hash mismatch -> request returns to login JSP
|
||||
with `Invalid username or password.`
|
||||
- Unsafe or blank redirect -> ignore and route to `/dashboard` after success.
|
||||
- Missing `db.properties`, JDBC failure, or unsupported role code -> request
|
||||
returns a generic service-unavailable message and logs server-side details.
|
||||
- Authenticated user missing a required permission -> HTTP 403 and
|
||||
@@ -123,6 +147,8 @@ table names here.
|
||||
unavailable.
|
||||
- Run `PermissionPolicyCheck` or equivalent assertions for administrator,
|
||||
librarian, and reader permissions.
|
||||
- Run `AuthServiceCheck` or equivalent assertions for required-field failures,
|
||||
invalid credentials, success, permission checks, and DAO failure fallback.
|
||||
- When Maven/Tomcat dependencies are installed, run `mvn test` or
|
||||
`mvn clean package` to compile Servlet and JSP integration.
|
||||
|
||||
@@ -131,11 +157,12 @@ table names here.
|
||||
#### Wrong
|
||||
|
||||
```java
|
||||
// JSP or Servlet opens JDBC and checks passwords directly.
|
||||
// JSP, Servlet, or session code opens JDBC and stores password_hash.
|
||||
```
|
||||
|
||||
#### Correct
|
||||
|
||||
```text
|
||||
login.jsp -> LoginServlet -> AuthService -> UserDao -> users/roles tables
|
||||
session -> AuthenticatedUser snapshot + role/permission codes only
|
||||
```
|
||||
|
||||
@@ -7,10 +7,9 @@
|
||||
## Overview
|
||||
|
||||
The developer has established the backend architecture as a B/S Java web
|
||||
application using JSP + Servlet, MySQL, Tomcat, and IDEA. Application source
|
||||
code does not exist in this workspace yet, so package names, class names, and
|
||||
table names below are illustrative project conventions for future code rather
|
||||
than references to existing files.
|
||||
application using JSP + Servlet, MySQL, Tomcat, and IDEA. The initial scaffold
|
||||
now exists under `src/main/`; remaining module names below describe conventions
|
||||
for future feature work.
|
||||
|
||||
Use a layered design:
|
||||
|
||||
@@ -46,7 +45,7 @@ Before backend implementation, read:
|
||||
- `.trellis/spec/backend/error-handling.md`
|
||||
- `.trellis/spec/backend/logging-guidelines.md`
|
||||
- `.trellis/spec/backend/quality-guidelines.md`
|
||||
- `.trellis/tasks/00-bootstrap-guidelines/research/project-requirements.md`
|
||||
- `.trellis/tasks/archive/2026-04/00-bootstrap-guidelines/research/project-requirements.md`
|
||||
|
||||
---
|
||||
|
||||
@@ -67,9 +66,9 @@ Before backend implementation, read:
|
||||
|
||||
## Evidence
|
||||
|
||||
- `.trellis/tasks/00-bootstrap-guidelines/research/repo-scan.md` records that
|
||||
no application source code exists yet.
|
||||
- `.trellis/tasks/00-bootstrap-guidelines/research/project-requirements.md`
|
||||
- `.trellis/tasks/archive/2026-04/00-bootstrap-guidelines/research/repo-scan.md`
|
||||
records the initial pre-scaffold repo scan.
|
||||
- `.trellis/tasks/archive/2026-04/00-bootstrap-guidelines/research/project-requirements.md`
|
||||
records the developer-provided stack, architecture, modules, and data model.
|
||||
|
||||
---
|
||||
|
||||
@@ -40,15 +40,15 @@ Before frontend implementation, read:
|
||||
- `.trellis/spec/frontend/state-management.md`
|
||||
- `.trellis/spec/frontend/type-safety.md`
|
||||
- `.trellis/spec/frontend/quality-guidelines.md`
|
||||
- `.trellis/tasks/00-bootstrap-guidelines/research/project-requirements.md`
|
||||
- `.trellis/tasks/archive/2026-04/00-bootstrap-guidelines/research/project-requirements.md`
|
||||
|
||||
---
|
||||
|
||||
## Evidence
|
||||
|
||||
- `.trellis/tasks/00-bootstrap-guidelines/research/repo-scan.md` records that
|
||||
no application source code exists yet.
|
||||
- `.trellis/tasks/00-bootstrap-guidelines/research/project-requirements.md`
|
||||
- `.trellis/tasks/archive/2026-04/00-bootstrap-guidelines/research/repo-scan.md`
|
||||
records the initial pre-scaffold repo scan.
|
||||
- `.trellis/tasks/archive/2026-04/00-bootstrap-guidelines/research/project-requirements.md`
|
||||
records the developer-provided JSP presentation approach and image-to-JSP
|
||||
workflow.
|
||||
|
||||
|
||||
@@ -23,6 +23,81 @@ rendering.
|
||||
|
||||
---
|
||||
|
||||
## Scenario: Login JSP And Servlet Contract
|
||||
|
||||
### 1. Scope / Trigger
|
||||
|
||||
- Trigger: the initial login scaffold introduced a cross-layer JSP/Servlet
|
||||
contract for authentication screens and protected role pages.
|
||||
|
||||
### 2. Signatures
|
||||
|
||||
- Login form: `POST /login`.
|
||||
- Request fields: `username`, `password`, and optional `redirect`.
|
||||
- Login JSP request attributes: `errorMessage`, `username`, and `redirect`.
|
||||
- Dashboard/role JSP session attributes: `authenticatedUser`, `userRole`, and
|
||||
`userPermissions`.
|
||||
- Role page request attributes: `areaName` and `areaSummary`.
|
||||
|
||||
### 3. Contracts
|
||||
|
||||
- `username` is trimmed in the Servlet before service authentication and may be
|
||||
echoed back only through JSP escaping.
|
||||
- `password` is submitted to the Servlet and must never be written to a request
|
||||
attribute or session attribute.
|
||||
- `redirect` must be a same-application path beginning with one `/`; invalid
|
||||
values are ignored.
|
||||
- JSPs render data with JSP EL/JSTL, not scriptlet Java.
|
||||
- JSPs may read safe session snapshots, but they must not call DAOs or inspect
|
||||
password hashes.
|
||||
|
||||
### 4. Validation & Error Matrix
|
||||
|
||||
- Missing `username` or `password` -> `errorMessage` displays
|
||||
`Username and password are required.`
|
||||
- Invalid credentials -> `errorMessage` displays
|
||||
`Invalid username or password.`
|
||||
- Login service unavailable -> `errorMessage` displays a generic unavailable
|
||||
message; details stay in server logs.
|
||||
- Missing authenticated session on protected pages -> redirect to `/login` with
|
||||
a safe `redirect` value.
|
||||
- Insufficient role permission -> render `/unauthorized`.
|
||||
|
||||
### 5. Good/Base/Bad Cases
|
||||
|
||||
- Good: failed login keeps the escaped username and never redisplays the
|
||||
password.
|
||||
- Base: dashboard reads `sessionScope.authenticatedUser.displayName` and
|
||||
`sessionScope.userRole` only for display/navigation.
|
||||
- Bad: JSP uses scriptlets, JDBC, or raw request parameters to decide
|
||||
authentication.
|
||||
|
||||
### 6. Tests Required
|
||||
|
||||
- Scan JSPs to confirm there are no scriptlets beyond directives.
|
||||
- Scan JSP/static assets to confirm no SQL/JDBC access exists in presentation
|
||||
files.
|
||||
- Run service-level auth checks for required fields, invalid credentials,
|
||||
success, DAO fallback, and permission checks.
|
||||
- When Maven/Tomcat is available, run a Servlet/JSP compile or package check.
|
||||
|
||||
### 7. Wrong vs Correct
|
||||
|
||||
#### Wrong
|
||||
|
||||
```jsp
|
||||
<%-- JSP checks request.getParameter("password") or runs SQL directly. --%>
|
||||
```
|
||||
|
||||
#### Correct
|
||||
|
||||
```text
|
||||
login.jsp displays attributes set by LoginServlet; AuthService and UserDao own
|
||||
authentication and database access.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Validation
|
||||
|
||||
- Parse and validate IDs, dates, enum/status values, and required strings in
|
||||
|
||||
Reference in New Issue
Block a user