Using ExternalService and ExternalServiceDTO

This commit is contained in:
gamab
2023-05-24 10:48:00 +02:00
parent 5c7b57b98a
commit c4c498e55b
12 changed files with 111 additions and 111 deletions
+14 -14
View File
@@ -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, ",")
}
+15 -15
View File
@@ -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",
+6 -6
View File
@@ -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)
}
@@ -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",
+4 -4
View File
@@ -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,
@@ -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",
+2 -2
View File
@@ -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
}
@@ -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),
+3 -3
View File
@@ -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
}
+14 -14
View File
@@ -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)
+13 -13
View File
@@ -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
+21 -21
View File
@@ -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