Documentation update
dequote and the count components are still missing
This commit is contained in:
@@ -57,8 +57,8 @@ pub fn encode_token(header: &Header, id: String, key: &EncodingKey) -> String {
|
|||||||
/// - `key`: The `DecodingKey` used to verify the JWT's signature.
|
/// - `key`: The `DecodingKey` used to verify the JWT's signature.
|
||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
/// - `Ok(Claims)`: If the token is successfully decoded and verified, returns the extracted `Claims`.
|
/// - `200 OK`: If the token is successfully decoded and verified, returns the extracted `Claims`.
|
||||||
/// - `Err((StatusCode, Json<Error>))`: If the token is invalid, expired, or cannot be decoded,
|
/// - `401 UNAUTHORIZED`: If the token is invalid, expired, or cannot be decoded,
|
||||||
/// returns an `UNAUTHORIZED` status code along with a JSON error message.
|
/// returns an `UNAUTHORIZED` status code along with a JSON error message.
|
||||||
pub fn decode_token(token: String, key: &DecodingKey) -> Result<Claims, (StatusCode, Json<Error>)> {
|
pub fn decode_token(token: String, key: &DecodingKey) -> Result<Claims, (StatusCode, Json<Error>)> {
|
||||||
let mut validation = jsonwebtoken::Validation::new(jsonwebtoken::Algorithm::HS256);
|
let mut validation = jsonwebtoken::Validation::new(jsonwebtoken::Algorithm::HS256);
|
||||||
|
|||||||
@@ -26,13 +26,13 @@ use crate::{AppState, cookie::jwt::decode_token, handlers::auth::filter_user, mo
|
|||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
/// - `cookies`: The `CookieJar` from the request, used to extract the `token` cookie.
|
/// - `cookies`: The `CookieJar` from the request, used to extract the `token` cookie.
|
||||||
/// - `State(data)`: Application state containing `AppState` for database access and `token_secret`.
|
/// - `request`: The incoming HTTP request, which will have user data injected into its extensions.
|
||||||
/// - `mut request`: The incoming HTTP request, which will have user data injected into its extensions.
|
|
||||||
/// - `next`: The next middleware or handler in the chain.
|
/// - `next`: The next middleware or handler in the chain.
|
||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
/// - `Ok(impl IntoResponse)`: If validation succeeds, the request proceeds to the next handler.
|
/// - `200 OK`: If validation succeeds, the request proceeds to the next handler.
|
||||||
/// - `Err((StatusCode, Json<serde_json::Value>))`: An error response if validation fails.
|
/// - `401 UNAUTHORIZED`: If validating the user fails.
|
||||||
|
/// - `500 INTERNAL SERVER ERROR`: If the database query fails
|
||||||
pub async fn validate_token(
|
pub async fn validate_token(
|
||||||
cookies: CookieJar,
|
cookies: CookieJar,
|
||||||
State(data): State<Arc<AppState>>,
|
State(data): State<Arc<AppState>>,
|
||||||
@@ -119,14 +119,13 @@ pub async fn validate_token(
|
|||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
/// - `cookies`: The `CookieJar` from the request.
|
/// - `cookies`: The `CookieJar` from the request.
|
||||||
/// - `State(data)`: Application state containing `AppState`.
|
/// - `request`: The incoming HTTP request, which will have admin user data injected.
|
||||||
/// - `mut request`: The incoming HTTP request, which will have admin user data injected.
|
|
||||||
/// - `next`: The next middleware or handler in the chain.
|
/// - `next`: The next middleware or handler in the chain.
|
||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
/// - `Ok(impl IntoResponse)`: If validation and admin check succeed, the request proceeds.
|
/// - `200 OK`: If validation and admin check succeed, the request proceeds.
|
||||||
/// - `Err((StatusCode, Json<serde_json::Value>))`: An error response if validation fails
|
/// - `401 UNAUTHORIZED`: An error response if validation fails or the user is not an admin.
|
||||||
/// or the user is not an admin.
|
/// - `500 INTERNAL SERVER ERROR`: If the databse query fails
|
||||||
pub async fn validate_admin(
|
pub async fn validate_admin(
|
||||||
cookies: CookieJar,
|
cookies: CookieJar,
|
||||||
State(data): State<Arc<AppState>>,
|
State(data): State<Arc<AppState>>,
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ use crate::{
|
|||||||
/// before being stored. Only administrators can create new users.
|
/// before being stored. Only administrators can create new users.
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
/// - `request`: User creation details including first/last name, username, admin flag, and password
|
/// - `request`: Json with [UserCreateScheme] as it's format
|
||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
/// - `200 OK` on successful user creation
|
/// - `200 OK` on successful user creation
|
||||||
@@ -110,10 +110,10 @@ pub async fn create_user(
|
|||||||
/// The token is valid for 1 hour.
|
/// The token is valid for 1 hour.
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
/// - `request`: Login credentials (username, password)
|
/// - `request`: Login credentials in Json format using the [LoginScheme]
|
||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
/// - `200 OK` with JSON containing token and filtered user info
|
/// - `200 OK` with JSON containing token and [FilteredUser] info
|
||||||
/// - `400 Bad Request` if username not found or password invalid
|
/// - `400 Bad Request` if username not found or password invalid
|
||||||
/// - `500 Internal Server Error` if database query fails
|
/// - `500 Internal Server Error` if database query fails
|
||||||
///
|
///
|
||||||
@@ -231,7 +231,7 @@ pub async fn logout() -> Result<impl IntoResponse, (StatusCode, Json<serde_json:
|
|||||||
/// Useful for frontends to display logged-in user info or verify authentication.
|
/// Useful for frontends to display logged-in user info or verify authentication.
|
||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
/// - `200 OK` with user data (excluding password)
|
/// - `200 OK` with the [FilteredUser] in Json format
|
||||||
/// - Automatically returns `401 Unauthorized` if not authenticated (middleware)
|
/// - Automatically returns `401 Unauthorized` if not authenticated (middleware)
|
||||||
///
|
///
|
||||||
/// # Example Response
|
/// # Example Response
|
||||||
@@ -306,7 +306,7 @@ pub async fn delete_user(
|
|||||||
/// Password hashes are not included in the response.
|
/// Password hashes are not included in the response.
|
||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
/// - `200 OK` with array of FilteredUser objects
|
/// - `200 OK` with array of [FilteredUser] objects
|
||||||
/// - `500 Internal Server Error` if database query fails
|
/// - `500 Internal Server Error` if database query fails
|
||||||
///
|
///
|
||||||
/// # Example Response
|
/// # Example Response
|
||||||
@@ -352,15 +352,11 @@ pub async fn get_users(
|
|||||||
|
|
||||||
/// Retrieves a single user's details by their ID.
|
/// Retrieves a single user's details by their ID.
|
||||||
///
|
///
|
||||||
/// This endpoint allows fetching a specific user's information. It returns a `FilteredUser`
|
|
||||||
/// object, ensuring sensitive data like password hashes are not exposed.
|
|
||||||
///
|
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
/// - `Path(id)`: The ID of the user to retrieve, extracted from the URL path.
|
/// - `id`: The ID of the user to retrieve, extracted from the URL path.
|
||||||
/// - `State(data)`: Application state containing `AppState` for database access.
|
|
||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
/// - `200 OK` with a `FilteredUser` JSON object if the user is found.
|
/// - `200 OK` with a [FilteredUser] JSON object if the user is found.
|
||||||
/// - `404 Not Found` if a user with the given ID does not exist.
|
/// - `404 Not Found` if a user with the given ID does not exist.
|
||||||
/// - `500 Internal Server Error` if a database query error occurs.
|
/// - `500 Internal Server Error` if a database query error occurs.
|
||||||
///
|
///
|
||||||
@@ -396,17 +392,12 @@ pub async fn get_user_by_id(
|
|||||||
|
|
||||||
/// Updates an existing user's information.
|
/// Updates an existing user's information.
|
||||||
///
|
///
|
||||||
/// This endpoint allows administrators to modify a user's `first_name`, `last_name`,
|
|
||||||
/// `username`, `is_admin` status, and optionally their password. If `new_pwd` in the
|
|
||||||
/// request body is an empty string, the user's password remains unchanged.
|
|
||||||
///
|
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
/// - `Path(id)`: The ID of the user to update, extracted from the URL path.
|
/// - `id`: The ID of the user to update, extracted from the URL path.
|
||||||
/// - `State(data)`: Application state containing `AppState` for database access.
|
/// - `body`: [UserUpdateScheme] containing the fields to update.
|
||||||
/// - `Json(body)`: `UserUpdateScheme` containing the fields to update.
|
|
||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
/// - `200 OK` with the `FilteredUser` object of the updated user.
|
/// - `200 OK` with the [FilteredUser] object of the updated user.
|
||||||
/// - `404 Not Found` if a user with the given ID does not exist.
|
/// - `404 Not Found` if a user with the given ID does not exist.
|
||||||
/// - `500 Internal Server Error` if a database query or password hashing error occurs.
|
/// - `500 Internal Server Error` if a database query or password hashing error occurs.
|
||||||
///
|
///
|
||||||
@@ -470,11 +461,8 @@ pub async fn update_user(
|
|||||||
|
|
||||||
/// Checks if any administrator user exists in the system.
|
/// Checks if any administrator user exists in the system.
|
||||||
///
|
///
|
||||||
/// This endpoint is used during initialization to determine if the setup page should be displayed.
|
|
||||||
/// It counts all users with `is_admin = true` in the database.
|
|
||||||
///
|
|
||||||
/// # Returns
|
/// # Returns
|
||||||
/// - `200 OK` with JSON: `{"has_admin": bool}` - Whether at least one admin exists
|
/// - `200 OK` On successful database query
|
||||||
/// - `500 Internal Server Error` if database query fails
|
/// - `500 Internal Server Error` if database query fails
|
||||||
///
|
///
|
||||||
/// # Example Response
|
/// # Example Response
|
||||||
@@ -507,7 +495,7 @@ pub async fn check_admin_exists(
|
|||||||
/// with proper authorization.
|
/// with proper authorization.
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
/// - `request`: User creation details (first_name, last_name, username, password)
|
/// - `request`: [UserCreateScheme] as a Json value
|
||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
/// - `200 OK` with success message if admin account created
|
/// - `200 OK` with success message if admin account created
|
||||||
@@ -594,10 +582,10 @@ pub async fn setup_initial_admin(
|
|||||||
/// serializing User objects.
|
/// serializing User objects.
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
/// - `user`: Reference to the internal User struct containing password hash
|
/// - `user`: Reference to the internal [User] struct containing password hash
|
||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
/// FilteredUser with only safe-to-share information:
|
/// [FilteredUser] with only safe-to-share information:
|
||||||
/// - `id`: User ID
|
/// - `id`: User ID
|
||||||
/// - `first_name`, `last_name`: User name
|
/// - `first_name`, `last_name`: User name
|
||||||
/// - `username`: Login username
|
/// - `username`: Login username
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ use crate::{
|
|||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
/// - `user`: Authenticated user (extracted from JWT token)
|
/// - `user`: Authenticated user (extracted from JWT token)
|
||||||
/// - `body`: Ticket details (category, subject, description, room)
|
/// - `body`: Json with the [TicketCreateScheme] as it's format
|
||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
/// - `200 OK` on successful creation
|
/// - `200 OK` on successful creation
|
||||||
@@ -95,17 +95,16 @@ pub async fn delete_ticket(
|
|||||||
Ok(StatusCode::NO_CONTENT)
|
Ok(StatusCode::NO_CONTENT)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieves all non-archived tickets.
|
/// Retrieves all tickets.
|
||||||
///
|
///
|
||||||
/// Returns a list of all active tickets with user information denormalized for easier rendering.
|
/// Returns a list of all tickets with user information denormalized for easier rendering.
|
||||||
/// Tickets are ordered by creation date (newest first).
|
/// Tickets are ordered by creation date (newest first).
|
||||||
///
|
///
|
||||||
/// # Filtering
|
/// # Filtering
|
||||||
/// - Excludes tickets with status "Archived"
|
|
||||||
/// - Uses LEFT JOIN to include creator information
|
/// - Uses LEFT JOIN to include creator information
|
||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
/// - `200 OK` with array of TicketResponse objects
|
/// - `200 OK` with array of [TicketResponse] objects
|
||||||
/// - `500 Internal Server Error` if database query fails
|
/// - `500 Internal Server Error` if database query fails
|
||||||
///
|
///
|
||||||
/// # Example Response
|
/// # Example Response
|
||||||
@@ -174,7 +173,7 @@ pub async fn get_tickets(
|
|||||||
/// - `id`: Ticket ID to retrieve
|
/// - `id`: Ticket ID to retrieve
|
||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
/// - `200 OK` with TicketResponse object
|
/// - `200 OK` with [TicketResponse] object
|
||||||
/// - `404 Not Found` if ticket doesn't exist
|
/// - `404 Not Found` if ticket doesn't exist
|
||||||
/// - `500 Internal Server Error` if database error occurs
|
/// - `500 Internal Server Error` if database error occurs
|
||||||
///
|
///
|
||||||
@@ -247,10 +246,10 @@ pub async fn get_ticket_by_id(
|
|||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
/// - `id`: Ticket ID to update
|
/// - `id`: Ticket ID to update
|
||||||
/// - `body`: Update payload containing new status
|
/// - `body`: Update payload as a Json array with [TicketUpdateScheme] as it's format
|
||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
/// - `200 OK` with updated TicketResponse
|
/// - `200 OK` with updated [TicketResponse]
|
||||||
/// - `500 Internal Server Error` if ticket not found or database error
|
/// - `500 Internal Server Error` if ticket not found or database error
|
||||||
///
|
///
|
||||||
/// # Typical Status Flow
|
/// # Typical Status Flow
|
||||||
|
|||||||
@@ -29,18 +29,28 @@ use tower_http::cors::CorsLayer;
|
|||||||
|
|
||||||
use crate::env::Env;
|
use crate::env::Env;
|
||||||
|
|
||||||
|
/// A variable to count the problems fixed by a very easy solution
|
||||||
static EASY_FIX_COUNT: AtomicI64 = AtomicI64::new(0);
|
static EASY_FIX_COUNT: AtomicI64 = AtomicI64::new(0);
|
||||||
|
|
||||||
|
/// The Response struct for the [EASY_FIX_COUNT]
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
struct CounterResp {
|
struct CounterResp {
|
||||||
value: i64,
|
value: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets the [EASY_FIX_COUNT] value
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
/// - `200 OK` with the value on success
|
||||||
async fn get_count() -> Json<CounterResp> {
|
async fn get_count() -> Json<CounterResp> {
|
||||||
let v = EASY_FIX_COUNT.load(Ordering::SeqCst);
|
let v = EASY_FIX_COUNT.load(Ordering::SeqCst);
|
||||||
Json(CounterResp { value: v })
|
Json(CounterResp { value: v })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Incremets the [EASY_FIX_COUNT] value by one
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
/// - `200 OK` with the new value on success
|
||||||
async fn increment() -> Result<Json<CounterResp>, StatusCode> {
|
async fn increment() -> Result<Json<CounterResp>, StatusCode> {
|
||||||
let new = EASY_FIX_COUNT.fetch_add(1, Ordering::SeqCst) + 1;
|
let new = EASY_FIX_COUNT.fetch_add(1, Ordering::SeqCst) + 1;
|
||||||
Ok(Json(CounterResp { value: new }))
|
Ok(Json(CounterResp { value: new }))
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ fn sidebar_shell(props: &SidebarShellProps) -> Html {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Props for the AdminCheckWrapper component.
|
/// Props for the [AdminCheckWrapper] component.
|
||||||
#[derive(Properties, PartialEq)]
|
#[derive(Properties, PartialEq)]
|
||||||
pub struct AdminCheckWrapperProps {
|
pub struct AdminCheckWrapperProps {
|
||||||
pub children: Children,
|
pub children: Children,
|
||||||
@@ -166,7 +166,7 @@ fn admin_check_wrapper(props: &AdminCheckWrapperProps) -> Html {
|
|||||||
|
|
||||||
/// The main routing logic for the application.
|
/// The main routing logic for the application.
|
||||||
///
|
///
|
||||||
/// This function takes a `Route` enum variant and returns the corresponding HTML
|
/// This function takes a [Route] enum variant and returns the corresponding HTML
|
||||||
/// content to be rendered. It acts as a central dispatcher for the application's
|
/// content to be rendered. It acts as a central dispatcher for the application's
|
||||||
/// navigation.
|
/// navigation.
|
||||||
///
|
///
|
||||||
@@ -259,12 +259,12 @@ fn switch(route: Route) -> Html {
|
|||||||
/// The root component of the Yew application.
|
/// The root component of the Yew application.
|
||||||
///
|
///
|
||||||
/// This component sets up the application's routing using `yew-router`'s
|
/// This component sets up the application's routing using `yew-router`'s
|
||||||
/// [`BrowserRouter`] and [`Switch`] components. All other application content
|
/// `BrowserRouter` and `Switch` components. All other application content
|
||||||
/// is rendered based on the current route.
|
/// is rendered based on the current route.
|
||||||
///
|
///
|
||||||
/// # Structure
|
/// # Structure
|
||||||
/// - [`BrowserRouter`]: Enables client-side routing.
|
/// - `BrowserRouter`: Enables client-side routing.
|
||||||
/// - [`Switch`]: Renders components based on the matched [`Route`].
|
/// - `Switch`: Renders components based on the matched [Route].
|
||||||
#[component(App)]
|
#[component(App)]
|
||||||
pub fn app() -> Html {
|
pub fn app() -> Html {
|
||||||
html! {
|
html! {
|
||||||
|
|||||||
@@ -97,10 +97,6 @@ pub fn not_found_component() -> Html {
|
|||||||
|
|
||||||
/// A component displayed when a user attempts to access a page for which they do not have sufficient permissions.
|
/// A component displayed when a user attempts to access a page for which they do not have sufficient permissions.
|
||||||
///
|
///
|
||||||
/// It informs the user about the access restriction and provides instructions to contact
|
|
||||||
/// a specific person ("Herr Winter") if they believe this is an error.
|
|
||||||
/// It also includes a link to return to the home page.
|
|
||||||
///
|
|
||||||
/// # Example
|
/// # Example
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// html! {
|
/// html! {
|
||||||
|
|||||||
Reference in New Issue
Block a user