--- source_files: - DataPRO/DbAPI/User/User.cs generated_at: "2026-04-16T04:25:44.390617+00:00" model: "Qwen/Qwen3-Coder-Next-FP8" schema_version: 1 sha256: "e2da1167bdd7ae60" --- # User ## Documentation: `DbAPI.User.User` Class ### 1. Purpose This module provides a concrete, internal implementation of the `IUserDbRecord` interface (which itself implements `IUser`) for representing user records retrieved from the database. It encapsulates user data fields (e.g., ID, credentials, role, metadata) and exposes a static factory method (`GetUser`) to fetch a user record by username via stored procedures. Its role is to act as a data carrier between the database layer and higher-level authentication or user management logic, ensuring structured access to user information while abstracting SQL interaction details. ### 2. Public Interface *Note: The class is `internal`, so its members are not part of the public API surface of the `DbAPI.User` namespace, but they are documented per requirements.* - **`User` Constructor** ```csharp internal User(int id, string user, string display, string pwd, short role, DateTime lastModified, string lastModifiedBy, bool local) ``` Initializes a new `User` instance with all required field values. Parameters map directly to the public properties. - **`GetUser` Static Method** ```csharp internal static ulong GetUser(IConnectionDetails connection, out IUserDbRecord usr, string userName) ``` Retrieves a user record from the database by `userName`. Executes two stored procedures sequentially: 1. `sp_UsersGetId` to resolve the user ID from the username (output parameter `@UserId`). 2. `sp_UsersGet` to fetch full user details using the resolved ID. On success, populates `usr` with a new `User` instance and returns `ERROR_SUCCESS` (`0`). On failure, returns an error code (e.g., `ERROR_LOGINFAILED`, `ERROR_ACCESS_DENIED`, `ERROR_UNKNOWN`) and sets `usr` to `null`. **Properties of `usr` are populated using `Utility` helper methods** (e.g., `Utility.GetInt`, `Utility.GetString`, etc.), which handle `DBNull` and type conversion. ### 3. Invariants - **`ID` must be a positive integer** (validated in `GetUser`: `if (0 >= id) { return ERROR_LOGINFAILED; }`). - **`UserName`, `DisplayName`, `Password`, `LastModifiedBy` must be non-null strings** (assigned via `Utility.GetString`, which likely returns `string.Empty` on `DBNull`; source does not confirm null-safety, but assignment occurs unconditionally). - **`LastModified` defaults to `DateTime.MinValue` if `DBNull`** (handled by `Utility.GetDateTime(..., DateTime.MinValue)`). - **`Role` is a `short`** (no explicit range validation in code; assumed to be domain-constrained by application logic). - **`LocalOnly` is a boolean** (assigned via `Utility.GetBool`, implying strict `true`/`false` mapping). - **Database connection is disposed after use** (ensured by `finally { cmd.Connection.Dispose(); }`). - **Stored procedure names are fixed**: `sp_UsersGetId` (ID lookup), `sp_UsersGet` (full record fetch). ### 4. Dependencies - **Imports/Usings**: - `DbAPI.Connections` → Provides `IConnectionDetails`, `ConnectionManager`, and `Errors.ErrorCodes`. - `DTS.Common.Classes` → Likely contains `Utility` (used for type-safe data extraction). - `DTS.Common.Interface.Database` → Defines `IUserDbRecord` (implemented by `User`). - `System.Data`, `System.Data.SqlClient` → For `SqlDbType`, `CommandType`, `SqlParameter`, `IDataReader`. - **External Dependencies**: - SQL Server database with stored procedures: `sp_UsersGetId` (input: `@UserName NVARCHAR(255)`, output: `@UserId INT`) and `sp_UsersGet` (input: `@UserId INT`). - `ConnectionManager.GetSqlCommand` must return `ERROR_SUCCESS` for valid connections. - **Depended Upon**: - `IUserDbRecord` interface (consumed by callers of `GetUser`). - Likely used by authentication modules (e.g., login workflows) that require user record resolution. ### 5. Gotchas - **Password stored in plaintext**: The `Password` property is directly assigned from the database (`var password = Utility.GetString(reader, "password");`). No hashing or encryption handling is evident—this may indicate legacy security practices. - **Two-step database round-trips**: `GetUser` executes *two* stored procedures (ID lookup → full record fetch), which could be optimized into one query. - **`reader.Close()` before reusing `cmd`**: The `SqlDataReader` is closed before resetting `cmd.CommandText` and parameters. This is safe but non-idiomatic; `using` blocks would improve robustness. - **No validation of `userName` input**: Empty or null `userName` may cause unexpected behavior (e.g., SQL injection risk if `ConnectionManager` does not sanitize parameters). - **`ERROR_ACCESS_DENIED` returned for `GetSqlCommand` failure**: This error code is misleading—it suggests authentication failure, but it may also indicate connection configuration issues. - **`IUserDbRecord` interface is not defined here**: Behavior of `IUser`/`IUserDbRecord` members (e.g., `ID`, `UserName`) is assumed from implementation but not verified in this file. - **`Utility` methods behavior is inferred**: Assumptions about `Utility.GetString` returning `string.Empty` on `DBNull` are not confirmed by this source. *None identified from source alone.*