Skip to content

Authorize a policy for the current user

This is the authorization heart of the library. Every consuming application relies on it to decide whether the signed-in user may see a given policy, and the answer depends on both the policy (is it a SAIF-secured policy?) and the user (an agent, a policyholder, a group administrator, a loss-control consultant, a fee auditor, or SAIF staff). The evaluation is ordered so that the hard denials happen before any user-type reasoning, and it fails closed when nothing matches.

Field Value
Operation ID OP-06
Trigger A consumer asks whether the current principal may see a policy
Inputs A clsSecurityPrincipal and IDataPortalInfo supplied to the constructor, plus the target policy or policy number
Outputs A boolean access decision
Primary components clsPolicySecurity.IsPolicyValidForUser
Entry point Business/SAIF.Business.View.Policy/clsPolicySecurity.vb

Steps

  1. On construction, read the BDS_USER, bdsDatabase, and BDS_DATABASENAME settings and build a second, SQL Server data portal for the group-membership store.
  2. Missing or wrong settings are not detected here; the failure appears when the group branch first executes.**
  3. See Configuration for the settings and their risks.
  4. Classify the principal into a user type — SAIF employee, agent, policyholder, group, loss control, auditor, MCO, medical provider, or bookkeeper.
  5. The classification is performed by clsUserType from the SAIF.BOF.Business package; its internal steps are not visible in this repository.**
  6. If the policy's secure-policy code marks it as a SAIF-secured policy and the principal does not hold the SAIFpolicyInfo authorization, refuse immediately (BR-001).
  7. This check runs before all others, so no user type can bypass it.
  8. If the policy is invalid or its policy number is zero, refuse (BR-002).
  9. The policy header must have loaded successfully first (Retrieve policy header, SQL-007).
  10. Branch on the user type and evaluate the matching rule:
  11. SAIF employees, MCO users, medical providers, and bookkeepers are allowed (BR-003).
  12. An agent is allowed when the trimmed user number matches the policy's agent number or agency sequence number (BR-004).
  13. A policyholder is allowed when the target is their own policy or shares a parent association with it (BR-005); this loads the user's own policy (Retrieve policy header) and its associations (Resolve policy associations, SQL-026).
  14. A group user is allowed when the group-membership procedure cp_policy_in_group returns a count greater than zero for the group, chapter, and policy (BR-006).
  15. A loss-control user is allowed when the policy's loss-control team assignment name starts with their identifier (BR-007, SQL-009); demo users are matched on the assignment's user-id name instead.
  16. An auditor is allowed when a current, non-cancelled audit exists for the policy under their vendor number (BR-008, PA_AUDIT).
  17. Return the accumulated decision. A user type that matched no branch leaves the decision at its initial refusal (BR-019).

Process flow

The following diagram visualizes this operation's control flow.

flowchart TD
    Start([Access decision requested]) --> Init[Build the group-membership<br>data portal from settings]
    Init --> UT[Classify the principal]
    UT --> Sec{Secure policy without<br>SAIFpolicyInfo?}
    Sec -->|Yes| Deny([Refuse])
    Sec -->|No| Val{Policy valid and<br>numbered?}
    Val -->|No| Deny
    Val -->|Yes| Br{User type}
    Br -->|SAIF, MCO, provider, bookkeeper| Allow([Allow])
    Br -->|Agent| A1{Agent or agency<br>number matches?}
    Br -->|Policyholder| A2{Same policy or<br>shared parent?}
    Br -->|Group| A3{In group or chapter?}
    Br -->|Loss control| A4{Assignment name<br>prefix matches?}
    Br -->|Auditor| A5{Current audit exists?}
    Br -->|Unmatched| Deny
    A1 -->|Yes| Allow
    A1 -->|No| Deny
    A2 -->|Yes| Allow
    A2 -->|No| Deny
    A3 -->|Yes| Allow
    A3 -->|No| Deny
    A4 -->|Yes| Allow
    A4 -->|No| Deny
    A5 -->|Yes| Allow
    A5 -->|No| Deny

Failure and edge-case behavior

  • An unmatched user type is refused rather than allowed, so the operation fails closed (BR-019).
  • A policy with no loss-control team assignment stays inaccessible to loss-control users (BR-007).
  • A misconfigured group-membership store surfaces only when a group user is evaluated.**
  • The policyholder branch performs additional reads, so it is materially more expensive than the other branches.

Note: Statements marked with † are derived from dependency library documentation via the Legends CLI. Statements marked with * were inferred from code structure or contextual evidence. Statements marked with ** could not be confirmed; treat as unknown until verified.

Sources

  • Business/SAIF.Business.View.Policy/clsPolicySecurity.vb
  • Business/SAIF.Business.View.Policy/clsPolicyData.vb