Skip to content

Commit 86523ca

Browse files
authored
fix(rbac): allow uploads to org members, refactor CAS credential logic (#2174)
Signed-off-by: Jose I. Paris <[email protected]>
1 parent 2c18ddc commit 86523ca

File tree

2 files changed

+27
-17
lines changed

2 files changed

+27
-17
lines changed

app/controlplane/internal/service/cascredential.go

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -78,16 +78,26 @@ func (s *CASCredentialsService) Get(ctx context.Context, req *pb.CASCredentialsS
7878
policyToCheck = authz.PolicyArtifactUpload
7979
}
8080

81+
// Enforce required role
8182
if ok, err := s.authz.Enforce(currentAuthzSubject, policyToCheck); err != nil {
8283
return nil, handleUseCaseErr(err, s.log)
8384
} else if !ok {
8485
return nil, errors.Forbidden("forbidden", "not allowed to perform this operation")
8586
}
8687

88+
// Get default backend
89+
defaultBackend, err := s.casBackendUC.FindDefaultBackend(ctx, currentOrg.ID)
90+
if err != nil && !biz.IsNotFound(err) {
91+
return nil, handleUseCaseErr(err, s.log)
92+
} else if defaultBackend == nil {
93+
return nil, errors.NotFound("not found", "main CAS backend not found")
94+
}
95+
8796
var backend *biz.CASBackend
8897

8998
// Try to find the proper backend where the artifact is stored
90-
if role == casJWT.Downloader {
99+
switch role {
100+
case casJWT.Downloader:
91101
var mapping *biz.CASMapping
92102

93103
// If we are logged in as a user, we'll try to find a mapping for that user
@@ -100,37 +110,35 @@ func (s *CASCredentialsService) Get(ctx context.Context, req *pb.CASCredentialsS
100110
if err != nil {
101111
return nil, handleUseCaseErr(err, s.log)
102112
}
103-
// TODO: pass projectIDs when RBAC for API tokens is supported
104-
mapping, err = s.casMappingUC.FindCASMappingForDownloadByOrg(ctx, req.Digest, []uuid.UUID{orgID}, nil)
113+
114+
// pass projectIDs if it's included in the token
115+
projectIDs := make(map[uuid.UUID][]uuid.UUID)
116+
if currentAPIToken.ProjectID != nil {
117+
projectIDs[orgID] = []uuid.UUID{*currentAPIToken.ProjectID}
118+
}
119+
mapping, err = s.casMappingUC.FindCASMappingForDownloadByOrg(ctx, req.Digest, []uuid.UUID{orgID}, projectIDs)
105120
}
106121

107-
// If we can't find a mapping, we'll use the default backend
108122
if err != nil && !biz.IsNotFound(err) {
109123
if biz.IsErrValidation(err) {
110124
return nil, errors.BadRequest("invalid", err.Error())
111125
}
112-
113126
return nil, handleUseCaseErr(err, s.log)
114127
}
115128

116129
if mapping != nil {
117130
backend = mapping.CASBackend
131+
} else if currentAuthzSubject == string(authz.RoleAdmin) || currentAuthzSubject == string(authz.RoleOwner) {
132+
// fallback to default mapping for admins
133+
backend = defaultBackend
118134
}
135+
case casJWT.Uploader:
136+
backend = defaultBackend
119137
}
120138

121-
// If the backend was not found, use the default backend for the current org, only if the user is admin and RBAC doesn't apply.
139+
// If the backend is not resolved, deny the operation.
122140
if backend == nil {
123-
if currentAuthzSubject == string(authz.RoleAdmin) || currentAuthzSubject == string(authz.RoleOwner) {
124-
// Load the default CAS backend, we'll use it for uploads and as fallback on downloads
125-
backend, err = s.casBackendUC.FindDefaultBackend(ctx, currentOrg.ID)
126-
if err != nil && !biz.IsNotFound(err) {
127-
return nil, handleUseCaseErr(err, s.log)
128-
} else if backend == nil {
129-
return nil, errors.NotFound("not found", "main CAS backend not found")
130-
}
131-
} else {
132-
return nil, errors.Forbidden("forbidden", "operation not allowed")
133-
}
141+
return nil, errors.Forbidden("forbidden", "operation not allowed")
134142
}
135143

136144
// inline backends don't have a download URL
@@ -147,4 +155,5 @@ func (s *CASCredentialsService) Get(ctx context.Context, req *pb.CASCredentialsS
147155
return &pb.CASCredentialsServiceGetResponse{
148156
Result: &pb.CASCredentialsServiceGetResponse_Result{Token: t, Backend: bizCASBackendToPb(backend)},
149157
}, nil
158+
150159
}

app/controlplane/pkg/authz/authz.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ var RolesMap = map[Role][]*Policy{
221221
PolicyWorkflowRunRead,
222222

223223
PolicyArtifactDownload,
224+
PolicyArtifactUpload,
224225

225226
PolicyCASBackendList,
226227

0 commit comments

Comments
 (0)