Add harness api call validation support
This commit is contained in:
parent
44985f574d
commit
379f7be90d
@ -268,6 +268,7 @@ func (svr *Service) login() (conn net.Conn, cm *ConnectionManager, err error) {
|
||||
Timestamp: time.Now().Unix(),
|
||||
RunID: svr.runID,
|
||||
Metas: svr.cfg.Metadatas,
|
||||
ApiKey: svr.cfg.ApiKey,
|
||||
}
|
||||
|
||||
// Add auth
|
||||
|
@ -15,7 +15,11 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/samber/lo"
|
||||
@ -62,10 +66,84 @@ func (auth *TokenAuthSetterVerifier) SetNewWorkConn(newWorkConnMsg *msg.NewWorkC
|
||||
return nil
|
||||
}
|
||||
|
||||
func extractBetweenDots(input string) string {
|
||||
firstDotIndex := strings.Index(input, ".")
|
||||
if firstDotIndex == -1 {
|
||||
return ""
|
||||
}
|
||||
|
||||
secondDotIndex := strings.Index(input[firstDotIndex+1:], ".")
|
||||
if secondDotIndex == -1 {
|
||||
return ""
|
||||
}
|
||||
|
||||
extracted := input[firstDotIndex+1 : firstDotIndex+1+secondDotIndex]
|
||||
|
||||
return extracted
|
||||
}
|
||||
func validateApiKey(apiKey string) bool {
|
||||
accoundId := extractBetweenDots(apiKey)
|
||||
|
||||
if accoundId == "" {
|
||||
fmt.Errorf("token in login doesn't match format. Can't extract account ID")
|
||||
return false
|
||||
}
|
||||
|
||||
reqUrl := "https://app.harness.io/authz/api/acl"
|
||||
|
||||
var formated = fmt.Sprintf(`{
|
||||
"permissions": [
|
||||
{
|
||||
"resourceScope": {
|
||||
"accountIdentifier": "%s",
|
||||
"orgIdentifier": "",
|
||||
"projectIdentifier": ""
|
||||
},
|
||||
"resourceType": "PIPLINE",
|
||||
"permission": "core_pipeline_view"
|
||||
}
|
||||
]
|
||||
}`, accoundId)
|
||||
|
||||
req, err := http.NewRequest("POST", reqUrl, bytes.NewReader([]byte(formated)))
|
||||
if err != nil {
|
||||
fmt.Errorf(err.Error())
|
||||
return false
|
||||
}
|
||||
req.Header.Add("Content-Type", "application/json")
|
||||
req.Header.Add("x-api-key", apiKey)
|
||||
res, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
fmt.Errorf("Error calling api call for api key validation")
|
||||
return false
|
||||
}
|
||||
defer res.Body.Close()
|
||||
body, err := ioutil.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
fmt.Errorf("Api key validation response error")
|
||||
return false
|
||||
}
|
||||
|
||||
searchSubstring := `"permitted":true`
|
||||
bodyStr := string(body)
|
||||
|
||||
if !strings.Contains(bodyStr, searchSubstring) {
|
||||
fmt.Errorf("The API key is not valid")
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (auth *TokenAuthSetterVerifier) VerifyLogin(m *msg.Login) error {
|
||||
if !util.ConstantTimeEqString(util.GetAuthKey(auth.token, m.Timestamp), m.PrivilegeKey) {
|
||||
return fmt.Errorf("token in login doesn't match token from configuration")
|
||||
}
|
||||
|
||||
if !validateApiKey(m.ApiKey) {
|
||||
return fmt.Errorf("Harness Api key isn't valid")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -167,6 +167,8 @@ type ClientCommonConf struct {
|
||||
// Enable golang pprof handlers in admin listener.
|
||||
// Admin port must be set first.
|
||||
PprofEnable bool `ini:"pprof_enable" json:"pprof_enable"`
|
||||
|
||||
ApiKey string `ini:"api_key" json:"api_key"`
|
||||
}
|
||||
|
||||
// Supported sources including: string(file path), []byte, Reader interface.
|
||||
|
@ -25,6 +25,7 @@ import (
|
||||
|
||||
func Convert_ClientCommonConf_To_v1(conf *ClientCommonConf) *v1.ClientCommonConfig {
|
||||
out := &v1.ClientCommonConfig{}
|
||||
out.ApiKey = conf.ApiKey
|
||||
out.User = conf.User
|
||||
out.Auth.Method = v1.AuthMethod(conf.ClientConfig.AuthenticationMethod)
|
||||
out.Auth.Token = conf.ClientConfig.Token
|
||||
|
@ -70,6 +70,8 @@ type ClientCommonConfig struct {
|
||||
|
||||
// Include other config files for proxies.
|
||||
IncludeConfigFiles []string `json:"includes,omitempty"`
|
||||
|
||||
ApiKey string `json:"api_key,omitempty"`
|
||||
}
|
||||
|
||||
func (c *ClientCommonConfig) Complete() {
|
||||
|
@ -74,6 +74,7 @@ type Login struct {
|
||||
Timestamp int64 `json:"timestamp,omitempty"`
|
||||
RunID string `json:"run_id,omitempty"`
|
||||
Metas map[string]string `json:"metas,omitempty"`
|
||||
ApiKey string `json:"api_key,omitempty"`
|
||||
|
||||
// Some global configures.
|
||||
PoolCount int `json:"pool_count,omitempty"`
|
||||
|
Loading…
Reference in New Issue
Block a user