Auth: Add organization mapping configuration to the UI (#90003)

* Add org_mapping and org_attribute_path to the UI

* Add validators, allow setting org mapping to only Grafana Admins

* comment

* Address feedback, improve validation, fix FE test, lint
This commit is contained in:
Misi
2024-07-04 16:00:56 +02:00
committed by GitHub
parent d5b21f77aa
commit b174c1310a
14 changed files with 313 additions and 44 deletions
@@ -12,10 +12,11 @@ import (
)
type testCase struct {
name string
input *social.OAuthInfo
requester identity.Requester
wantErr error
name string
input *social.OAuthInfo
oldSettings *social.OAuthInfo
requester identity.Requester
wantErr error
}
func TestUrlValidator(t *testing.T) {
@@ -81,20 +82,39 @@ func TestRequiredValidator(t *testing.T) {
func TestAllowAssignGrafanaAdminValidator(t *testing.T) {
tc := []testCase{
{
name: "passes when user is grafana admin and allow assign grafana admin is true",
name: "passes when user is Grafana Admin and Allow assign Grafana Admin was changed",
input: &social.OAuthInfo{
AllowAssignGrafanaAdmin: true,
},
oldSettings: &social.OAuthInfo{
AllowAssignGrafanaAdmin: false,
},
requester: &user.SignedInUser{
IsGrafanaAdmin: true,
},
wantErr: nil,
},
{
name: "fails when user is not grafana admin and allow assign grafana admin is true",
name: "passess when user is not Grafana Admin and Allow assign Grafana Admin was not changed",
input: &social.OAuthInfo{
AllowAssignGrafanaAdmin: true,
},
oldSettings: &social.OAuthInfo{
AllowAssignGrafanaAdmin: true,
},
requester: &user.SignedInUser{
IsGrafanaAdmin: false,
},
wantErr: nil,
},
{
name: "fails when user is not Grafana Admin and Allow assign Grafana Admin was changed",
input: &social.OAuthInfo{
AllowAssignGrafanaAdmin: true,
},
oldSettings: &social.OAuthInfo{
AllowAssignGrafanaAdmin: false,
},
requester: &user.SignedInUser{
IsGrafanaAdmin: false,
},
@@ -104,7 +124,7 @@ func TestAllowAssignGrafanaAdminValidator(t *testing.T) {
for _, tt := range tc {
t.Run(tt.name, func(t *testing.T) {
err := AllowAssignGrafanaAdminValidator(tt.input, tt.requester)
err := AllowAssignGrafanaAdminValidator(tt.input, tt.oldSettings, tt.requester)(tt.input, tt.requester)
if tt.wantErr != nil {
require.ErrorIs(t, err, tt.wantErr)
return
@@ -117,7 +137,7 @@ func TestAllowAssignGrafanaAdminValidator(t *testing.T) {
func TestSkipOrgRoleSyncAllowAssignGrafanaAdminValidator(t *testing.T) {
tc := []testCase{
{
name: "passes when allow assign grafana admin is set, but skip org role sync is not set",
name: "passes when allow assign Grafana Admin is set, but skip org role sync is not set",
input: &social.OAuthInfo{
AllowAssignGrafanaAdmin: true,
SkipOrgRoleSync: false,
@@ -125,7 +145,7 @@ func TestSkipOrgRoleSyncAllowAssignGrafanaAdminValidator(t *testing.T) {
wantErr: nil,
},
{
name: "passes when allow assign grafana admin is not set, but skip org role sync is set",
name: "passes when allow assign Grafana Admin is not set, but skip org role sync is set",
input: &social.OAuthInfo{
AllowAssignGrafanaAdmin: false,
SkipOrgRoleSync: true,
@@ -133,7 +153,7 @@ func TestSkipOrgRoleSyncAllowAssignGrafanaAdminValidator(t *testing.T) {
wantErr: nil,
},
{
name: "fails when both allow assign grafana admin and skip org role sync is set",
name: "fails when both allow assign Grafana Admin and skip org role sync is set",
input: &social.OAuthInfo{
AllowAssignGrafanaAdmin: true,
SkipOrgRoleSync: true,
@@ -153,3 +173,126 @@ func TestSkipOrgRoleSyncAllowAssignGrafanaAdminValidator(t *testing.T) {
})
}
}
func TestOrgMappingValidator(t *testing.T) {
tc := []testCase{
{
name: "passes when user is Grafana Admin and Org mapping was changed",
input: &social.OAuthInfo{
OrgMapping: []string{"group1:1:Viewer"},
},
oldSettings: &social.OAuthInfo{
OrgMapping: []string{"group1:2:Viewer"},
},
requester: &user.SignedInUser{
IsGrafanaAdmin: true,
},
wantErr: nil,
},
{
name: "passes when user is not Grafana Admin and Org mapping was not changed",
input: &social.OAuthInfo{
OrgMapping: []string{"group1:1:Viewer"},
},
oldSettings: &social.OAuthInfo{
OrgMapping: []string{"group1:1:Viewer"},
},
requester: &user.SignedInUser{
IsGrafanaAdmin: false,
},
wantErr: nil,
},
{
name: "fails when user is not Grafana Admin and Org mapping was changed",
input: &social.OAuthInfo{
OrgMapping: []string{"group1:1:Viewer"},
},
oldSettings: &social.OAuthInfo{
OrgMapping: []string{},
},
requester: &user.SignedInUser{
IsGrafanaAdmin: false,
},
wantErr: ssosettings.ErrInvalidOAuthConfig("Organization mapping can only be updated by Grafana Server Admins."),
},
}
for _, tt := range tc {
t.Run(tt.name, func(t *testing.T) {
err := OrgMappingValidator(tt.input, tt.oldSettings, tt.requester)(tt.input, tt.requester)
if tt.wantErr != nil {
require.ErrorIs(t, err, tt.wantErr)
return
}
require.NoError(t, err)
})
}
}
func TestOrgAttributePathValidator(t *testing.T) {
tc := []testCase{
{
name: "passes when user is Grafana Admin and Org attribute path was changed",
input: &social.OAuthInfo{
OrgAttributePath: "path",
},
oldSettings: &social.OAuthInfo{
OrgAttributePath: "old-path",
},
requester: &user.SignedInUser{
IsGrafanaAdmin: true,
},
wantErr: nil,
},
{
name: "passes when user is Grafana Admin and Org attribute path was not changed",
input: &social.OAuthInfo{
OrgAttributePath: "path",
},
oldSettings: &social.OAuthInfo{
OrgAttributePath: "path",
},
requester: &user.SignedInUser{
IsGrafanaAdmin: false,
},
wantErr: nil,
},
{
name: "fails when user is not Grafana Admin and Org attribute path casing was changed",
input: &social.OAuthInfo{
OrgAttributePath: "path",
},
oldSettings: &social.OAuthInfo{
OrgAttributePath: "Path",
},
requester: &user.SignedInUser{
IsGrafanaAdmin: false,
},
wantErr: ssosettings.ErrInvalidOAuthConfig("Organization attribute path can only be updated by Grafana Server Admins."),
},
{
name: "fails when user is not Grafana Admin and Org attribute path was changed",
input: &social.OAuthInfo{
OrgAttributePath: "path",
},
oldSettings: &social.OAuthInfo{
OrgAttributePath: "old-path",
},
requester: &user.SignedInUser{
IsGrafanaAdmin: false,
},
wantErr: ssosettings.ErrInvalidOAuthConfig("Organization attribute path can only be updated by Grafana Server Admins."),
},
}
for _, tt := range tc {
t.Run(tt.name, func(t *testing.T) {
err := OrgAttributePathValidator(tt.input, tt.oldSettings, tt.requester)(tt.input, tt.requester)
if tt.wantErr != nil {
require.ErrorIs(t, err, tt.wantErr)
return
}
require.NoError(t, err)
})
}
}