From ccb42d32499ee1fcfe7dc9711f5e82eb5a9176b2 Mon Sep 17 00:00:00 2001 From: Jesse Glick Date: Fri, 16 Dec 2016 18:02:28 -0500 Subject: [PATCH] [JENKINS-36240] Added GHRepository.getPermission(String). --- .../java/org/kohsuke/github/GHPermission.java | 53 +++++++++++++++++++ .../java/org/kohsuke/github/GHRepository.java | 12 +++++ .../java/org/kohsuke/github/Requester.java | 11 ++-- .../org/kohsuke/github/RepositoryTest.java | 25 +++++++++ 4 files changed, 98 insertions(+), 3 deletions(-) create mode 100644 src/main/java/org/kohsuke/github/GHPermission.java diff --git a/src/main/java/org/kohsuke/github/GHPermission.java b/src/main/java/org/kohsuke/github/GHPermission.java new file mode 100644 index 0000000000..8bc28c719a --- /dev/null +++ b/src/main/java/org/kohsuke/github/GHPermission.java @@ -0,0 +1,53 @@ +/* + * The MIT License + * + * Copyright 2016 CloudBees, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package org.kohsuke.github; + +/** + * Permission for a user in a repository. + * @see API + */ +public class GHPermission { + + private String permission; + private GHUser user; + + /** + * @return one of {@code admin}, {@code write}, {@code read}, or {@code none} + */ + public String getPermission() { + return permission; + } + + public GHUser getUser() { + return user; + } + + void wrapUp(GitHub root) { + if (user != null) { + user.root = root; + } + } + +} diff --git a/src/main/java/org/kohsuke/github/GHRepository.java b/src/main/java/org/kohsuke/github/GHRepository.java index f34ea85004..d3af91a210 100644 --- a/src/main/java/org/kohsuke/github/GHRepository.java +++ b/src/main/java/org/kohsuke/github/GHRepository.java @@ -480,6 +480,18 @@ public Set getCollaboratorNames() throws IOException { return r; } + /** + * Obtain permission for a given user in this repository. + * @param user a {@link GHUser#getLogin} + * @throws FileNotFoundException under some conditions (e.g., private repo you can see but are not an admin of); treat as unknown + * @throws HttpException with a 403 under other conditions (e.g., public repo you have no special rights to); treat as unknown + */ + public GHPermission getPermission(String user) throws IOException { + GHPermission perm = root.retrieve().withHeader("Accept", "application/vnd.github.korra-preview").to(getApiTailUrl("collaborators/" + user + "/permission"), GHPermission.class); + perm.wrapUp(root); + return perm; + } + /** * If this repository belongs to an organization, return a set of teams. */ diff --git a/src/main/java/org/kohsuke/github/Requester.java b/src/main/java/org/kohsuke/github/Requester.java index 70c48940c0..2eb3f282fb 100644 --- a/src/main/java/org/kohsuke/github/Requester.java +++ b/src/main/java/org/kohsuke/github/Requester.java @@ -598,11 +598,16 @@ private InputStream wrapStream(InputStream in) throws IOException { InputStream es = wrapStream(uc.getErrorStream()); try { if (es!=null) { + String error = IOUtils.toString(es, "UTF-8"); if (e instanceof FileNotFoundException) { // pass through 404 Not Found to allow the caller to handle it intelligently - throw (IOException) new FileNotFoundException(IOUtils.toString(es, "UTF-8")).initCause(e); - } else - throw (IOException) new IOException(IOUtils.toString(es, "UTF-8")).initCause(e); + throw (IOException) new FileNotFoundException(error).initCause(e); + } else if (e instanceof HttpException) { + HttpException http = (HttpException) e; + throw (IOException) new HttpException(error, http.getResponseCode(), http.getResponseMessage(), http.getUrl(), e); + } else { + throw (IOException) new IOException(error).initCause(e); + } } else throw e; } finally { diff --git a/src/test/java/org/kohsuke/github/RepositoryTest.java b/src/test/java/org/kohsuke/github/RepositoryTest.java index dae2892a45..21625fbf89 100644 --- a/src/test/java/org/kohsuke/github/RepositoryTest.java +++ b/src/test/java/org/kohsuke/github/RepositoryTest.java @@ -1,9 +1,11 @@ package org.kohsuke.github; +import java.io.FileNotFoundException; import org.junit.Test; import org.kohsuke.github.GHRepository.Contributor; import java.io.IOException; +import org.junit.Ignore; /** * @author Kohsuke Kawaguchi @@ -40,6 +42,29 @@ public void listContributors() throws IOException { assertTrue(kohsuke); } + @Ignore("depends on who runs this test whether it can pass or not") + @Test + public void getPermission() throws Exception { + GHRepository r = gitHub.getOrganization("cloudbeers").getRepository("yolo"); + assertEquals("admin", r.getPermission("jglick").getPermission()); + assertEquals("read", r.getPermission("dude").getPermission()); + r = gitHub.getOrganization("cloudbees").getRepository("private-repo-not-writable-by-me"); + try { + r.getPermission("jglick"); + fail(); + } catch (FileNotFoundException x) { + x.printStackTrace(); // good + } + r = gitHub.getOrganization("apache").getRepository("groovy"); + try { + r.getPermission("jglick"); + fail(); + } catch (HttpException x) { + x.printStackTrace(); // good + assertEquals(403, x.getResponseCode()); + } + } + private GHRepository getRepository() throws IOException { return gitHub.getOrganization("github-api-test-org").getRepository("jenkins"); }