From fb1ee8c3fd62c02aef549c335713209409f3bae8 Mon Sep 17 00:00:00 2001 From: Ivan Fernandez Calvo Date: Tue, 30 Mar 2021 18:13:45 +0200 Subject: [PATCH 1/3] feat: step hasCommentAuthorWritePermissions --- ...sCommentAuthorWritePermissionsTests.groovy | 57 +++++++++++++++++++ vars/README.md | 13 +++++ vars/hasCommentAuthorWritePermissions.groovy | 29 ++++++++++ vars/hasCommentAuthorWritePermissions.txt | 11 ++++ 4 files changed, 110 insertions(+) create mode 100644 src/test/groovy/HasCommentAuthorWritePermissionsTests.groovy create mode 100644 vars/hasCommentAuthorWritePermissions.groovy create mode 100644 vars/hasCommentAuthorWritePermissions.txt diff --git a/src/test/groovy/HasCommentAuthorWritePermissionsTests.groovy b/src/test/groovy/HasCommentAuthorWritePermissionsTests.groovy new file mode 100644 index 000000000..6ccbf530f --- /dev/null +++ b/src/test/groovy/HasCommentAuthorWritePermissionsTests.groovy @@ -0,0 +1,57 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import org.junit.Before +import org.junit.Test +import static org.junit.Assert.assertTrue + +class HasCommentAuthorWritePermissionsTests extends ApmBasePipelineTest { + + @Override + @Before + void setUp() throws Exception { + super.setUp() + script = loadScript('vars/hasCommentAuthorWritePermissions.groovy') + helper.registerAllowedMethod('githubRepoGetUserPermission', [Map.class], { m -> [ permission: "write" ] }) + helper.registerAllowedMethod('githubApiCall', [Map.class], { m -> [ user: [ login: "foo" ] ] }) + } + + @Test + void test() throws Exception { + def ret = script.call(repoName: "owner/repo", commentId: "1") + printCallStack() + assertTrue(ret) + assertTrue(assertMethodCallContainsPattern('githubApiCall', 'url=https://api.github.com/repos/owner/repo/issues/comments/1')) + assertTrue(assertMethodCallContainsPattern('githubRepoGetUserPermission', 'repo=owner/repo')) + assertTrue(assertMethodCallContainsPattern('githubRepoGetUserPermission', 'user=foo')) + assertJobStatusSuccess() + } + + @Test + void testNoRepo() throws Exception { + testError("hasCommentAuthorWritePermissions: repoName params is required"){ + script.call(commentId: "1") + } + } + + @Test + void testNoCommentID() throws Exception { + testError("hasCommentAuthorWritePermissions: commentId params is required"){ + script.call(repoName: "owner/repo") + } + } +} diff --git a/vars/README.md b/vars/README.md index fbcef0838..9aa49ddd4 100644 --- a/vars/README.md +++ b/vars/README.md @@ -1310,6 +1310,19 @@ Wrapper to interact with the gsutil command line. It returns the stdout output. * command: The gsutil command to be executed. Mandatory * credentialsId: The credentials to access the repo (repo permissions). Mandatory. +## hasCommentAuthorWritePermissions + +Check if the author of a GitHub comment has admin or write permissions in the repository. + +``` +if(!hasCommentAuthorWritePermissions(repoName: "elastic/kibana", commentId: env.GT_COMMENT_ID)){ + error("Only Elasticians can deploy Docker images") +} +``` + +* *repoName:* organization and name of the repository (Organization/Repository) +* *commentId:* ID of the comment we want to check. + ## httpRequest Step to make HTTP request and get the result. If the return code is >= 400, it would throw an error. diff --git a/vars/hasCommentAuthorWritePermissions.groovy b/vars/hasCommentAuthorWritePermissions.groovy new file mode 100644 index 000000000..889d44cd2 --- /dev/null +++ b/vars/hasCommentAuthorWritePermissions.groovy @@ -0,0 +1,29 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + Check if the author of a GitHub comment has admin or write permissions in the repository. +*/ +def call(Map args = [:]){ + def repoName = args.containsKey('repoName') ? args.repoName : error('hasCommentAuthorWritePermissions: repoName params is required') + def commentId = args.containsKey('commentId') ? args.commentId : error('hasCommentAuthorWritePermissions: commentId params is required') + def token = getGithubToken() + def url = "https://api.github.com/repos/${repoName}/issues/comments/${commentId}" + def comment = githubApiCall(token: token, url: url, noCache: true) + def json = githubRepoGetUserPermission(token: token, repo: repoName, user: comment?.user?.login) + return json?.permission == 'admin' || json?.permission == 'write' +} diff --git a/vars/hasCommentAuthorWritePermissions.txt b/vars/hasCommentAuthorWritePermissions.txt new file mode 100644 index 000000000..765c7d102 --- /dev/null +++ b/vars/hasCommentAuthorWritePermissions.txt @@ -0,0 +1,11 @@ + +Check if the author of a GitHub comment has admin or write permissions in the repository. + +``` +if(!hasCommentAuthorWritePermissions(repoName: "elastic/kibana", commentId: env.GT_COMMENT_ID)){ + error("Only Elasticians can deploy Docker images") +} +``` + +* *repoName:* organization and name of the repository (Organization/Repository) +* *commentId:* ID of the comment we want to check. From e786a359da87dc84602162acf8186ba123091838 Mon Sep 17 00:00:00 2001 From: Ivan Fernandez Calvo Date: Tue, 30 Mar 2021 18:15:36 +0200 Subject: [PATCH 2/3] Update vars/README.md --- vars/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/vars/README.md b/vars/README.md index 9aa49ddd4..07ff0903e 100644 --- a/vars/README.md +++ b/vars/README.md @@ -1315,7 +1315,7 @@ Wrapper to interact with the gsutil command line. It returns the stdout output. Check if the author of a GitHub comment has admin or write permissions in the repository. ``` -if(!hasCommentAuthorWritePermissions(repoName: "elastic/kibana", commentId: env.GT_COMMENT_ID)){ +if(!hasCommentAuthorWritePermissions(repoName: "elastic/beats", commentId: env.GT_COMMENT_ID)){ error("Only Elasticians can deploy Docker images") } ``` @@ -2979,4 +2979,3 @@ writeVaultSecret(secret: 'secret/apm-team/ci/temp/github-comment', data: ['secre * secret: Name of the secret on the the vault root path. Mandatory * data: What's the data to be written. Mandatory - From ccf8d33b1082e18ff0b19cbb445966fdc115fdf9 Mon Sep 17 00:00:00 2001 From: Ivan Fernandez Calvo Date: Tue, 30 Mar 2021 18:15:54 +0200 Subject: [PATCH 3/3] Update vars/README.md --- vars/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vars/README.md b/vars/README.md index 07ff0903e..6594dd9e0 100644 --- a/vars/README.md +++ b/vars/README.md @@ -1316,7 +1316,7 @@ Check if the author of a GitHub comment has admin or write permissions in the re ``` if(!hasCommentAuthorWritePermissions(repoName: "elastic/beats", commentId: env.GT_COMMENT_ID)){ - error("Only Elasticians can deploy Docker images") + error("Only Elasticians can do this action.") } ```