diff --git a/pkg/services/oauthserver/client.go b/pkg/services/oauthserver/client.go index c7aded29470..765578c2857 100644 --- a/pkg/services/oauthserver/client.go +++ b/pkg/services/oauthserver/client.go @@ -18,7 +18,7 @@ type KeyResult struct { Generated bool `json:"generated,omitempty"` } -type ClientDTO struct { +type ExternalServiceDTO struct { Name string `json:"name"` ID string `json:"clientId"` Secret string `json:"clientSecret"` @@ -28,7 +28,7 @@ type ClientDTO struct { KeyResult *KeyResult `json:"key,omitempty"` } -type Client struct { +type ExternalService struct { ID int64 `xorm:"id pk autoincr"` Name string `xorm:"name"` ClientID string `xorm:"client_id"` @@ -49,8 +49,8 @@ type Client struct { ImpersonateScopes []string } -func (c *Client) ToDTO() *ClientDTO { - c2 := ClientDTO{ +func (c *ExternalService) ToDTO() *ExternalServiceDTO { + c2 := ExternalServiceDTO{ Name: c.Name, ID: c.ClientID, Secret: c.Secret, @@ -64,38 +64,38 @@ func (c *Client) ToDTO() *ClientDTO { return &c2 } -func (c *Client) LogID() string { +func (c *ExternalService) LogID() string { return "{name: " + c.Name + ", clientID: " + c.ClientID + "}" } // GetID returns the client ID. -func (c *Client) GetID() string { return c.ClientID } +func (c *ExternalService) GetID() string { return c.ClientID } // GetHashedSecret returns the hashed secret as it is stored in the store. -func (c *Client) GetHashedSecret() []byte { +func (c *ExternalService) GetHashedSecret() []byte { // Hashed version is stored in the secret field return []byte(c.Secret) } // GetRedirectURIs returns the client's allowed redirect URIs. -func (c *Client) GetRedirectURIs() []string { +func (c *ExternalService) GetRedirectURIs() []string { return []string{c.RedirectURI} } // GetGrantTypes returns the client's allowed grant types. -func (c *Client) GetGrantTypes() fosite.Arguments { +func (c *ExternalService) GetGrantTypes() fosite.Arguments { return strings.Split(c.GrantTypes, ",") } // GetResponseTypes returns the client's allowed response types. // All allowed combinations of response types have to be listed, each combination having // response types of the combination separated by a space. -func (c *Client) GetResponseTypes() fosite.Arguments { +func (c *ExternalService) GetResponseTypes() fosite.Arguments { return fosite.Arguments{"code"} } // GetScopes returns the scopes this client is allowed to request on its own behalf. -func (c *Client) GetScopes() fosite.Arguments { +func (c *ExternalService) GetScopes() fosite.Arguments { if c.Scopes != nil { return c.Scopes } @@ -114,7 +114,7 @@ func (c *Client) GetScopes() fosite.Arguments { } // GetScopes returns the scopes this client is allowed to request on a specific user. -func (c *Client) GetScopesOnUser(ctx context.Context, accessControl ac.AccessControl, userID int64) []string { +func (c *ExternalService) GetScopesOnUser(ctx context.Context, accessControl ac.AccessControl, userID int64) []string { ev := ac.EvalPermission(ac.ActionUsersImpersonate, ac.Scope("users", "id", strconv.FormatInt(userID, 10))) hasAccess, errAccess := accessControl.Evaluate(ctx, c.SignedInUser, ev) if errAccess != nil || !hasAccess { @@ -151,11 +151,11 @@ func (c *Client) GetScopesOnUser(ctx context.Context, accessControl ac.AccessCon } // IsPublic returns true, if this client is marked as public. -func (c *Client) IsPublic() bool { +func (c *ExternalService) IsPublic() bool { return false } // GetAudience returns the allowed audience(s) for this client. -func (c *Client) GetAudience() fosite.Arguments { +func (c *ExternalService) GetAudience() fosite.Arguments { return strings.Split(c.Audiences, ",") } diff --git a/pkg/services/oauthserver/client_test.go b/pkg/services/oauthserver/client_test.go index 4806a7d2eb1..e38a9a92430 100644 --- a/pkg/services/oauthserver/client_test.go +++ b/pkg/services/oauthserver/client_test.go @@ -13,10 +13,10 @@ import ( "github.com/stretchr/testify/require" ) -func setupTestEnv(t *testing.T) *Client { +func setupTestEnv(t *testing.T) *ExternalService { t.Helper() - client := &Client{ + client := &ExternalService{ Name: "my-ext-service", ClientID: "RANDOMID", Secret: "RANDOMSECRET", @@ -37,19 +37,19 @@ func TestClient_GetScopesOnUser(t *testing.T) { testCases := []struct { name string impersonatePermissions []ac.Permission - initTestEnv func(*Client) + initTestEnv func(*ExternalService) expectedScopes []string }{ { name: "should return nil when the service account has no impersonate permissions", - initTestEnv: func(c *Client) { + initTestEnv: func(c *ExternalService) { c.SelfPermissions = []ac.Permission{} }, expectedScopes: nil, }, { name: "should return the 'profile', 'email' and associated RBAC action", - initTestEnv: func(c *Client) { + initTestEnv: func(c *ExternalService) { c.SelfPermissions = []ac.Permission{ {Action: ac.ActionUsersImpersonate, Scope: ac.ScopeUsersAll}, } @@ -66,7 +66,7 @@ func TestClient_GetScopesOnUser(t *testing.T) { }, { name: "should return 'entitlements' and associated RBAC action scopes", - initTestEnv: func(c *Client) { + initTestEnv: func(c *ExternalService) { c.SelfPermissions = []ac.Permission{ {Action: ac.ActionUsersImpersonate, Scope: ac.ScopeUsersAll}, } @@ -83,7 +83,7 @@ func TestClient_GetScopesOnUser(t *testing.T) { }, { name: "should return 'groups' and associated RBAC action scopes", - initTestEnv: func(c *Client) { + initTestEnv: func(c *ExternalService) { c.SelfPermissions = []ac.Permission{ {Action: ac.ActionUsersImpersonate, Scope: ac.ScopeUsersAll}, } @@ -100,7 +100,7 @@ func TestClient_GetScopesOnUser(t *testing.T) { }, { name: "should return all scopes", - initTestEnv: func(c *Client) { + initTestEnv: func(c *ExternalService) { c.SelfPermissions = []ac.Permission{ {Action: ac.ActionUsersImpersonate, Scope: ac.ScopeUsersAll}, } @@ -123,7 +123,7 @@ func TestClient_GetScopesOnUser(t *testing.T) { }, { name: "should return stored scopes when the client's impersonate scopes has already been set", - initTestEnv: func(c *Client) { + initTestEnv: func(c *ExternalService) { c.SignedInUser.Permissions = map[int64]map[string][]string{ 1: { ac.ActionUsersImpersonate: {ac.ScopeUsersAll}, @@ -150,19 +150,19 @@ func TestClient_GetScopes(t *testing.T) { testCases := []struct { name string impersonatePermissions []ac.Permission - initTestEnv func(*Client) + initTestEnv func(*ExternalService) expectedScopes []string }{ { name: "should return default scopes when the signed in user is nil", - initTestEnv: func(c *Client) { + initTestEnv: func(c *ExternalService) { c.SignedInUser = nil }, expectedScopes: []string{"profile", "email", "entitlements", "groups"}, }, { name: "should return additional scopes from signed in user's permissions", - initTestEnv: func(c *Client) { + initTestEnv: func(c *ExternalService) { c.SignedInUser.Permissions = map[int64]map[string][]string{ 1: { dashboards.ActionDashboardsRead: {dashboards.ScopeDashboardsAll}, @@ -173,14 +173,14 @@ func TestClient_GetScopes(t *testing.T) { }, { name: "should return default scopes when the signed in user has no permissions", - initTestEnv: func(c *Client) { + initTestEnv: func(c *ExternalService) { c.SignedInUser.Permissions = map[int64]map[string][]string{} }, expectedScopes: []string{"profile", "email", "entitlements", "groups"}, }, { name: "should return stored scopes when the client's scopes has already been set", - initTestEnv: func(c *Client) { + initTestEnv: func(c *ExternalService) { c.Scopes = []string{"profile", "email", "entitlements", "groups"} }, expectedScopes: []string{"profile", "email", "entitlements", "groups"}, @@ -199,7 +199,7 @@ func TestClient_GetScopes(t *testing.T) { } func TestClient_ToDTO(t *testing.T) { - client := &Client{ + client := &ExternalService{ ID: 1, Name: "my-ext-service", ClientID: "test", diff --git a/pkg/services/oauthserver/models.go b/pkg/services/oauthserver/models.go index 9dd61f2a1fd..1b492c93ee8 100644 --- a/pkg/services/oauthserver/models.go +++ b/pkg/services/oauthserver/models.go @@ -29,10 +29,10 @@ const ( type OAuth2Server interface { // SaveExternalService creates or updates an external service in the database, it generates client_id and secrets and // it ensures that the associated service account has the correct permissions. - SaveExternalService(ctx context.Context, cmd *ExternalServiceRegistration) (*ClientDTO, error) + SaveExternalService(ctx context.Context, cmd *ExternalServiceRegistration) (*ExternalServiceDTO, error) // GetExternalService retrieves an external service from store by client_id. It populates the SelfPermissions and // SignedInUser from the associated service account. - GetExternalService(ctx context.Context, id string) (*Client, error) + GetExternalService(ctx context.Context, id string) (*ExternalService, error) // HandleTokenRequest handles the client's OAuth2 query to obtain an access_token by presenting its authorization // grant (ex: client_credentials, jwtbearer). @@ -45,10 +45,10 @@ type OAuth2Server interface { //go:generate mockery --name Store --structname MockStore --outpkg oauthtest --filename store_mock.go --output ./oauthtest/ type Store interface { - RegisterExternalService(ctx context.Context, client *Client) error - SaveExternalService(ctx context.Context, client *Client) error - GetExternalService(ctx context.Context, id string) (*Client, error) - GetExternalServiceByName(ctx context.Context, name string) (*Client, error) + RegisterExternalService(ctx context.Context, client *ExternalService) error + SaveExternalService(ctx context.Context, client *ExternalService) error + GetExternalService(ctx context.Context, id string) (*ExternalService, error) + GetExternalServiceByName(ctx context.Context, name string) (*ExternalService, error) GetExternalServicePublicKey(ctx context.Context, clientID string) (*jose.JSONWebKey, error) } diff --git a/pkg/services/oauthserver/oasimpl/aggregate_store_test.go b/pkg/services/oauthserver/oasimpl/aggregate_store_test.go index 09c7d35e520..1db2bbb6a91 100644 --- a/pkg/services/oauthserver/oasimpl/aggregate_store_test.go +++ b/pkg/services/oauthserver/oasimpl/aggregate_store_test.go @@ -13,8 +13,8 @@ import ( "github.com/grafana/grafana/pkg/services/user" ) -var cachedUser = func() *oauthserver.Client { - return &oauthserver.Client{ +var cachedUser = func() *oauthserver.ExternalService { + return &oauthserver.ExternalService{ Name: "my-ext-service", ClientID: "RANDOMID", Secret: "RANDOMSECRET", diff --git a/pkg/services/oauthserver/oasimpl/service.go b/pkg/services/oauthserver/oasimpl/service.go index 9c61e00efd1..7c7e805b02f 100644 --- a/pkg/services/oauthserver/oasimpl/service.go +++ b/pkg/services/oauthserver/oasimpl/service.go @@ -132,10 +132,10 @@ func newProvider(config *fosite.Config, storage interface{}, key interface{}) fo // GetExternalService retrieves an external service from store by client_id. It populates the SelfPermissions and // SignedInUser from the associated service account. // For performance reason, the service uses caching. -func (s *OAuth2ServiceImpl) GetExternalService(ctx context.Context, id string) (*oauthserver.Client, error) { +func (s *OAuth2ServiceImpl) GetExternalService(ctx context.Context, id string) (*oauthserver.ExternalService, error) { entry, ok := s.cache.Get(id) if ok { - client, ok := entry.(oauthserver.Client) + client, ok := entry.(oauthserver.ExternalService) if ok { s.logger.Debug("GetExternalService: cache hit", "client id", id) return &client, nil @@ -178,7 +178,7 @@ func (s *OAuth2ServiceImpl) GetExternalService(ctx context.Context, id string) ( // SaveExternalService creates or updates an external service in the database, it generates client_id and secrets and // it ensures that the associated service account has the correct permissions. // Database consistency is not guaranteed, consider changing this in the future. -func (s *OAuth2ServiceImpl) SaveExternalService(ctx context.Context, registration *oauthserver.ExternalServiceRegistration) (*oauthserver.ClientDTO, error) { +func (s *OAuth2ServiceImpl) SaveExternalService(ctx context.Context, registration *oauthserver.ExternalServiceRegistration) (*oauthserver.ExternalServiceDTO, error) { if registration == nil { s.logger.Warn("RegisterExternalService called without registration") return nil, nil @@ -199,7 +199,7 @@ func (s *OAuth2ServiceImpl) SaveExternalService(ctx context.Context, registratio // Otherwise, create a new client if client == nil { s.logger.Debug("External service does not yet exist", "external service name", registration.Name) - client = &oauthserver.Client{ + client = &oauthserver.ExternalService{ Name: registration.Name, ServiceAccountID: oauthserver.NoServiceAccountID, Audiences: s.cfg.AppURL, diff --git a/pkg/services/oauthserver/oasimpl/service_test.go b/pkg/services/oauthserver/oasimpl/service_test.go index 9662024183d..dcb7f53b45b 100644 --- a/pkg/services/oauthserver/oasimpl/service_test.go +++ b/pkg/services/oauthserver/oasimpl/service_test.go @@ -103,8 +103,8 @@ func TestOAuth2ServiceImpl_SaveExternalService(t *testing.T) { sa1Profile := sa.ServiceAccountProfileDTO{Id: 1, Name: serviceName, Login: serviceName, OrgId: oauthserver.TmpOrgID, IsDisabled: false, Role: "Viewer"} prevSaID := int64(3) // Using a function to prevent modifying the same object in the tests - client1 := func() *oauthserver.Client { - return &oauthserver.Client{ + client1 := func() *oauthserver.ExternalService { + return &oauthserver.ExternalService{ Name: serviceName, ClientID: "RANDOMID", Secret: "RANDOMSECRET", @@ -136,7 +136,7 @@ func TestOAuth2ServiceImpl_SaveExternalService(t *testing.T) { env.OAuthStore.AssertCalled(t, "GetExternalServiceByName", mock.Anything, mock.MatchedBy(func(name string) bool { return name == serviceName })) - env.OAuthStore.AssertCalled(t, "SaveExternalService", mock.Anything, mock.MatchedBy(func(client *oauthserver.Client) bool { + env.OAuthStore.AssertCalled(t, "SaveExternalService", mock.Anything, mock.MatchedBy(func(client *oauthserver.ExternalService) bool { ok := client.Name == serviceName ok = ok && client.ClientID != "" ok = ok && client.Secret != "" @@ -163,7 +163,7 @@ func TestOAuth2ServiceImpl_SaveExternalService(t *testing.T) { }, mockChecks: func(t *testing.T, env *TestEnv) { // Check that the client has a service account and the correct grant type - env.OAuthStore.AssertCalled(t, "SaveExternalService", mock.Anything, mock.MatchedBy(func(client *oauthserver.Client) bool { + env.OAuthStore.AssertCalled(t, "SaveExternalService", mock.Anything, mock.MatchedBy(func(client *oauthserver.ExternalService) bool { return client.Name == serviceName && client.GrantTypes == "client_credentials" && client.ServiceAccountID == sa1.Id })) @@ -192,7 +192,7 @@ func TestOAuth2ServiceImpl_SaveExternalService(t *testing.T) { }, mockChecks: func(t *testing.T, env *TestEnv) { // Check that the service has no service account anymore - env.OAuthStore.AssertCalled(t, "SaveExternalService", mock.Anything, mock.MatchedBy(func(client *oauthserver.Client) bool { + env.OAuthStore.AssertCalled(t, "SaveExternalService", mock.Anything, mock.MatchedBy(func(client *oauthserver.ExternalService) bool { return client.Name == serviceName && client.ServiceAccountID == oauthserver.NoServiceAccountID })) // Check that the service account is retrieved with the correct ID @@ -301,8 +301,8 @@ func TestOAuth2ServiceImpl_SaveExternalService(t *testing.T) { func TestOAuth2ServiceImpl_GetExternalService(t *testing.T) { const serviceName = "my-ext-service" - dummyClient := func() *oauthserver.Client { - return &oauthserver.Client{ + dummyClient := func() *oauthserver.ExternalService { + return &oauthserver.ExternalService{ Name: serviceName, ClientID: "RANDOMID", Secret: "RANDOMSECRET", @@ -311,7 +311,7 @@ func TestOAuth2ServiceImpl_GetExternalService(t *testing.T) { ServiceAccountID: 1, } } - cachedUser := &oauthserver.Client{ + cachedUser := &oauthserver.ExternalService{ Name: serviceName, ClientID: "RANDOMID", Secret: "RANDOMSECRET", diff --git a/pkg/services/oauthserver/oasimpl/token.go b/pkg/services/oauthserver/oasimpl/token.go index b47099ae4ff..9709f2e6769 100644 --- a/pkg/services/oauthserver/oasimpl/token.go +++ b/pkg/services/oauthserver/oasimpl/token.go @@ -98,7 +98,7 @@ func splitOAuthScopes(requestedScopes fosite.Arguments) (map[string]bool, map[st // handleJWTBearer populates the "impersonation" access_token generated by fosite to match the rfc9068 specifications (entitlements, groups) // It ensures that the user can be impersonated, that the generated token audiences only contain Grafana's AppURL (and token endpoint) // and that entitlements solely contain the user's permissions that the client is allowed to have. -func (s *OAuth2ServiceImpl) handleJWTBearer(ctx context.Context, accessRequest fosite.AccessRequester, currentOAuthSessionData *PluginAuthSession, client *oauthserver.Client) error { +func (s *OAuth2ServiceImpl) handleJWTBearer(ctx context.Context, accessRequest fosite.AccessRequester, currentOAuthSessionData *PluginAuthSession, client *oauthserver.ExternalService) error { if !accessRequest.GetGrantTypes().ExactOne(string(fosite.GrantTypeJWTBearer)) { return nil } @@ -290,7 +290,7 @@ func (*OAuth2ServiceImpl) filteredImpersonatePermissions(impersonatePermissions } // handleClientCredentials populates the client's access_token generated by fosite to match the rfc9068 specifications (entitlements, groups) -func (s *OAuth2ServiceImpl) handleClientCredentials(ctx context.Context, accessRequest fosite.AccessRequester, currentOAuthSessionData *PluginAuthSession, client *oauthserver.Client) error { +func (s *OAuth2ServiceImpl) handleClientCredentials(ctx context.Context, accessRequest fosite.AccessRequester, currentOAuthSessionData *PluginAuthSession, client *oauthserver.ExternalService) error { if !accessRequest.GetGrantTypes().ExactOne("client_credentials") { return nil } diff --git a/pkg/services/oauthserver/oasimpl/token_test.go b/pkg/services/oauthserver/oasimpl/token_test.go index 93e978ad978..1b1cdea2b9b 100644 --- a/pkg/services/oauthserver/oasimpl/token_test.go +++ b/pkg/services/oauthserver/oasimpl/token_test.go @@ -31,7 +31,7 @@ import ( ) func TestOAuth2ServiceImpl_handleClientCredentials(t *testing.T) { - client1 := &oauthserver.Client{ + client1 := &oauthserver.ExternalService{ Name: "testapp", ClientID: "RANDOMID", GrantTypes: string(fosite.GrantTypeClientCredentials), @@ -53,13 +53,13 @@ func TestOAuth2ServiceImpl_handleClientCredentials(t *testing.T) { tests := []struct { name string scopes []string - client *oauthserver.Client + client *oauthserver.ExternalService expectedClaims map[string]interface{} wantErr bool }{ { name: "no claim without client_credentials grant type", - client: &oauthserver.Client{ + client: &oauthserver.ExternalService{ Name: "testapp", ClientID: "RANDOMID", GrantTypes: string(fosite.GrantTypeJWTBearer), @@ -135,7 +135,7 @@ func TestOAuth2ServiceImpl_handleClientCredentials(t *testing.T) { func TestOAuth2ServiceImpl_handleJWTBearer(t *testing.T) { now := time.Now() - client1 := &oauthserver.Client{ + client1 := &oauthserver.ExternalService{ Name: "testapp", ClientID: "RANDOMID", GrantTypes: string(fosite.GrantTypeJWTBearer), @@ -164,7 +164,7 @@ func TestOAuth2ServiceImpl_handleJWTBearer(t *testing.T) { {ID: 1, Name: "Team 1", OrgID: 1}, {ID: 2, Name: "Team 2", OrgID: 1}, } - client1WithPerm := func(perms []ac.Permission) *oauthserver.Client { + client1WithPerm := func(perms []ac.Permission) *oauthserver.ExternalService { client := *client1 client.ImpersonatePermissions = perms return &client @@ -174,14 +174,14 @@ func TestOAuth2ServiceImpl_handleJWTBearer(t *testing.T) { name string initEnv func(*TestEnv) scopes []string - client *oauthserver.Client + client *oauthserver.ExternalService subject string expectedClaims map[string]interface{} wantErr bool }{ { name: "no claim without jwtbearer grant type", - client: &oauthserver.Client{ + client: &oauthserver.ExternalService{ Name: "testapp", ClientID: "RANDOMID", GrantTypes: string(fosite.GrantTypeClientCredentials), @@ -196,7 +196,7 @@ func TestOAuth2ServiceImpl_handleJWTBearer(t *testing.T) { }, { name: "err client is not allowed to impersonate", - client: &oauthserver.Client{ + client: &oauthserver.ExternalService{ Name: "testapp", ClientID: "RANDOMID", GrantTypes: string(fosite.GrantTypeJWTBearer), @@ -477,7 +477,7 @@ func TestOAuth2ServiceImpl_HandleTokenRequest(t *testing.T) { client1Secret := "RANDOMSECRET" hashedSecret, err := bcrypt.GenerateFromPassword([]byte(client1Secret), bcrypt.DefaultCost) require.NoError(t, err) - client1 := &oauthserver.Client{ + client1 := &oauthserver.ExternalService{ Name: "testapp", ClientID: "RANDOMID", Secret: string(hashedSecret), diff --git a/pkg/services/oauthserver/oastest/fakes.go b/pkg/services/oauthserver/oastest/fakes.go index 6a6be0d398e..95e639d02fb 100644 --- a/pkg/services/oauthserver/oastest/fakes.go +++ b/pkg/services/oauthserver/oastest/fakes.go @@ -9,18 +9,18 @@ import ( ) type FakeService struct { - ExpectedClient *oauthserver.Client + ExpectedClient *oauthserver.ExternalService ExpectedKey *jose.JSONWebKey ExpectedErr error } var _ oauthserver.OAuth2Server = &FakeService{} -func (s *FakeService) SaveExternalService(ctx context.Context, cmd *oauthserver.ExternalServiceRegistration) (*oauthserver.ClientDTO, error) { +func (s *FakeService) SaveExternalService(ctx context.Context, cmd *oauthserver.ExternalServiceRegistration) (*oauthserver.ExternalServiceDTO, error) { return s.ExpectedClient.ToDTO(), s.ExpectedErr } -func (s *FakeService) GetExternalService(ctx context.Context, id string) (*oauthserver.Client, error) { +func (s *FakeService) GetExternalService(ctx context.Context, id string) (*oauthserver.ExternalService, error) { return s.ExpectedClient, s.ExpectedErr } diff --git a/pkg/services/oauthserver/oastest/store_mock.go b/pkg/services/oauthserver/oastest/store_mock.go index 92d793bd29c..b3107cbe4c5 100644 --- a/pkg/services/oauthserver/oastest/store_mock.go +++ b/pkg/services/oauthserver/oastest/store_mock.go @@ -17,19 +17,19 @@ type MockStore struct { } // GetExternalService provides a mock function with given fields: ctx, id -func (_m *MockStore) GetExternalService(ctx context.Context, id string) (*oauthserver.Client, error) { +func (_m *MockStore) GetExternalService(ctx context.Context, id string) (*oauthserver.ExternalService, error) { ret := _m.Called(ctx, id) - var r0 *oauthserver.Client + var r0 *oauthserver.ExternalService var r1 error - if rf, ok := ret.Get(0).(func(context.Context, string) (*oauthserver.Client, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, string) (*oauthserver.ExternalService, error)); ok { return rf(ctx, id) } - if rf, ok := ret.Get(0).(func(context.Context, string) *oauthserver.Client); ok { + if rf, ok := ret.Get(0).(func(context.Context, string) *oauthserver.ExternalService); ok { r0 = rf(ctx, id) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*oauthserver.Client) + r0 = ret.Get(0).(*oauthserver.ExternalService) } } @@ -43,19 +43,19 @@ func (_m *MockStore) GetExternalService(ctx context.Context, id string) (*oauths } // GetExternalServiceByName provides a mock function with given fields: ctx, name -func (_m *MockStore) GetExternalServiceByName(ctx context.Context, name string) (*oauthserver.Client, error) { +func (_m *MockStore) GetExternalServiceByName(ctx context.Context, name string) (*oauthserver.ExternalService, error) { ret := _m.Called(ctx, name) - var r0 *oauthserver.Client + var r0 *oauthserver.ExternalService var r1 error - if rf, ok := ret.Get(0).(func(context.Context, string) (*oauthserver.Client, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, string) (*oauthserver.ExternalService, error)); ok { return rf(ctx, name) } - if rf, ok := ret.Get(0).(func(context.Context, string) *oauthserver.Client); ok { + if rf, ok := ret.Get(0).(func(context.Context, string) *oauthserver.ExternalService); ok { r0 = rf(ctx, name) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*oauthserver.Client) + r0 = ret.Get(0).(*oauthserver.ExternalService) } } @@ -95,11 +95,11 @@ func (_m *MockStore) GetExternalServicePublicKey(ctx context.Context, clientID s } // RegisterExternalService provides a mock function with given fields: ctx, client -func (_m *MockStore) RegisterExternalService(ctx context.Context, client *oauthserver.Client) error { +func (_m *MockStore) RegisterExternalService(ctx context.Context, client *oauthserver.ExternalService) error { ret := _m.Called(ctx, client) var r0 error - if rf, ok := ret.Get(0).(func(context.Context, *oauthserver.Client) error); ok { + if rf, ok := ret.Get(0).(func(context.Context, *oauthserver.ExternalService) error); ok { r0 = rf(ctx, client) } else { r0 = ret.Error(0) @@ -109,11 +109,11 @@ func (_m *MockStore) RegisterExternalService(ctx context.Context, client *oauths } // SaveExternalService provides a mock function with given fields: ctx, client -func (_m *MockStore) SaveExternalService(ctx context.Context, client *oauthserver.Client) error { +func (_m *MockStore) SaveExternalService(ctx context.Context, client *oauthserver.ExternalService) error { ret := _m.Called(ctx, client) var r0 error - if rf, ok := ret.Get(0).(func(context.Context, *oauthserver.Client) error); ok { + if rf, ok := ret.Get(0).(func(context.Context, *oauthserver.ExternalService) error); ok { r0 = rf(ctx, client) } else { r0 = ret.Error(0) diff --git a/pkg/services/oauthserver/store/database.go b/pkg/services/oauthserver/store/database.go index 26d2bfab61c..a153701af7d 100644 --- a/pkg/services/oauthserver/store/database.go +++ b/pkg/services/oauthserver/store/database.go @@ -22,7 +22,7 @@ func NewStore(db db.DB) oauthserver.Store { return &store{db: db} } -func createImpersonatePermissions(sess *db.Session, client *oauthserver.Client) error { +func createImpersonatePermissions(sess *db.Session, client *oauthserver.ExternalService) error { if len(client.ImpersonatePermissions) == 0 { return nil } @@ -38,7 +38,7 @@ func createImpersonatePermissions(sess *db.Session, client *oauthserver.Client) return err } -func registerExternalService(sess *db.Session, client *oauthserver.Client) error { +func registerExternalService(sess *db.Session, client *oauthserver.ExternalService) error { insertQuery := []interface{}{ `INSERT INTO oauth_client (name, client_id, secret, grant_types, audiences, service_account_id, public_pem, redirect_uri) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, client.Name, @@ -57,13 +57,13 @@ func registerExternalService(sess *db.Session, client *oauthserver.Client) error return createImpersonatePermissions(sess, client) } -func (s *store) RegisterExternalService(ctx context.Context, client *oauthserver.Client) error { +func (s *store) RegisterExternalService(ctx context.Context, client *oauthserver.ExternalService) error { return s.db.WithTransactionalDbSession(ctx, func(sess *db.Session) error { return registerExternalService(sess, client) }) } -func recreateImpersonatePermissions(sess *db.Session, client *oauthserver.Client, prevClientID string) error { +func recreateImpersonatePermissions(sess *db.Session, client *oauthserver.ExternalService, prevClientID string) error { deletePermQuery := `DELETE FROM oauth_impersonate_permission WHERE client_id = ?` if _, errDelPerm := sess.Exec(deletePermQuery, prevClientID); errDelPerm != nil { return errDelPerm @@ -76,7 +76,7 @@ func recreateImpersonatePermissions(sess *db.Session, client *oauthserver.Client return createImpersonatePermissions(sess, client) } -func updateExternalService(sess *db.Session, client *oauthserver.Client, prevClientID string) error { +func updateExternalService(sess *db.Session, client *oauthserver.ExternalService, prevClientID string) error { updateQuery := []interface{}{ `UPDATE oauth_client SET client_id = ?, secret = ?, grant_types = ?, audiences = ?, service_account_id = ?, public_pem = ?, redirect_uri = ? WHERE name = ?`, client.ClientID, @@ -95,7 +95,7 @@ func updateExternalService(sess *db.Session, client *oauthserver.Client, prevCli return recreateImpersonatePermissions(sess, client, prevClientID) } -func (s *store) SaveExternalService(ctx context.Context, client *oauthserver.Client) error { +func (s *store) SaveExternalService(ctx context.Context, client *oauthserver.ExternalService) error { if client.Name == "" { return oauthserver.ErrClientRequiredName } @@ -116,8 +116,8 @@ func (s *store) SaveExternalService(ctx context.Context, client *oauthserver.Cli }) } -func (s *store) GetExternalService(ctx context.Context, id string) (*oauthserver.Client, error) { - res := &oauthserver.Client{} +func (s *store) GetExternalService(ctx context.Context, id string) (*oauthserver.ExternalService, error) { + res := &oauthserver.ExternalService{} if id == "" { return nil, oauthserver.ErrClientRequiredID } @@ -145,7 +145,7 @@ func (s *store) GetExternalService(ctx context.Context, id string) (*oauthserver // GetPublicKey returns public key, issued by 'issuer', and assigned for subject. Public key is used to check // signature of jwt assertion in authorization grants. func (s *store) GetExternalServicePublicKey(ctx context.Context, clientID string) (*jose.JSONWebKey, error) { - res := &oauthserver.Client{} + res := &oauthserver.ExternalService{} if clientID == "" { return nil, oauthserver.ErrClientRequiredID } @@ -183,8 +183,8 @@ func (s *store) GetExternalServicePublicKey(ctx context.Context, clientID string }, nil } -func (s *store) GetExternalServiceByName(ctx context.Context, name string) (*oauthserver.Client, error) { - res := &oauthserver.Client{} +func (s *store) GetExternalServiceByName(ctx context.Context, name string) (*oauthserver.ExternalService, error) { + res := &oauthserver.ExternalService{} if name == "" { return nil, oauthserver.ErrClientRequiredName } @@ -198,8 +198,8 @@ func (s *store) GetExternalServiceByName(ctx context.Context, name string) (*oau return res, err } -func getExternalServiceByName(sess *db.Session, name string) (*oauthserver.Client, error) { - res := &oauthserver.Client{} +func getExternalServiceByName(sess *db.Session, name string) (*oauthserver.ExternalService, error) { + res := &oauthserver.ExternalService{} getClientQuery := `SELECT id, name, client_id, secret, grant_types, audiences, service_account_id, public_pem, redirect_uri FROM oauth_client diff --git a/pkg/services/oauthserver/store/database_test.go b/pkg/services/oauthserver/store/database_test.go index 35352398b16..4a095423e89 100644 --- a/pkg/services/oauthserver/store/database_test.go +++ b/pkg/services/oauthserver/store/database_test.go @@ -17,12 +17,12 @@ func TestStore_RegisterAndGetClient(t *testing.T) { s := &store{db: db.InitTestDB(t, db.InitTestDBOpt{FeatureFlags: []string{featuremgmt.FlagExternalServiceAuth}})} tests := []struct { name string - client oauthserver.Client + client oauthserver.ExternalService wantErr bool }{ { name: "register and get", - client: oauthserver.Client{ + client: oauthserver.ExternalService{ Name: "The Worst App Ever", ClientID: "ANonRandomClientID", Secret: "ICouldKeepSecrets", @@ -59,7 +59,7 @@ dCBBIFJlZ3VsYXIgQmFzZTY0IEVuY29kZWQgU3RyaW5nLi4uCg== }, { name: "register with impersonate permissions and get", - client: oauthserver.Client{ + client: oauthserver.ExternalService{ Name: "The Best App Ever", ClientID: "AnAlmostRandomClientID", Secret: "ICannotKeepSecrets", @@ -80,7 +80,7 @@ dCBBIFJlZ3VsYXIgQmFzZTY0IEVuY29kZWQgU3RyaW5nLi4uCg== }, { name: "register with audiences and get", - client: oauthserver.Client{ + client: oauthserver.ExternalService{ Name: "The Most Normal App Ever", ClientID: "AnAlmostRandomClientIDAgain", Secret: "ICanKeepSecretsEventually", @@ -111,7 +111,7 @@ dCBBIFJlZ3VsYXIgQmFzZTY0IEVuY29kZWQgU3RyaW5nLi4uCg== } func TestStore_SaveExternalService(t *testing.T) { - client1 := oauthserver.Client{ + client1 := oauthserver.ExternalService{ Name: "my-external-service", ClientID: "ClientID", Secret: "Secret", @@ -136,42 +136,42 @@ func TestStore_SaveExternalService(t *testing.T) { tests := []struct { name string - runs []oauthserver.Client + runs []oauthserver.ExternalService wantErr bool }{ { name: "error no name", - runs: []oauthserver.Client{{}}, + runs: []oauthserver.ExternalService{{}}, wantErr: true, }, { name: "simple register", - runs: []oauthserver.Client{client1}, + runs: []oauthserver.ExternalService{client1}, wantErr: false, }, { name: "no update", - runs: []oauthserver.Client{client1, client1}, + runs: []oauthserver.ExternalService{client1, client1}, wantErr: false, }, { name: "add permissions", - runs: []oauthserver.Client{client1, client1WithPerm}, + runs: []oauthserver.ExternalService{client1, client1WithPerm}, wantErr: false, }, { name: "remove permissions", - runs: []oauthserver.Client{client1WithPerm, client1}, + runs: []oauthserver.ExternalService{client1WithPerm, client1}, wantErr: false, }, { name: "update id and secrets", - runs: []oauthserver.Client{client1, client1WithNewSecrets}, + runs: []oauthserver.ExternalService{client1, client1WithNewSecrets}, wantErr: false, }, { name: "update audience", - runs: []oauthserver.Client{client1, client1WithAud}, + runs: []oauthserver.ExternalService{client1, client1WithAud}, wantErr: false, }, } @@ -193,7 +193,7 @@ func TestStore_SaveExternalService(t *testing.T) { } func TestStore_GetExternalServiceByName(t *testing.T) { - client1 := oauthserver.Client{ + client1 := oauthserver.ExternalService{ Name: "my-external-service", ClientID: "ClientID", Secret: "Secret", @@ -203,7 +203,7 @@ func TestStore_GetExternalServiceByName(t *testing.T) { ImpersonatePermissions: []accesscontrol.Permission{}, RedirectURI: "/whereto", } - client2 := oauthserver.Client{ + client2 := oauthserver.ExternalService{ Name: "my-external-service-2", ClientID: "ClientID2", Secret: "Secret2", @@ -224,7 +224,7 @@ func TestStore_GetExternalServiceByName(t *testing.T) { tests := []struct { name string search string - want *oauthserver.Client + want *oauthserver.ExternalService wantErr bool }{ { @@ -268,8 +268,8 @@ func TestStore_GetExternalServiceByName(t *testing.T) { func TestStore_GetExternalServicePublicKey(t *testing.T) { clientID := "ClientID" - createClient := func(clientID string, publicPem string) *oauthserver.Client { - return &oauthserver.Client{ + createClient := func(clientID string, publicPem string) *oauthserver.ExternalService { + return &oauthserver.ExternalService{ Name: "my-external-service", ClientID: clientID, Secret: "Secret", @@ -283,7 +283,7 @@ func TestStore_GetExternalServicePublicKey(t *testing.T) { testCases := []struct { name string - client *oauthserver.Client + client *oauthserver.ExternalService clientID string want *jose.JSONWebKey wantErr bool @@ -336,7 +336,7 @@ mgGaC8vUIigFQVsVB+v/HZ4yG1Rcvysig+tyNk1dZQpozpFc2dGmzHlGhw== } } -func compareClientToStored(t *testing.T, s *store, wanted *oauthserver.Client) { +func compareClientToStored(t *testing.T, s *store, wanted *oauthserver.ExternalService) { ctx := context.Background() stored, err := s.GetExternalService(ctx, wanted.ClientID) require.NoError(t, err) @@ -345,7 +345,7 @@ func compareClientToStored(t *testing.T, s *store, wanted *oauthserver.Client) { compareClients(t, stored, wanted) } -func compareClients(t *testing.T, stored *oauthserver.Client, wanted *oauthserver.Client) { +func compareClients(t *testing.T, stored *oauthserver.ExternalService, wanted *oauthserver.ExternalService) { // Reset ID so we can compare require.NotZero(t, stored.ID) stored.ID = 0