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(),
|
Timestamp: time.Now().Unix(),
|
||||||
RunID: svr.runID,
|
RunID: svr.runID,
|
||||||
Metas: svr.cfg.Metadatas,
|
Metas: svr.cfg.Metadatas,
|
||||||
|
ApiKey: svr.cfg.ApiKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add auth
|
// Add auth
|
||||||
|
@ -15,7 +15,11 @@
|
|||||||
package auth
|
package auth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
@ -62,10 +66,84 @@ func (auth *TokenAuthSetterVerifier) SetNewWorkConn(newWorkConnMsg *msg.NewWorkC
|
|||||||
return nil
|
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 {
|
func (auth *TokenAuthSetterVerifier) VerifyLogin(m *msg.Login) error {
|
||||||
if !util.ConstantTimeEqString(util.GetAuthKey(auth.token, m.Timestamp), m.PrivilegeKey) {
|
if !util.ConstantTimeEqString(util.GetAuthKey(auth.token, m.Timestamp), m.PrivilegeKey) {
|
||||||
return fmt.Errorf("token in login doesn't match token from configuration")
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,6 +167,8 @@ type ClientCommonConf struct {
|
|||||||
// Enable golang pprof handlers in admin listener.
|
// Enable golang pprof handlers in admin listener.
|
||||||
// Admin port must be set first.
|
// Admin port must be set first.
|
||||||
PprofEnable bool `ini:"pprof_enable" json:"pprof_enable"`
|
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.
|
// Supported sources including: string(file path), []byte, Reader interface.
|
||||||
|
@ -25,6 +25,7 @@ import (
|
|||||||
|
|
||||||
func Convert_ClientCommonConf_To_v1(conf *ClientCommonConf) *v1.ClientCommonConfig {
|
func Convert_ClientCommonConf_To_v1(conf *ClientCommonConf) *v1.ClientCommonConfig {
|
||||||
out := &v1.ClientCommonConfig{}
|
out := &v1.ClientCommonConfig{}
|
||||||
|
out.ApiKey = conf.ApiKey
|
||||||
out.User = conf.User
|
out.User = conf.User
|
||||||
out.Auth.Method = v1.AuthMethod(conf.ClientConfig.AuthenticationMethod)
|
out.Auth.Method = v1.AuthMethod(conf.ClientConfig.AuthenticationMethod)
|
||||||
out.Auth.Token = conf.ClientConfig.Token
|
out.Auth.Token = conf.ClientConfig.Token
|
||||||
|
@ -70,6 +70,8 @@ type ClientCommonConfig struct {
|
|||||||
|
|
||||||
// Include other config files for proxies.
|
// Include other config files for proxies.
|
||||||
IncludeConfigFiles []string `json:"includes,omitempty"`
|
IncludeConfigFiles []string `json:"includes,omitempty"`
|
||||||
|
|
||||||
|
ApiKey string `json:"api_key,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ClientCommonConfig) Complete() {
|
func (c *ClientCommonConfig) Complete() {
|
||||||
|
@ -74,6 +74,7 @@ type Login struct {
|
|||||||
Timestamp int64 `json:"timestamp,omitempty"`
|
Timestamp int64 `json:"timestamp,omitempty"`
|
||||||
RunID string `json:"run_id,omitempty"`
|
RunID string `json:"run_id,omitempty"`
|
||||||
Metas map[string]string `json:"metas,omitempty"`
|
Metas map[string]string `json:"metas,omitempty"`
|
||||||
|
ApiKey string `json:"api_key,omitempty"`
|
||||||
|
|
||||||
// Some global configures.
|
// Some global configures.
|
||||||
PoolCount int `json:"pool_count,omitempty"`
|
PoolCount int `json:"pool_count,omitempty"`
|
||||||
|
Loading…
Reference in New Issue
Block a user