Class Visibility

java.lang.Object
io.jenkins.plugins.batchcontrol.ui.Visibility

@Restricted(org.kohsuke.accmod.restrictions.NoExternalUse.class) public final class Visibility extends Object
Per-object visibility predicates for the request and grant screens (P-09, security review S-01). The section gates stay coarse; these predicates decide which rows a caller may see, and the SAME predicate gates the detail URL, so list and detail can never diverge. A non-visible object renders exactly like a nonexistent one (404) to hide its existence.

Read-only: only public model getters, findVisibleJob(java.lang.String) / findVisibleItem(java.lang.String) and hasPermission are used. State-changing endpoints keep their own permission checks — nothing here replaces them.

  • Method Summary

    Modifier and Type
    Method
    Description
    static boolean
    An activation or hold request is visible iff the caller has Manage, or is the requester or a member of the designated approver set (P-09, SPEC item 6a).
    static boolean
    An active grant is visible iff the caller has Manage, or the grant is their own.
    static boolean
    A grant request is visible iff the caller has Manage, or is the requester or a member of the designated approver set (D-37).
    static boolean
    A run request is visible iff the caller has Manage (or Overall/Administer), OR is the requester, OR is a member of the designated approver set (D-37), OR holds Item/Read on the target job.
    static Item
    The Item form of findVisibleJob(java.lang.String), for call sites that accept folders too.
    static Job<?,?>
    Resolves a job by full name for display purposes, treating "the caller may not see it" exactly like "it does not exist" (S-16).
    static String
    runUrl(String jobFullName, int number)
    The one run-link rule of every Batch Control screen (D-44): a run links to its build page only when the viewer holds Item/Read on the job; otherwise the view renders the run as plain text, and a build that has been deleted since is plain text too (e2e-03 DEF-23).
    static String
    runUrl(String, int) for a stored run id of the form jobFullName#number.

    Methods inherited from class java.lang.Object

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

    • findVisibleJob

      @CheckForNull public static Job<?,?> findVisibleJob(@CheckForNull String fullName)
      Resolves a job by full name for display purposes, treating "the caller may not see it" exactly like "it does not exist" (S-16).

      Jenkins.getItemByFullName is permission-aware but it does not report an invisible item by returning null: when the caller holds Item/Discover and not Item/Read, core throws AccessDeniedException (that is how Item/Discover is specified — "the item exists, log in to see it"). Only a caller with neither permission gets null.

      Letting that exception escape a Jelly-facing getter is worse than a 403: Jenkins' JEXL evaluator catches it and resolves the whole expression to null, so the page still answers HTTP 200 while the row list comes back empty and the record count renders as a blank. One request filed against a discover-only job then wipes out every other row on /batch-control/requests/, including the caller's own, and nothing anywhere tells the caller that anything was withheld. A user who cannot see their own request concludes it was never filed.

      So every display-time lookup funnels through here instead, and a discover-only job is treated exactly like an invisible or deleted one: that row drops out and the rest of the screen renders normally. The disclosure boundary is unchanged — nothing is shown that Item/Read would not have shown — and the side effect of the old behaviour (roughly 190 log lines per swallowed lookup) disappears with it.

      Parameters:
      fullName - the job's full name as stored on the record, possibly null
      Returns:
      the job, or null when it does not exist, is not a Job, or is not visible to the caller
    • findVisibleItem

      @CheckForNull public static Item findVisibleItem(@CheckForNull String fullName)
      The Item form of findVisibleJob(java.lang.String), for call sites that accept folders too.
      Parameters:
      fullName - the item's full name, possibly null
      Returns:
      the item, or null when it does not exist or is not visible to the caller
    • runUrl

      @CheckForNull public static String runUrl(@CheckForNull String jobFullName, int number)
      The one run-link rule of every Batch Control screen (D-44): a run links to its build page only when the viewer holds Item/Read on the job; otherwise the view renders the run as plain text, and a build that has been deleted since is plain text too (e2e-03 DEF-23). The history screens follow it too: they stay outside the P-09 record-visibility boundary (S-12, every ViewHistory holder sees every row), but a link to a job the viewer cannot read would only advertise the job's URL and answer 404.
      Returns:
      the root-relative build URL, the run's own Run.getUrl() (job/a/job/b/12/, job/mx/X=a/1/ for a matrix configuration), or null for plain text
    • runUrlFromRunId

      @CheckForNull public static String runUrlFromRunId(@CheckForNull String runId)
      runUrl(String, int) for a stored run id of the form jobFullName#number.
      Returns:
      the root-relative build URL, or null when the id is malformed or the viewer may not read the job (the view then renders the id as plain text)
    • canSeeRunRequest

      public static boolean canSeeRunRequest(RunRequest request)
      A run request is visible iff the caller has Manage (or Overall/Administer), OR is the requester, OR is a member of the designated approver set (D-37), OR holds Item/Read on the target job. When the job no longer exists — or is invisible to the caller, including the discover-only case handled by findVisibleJob(java.lang.String) — only requester/approver/Manage still see it.
    • canSeeGrantRequest

      public static boolean canSeeGrantRequest(GrantRequest request)
      A grant request is visible iff the caller has Manage, or is the requester or a member of the designated approver set (D-37).
    • canSeeActivationRequest

      public static boolean canSeeActivationRequest(ActivationRequest request)
      An activation or hold request is visible iff the caller has Manage, or is the requester or a member of the designated approver set (P-09, SPEC item 6a). Unlike a run request, Item/Read on the job does not make it visible: the request carries the approver set and the reason, which the job page does not otherwise disclose.
    • canSeeGrant

      public static boolean canSeeGrant(Grant grant)
      An active grant is visible iff the caller has Manage, or the grant is their own.