/* Given a token, return true if the token is valid for one of the roles listed in role. Role is a list of space separated role names. Token is expected to be token/projectr; we will test only with the indicated project. 2015.12.09 - We will only accept token/project strings as trying a token against every proejct that Tegu knows about doesn't scale in the openstack world, and openstack doesn't make a 'generic' crack function available. If a string is passed as token and _NOT_ token/project it will be rejected with an appropriate error. WARNING: If the token passed to us to crack is not a valid token the error message that openstack returns might be very misleading, suggesting that Tegu is not authorised to crack the token: Unauthorized (401): The request you have made requires authentication. This is not cool openstack. The token is invalid, full stop and you should say so. */ func has_any_role(os_refs map[string]*ostack.Ostack, admin *ostack.Ostack, token *string, roles *string) (userproj string, err error) { rtoks := strings.Split(*roles, ",") // simple tokenising of role list userproj = "" if strings.Contains(*token, "/") { // assume it's token/project (could also be tok/proj/junk) const p int = 1 // order in split tokens (project) const t int = 0 // order in split tokens (actual token) toks := strings.Split(*token, "/") if toks[p] == "" { osif_sheep.Baa(2, "has_any_role: project/token had empty project") return "", fmt.Errorf("project portion of token/project was empty") } stuff, err := admin.Crack_ptoken(&toks[t], &toks[p], false) // crack user info based on project and token if err == nil { state := gizmos.Map_has_any(stuff.Roles, rtoks) // true if any from rtoks list matches any in Roles if state { osif_sheep.Baa(2, "has_any_role: token/project validated for roles: %s", *roles) return (stuff.User + "," + stuff.TenantId), nil } else { err = fmt.Errorf("none matched") } } osif_sheep.Baa(2, "has_any_role: token/project %s/%s not valid for roles: %s: %s (caution, 401 error from openstack is misleading if it suggests the request requires auth)", toks[0], toks[1], *roles, err) return "", fmt.Errorf("has_any_role: token/project not valid for roles: %s: %s", *roles, err) } return "", fmt.Errorf("has_any_role: rejected: data was NOT of the form token/project") }
/* Given a token, return true if the token is valid for one of the roles listed in role. Role is a list of space separated role names. If token is actually tokken/project, then we will test only with the indicated project. Otherwise we will test the token against every project we know about and return true if any of the roles in the list is defined for the user in any project. This _is_ needed to authenticate Tegu requests which are not directly project oriented (e.g. set capacities, graph, etc.), so it is legitimate for a token to be submitted without a leading project/ string. */ func has_any_role(os_refs map[string]*ostack.Ostack, admin *ostack.Ostack, token *string, roles *string) (has_role bool, err error) { rtoks := strings.Split(*roles, ",") // simple tokenising of role list has_role = false if strings.Contains(*token, "/") { // assume it's token/project const p int = 1 // order in split tokens (project) const t int = 0 // order in split tokens (actual token) toks := strings.Split(*token, "/") if toks[p] == "" { osif_sheep.Baa(2, "has_any_role: project/token had empty project") return false, fmt.Errorf("project portion of token/project was empty") } stuff, err := admin.Crack_ptoken(&toks[t], &toks[p], false) // crack user info based on project and token if err == nil { state := gizmos.Map_has_any(stuff.Roles, rtoks) // true if any from rtoks list matches any in Roles if state { osif_sheep.Baa(2, "has_any_role: token/project validated for roles: %s", *roles) return true, nil } else { err = fmt.Errorf("none matched") } } osif_sheep.Baa(2, "has_any_role: token/project not valid for roles: %s: %s", *roles, err) return false, fmt.Errorf("has_any_role: token/project not valid for roles: %s: %s", roles, err) } for _, v := range os_refs { pname, _ := v.Get_project() osif_sheep.Baa(2, "has_any_role: checking %s", *pname) stuff, err := admin.Crack_ptoken(token, pname, false) // return a stuff struct with details about the token if err == nil { err = fmt.Errorf("role not defined; %s", *roles) // asume error state := gizmos.Map_has_any(stuff.Roles, rtoks) // true if any role token matches anything from ostack if state { osif_sheep.Baa(2, "has_any_role: verified in %s", *pname) return true, nil } } else { osif_sheep.Baa(2, "has_any_role: crack failed for project=%s: %s", *pname, err) } } if err == nil { err = fmt.Errorf("undetermined reason") } osif_sheep.Baa(1, "unable to verify role: %s: %s", *roles, err) return false, err }