-
Notifications
You must be signed in to change notification settings - Fork 372
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[JENKINS-73474] Add GitHubAppCredentials.withOwner
non regression test
#804
Changes from 2 commits
d16d722
bf16201
700dda9
e23cd89
a26ed7f
53c2def
ace081f
35aafa2
718cd74
d7a0bf3
24cb39b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package org.jenkinsci.plugins.github_branch_source; | ||
|
||
import com.cloudbees.plugins.credentials.CredentialsScope; | ||
import hudson.util.Secret; | ||
|
||
public class GitHubApp { | ||
|
||
// PKCS8 private key (https://stackoverflow.com/a/22176759/4951015) | ||
private static final String PRIVATE_KEY = "-----BEGIN PRIVATE KEY-----\n" | ||
+ | ||
// Windows line ending | ||
"MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQD7vHsVwyDV8cj7\r\n" | ||
+ | ||
// This should also work | ||
"5yR4WWl6rlgf/e5zmeBgtm0PCgnitcSbD5FU33301DPY5a7AtqVBOwEnE14L9XS7\r" | ||
+ "ov61U+x1m4aQmqR/dPQaA2ayh2cYPszWNQMp42ArDIfg7DhSrvsRJKHsbPXlPjqe\n" | ||
+ "c0udLqhSLVIO9frNLf+dAsLsgYk8O39PKGb33akGG7tWTe0J+akNQjgbS7vOi8sS\n" | ||
+ "NLwHIdYfz/Am+6Xmm+J4yVs6+Xt3kOeLdFBkz8H/HGsJq854MbIAK/HuId1MOPS0\n" | ||
+ "cDWh37tzRsM+q/HZzYRkc5bhNKw/Mj9jN9jD5GH0Lfea0QFedjppf1KvWdcXn+/W\n" | ||
+ "M7OmyfhvAgMBAAECggEAN96H7reExRbJRWbySCeH6mthMZB46H0hODWklK7krMUs\n" | ||
+ "okFdPtnvKXQjIaMwGqMuoACJa/O3bq4GP1KYdwPuOdfPkK5RjdwWBOP2We8FKXNe\n" | ||
+ "oLfZQOWuxT8dtQSYJ3mgTRi1OzSfikY6Wko6YOMnBj36tUlQZVMtJNqlCjphi9Uz\n" | ||
+ "6EyvRURlDG8sBBbC7ods5B0789qk3iGH/97ia+1QIqXAUaVFg3/BA6wkxkbNG2sN\n" | ||
+ "tqULgVYTw32Oj/Y/H1Y250RoocTyfsUS3I3aPIlnvcgp2bugWqDyYJ58nDIt3Pku\n" | ||
+ "fjImWrNz/pNiEs+efnb0QEk7m5hYwxmyXN4KRSv0OQKBgQD+I3Y3iNKSVr6wXjur\n" | ||
+ "OPp45fxS2sEf5FyFYOn3u760sdJOH9fGlmf9sDozJ8Y8KCaQCN5tSe3OM+XDrmiw\n" | ||
+ "Cu/oaqJ1+G4RG+6w1RJF+5Nfg6PkUs7eJehUgZ2Tox8Tg1mfVIV8KbMwNi5tXpug\n" | ||
+ "MVmA2k9xjc4uMd2jSnSj9NAqrQKBgQD9lIO1tY6YKF0Eb0Qi/iLN4UqBdJfnALBR\n" | ||
+ "MjxYxqqI8G4wZEoZEJJvT1Lm6Q3o577N95SihZoj69tb10vvbEz1pb3df7c1HEku\n" | ||
+ "LXcyVMvjR/CZ7dOSNgLGAkFfOoPhcF/OjSm4DrGPe3GiBxhwXTBjwJ5TIgEDkVIx\n" | ||
+ "ZVo5r7gPCwKBgQCOvsZo/Q4hql2jXNqxGuj9PVkUBNFTI4agWEYyox7ECdlxjks5\n" | ||
+ "vUOd5/1YvG+JXJgEcSbWRh8volDdL7qXnx0P881a6/aO35ybcKK58kvd62gEGEsf\n" | ||
+ "1jUAOmmTAp2y7SVK7EOp8RY370b2oZxSR0XZrUXQJ3F22wV98ZVAfoLqZQKBgDIr\n" | ||
+ "PdunbezAn5aPBOX/bZdZ6UmvbZYwVrHZxIKz2214U/STAu3uj2oiQX6ZwTzBDMjn\n" | ||
+ "IKr+z74nnaCP+eAGhztabTPzXqXNUNUn/Zshl60BwKJToTYeJXJTY+eZRhpGB05w\n" | ||
+ "Mz7M+Wgvvg2WZcllRnuV0j0UTysLhz1qle0vzLR9AoGBAOukkFFm2RLm9N1P3gI8\n" | ||
+ "mUadeAlYRZ5o0MvumOHaB5pDOCKhrqAhop2gnM0f5uSlapCtlhj0Js7ZyS3Giezg\n" | ||
+ "38oqAhAYxy2LMoLD7UtsHXNp0OnZ22djcDwh+Wp2YORm7h71yOM0NsYubGbp+CmT\n" | ||
+ "Nw9bewRvqjySBlDJ9/aNSeEY\n" | ||
+ "-----END PRIVATE KEY-----"; | ||
|
||
public static GitHubAppCredentials createCredentials(final String id) { | ||
return new GitHubAppCredentials(CredentialsScope.GLOBAL, id, "sample", "54321", Secret.fromString(PRIVATE_KEY)); | ||
} | ||
|
||
public static GitHubAppCredentials createCredentials(final String id, final String owner) { | ||
final var credentials = createCredentials(id); | ||
credentials.setOwner(owner); | ||
return credentials; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
package org.jenkinsci.plugins.github_branch_source; | ||
|
||
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; | ||
import static com.github.tomakehurst.wiremock.client.WireMock.equalToJson; | ||
import static com.github.tomakehurst.wiremock.client.WireMock.get; | ||
import static com.github.tomakehurst.wiremock.client.WireMock.post; | ||
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; | ||
import static org.hamcrest.MatcherAssert.assertThat; | ||
import static org.hamcrest.Matchers.notNullValue; | ||
|
||
import com.cloudbees.plugins.credentials.CredentialsProvider; | ||
import com.cloudbees.plugins.credentials.domains.Domain; | ||
import hudson.model.Cause; | ||
import java.time.Duration; | ||
import java.time.Instant; | ||
import java.time.format.DateTimeFormatter; | ||
import java.time.temporal.ChronoUnit; | ||
import java.util.Arrays; | ||
import java.util.Collections; | ||
import java.util.Date; | ||
import jenkins.branch.BranchSource; | ||
import org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject; | ||
import org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProjectTest; | ||
import org.junit.Before; | ||
import org.junit.Test; | ||
|
||
public class GithubAppCredentialsContextualizationTest extends AbstractGitHubWireMockTest { | ||
jeromepochat marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
@Before | ||
public void setUpWireMock() throws Exception { | ||
GitHubConfiguration.get().setApiRateLimitChecker(ApiRateLimitChecker.ThrottleOnOver); | ||
|
||
// Add wiremock responses for App, App Installation, and App Installation Token | ||
githubApi.stubFor(get(urlEqualTo("/app")) | ||
.willReturn(aResponse() | ||
.withHeader("Content-Type", "application/json; charset=utf-8") | ||
.withBodyFile("../AppCredentials/files/body-mapping-githubapp-app.json"))); | ||
githubApi.stubFor(get(urlEqualTo("/app/installations")) | ||
.willReturn(aResponse() | ||
.withHeader("Content-Type", "application/json; charset=utf-8") | ||
.withBodyFile("../AppCredentials/files/body-mapping-githubapp-installations.json"))); | ||
githubApi.stubFor(post(urlEqualTo("/app/installations/654321/access_tokens")) | ||
.withRequestBody(equalToJson( | ||
"{\"permissions\":{\"pull_requests\":\"write\",\"metadata\":\"read\",\"checks\":\"write\",\"contents\":\"read\"}}", | ||
true, | ||
false)) | ||
.willReturn(aResponse() | ||
.withHeader("Content-Type", "application/json; charset=utf-8") | ||
.withBody("{\n" | ||
+ " \"token\": \"super-secret-token\",\n" | ||
+ | ||
// This token will go stale at the soonest allowed time but will not | ||
// expire for the duration of the test | ||
" \"expires_at\": \"" | ||
+ printDate(new Date(System.currentTimeMillis() | ||
+ Duration.ofMinutes(10).toMillis())) | ||
+ "\"" | ||
+ // 2019-08-10T05:54:58Z | ||
"}"))); | ||
} | ||
|
||
@Test | ||
public void ownerMustBeInferedFromRepository() throws Exception { | ||
jeromepochat marked this conversation as resolved.
Show resolved
Hide resolved
|
||
final var store = CredentialsProvider.lookupStores(r.jenkins).iterator().next(); | ||
|
||
final var credentials = GitHubApp.createCredentials("myAppCredentialsWithoutOwner"); | ||
store.addCredentials(Domain.global(), credentials); | ||
credentials.setApiUri(githubApi.baseUrl()); | ||
|
||
final var scmSource = new GitHubSCMSource("cloudbeers", "multibranch-demo", null, false); | ||
scmSource.setTraits(Arrays.asList(new BranchDiscoveryTrait(true, true))); | ||
scmSource.setCredentialsId(credentials.getId()); | ||
scmSource.setApiUri(githubApi.baseUrl()); | ||
|
||
final var multiBranchProject = r.jenkins.createProject(WorkflowMultiBranchProject.class, "multibranch-demo"); | ||
multiBranchProject.setSourcesList(Collections.singletonList(new BranchSource(scmSource))); | ||
multiBranchProject.scheduleBuild(new Cause.UserIdCause()); | ||
|
||
r.waitUntilNoActivity(); | ||
|
||
final var branchProject = | ||
WorkflowMultiBranchProjectTest.scheduleAndFindBranchProject(multiBranchProject, "master"); | ||
assertThat(branchProject, notNullValue()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And without the fix, is this the line that fails? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yes. I confirm that the test is failing without #803 |
||
} | ||
|
||
static String printDate(Date dt) { | ||
return DateTimeFormatter.ISO_INSTANT.format( | ||
Instant.ofEpochMilli(dt.getTime()).truncatedTo(ChronoUnit.SECONDS)); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,11 +3,11 @@ | |
import static com.github.tomakehurst.wiremock.client.WireMock.*; | ||
import static org.hamcrest.MatcherAssert.assertThat; | ||
import static org.hamcrest.Matchers.*; | ||
import static org.hamcrest.Matchers.equalTo; | ||
import static org.jenkinsci.plugins.github_branch_source.Connector.createGitHubBuilder; | ||
import static org.junit.Assert.assertThrows; | ||
|
||
import com.cloudbees.plugins.credentials.CredentialsProvider; | ||
import com.cloudbees.plugins.credentials.CredentialsScope; | ||
import com.cloudbees.plugins.credentials.CredentialsStore; | ||
import com.cloudbees.plugins.credentials.domains.Domain; | ||
import com.github.tomakehurst.wiremock.http.RequestMethod; | ||
|
@@ -19,7 +19,6 @@ | |
import hudson.model.Result; | ||
import hudson.model.Slave; | ||
import hudson.model.StringParameterDefinition; | ||
import hudson.util.Secret; | ||
import java.time.Duration; | ||
import java.time.Instant; | ||
import java.time.format.DateTimeFormatter; | ||
|
@@ -56,40 +55,6 @@ public class GithubAppCredentialsTest extends AbstractGitHubWireMockTest { | |
private static GitHubAppCredentials appCredentials, appCredentialsNoOwner; | ||
private static LogRecorder logRecorder; | ||
|
||
// https://stackoverflow.com/a/22176759/4951015 | ||
public static final String PKCS8_PRIVATE_KEY = "-----BEGIN PRIVATE KEY-----\n" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Extracted to |
||
+ | ||
// Windows line ending | ||
"MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQD7vHsVwyDV8cj7\r\n" | ||
+ | ||
// This should also work | ||
"5yR4WWl6rlgf/e5zmeBgtm0PCgnitcSbD5FU33301DPY5a7AtqVBOwEnE14L9XS7\r" | ||
+ "ov61U+x1m4aQmqR/dPQaA2ayh2cYPszWNQMp42ArDIfg7DhSrvsRJKHsbPXlPjqe\n" | ||
+ "c0udLqhSLVIO9frNLf+dAsLsgYk8O39PKGb33akGG7tWTe0J+akNQjgbS7vOi8sS\n" | ||
+ "NLwHIdYfz/Am+6Xmm+J4yVs6+Xt3kOeLdFBkz8H/HGsJq854MbIAK/HuId1MOPS0\n" | ||
+ "cDWh37tzRsM+q/HZzYRkc5bhNKw/Mj9jN9jD5GH0Lfea0QFedjppf1KvWdcXn+/W\n" | ||
+ "M7OmyfhvAgMBAAECggEAN96H7reExRbJRWbySCeH6mthMZB46H0hODWklK7krMUs\n" | ||
+ "okFdPtnvKXQjIaMwGqMuoACJa/O3bq4GP1KYdwPuOdfPkK5RjdwWBOP2We8FKXNe\n" | ||
+ "oLfZQOWuxT8dtQSYJ3mgTRi1OzSfikY6Wko6YOMnBj36tUlQZVMtJNqlCjphi9Uz\n" | ||
+ "6EyvRURlDG8sBBbC7ods5B0789qk3iGH/97ia+1QIqXAUaVFg3/BA6wkxkbNG2sN\n" | ||
+ "tqULgVYTw32Oj/Y/H1Y250RoocTyfsUS3I3aPIlnvcgp2bugWqDyYJ58nDIt3Pku\n" | ||
+ "fjImWrNz/pNiEs+efnb0QEk7m5hYwxmyXN4KRSv0OQKBgQD+I3Y3iNKSVr6wXjur\n" | ||
+ "OPp45fxS2sEf5FyFYOn3u760sdJOH9fGlmf9sDozJ8Y8KCaQCN5tSe3OM+XDrmiw\n" | ||
+ "Cu/oaqJ1+G4RG+6w1RJF+5Nfg6PkUs7eJehUgZ2Tox8Tg1mfVIV8KbMwNi5tXpug\n" | ||
+ "MVmA2k9xjc4uMd2jSnSj9NAqrQKBgQD9lIO1tY6YKF0Eb0Qi/iLN4UqBdJfnALBR\n" | ||
+ "MjxYxqqI8G4wZEoZEJJvT1Lm6Q3o577N95SihZoj69tb10vvbEz1pb3df7c1HEku\n" | ||
+ "LXcyVMvjR/CZ7dOSNgLGAkFfOoPhcF/OjSm4DrGPe3GiBxhwXTBjwJ5TIgEDkVIx\n" | ||
+ "ZVo5r7gPCwKBgQCOvsZo/Q4hql2jXNqxGuj9PVkUBNFTI4agWEYyox7ECdlxjks5\n" | ||
+ "vUOd5/1YvG+JXJgEcSbWRh8volDdL7qXnx0P881a6/aO35ybcKK58kvd62gEGEsf\n" | ||
+ "1jUAOmmTAp2y7SVK7EOp8RY370b2oZxSR0XZrUXQJ3F22wV98ZVAfoLqZQKBgDIr\n" | ||
+ "PdunbezAn5aPBOX/bZdZ6UmvbZYwVrHZxIKz2214U/STAu3uj2oiQX6ZwTzBDMjn\n" | ||
+ "IKr+z74nnaCP+eAGhztabTPzXqXNUNUn/Zshl60BwKJToTYeJXJTY+eZRhpGB05w\n" | ||
+ "Mz7M+Wgvvg2WZcllRnuV0j0UTysLhz1qle0vzLR9AoGBAOukkFFm2RLm9N1P3gI8\n" | ||
+ "mUadeAlYRZ5o0MvumOHaB5pDOCKhrqAhop2gnM0f5uSlapCtlhj0Js7ZyS3Giezg\n" | ||
+ "38oqAhAYxy2LMoLD7UtsHXNp0OnZ22djcDwh+Wp2YORm7h71yOM0NsYubGbp+CmT\n" | ||
+ "Nw9bewRvqjySBlDJ9/aNSeEY\n" | ||
+ "-----END PRIVATE KEY-----"; | ||
|
||
@Rule | ||
public GitSampleRepoRule sampleRepo = new GitSampleRepoRule(); | ||
|
||
|
@@ -106,16 +71,9 @@ public static void setUpJenkins() throws Exception { | |
// Add credential (Must have valid private key for Jwt to work, but App doesn't have to actually | ||
// exist) | ||
store = CredentialsProvider.lookupStores(r.jenkins).iterator().next(); | ||
appCredentials = new GitHubAppCredentials( | ||
CredentialsScope.GLOBAL, myAppCredentialsId, "sample", "54321", Secret.fromString(PKCS8_PRIVATE_KEY)); | ||
appCredentials.setOwner("cloudBeers"); | ||
appCredentials = GitHubApp.createCredentials(myAppCredentialsId, "cloudBeers"); | ||
store.addCredentials(Domain.global(), appCredentials); | ||
appCredentialsNoOwner = new GitHubAppCredentials( | ||
CredentialsScope.GLOBAL, | ||
myAppCredentialsNoOwnerId, | ||
"sample", | ||
"54321", | ||
Secret.fromString(PKCS8_PRIVATE_KEY)); | ||
appCredentialsNoOwner = GitHubApp.createCredentials(myAppCredentialsNoOwnerId); | ||
store.addCredentials(Domain.global(), appCredentialsNoOwner); | ||
|
||
// Add agent | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
[ | ||
{ | ||
"name": "master", | ||
"commit": { | ||
"sha": "ba1fdaa6c2088cecea85333e763710cd3f39688f", | ||
"url": "https://api.github.com/repos/cloudbeers/multibranch-demo/commits/ba1fdaa6c2088cecea85333e763710cd3f39688f" | ||
}, | ||
"protected": false | ||
} | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
[ | ||
{ | ||
"name": "Jenkinsfile", | ||
"path": "Jenkinsfile", | ||
"sha": "98c0f1dad6a7874ff6a7ccc4dd72a5519ec8fdba", | ||
"size": 351, | ||
"url": "https://api.github.com/repos/cloudbeers/multibranch-demo/contents/Jenkinsfile?ref=refs/heads/master", | ||
"html_url": "https://github.com/cloudbeers/multibranch-demo/blob/refs/heads/master/Jenkinsfile", | ||
"git_url": "https://api.github.com/repos/cloudbeers/multibranch-demo/git/blobs/98c0f1dad6a7874ff6a7ccc4dd72a5519ec8fdba", | ||
"download_url": "https://raw.githubusercontent.com/cloudbeers/multibranch-demo/refs/heads/master/Jenkinsfile", | ||
"type": "file", | ||
"_links": { | ||
"self": "https://api.github.com/repos/cloudbeers/multibranch-demo/contents/Jenkinsfile?ref=refs/heads/master", | ||
"git": "https://api.github.com/repos/cloudbeers/multibranch-demo/git/blobs/98c0f1dad6a7874ff6a7ccc4dd72a5519ec8fdba", | ||
"html": "https://github.com/cloudbeers/multibranch-demo/blob/refs/heads/master/Jenkinsfile" | ||
} | ||
}, | ||
{ | ||
"name": "README.md", | ||
"path": "README.md", | ||
"sha": "59e16b0d408539ab4f23d64f2cafd33495eb21ad", | ||
"size": 131, | ||
"url": "https://api.github.com/repos/cloudbeers/multibranch-demo/contents/README.md?ref=refs/heads/master", | ||
"html_url": "https://github.com/cloudbeers/multibranch-demo/blob/refs/heads/master/README.md", | ||
"git_url": "https://api.github.com/repos/cloudbeers/multibranch-demo/git/blobs/59e16b0d408539ab4f23d64f2cafd33495eb21ad", | ||
"download_url": "https://raw.githubusercontent.com/cloudbeers/multibranch-demo/refs/heads/master/README.md", | ||
"type": "file", | ||
"_links": { | ||
"self": "https://api.github.com/repos/cloudbeers/multibranch-demo/contents/README.md?ref=refs/heads/master", | ||
"git": "https://api.github.com/repos/cloudbeers/multibranch-demo/git/blobs/59e16b0d408539ab4f23d64f2cafd33495eb21ad", | ||
"html": "https://github.com/cloudbeers/multibranch-demo/blob/refs/heads/master/README.md" | ||
} | ||
}, | ||
{ | ||
"name": "hello-world.go", | ||
"path": "hello-world.go", | ||
"sha": "b64817ed596a1dae19dfa3f8a6e6bc26506cc645", | ||
"size": 75, | ||
"url": "https://api.github.com/repos/cloudbeers/multibranch-demo/contents/hello-world.go?ref=refs/heads/master", | ||
"html_url": "https://github.com/cloudbeers/multibranch-demo/blob/refs/heads/master/hello-world.go", | ||
"git_url": "https://api.github.com/repos/cloudbeers/multibranch-demo/git/blobs/b64817ed596a1dae19dfa3f8a6e6bc26506cc645", | ||
"download_url": "https://raw.githubusercontent.com/cloudbeers/multibranch-demo/refs/heads/master/hello-world.go", | ||
"type": "file", | ||
"_links": { | ||
"self": "https://api.github.com/repos/cloudbeers/multibranch-demo/contents/hello-world.go?ref=refs/heads/master", | ||
"git": "https://api.github.com/repos/cloudbeers/multibranch-demo/git/blobs/b64817ed596a1dae19dfa3f8a6e6bc26506cc645", | ||
"html": "https://github.com/cloudbeers/multibranch-demo/blob/refs/heads/master/hello-world.go" | ||
} | ||
} | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
[] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW when updating to 2.479.x we can switch to a multiline text block which would be more legible.