Java Code Examples for hudson.security.ACL#impersonate()

The following examples show how to use hudson.security.ACL#impersonate() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: CLICommandInvoker.java    From jenkins-test-harness with MIT License 6 votes vote down vote up
private void setAuth() {

        if (permissions.isEmpty()) return;

        JenkinsRule.DummySecurityRealm realm = rule.createDummySecurityRealm();
        realm.addGroups(username, "group");

        originalSecurityRealm = rule.jenkins.getSecurityRealm();
        rule.jenkins.setSecurityRealm(realm);

        originalAuthorizationStrategy = rule.jenkins.getAuthorizationStrategy();
        rule.jenkins.setAuthorizationStrategy(new GrantPermissions(username, permissions));

        command.setTransportAuth(user().impersonate());
        // Otherwise it is SYSTEM, which would be relevant for a command overriding main:
        originalSecurityContext = ACL.impersonate(Jenkins.ANONYMOUS);
    }
 
Example 2
Source File: HudsonTestCase.java    From jenkins-test-harness with MIT License 6 votes vote down vote up
@Override
protected void runTest() throws Throwable {
    System.out.println("=== Starting "+ getClass().getSimpleName() + "." + getName());
    // so that test code has all the access to the system
    ACL.impersonate(ACL.SYSTEM);

    try {
        super.runTest();
    } catch (Throwable t) {
        // allow the late attachment of a debugger in case of a failure. Useful
        // for diagnosing a rare failure
        try {
            throw new BreakException();
        } catch (BreakException e) {}

        // dump threads
        ThreadInfo[] threadInfos = Functions.getThreadInfos();
        ThreadGroupMap m = Functions.sortThreadsAndGetGroupMap(threadInfos);
        for (ThreadInfo ti : threadInfos) {
            System.err.println(Functions.dumpThreadInfo(ti, m));
        }
        throw t;
    }
}
 
Example 3
Source File: PushBuildAction.java    From gitlab-plugin with GNU General Public License v2.0 6 votes vote down vote up
public void execute() {
    if (pushHook.getRepository() != null && pushHook.getRepository().getUrl() == null) {
        LOGGER.log(Level.WARNING, "No repository url found.");
        return;
    }

    if (project instanceof Job<?, ?>) {
        ACL.impersonate(ACL.SYSTEM, new TriggerNotifier(project, secretToken, Jenkins.getAuthentication()) {
            @Override
            protected void performOnPost(GitLabPushTrigger trigger) {
                trigger.onPost(pushHook);
            }
        });
        throw HttpResponses.ok();
    }
    if (project instanceof SCMSourceOwner) {
        ACL.impersonate(ACL.SYSTEM, new SCMSourceOwnerNotifier());
        throw HttpResponses.ok();
    }
    throw HttpResponses.errorWithoutStack(409, "Push Hook is not supported for this project");
}
 
Example 4
Source File: BuildStatus.java    From jenkins-status-badges-plugin with MIT License 6 votes vote down vote up
public Job<?, ?> getProject( String job, StaplerRequest req, StaplerResponse rsp )
    throws HttpResponses.HttpResponseException
{
    Job<?, ?> p;

    SecurityContext orig = ACL.impersonate( ACL.SYSTEM );
    try
    {
        p = Jenkins.getInstance().getItemByFullName( job, Job.class );
    }
    finally
    {
        SecurityContextHolder.setContext( orig );
    }

    if ( p == null )
    {
        throw org.kohsuke.stapler.HttpResponses.notFound();
    }

    return p;
}
 
Example 5
Source File: JmhBenchmarkState.java    From jenkins-test-harness with MIT License 5 votes vote down vote up
/**
 * Sets up the temporary Jenkins instance for benchmarks.
 * <p>
 * One Jenkins instance is created for each fork of the benchmark.
 *
 * @throws Exception if unable to start the instance.
 */
@Setup(org.openjdk.jmh.annotations.Level.Trial)
public final void setupJenkins() throws Exception {
    // Set the jenkins.install.InstallState TEST to emulate
    // org.jvnet.hudson.test.JenkinsRule behaviour and avoid manual
    // security setup as in a default installation.
    System.setProperty("jenkins.install.state", "TEST");
    launchInstance();
    ACL.impersonate(ACL.SYSTEM);
    setup();
}
 
