Auth: Load oauth_allow_insecure_email_lookup using the SettingsProvider (#82460)

* wip

* Introduce fixed:server.config:writer role

* Fix tests

* Update name
This commit is contained in:
Misi 2024-02-16 12:05:00 +01:00 committed by GitHub
parent ac84069071
commit bb9d5799cf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 38 additions and 13 deletions

View File

@ -263,6 +263,19 @@ var (
},
},
}
generalAuthConfigWriterRole = RoleDTO{
Name: "fixed:general.auth.config:writer",
DisplayName: "General authentication config writer",
Description: "Read and update the Grafana instance's general authentication configuration.",
Group: "Settings",
Permissions: []Permission{
{
Action: ActionSettingsWrite,
Scope: "settings:auth:oauth_allow_insecure_email_lookup",
},
},
}
)
// Declare OSS roles to the accesscontrol service
@ -299,6 +312,10 @@ func DeclareFixedRoles(service Service, cfg *setting.Cfg) error {
Role: usersWriterRole,
Grants: []string{RoleGrafanaAdmin},
}
generalAuthConfigWriter := RoleRegistration{
Role: generalAuthConfigWriterRole,
Grants: []string{RoleGrafanaAdmin},
}
// TODO: Move to own service when implemented
authenticationConfigWriter := RoleRegistration{
@ -311,7 +328,7 @@ func DeclareFixedRoles(service Service, cfg *setting.Cfg) error {
}
return service.DeclareFixedRoles(ldapReader, ldapWriter, orgUsersReader, orgUsersWriter,
settingsReader, statsReader, usersReader, usersWriter, authenticationConfigWriter)
settingsReader, statsReader, usersReader, usersWriter, authenticationConfigWriter, generalAuthConfigWriter)
}
func ConcatPermissions(permissions ...[]Permission) []Permission {

View File

@ -73,6 +73,7 @@ func ProvideService(
socialService social.Service, cache *remotecache.RemoteCache,
ldapService service.LDAP, registerer prometheus.Registerer,
signingKeysService signingkeys.Service, oauthServer oauthserver.OAuth2Server,
settingsProviderService setting.Provider,
) *Service {
s := &Service{
log: log.New("authn.service"),
@ -141,7 +142,7 @@ func ProvideService(
for name := range socialService.GetOAuthProviders() {
clientName := authn.ClientWithPrefix(name)
s.RegisterClient(clients.ProvideOAuth(clientName, cfg, oauthTokenService, socialService))
s.RegisterClient(clients.ProvideOAuth(clientName, cfg, oauthTokenService, socialService, settingsProviderService))
}
// FIXME (jguer): move to User package

View File

@ -65,12 +65,12 @@ var _ authn.RedirectClient = new(OAuth)
func ProvideOAuth(
name string, cfg *setting.Cfg, oauthService oauthtoken.OAuthTokenService,
socialService social.Service,
socialService social.Service, settingsProviderService setting.Provider,
) *OAuth {
providerName := strings.TrimPrefix(name, "auth.client.")
return &OAuth{
name, fmt.Sprintf("oauth_%s", providerName), providerName,
log.New(name), cfg, oauthService, socialService,
log.New(name), cfg, settingsProviderService, oauthService, socialService,
}
}
@ -81,8 +81,9 @@ type OAuth struct {
log log.Logger
cfg *setting.Cfg
oauthService oauthtoken.OAuthTokenService
socialService social.Service
settingsProviderSvc setting.Provider
oauthService oauthtoken.OAuthTokenService
socialService social.Service
}
func (c *OAuth) Name() string {
@ -168,7 +169,8 @@ func (c *OAuth) Authenticate(ctx context.Context, r *authn.Request) (*authn.Iden
})
lookupParams := login.UserLookupParams{}
if c.cfg.OAuthAllowInsecureEmailLookup {
allowInsecureEmailLookup := c.settingsProviderSvc.KeyValue("auth", "oauth_allow_insecure_email_lookup").MustBool(false)
if allowInsecureEmailLookup {
lookupParams.Email = &userInfo.Email
}

View File

@ -4,6 +4,7 @@ import (
"context"
"net/http"
"net/url"
"strconv"
"strings"
"testing"
"time"
@ -201,10 +202,12 @@ func TestOAuth_Authenticate(t *testing.T) {
for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
cfg := setting.NewCfg()
auth, err := cfg.Raw.NewSection("auth")
assert.NoError(t, err)
_, err = auth.NewKey("oauth_allow_insecure_email_lookup", strconv.FormatBool(tt.allowInsecureTakeover))
assert.NoError(t, err)
if tt.allowInsecureTakeover {
cfg.OAuthAllowInsecureEmailLookup = true
}
settingsProvider := &setting.OSSImpl{Cfg: cfg}
if tt.addStateCookie {
v := tt.stateCookieValue
@ -228,7 +231,7 @@ func TestOAuth_Authenticate(t *testing.T) {
},
}
c := ProvideOAuth(authn.ClientWithPrefix("azuread"), cfg, nil, fakeSocialSvc)
c := ProvideOAuth(authn.ClientWithPrefix("azuread"), cfg, nil, fakeSocialSvc, settingsProvider)
identity, err := c.Authenticate(context.Background(), tt.req)
assert.ErrorIs(t, err, tt.expectedErr)
@ -309,7 +312,9 @@ func TestOAuth_RedirectURL(t *testing.T) {
},
}
c := ProvideOAuth(authn.ClientWithPrefix("azuread"), setting.NewCfg(), nil, fakeSocialSvc)
cfg := setting.NewCfg()
c := ProvideOAuth(authn.ClientWithPrefix("azuread"), cfg, nil, fakeSocialSvc, &setting.OSSImpl{Cfg: cfg})
redirect, err := c.RedirectURL(context.Background(), nil)
assert.ErrorIs(t, err, tt.expectedErr)
@ -422,7 +427,7 @@ func TestOAuth_Logout(t *testing.T) {
fakeSocialSvc := &socialtest.FakeSocialService{
ExpectedAuthInfoProvider: tt.oauthCfg,
}
c := ProvideOAuth(authn.ClientWithPrefix("azuread"), tt.cfg, mockService, fakeSocialSvc)
c := ProvideOAuth(authn.ClientWithPrefix("azuread"), tt.cfg, mockService, fakeSocialSvc, &setting.OSSImpl{Cfg: tt.cfg})
redirect, ok := c.Logout(context.Background(), &authn.Identity{}, &login.UserAuth{})