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 7214507b6 fix: github create connection failed with InstallationId 
required error when auth method is AccessToken (#5325)
7214507b6 is described below

commit 7214507b6c0f1b3be0fd8bef6f77c30e22f7dc6e
Author: Klesh Wong <[email protected]>
AuthorDate: Wed May 31 15:19:09 2023 +0800

    fix: github create connection failed with InstallationId required error 
when auth method is AccessToken (#5325)
    
    * refactor: rename transformation rule to scope config - jira
    
    * fix: jira unit test failed after scopeConfig refactor
    
    * fix: github create connection failed with InstallationId required error 
when auth method is AccessToken
---
 .../helpers/pluginhelper/api/connection_auths.go   | 32 ++++++++++--
 backend/plugins/github/models/connection.go        |  4 +-
 backend/plugins/github/models/connection_test.go   | 61 ++++++++++++++++++++++
 3 files changed, 91 insertions(+), 6 deletions(-)

diff --git a/backend/helpers/pluginhelper/api/connection_auths.go 
b/backend/helpers/pluginhelper/api/connection_auths.go
index 9b7860208..acb4da04d 100644
--- a/backend/helpers/pluginhelper/api/connection_auths.go
+++ b/backend/helpers/pluginhelper/api/connection_auths.go
@@ -20,10 +20,12 @@ package api
 import (
        "encoding/base64"
        "fmt"
-       "github.com/apache/incubator-devlake/core/plugin"
        "net/http"
+       "reflect"
        "strings"
 
+       "github.com/apache/incubator-devlake/core/plugin"
+
        "github.com/apache/incubator-devlake/core/errors"
        "github.com/go-playground/validator/v10"
 )
@@ -148,16 +150,38 @@ func (ma *MultiAuth) ValidateConnection(connection 
interface{}, v *validator.Val
        validationErrors := v.Struct(connection).(validator.ValidationErrors)
        if validationErrors != nil {
                filteredValidationErrors := make(validator.ValidationErrors, 0)
+               connType := reflect.TypeOf(connection).Elem()
                for _, e := range validationErrors {
-                       // JiraConnection.JiraConn.BasicAuth.Username
                        ns := strings.Split(e.Namespace(), ".")
                        if len(ns) > 1 {
-                               // BasicAuth
+                               // case 1: using the origin Authenticator 
directly, e.g. BasicAuth in JiraConnection.JiraConn.BasicAuth.Username
                                authName := ns[len(ns)-2]
                                if plugin.ALL_AUTH[authName] && authName != 
ma.AuthMethod {
                                        continue
                                }
-                               filteredValidationErrors = 
append(filteredValidationErrors, e)
+                               // case 2: embed origin Authenticator, e.g. 
GithubAppKey from
+                               // 
https://github.com/apache/incubator-devlake/blob/16f97a1a7605d5ce7cf391bbec1270eec7c77b6e/backend/plugins/github/models/connection.go#L41
+                               // skip the error if the field doesn't belong 
to the current authMethod
+                               shouldInclude := true
+                               t := connType
+                               // search from outer to inner of the struct to 
see if any field has tag `authMethod`
+                               for _, n := range ns[1:] {
+                                       if field, ok := t.FieldByName(n); ok {
+                                               authMethod := 
field.Tag.Get("authMethod")
+                                               // drop error if authMethod was 
marked and it doesn't equal to current AutheMethod
+                                               if authMethod != "" && 
authMethod != ma.AuthMethod {
+                                                       shouldInclude = false
+                                                       break
+                                               }
+                                               t = field.Type
+                                               if t.Kind() == reflect.Ptr {
+                                                       t = t.Elem()
+                                               }
+                                       }
+                               }
+                               if shouldInclude {
+                                       filteredValidationErrors = 
append(filteredValidationErrors, e)
+                               }
                        }
                }
                if len(filteredValidationErrors) > 0 {
diff --git a/backend/plugins/github/models/connection.go 
b/backend/plugins/github/models/connection.go
index b321ff86b..b1ac0252b 100644
--- a/backend/plugins/github/models/connection.go
+++ b/backend/plugins/github/models/connection.go
@@ -47,8 +47,8 @@ type GithubAppKey struct {
 type GithubConn struct {
        helper.RestConnection `mapstructure:",squash"`
        helper.MultiAuth      `mapstructure:",squash"`
-       GithubAccessToken     `mapstructure:",squash"`
-       GithubAppKey          `mapstructure:",squash"`
+       GithubAccessToken     `mapstructure:",squash" authMethod:"AccessToken"`
+       GithubAppKey          `mapstructure:",squash" authMethod:"AppKey"`
 }
 
 // PrepareApiClient splits Token to tokens for SetupAuthentication to utilize
diff --git a/backend/plugins/github/models/connection_test.go 
b/backend/plugins/github/models/connection_test.go
new file mode 100644
index 000000000..3c04d0951
--- /dev/null
+++ b/backend/plugins/github/models/connection_test.go
@@ -0,0 +1,61 @@
+/*
+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 models
+
+import (
+       "testing"
+
+       "github.com/go-playground/validator/v10"
+       "github.com/stretchr/testify/assert"
+)
+
+func TestAccessTokenSuccess(t *testing.T) {
+       accessToken := &GithubConnection{}
+       accessToken.AuthMethod = "AccessToken"
+       accessToken.Endpoint = "https://api.github.com/";
+       accessToken.Name = "test"
+       accessToken.Token = "some_token"
+       err := accessToken.ValidateConnection(accessToken, validator.New())
+       assert.NoError(t, err)
+}
+
+func TestAccessTokenFail(t *testing.T) {
+       accessToken := &GithubConnection{}
+       accessToken.AuthMethod = "AccessToken"
+       accessToken.Endpoint = "https://api.github.com/";
+       accessToken.Name = "test"
+       accessToken.Token = ""
+       err := accessToken.ValidateConnection(accessToken, validator.New())
+       if assert.Error(t, err) {
+               assert.Contains(t, err.Error(), "Token")
+       }
+}
+
+func TestAppKeyFail(t *testing.T) {
+       appkey := &GithubConnection{}
+       appkey.AuthMethod = "AppKey"
+       appkey.Endpoint = "https://api.github.com/";
+       appkey.Name = "test"
+       err := appkey.ValidateConnection(appkey, validator.New())
+       if assert.Error(t, err) {
+               assert.Contains(t, err.Error(), "InstallationID")
+               assert.Contains(t, err.Error(), "AppId")
+               assert.Contains(t, err.Error(), "SecretKey")
+               println()
+       }
+}

Reply via email to