Example 6
Source File: GHPullRequestSubscriber.java    From github-integration-plugin with MIT License 5 votes vote down vote up
static Set<Job> getPRTriggerJobs(final String repo) {
    final Set<Job> ret = new HashSet<>();

    ACL.impersonate(ACL.SYSTEM, () -> {
        List<Job> jobs = Jenkins.getActiveInstance().getAllItems(Job.class);
        ret.addAll(FluentIterableWrapper.from(jobs)
                .filter(isBuildable())
                .filter(withPRTrigger())
                .filter(withRepo(repo))
                .toSet()
        );
    });

    return ret;
}
 
Example 7
Source File: PipelineBuildAction.java    From gitlab-plugin with GNU General Public License v2.0 5 votes vote down vote up
void execute() {
    if (!(project instanceof Job<?, ?>)) {
        throw HttpResponses.errorWithoutStack(409, "Pipeline Hook is not supported for this project");
    }
    ACL.impersonate(ACL.SYSTEM, new TriggerNotifier(project, secretToken, Jenkins.getAuthentication()) {
        @Override
        protected void performOnPost(GitLabPushTrigger trigger) {
            trigger.onPost(pipelineBuildHook);
        }
    });
    throw HttpResponses.ok();
}
 
Example 8
Source File: NoteBuildAction.java    From gitlab-plugin with GNU General Public License v2.0 5 votes vote down vote up
public void execute(StaplerResponse response) {
    if (!(project instanceof Job<?, ?>)) {
        throw HttpResponses.errorWithoutStack(409, "Note Hook is not supported for this project");
    }
    ACL.impersonate(ACL.SYSTEM, new BuildWebHookAction.TriggerNotifier(project, secretToken, Jenkins.getAuthentication()) {
        @Override
        protected void performOnPost(GitLabPushTrigger trigger) {
            trigger.onPost(noteHook);
        }
    });
    throw HttpResponses.ok();
}
 
Example 9
Source File: MergeRequestBuildAction.java    From gitlab-plugin with GNU General Public License v2.0 5 votes vote down vote up
public void execute() {
    if (!(project instanceof Job<?, ?>)) {
        throw HttpResponses.errorWithoutStack(409, "Merge Request Hook is not supported for this project");
    }
    ACL.impersonate(ACL.SYSTEM, new TriggerNotifier(project, secretToken, Jenkins.getAuthentication()) {
        @Override
        protected void performOnPost(GitLabPushTrigger trigger) {
            trigger.onPost(mergeRequestHook);
        }
    });
    throw HttpResponses.ok();
}
 
Example 10
Source File: ACLUtil.java    From gitlab-plugin with GNU General Public License v2.0 5 votes vote down vote up
public static <T> T impersonate(Authentication auth, final Function<T> function) {
    final ObjectHolder<T> holder = new ObjectHolder<T>();
    ACL.impersonate(auth, new Runnable() {
        public void run() {
            holder.setValue(function.invoke());
        }
    });
    return holder.getValue();
}
 
Example 11
Source File: PRUpdateGHEventSubscriber.java    From github-pr-comment-build-plugin with MIT License 4 votes vote down vote up
/**
 * Handles updates of pull requests.
 * @param event only PULL_REQUEST events
 * @param payload payload of gh-event. Never blank
 */
