Security role assignment¶
AppManagerBase reduces application-level authorization to a single enum value, AppSecurityRole, and derives every caller-visible accessibility flag from that one value. A subclass's OnCheckSecurity() hook (declared MustOverride, implemented by consuming application managers) is the expected place to evaluate whatever criteria the application uses and then call one of the three role-setting methods.
| Field | Value |
|---|---|
| Operation ID | OP-APP-02 |
| Trigger | Subclass OnCheckSecurity() implementation (or any other subclass code) calls MarkUpdate(), MarkViewOnly(), or MarkNoAccess() |
| Inputs | Whatever caller/application state the subclass's security evaluation logic examines (not part of this library) |
| Outputs | Updated m_AppSecurityRole value; derived SecurityRole, IsAccessible, IsUpdateable, IsViewOnly, IsRestricted property values |
| Primary components | AppManagerBase.MarkUpdate, AppManagerBase.MarkViewOnly, AppManagerBase.MarkNoAccess, AppManagerBase.SecurityRole, AppManagerBase.IsAccessible, AppManagerBase.IsUpdateable, AppManagerBase.IsViewOnly, AppManagerBase.IsRestricted |
| Entry point | Application\SAIF.Application\AppManagerBase.vb |
Steps¶
- Manager starts with no access. The private field
m_AppSecurityRoleis initialized toAppSecurityRole.NoAccessat declaration, so any manager instance is restricted by default until its security evaluation explicitly grants a different role (BR-001). - Subclass evaluates security state. The subclass's
OnCheckSecurity()override runs whatever caller/context checks the consuming application requires (for example, comparing anAppSecurityRolederived from an AD group lookup or resource check performed via AD resource access check (cached)). - This step may embed a call into
UserAccess.HasAccess(...)to decide which role to assign; see that operation's own steps for how the underlying authorization decision is made and cached. - Assign exactly one role. The subclass calls exactly one of:
MarkUpdate()— setsm_AppSecurityRole = AppSecurityRole.Update.MarkViewOnly()— setsm_AppSecurityRole = AppSecurityRole.ViewOnly.MarkNoAccess()— setsm_AppSecurityRole = AppSecurityRole.NoAccess.- Each method unconditionally overwrites
m_AppSecurityRolewith no validation of the prior value, so calling more than one in sequence simply leaves the role at whichever was called last (BR-001). - Derive read-only accessibility flags. Callers read any of the following properties, each of which recomputes its result from the single
m_AppSecurityRolevalue on every access (no caching): SecurityRolereturnsm_AppSecurityRoledirectly.IsAccessiblereturnsTruewhenSecurityRole <> AppSecurityRole.NoAccess.IsRestrictedreturnsTruewhenSecurityRole = AppSecurityRole.NoAccess.IsUpdateablereturnsTruewhenSecurityRole = AppSecurityRole.Update.IsViewOnlyreturnsTruewhenSecurityRole = AppSecurityRole.ViewOnly.- Because these are simple derivations of one field,
IsAccessibleandIsRestrictedare always complements of each other, and exactly one ofIsUpdateable/IsViewOnly/IsRestrictedisTrueat any time (BR-001).
Process flow¶
The following diagram visualizes how a role assignment call updates the derived accessibility flags.
flowchart TD
Start([Subclass OnCheckSecurity runs]) --> Eval[Evaluate caller / application state]
Eval --> Which{Which role applies?}
Which -->|Full access| MarkUpdate[MarkUpdate sets Update]
Which -->|Read only| MarkViewOnly[MarkViewOnly sets ViewOnly]
Which -->|No access| MarkNoAccess[MarkNoAccess sets NoAccess]
MarkUpdate --> Derive[Callers read SecurityRole,<br>IsAccessible, IsUpdateable,<br>IsViewOnly, IsRestricted]
MarkViewOnly --> Derive
MarkNoAccess --> Derive
Derive --> End([Caller adjusts UI / logic<br>based on flags])
Failure and edge-case behavior¶
AppManagerBasenever callsOnCheckSecurity()itself in the code shown in this library — it is aMustOverridehook that the consuming application is responsible for invoking at the appropriate point in its own lifecycle; if a subclass never calls it (or never calls one of theMark*methods), the manager remains at the defaultNoAccessrole (BR-001).- Calling more than one
Mark*method leaves the role at the last call; there is no guard against contradictory sequential assignment within a single evaluation.* - No event or notification is raised when the role changes; callers must re-read the accessibility properties after each
OnCheckSecurity()cycle to see updated values.*
Note: Statements marked with
*were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts.
Related documentation¶
Sources¶
Application\SAIF.Application\AppManagerBase.vbApplication\SAIF.Application\Enums.vb