Class ApprovalPolicy

java.lang.Object
io.jenkins.plugins.batchcontrol.policy.ApprovalPolicy

@Restricted(org.kohsuke.accmod.restrictions.NoExternalUse.class) public final class ApprovalPolicy extends Object
Approver eligibility rules (SPEC items 2 and 3), shared by RunRequestService and GrantRequestService. Two different failure families are used on purpose:
  • IllegalArgumentException for designation-time validation (bad input on request creation or approver change);
  • AccessDeniedException for decision-time refusals (the caller may not decide this request), which the web layer surfaces as 403.
  • Method Summary

    Modifier and Type
    Method
    Description
    static boolean
    Whether the current caller is an administrator (Overall/Administer).
    static boolean
    D-38b: whether the current caller is requester and holds BatchControl/Request on the item fullName (inherited from a folder or from Jenkins, as Jenkins' ACL resolves it).
    static boolean
    Checks that the current caller may decide (approve/reject) the given request (SPEC item 3: list membership AND the Approve permission at decision time, SPEC item 2: admin self-approval policy, D-37: any member of the designated set).
    static boolean
    checkDecision(String requestId, String requester, List<String> designatedApprovers)
    Request-type-agnostic decision check, shared by run requests and grant requests (SPEC item 8 reuses the SPEC item 3 approver rules).
    static void
    checkDesignation(String requester, String approver, Job<?,?> job)
    Validates a single-approver designation (pre D-37 form).
    static List<String>
    checkDesignation(String requester, List<String> approvers, Job<?,?> job)
    Validates an approver-set designation at creation / change time (SPEC item 3, D-37): at least one approver, and every member is on the global list, allowed by the job-level restriction and not the requester (administrator exception per the self-approval policy).
    static boolean
    checkJobDecision(String requestId, String requester, List<String> designatedApprovers, String jobFullName)
    The decision check of a request whose subject is one job (run and activation requests, SPEC items 3 and 6a): checkDecision(String, String, List) plus the job's own approver list in force at decision time.
    static boolean
    Whether the user id is on the global approver list.
    static Item
    As jobForPolicy(String) for any item (an activation request's subject may be a computed folder, D-46).
    static List<String>
    The job-level approver restriction, or an empty list when the job does not narrow it.
    static Job<?,?>
    jobForPolicy(String jobFullName)
    Resolves the job a request targets, for applying its approver policy (security-08 S-11).

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Method Details

    • isListedApprover

      public static boolean isListedApprover(String userId)
      Whether the user id is on the global approver list.
    • jobApproverRestriction

      public static List<String> jobApproverRestriction(Job<?,?> job)
      The job-level approver restriction, or an empty list when the job does not narrow it.
    • jobForPolicy

      public static Job<?,?> jobForPolicy(String jobFullName)
      Resolves the job a request targets, for applying its approver policy (security-08 S-11). Callers must have finished their own permission checks first (requester identity for a designation change, designated membership plus Approve for a decision).

      ACL.SYSTEM2 switch, with its reason: the job's own approver list must bind the designation and the decision even when the acting user cannot read the job (a requester who lost Item/Read would otherwise get null and skip jobApprovers). The lookup only reads the job's property; nothing is done on the job as SYSTEM.

    • itemForPolicy

      public static Item itemForPolicy(String fullName)
      As jobForPolicy(String) for any item (an activation request's subject may be a computed folder, D-46). Same SYSTEM switch and the same precondition: the caller's permission checks are complete, and the item is only looked up, never acted on.
    • callerIsRequesterWithRequest

      public static boolean callerIsRequesterWithRequest(String requester, String fullName)
      D-38b: whether the current caller is requester and holds BatchControl/Request on the item fullName (inherited from a folder or from Jenkins, as Jenkins' ACL resolves it). This is the requester's right to cancel or re-designate their own request; Jenkins-level Request is no longer required. When the item no longer exists, Jenkins-level Request decides.

      The requester identity is checked first; only then is the item looked up through itemForPolicy(String) (a SYSTEM lookup, so a requester who lost Item/Read is judged on Request alone), and the permission is evaluated for the caller's own authentication, never as SYSTEM.

    • callerIsAdmin

      public static boolean callerIsAdmin()
      Whether the current caller is an administrator (Overall/Administer).
    • checkDesignation

      public static void checkDesignation(String requester, String approver, Job<?,?> job)
      Validates a single-approver designation (pre D-37 form).
      See Also:
    • checkDesignation

      public static List<String> checkDesignation(String requester, List<String> approvers, Job<?,?> job)
      Validates an approver-set designation at creation / change time (SPEC item 3, D-37): at least one approver, and every member is on the global list, allowed by the job-level restriction and not the requester (administrator exception per the self-approval policy).
      Parameters:
      requester - the requesting user id (the current caller)
      approvers - the designated approver ids
      job - the target job, used for the optional job-level approver restriction
      Returns:
      the normalized set (trimmed, de-duplicated, designation order)
      Throws:
      IllegalArgumentException - if the designation violates the policy
    • checkDecision

      public static boolean checkDecision(RunRequest request)
      Checks that the current caller may decide (approve/reject) the given request (SPEC item 3: list membership AND the Approve permission at decision time, SPEC item 2: admin self-approval policy, D-37: any member of the designated set).
      Returns:
      true when this decision is a self-approval (requester == decider)
      Throws:
      org.springframework.security.access.AccessDeniedException - if the caller may not decide the request
    • checkJobDecision

      public static boolean checkJobDecision(String requestId, String requester, List<String> designatedApprovers, String jobFullName)
      The decision check of a request whose subject is one job (run and activation requests, SPEC items 3 and 6a): checkDecision(String, String, List) plus the job's own approver list in force at decision time.
      Returns:
      true when this decision is a self-approval (requester == decider)
      Throws:
      org.springframework.security.access.AccessDeniedException - if the caller may not decide the request
    • checkDecision

      public static boolean checkDecision(String requestId, String requester, List<String> designatedApprovers)
      Request-type-agnostic decision check, shared by run requests and grant requests (SPEC item 8 reuses the SPEC item 3 approver rules). The caller must be a member of the designated set (D-29 exclusivity applied to the set, D-37); the permission, list and self-approval checks apply to the deciding user.
      Parameters:
      requestId - the request id (for error messages only)
      requester - the request's requester id
      designatedApprovers - the request's currently designated approver set
      Returns:
      true when this decision is a self-approval (requester == decider)
      Throws:
      org.springframework.security.access.AccessDeniedException - if the caller may not decide the request