@Override
protected void onEvent(GHEvent event, String payload) {
    JSONObject json = JSONObject.fromObject(payload);

    // Since we receive both pull request and issue comment events in this same code,
    //  we check first which one it is and set values from different fields
    JSONObject pullRequest = json.getJSONObject("pull_request");
    final String pullRequestUrl = pullRequest.getString("html_url");
    Integer pullRequestId = pullRequest.getInt("number");

    // Make sure the action is edited
    String action = json.getString("action");
    if (!ACTION_EDITED.equals(action)) {
        LOGGER.log(Level.FINER, "Pull request action is not edited ({0}) for PR {1}, ignoring",
                new Object[] { action, pullRequestUrl }
        );
        return;
    }

    // Set some values used below
    final Pattern pullRequestJobNamePattern = Pattern.compile("^PR-" + pullRequestId + "\\b.*$",
            Pattern.CASE_INSENSITIVE);

    // Make sure the repository URL is valid
    String repoUrl = json.getJSONObject("repository").getString("html_url");
    Matcher matcher = REPOSITORY_NAME_PATTERN.matcher(repoUrl);
    if (!matcher.matches()) {
        LOGGER.log(Level.WARNING, "Malformed repository URL {0}", repoUrl);
        return;
    }
    final GitHubRepositoryName changedRepository = GitHubRepositoryName.create(repoUrl);
    if (changedRepository == null) {
        LOGGER.log(Level.WARNING, "Malformed repository URL {0}", repoUrl);
        return;
    }

    LOGGER.log(Level.FINE, "Received update on PR {1} for {2}", new Object[] { pullRequestId, repoUrl });
    ACL.impersonate(ACL.SYSTEM, new Runnable() {
        @Override
        public void run() {
            boolean jobFound = false;
            for (final SCMSourceOwner owner : SCMSourceOwners.all()) {
                for (SCMSource source : owner.getSCMSources()) {
                    if (!(source instanceof GitHubSCMSource)) {
                        continue;
                    }
                    GitHubSCMSource gitHubSCMSource = (GitHubSCMSource) source;
                    if (gitHubSCMSource.getRepoOwner().equalsIgnoreCase(changedRepository.getUserName()) &&
                            gitHubSCMSource.getRepository().equalsIgnoreCase(changedRepository.getRepositoryName())) {
                        for (Job<?, ?> job : owner.getAllJobs()) {
                            if (pullRequestJobNamePattern.matcher(job.getName()).matches()) {
                                if (!(job.getParent() instanceof MultiBranchProject)) {
                                    continue;
                                }
                                boolean propFound = false;
                                for (BranchProperty prop : ((MultiBranchProject) job.getParent()).getProjectFactory().
                                        getBranch(job).getProperties()) {
                                    if (!(prop instanceof TriggerPRUpdateBranchProperty)) {
                                        continue;
                                    }
                                    propFound = true;
                                    ParameterizedJobMixIn.scheduleBuild2(job, 0,
                                            new CauseAction(new GitHubPullRequestUpdateCause(pullRequestUrl)));
                                    break;
                                }

                                if (!propFound) {
                                    LOGGER.log(Level.FINE,
                                            "Job {0} for {1}:{2}/{3} does not have a trigger PR update branch property",
                                            new Object[] {
                                                    job.getFullName(),
                                                    changedRepository.getHost(),
                                                    changedRepository.getUserName(),
                                                    changedRepository.getRepositoryName()
                                            }
                                    );
                                }

                                jobFound = true;
                            }
                        }
                    }
                }
            }
            if (!jobFound) {
                LOGGER.log(Level.FINE, "PR update on {0}:{1}/{2} did not match any job",
                        new Object[] {
                                changedRepository.getHost(), changedRepository.getUserName(),
                                changedRepository.getRepositoryName()
                        }
                );
            }
        }
    });
}
 
Example 12
Source File: PRReviewGHEventSubscriber.java    From github-pr-comment-build-plugin with MIT License 4 votes vote down vote up
/**
 * Handles updates of pull requests.
 * @param event only PULL_REQUEST_REVIEW events
 * @param payload payload of gh-event. Never blank
 */
