Skip to content

Commit 3a70613

Browse files
authored
feat(api): do not consider service as admin or maintainer (#6121)
* feat(api): do not consider service as admin or maintainer Signed-off-by: francois samin <[email protected]>
1 parent a46f403 commit 3a70613

32 files changed

+299
-325
lines changed

engine/api/action.go

+12
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,10 @@ func (api *API) getActionHandler() service.Handler {
214214

215215
func (api *API) putActionHandler() service.Handler {
216216
return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
217+
if isService(ctx) {
218+
return sdk.WithStack(sdk.ErrForbidden)
219+
}
220+
217221
vars := mux.Vars(r)
218222

219223
groupName := vars["permGroupName"]
@@ -307,6 +311,10 @@ func (api *API) putActionHandler() service.Handler {
307311

308312
func (api *API) deleteActionHandler() service.Handler {
309313
return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
314+
if isService(ctx) {
315+
return sdk.WithStack(sdk.ErrForbidden)
316+
}
317+
310318
vars := mux.Vars(r)
311319

312320
groupName := vars["permGroupName"]
@@ -425,6 +433,10 @@ func (api *API) getActionAuditHandler() service.Handler {
425433

426434
func (api *API) postActionAuditRollbackHandler() service.Handler {
427435
return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
436+
if isService(ctx) {
437+
return sdk.WithStack(sdk.ErrForbidden)
438+
}
439+
428440
vars := mux.Vars(r)
429441

430442
groupName := vars["permGroupName"]

engine/api/api_helper.go

+8
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,14 @@ func isHatchery(ctx context.Context) bool {
8585
return c.Service != nil && c.Service.Type == sdk.TypeHatchery
8686
}
8787

88+
func isHatcheryShared(ctx context.Context) bool {
89+
c := getAPIConsumer(ctx)
90+
if c == nil {
91+
return false
92+
}
93+
return isHatchery(ctx) && c.GroupIDs.Contains(group.SharedInfraGroup.ID)
94+
}
95+
8896
func isCDN(ctx context.Context) bool {
8997
c := getAPIConsumer(ctx)
9098
if c == nil {

engine/api/api_routes.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ func (api *API) InitRouter() {
168168
r.Handle("/project/{permProjectKey}/variable/{name}/audit", Scope(sdk.AuthConsumerScopeProject), r.GET(api.getVariableAuditInProjectHandler))
169169
r.Handle("/project/{permProjectKey}/applications", Scope(sdk.AuthConsumerScopeProject), r.GET(api.getApplicationsHandler), r.POST(api.addApplicationHandler))
170170
r.Handle("/project/{permProjectKey}/integrations", Scope(sdk.AuthConsumerScopeProject), r.GET(api.getProjectIntegrationsHandler), r.POST(api.postProjectIntegrationHandler))
171-
r.Handle("/project/{permProjectKey}/integrations/{integrationName}", Scope(sdk.AuthConsumerScopeProject), r.GET(api.getProjectIntegrationHandler), r.PUT(api.putProjectIntegrationHandler), r.DELETE(api.deleteProjectIntegrationHandler))
171+
r.Handle("/project/{permProjectKeyWithHooksAllowed}/integrations/{integrationName}", Scope(sdk.AuthConsumerScopeProject), r.GET(api.getProjectIntegrationHandler), r.PUT(api.putProjectIntegrationHandler), r.DELETE(api.deleteProjectIntegrationHandler))
172172
r.Handle("/project/{permProjectKey}/integrations/{integrationName}/workerhooks", Scopes(sdk.AuthConsumerScopeProject, sdk.AuthConsumerScopeRunExecution), r.GET(api.getProjectIntegrationWorkerHookHandler), r.POST(api.postProjectIntegrationWorkerHookHandler))
173173
r.Handle("/project/{permProjectKey}/notifications", Scope(sdk.AuthConsumerScopeProject), r.GET(api.getProjectNotificationsHandler, DEPRECATED))
174174
r.Handle("/project/{permProjectKey}/keys", Scope(sdk.AuthConsumerScopeProject), r.GET(api.getKeysInProjectHandler), r.POST(api.addKeyInProjectHandler))
@@ -223,7 +223,7 @@ func (api *API) InitRouter() {
223223

224224
r.Handle("/project/{key}/type/{type}/access", Scope(sdk.AuthConsumerScopeService), r.GET(api.getProjectAccessHandler))
225225
r.Handle("/project/{permProjectKey}/workflows", Scope(sdk.AuthConsumerScopeProject), r.POST(api.postWorkflowHandler), r.GET(api.getWorkflowsHandler))
226-
r.Handle("/project/{key}/workflows/{permWorkflowName}", Scope(sdk.AuthConsumerScopeProject), r.GET(api.getWorkflowHandler), r.PUT(api.putWorkflowHandler), r.DELETE(api.deleteWorkflowHandler))
226+
r.Handle("/project/{key}/workflows/{permWorkflowNameAdvanced}", Scope(sdk.AuthConsumerScopeProject), r.GET(api.getWorkflowHandler), r.PUT(api.putWorkflowHandler), r.DELETE(api.deleteWorkflowHandler))
227227
r.Handle("/project/{key}/workflows/{permWorkflowName}/delete/dependencies", Scope(sdk.AuthConsumerScopeProject), r.GET(api.getWorkflowDependenciesHandler))
228228
r.Handle("/project/{key}/workflows/{permWorkflowName}/retention/maxruns", Scope(sdk.AuthConsumerScopeProject), r.POST(api.postWorkflowMaxRunHandler, service.OverrideAuth(api.authAdminMiddleware)))
229229
r.Handle("/project/{key}/workflows/{permWorkflowName}/retention/dryrun", Scope(sdk.AuthConsumerScopeProject), r.POST(api.postWorkflowRetentionPolicyDryRun))
@@ -265,7 +265,7 @@ func (api *API) InitRouter() {
265265

266266
// Workflows run
267267
r.Handle("/project/{permProjectKey}/runs", Scope(sdk.AuthConsumerScopeProject), r.GET(api.getWorkflowAllRunsHandler))
268-
r.Handle("/project/{key}/workflows/{permWorkflowName}/runs", Scope(sdk.AuthConsumerScopeRun), r.GET(api.getWorkflowRunsHandler), r.POSTEXECUTE(api.postWorkflowRunHandler))
268+
r.Handle("/project/{key}/workflows/{permWorkflowNameAdvanced}/runs", Scope(sdk.AuthConsumerScopeRun), r.GET(api.getWorkflowRunsHandler), r.POSTEXECUTE(api.postWorkflowRunHandler))
269269
r.Handle("/project/{key}/workflows/{permWorkflowName}/runs/branch/{branch}", Scope(sdk.AuthConsumerScopeRun), r.DELETE(api.deleteWorkflowRunsBranchHandler))
270270
r.Handle("/project/{key}/workflows/{permWorkflowName}/runs/latest", Scope(sdk.AuthConsumerScopeRun), r.GET(api.getLatestWorkflowRunHandler))
271271
r.Handle("/project/{key}/workflows/{permWorkflowName}/runs/tags", Scope(sdk.AuthConsumerScopeRun), r.GET(api.getWorkflowRunTagsHandler))
@@ -289,7 +289,7 @@ func (api *API) InitRouter() {
289289
r.Handle("/project/{key}/workflows/{permWorkflowName}/hook/triggers/condition", Scope(sdk.AuthConsumerScopeRun), r.GET(api.getWorkflowTriggerHookConditionHandler))
290290
r.Handle("/project/{key}/workflows/{permWorkflowName}/triggers/condition", Scope(sdk.AuthConsumerScopeRun), r.GET(api.getWorkflowTriggerConditionHandler))
291291
r.Handle("/project/{key}/workflows/{permWorkflowName}/runs/{number}/nodes/{nodeRunID}/release", Scope(sdk.AuthConsumerScopeRunExecution), r.POSTEXECUTE(api.releaseApplicationWorkflowHandler, MaintenanceAware()))
292-
r.Handle("/project/{key}/workflows/{permWorkflowName}/runs/{number}/hooks/{hookRunID}/callback", Scope(sdk.AuthConsumerScopeRun), r.POST(api.postWorkflowJobHookCallbackHandler, MaintenanceAware()))
292+
r.Handle("/project/{key}/workflows/{permWorkflowNameAdvanced}/runs/{number}/hooks/{hookRunID}/callback", Scope(sdk.AuthConsumerScopeRun), r.POST(api.postWorkflowJobHookCallbackHandler, MaintenanceAware()))
293293
r.Handle("/project/{key}/workflows/{permWorkflowName}/runs/{number}/hooks/{hookRunID}/details", Scope(sdk.AuthConsumerScopeRun), r.GET(api.getWorkflowJobHookDetailsHandler))
294294

295295
// Environment

engine/api/auth_builtin.go

+2
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ func (api *API) postAuthBuiltinSigninHandler() service.Handler {
133133
if hasService {
134134
ctx = context.WithValue(ctx, cdslog.AuthServiceName, srv.Name)
135135
SetTracker(w, cdslog.AuthServiceName, srv.Name)
136+
ctx = context.WithValue(ctx, cdslog.AuthServiceType, srv.Type)
137+
SetTracker(w, cdslog.AuthServiceType, srv.Type)
136138

137139
if err := api.serviceRegister(ctx, tx, &srv); err != nil {
138140
return err

engine/api/bookmark_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,8 @@ func Test_postUserFavoriteHandler(t *testing.T) {
8282
assert.True(t, pRes.Favorite, "project favorite flag should be set")
8383

8484
uri = api.Router.GetRoute(http.MethodGet, api.getWorkflowHandler, map[string]string{
85-
"key": proj.Key,
86-
"permWorkflowName": wkf.Name,
85+
"key": proj.Key,
86+
"permWorkflowNameAdvanced": wkf.Name,
8787
})
8888
req = assets.NewJWTAuthentifiedRequest(t, jwt, http.MethodGet, uri, nil)
8989
w = httptest.NewRecorder()

engine/api/download/download_test.go

+3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ import (
77
)
88

99
func TestInit(t *testing.T) {
10+
if os.Getenv("CI") != "1" {
11+
t.Skip("Skip download test when not running on CI")
12+
}
1013
tmpDir1, _ := os.MkdirTemp(os.TempDir(), "download1")
1114
tmpDir2, _ := os.MkdirTemp(os.TempDir(), "download2")
1215
defer os.RemoveAll(tmpDir1)

engine/api/group.go

+4
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,10 @@ func (api *API) postGroupHandler() service.Handler {
119119

120120
func (api *API) putGroupHandler() service.Handler {
121121
return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
122+
if isService(ctx) {
123+
return sdk.WithStack(sdk.ErrForbidden)
124+
}
125+
122126
vars := mux.Vars(r)
123127
groupName := vars["permGroupName"]
124128

engine/api/project_integration.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,15 @@ import (
1717
func (api *API) getProjectIntegrationHandler() service.Handler {
1818
return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
1919
vars := mux.Vars(r)
20-
projectKey := vars[permProjectKey]
20+
projectKey := vars["permProjectKeyWithHooksAllowed"]
2121
integrationName := vars["integrationName"]
2222

2323
var integ sdk.ProjectIntegration
2424
var err error
2525

2626
clearPassword := service.FormBool(r, "clearPassword")
2727
if clearPassword {
28-
if !isService(ctx) && !isWorker(ctx) {
28+
if !isHooks(ctx) && !isWorker(ctx) {
2929
return sdk.WithStack(sdk.ErrForbidden)
3030
}
3131
integ, err = integration.LoadProjectIntegrationByNameWithClearPassword(ctx, api.mustDB(), projectKey, integrationName)
@@ -52,7 +52,7 @@ func (api *API) getProjectIntegrationHandler() service.Handler {
5252
func (api *API) putProjectIntegrationHandler() service.Handler {
5353
return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
5454
vars := mux.Vars(r)
55-
projectKey := vars[permProjectKey]
55+
projectKey := vars["permProjectKeyWithHooksAllowed"]
5656
integrationName := vars["integrationName"]
5757

5858
var projectIntegration sdk.ProjectIntegration
@@ -141,7 +141,7 @@ func (api *API) putProjectIntegrationHandler() service.Handler {
141141
func (api *API) deleteProjectIntegrationHandler() service.Handler {
142142
return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
143143
vars := mux.Vars(r)
144-
projectKey := vars[permProjectKey]
144+
projectKey := vars["permProjectKeyWithHooksAllowed"]
145145
integrationName := vars["integrationName"]
146146

147147
p, err := project.Load(ctx, api.mustDB(), projectKey, project.LoadOptions.WithIntegrations)

engine/api/project_integration_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ func TestAddUpdateAndDeleteProjectIntegration(t *testing.T) {
4949
pp.ProjectID = proj.ID
5050

5151
vars = map[string]string{}
52-
vars[permProjectKey] = proj.Key
52+
vars["permProjectKeyWithHooksAllowed"] = proj.Key
5353
vars["integrationName"] = "kafkaTest"
5454
uri = router.GetRoute("PUT", api.putProjectIntegrationHandler, vars)
5555
req = assets.NewAuthentifiedRequest(t, u, pass, "PUT", uri, pp)
@@ -60,7 +60,7 @@ func TestAddUpdateAndDeleteProjectIntegration(t *testing.T) {
6060

6161
// GET integration
6262
vars = map[string]string{}
63-
vars[permProjectKey] = proj.Key
63+
vars["permProjectKeyWithHooksAllowed"] = proj.Key
6464
vars["integrationName"] = pp.Name
6565
uri = router.GetRoute("GET", api.getProjectIntegrationHandler, vars)
6666

@@ -72,7 +72,7 @@ func TestAddUpdateAndDeleteProjectIntegration(t *testing.T) {
7272

7373
// DELETE integration
7474
vars = map[string]string{}
75-
vars[permProjectKey] = proj.Key
75+
vars["permProjectKeyWithHooksAllowed"] = proj.Key
7676
vars["integrationName"] = pp.Name
7777
uri = router.GetRoute("DELETE", api.deleteProjectIntegrationHandler, vars)
7878
req = assets.NewAuthentifiedRequest(t, u, pass, "DELETE", uri, nil)

engine/api/router_middleware_auth.go

+2
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,8 @@ func (api *API) authOptionalMiddleware(ctx context.Context, w http.ResponseWrite
157157
if consumer.Service != nil {
158158
ctx = context.WithValue(ctx, cdslog.AuthServiceName, consumer.Service.Name)
159159
SetTracker(w, cdslog.AuthServiceName, consumer.Service.Name)
160+
ctx = context.WithValue(ctx, cdslog.AuthServiceType, consumer.Service.Type)
161+
SetTracker(w, cdslog.AuthServiceType, consumer.Service.Type)
160162
}
161163

162164
// Add worker for consumer if exists

0 commit comments

Comments
 (0)