mirror of
https://github.com/goharbor/harbor.git
synced 2025-01-03 14:37:44 +01:00
handle the case when docker request token for multiple scopes
This commit is contained in:
parent
54e41ccaaf
commit
0532735d21
@ -42,13 +42,14 @@ func (a *TokenHandler) Get() {
|
|||||||
username, password, _ := request.BasicAuth()
|
username, password, _ := request.BasicAuth()
|
||||||
authenticated := authenticate(username, password)
|
authenticated := authenticate(username, password)
|
||||||
service := a.GetString("service")
|
service := a.GetString("service")
|
||||||
scope := a.GetString("scope")
|
scopes := a.GetStrings("scope")
|
||||||
|
log.Debugf("scopes: %+v", scopes)
|
||||||
|
|
||||||
if len(scope) == 0 && !authenticated {
|
if len(scopes) == 0 && !authenticated {
|
||||||
log.Info("login request with invalid credentials")
|
log.Info("login request with invalid credentials")
|
||||||
a.CustomAbort(http.StatusUnauthorized, "")
|
a.CustomAbort(http.StatusUnauthorized, "")
|
||||||
}
|
}
|
||||||
access := svc_utils.GetResourceActions(scope)
|
access := svc_utils.GetResourceActions(scopes)
|
||||||
for _, a := range access {
|
for _, a := range access {
|
||||||
svc_utils.FilterAccess(username, authenticated, a)
|
svc_utils.FilterAccess(username, authenticated, a)
|
||||||
}
|
}
|
||||||
|
@ -38,17 +38,19 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// GetResourceActions ...
|
// GetResourceActions ...
|
||||||
func GetResourceActions(scope string) []*token.ResourceActions {
|
func GetResourceActions(scopes []string) []*token.ResourceActions {
|
||||||
var res []*token.ResourceActions
|
var res []*token.ResourceActions
|
||||||
if scope == "" {
|
for _, s := range scopes {
|
||||||
return res
|
if s == "" {
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
items := strings.Split(scope, ":")
|
items := strings.Split(s, ":")
|
||||||
res = append(res, &token.ResourceActions{
|
res = append(res, &token.ResourceActions{
|
||||||
Type: items[0],
|
Type: items[0],
|
||||||
Name: items[1],
|
Name: items[1],
|
||||||
Actions: strings.Split(items[2], ","),
|
Actions: strings.Split(items[2], ","),
|
||||||
})
|
})
|
||||||
|
}
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,9 +68,12 @@ func FilterAccess(username string, authenticated bool, a *token.ResourceActions)
|
|||||||
if strings.Contains(a.Name, "/") { //Only check the permission when the requested image has a namespace, i.e. project
|
if strings.Contains(a.Name, "/") { //Only check the permission when the requested image has a namespace, i.e. project
|
||||||
projectName := a.Name[0:strings.LastIndex(a.Name, "/")]
|
projectName := a.Name[0:strings.LastIndex(a.Name, "/")]
|
||||||
var permission string
|
var permission string
|
||||||
var err error
|
|
||||||
if authenticated {
|
if authenticated {
|
||||||
if username == "admin" {
|
isAdmin, err := dao.IsAdminRole(username)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("Error occurred in IsAdminRole: %v")
|
||||||
|
}
|
||||||
|
if isAdmin {
|
||||||
exist, err := dao.ProjectExists(projectName)
|
exist, err := dao.ProjectExists(projectName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Error occurred in CheckExistProject: %v", err)
|
log.Errorf("Error occurred in CheckExistProject: %v", err)
|
||||||
@ -100,8 +105,8 @@ func FilterAccess(username string, authenticated bool, a *token.ResourceActions)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GenTokenForUI is for the UI process to call, so it won't establish a https connection from UI to proxy.
|
// GenTokenForUI is for the UI process to call, so it won't establish a https connection from UI to proxy.
|
||||||
func GenTokenForUI(username, service, scope string) (string, error) {
|
func GenTokenForUI(username string, service string, scopes []string) (string, error) {
|
||||||
access := GetResourceActions(scope)
|
access := GetResourceActions(scopes)
|
||||||
for _, a := range access {
|
for _, a := range access {
|
||||||
FilterAccess(username, true, a)
|
FilterAccess(username, true, a)
|
||||||
}
|
}
|
||||||
|
@ -63,14 +63,15 @@ func RegistryAPIGet(url, username string) ([]byte, error) {
|
|||||||
authenticate := response.Header.Get("WWW-Authenticate")
|
authenticate := response.Header.Get("WWW-Authenticate")
|
||||||
log.Debugf("authenticate header: %s", authenticate)
|
log.Debugf("authenticate header: %s", authenticate)
|
||||||
var service string
|
var service string
|
||||||
var scope string
|
var scopes []string
|
||||||
|
//Disregard the case for hanlding multiple scopes for http call initiated from UI, as there's refactor planned.
|
||||||
re := regexp.MustCompile(`service=\"(.*?)\".*scope=\"(.*?)\"`)
|
re := regexp.MustCompile(`service=\"(.*?)\".*scope=\"(.*?)\"`)
|
||||||
res := re.FindStringSubmatch(authenticate)
|
res := re.FindStringSubmatch(authenticate)
|
||||||
if len(res) > 2 {
|
if len(res) > 2 {
|
||||||
service = res[1]
|
service = res[1]
|
||||||
scope = res[2]
|
scopes = append(scopes, res[2])
|
||||||
}
|
}
|
||||||
token, err := GenTokenForUI(username, service, scope)
|
token, err := GenTokenForUI(username, service, scopes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user