Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitaaf08d5

Browse files
Emyrkkylecarbs
authored andcommitted
feat: Add RBAC to /files endpoints (#1664)
* feat: Add RBAC to /files endpoints
1 parent524fed2 commitaaf08d5

File tree

4 files changed

+25
-6
lines changed

4 files changed

+25
-6
lines changed

‎coderd/coderd.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ func newRouter(options *Options, a *api) chi.Router {
134134
r.Route("/files",func(r chi.Router) {
135135
r.Use(
136136
apiKeyMiddleware,
137+
authRolesMiddleware,
137138
// This number is arbitrary, but reading/writing
138139
// file content is expensive so it should be small.
139140
httpmw.RateLimitPerMinute(12),

‎coderd/coderd_test.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"github.com/coder/coder/buildinfo"
1717
"github.com/coder/coder/coderd/coderdtest"
1818
"github.com/coder/coder/coderd/rbac"
19+
"github.com/coder/coder/codersdk"
1920
)
2021

2122
funcTestMain(m*testing.M) {
@@ -34,6 +35,7 @@ func TestBuildInfo(t *testing.T) {
3435
// TestAuthorizeAllEndpoints will check `authorize` is called on every endpoint registered.
3536
funcTestAuthorizeAllEndpoints(t*testing.T) {
3637
t.Parallel()
38+
ctx:=context.Background()
3739

3840
authorizer:=&fakeAuthorizer{}
3941
srv,client,_:=coderdtest.NewWithServer(t,&coderdtest.Options{
@@ -50,6 +52,8 @@ func TestAuthorizeAllEndpoints(t *testing.T) {
5052
template:=coderdtest.CreateTemplate(t,client,admin.OrganizationID,version.ID)
5153
workspace:=coderdtest.CreateWorkspace(t,client,admin.OrganizationID,template.ID)
5254
coderdtest.AwaitWorkspaceBuildJob(t,client,workspace.LatestBuild.ID)
55+
file,err:=client.Upload(ctx,codersdk.ContentTypeTar,make([]byte,1024))
56+
require.NoError(t,err,"upload file")
5357

5458
// Always fail auth from this point forward
5559
authorizer.AlwaysReturn=rbac.ForbiddenWithInternal(xerrors.New("fake implementation"),nil,nil)
@@ -121,8 +125,6 @@ func TestAuthorizeAllEndpoints(t *testing.T) {
121125

122126
"POST:/api/v2/users/{user}/organizations": {NoAuthorize:true},
123127

124-
"POST:/api/v2/files": {NoAuthorize:true},
125-
"GET:/api/v2/files/{hash}": {NoAuthorize:true},
126128
"GET:/api/v2/workspaces/{workspace}/watch": {NoAuthorize:true},
127129

128130
// These endpoints have more assertions. This is good, add more endpoints to assert if you can!
@@ -184,6 +186,10 @@ func TestAuthorizeAllEndpoints(t *testing.T) {
184186
AssertObject:workspaceRBACObj,
185187
},
186188

189+
"POST:/api/v2/files": {AssertAction:rbac.ActionCreate,AssertObject:rbac.ResourceFile},
190+
"GET:/api/v2/files/{fileHash}": {AssertAction:rbac.ActionRead,
191+
AssertObject:rbac.ResourceFile.WithOwner(admin.UserID.String()).WithID(file.Hash)},
192+
187193
// These endpoints need payloads to get to the auth part. Payloads will be required
188194
"PUT:/api/v2/users/{user}/roles": {StatusCode:http.StatusBadRequest,NoAuthorize:true},
189195
"POST:/api/v2/workspaces/{workspace}/builds": {StatusCode:http.StatusBadRequest,NoAuthorize:true},
@@ -220,6 +226,7 @@ func TestAuthorizeAllEndpoints(t *testing.T) {
220226
route=strings.ReplaceAll(route,"{workspacebuild}",workspace.LatestBuild.ID.String())
221227
route=strings.ReplaceAll(route,"{workspacename}",workspace.Name)
222228
route=strings.ReplaceAll(route,"{workspacebuildname}",workspace.LatestBuild.Name)
229+
route=strings.ReplaceAll(route,"{hash}",file.Hash)
223230

224231
resp,err:=client.Request(context.Background(),method,route,nil)
225232
require.NoError(t,err,"do req")

‎coderd/files.go

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,18 @@ import (
1414
"github.com/coder/coder/coderd/database"
1515
"github.com/coder/coder/coderd/httpapi"
1616
"github.com/coder/coder/coderd/httpmw"
17+
"github.com/coder/coder/coderd/rbac"
1718
"github.com/coder/coder/codersdk"
1819
)
1920

2021
func (api*api)postFile(rw http.ResponseWriter,r*http.Request) {
2122
apiKey:=httpmw.APIKey(r)
23+
// This requires the site wide action to create files.
24+
// Once created, a user can read their own files uploaded
25+
if!api.Authorize(rw,r,rbac.ActionCreate,rbac.ResourceFile) {
26+
return
27+
}
28+
2229
contentType:=r.Header.Get("Content-Type")
2330

2431
switchcontentType {
@@ -77,9 +84,7 @@ func (api *api) fileByHash(rw http.ResponseWriter, r *http.Request) {
7784
}
7885
file,err:=api.Database.GetFileByHash(r.Context(),hash)
7986
iferrors.Is(err,sql.ErrNoRows) {
80-
httpapi.Write(rw,http.StatusNotFound, httpapi.Response{
81-
Message:"no file exists with that hash",
82-
})
87+
httpapi.Forbidden(rw)
8388
return
8489
}
8590
iferr!=nil {
@@ -88,6 +93,12 @@ func (api *api) fileByHash(rw http.ResponseWriter, r *http.Request) {
8893
})
8994
return
9095
}
96+
97+
if!api.Authorize(rw,r,rbac.ActionRead,
98+
rbac.ResourceFile.WithOwner(file.CreatedBy.String()).WithID(file.Hash)) {
99+
return
100+
}
101+
91102
rw.Header().Set("Content-Type",file.Mimetype)
92103
rw.WriteHeader(http.StatusOK)
93104
_,_=rw.Write(file.Data)

‎coderd/files_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ func TestDownload(t *testing.T) {
5050
_,_,err:=client.Download(context.Background(),"something")
5151
varapiErr*codersdk.Error
5252
require.ErrorAs(t,err,&apiErr)
53-
require.Equal(t,http.StatusNotFound,apiErr.StatusCode())
53+
require.Equal(t,http.StatusForbidden,apiErr.StatusCode())
5454
})
5555

5656
t.Run("Insert",func(t*testing.T) {

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp