You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@devlake.apache.org by mi...@apache.org on 2023/05/22 03:07:10 UTC
[incubator-devlake] branch main updated: feat: add warning to github test connection (#5205)
This is an automated email from the ASF dual-hosted git repository.
mintsweet pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-devlake.git
The following commit(s) were added to refs/heads/main by this push:
new 6f23b37a3 feat: add warning to github test connection (#5205)
6f23b37a3 is described below
commit 6f23b37a32430f65f1b6fe27b287e64fe2c7ea42
Author: Klesh Wong <zh...@merico.dev>
AuthorDate: Mon May 22 11:07:05 2023 +0800
feat: add warning to github test connection (#5205)
---
backend/plugins/github/api/connection.go | 75 ++++++++++++++++++---------
backend/plugins/github/api/connection_test.go | 50 ++++++++++++++++++
2 files changed, 101 insertions(+), 24 deletions(-)
diff --git a/backend/plugins/github/api/connection.go b/backend/plugins/github/api/connection.go
index 158eac572..76e612701 100644
--- a/backend/plugins/github/api/connection.go
+++ b/backend/plugins/github/api/connection.go
@@ -19,6 +19,7 @@ package api
import (
"context"
+ "fmt"
"net/http"
"strings"
@@ -29,11 +30,31 @@ import (
"github.com/apache/incubator-devlake/server/api/shared"
)
-var requirePermission = []string{"repo:status", "repo_deployment", "read:user", "read:org"}
+var publicPermissions = []string{"repo:status", "repo_deployment", "read:user", "read:org"}
+var privatePermissions = []string{"repo"}
+var parentPermissions = map[string]string{
+ "repo:status": "repo",
+ "repo_deployment": "repo",
+ "read:user": "user",
+ "read:org": "admin:org",
+}
+
+// findMissingPerms returns the missing required permissions from the given user permissions
+func findMissingPerms(userPerms map[string]bool, requiredPerms []string) []string {
+ missingPerms := make([]string, 0)
+ for _, pp := range requiredPerms {
+ // either the specific permission or its parent permission(larger) is granted
+ if !userPerms[pp] && !userPerms[parentPermissions[pp]] {
+ missingPerms = append(missingPerms, pp)
+ }
+ }
+ return missingPerms
+}
type GithubTestConnResponse struct {
shared.ApiBody
- Login string `json:"login"`
+ Login string `json:"login"`
+ Warning bool `json:"warning"`
}
// @Summary test github connection
@@ -77,35 +98,41 @@ func TestConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
return nil, errors.BadInput.Wrap(err, "invalid token")
}
+ success := false
+ warning := false
+ messages := []string{}
// for github classic token, check permission
if strings.HasPrefix(conn.Token, "ghp_") {
scopes := res.Header.Get("X-OAuth-Scopes")
- for _, permission := range requirePermission {
- if !strings.Contains(scopes, permission) {
- if permission == "repo:status" || permission == "repo_deployment" {
- // If the missing permission is repo:status or repo_deployment, check if the repo permission is present
- if strings.Contains(scopes, "repo") {
- continue
- }
- }
- if permission == "read:user" {
- if strings.Contains(scopes, "user") {
- continue
- }
- }
- if permission == "read:org" {
- if strings.Contains(scopes, "admin:org") {
- continue
- }
- }
- return nil, errors.BadInput.New("insufficient token permission")
- }
+ // convert "X-OAuth-Scopes" header to user permissions map
+ userPerms := map[string]bool{}
+ for _, userPerm := range strings.Split(scopes, ", ") {
+ userPerms[userPerm] = true
+ }
+ // check public repo permission
+ missingPubPerms := findMissingPerms(userPerms, publicPermissions)
+ success = len(missingPubPerms) == 0
+ if !success {
+ messages = append(messages, fmt.Sprintf(
+ "%s is/are required to collect data from Public Repos",
+ strings.Join(missingPubPerms, ", "),
+ ))
+ }
+ // check private repo permission
+ missingPriPerms := findMissingPerms(userPerms, privatePermissions)
+ warning = len(missingPriPerms) > 0
+ if warning {
+ messages = append(messages, fmt.Sprintf(
+ "%s is/are required to collect data from Private Repos",
+ strings.Join(missingPriPerms, ", "),
+ ))
}
}
githubApiResponse := &GithubTestConnResponse{}
- githubApiResponse.Success = true
- githubApiResponse.Message = "success"
+ githubApiResponse.Success = success
+ githubApiResponse.Warning = warning
+ githubApiResponse.Message = strings.Join(messages, ";\n")
githubApiResponse.Login = githubUserOfToken.Login
return &plugin.ApiResourceOutput{Body: githubApiResponse, Status: http.StatusOK}, nil
}
diff --git a/backend/plugins/github/api/connection_test.go b/backend/plugins/github/api/connection_test.go
new file mode 100644
index 000000000..5f9a239f3
--- /dev/null
+++ b/backend/plugins/github/api/connection_test.go
@@ -0,0 +1,50 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF 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.
+*/
+
+package api
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestFindMissingPerms(t *testing.T) {
+ // permission is larger than required
+ userPerms := map[string]bool{
+ "repo": true,
+ }
+ requiredPerms := []string{"repo:status"}
+ missingPerms := findMissingPerms(userPerms, requiredPerms)
+ assert.Empty(t, missingPerms)
+
+ // permission equals to required
+ userPerms = map[string]bool{
+ "repo:status": true,
+ }
+ requiredPerms = []string{"repo:status"}
+ missingPerms = findMissingPerms(userPerms, requiredPerms)
+ assert.Empty(t, missingPerms)
+
+ // permissions are missing
+ userPerms = map[string]bool{
+ "admin:org": true,
+ }
+ requiredPerms = []string{"repo:status", "read:user"}
+ missingPerms = findMissingPerms(userPerms, requiredPerms)
+ assert.Equal(t, []string{"repo:status", "read:user"}, missingPerms)
+}