Skip to content

Commit f98e55f

Browse files
authored
Implement auth token issuance on cluster access (#179)
* Implement auth token issuance on cluster access Signed-off-by: Jan Steffen <[email protected]> * Allow system admin access to all clusters Signed-off-by: Jan Steffen <[email protected]> * Add oncall for admins Signed-off-by: Jan Steffen <[email protected]>
1 parent c1d4915 commit f98e55f

File tree

12 files changed

+274
-107
lines changed

12 files changed

+274
-107
lines changed

cmd/gateway/server.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,17 @@ var serverCmd = &cobra.Command{
180180
return err
181181
}
182182

183+
tenantClusterBindingRepository := repositories.NewTenantClusterBindingRepository(esr.NewInMemoryRepository[*projections.TenantClusterBinding]())
184+
tenantClusterBindingProjector := projectors.NewTenantClusterBindingProjector()
185+
tenantClusterBindingProjectingHandler := eventhandler.NewProjectingEventHandler[*projections.TenantClusterBinding](tenantClusterBindingProjector, tenantClusterBindingRepository)
186+
tenantClusterBindingHandlerChain := eventsourcing.UseEventHandlerMiddleware(tenantClusterBindingProjectingHandler, eventhandler.NewEventStoreReplayMiddleware(esClient), eventhandler.NewEventStoreRefreshMiddleware(esClient, refreshDuration))
187+
tenantClusterBindingMatcher := ebConsumer.Matcher().MatchAggregateType(aggregates.TenantClusterBinding)
188+
if err := ebConsumer.AddHandler(ctx, tenantClusterBindingHandlerChain, tenantClusterBindingMatcher); err != nil {
189+
return err
190+
}
191+
192+
clusterAccessRepo := repositories.NewClusterAccessRepository(tenantClusterBindingRepository, clusterRepository, userRoleBindingRepository)
193+
183194
if err := handler.WarmUp(ctx, esClient, aggregates.User, userHandlerChain); err != nil {
184195
return err
185196
}
@@ -189,6 +200,9 @@ var serverCmd = &cobra.Command{
189200
if err := handler.WarmUp(ctx, esClient, aggregates.Cluster, clusterHandlerChain); err != nil {
190201
return err
191202
}
203+
if err := handler.WarmUp(ctx, esClient, aggregates.TenantClusterBinding, tenantClusterBindingHandlerChain); err != nil {
204+
return err
205+
}
192206

193207
// API servers
194208
authServer, err := gateway.NewAuthServer(ctx, gatewayURL, server, policiesPath, userRoleBindingRepository)
@@ -223,7 +237,7 @@ var serverCmd = &cobra.Command{
223237
}
224238
tokenLifeTimePerRole[k] = k8sTokenValidityDuration
225239
}
226-
clusterAuthApiServer := gateway.NewClusterAuthAPIServer(gatewayURL, signer, clusterRepository, tokenLifeTimePerRole)
240+
clusterAuthApiServer := gateway.NewClusterAuthAPIServer(gatewayURL, signer, clusterAccessRepo, tokenLifeTimePerRole)
227241
apiTokenServer := gateway.NewAPITokenServer(gatewayURL, signer, userRepository)
228242

229243
authMiddleware := authm.NewAuthMiddleware(authServer.AsClient(), []string{

go.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ go-rebuild-mocks: .protobuf-deps $(MOCKGEN)
133133
$(MOCKGEN) -copyright_file hack/copyright.lic -destination internal/test/api/gateway/gateway_auth_client.go github.com/finleap-connect/monoskope/pkg/api/gateway GatewayAuthClient
134134
$(MOCKGEN) -copyright_file hack/copyright.lic -destination internal/test/eventsourcing/mock_handler.go github.com/finleap-connect/monoskope/pkg/eventsourcing EventHandler
135135
$(MOCKGEN) -copyright_file hack/copyright.lic -destination internal/test/eventsourcing/aggregate_store.go github.com/finleap-connect/monoskope/pkg/eventsourcing AggregateStore
136-
$(MOCKGEN) -copyright_file hack/copyright.lic -destination internal/test/domain/repositories/repositories.go github.com/finleap-connect/monoskope/pkg/domain/repositories UserRepository,ClusterRepository
136+
$(MOCKGEN) -copyright_file hack/copyright.lic -destination internal/test/domain/repositories/repositories.go github.com/finleap-connect/monoskope/pkg/domain/repositories UserRepository,ClusterRepository,ClusterAccessRepository
137137

138138
go-run-: ## run cmd, e.g. `make go-run-gateway ARGS="server"` to pass arguments
139139
$(GO) run cmd/$*/*.go $(ARGS)

go.mod

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ require (
4848
sigs.k8s.io/controller-runtime v0.11.2
4949
)
5050

51+
require k8s.io/utils v0.0.0-20211116205334-6203023598ed
52+
5153
require (
5254
cloud.google.com/go v0.99.0 // indirect
5355
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
@@ -77,7 +79,7 @@ require (
7779
github.com/gobwas/glob v0.2.3 // indirect
7880
github.com/goccy/go-json v0.9.7 // indirect
7981
github.com/gogo/protobuf v1.3.2 // indirect
80-
github.com/google/go-cmp v0.5.7 // indirect
82+
github.com/google/go-cmp v0.5.8 // indirect
8183
github.com/google/gofuzz v1.2.0 // indirect
8284
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
8385
github.com/googleapis/gnostic v0.5.5 // indirect
@@ -128,6 +130,7 @@ require (
128130
golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect
129131
golang.org/x/text v0.3.7 // indirect
130132
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
133+
golang.org/x/tools v0.1.10 // indirect
131134
google.golang.org/appengine v1.6.7 // indirect
132135
google.golang.org/genproto v0.0.0-20220118154757-00ab72f36ad5 // indirect
133136
gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0 // indirect
@@ -137,7 +140,6 @@ require (
137140
k8s.io/api v0.23.6 // indirect
138141
k8s.io/klog/v2 v2.30.0 // indirect
139142
k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 // indirect
140-
k8s.io/utils v0.0.0-20211116205334-6203023598ed // indirect
141143
mellium.im/sasl v0.2.1 // indirect
142144
sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 // indirect
143145
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect

go.sum

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -568,8 +568,9 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
568568
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
569569
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
570570
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
571-
github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
572571
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
572+
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
573+
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
573574
github.com/google/go-containerregistry v0.5.1/go.mod h1:Ct15B4yir3PLOP5jsy0GNeYVaIZs/MK/Jz5any1wFW0=
574575
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
575576
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
@@ -1222,8 +1223,8 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
12221223
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
12231224
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
12241225
golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
1225-
golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
12261226
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
1227+
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o=
12271228
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
12281229
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
12291230
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -1530,8 +1531,9 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
15301531
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
15311532
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
15321533
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
1533-
golang.org/x/tools v0.1.9 h1:j9KsMiaP1c3B0OTQGth0/k+miLGTgLsAFUCrF2vLcF8=
15341534
golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
1535+
golang.org/x/tools v0.1.10 h1:QjFRCZxdOhBJ/UNgnBZLbNV13DlbnK0quyivTnXJM20=
1536+
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
15351537
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
15361538
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
15371539
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

internal/gateway/auth_server_test.go

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,10 @@ import (
4040

4141
var _ = Describe("Gateway Auth Server", func() {
4242
var (
43-
ctx = context.Background()
44-
expectedUserId = uuid.New()
45-
expectedRole = roles.User
46-
expectedScope = scopes.Tenant
47-
expectedResource = "1234"
43+
ctx = context.Background()
44+
expectedUserId = uuid.New()
45+
expectedRole = roles.User
46+
expectedScope = scopes.Tenant
4847
)
4948

5049
getTokenForUser := func(user *projections.User) string {
@@ -63,7 +62,7 @@ var _ = Describe("Gateway Auth Server", func() {
6362
UserId: expectedUserId.String(),
6463
Role: string(expectedRole),
6564
Scope: string(expectedScope),
66-
Resource: wrapperspb.String(expectedResource),
65+
Resource: wrapperspb.String(testEnv.SomeTenantId.String()),
6766
},
6867
)
6968
Expect(err).ToNot(HaveOccurred())

internal/gateway/cluster_auth_server.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,32 +28,32 @@ import (
2828

2929
type clusterAuthApiServer struct {
3030
api.UnimplementedClusterAuthServer
31-
log logger.Logger
32-
signer jwt.JWTSigner
33-
clusterRepo repositories.ClusterRepository
34-
issuer string
35-
validity map[string]time.Duration
31+
log logger.Logger
32+
signer jwt.JWTSigner
33+
clusterAccessRepo repositories.ClusterAccessRepository
34+
issuer string
35+
validity map[string]time.Duration
3636
}
3737

3838
func NewClusterAuthAPIServer(
3939
issuer string,
4040
signer jwt.JWTSigner,
41-
clusterRepo repositories.ClusterRepository,
41+
clusterAccessRepo repositories.ClusterAccessRepository,
4242
validity map[string]time.Duration,
4343
) api.ClusterAuthServer {
4444
s := &clusterAuthApiServer{
45-
log: logger.WithName("server"),
46-
signer: signer,
47-
clusterRepo: clusterRepo,
48-
issuer: issuer,
49-
validity: validity,
45+
log: logger.WithName("server"),
46+
signer: signer,
47+
clusterAccessRepo: clusterAccessRepo,
48+
issuer: issuer,
49+
validity: validity,
5050
}
5151
return s
5252
}
5353

5454
func (s *clusterAuthApiServer) GetAuthToken(ctx context.Context, request *api.ClusterAuthTokenRequest) (*api.ClusterAuthTokenResponse, error) {
5555
response := new(api.ClusterAuthTokenResponse)
56-
uc := usecases.NewGetAuthTokenUsecase(request, response, s.signer, s.clusterRepo, s.issuer, s.validity)
56+
uc := usecases.NewGetAuthTokenUsecase(request, response, s.signer, s.clusterAccessRepo, s.issuer, s.validity)
5757
err := uc.Run(ctx)
5858
if err != nil {
5959
return nil, errors.TranslateToGrpcError(err)

internal/gateway/cluster_auth_server_test.go

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,25 +33,22 @@ var _ = Describe("Internal/Gateway/ClusterAuthServer", func() {
3333
mdManager, err := metadata.NewDomainMetadataManager(ctx)
3434
Expect(err).ToNot(HaveOccurred())
3535

36-
It("can retrieve auth url", func() {
36+
It("can request a cluster auth token", func() {
3737
conn, err := CreateInsecureConnection(ctx, testEnv.ApiListenerAPIServer.Addr().String())
3838
Expect(err).ToNot(HaveOccurred())
3939

40-
clusters, err := testEnv.ClusterRepo.AllWith(ctx, false)
41-
Expect(err).ToNot(HaveOccurred())
42-
Expect(len(clusters)).To(BeNumerically(">=", 1))
4340
defer conn.Close()
4441
apiClient := api.NewClusterAuthClient(conn)
4542

4643
mdManager.SetUserInformation(&metadata.UserInformation{
47-
Id: uuid.MustParse(testEnv.AdminUser.GetId()),
48-
Name: testEnv.AdminUser.Name,
49-
Email: testEnv.AdminUser.Email,
44+
Id: uuid.MustParse(testEnv.TenantAdminUser.GetId()),
45+
Name: testEnv.TenantAdminUser.Name,
46+
Email: testEnv.TenantAdminUser.Email,
5047
NotBefore: time.Now().UTC(),
5148
})
5249

5350
response, err := apiClient.GetAuthToken(mdManager.GetOutgoingGrpcContext(), &api.ClusterAuthTokenRequest{
54-
ClusterId: clusters[0].Id,
51+
ClusterId: testEnv.TestClusterId.String(),
5552
Role: string(expectedRole),
5653
})
5754
Expect(err).ToNot(HaveOccurred())

internal/gateway/testenv.go

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ type TestEnv struct {
6565
ExistingUser *projections.User
6666
NotExistingUser *projections.User
6767
PoliciesPath string
68+
SomeTenantId uuid.UUID
69+
TestClusterId uuid.UUID
6870
}
6971

7072
func NewTestEnvWithParent(testeEnv *test.TestEnv) (*TestEnv, error) {
@@ -158,6 +160,8 @@ func NewTestEnvWithParent(testeEnv *test.TestEnv) (*TestEnv, error) {
158160
return nil, err
159161
}
160162

163+
env.SomeTenantId = uuid.New()
164+
161165
// Setup user repo
162166
adminUser := projections.NewUserProjection(uuid.New())
163167
adminUser.Name = "admin"
@@ -184,7 +188,7 @@ func NewTestEnvWithParent(testeEnv *test.TestEnv) (*TestEnv, error) {
184188
tenantAdminRoleBinding.UserId = tenantAdminUser.Id
185189
tenantAdminRoleBinding.Role = string(roles.Admin)
186190
tenantAdminRoleBinding.Scope = string(scopes.Tenant)
187-
tenantAdminRoleBinding.Resource = "1234"
191+
tenantAdminRoleBinding.Resource = env.SomeTenantId.String()
188192

189193
env.AdminUser = adminUser
190194
env.TenantAdminUser = tenantAdminUser
@@ -216,8 +220,8 @@ func NewTestEnvWithParent(testeEnv *test.TestEnv) (*TestEnv, error) {
216220
}
217221

218222
// Setup cluster repo
219-
clusterId := uuid.New()
220-
testCluster := projections.NewClusterProjection(clusterId)
223+
env.TestClusterId = uuid.New()
224+
testCluster := projections.NewClusterProjection(env.TestClusterId)
221225
testCluster.Name = "test-cluster"
222226
testCluster.DisplayName = "Test Cluster"
223227
testCluster.ApiServerAddress = "https://somecluster.io"
@@ -228,11 +232,23 @@ func NewTestEnvWithParent(testeEnv *test.TestEnv) (*TestEnv, error) {
228232
return nil, err
229233
}
230234

235+
tenantClusterBindingId := uuid.New()
236+
tenantClusterBinding := projections.NewTenantClusterBindingProjection(tenantClusterBindingId)
237+
tenantClusterBinding.ClusterId = env.TestClusterId.String()
238+
tenantClusterBinding.TenantId = env.SomeTenantId.String()
239+
240+
inMemoryTemamtClusterBindingRepo := es_repos.NewInMemoryRepository[*projections.TenantClusterBinding]()
241+
if err := inMemoryTemamtClusterBindingRepo.Upsert(context.Background(), tenantClusterBinding); err != nil {
242+
return nil, err
243+
}
244+
231245
userRoleBindingRepo := repositories.NewUserRoleBindingRepository(inMemoryUserRoleBindingRepo)
232246
userRepo := repositories.NewUserRepository(inMemoryUserRepo, repositories.NewUserRoleBindingRepository(inMemoryUserRoleBindingRepo))
247+
tenantClusterbindingRepo := repositories.NewTenantClusterBindingRepository(inMemoryTemamtClusterBindingRepo)
233248
env.ClusterRepo = repositories.NewClusterRepository(inMemoryClusterRepo)
249+
234250
gatewayApiServer := NewGatewayAPIServer(env.ClientAuthConfig, authClient, authServer, userRepo)
235-
authApiServer := NewClusterAuthAPIServer("https://localhost", signer, env.ClusterRepo, map[string]time.Duration{
251+
authApiServer := NewClusterAuthAPIServer("https://localhost", signer, repositories.NewClusterAccessRepository(tenantClusterbindingRepo, env.ClusterRepo, userRoleBindingRepo), map[string]time.Duration{
236252
"default": time.Hour * 1,
237253
})
238254

internal/gateway/usecases/get_auth_token.go

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -21,33 +21,35 @@ import (
2121
"time"
2222

2323
"github.com/finleap-connect/monoskope/internal/gateway/auth"
24+
"github.com/finleap-connect/monoskope/pkg/api/domain/projections"
2425
api "github.com/finleap-connect/monoskope/pkg/api/gateway"
26+
"github.com/finleap-connect/monoskope/pkg/domain/errors"
2527
domainErrors "github.com/finleap-connect/monoskope/pkg/domain/errors"
2628
"github.com/finleap-connect/monoskope/pkg/domain/metadata"
2729
"github.com/finleap-connect/monoskope/pkg/domain/repositories"
2830
"github.com/finleap-connect/monoskope/pkg/jwt"
2931
"github.com/finleap-connect/monoskope/pkg/k8s"
3032
"github.com/finleap-connect/monoskope/pkg/logger"
3133
"github.com/finleap-connect/monoskope/pkg/usecase"
32-
"github.com/google/uuid"
3334
"google.golang.org/protobuf/types/known/timestamppb"
35+
"k8s.io/utils/strings/slices"
3436
)
3537

3638
type getAuthTokenUsecase struct {
3739
*usecase.UseCaseBase
38-
request *api.ClusterAuthTokenRequest
39-
result *api.ClusterAuthTokenResponse
40-
signer jwt.JWTSigner
41-
clusterRepo repositories.ClusterRepository
42-
issuer string
43-
validity map[string]time.Duration
40+
request *api.ClusterAuthTokenRequest
41+
result *api.ClusterAuthTokenResponse
42+
signer jwt.JWTSigner
43+
clusterAccessRepo repositories.ClusterAccessRepository
44+
issuer string
45+
validity map[string]time.Duration
4446
}
4547

4648
func NewGetAuthTokenUsecase(
4749
request *api.ClusterAuthTokenRequest,
4850
response *api.ClusterAuthTokenResponse,
4951
signer jwt.JWTSigner,
50-
clusterRepo repositories.ClusterRepository,
52+
clusterAccessRepo repositories.ClusterAccessRepository,
5153
issuer string,
5254
validity map[string]time.Duration,
5355
) usecase.UseCase {
@@ -56,7 +58,7 @@ func NewGetAuthTokenUsecase(
5658
request,
5759
response,
5860
signer,
59-
clusterRepo,
61+
clusterAccessRepo,
6062
issuer,
6163
validity,
6264
}
@@ -80,22 +82,28 @@ func (s *getAuthTokenUsecase) Run(ctx context.Context) error {
8082
}
8183

8284
clusterId := s.request.GetClusterId()
83-
s.Log.V(logger.DebugLevel).Info("Getting cluster by id...", "id", clusterId)
84-
85-
uuid, err := uuid.Parse(clusterId)
85+
s.Log.V(logger.DebugLevel).Info("Checking user is allowed to access cluster...", "clusterId", clusterId)
86+
clusterAccesses, err := s.clusterAccessRepo.GetClustersAccessibleByUserId(ctx, userInfo.Id)
8687
if err != nil {
8788
return err
8889
}
8990

90-
cluster, err := s.clusterRepo.ById(ctx, uuid)
91-
if err != nil {
92-
return err
91+
var foundClusterAccess *projections.ClusterAccess
92+
for _, clusterAccess := range clusterAccesses {
93+
if clusterAccess.Cluster.Id == clusterId {
94+
foundClusterAccess = clusterAccess
95+
break
96+
}
9397
}
9498

95-
k8sRole := s.request.GetRole()
96-
s.Log.V(logger.DebugLevel).Info("Validating role exists...", "role", k8sRole)
97-
if err := k8s.ValidateRole(k8sRole); err != nil {
98-
return err
99+
if foundClusterAccess == nil {
100+
s.Log.V(logger.DebugLevel).Info("User is not authorized to access cluster.", "clusterId", clusterId)
101+
return errors.ErrUnauthorized
102+
}
103+
104+
if !slices.Contains(foundClusterAccess.Roles, s.request.Role) {
105+
s.Log.V(logger.DebugLevel).Info("User is not authorized to access cluster with role.", "clusterId", clusterId, "role", s.request.Role)
106+
return errors.ErrUnauthorized
99107
}
100108

101109
username := strings.ToLower(strings.Split(userInfo.Email, "@")[0])
@@ -109,8 +117,8 @@ func (s *getAuthTokenUsecase) Run(ctx context.Context) error {
109117
Email: userInfo.Email,
110118
EmailVerified: true,
111119
}, &jwt.ClusterClaim{
112-
ClusterId: cluster.GetId(),
113-
ClusterName: cluster.GetName(),
120+
ClusterId: foundClusterAccess.Cluster.GetId(),
121+
ClusterName: foundClusterAccess.Cluster.GetName(),
114122
ClusterUserName: username,
115123
ClusterRole: s.request.Role,
116124
}, s.issuer, userInfo.Id.String(), s.validity[s.request.Role])

0 commit comments

Comments
 (0)