mirror of
https://github.com/goharbor/harbor.git
synced 2025-01-23 16:11:24 +01:00
implement admiral login
This commit is contained in:
parent
81c475eb93
commit
94822746f1
@ -15,6 +15,7 @@
|
||||
package authcontext
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
@ -93,29 +94,18 @@ func (a *AuthContext) HasAllPerm(project string) bool {
|
||||
|
||||
// GetByToken ...
|
||||
func GetByToken(token string) (*AuthContext, error) {
|
||||
endpoint := config.AdmiralEndpoint()
|
||||
path := strings.TrimRight(endpoint, "/") + "/sso/auth-context"
|
||||
req, err := http.NewRequest(http.MethodGet, path, nil)
|
||||
req, err := http.NewRequest(http.MethodGet, buildCtxURL(), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req.Header.Add(AuthTokenHeader, token)
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
code, _, data, err := send(req)
|
||||
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
if code != http.StatusOK {
|
||||
return nil, fmt.Errorf("failed to get auth context by token: %d %s",
|
||||
resp.StatusCode, string(data))
|
||||
code, string(data))
|
||||
}
|
||||
|
||||
ctx := &AuthContext{
|
||||
@ -127,3 +117,59 @@ func GetByToken(token string) (*AuthContext, error) {
|
||||
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
// Login ...
|
||||
func Login(username, password string) (string, *AuthContext, error) {
|
||||
data, err := json.Marshal(&struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
}{
|
||||
Username: username,
|
||||
Password: password,
|
||||
})
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
req, err := http.NewRequest(http.MethodPost, buildLoginURL(), bytes.NewBuffer(data))
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
code, header, data, err := send(req)
|
||||
if code != http.StatusOK {
|
||||
return "", nil, fmt.Errorf("failed to login with user %s: %d %s", username,
|
||||
code, string(data))
|
||||
}
|
||||
|
||||
ctx := &AuthContext{
|
||||
Projects: make(map[string][]string),
|
||||
}
|
||||
if err = json.Unmarshal(data, ctx); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
return header.Get(AuthTokenHeader), ctx, nil
|
||||
}
|
||||
|
||||
func send(req *http.Request) (int, http.Header, []byte, error) {
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return 0, nil, nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return 0, nil, nil, err
|
||||
}
|
||||
return resp.StatusCode, resp.Header, data, nil
|
||||
}
|
||||
|
||||
func buildCtxURL() string {
|
||||
return strings.TrimRight(config.AdmiralEndpoint(), "/") + "/sso/auth-context"
|
||||
}
|
||||
|
||||
func buildLoginURL() string {
|
||||
return strings.TrimRight(config.AdmiralEndpoint(), "/") + "/sso/login"
|
||||
}
|
||||
|
@ -51,6 +51,7 @@ func Init() {
|
||||
if config.WithAdmiral() {
|
||||
reqCtxModifiers = []ReqCtxModifier{
|
||||
&secretReqCtxModifier{},
|
||||
&basicAuthReqCtxModifier{},
|
||||
&tokenReqCtxModifier{},
|
||||
&unauthorizedReqCtxModifier{}}
|
||||
return
|
||||
@ -123,34 +124,43 @@ func (b *basicAuthReqCtxModifier) Modify(ctx *beegoctx.Context) bool {
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
user, err := auth.Login(models.AuthModel{
|
||||
Principal: username,
|
||||
Password: password,
|
||||
})
|
||||
if err != nil {
|
||||
log.Errorf("failed to authenticate %s: %v", username, err)
|
||||
return false
|
||||
}
|
||||
if user == nil {
|
||||
return false
|
||||
}
|
||||
log.Debug("got user information via basic auth")
|
||||
|
||||
var securCtx security.Context
|
||||
var pm projectmanager.ProjectManager
|
||||
log.Debug("got user information via basic auth")
|
||||
|
||||
if config.WithAdmiral() {
|
||||
// integration with admiral
|
||||
// we can add logic here to support basic auth in integration mode
|
||||
log.Debug("basic auth isn't supported in integration mode")
|
||||
return false
|
||||
}
|
||||
token, authCtx, err := authcontext.Login(username, password)
|
||||
if err != nil {
|
||||
log.Errorf("failed to authenticate %s: %v", username, err)
|
||||
return false
|
||||
}
|
||||
|
||||
// standalone
|
||||
log.Debug("using local database project manager")
|
||||
pm = config.GlobalProjectMgr
|
||||
log.Debug("creating local database security context...")
|
||||
securCtx = local.NewSecurityContext(user, pm)
|
||||
log.Debug("creating PMS project manager...")
|
||||
pm = pms.NewProjectManager(config.AdmiralEndpoint(), token)
|
||||
|
||||
log.Debug("creating admiral security context...")
|
||||
securCtx = admiral.NewSecurityContext(authCtx, pm)
|
||||
} else {
|
||||
// standalone
|
||||
user, err := auth.Login(models.AuthModel{
|
||||
Principal: username,
|
||||
Password: password,
|
||||
})
|
||||
if err != nil {
|
||||
log.Errorf("failed to authenticate %s: %v", username, err)
|
||||
return false
|
||||
}
|
||||
if user == nil {
|
||||
log.Debug("basic auth user is nil")
|
||||
return false
|
||||
}
|
||||
log.Debug("using local database project manager")
|
||||
pm = config.GlobalProjectMgr
|
||||
log.Debug("creating local database security context...")
|
||||
securCtx = local.NewSecurityContext(user, pm)
|
||||
}
|
||||
|
||||
setSecurCtxAndPM(ctx.Request, securCtx, pm)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user