handle the case when docker request token for multiple scopes

This commit is contained in:
Tan Jiang 2016-04-05 19:48:13 +08:00
parent 54e41ccaaf
commit 0532735d21
3 changed files with 26 additions and 19 deletions

View File

@ -42,13 +42,14 @@ func (a *TokenHandler) Get() {
username, password, _ := request.BasicAuth()
authenticated := authenticate(username, password)
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")
a.CustomAbort(http.StatusUnauthorized, "")
}
access := svc_utils.GetResourceActions(scope)
access := svc_utils.GetResourceActions(scopes)
for _, a := range access {
svc_utils.FilterAccess(username, authenticated, a)
}

View File

@ -38,17 +38,19 @@ const (
)
// GetResourceActions ...
func GetResourceActions(scope string) []*token.ResourceActions {
func GetResourceActions(scopes []string) []*token.ResourceActions {
var res []*token.ResourceActions
if scope == "" {
return res
for _, s := range scopes {
if s == "" {
continue
}
items := strings.Split(s, ":")
res = append(res, &token.ResourceActions{
Type: items[0],
Name: items[1],
Actions: strings.Split(items[2], ","),
})
}
items := strings.Split(scope, ":")
res = append(res, &token.ResourceActions{
Type: items[0],
Name: items[1],
Actions: strings.Split(items[2], ","),
})
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
projectName := a.Name[0:strings.LastIndex(a.Name, "/")]
var permission string
var err error
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)
if err != nil {
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.
func GenTokenForUI(username, service, scope string) (string, error) {
access := GetResourceActions(scope)
func GenTokenForUI(username string, service string, scopes []string) (string, error) {
access := GetResourceActions(scopes)
for _, a := range access {
FilterAccess(username, true, a)
}

View File

@ -63,14 +63,15 @@ func RegistryAPIGet(url, username string) ([]byte, error) {
authenticate := response.Header.Get("WWW-Authenticate")
log.Debugf("authenticate header: %s", authenticate)
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=\"(.*?)\"`)
res := re.FindStringSubmatch(authenticate)
if len(res) > 2 {
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 {
return nil, err
}