Skip to content

Commit

Permalink
Api auth code (#247)
Browse files Browse the repository at this point in the history
Co-authored-by: Da.Lei <[email protected]>
  • Loading branch information
Rader and Da.Lei authored Jan 22, 2025
1 parent 60937af commit a8d401b
Show file tree
Hide file tree
Showing 15 changed files with 434 additions and 188 deletions.
20 changes: 16 additions & 4 deletions api/handler/code.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ func (h *CodeHandler) Create(ctx *gin.Context) {

code, err := h.code.Create(ctx.Request.Context(), req)
if err != nil {
if errors.Is(err, component.ErrForbidden) {
httpbase.ForbiddenError(ctx, err)
return
}
slog.Error("Failed to create code", slog.Any("error", err))
httpbase.ServerError(ctx, err)
return
Expand Down Expand Up @@ -189,6 +193,10 @@ func (h *CodeHandler) Update(ctx *gin.Context) {

code, err := h.code.Update(ctx.Request.Context(), req)
if err != nil {
if errors.Is(err, component.ErrForbidden) {
httpbase.ForbiddenError(ctx, err)
return
}
slog.Error("Failed to update code", slog.Any("error", err))
httpbase.ServerError(ctx, err)
return
Expand Down Expand Up @@ -226,6 +234,10 @@ func (h *CodeHandler) Delete(ctx *gin.Context) {
}
err = h.code.Delete(ctx.Request.Context(), namespace, name, currentUser)
if err != nil {
if errors.Is(err, component.ErrForbidden) {
httpbase.ForbiddenError(ctx, err)
return
}
slog.Error("Failed to delete code", slog.Any("error", err))
httpbase.ServerError(ctx, err)
return
Expand Down Expand Up @@ -258,8 +270,8 @@ func (h *CodeHandler) Show(ctx *gin.Context) {
currentUser := httpbase.GetCurrentUser(ctx)
detail, err := h.code.Show(ctx.Request.Context(), namespace, name, currentUser)
if err != nil {
if errors.Is(err, component.ErrUnauthorized) {
httpbase.UnauthorizedError(ctx, err)
if errors.Is(err, component.ErrForbidden) {
httpbase.ForbiddenError(ctx, err)
return
}
slog.Error("Failed to get code", slog.Any("error", err))
Expand Down Expand Up @@ -293,8 +305,8 @@ func (h *CodeHandler) Relations(ctx *gin.Context) {
currentUser := httpbase.GetCurrentUser(ctx)
detail, err := h.code.Relations(ctx.Request.Context(), namespace, name, currentUser)
if err != nil {
if errors.Is(err, component.ErrUnauthorized) {
httpbase.UnauthorizedError(ctx, err)
if errors.Is(err, component.ErrForbidden) {
httpbase.ForbiddenError(ctx, err)
return
}
slog.Error("Failed to get code relations", slog.Any("error", err))
Expand Down
24 changes: 18 additions & 6 deletions api/handler/dataset.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ func (h *DatasetHandler) Create(ctx *gin.Context) {

dataset, err := h.dataset.Create(ctx.Request.Context(), req)
if err != nil {
if errors.Is(err, component.ErrForbidden) {
httpbase.ForbiddenError(ctx, err)
return
}
slog.Error("Failed to create dataset", slog.Any("error", err))
httpbase.ServerError(ctx, err)
return
Expand Down Expand Up @@ -202,6 +206,10 @@ func (h *DatasetHandler) Update(ctx *gin.Context) {

dataset, err := h.dataset.Update(ctx.Request.Context(), req)
if err != nil {
if errors.Is(err, component.ErrForbidden) {
httpbase.ForbiddenError(ctx, err)
return
}
slog.Error("Failed to update dataset", slog.Any("error", err))
httpbase.ServerError(ctx, err)
return
Expand Down Expand Up @@ -239,6 +247,10 @@ func (h *DatasetHandler) Delete(ctx *gin.Context) {
}
err = h.dataset.Delete(ctx.Request.Context(), namespace, name, currentUser)
if err != nil {
if errors.Is(err, component.ErrForbidden) {
httpbase.ForbiddenError(ctx, err)
return
}
slog.Error("Failed to delete dataset", slog.Any("error", err))
httpbase.ServerError(ctx, err)
return
Expand Down Expand Up @@ -271,8 +283,8 @@ func (h *DatasetHandler) Show(ctx *gin.Context) {
currentUser := httpbase.GetCurrentUser(ctx)
detail, err := h.dataset.Show(ctx.Request.Context(), namespace, name, currentUser)
if err != nil {
if errors.Is(err, component.ErrUnauthorized) {
httpbase.UnauthorizedError(ctx, err)
if errors.Is(err, component.ErrForbidden) {
httpbase.ForbiddenError(ctx, err)
return
}
slog.Error("Failed to get dataset", slog.Any("error", err))
Expand Down Expand Up @@ -307,8 +319,8 @@ func (h *DatasetHandler) Relations(ctx *gin.Context) {
currentUser := httpbase.GetCurrentUser(ctx)
detail, err := h.dataset.Relations(ctx.Request.Context(), namespace, name, currentUser)
if err != nil {
if errors.Is(err, component.ErrUnauthorized) {
httpbase.UnauthorizedError(ctx, err)
if errors.Is(err, component.ErrForbidden) {
httpbase.ForbiddenError(ctx, err)
return
}
slog.Error("Failed to get dataset relations", slog.Any("error", err))
Expand Down Expand Up @@ -357,8 +369,8 @@ func (h *DatasetHandler) AllFiles(ctx *gin.Context) {
req.Ref = ""
detail, err := h.repo.AllFiles(ctx.Request.Context(), req)
if err != nil {
if errors.Is(err, component.ErrUnauthorized) {
httpbase.UnauthorizedError(ctx, err)
if errors.Is(err, component.ErrForbidden) {
httpbase.ForbiddenError(ctx, err)
return
}
slog.Error("Failed to get dataset all files", slog.Any("error", err))
Expand Down
186 changes: 138 additions & 48 deletions api/handler/dataset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/stretchr/testify/require"
mockcomponent "opencsg.com/csghub-server/_mocks/opencsg.com/csghub-server/component"
"opencsg.com/csghub-server/common/types"
"opencsg.com/csghub-server/component"
)

type DatasetTester struct {
Expand Down Expand Up @@ -86,78 +87,167 @@ func TestDatasetHandler_Index(t *testing.T) {
}

func TestDatasetHandler_Update(t *testing.T) {
tester := NewDatasetTester(t).WithHandleFunc(func(h *DatasetHandler) gin.HandlerFunc {
return h.Update
t.Run("forbidden", func(t *testing.T) {
tester := NewDatasetTester(t).WithHandleFunc(func(h *DatasetHandler) gin.HandlerFunc {
return h.Update
})
tester.RequireUser(t)

tester.mocks.sensitive.EXPECT().CheckRequestV2(tester.ctx, &types.UpdateDatasetReq{}).Return(true, nil)
tester.mocks.dataset.EXPECT().Update(tester.ctx, &types.UpdateDatasetReq{
UpdateRepoReq: types.UpdateRepoReq{
Username: "u",
Namespace: "u-other",
Name: "r",
},
}).Return(nil, component.ErrForbiddenMsg("user not allowed to update dataset"))
tester.WithParam("namespace", "u-other").WithParam("name", "r").
WithBody(t, &types.UpdateDatasetReq{
UpdateRepoReq: types.UpdateRepoReq{Name: "r"},
}).
WithUser().
Execute()

require.Equal(t, 403, tester.response.Code)
})

t.Run("normal", func(t *testing.T) {
tester := NewDatasetTester(t).WithHandleFunc(func(h *DatasetHandler) gin.HandlerFunc {
return h.Update
})
tester.RequireUser(t)

tester.mocks.sensitive.EXPECT().CheckRequestV2(tester.ctx, &types.UpdateDatasetReq{}).Return(true, nil)
tester.mocks.dataset.EXPECT().Update(tester.ctx, &types.UpdateDatasetReq{
UpdateRepoReq: types.UpdateRepoReq{
Username: "u",
Namespace: "u",
Name: "r",
},
}).Return(&types.Dataset{Name: "foo"}, nil)
tester.WithBody(t, &types.UpdateDatasetReq{
UpdateRepoReq: types.UpdateRepoReq{Name: "r"},
}).Execute()

tester.ResponseEq(t, 200, tester.OKText, &types.Dataset{Name: "foo"})
})
tester.RequireUser(t)

tester.mocks.sensitive.EXPECT().CheckRequestV2(tester.ctx, &types.UpdateDatasetReq{}).Return(true, nil)
tester.mocks.dataset.EXPECT().Update(tester.ctx, &types.UpdateDatasetReq{
UpdateRepoReq: types.UpdateRepoReq{
Username: "u",
Namespace: "u",
Name: "r",
},
}).Return(&types.Dataset{Name: "foo"}, nil)
tester.WithBody(t, &types.UpdateDatasetReq{
UpdateRepoReq: types.UpdateRepoReq{Name: "r"},
}).Execute()

tester.ResponseEq(t, 200, tester.OKText, &types.Dataset{Name: "foo"})
}

func TestDatasetHandler_Delete(t *testing.T) {
tester := NewDatasetTester(t).WithHandleFunc(func(h *DatasetHandler) gin.HandlerFunc {
return h.Delete
t.Run("forbidden", func(t *testing.T) {
tester := NewDatasetTester(t).WithHandleFunc(func(h *DatasetHandler) gin.HandlerFunc {
return h.Delete
})
tester.RequireUser(t)

tester.mocks.dataset.EXPECT().Delete(tester.ctx, "u-other", "r", "u").Return(component.ErrForbidden)
tester.WithParam("namespace", "u-other").WithParam("name", "r")
tester.WithUser().Execute()

require.Equal(t, 403, tester.response.Code)
})
tester.RequireUser(t)

tester.mocks.dataset.EXPECT().Delete(tester.ctx, "u", "r", "u").Return(nil)
tester.Execute()
t.Run("normal", func(t *testing.T) {
tester := NewDatasetTester(t).WithHandleFunc(func(h *DatasetHandler) gin.HandlerFunc {
return h.Delete
})
tester.RequireUser(t)

tester.ResponseEq(t, 200, tester.OKText, nil)
tester.mocks.dataset.EXPECT().Delete(tester.ctx, "u", "r", "u").Return(nil)
tester.Execute()

tester.ResponseEq(t, 200, tester.OKText, nil)
})
}

func TestDatasetHandler_Show(t *testing.T) {
tester := NewDatasetTester(t).WithHandleFunc(func(h *DatasetHandler) gin.HandlerFunc {
return h.Show
t.Run("forbidden", func(t *testing.T) {
tester := NewDatasetTester(t).WithHandleFunc(func(h *DatasetHandler) gin.HandlerFunc {
return h.Show
})

tester.mocks.dataset.EXPECT().Show(tester.ctx, "u-other", "r", "u").Return(nil, component.ErrForbidden)
tester.WithParam("namespace", "u-other").WithParam("name", "r")
tester.WithUser().Execute()

require.Equal(t, 403, tester.response.Code)
})

tester.mocks.dataset.EXPECT().Show(tester.ctx, "u", "r", "u").Return(&types.Dataset{
Name: "d",
}, nil)
tester.WithUser().Execute()
t.Run("normal", func(t *testing.T) {
tester := NewDatasetTester(t).WithHandleFunc(func(h *DatasetHandler) gin.HandlerFunc {
return h.Show
})

tester.mocks.dataset.EXPECT().Show(tester.ctx, "u", "r", "u").Return(&types.Dataset{
Name: "d",
}, nil)
tester.WithUser().Execute()

tester.ResponseEq(t, 200, tester.OKText, &types.Dataset{Name: "d"})
tester.ResponseEq(t, 200, tester.OKText, &types.Dataset{Name: "d"})
})
}

func TestDatasetHandler_Relations(t *testing.T) {
tester := NewDatasetTester(t).WithHandleFunc(func(h *DatasetHandler) gin.HandlerFunc {
return h.Relations
t.Run("forbidden", func(t *testing.T) {
tester := NewDatasetTester(t).WithHandleFunc(func(h *DatasetHandler) gin.HandlerFunc {
return h.Relations
})

tester.mocks.dataset.EXPECT().Relations(tester.ctx, "u-other", "r", "u").Return(nil, component.ErrForbidden)
tester.WithParam("namespace", "u-other").WithParam("name", "r")
tester.WithUser().Execute()

require.Equal(t, 403, tester.response.Code)

})

tester.mocks.dataset.EXPECT().Relations(tester.ctx, "u", "r", "u").Return(&types.Relations{
Models: []*types.Model{{Name: "m"}},
}, nil)
tester.WithUser().Execute()
t.Run("normal", func(t *testing.T) {
tester := NewDatasetTester(t).WithHandleFunc(func(h *DatasetHandler) gin.HandlerFunc {
return h.Relations
})

tester.mocks.dataset.EXPECT().Relations(tester.ctx, "u", "r", "u").Return(&types.Relations{
Models: []*types.Model{{Name: "m"}},
}, nil)
tester.WithUser().Execute()

tester.ResponseEq(t, 200, tester.OKText, &types.Relations{
Models: []*types.Model{{Name: "m"}},
tester.ResponseEq(t, 200, tester.OKText, &types.Relations{
Models: []*types.Model{{Name: "m"}},
})
})
}

func TestDatasetHandler_AllFiles(t *testing.T) {
tester := NewDatasetTester(t).WithHandleFunc(func(h *DatasetHandler) gin.HandlerFunc {
return h.AllFiles
t.Run("forbidden", func(t *testing.T) {
tester := NewDatasetTester(t).WithHandleFunc(func(h *DatasetHandler) gin.HandlerFunc {
return h.AllFiles
})

tester.mocks.repo.EXPECT().AllFiles(tester.ctx, types.GetAllFilesReq{
Namespace: "u-other",
Name: "r",
RepoType: types.DatasetRepo,
CurrentUser: "u",
}).Return(nil, component.ErrForbidden)
tester.WithParam("namespace", "u-other").WithParam("name", "r")
tester.WithUser().Execute()

require.Equal(t, 403, tester.response.Code)
})

tester.mocks.repo.EXPECT().AllFiles(tester.ctx, types.GetAllFilesReq{
Namespace: "u",
Name: "r",
RepoType: types.DatasetRepo,
CurrentUser: "u",
}).Return([]*types.File{{Name: "f"}}, nil)
tester.WithUser().Execute()
t.Run("normal", func(t *testing.T) {
tester := NewDatasetTester(t).WithHandleFunc(func(h *DatasetHandler) gin.HandlerFunc {
return h.AllFiles
})

tester.mocks.repo.EXPECT().AllFiles(tester.ctx, types.GetAllFilesReq{
Namespace: "u",
Name: "r",
RepoType: types.DatasetRepo,
CurrentUser: "u",
}).Return([]*types.File{{Name: "f"}}, nil)
tester.WithUser().Execute()

tester.ResponseEq(t, 200, tester.OKText, []*types.File{{Name: "f"}})
tester.ResponseEq(t, 200, tester.OKText, []*types.File{{Name: "f"}})
})
}
4 changes: 4 additions & 0 deletions api/handler/git_http.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ func (h *GitHTTPHandler) GitUploadPack(ctx *gin.Context) {

err := h.gitHttp.GitUploadPack(ctx.Request.Context(), req)
if err != nil {
if errors.Is(err, component.ErrForbidden) {
httpbase.ForbiddenError(ctx, err)
return
}
httpbase.ServerError(ctx, err)
return
}
Expand Down
Loading

0 comments on commit a8d401b

Please sign in to comment.