mirror of
https://github.com/goharbor/harbor.git
synced 2024-08-19 18:42:47 +02:00
Merge pull request #2717 from ywk253100/170706_integration
Update auth context as Admiral's API changed
This commit is contained in:
commit
186538010d
|
@ -20,10 +20,12 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"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/utils"
|
||||||
"github.com/vmware/harbor/src/common/utils/log"
|
"github.com/vmware/harbor/src/common/utils/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -37,9 +39,10 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
type project struct {
|
type project struct {
|
||||||
DocumentSelfLink string `json:"documentSelfLink"`
|
SelfLink string `json:"documentSelfLink"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Roles []string `json:"roles"`
|
Roles []string `json:"roles"`
|
||||||
|
Properties map[string]string `json:"customProperties"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// AuthContext ...
|
// AuthContext ...
|
||||||
|
@ -63,29 +66,19 @@ func (a *AuthContext) IsSysAdmin() bool {
|
||||||
|
|
||||||
// GetProjectRoles ...
|
// GetProjectRoles ...
|
||||||
func (a *AuthContext) GetProjectRoles(projectIDOrName interface{}) []int {
|
func (a *AuthContext) GetProjectRoles(projectIDOrName interface{}) []int {
|
||||||
var isID bool
|
id, name, err := utils.ParseProjectIDOrName(projectIDOrName)
|
||||||
var id int64
|
if err != nil {
|
||||||
var name string
|
log.Errorf("failed to parse project ID or name: %v", err)
|
||||||
|
return []int{}
|
||||||
id, isID = projectIDOrName.(int64)
|
|
||||||
if !isID {
|
|
||||||
name, _ = projectIDOrName.(string)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
roles := []string{}
|
roles := []string{}
|
||||||
for _, project := range a.Projects {
|
for _, project := range a.Projects {
|
||||||
p := convertProject(project)
|
p := convertProject(project)
|
||||||
if isID {
|
if p.ProjectID == id || p.Name == name {
|
||||||
if p.ProjectID == id {
|
|
||||||
roles = append(roles, project.Roles...)
|
roles = append(roles, project.Roles...)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if p.Name == name {
|
|
||||||
roles = append(roles, project.Roles...)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return convertRoles(roles)
|
return convertRoles(roles)
|
||||||
|
@ -100,12 +93,29 @@ func (a *AuthContext) GetMyProjects() []*models.Project {
|
||||||
return projects
|
return projects
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO populate harbor ID to the project
|
|
||||||
// convert project returned by Admiral to project used in Harbor
|
// convert project returned by Admiral to project used in Harbor
|
||||||
func convertProject(p *project) *models.Project {
|
func convertProject(p *project) *models.Project {
|
||||||
project := &models.Project{
|
project := &models.Project{
|
||||||
Name: p.Name,
|
Name: p.Name,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
index := ""
|
||||||
|
if p.Properties != nil {
|
||||||
|
index = p.Properties["__projectIndex"]
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(index) == 0 {
|
||||||
|
log.Errorf("property __projectIndex not found when parsing project")
|
||||||
|
return project
|
||||||
|
}
|
||||||
|
|
||||||
|
id, err := strconv.ParseInt(index, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("failed to parse __projectIndex %s: %v", index, err)
|
||||||
|
return project
|
||||||
|
}
|
||||||
|
|
||||||
|
project.ProjectID = id
|
||||||
return project
|
return project
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@ func TestGetProjectRoles(t *testing.T) {
|
||||||
&project{
|
&project{
|
||||||
Name: "project",
|
Name: "project",
|
||||||
Roles: []string{projectAdminRole, developerRole, guestRole},
|
Roles: []string{projectAdminRole, developerRole, guestRole},
|
||||||
|
Properties: map[string]string{"__projectIndex": "9"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -52,7 +53,9 @@ func TestGetProjectRoles(t *testing.T) {
|
||||||
roles := ctx.GetProjectRoles("project")
|
roles := ctx.GetProjectRoles("project")
|
||||||
assert.Equal(t, 3, len(roles))
|
assert.Equal(t, 3, len(roles))
|
||||||
|
|
||||||
// TODO add test case with ID
|
// test with ID
|
||||||
|
roles = ctx.GetProjectRoles(9)
|
||||||
|
assert.Equal(t, 3, len(roles))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetMyProjects(t *testing.T) {
|
func TestGetMyProjects(t *testing.T) {
|
|
@ -17,7 +17,7 @@ package admiral
|
||||||
import (
|
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"
|
"github.com/vmware/harbor/src/common/security/admiral/authcontext"
|
||||||
"github.com/vmware/harbor/src/common/utils/log"
|
"github.com/vmware/harbor/src/common/utils/log"
|
||||||
"github.com/vmware/harbor/src/ui/projectmanager"
|
"github.com/vmware/harbor/src/ui/projectmanager"
|
||||||
)
|
)
|
||||||
|
|
|
@ -16,6 +16,7 @@ package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
@ -125,3 +126,34 @@ func ParseTimeStamp(timestamp string) (*time.Time, error) {
|
||||||
t := time.Unix(i, 0)
|
t := time.Unix(i, 0)
|
||||||
return &t, nil
|
return &t, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ParseProjectIDOrName parses value to ID(int64) or name(string)
|
||||||
|
func ParseProjectIDOrName(value interface{}) (int64, string, error) {
|
||||||
|
if value == nil {
|
||||||
|
return 0, "", errors.New("harborIDOrName is nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
var id int64
|
||||||
|
var name string
|
||||||
|
switch value.(type) {
|
||||||
|
case int:
|
||||||
|
i := value.(int)
|
||||||
|
id = int64(i)
|
||||||
|
if id == 0 {
|
||||||
|
return 0, "", fmt.Errorf("invalid ID: 0")
|
||||||
|
}
|
||||||
|
case int64:
|
||||||
|
id = value.(int64)
|
||||||
|
if id == 0 {
|
||||||
|
return 0, "", fmt.Errorf("invalid ID: 0")
|
||||||
|
}
|
||||||
|
case string:
|
||||||
|
name = value.(string)
|
||||||
|
if len(name) == 0 {
|
||||||
|
return 0, "", fmt.Errorf("empty name")
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return 0, "", fmt.Errorf("unsupported type")
|
||||||
|
}
|
||||||
|
return id, name, nil
|
||||||
|
}
|
||||||
|
|
|
@ -211,3 +211,35 @@ func TestParseTimeStamp(t *testing.T) {
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, now, result.Unix())
|
assert.Equal(t, now, result.Unix())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestParseHarborIDOrName(t *testing.T) {
|
||||||
|
// nil input
|
||||||
|
id, name, err := ParseProjectIDOrName(nil)
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
|
||||||
|
// invalid ID
|
||||||
|
id, name, err = ParseProjectIDOrName(0)
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
|
||||||
|
// invalid name
|
||||||
|
id, name, err = ParseProjectIDOrName("")
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
|
||||||
|
// valid int ID
|
||||||
|
id, name, err = ParseProjectIDOrName(1)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, int64(1), id)
|
||||||
|
assert.Equal(t, "", name)
|
||||||
|
|
||||||
|
// valid int64 ID
|
||||||
|
id, name, err = ParseProjectIDOrName(int64(1))
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, int64(1), id)
|
||||||
|
assert.Equal(t, "", name)
|
||||||
|
|
||||||
|
// valid name
|
||||||
|
id, name, err = ParseProjectIDOrName("project")
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, int64(0), id)
|
||||||
|
assert.Equal(t, "project", name)
|
||||||
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ import (
|
||||||
secstore "github.com/vmware/harbor/src/common/secret"
|
secstore "github.com/vmware/harbor/src/common/secret"
|
||||||
"github.com/vmware/harbor/src/common/security"
|
"github.com/vmware/harbor/src/common/security"
|
||||||
"github.com/vmware/harbor/src/common/security/admiral"
|
"github.com/vmware/harbor/src/common/security/admiral"
|
||||||
"github.com/vmware/harbor/src/common/security/authcontext"
|
"github.com/vmware/harbor/src/common/security/admiral/authcontext"
|
||||||
"github.com/vmware/harbor/src/common/security/local"
|
"github.com/vmware/harbor/src/common/security/local"
|
||||||
"github.com/vmware/harbor/src/common/security/secret"
|
"github.com/vmware/harbor/src/common/security/secret"
|
||||||
"github.com/vmware/harbor/src/common/utils/log"
|
"github.com/vmware/harbor/src/common/utils/log"
|
||||||
|
@ -99,19 +99,14 @@ func (s *secretReqCtxModifier) Modify(ctx *beegoctx.Context) bool {
|
||||||
if len(scrt) == 0 {
|
if len(scrt) == 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debug("got secret from request")
|
log.Debug("got secret from request")
|
||||||
|
|
||||||
var pm projectmanager.ProjectManager
|
log.Debug("using global project manager")
|
||||||
if config.WithAdmiral() {
|
pm := config.GlobalProjectMgr
|
||||||
// TODO project manager with harbor service accout
|
|
||||||
} else {
|
|
||||||
log.Debug("using local database project manager")
|
|
||||||
pm = config.GlobalProjectMgr
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debug("creating a secret security context...")
|
log.Debug("creating a secret security context...")
|
||||||
securCtx := secret.NewSecurityContext(scrt, s.store)
|
securCtx := secret.NewSecurityContext(scrt, s.store)
|
||||||
|
|
||||||
setSecurCtxAndPM(ctx.Request, securCtx, pm)
|
setSecurCtxAndPM(ctx.Request, securCtx, pm)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
|
Loading…
Reference in New Issue
Block a user