Authorize a user for a policy¶
Decides whether the current user may view a policy, applying a different authorization strategy per user type: unconditional access for internal roles, agent/agency number match, policyholder parent-affiliation match, group/chapter membership, loss-control assignment match, or auditor access-window check.
| Field | Value |
|---|---|
| Operation ID | op-07-authorize-user |
| Trigger | Caller invokes clsPolicySecurity.IsPolicyValidForUser(inPolicyData) (or the policy-number overload, which retrieves the policy first) |
| Inputs | clsPolicyData (or policy number), current UserType/SecurityPrincipal |
| Outputs | Boolean |
| Primary components | IsPolicyValidForUser, IsPolicyValidForParentPolicy, IsInGroup, CanAuditorAccessPolicy, CanSafetyConsultantAccessPolicy |
| Entry point | SAIF.Business.View.Policy/clsPolicySecurity.vb |
Steps¶
IsPolicyValidForUser(inPolicyData)first checks the secure-policy carve-out: ifinPolicyData.SecurePolicyCode = clsConstants.SAIFand the security principal is not authorized for"SAIFpolicyInfo", access is denied immediately (BR-VP-003).- If
Not inPolicyData.IsValidorinPolicyData.PolicyNum = 0, access is denied immediately (BR-VP-004). - Otherwise, a
Select CaseonUserType.UserTypedecides access (BR-VP-005): SaifEmployee,MCO,MedProv,Bookkeeper→ access granted unconditionally.Agent→ access granted ifUserType.UserNumberequalsinPolicyData.AgentNumorinPolicyData.Agency.AgencySeqNum.PolicyHolder→ delegates entirely toIsPolicyValidForParentPolicy(inPolicyData.PolicyNum)(BR-VP-009) — a comment notes this replaced an earlier direct-number/affiliate-list check.Group→ delegates toIsInGroup(inPolicyData.PolicyNum, UserType.GroupID, UserType.GroupChapterID).LossControl→ looks up theLossControlConsultantteam assignment oninPolicyData.TeamAssignmentCollection; if present, compares eitherta.UserIdName(forDemoLossControlaccess level) orta.UserNameagainst the current user number viaCanSafetyConsultantAccessPolicy(BR-VP-007, BR-VP-008).Auditor→ delegates toCanAuditorAccessPolicy(inPolicyData.PolicyNum, UserType.UserNumber).IsPolicyValidForParentPolicy(inPolicyNum): if the user's own number equals the requested policy number, returnsTruedirectly; otherwise builds the set ofAssociationTypesfor which the logged-in user's own policy (UsersPolicyData) is a parent, and returnsTrueif any of the user's associations of those types point atinPolicyNum.IsInGroupexecutescp_policy_in_group(SQL-023) as a scalar stored-procedure query on the SQL Server (BDS) data portal, binding@groupID,@Chapters,@policyNum; returnsTrueif the count is greater than zero.CanAuditorAccessPolicyexecutes an inlinepa_audit/pa_auditor/pa_policy_periodcount query (SQL-024) on Oracle, binding the vendor number and a 60-day access window (DPI.DataSourceDate.AddDays(-60)) against both cancel date and completed date (BR-VP-006); returnsTrueif the count is greater than zero.CanSafetyConsultantAccessPolicystrips any"%"-delimited suffix from the current user's number and checks whether the team-assignment user name, trimmed and upper-cased, starts with that prefix (BR-VP-007).- The obsolete
SQL-013/GetParentPolicylookup (SQL-013) is cited by the hub catalog against this operation but its call site was found in the affiliated-policy legacy path (see Retrieve affiliated policies (legacy)), not inIsPolicyValidForParentPolicyitself.*
Process flow¶
flowchart TD
Start(["Caller invokes<br>IsPolicyValidForUser"]) --> A{Secure policy and<br>not SAIFpolicyInfo authorized?}
A -->|Yes| Deny(["Access denied"])
A -->|No| B{Invalid or<br>zero policy num?}
B -->|Yes| Deny
B -->|No| C{User type?}
C -->|SaifEmployee/MCO/MedProv/Bookkeeper| Grant(["Access granted"])
C -->|Agent| D{Agent/agency<br>number matches?}
D -->|Yes| Grant
D -->|No| Deny
C -->|PolicyHolder| E["IsPolicyValidForParentPolicy"]
E --> F{Match found?}
F -->|Yes| Grant
F -->|No| Deny
C -->|Group| G["IsInGroup:<br>cp_policy_in_group"]
G --> Grant
C -->|LossControl| H["Team assignment lookup +<br>CanSafetyConsultantAccessPolicy"]
H --> Grant
C -->|Auditor| I["CanAuditorAccessPolicy:<br>60-day audit window"]
I --> Grant
Failure and edge-case behavior¶
- No exception is thrown on denial in any branch; the method always returns
Boolean, and nothing in this library logs denied-access attempts.* LossControlaccess silently returnsFalse(falls through withhasAccessunset/False) if noLossControlConsultantteam assignment exists on the policy — indistinguishable from an explicit denial.*IsInGrouprelies on the BDS (SQL Server) data portal initialized inclsPolicySecurity.Initialize(); ifBDS_USER,bdsDatabase, orBDS_DATABASENAMEconfiguration is missing or wrong,Initialize()still succeeds and the failure surfaces only whenIsInGroupexecutes.*
Note: Statements marked with * were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts. Statements marked with ** could not be confirmed; treat as unknown until verified.
Related documentation¶
Sources¶
SAIF.Business.View.Policy/clsPolicySecurity.vb