mirror of https://github.com/grafana/grafana
Auth: Restore legacy behavior and add deprecation notice for empty org role in oauth (#55118)
* Auth: Add deprecation notice for empty org role Co-authored-by: Gabriel MABILLE <gamab@users.noreply.github.com> * fix recasts * fix azure tests missing logger * Adding test to gitlab oauth * Covering more cases * Cover more options * Add role attributestrict check fail * Adding one more edge case test * Using legacy for gitlab * Yet another edge case YAEC * Reverting github oauth to legacy Co-authored-by: Jguer <joao.guerreiro@grafana.com> * Not using token Co-authored-by: Jguer <joao.guerreiro@grafana.com> * Nit. * Adding warning in docs Co-authored-by: Jguer <joao.guerreiro@grafana.com> * add warning to generic oauth Co-authored-by: Jguer <joao.guerreiro@grafana.com> * Be more precise Co-authored-by: Jguer <joao.guerreiro@grafana.com> * Adding warning to github oauth Co-authored-by: Jguer <joao.guerreiro@grafana.com> * Adding warning to gitlab oauth Co-authored-by: Jguer <joao.guerreiro@grafana.com> * Adding warning to okta oauth Co-authored-by: Jguer <joao.guerreiro@grafana.com> * Add docs about mapping to AzureAD Co-authored-by: Jguer <joao.guerreiro@grafana.com> * Clarify oauth_skip_org_role_update_sync Co-authored-by: Jguer <joao.guerreiro@grafana.com> * Nit. * Nit on Azure AD Co-authored-by: Jguer <joao.guerreiro@grafana.com> * Reorder docs index Co-authored-by: Jguer <joao.guerreiro@grafana.com> * Fix typo Co-authored-by: Jguer <joao.guerreiro@grafana.com> Co-authored-by: Gabriel MABILLE <gamab@users.noreply.github.com> Co-authored-by: gamab <gabi.mabs@gmail.com>pull/55268/head
parent
f1e8a528d1
commit
00e7324bf6
@ -0,0 +1,159 @@ |
||||
package social |
||||
|
||||
import ( |
||||
"net/http" |
||||
"net/http/httptest" |
||||
"strings" |
||||
"testing" |
||||
|
||||
"github.com/grafana/grafana/pkg/services/org" |
||||
"github.com/stretchr/testify/require" |
||||
) |
||||
|
||||
const ( |
||||
apiURI = "/api/v4" |
||||
userURI = "/api/v4/user" |
||||
groupsURI = "/api/v4/groups" |
||||
|
||||
gitlabAttrPath = `is_admin && 'GrafanaAdmin' || contains(groups[*], 'admins') && 'Admin' || contains(groups[*], 'editors') && 'Editor' || contains(groups[*], 'viewers') && 'Viewer'` |
||||
|
||||
rootUserRespBody = `{"id":1,"username":"root","name":"Administrator","state":"active","email":"root@example.org","is_admin":true,"namespace_id":1}` |
||||
editorUserRespBody = `{"id":3,"username":"gitlab-editor","name":"Gitlab Editor","state":"active","email":"gitlab-editor@example.org","is_admin":false,"namespace_id":1}` |
||||
|
||||
adminGroup = `{"id":4,"web_url":"http://grafana-gitlab.local/groups/admins","name":"Admins","path":"admins","project_creation_level":"developer","full_name":"Admins","full_path":"admins","created_at":"2022-09-13T19:38:04.891Z"}` |
||||
editorGroup = `{"id":5,"web_url":"http://grafana-gitlab.local/groups/editors","name":"Editors","path":"editors","project_creation_level":"developer","full_name":"Editors","full_path":"editors","created_at":"2022-09-13T19:38:15.074Z"}` |
||||
viewerGroup = `{"id":6,"web_url":"http://grafana-gitlab.local/groups/viewers","name":"Viewers","path":"viewers","project_creation_level":"developer","full_name":"Viewers","full_path":"viewers","created_at":"2022-09-13T19:38:25.777Z"}` |
||||
// serverAdminGroup = `{"id":7,"web_url":"http://grafana-gitlab.local/groups/serveradmins","name":"ServerAdmins","path":"serveradmins","project_creation_level":"developer","full_name":"ServerAdmins","full_path":"serveradmins","created_at":"2022-09-13T19:38:36.227Z"}`
|
||||
) |
||||
|
||||
func TestSocialGitlab_UserInfo(t *testing.T) { |
||||
provider := SocialGitlab{ |
||||
SocialBase: &SocialBase{ |
||||
log: newLogger("gitlab_oauth_test", "debug"), |
||||
}, |
||||
} |
||||
|
||||
type conf struct { |
||||
AllowAssignGrafanaAdmin bool |
||||
RoleAttributeStrict bool |
||||
AutoAssignOrgRole org.RoleType |
||||
} |
||||
|
||||
tests := []struct { |
||||
Name string |
||||
Cfg conf |
||||
UserRespBody string |
||||
GroupsRespBody string |
||||
RoleAttributePath string |
||||
ExpectedLogin string |
||||
ExpectedEmail string |
||||
ExpectedRole org.RoleType |
||||
ExpectedGrafanaAdmin *bool |
||||
ExpectedError error |
||||
}{ |
||||
{ |
||||
Name: "Server Admin Allowed", |
||||
Cfg: conf{AllowAssignGrafanaAdmin: true}, |
||||
UserRespBody: rootUserRespBody, |
||||
GroupsRespBody: "[" + strings.Join([]string{adminGroup, editorGroup, viewerGroup}, ",") + "]", |
||||
RoleAttributePath: gitlabAttrPath, |
||||
ExpectedLogin: "root", |
||||
ExpectedEmail: "root@example.org", |
||||
ExpectedRole: "Admin", |
||||
ExpectedGrafanaAdmin: trueBoolPtr(), |
||||
}, |
||||
{ // Edge case, user in Viewer Group, Server Admin disabled but attribute path contains a condition for Server Admin => User has the Admin role
|
||||
Name: "Server Admin Disabled", |
||||
Cfg: conf{AllowAssignGrafanaAdmin: false}, |
||||
UserRespBody: rootUserRespBody, |
||||
GroupsRespBody: "[" + strings.Join([]string{viewerGroup}, ",") + "]", |
||||
RoleAttributePath: gitlabAttrPath, |
||||
ExpectedLogin: "root", |
||||
ExpectedEmail: "root@example.org", |
||||
ExpectedRole: "Admin", |
||||
}, |
||||
{ |
||||
Name: "Editor", |
||||
Cfg: conf{AllowAssignGrafanaAdmin: true}, |
||||
UserRespBody: editorUserRespBody, |
||||
GroupsRespBody: "[" + strings.Join([]string{viewerGroup, editorGroup}, ",") + "]", |
||||
RoleAttributePath: gitlabAttrPath, |
||||
ExpectedLogin: "gitlab-editor", |
||||
ExpectedEmail: "gitlab-editor@example.org", |
||||
ExpectedRole: "Editor", |
||||
ExpectedGrafanaAdmin: falseBoolPtr(), |
||||
}, |
||||
{ // Case that's going to change with Grafana 10
|
||||
Name: "No fallback to default org role (will change in Grafana 10)", |
||||
Cfg: conf{AutoAssignOrgRole: org.RoleViewer}, |
||||
UserRespBody: editorUserRespBody, |
||||
GroupsRespBody: "[" + strings.Join([]string{}, ",") + "]", |
||||
RoleAttributePath: gitlabAttrPath, |
||||
ExpectedLogin: "gitlab-editor", |
||||
ExpectedEmail: "gitlab-editor@example.org", |
||||
ExpectedRole: "", |
||||
}, |
||||
{ |
||||
Name: "Strict mode prevents fallback to default", |
||||
Cfg: conf{RoleAttributeStrict: true, AutoAssignOrgRole: org.RoleViewer}, |
||||
UserRespBody: editorUserRespBody, |
||||
GroupsRespBody: "[" + strings.Join([]string{}, ",") + "]", |
||||
RoleAttributePath: gitlabAttrPath, |
||||
ExpectedError: ErrInvalidBasicRole, |
||||
}, |
||||
{ // Edge case, no match, no strict mode and no fallback => User has an empty role
|
||||
Name: "Fallback with no default will create a user with an empty role", |
||||
Cfg: conf{}, |
||||
UserRespBody: editorUserRespBody, |
||||
GroupsRespBody: "[" + strings.Join([]string{}, ",") + "]", |
||||
RoleAttributePath: gitlabAttrPath, |
||||
ExpectedLogin: "gitlab-editor", |
||||
ExpectedEmail: "gitlab-editor@example.org", |
||||
ExpectedRole: "", |
||||
}, |
||||
{ // Edge case, no attribute path with strict mode => User has an empty role
|
||||
Name: "Strict mode with no attribute path", |
||||
Cfg: conf{RoleAttributeStrict: true, AutoAssignOrgRole: org.RoleViewer}, |
||||
UserRespBody: editorUserRespBody, |
||||
GroupsRespBody: "[" + strings.Join([]string{editorGroup}, ",") + "]", |
||||
RoleAttributePath: "", |
||||
ExpectedError: ErrInvalidBasicRole, |
||||
}, |
||||
} |
||||
|
||||
for _, test := range tests { |
||||
provider.roleAttributePath = test.RoleAttributePath |
||||
provider.allowAssignGrafanaAdmin = test.Cfg.AllowAssignGrafanaAdmin |
||||
provider.autoAssignOrgRole = string(test.Cfg.AutoAssignOrgRole) |
||||
provider.roleAttributeStrict = test.Cfg.RoleAttributeStrict |
||||
|
||||
t.Run(test.Name, func(t *testing.T) { |
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
||||
w.WriteHeader(http.StatusOK) |
||||
w.Header().Set("Content-Type", "application/json") |
||||
switch r.RequestURI { |
||||
case userURI: |
||||
_, err := w.Write([]byte(test.UserRespBody)) |
||||
require.NoError(t, err) |
||||
case groupsURI: |
||||
_, err := w.Write([]byte(test.GroupsRespBody)) |
||||
require.NoError(t, err) |
||||
default: |
||||
w.WriteHeader(http.StatusNotFound) |
||||
} |
||||
})) |
||||
provider.apiUrl = ts.URL + apiURI |
||||
actualResult, err := provider.UserInfo(ts.Client(), nil) |
||||
if test.ExpectedError != nil { |
||||
require.Equal(t, err, test.ExpectedError) |
||||
return |
||||
} |
||||
|
||||
require.NoError(t, err) |
||||
require.Equal(t, test.ExpectedEmail, actualResult.Email) |
||||
require.Equal(t, test.ExpectedLogin, actualResult.Login) |
||||
require.Equal(t, test.ExpectedRole, actualResult.Role) |
||||
require.Equal(t, test.ExpectedGrafanaAdmin, actualResult.IsGrafanaAdmin) |
||||
}) |
||||
} |
||||
} |
||||
Loading…
Reference in new issue