@Override
protected void onEvent(GHEvent event, String payload) {
    JSONObject json = JSONObject.fromObject(payload);

    JSONObject pullRequest = json.getJSONObject("pull_request");
    final String pullRequestUrl = pullRequest.getString("html_url");
    Integer pullRequestId = pullRequest.getInt("number");

    // Set some values used below
    final Pattern pullRequestJobNamePattern = Pattern.compile("^PR-" + pullRequestId + "\\b.*$",
            Pattern.CASE_INSENSITIVE);

    // Make sure the repository URL is valid
    String repoUrl = json.getJSONObject("repository").getString("html_url");
    Matcher matcher = REPOSITORY_NAME_PATTERN.matcher(repoUrl);
    if (!matcher.matches()) {
        LOGGER.log(Level.WARNING, "Malformed repository URL {0}", repoUrl);
        return;
    }
    final GitHubRepositoryName changedRepository = GitHubRepositoryName.create(repoUrl);
    if (changedRepository == null) {
        LOGGER.log(Level.WARNING, "Malformed repository URL {0}", repoUrl);
        return;
    }

    LOGGER.log(Level.FINE, "Received review on PR {1} for {2}", new Object[] { pullRequestId, repoUrl });
    ACL.impersonate(ACL.SYSTEM, new Runnable() {
        @Override
        public void run() {
            boolean jobFound = false;
            for (final SCMSourceOwner owner : SCMSourceOwners.all()) {
                for (SCMSource source : owner.getSCMSources()) {
                    if (!(source instanceof GitHubSCMSource)) {
                        continue;
                    }
                    GitHubSCMSource gitHubSCMSource = (GitHubSCMSource) source;
                    if (gitHubSCMSource.getRepoOwner().equalsIgnoreCase(changedRepository.getUserName()) &&
                            gitHubSCMSource.getRepository().equalsIgnoreCase(changedRepository.getRepositoryName())) {
                        for (Job<?, ?> job : owner.getAllJobs()) {
                            if (pullRequestJobNamePattern.matcher(job.getName()).matches()) {
                                if (!(job.getParent() instanceof MultiBranchProject)) {
                                    continue;
                                }
                                boolean propFound = false;
                                for (BranchProperty prop : ((MultiBranchProject) job.getParent()).getProjectFactory().
                                        getBranch(job).getProperties()) {
                                    if (!(prop instanceof TriggerPRReviewBranchProperty)) {
                                        continue;
                                    }
                                    propFound = true;
                                    ParameterizedJobMixIn.scheduleBuild2(job, 0,
                                            new CauseAction(new GitHubPullRequestReviewCause(pullRequestUrl)));
                                    break;
                                }

                                if (!propFound) {
                                    LOGGER.log(Level.FINE,
                                            "Job {0} for {1}:{2}/{3} does not have a trigger PR review branch property",
                                            new Object[] {
                                                    job.getFullName(),
                                                    changedRepository.getHost(),
                                                    changedRepository.getUserName(),
                                                    changedRepository.getRepositoryName()
                                            }
                                    );
                                }

                                jobFound = true;
                            }
                        }
                    }
                }
            }
            if (!jobFound) {
                LOGGER.log(Level.FINE, "PR review on {0}:{1}/{2} did not match any job",
                        new Object[] {
                                changedRepository.getHost(), changedRepository.getUserName(),
                                changedRepository.getRepositoryName()
                        }
                );
            }
        }
    });
}
 
Example 13
Source File: GithubServerContainer.java    From blueocean-plugin with MIT License 4 votes vote down vote up
public @CheckForNull ScmServerEndpoint create(@JsonBody JSONObject request) {

        List<ErrorMessage.Error> errors = Lists.newLinkedList();

        // Validate name
        final String name = (String) request.get(GithubServer.NAME);
        if (StringUtils.isEmpty(name)) {
            errors.add(new ErrorMessage.Error(GithubServer.NAME, ErrorMessage.Error.ErrorCodes.MISSING.toString(), GithubServer.NAME + " is required"));
        } else {
            GithubServer byName = findByName(name);
            if (byName != null) {
                errors.add(new ErrorMessage.Error(GithubServer.NAME, ErrorMessage.Error.ErrorCodes.ALREADY_EXISTS.toString(), GithubServer.NAME + " already exists for server at '" + byName.getApiUrl() + "'"));
            }
        }

        // Validate url
        final String url = (String) request.get(GithubServer.API_URL);
        if (StringUtils.isEmpty(url)) {
            errors.add(new ErrorMessage.Error(GithubServer.API_URL, ErrorMessage.Error.ErrorCodes.MISSING.toString(), GithubServer.API_URL + " is required"));
        } else {
            Endpoint byUrl = GitHubConfiguration.get().findEndpoint(url);
            if (byUrl != null) {
                errors.add(new ErrorMessage.Error(GithubServer.API_URL, ErrorMessage.Error.ErrorCodes.ALREADY_EXISTS.toString(), GithubServer.API_URL + " is already registered as '" + byUrl.getName() + "'"));
            }
        }

        if (StringUtils.isNotEmpty(url)) {
            // Validate that the URL represents a GitHub API endpoint
            try {
                HttpURLConnection connection = HttpRequest.get(url).connect();

                if (connection.getHeaderField("X-GitHub-Request-Id") == null) {
                    errors.add(new ErrorMessage.Error(GithubServer.API_URL, ErrorMessage.Error.ErrorCodes.INVALID.toString(), ERROR_MESSAGE_INVALID_SERVER));
                } else {
                    boolean isGithubCloud = false;
                    boolean isGithubEnterprise = false;

                    try {
                        InputStream inputStream;
                        int code = connection.getResponseCode();

                        if (200 <= code && code < 300) {
                            inputStream = HttpRequest.getInputStream(connection);
                        } else {
                            inputStream = HttpRequest.getErrorStream(connection);
                        }

                        TypeReference<HashMap<String, Object>> typeRef = new TypeReference<HashMap<String, Object>>(){};
                        Map<String, String> responseBody = GithubScm.getMappingObjectReader().forType(typeRef).readValue(inputStream);

                        isGithubCloud = code == 200 && responseBody.containsKey("current_user_url");
                        isGithubEnterprise = code == 401 && responseBody.containsKey("message");
                    } catch (IllegalArgumentException | IOException ioe) {
                        LOGGER.log(Level.INFO, "Could not parse response body from Github");
                    }

                    if (!isGithubCloud && !isGithubEnterprise) {
                        errors.add(new ErrorMessage.Error(GithubServer.API_URL, ErrorMessage.Error.ErrorCodes.INVALID.toString(), ERROR_MESSAGE_INVALID_APIURL));
                    }
                }
            } catch (Throwable e) {
                errors.add(new ErrorMessage.Error(GithubServer.API_URL, ErrorMessage.Error.ErrorCodes.INVALID.toString(), e.toString()));
                LOGGER.log(Level.INFO, "Could not connect to Github", e);
            }
        }

        if (errors.isEmpty()) {
            SecurityContext old = null;
            try {
                // We need to escalate privilege to add user defined endpoint to
                old = ACL.impersonate(ACL.SYSTEM);
                GitHubConfiguration config = GitHubConfiguration.get();
                String sanitizedUrl = discardQueryString(url);
                Endpoint endpoint = new Endpoint(sanitizedUrl, name);
                if (!config.addEndpoint(endpoint)) {
                    errors.add(new ErrorMessage.Error(GithubServer.API_URL, ErrorMessage.Error.ErrorCodes.ALREADY_EXISTS.toString(), GithubServer.API_URL + " is already registered as '" + endpoint.getName() + "'"));
                } else {
                    return new GithubServer(endpoint, getLink());
                }
            }finally {
                //reset back to original privilege level
                if(old != null){
                    SecurityContextHolder.setContext(old);
                }
            }
        }
        ErrorMessage message = new ErrorMessage(400, "Failed to create GitHub server");
        message.addAll(errors);
        throw new ServiceException.BadRequestException(message);
     }
 
