From 0532735d2162a6e61702229ad669e6751ba8b8ee Mon Sep 17 00:00:00 2001 From: Tan Jiang Date: Tue, 5 Apr 2016 19:48:13 +0800 Subject: [PATCH] handle the case when docker request token for multiple scopes --- service/token.go | 7 ++++--- service/utils/authutils.go | 31 ++++++++++++++++++------------- service/utils/registryutils.go | 7 ++++--- 3 files changed, 26 insertions(+), 19 deletions(-) diff --git a/service/token.go b/service/token.go index b274be3f8..cd2386833 100644 --- a/service/token.go +++ b/service/token.go @@ -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) } diff --git a/service/utils/authutils.go b/service/utils/authutils.go index 4c00dd579..c8a33710d 100644 --- a/service/utils/authutils.go +++ b/service/utils/authutils.go @@ -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) } diff --git a/service/utils/registryutils.go b/service/utils/registryutils.go index 66c39cd1f..37ada5426 100644 --- a/service/utils/registryutils.go +++ b/service/utils/registryutils.go @@ -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 }