implement admiral login

This commit is contained in:
Wenkai Yin 2017-06-21 17:50:36 +08:00
parent 81c475eb93
commit 94822746f1
2 changed files with 93 additions and 37 deletions

View File

@ -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"
}

View File

@ -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)