Example 14
Source File: GogsPayloadProcessor.java    From gogs-webhook-plugin with MIT License 4 votes vote down vote up
public GogsResults triggerJobs(String jobName, String deliveryID) {
    SecurityContext saveCtx = ACL.impersonate(ACL.SYSTEM);
    GogsResults result = new GogsResults();

    try {
        BuildableItem project = GogsUtils.find(jobName, BuildableItem.class);
        if (project != null) {
            GogsTrigger gTrigger = null;
            Cause cause = new GogsCause(deliveryID);

            if (project instanceof ParameterizedJobMixIn.ParameterizedJob) {
                ParameterizedJobMixIn.ParameterizedJob pJob = (ParameterizedJobMixIn.ParameterizedJob) project;
                for (Trigger trigger : pJob.getTriggers().values()) {
                    if (trigger instanceof GogsTrigger) {
                        gTrigger = (GogsTrigger) trigger;
                        break;
                    }
                }
            }

            if (gTrigger != null) {
                SCMTriggerItem item = SCMTriggerItem.SCMTriggerItems.asSCMTriggerItem(project);
                GogsPayload gogsPayload = new GogsPayload(this.payload);
                if (item != null) {
                    item.scheduleBuild2(0, gogsPayload);
                }
            } else {
                project.scheduleBuild(0, cause);
            }
            result.setMessage(String.format("Job '%s' is executed", jobName));
        } else {
            String msg = String.format("Job '%s' is not defined in Jenkins", jobName);
            result.setStatus(404, msg);
            LOGGER.warning(msg);
        }
    } catch (Exception e) {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        e.printStackTrace(pw);
        LOGGER.severe(sw.toString());
    } finally {
        SecurityContextHolder.setContext(saveCtx);
    }

    return result;
}
 
