Merge pull request #2649 from ywk253100/170627_service_account

Implement GetByMember function in PMS project manager
This commit is contained in:
Wenkai Yin 2017-06-28 15:25:21 +08:00 committed by GitHub
commit ab65bca2fe
6 changed files with 78 additions and 24 deletions

View File

@ -21,8 +21,6 @@ import (
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"strings" "strings"
"github.com/vmware/harbor/src/ui/config"
) )
const ( const (
@ -92,9 +90,31 @@ func (a *AuthContext) HasAllPerm(project string) bool {
return false return false
} }
// GetByToken ... // GetMyProjects returns all projects which the user is a member of
func GetByToken(token string) (*AuthContext, error) { func (a *AuthContext) GetMyProjects() ([]string, error) {
req, err := http.NewRequest(http.MethodGet, buildCtxURL(), nil) existence := map[string]string{}
projects := []string{}
for _, list := range a.Projects {
for _, p := range list {
if len(existence[p]) > 0 {
continue
}
existence[p] = p
projects = append(projects, p)
}
}
return projects, nil
}
// GetByToken gets the user's auth context, if the username is not provided
// get the default auth context of the token
func GetByToken(url, token string, username ...string) (*AuthContext, error) {
principalID := ""
if len(username) > 0 {
principalID = username[0]
}
req, err := http.NewRequest(http.MethodGet, buildCtxURL(url, principalID), nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -119,7 +139,7 @@ func GetByToken(token string) (*AuthContext, error) {
} }
// Login ... // Login ...
func Login(username, password string) (string, *AuthContext, error) { func Login(url, username, password string) (string, *AuthContext, error) {
data, err := json.Marshal(&struct { data, err := json.Marshal(&struct {
Username string `json:"username"` Username string `json:"username"`
Password string `json:"password"` Password string `json:"password"`
@ -131,7 +151,7 @@ func Login(username, password string) (string, *AuthContext, error) {
return "", nil, err return "", nil, err
} }
req, err := http.NewRequest(http.MethodPost, buildLoginURL(), bytes.NewBuffer(data)) req, err := http.NewRequest(http.MethodPost, buildLoginURL(url), bytes.NewBuffer(data))
if err != nil { if err != nil {
return "", nil, err return "", nil, err
} }
@ -166,10 +186,14 @@ func send(req *http.Request) (int, http.Header, []byte, error) {
return resp.StatusCode, resp.Header, data, nil return resp.StatusCode, resp.Header, data, nil
} }
func buildCtxURL() string { func buildCtxURL(url, principalID string) string {
return strings.TrimRight(config.AdmiralEndpoint(), "/") + "/sso/auth-context" url = strings.TrimRight(url, "/") + "/sso/auth-context"
if len(principalID) > 0 {
url += "/" + principalID
}
return url
} }
func buildLoginURL() string { func buildLoginURL(url string) string {
return strings.TrimRight(config.AdmiralEndpoint(), "/") + "/sso/login" return strings.TrimRight(url, "/") + "/sso/login"
} }

View File

@ -24,8 +24,8 @@ type Context interface {
IsSysAdmin() bool IsSysAdmin() bool
// HasReadPerm returns whether the user has read permission to the project // HasReadPerm returns whether the user has read permission to the project
HasReadPerm(projectIDOrName interface{}) bool HasReadPerm(projectIDOrName interface{}) bool
// HasWritePerm returns whether the user has write permission to the project // HasWritePerm returns whether the user has write permission to the project
HasWritePerm(projectIDOrName interface{}) bool HasWritePerm(projectIDOrName interface{}) bool
// HasAllPerm returns whether the user has all permissions to the project // HasAllPerm returns whether the user has all permissions to the project
HasAllPerm(projectIDOrName interface{}) bool HasAllPerm(projectIDOrName interface{}) bool
} }

View File

@ -131,7 +131,7 @@ func (b *basicAuthReqCtxModifier) Modify(ctx *beegoctx.Context) bool {
if config.WithAdmiral() { if config.WithAdmiral() {
// integration with admiral // integration with admiral
token, authCtx, err := authcontext.Login(username, password) token, authCtx, err := authcontext.Login(config.AdmiralEndpoint(), username, password)
if err != nil { if err != nil {
log.Errorf("failed to authenticate %s: %v", username, err) log.Errorf("failed to authenticate %s: %v", username, err)
return false return false
@ -204,7 +204,7 @@ func (t *tokenReqCtxModifier) Modify(ctx *beegoctx.Context) bool {
log.Debug("got token from request") log.Debug("got token from request")
authContext, err := authcontext.GetByToken(token) authContext, err := authcontext.GetByToken(config.AdmiralEndpoint(), token)
if err != nil { if err != nil {
log.Errorf("failed to get auth context: %v", err) log.Errorf("failed to get auth context: %v", err)
return false return false

View File

@ -115,6 +115,10 @@ func (p *ProjectManager) GetPublic() ([]*models.Project, error) {
// GetByMember returns all projects which the user is a member of // GetByMember returns all projects which the user is a member of
func (p *ProjectManager) GetByMember(username string) ( func (p *ProjectManager) GetByMember(username string) (
[]*models.Project, error) { []*models.Project, error) {
if len(username) == 0 {
return []*models.Project{}, nil
}
return p.GetAll(&models.ProjectQueryParam{ return p.GetAll(&models.ProjectQueryParam{
Member: &models.MemberQuery{ Member: &models.MemberQuery{
Name: username, Name: username,

View File

@ -153,7 +153,13 @@ func TestGetPublic(t *testing.T) {
func TestGetByMember(t *testing.T) { func TestGetByMember(t *testing.T) {
pm := &ProjectManager{} pm := &ProjectManager{}
projects, err := pm.GetByMember("admin") // empty username
projects, err := pm.GetByMember("")
assert.Nil(t, err)
assert.Equal(t, 0, len(projects))
//non-empty username
projects, err = pm.GetByMember("admin")
assert.Nil(t, err) assert.Nil(t, err)
assert.NotEqual(t, 0, len(projects)) assert.NotEqual(t, 0, len(projects))
} }

View File

@ -28,6 +28,7 @@ import (
"github.com/vmware/harbor/src/common" "github.com/vmware/harbor/src/common"
"github.com/vmware/harbor/src/common/models" "github.com/vmware/harbor/src/common/models"
"github.com/vmware/harbor/src/common/security/authcontext"
er "github.com/vmware/harbor/src/common/utils/error" er "github.com/vmware/harbor/src/common/utils/error"
"github.com/vmware/harbor/src/common/utils/log" "github.com/vmware/harbor/src/common/utils/log"
) )
@ -230,8 +231,11 @@ func (p *ProjectManager) Exist(projectIDOrName interface{}) (bool, error) {
return project != nil, nil return project != nil, nil
} }
// GetRoles ... // GetRoles gets roles that the user has to the project
// TODO empty this method after implementing security context with auth context // This method is used in GET /projects API.
// Jobservice calls GET /projects API to get information of source
// project when trying to replicate the project. There is no auth
// context in this use case, so the method is needed.
func (p *ProjectManager) GetRoles(username string, projectIDOrName interface{}) ([]int, error) { func (p *ProjectManager) GetRoles(username string, projectIDOrName interface{}) ([]int, error) {
if len(username) == 0 || projectIDOrName == nil { if len(username) == 0 || projectIDOrName == nil {
return nil, nil return nil, nil
@ -303,8 +307,26 @@ func (p *ProjectManager) GetPublic() ([]*models.Project, error) {
// GetByMember ... // GetByMember ...
func (p *ProjectManager) GetByMember(username string) ([]*models.Project, error) { func (p *ProjectManager) GetByMember(username string) ([]*models.Project, error) {
// TODO add implement projects := []*models.Project{}
return nil, nil ctx, err := authcontext.GetByToken(p.endpoint, p.token, username)
if err != nil {
return projects, err
}
names, err := ctx.GetMyProjects()
if err != nil {
return projects, err
}
for _, name := range names {
project, err := p.Get(name)
if err != nil {
return projects, err
}
projects = append(projects, project)
}
return projects, nil
} }
// Create ... // Create ...
@ -396,11 +418,9 @@ func (p *ProjectManager) GetTotal(query *models.ProjectQueryParam, base ...*mode
return int64(len(projects)), err return int64(len(projects)), err
} }
// GetHasReadPerm returns all projects that user has read perm to // GetHasReadPerm ...
// TODO maybe can be removed as search isn't implemented in integration mode
func (p *ProjectManager) GetHasReadPerm(username ...string) ([]*models.Project, error) { func (p *ProjectManager) GetHasReadPerm(username ...string) ([]*models.Project, error) {
// TODO add implement return nil, errors.New("GetHasReadPerm is unsupported")
return nil, nil
} }
func (p *ProjectManager) send(method, path string, body io.Reader) ([]byte, error) { func (p *ProjectManager) send(method, path string, body io.Reader) ([]byte, error) {