* Pass role to Grafana using auth proxy
By default, the role will be applied to the default org of the user.
If the request uses the standard header "X-Grafana-Org-Id", the role will be applied to the specified org
Tested in both unit test and manually E2E
* Address comment: only allow the user role to be applied to the default org
Co-authored-by: Leonard Gram <leo@xlson.com>
(cherry picked from commit ad1f792b8b)
Co-authored-by: yuwaMSFT2 <yuwa@microsoft.com>
This commit is contained in:
co-authored by
yuwaMSFT2
parent
f18749927c
commit
4308a77e27
@@ -45,7 +45,7 @@ var isLDAPEnabled = func(cfg *setting.Cfg) bool {
|
||||
var newLDAP = multildap.New
|
||||
|
||||
// supportedHeaders states the supported headers configuration fields
|
||||
var supportedHeaderFields = []string{"Name", "Email", "Login", "Groups"}
|
||||
var supportedHeaderFields = []string{"Name", "Email", "Login", "Groups", "Role"}
|
||||
|
||||
// AuthProxy struct
|
||||
type AuthProxy struct {
|
||||
@@ -152,7 +152,7 @@ func HashCacheKey(key string) (string, error) {
|
||||
|
||||
// getKey forms a key for the cache based on the headers received as part of the authentication flow.
|
||||
// Our configuration supports multiple headers. The main header contains the email or username.
|
||||
// And the additional ones that allow us to specify extra attributes: Name, Email or Groups.
|
||||
// And the additional ones that allow us to specify extra attributes: Name, Email, Role, or Groups.
|
||||
func (auth *AuthProxy) getKey() (string, error) {
|
||||
key := strings.TrimSpace(auth.header) // start the key with the main header
|
||||
|
||||
@@ -278,9 +278,23 @@ func (auth *AuthProxy) LoginViaHeader() (int64, error) {
|
||||
}
|
||||
|
||||
auth.headersIterator(func(field string, header string) {
|
||||
if field == "Groups" {
|
||||
switch field {
|
||||
case "Groups":
|
||||
extUser.Groups = util.SplitString(header)
|
||||
} else {
|
||||
case "Role":
|
||||
// If Role header is specified, we update the user role of the default org
|
||||
if header != "" {
|
||||
rt := models.RoleType(header)
|
||||
if rt.IsValid() {
|
||||
extUser.OrgRoles = map[int64]models.RoleType{}
|
||||
orgID := int64(1)
|
||||
if setting.AutoAssignOrg && setting.AutoAssignOrgId > 0 {
|
||||
orgID = int64(setting.AutoAssignOrgId)
|
||||
}
|
||||
extUser.OrgRoles[orgID] = rt
|
||||
}
|
||||
}
|
||||
default:
|
||||
reflect.ValueOf(extUser).Elem().FieldByName(field).SetString(header)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -107,8 +107,9 @@ func TestMiddlewareContext(t *testing.T) {
|
||||
t.Run("When the cache key contains additional headers", func(t *testing.T) {
|
||||
const id int64 = 33
|
||||
const group = "grafana-core-team"
|
||||
const role = "Admin"
|
||||
|
||||
h, err := HashCacheKey(hdrName + "-" + group)
|
||||
h, err := HashCacheKey(hdrName + "-" + group + "-" + role)
|
||||
require.NoError(t, err)
|
||||
key := fmt.Sprintf(CachePrefix, h)
|
||||
err = cache.Set(key, id, 0)
|
||||
@@ -116,9 +117,10 @@ func TestMiddlewareContext(t *testing.T) {
|
||||
|
||||
auth := prepareMiddleware(t, cache, func(req *http.Request, cfg *setting.Cfg) {
|
||||
req.Header.Set("X-WEBAUTH-GROUPS", group)
|
||||
cfg.AuthProxyHeaders = map[string]string{"Groups": "X-WEBAUTH-GROUPS"}
|
||||
req.Header.Set("X-WEBAUTH-ROLE", role)
|
||||
cfg.AuthProxyHeaders = map[string]string{"Groups": "X-WEBAUTH-GROUPS", "Role": "X-WEBAUTH-ROLE"}
|
||||
})
|
||||
assert.Equal(t, "auth-proxy-sync-ttl:14f69b7023baa0ac98c96b31cec07bc0", key)
|
||||
assert.Equal(t, "auth-proxy-sync-ttl:f5acfffd56daac98d502ef8c8b8c5d56", key)
|
||||
|
||||
gotID, err := auth.Login(logger, false)
|
||||
require.NoError(t, err)
|
||||
|
||||
Reference in New Issue
Block a user