Example 15
Source File: JenkinsRule.java    From jenkins-test-harness with MIT License 4 votes vote down vote up
public Statement apply(final Statement base, final Description description) {
    if (description.getAnnotation(WithoutJenkins.class) != null) {
        // request has been made to not create the instance for this test method
        return base;
    }
    Statement wrapped = new Statement() {
        @Override
        public void evaluate() throws Throwable {
            testDescription = description;
            Thread t = Thread.currentThread();
            String o = t.getName();
            t.setName("Executing "+ testDescription.getDisplayName());
            System.out.println("=== Starting " + testDescription.getDisplayName());
            before();
            try {
                // so that test code has all the access to the system
                ACL.impersonate(ACL.SYSTEM);
                try {
                    base.evaluate();
                } catch (Throwable th) {
                    // allow the late attachment of a debugger in case of a failure. Useful
                    // for diagnosing a rare failure
                    try {
                        throw new BreakException();
                    } catch (BreakException e) {}

                    RandomlyFails rf = testDescription.getAnnotation(RandomlyFails.class);
                    if (rf != null) {
                        System.err.println("Note: known to randomly fail: " + rf.value());
                    }

                    throw th;
                }
            } finally {
                after();
                testDescription = null;
                t.setName(o);
            }
        }
    };
    final int testTimeout = getTestTimeoutOverride(description);
    if (testTimeout <= 0) {
        System.out.println("Test timeout disabled.");
        return wrapped;
    } else {
        final Statement timeoutStatement = Timeout.seconds(testTimeout).apply(wrapped, description);
        return new Statement() {
            @Override
            public void evaluate() throws Throwable {
                try {
                    timeoutStatement.evaluate();
                } catch (TestTimedOutException x) {
                    // withLookingForStuckThread does not work well; better to just have a full thread dump.
                    LOGGER.warning(String.format("Test timed out (after %d seconds).", testTimeout));
                    dumpThreads();
                    throw x;
                }
            }
        };
    }
}
 
Example 16
Source File: MockAuthorizationStrategyTest.java    From jenkins-test-harness with MIT License 4 votes vote down vote up
@Test
public void smokes() throws Exception {
    final MockFolder d = r.createFolder("d");
    final FreeStyleProject p = d.createProject(FreeStyleProject.class, "p");
    r.jenkins.setSecurityRealm(r.createDummySecurityRealm());
    r.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy().
        grant(Jenkins.ADMINISTER).everywhere().to("root").
        grantWithoutImplication(Jenkins.ADMINISTER).onRoot().to("admin").
        grant(Jenkins.READ, Item.READ).everywhere().toEveryone().
        grant(Item.EXTENDED_READ).everywhere().toAuthenticated().
        grant(Item.CREATE).onItems(d).to("dev").
        grant(Item.CONFIGURE).onItems(p).to("dev").
        grant(Item.BUILD).onFolders(d).to("dev"));
    ACL.impersonate(User.get("root").impersonate(), new Runnable() {
        @Override
        public void run() {
            assertTrue(r.jenkins.hasPermission(Jenkins.RUN_SCRIPTS));
            assertTrue(p.hasPermission(Item.DELETE));
        }
    });
    ACL.impersonate(User.get("admin").impersonate(), new Runnable() {
        @Override
        public void run() {
            assertFalse(r.jenkins.hasPermission(Jenkins.RUN_SCRIPTS));
            assertTrue(r.jenkins.hasPermission(Jenkins.ADMINISTER));
            assertFalse(p.hasPermission(Item.DELETE));
            assertTrue(p.hasPermission(Item.READ));
        }
    });
    ACL.impersonate(User.get("dev").impersonate(), new Runnable() {
        @Override
        public void run() {
            assertFalse(r.jenkins.hasPermission(Jenkins.ADMINISTER));
            assertTrue(r.jenkins.hasPermission(Jenkins.READ));
            assertFalse(p.hasPermission(Item.DELETE));
            assertTrue(p.hasPermission(Item.CONFIGURE));
            assertTrue(p.hasPermission(Item.BUILD));
            assertFalse(d.hasPermission(Item.CONFIGURE));
            assertTrue(d.hasPermission(Item.CREATE));
            assertTrue(d.hasPermission(Item.READ));
            assertTrue(d.hasPermission(Item.EXTENDED_READ));
            assertFalse(p.hasPermission(Item.CREATE));
        }
    });
    ACL.impersonate(Jenkins.ANONYMOUS, new Runnable() {
        @Override
        public void run() {
            assertFalse(r.jenkins.hasPermission(Jenkins.ADMINISTER));
            assertTrue(r.jenkins.hasPermission(Jenkins.READ));
            assertFalse(p.hasPermission(Item.DELETE));
            assertTrue(p.hasPermission(Item.READ));
            assertFalse(p.hasPermission(Item.EXTENDED_READ));
        }
    });
    assertTrue("SYSTEM has everything", r.jenkins.hasPermission(Jenkins.RUN_SCRIPTS)); // handled by SidACL
}