diff --git a/_mocks/opencsg.com/csghub-server/component/mock_TagComponent.go b/_mocks/opencsg.com/csghub-server/component/mock_TagComponent.go index b65cdc23..8aebb025 100644 --- a/_mocks/opencsg.com/csghub-server/component/mock_TagComponent.go +++ b/_mocks/opencsg.com/csghub-server/component/mock_TagComponent.go @@ -190,9 +190,9 @@ func (_c *MockTagComponent_ClearMetaTags_Call) RunAndReturn(run func(context.Con return _c } -// CreateCategory provides a mock function with given fields: ctx, username, req -func (_m *MockTagComponent) CreateCategory(ctx context.Context, username string, req types.CreateCategory) (*database.TagCategory, error) { - ret := _m.Called(ctx, username, req) +// CreateCategory provides a mock function with given fields: ctx, req +func (_m *MockTagComponent) CreateCategory(ctx context.Context, req types.CreateCategory) (*database.TagCategory, error) { + ret := _m.Called(ctx, req) if len(ret) == 0 { panic("no return value specified for CreateCategory") @@ -200,19 +200,19 @@ func (_m *MockTagComponent) CreateCategory(ctx context.Context, username string, var r0 *database.TagCategory var r1 error - if rf, ok := ret.Get(0).(func(context.Context, string, types.CreateCategory) (*database.TagCategory, error)); ok { - return rf(ctx, username, req) + if rf, ok := ret.Get(0).(func(context.Context, types.CreateCategory) (*database.TagCategory, error)); ok { + return rf(ctx, req) } - if rf, ok := ret.Get(0).(func(context.Context, string, types.CreateCategory) *database.TagCategory); ok { - r0 = rf(ctx, username, req) + if rf, ok := ret.Get(0).(func(context.Context, types.CreateCategory) *database.TagCategory); ok { + r0 = rf(ctx, req) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*database.TagCategory) } } - if rf, ok := ret.Get(1).(func(context.Context, string, types.CreateCategory) error); ok { - r1 = rf(ctx, username, req) + if rf, ok := ret.Get(1).(func(context.Context, types.CreateCategory) error); ok { + r1 = rf(ctx, req) } else { r1 = ret.Error(1) } @@ -227,15 +227,14 @@ type MockTagComponent_CreateCategory_Call struct { // CreateCategory is a helper method to define mock.On call // - ctx context.Context -// - username string // - req types.CreateCategory -func (_e *MockTagComponent_Expecter) CreateCategory(ctx interface{}, username interface{}, req interface{}) *MockTagComponent_CreateCategory_Call { - return &MockTagComponent_CreateCategory_Call{Call: _e.mock.On("CreateCategory", ctx, username, req)} +func (_e *MockTagComponent_Expecter) CreateCategory(ctx interface{}, req interface{}) *MockTagComponent_CreateCategory_Call { + return &MockTagComponent_CreateCategory_Call{Call: _e.mock.On("CreateCategory", ctx, req)} } -func (_c *MockTagComponent_CreateCategory_Call) Run(run func(ctx context.Context, username string, req types.CreateCategory)) *MockTagComponent_CreateCategory_Call { +func (_c *MockTagComponent_CreateCategory_Call) Run(run func(ctx context.Context, req types.CreateCategory)) *MockTagComponent_CreateCategory_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string), args[2].(types.CreateCategory)) + run(args[0].(context.Context), args[1].(types.CreateCategory)) }) return _c } @@ -245,14 +244,14 @@ func (_c *MockTagComponent_CreateCategory_Call) Return(_a0 *database.TagCategory return _c } -func (_c *MockTagComponent_CreateCategory_Call) RunAndReturn(run func(context.Context, string, types.CreateCategory) (*database.TagCategory, error)) *MockTagComponent_CreateCategory_Call { +func (_c *MockTagComponent_CreateCategory_Call) RunAndReturn(run func(context.Context, types.CreateCategory) (*database.TagCategory, error)) *MockTagComponent_CreateCategory_Call { _c.Call.Return(run) return _c } -// CreateTag provides a mock function with given fields: ctx, username, req -func (_m *MockTagComponent) CreateTag(ctx context.Context, username string, req types.CreateTag) (*database.Tag, error) { - ret := _m.Called(ctx, username, req) +// CreateTag provides a mock function with given fields: ctx, req +func (_m *MockTagComponent) CreateTag(ctx context.Context, req types.CreateTag) (*database.Tag, error) { + ret := _m.Called(ctx, req) if len(ret) == 0 { panic("no return value specified for CreateTag") @@ -260,19 +259,19 @@ func (_m *MockTagComponent) CreateTag(ctx context.Context, username string, req var r0 *database.Tag var r1 error - if rf, ok := ret.Get(0).(func(context.Context, string, types.CreateTag) (*database.Tag, error)); ok { - return rf(ctx, username, req) + if rf, ok := ret.Get(0).(func(context.Context, types.CreateTag) (*database.Tag, error)); ok { + return rf(ctx, req) } - if rf, ok := ret.Get(0).(func(context.Context, string, types.CreateTag) *database.Tag); ok { - r0 = rf(ctx, username, req) + if rf, ok := ret.Get(0).(func(context.Context, types.CreateTag) *database.Tag); ok { + r0 = rf(ctx, req) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*database.Tag) } } - if rf, ok := ret.Get(1).(func(context.Context, string, types.CreateTag) error); ok { - r1 = rf(ctx, username, req) + if rf, ok := ret.Get(1).(func(context.Context, types.CreateTag) error); ok { + r1 = rf(ctx, req) } else { r1 = ret.Error(1) } @@ -287,15 +286,14 @@ type MockTagComponent_CreateTag_Call struct { // CreateTag is a helper method to define mock.On call // - ctx context.Context -// - username string // - req types.CreateTag -func (_e *MockTagComponent_Expecter) CreateTag(ctx interface{}, username interface{}, req interface{}) *MockTagComponent_CreateTag_Call { - return &MockTagComponent_CreateTag_Call{Call: _e.mock.On("CreateTag", ctx, username, req)} +func (_e *MockTagComponent_Expecter) CreateTag(ctx interface{}, req interface{}) *MockTagComponent_CreateTag_Call { + return &MockTagComponent_CreateTag_Call{Call: _e.mock.On("CreateTag", ctx, req)} } -func (_c *MockTagComponent_CreateTag_Call) Run(run func(ctx context.Context, username string, req types.CreateTag)) *MockTagComponent_CreateTag_Call { +func (_c *MockTagComponent_CreateTag_Call) Run(run func(ctx context.Context, req types.CreateTag)) *MockTagComponent_CreateTag_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string), args[2].(types.CreateTag)) + run(args[0].(context.Context), args[1].(types.CreateTag)) }) return _c } @@ -305,22 +303,22 @@ func (_c *MockTagComponent_CreateTag_Call) Return(_a0 *database.Tag, _a1 error) return _c } -func (_c *MockTagComponent_CreateTag_Call) RunAndReturn(run func(context.Context, string, types.CreateTag) (*database.Tag, error)) *MockTagComponent_CreateTag_Call { +func (_c *MockTagComponent_CreateTag_Call) RunAndReturn(run func(context.Context, types.CreateTag) (*database.Tag, error)) *MockTagComponent_CreateTag_Call { _c.Call.Return(run) return _c } -// DeleteCategory provides a mock function with given fields: ctx, username, id -func (_m *MockTagComponent) DeleteCategory(ctx context.Context, username string, id int64) error { - ret := _m.Called(ctx, username, id) +// DeleteCategory provides a mock function with given fields: ctx, id +func (_m *MockTagComponent) DeleteCategory(ctx context.Context, id int64) error { + ret := _m.Called(ctx, id) if len(ret) == 0 { panic("no return value specified for DeleteCategory") } var r0 error - if rf, ok := ret.Get(0).(func(context.Context, string, int64) error); ok { - r0 = rf(ctx, username, id) + if rf, ok := ret.Get(0).(func(context.Context, int64) error); ok { + r0 = rf(ctx, id) } else { r0 = ret.Error(0) } @@ -335,15 +333,14 @@ type MockTagComponent_DeleteCategory_Call struct { // DeleteCategory is a helper method to define mock.On call // - ctx context.Context -// - username string // - id int64 -func (_e *MockTagComponent_Expecter) DeleteCategory(ctx interface{}, username interface{}, id interface{}) *MockTagComponent_DeleteCategory_Call { - return &MockTagComponent_DeleteCategory_Call{Call: _e.mock.On("DeleteCategory", ctx, username, id)} +func (_e *MockTagComponent_Expecter) DeleteCategory(ctx interface{}, id interface{}) *MockTagComponent_DeleteCategory_Call { + return &MockTagComponent_DeleteCategory_Call{Call: _e.mock.On("DeleteCategory", ctx, id)} } -func (_c *MockTagComponent_DeleteCategory_Call) Run(run func(ctx context.Context, username string, id int64)) *MockTagComponent_DeleteCategory_Call { +func (_c *MockTagComponent_DeleteCategory_Call) Run(run func(ctx context.Context, id int64)) *MockTagComponent_DeleteCategory_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string), args[2].(int64)) + run(args[0].(context.Context), args[1].(int64)) }) return _c } @@ -353,22 +350,22 @@ func (_c *MockTagComponent_DeleteCategory_Call) Return(_a0 error) *MockTagCompon return _c } -func (_c *MockTagComponent_DeleteCategory_Call) RunAndReturn(run func(context.Context, string, int64) error) *MockTagComponent_DeleteCategory_Call { +func (_c *MockTagComponent_DeleteCategory_Call) RunAndReturn(run func(context.Context, int64) error) *MockTagComponent_DeleteCategory_Call { _c.Call.Return(run) return _c } -// DeleteTag provides a mock function with given fields: ctx, username, id -func (_m *MockTagComponent) DeleteTag(ctx context.Context, username string, id int64) error { - ret := _m.Called(ctx, username, id) +// DeleteTag provides a mock function with given fields: ctx, id +func (_m *MockTagComponent) DeleteTag(ctx context.Context, id int64) error { + ret := _m.Called(ctx, id) if len(ret) == 0 { panic("no return value specified for DeleteTag") } var r0 error - if rf, ok := ret.Get(0).(func(context.Context, string, int64) error); ok { - r0 = rf(ctx, username, id) + if rf, ok := ret.Get(0).(func(context.Context, int64) error); ok { + r0 = rf(ctx, id) } else { r0 = ret.Error(0) } @@ -383,15 +380,14 @@ type MockTagComponent_DeleteTag_Call struct { // DeleteTag is a helper method to define mock.On call // - ctx context.Context -// - username string // - id int64 -func (_e *MockTagComponent_Expecter) DeleteTag(ctx interface{}, username interface{}, id interface{}) *MockTagComponent_DeleteTag_Call { - return &MockTagComponent_DeleteTag_Call{Call: _e.mock.On("DeleteTag", ctx, username, id)} +func (_e *MockTagComponent_Expecter) DeleteTag(ctx interface{}, id interface{}) *MockTagComponent_DeleteTag_Call { + return &MockTagComponent_DeleteTag_Call{Call: _e.mock.On("DeleteTag", ctx, id)} } -func (_c *MockTagComponent_DeleteTag_Call) Run(run func(ctx context.Context, username string, id int64)) *MockTagComponent_DeleteTag_Call { +func (_c *MockTagComponent_DeleteTag_Call) Run(run func(ctx context.Context, id int64)) *MockTagComponent_DeleteTag_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string), args[2].(int64)) + run(args[0].(context.Context), args[1].(int64)) }) return _c } @@ -401,14 +397,14 @@ func (_c *MockTagComponent_DeleteTag_Call) Return(_a0 error) *MockTagComponent_D return _c } -func (_c *MockTagComponent_DeleteTag_Call) RunAndReturn(run func(context.Context, string, int64) error) *MockTagComponent_DeleteTag_Call { +func (_c *MockTagComponent_DeleteTag_Call) RunAndReturn(run func(context.Context, int64) error) *MockTagComponent_DeleteTag_Call { _c.Call.Return(run) return _c } -// GetTagByID provides a mock function with given fields: ctx, username, id -func (_m *MockTagComponent) GetTagByID(ctx context.Context, username string, id int64) (*database.Tag, error) { - ret := _m.Called(ctx, username, id) +// GetTagByID provides a mock function with given fields: ctx, id +func (_m *MockTagComponent) GetTagByID(ctx context.Context, id int64) (*database.Tag, error) { + ret := _m.Called(ctx, id) if len(ret) == 0 { panic("no return value specified for GetTagByID") @@ -416,19 +412,19 @@ func (_m *MockTagComponent) GetTagByID(ctx context.Context, username string, id var r0 *database.Tag var r1 error - if rf, ok := ret.Get(0).(func(context.Context, string, int64) (*database.Tag, error)); ok { - return rf(ctx, username, id) + if rf, ok := ret.Get(0).(func(context.Context, int64) (*database.Tag, error)); ok { + return rf(ctx, id) } - if rf, ok := ret.Get(0).(func(context.Context, string, int64) *database.Tag); ok { - r0 = rf(ctx, username, id) + if rf, ok := ret.Get(0).(func(context.Context, int64) *database.Tag); ok { + r0 = rf(ctx, id) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*database.Tag) } } - if rf, ok := ret.Get(1).(func(context.Context, string, int64) error); ok { - r1 = rf(ctx, username, id) + if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok { + r1 = rf(ctx, id) } else { r1 = ret.Error(1) } @@ -443,15 +439,14 @@ type MockTagComponent_GetTagByID_Call struct { // GetTagByID is a helper method to define mock.On call // - ctx context.Context -// - username string // - id int64 -func (_e *MockTagComponent_Expecter) GetTagByID(ctx interface{}, username interface{}, id interface{}) *MockTagComponent_GetTagByID_Call { - return &MockTagComponent_GetTagByID_Call{Call: _e.mock.On("GetTagByID", ctx, username, id)} +func (_e *MockTagComponent_Expecter) GetTagByID(ctx interface{}, id interface{}) *MockTagComponent_GetTagByID_Call { + return &MockTagComponent_GetTagByID_Call{Call: _e.mock.On("GetTagByID", ctx, id)} } -func (_c *MockTagComponent_GetTagByID_Call) Run(run func(ctx context.Context, username string, id int64)) *MockTagComponent_GetTagByID_Call { +func (_c *MockTagComponent_GetTagByID_Call) Run(run func(ctx context.Context, id int64)) *MockTagComponent_GetTagByID_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string), args[2].(int64)) + run(args[0].(context.Context), args[1].(int64)) }) return _c } @@ -461,14 +456,14 @@ func (_c *MockTagComponent_GetTagByID_Call) Return(_a0 *database.Tag, _a1 error) return _c } -func (_c *MockTagComponent_GetTagByID_Call) RunAndReturn(run func(context.Context, string, int64) (*database.Tag, error)) *MockTagComponent_GetTagByID_Call { +func (_c *MockTagComponent_GetTagByID_Call) RunAndReturn(run func(context.Context, int64) (*database.Tag, error)) *MockTagComponent_GetTagByID_Call { _c.Call.Return(run) return _c } -// UpdateCategory provides a mock function with given fields: ctx, username, req, id -func (_m *MockTagComponent) UpdateCategory(ctx context.Context, username string, req types.UpdateCategory, id int64) (*database.TagCategory, error) { - ret := _m.Called(ctx, username, req, id) +// UpdateCategory provides a mock function with given fields: ctx, req, id +func (_m *MockTagComponent) UpdateCategory(ctx context.Context, req types.UpdateCategory, id int64) (*database.TagCategory, error) { + ret := _m.Called(ctx, req, id) if len(ret) == 0 { panic("no return value specified for UpdateCategory") @@ -476,19 +471,19 @@ func (_m *MockTagComponent) UpdateCategory(ctx context.Context, username string, var r0 *database.TagCategory var r1 error - if rf, ok := ret.Get(0).(func(context.Context, string, types.UpdateCategory, int64) (*database.TagCategory, error)); ok { - return rf(ctx, username, req, id) + if rf, ok := ret.Get(0).(func(context.Context, types.UpdateCategory, int64) (*database.TagCategory, error)); ok { + return rf(ctx, req, id) } - if rf, ok := ret.Get(0).(func(context.Context, string, types.UpdateCategory, int64) *database.TagCategory); ok { - r0 = rf(ctx, username, req, id) + if rf, ok := ret.Get(0).(func(context.Context, types.UpdateCategory, int64) *database.TagCategory); ok { + r0 = rf(ctx, req, id) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*database.TagCategory) } } - if rf, ok := ret.Get(1).(func(context.Context, string, types.UpdateCategory, int64) error); ok { - r1 = rf(ctx, username, req, id) + if rf, ok := ret.Get(1).(func(context.Context, types.UpdateCategory, int64) error); ok { + r1 = rf(ctx, req, id) } else { r1 = ret.Error(1) } @@ -503,16 +498,15 @@ type MockTagComponent_UpdateCategory_Call struct { // UpdateCategory is a helper method to define mock.On call // - ctx context.Context -// - username string // - req types.UpdateCategory // - id int64 -func (_e *MockTagComponent_Expecter) UpdateCategory(ctx interface{}, username interface{}, req interface{}, id interface{}) *MockTagComponent_UpdateCategory_Call { - return &MockTagComponent_UpdateCategory_Call{Call: _e.mock.On("UpdateCategory", ctx, username, req, id)} +func (_e *MockTagComponent_Expecter) UpdateCategory(ctx interface{}, req interface{}, id interface{}) *MockTagComponent_UpdateCategory_Call { + return &MockTagComponent_UpdateCategory_Call{Call: _e.mock.On("UpdateCategory", ctx, req, id)} } -func (_c *MockTagComponent_UpdateCategory_Call) Run(run func(ctx context.Context, username string, req types.UpdateCategory, id int64)) *MockTagComponent_UpdateCategory_Call { +func (_c *MockTagComponent_UpdateCategory_Call) Run(run func(ctx context.Context, req types.UpdateCategory, id int64)) *MockTagComponent_UpdateCategory_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string), args[2].(types.UpdateCategory), args[3].(int64)) + run(args[0].(context.Context), args[1].(types.UpdateCategory), args[2].(int64)) }) return _c } @@ -522,7 +516,7 @@ func (_c *MockTagComponent_UpdateCategory_Call) Return(_a0 *database.TagCategory return _c } -func (_c *MockTagComponent_UpdateCategory_Call) RunAndReturn(run func(context.Context, string, types.UpdateCategory, int64) (*database.TagCategory, error)) *MockTagComponent_UpdateCategory_Call { +func (_c *MockTagComponent_UpdateCategory_Call) RunAndReturn(run func(context.Context, types.UpdateCategory, int64) (*database.TagCategory, error)) *MockTagComponent_UpdateCategory_Call { _c.Call.Return(run) return _c } @@ -690,9 +684,9 @@ func (_c *MockTagComponent_UpdateRepoTagsByCategory_Call) RunAndReturn(run func( return _c } -// UpdateTag provides a mock function with given fields: ctx, username, id, req -func (_m *MockTagComponent) UpdateTag(ctx context.Context, username string, id int64, req types.UpdateTag) (*database.Tag, error) { - ret := _m.Called(ctx, username, id, req) +// UpdateTag provides a mock function with given fields: ctx, id, req +func (_m *MockTagComponent) UpdateTag(ctx context.Context, id int64, req types.UpdateTag) (*database.Tag, error) { + ret := _m.Called(ctx, id, req) if len(ret) == 0 { panic("no return value specified for UpdateTag") @@ -700,19 +694,19 @@ func (_m *MockTagComponent) UpdateTag(ctx context.Context, username string, id i var r0 *database.Tag var r1 error - if rf, ok := ret.Get(0).(func(context.Context, string, int64, types.UpdateTag) (*database.Tag, error)); ok { - return rf(ctx, username, id, req) + if rf, ok := ret.Get(0).(func(context.Context, int64, types.UpdateTag) (*database.Tag, error)); ok { + return rf(ctx, id, req) } - if rf, ok := ret.Get(0).(func(context.Context, string, int64, types.UpdateTag) *database.Tag); ok { - r0 = rf(ctx, username, id, req) + if rf, ok := ret.Get(0).(func(context.Context, int64, types.UpdateTag) *database.Tag); ok { + r0 = rf(ctx, id, req) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*database.Tag) } } - if rf, ok := ret.Get(1).(func(context.Context, string, int64, types.UpdateTag) error); ok { - r1 = rf(ctx, username, id, req) + if rf, ok := ret.Get(1).(func(context.Context, int64, types.UpdateTag) error); ok { + r1 = rf(ctx, id, req) } else { r1 = ret.Error(1) } @@ -727,16 +721,15 @@ type MockTagComponent_UpdateTag_Call struct { // UpdateTag is a helper method to define mock.On call // - ctx context.Context -// - username string // - id int64 // - req types.UpdateTag -func (_e *MockTagComponent_Expecter) UpdateTag(ctx interface{}, username interface{}, id interface{}, req interface{}) *MockTagComponent_UpdateTag_Call { - return &MockTagComponent_UpdateTag_Call{Call: _e.mock.On("UpdateTag", ctx, username, id, req)} +func (_e *MockTagComponent_Expecter) UpdateTag(ctx interface{}, id interface{}, req interface{}) *MockTagComponent_UpdateTag_Call { + return &MockTagComponent_UpdateTag_Call{Call: _e.mock.On("UpdateTag", ctx, id, req)} } -func (_c *MockTagComponent_UpdateTag_Call) Run(run func(ctx context.Context, username string, id int64, req types.UpdateTag)) *MockTagComponent_UpdateTag_Call { +func (_c *MockTagComponent_UpdateTag_Call) Run(run func(ctx context.Context, id int64, req types.UpdateTag)) *MockTagComponent_UpdateTag_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string), args[2].(int64), args[3].(types.UpdateTag)) + run(args[0].(context.Context), args[1].(int64), args[2].(types.UpdateTag)) }) return _c } @@ -746,7 +739,7 @@ func (_c *MockTagComponent_UpdateTag_Call) Return(_a0 *database.Tag, _a1 error) return _c } -func (_c *MockTagComponent_UpdateTag_Call) RunAndReturn(run func(context.Context, string, int64, types.UpdateTag) (*database.Tag, error)) *MockTagComponent_UpdateTag_Call { +func (_c *MockTagComponent_UpdateTag_Call) RunAndReturn(run func(context.Context, int64, types.UpdateTag) (*database.Tag, error)) *MockTagComponent_UpdateTag_Call { _c.Call.Return(run) return _c } diff --git a/api/handler/dataset.go b/api/handler/dataset.go index d6984650..baa70569 100644 --- a/api/handler/dataset.go +++ b/api/handler/dataset.go @@ -193,11 +193,11 @@ func (h *DatasetHandler) Update(ctx *gin.Context) { dataset, err := h.dataset.Update(ctx.Request.Context(), req) if err != nil { + slog.Error("Failed to update dataset", slog.Any("error", err)) if errors.Is(err, errorx.ErrForbidden) { httpbase.ForbiddenError(ctx, err) return } - slog.Error("Failed to update dataset", slog.Any("error", err)) httpbase.ServerError(ctx, err) return } diff --git a/api/handler/tag.go b/api/handler/tag.go index 41fd58f3..1a2c6101 100644 --- a/api/handler/tag.go +++ b/api/handler/tag.go @@ -38,6 +38,7 @@ type TagsHandler struct { // @Param category query string false "category name" // @Param scope query string false "scope name" Enums(model, dataset, code, space, prompt) // @Param built_in query bool false "built_in" +// @Param search query string false "search on name and show_name fields" // @Success 200 {object} types.ResponseWithTotal{data=[]types.RepoTag} "tags" // @Failure 400 {object} types.APIBadRequest "Bad request" // @Failure 500 {object} types.APIInternalServerError "Internal server error" @@ -61,7 +62,7 @@ func (t *TagsHandler) AllTags(ctx *gin.Context) { // CreateTag godoc // @Security ApiKey // @Summary Create new tag -// @Description Create new tag +// @Description Create new tag, used for admin // @Tags Tag // @Accept json // @Produce json @@ -71,14 +72,13 @@ func (t *TagsHandler) AllTags(ctx *gin.Context) { // @Failure 500 {object} types.APIInternalServerError "Internal server error" // @Router /tags [post] func (t *TagsHandler) CreateTag(ctx *gin.Context) { - userName := httpbase.GetCurrentUser(ctx) var req types.CreateTag if err := ctx.ShouldBindJSON(&req); err != nil { slog.Error("Bad request format", slog.Any("error", err)) httpbase.BadRequest(ctx, err.Error()) return } - tag, err := t.tag.CreateTag(ctx.Request.Context(), userName, req) + tag, err := t.tag.CreateTag(ctx.Request.Context(), req) if err != nil { slog.Error("Failed to create tag", slog.Any("req", req), slog.Any("error", err)) httpbase.ServerError(ctx, err) @@ -90,7 +90,7 @@ func (t *TagsHandler) CreateTag(ctx *gin.Context) { // GetTag godoc // @Security ApiKey // @Summary Get a tag by id -// @Description Get a tag by id +// @Description Get a tag by id, used for admin // @Tags Tag // @Accept json // @Produce json @@ -100,14 +100,13 @@ func (t *TagsHandler) CreateTag(ctx *gin.Context) { // @Failure 500 {object} types.APIInternalServerError "Internal server error" // @Router /tags/{id} [get] func (t *TagsHandler) GetTagByID(ctx *gin.Context) { - userName := httpbase.GetCurrentUser(ctx) id, err := strconv.ParseInt(ctx.Param("id"), 10, 64) if err != nil { slog.Error("Bad request format", slog.Any("error", err)) httpbase.BadRequest(ctx, err.Error()) return } - tag, err := t.tag.GetTagByID(ctx.Request.Context(), userName, id) + tag, err := t.tag.GetTagByID(ctx.Request.Context(), id) if err != nil { slog.Error("Failed to get tag", slog.Int64("id", id), slog.Any("error", err)) httpbase.ServerError(ctx, err) @@ -119,7 +118,7 @@ func (t *TagsHandler) GetTagByID(ctx *gin.Context) { // UpdateTag godoc // @Security ApiKey // @Summary Update a tag by id -// @Description Update a tag by id +// @Description Update a tag by id, used for admin // @Tags Tag // @Accept json // @Produce json @@ -130,7 +129,6 @@ func (t *TagsHandler) GetTagByID(ctx *gin.Context) { // @Failure 500 {object} types.APIInternalServerError "Internal server error" // @Router /tags/{id} [put] func (t *TagsHandler) UpdateTag(ctx *gin.Context) { - userName := httpbase.GetCurrentUser(ctx) id, err := strconv.ParseInt(ctx.Param("id"), 10, 64) if err != nil { slog.Error("Bad request format", slog.Any("error", err)) @@ -143,7 +141,7 @@ func (t *TagsHandler) UpdateTag(ctx *gin.Context) { httpbase.BadRequest(ctx, err.Error()) return } - tag, err := t.tag.UpdateTag(ctx.Request.Context(), userName, id, req) + tag, err := t.tag.UpdateTag(ctx.Request.Context(), id, req) if err != nil { slog.Error("Failed to update tag", slog.Int64("id", id), slog.Any("error", err)) httpbase.ServerError(ctx, err) @@ -155,7 +153,7 @@ func (t *TagsHandler) UpdateTag(ctx *gin.Context) { // DeleteTag godoc // @Security ApiKey // @Summary Delete a tag by id -// @Description Delete a tag by id +// @Description Delete a tag by id, used for admin // @Tags Tag // @Accept json // @Produce json @@ -165,14 +163,13 @@ func (t *TagsHandler) UpdateTag(ctx *gin.Context) { // @Failure 500 {object} types.APIInternalServerError "Internal server error" // @Router /tags/{id} [delete] func (t *TagsHandler) DeleteTag(ctx *gin.Context) { - userName := httpbase.GetCurrentUser(ctx) id, err := strconv.ParseInt(ctx.Param("id"), 10, 64) if err != nil { slog.Error("Bad request format", slog.Any("error", err)) httpbase.BadRequest(ctx, err.Error()) return } - err = t.tag.DeleteTag(ctx.Request.Context(), userName, id) + err = t.tag.DeleteTag(ctx.Request.Context(), id) if err != nil { slog.Error("Failed to delete tag", slog.Int64("id", id), slog.Any("error", err)) httpbase.ServerError(ctx, err) @@ -205,7 +202,7 @@ func (t *TagsHandler) AllCategories(ctx *gin.Context) { // CreateCategory godoc // @Security ApiKey // @Summary Create new category -// @Description Create new category +// @Description Create new category, used for admin // @Tags Tag // @Accept json // @Produce json @@ -215,14 +212,13 @@ func (t *TagsHandler) AllCategories(ctx *gin.Context) { // @Failure 500 {object} types.APIInternalServerError "Internal server error" // @Router /tags/categories [post] func (t *TagsHandler) CreateCategory(ctx *gin.Context) { - userName := httpbase.GetCurrentUser(ctx) var req types.CreateCategory if err := ctx.ShouldBindJSON(&req); err != nil { slog.Error("Bad request format", slog.Any("error", err)) httpbase.BadRequest(ctx, err.Error()) return } - category, err := t.tag.CreateCategory(ctx.Request.Context(), userName, req) + category, err := t.tag.CreateCategory(ctx.Request.Context(), req) if err != nil { if errors.Is(err, errorx.ErrForbidden) { httpbase.ForbiddenError(ctx, err) @@ -238,7 +234,7 @@ func (t *TagsHandler) CreateCategory(ctx *gin.Context) { // UpdateCategory godoc // @Security ApiKey // @Summary Create new category -// @Description Create new category +// @Description Create new category, used for admin // @Tags Tag // @Accept json // @Produce json @@ -248,7 +244,6 @@ func (t *TagsHandler) CreateCategory(ctx *gin.Context) { // @Failure 500 {object} types.APIInternalServerError "Internal server error" // @Router /tags/categories/id [put] func (t *TagsHandler) UpdateCategory(ctx *gin.Context) { - userName := httpbase.GetCurrentUser(ctx) var req types.UpdateCategory if err := ctx.ShouldBindJSON(&req); err != nil { slog.Error("Bad request format", slog.Any("error", err)) @@ -261,7 +256,7 @@ func (t *TagsHandler) UpdateCategory(ctx *gin.Context) { httpbase.BadRequest(ctx, err.Error()) return } - category, err := t.tag.UpdateCategory(ctx.Request.Context(), userName, req, id) + category, err := t.tag.UpdateCategory(ctx.Request.Context(), req, id) if err != nil { if errors.Is(err, errorx.ErrForbidden) { httpbase.ForbiddenError(ctx, err) @@ -277,7 +272,7 @@ func (t *TagsHandler) UpdateCategory(ctx *gin.Context) { // DeleteCategory godoc // @Security ApiKey // @Summary Delete a category by id -// @Description Delete a category by id +// @Description Delete a category by id, used for admin // @Tags Tag // @Accept json // @Produce json @@ -286,14 +281,14 @@ func (t *TagsHandler) UpdateCategory(ctx *gin.Context) { // @Failure 500 {object} types.APIInternalServerError "Internal server error" // @Router /tags/categories/id [delete] func (t *TagsHandler) DeleteCategory(ctx *gin.Context) { - userName := httpbase.GetCurrentUser(ctx) + id, err := strconv.ParseInt(ctx.Param("id"), 10, 64) if err != nil { slog.Error("Bad request format", slog.Any("error", err)) httpbase.BadRequest(ctx, err.Error()) return } - err = t.tag.DeleteCategory(ctx.Request.Context(), userName, id) + err = t.tag.DeleteCategory(ctx.Request.Context(), id) if err != nil { if errors.Is(err, errorx.ErrForbidden) { httpbase.ForbiddenError(ctx, err) diff --git a/api/handler/tag_test.go b/api/handler/tag_test.go index b5cbfbb4..f07f2346 100644 --- a/api/handler/tag_test.go +++ b/api/handler/tag_test.go @@ -66,7 +66,7 @@ func TestTagHandler_AllTags(t *testing.T) { t.Run("with builtin", func(t *testing.T) { var tags []*types.RepoTag - tags = append(tags, &types.RepoTag{ID: 1, Name: "test1"}) + tags = append(tags, &types.RepoTag{Name: "test1"}) values := url.Values{} values.Add("category", "task") @@ -105,7 +105,6 @@ func TestTagHandler_AllTags(t *testing.T) { } func TestTagHandler_CreateTag(t *testing.T) { - username := "testuser" data := types.CreateTag{ Name: "testtag", Scope: "testscope", @@ -118,11 +117,10 @@ func TestTagHandler_CreateTag(t *testing.T) { hr := httptest.NewRecorder() ginContext, _ := gin.CreateTestContext(hr) - ginContext.Set("currentUser", username) ginContext.Request = req tagComp := mockcom.NewMockTagComponent(t) - tagComp.EXPECT().CreateTag(ginContext.Request.Context(), username, mock.Anything).Return(&database.Tag{ID: 1, Name: "testtag"}, nil) + tagComp.EXPECT().CreateTag(ginContext.Request.Context(), mock.Anything).Return(&database.Tag{ID: 1, Name: "testtag"}, nil) tagHandler, err := NewTestTagHandler(tagComp) require.Nil(t, err) @@ -142,18 +140,15 @@ func TestTagHandler_CreateTag(t *testing.T) { } func TestTagHandler_GetTagByID(t *testing.T) { - username := "testuser" - req := httptest.NewRequest("get", "/api/v1/tags/1", nil) hr := httptest.NewRecorder() ginContext, _ := gin.CreateTestContext(hr) - ginContext.Set("currentUser", username) ginContext.AddParam("id", "1") ginContext.Request = req tagComp := mockcom.NewMockTagComponent(t) - tagComp.EXPECT().GetTagByID(ginContext.Request.Context(), username, int64(1)).Return(&database.Tag{ID: 1, Name: "test1"}, nil) + tagComp.EXPECT().GetTagByID(ginContext.Request.Context(), int64(1)).Return(&database.Tag{ID: 1, Name: "test1"}, nil) tagHandler, err := NewTestTagHandler(tagComp) require.Nil(t, err) @@ -173,7 +168,6 @@ func TestTagHandler_GetTagByID(t *testing.T) { } func TestTagHandler_UpdateTag(t *testing.T) { - username := "testuser" data := types.UpdateTag{ Name: "testtag", Scope: "testscope", @@ -186,12 +180,11 @@ func TestTagHandler_UpdateTag(t *testing.T) { hr := httptest.NewRecorder() ginContext, _ := gin.CreateTestContext(hr) - ginContext.Set("currentUser", username) ginContext.AddParam("id", "1") ginContext.Request = req tagComp := mockcom.NewMockTagComponent(t) - tagComp.EXPECT().UpdateTag(ginContext.Request.Context(), username, int64(1), mock.Anything).Return(&database.Tag{ID: 1, Name: "testtag"}, nil) + tagComp.EXPECT().UpdateTag(ginContext.Request.Context(), int64(1), mock.Anything).Return(&database.Tag{ID: 1, Name: "testtag"}, nil) tagHandler, err := NewTestTagHandler(tagComp) require.Nil(t, err) @@ -211,18 +204,15 @@ func TestTagHandler_UpdateTag(t *testing.T) { } func TestTagHandler_DeleteTag(t *testing.T) { - username := "testuser" - req := httptest.NewRequest("delete", "/api/v1/tags/1", nil) hr := httptest.NewRecorder() ginContext, _ := gin.CreateTestContext(hr) - ginContext.Set("currentUser", username) ginContext.AddParam("id", "1") ginContext.Request = req tagComp := mockcom.NewMockTagComponent(t) - tagComp.EXPECT().DeleteTag(ginContext.Request.Context(), username, int64(1)).Return(nil) + tagComp.EXPECT().DeleteTag(ginContext.Request.Context(), int64(1)).Return(nil) tagHandler, err := NewTestTagHandler(tagComp) require.Nil(t, err) @@ -272,7 +262,6 @@ func TestTagHandler_AllCategories(t *testing.T) { } func TestTagHandler_CreateCategory(t *testing.T) { - username := "testuser" data := types.CreateCategory{ Name: "testcate", Scope: "testscope", @@ -284,11 +273,10 @@ func TestTagHandler_CreateCategory(t *testing.T) { hr := httptest.NewRecorder() ginContext, _ := gin.CreateTestContext(hr) - ginContext.Set("currentUser", username) ginContext.Request = req tagComp := mockcom.NewMockTagComponent(t) - tagComp.EXPECT().CreateCategory(ginContext.Request.Context(), username, data).Return( + tagComp.EXPECT().CreateCategory(ginContext.Request.Context(), data).Return( &database.TagCategory{ID: 1, Name: "testcate", Scope: types.TagScope("testscope")}, nil, ) @@ -311,7 +299,6 @@ func TestTagHandler_CreateCategory(t *testing.T) { } func TestTagHandler_UpdateCategory(t *testing.T) { - username := "testuser" data := types.UpdateCategory{ Name: "testcate", Scope: "testscope", @@ -323,12 +310,11 @@ func TestTagHandler_UpdateCategory(t *testing.T) { hr := httptest.NewRecorder() ginContext, _ := gin.CreateTestContext(hr) - ginContext.Set("currentUser", username) ginContext.AddParam("id", "1") ginContext.Request = req tagComp := mockcom.NewMockTagComponent(t) - tagComp.EXPECT().UpdateCategory(ginContext.Request.Context(), username, data, int64(1)).Return( + tagComp.EXPECT().UpdateCategory(ginContext.Request.Context(), data, int64(1)).Return( &database.TagCategory{ID: 1, Name: "testcate", Scope: types.TagScope("testscope")}, nil, ) @@ -351,18 +337,15 @@ func TestTagHandler_UpdateCategory(t *testing.T) { } func TestTagHandler_DeleteCategory(t *testing.T) { - username := "testuser" - req := httptest.NewRequest("delete", "/tags/categories/1", nil) hr := httptest.NewRecorder() ginContext, _ := gin.CreateTestContext(hr) - ginContext.Set("currentUser", username) ginContext.AddParam("id", "1") ginContext.Request = req tagComp := mockcom.NewMockTagComponent(t) - tagComp.EXPECT().DeleteCategory(ginContext.Request.Context(), username, int64(1)).Return(nil) + tagComp.EXPECT().DeleteCategory(ginContext.Request.Context(), int64(1)).Return(nil) tagHandler, err := NewTestTagHandler(tagComp) require.Nil(t, err) diff --git a/builder/store/database/tag.go b/builder/store/database/tag.go index 8d591082..5c5f651d 100644 --- a/builder/store/database/tag.go +++ b/builder/store/database/tag.go @@ -97,6 +97,10 @@ func (ts *tagStoreImpl) AllTags(ctx context.Context, filter *types.TagFilter) ([ if filter.BuiltIn != nil { q = q.Where("built_in = ?", *filter.BuiltIn) } + if filter.Search != "" { + searchName := "%" + filter.Search + "%" + q = q.Where("name like ? OR show_name like ?", searchName, searchName) + } } err := q.Scan(ctx, &tags) @@ -188,7 +192,7 @@ func (ts *tagStoreImpl) AllCategories(ctx context.Context, scope types.TagScope) } func (ts *tagStoreImpl) CreateTag(ctx context.Context, tag Tag) (*Tag, error) { - _, err := ts.db.Operator.Core.NewInsert().Model(&tag).Exec(ctx) + err := ts.db.Operator.Core.NewInsert().Model(&tag).Scan(ctx, &tag) return &tag, err } @@ -205,6 +209,8 @@ func (ts *tagStoreImpl) SaveTags(ctx context.Context, tags []*Tag) error { } // SetMetaTags will delete existing tags and create new ones +// +// return updated meta tags, exclude exCategories func (ts *tagStoreImpl) SetMetaTags(ctx context.Context, repoType types.RepositoryType, namespace, name string, tags []*Tag) (repoTags []*RepositoryTag, err error) { repo := new(Repository) err = ts.db.Operator.Core.NewSelect().Model(repo). @@ -221,6 +227,7 @@ func (ts *tagStoreImpl) SetMetaTags(ctx context.Context, repoType types.Reposito "framework": true, "runtime_framework": true, "evaluation": true, + "industry": true, } for _, tag := range repo.Tags { if !exCategories[tag.Category] { @@ -373,7 +380,7 @@ func (ts *tagStoreImpl) FindOrCreate(ctx context.Context, tag Tag) (*Tag, error) var resTag Tag err := ts.db.Operator.Core.NewSelect(). Model(&resTag). - Where("name = ? and category = ? and built_in = ? and scope = ?", tag.Name, tag.Category, tag.BuiltIn, tag.Scope). + Where("name = ? and category = ? and scope = ?", tag.Name, tag.Category, tag.Scope). Scan(ctx) if err == nil { return &resTag, nil diff --git a/builder/store/database/tag_test.go b/builder/store/database/tag_test.go index 12f9276a..297173fc 100644 --- a/builder/store/database/tag_test.go +++ b/builder/store/database/tag_test.go @@ -77,7 +77,7 @@ func TestTagStore_AllTags(t *testing.T) { tag = database.Tag{ Category: "task", - Name: "tag_" + uuid.New().String(), + Name: "tag_" + uuid.New().String() + "search", Group: "Group One", Scope: types.CodeTagScope, } @@ -86,7 +86,7 @@ func TestTagStore_AllTags(t *testing.T) { tag = database.Tag{ Category: "library", - Name: "tag_" + uuid.New().String(), + Name: "tag_" + uuid.New().String() + "search", Group: "Group One", Scope: types.PromptTagScope, } @@ -125,6 +125,28 @@ func TestTagStore_AllTags(t *testing.T) { require.Empty(t, err) require.Equal(t, 2, len(tags)) + filterSearch := &types.TagFilter{ + Scopes: []types.TagScope{types.ModelTagScope, types.DatasetTagScope, types.CodeTagScope, types.PromptTagScope, types.SpaceTagScope}, + Categories: []string{"task"}, + BuiltIn: &builtIn, + Search: "search", + } + + tags, err = ts.AllTags(ctx, filterSearch) + require.Empty(t, err) + require.Equal(t, 1, len(tags)) + + filterSearchNoResult := &types.TagFilter{ + Scopes: []types.TagScope{types.ModelTagScope, types.DatasetTagScope, types.CodeTagScope, types.PromptTagScope, types.SpaceTagScope}, + Categories: []string{"task"}, + BuiltIn: &builtIn, + Search: "noResult", + } + + tags, err = ts.AllTags(ctx, filterSearchNoResult) + require.Empty(t, err) + require.Equal(t, 0, len(tags)) + modelTags, err := ts.AllModelTags(ctx) require.Empty(t, err) require.Equal(t, 1, len(modelTags)) @@ -348,7 +370,7 @@ func TestTagStore_CreateTag(t *testing.T) { ts := database.NewTagStoreWithDB(db) tag := database.Tag{ Category: "task", - Name: "tag_" + uuid.New().String(), + Name: "tag_" + uuid.NewString(), Group: "", Scope: types.ModelTagScope, } @@ -384,6 +406,26 @@ func TestTagStore_SetMetaTags(t *testing.T) { ts := database.NewTagStoreWithDB(db) var tags []*database.Tag + _, err = ts.CreateCategory(ctx, database.TagCategory{ + Name: "industry", + }) + require.Nil(t, err) + _, err = ts.CreateCategory(ctx, database.TagCategory{Name: "task"}) + require.NoError(t, err) + tag, err := ts.CreateTag(ctx, database.Tag{ + Name: "xxx", + Category: "industry", + Scope: types.ModelTagScope, + BuiltIn: true, + }) + require.Nil(t, err) + err = ts.UpsertRepoTags(ctx, repo.ID, []int64{}, []int64{tag.ID}) + require.Nil(t, err) + + getRepoTags, err := rs.Tags(ctx, repo.ID) + require.Empty(t, err) + require.Len(t, getRepoTags, 1) + tags = append(tags, &database.Tag{ Name: "tag_" + uuid.NewString(), Category: "task", @@ -400,6 +442,11 @@ func TestTagStore_SetMetaTags(t *testing.T) { BuiltIn: true, ShowName: "", }) + for i, tag := range tags { + updateTag, err := ts.CreateTag(ctx, *tag) + require.NoError(t, err) + tags[i] = updateTag + } _, err = ts.SetMetaTags(ctx, types.ModelRepo, userName, repoName, tags) // should report err as framework tag is not allowed require.NotEmpty(t, err) @@ -408,6 +455,10 @@ func TestTagStore_SetMetaTags(t *testing.T) { repoTags, err := ts.SetMetaTags(ctx, types.ModelRepo, userName, repoName, tags) require.Empty(t, err) require.Len(t, repoTags, 1) + + getRepoTags, err = rs.Tags(ctx, repo.ID) + require.Empty(t, err) + require.Len(t, getRepoTags, 2) } // TestSetLibraryTag tests the SetLibraryTag method @@ -438,7 +489,7 @@ func TestTagStore_SetLibraryTag(t *testing.T) { ts := database.NewTagStoreWithDB(db) tag := database.Tag{ Category: "task", - Name: "tag_" + uuid.New().String(), + Name: "tag_" + uuid.NewString(), Group: "", Scope: types.ModelTagScope, } @@ -447,7 +498,7 @@ func TestTagStore_SetLibraryTag(t *testing.T) { tag = database.Tag{ Category: "task", - Name: "tag_" + uuid.New().String(), + Name: "tag_" + uuid.NewString(), Group: "", Scope: types.ModelTagScope, } @@ -474,7 +525,7 @@ func TestTagStore_UpsertRepoTags(t *testing.T) { ts := database.NewTagStoreWithDB(db) tag := database.Tag{ Category: "task", - Name: "tag_" + uuid.New().String(), + Name: "tag_" + uuid.NewString(), Group: "", Scope: types.ModelTagScope, } @@ -505,7 +556,7 @@ func TestTagStore_UpsertRepoTags(t *testing.T) { tag = database.Tag{ Category: "task", - Name: "tag_" + uuid.New().String(), + Name: "tag_" + uuid.NewString(), Group: "", Scope: types.ModelTagScope, } @@ -533,17 +584,16 @@ func TestTagStore_RemoveRepoTags(t *testing.T) { ts := database.NewTagStoreWithDB(db) tag := database.Tag{ Category: "task", - Name: "tag_" + uuid.New().String(), + Name: "tag_" + uuid.NewString(), Group: "", Scope: types.ModelTagScope, } tag1, err := ts.CreateTag(ctx, tag) require.Empty(t, err) require.NotEmpty(t, tag1.ID) - tag = database.Tag{ Category: "task", - Name: "tag_" + uuid.New().String(), + Name: "tag_" + uuid.NewString(), Group: "", Scope: types.ModelTagScope, } @@ -594,7 +644,7 @@ func TestTagStore_RemoveRepoTagsByCategory(t *testing.T) { ts := database.NewTagStoreWithDB(db) tag := database.Tag{ Category: "task", - Name: "tag_" + uuid.New().String(), + Name: "tag_" + uuid.NewString(), Group: "", Scope: types.ModelTagScope, } @@ -603,7 +653,7 @@ func TestTagStore_RemoveRepoTagsByCategory(t *testing.T) { require.NotEmpty(t, tag1.ID) tag = database.Tag{ Category: "task", - Name: "tag_" + uuid.New().String(), + Name: "tag_" + uuid.NewString(), Group: "", Scope: types.ModelTagScope, } @@ -647,7 +697,7 @@ func TestTagStore_FindTagByID(t *testing.T) { ts := database.NewTagStoreWithDB(db) tag := database.Tag{ Category: "task", - Name: "tag_" + uuid.New().String(), + Name: "tag_" + uuid.NewString(), Group: "", Scope: types.ModelTagScope, } @@ -672,7 +722,7 @@ func TestTagStore_UpdateTagByID(t *testing.T) { tag := database.Tag{ Category: "task", - Name: "tag_" + uuid.New().String(), + Name: "tag_" + uuid.NewString(), Group: "", Scope: types.ModelTagScope, } @@ -700,7 +750,7 @@ func TestTagStore_DeleteTagByID(t *testing.T) { ts := database.NewTagStoreWithDB(db) tag := database.Tag{ Category: "task", - Name: "tag_" + uuid.New().String(), + Name: "tag_" + uuid.NewString(), Group: "", Scope: types.ModelTagScope, } diff --git a/common/errorx/error_system.go b/common/errorx/error_system.go index e2eecae5..f8afa149 100644 --- a/common/errorx/error_system.go +++ b/common/errorx/error_system.go @@ -23,6 +23,9 @@ const ( lfsNotFound lastOrgAdmin + + cannotPromoteSelfToAdmin + cannotSetRepoPrivacy ) var ( @@ -111,6 +114,30 @@ var ( // // zh-HK: 不能移除組織的最後一個管理員 ErrLastOrgAdmin = CustomError{prefix: errSysPrefix, code: lastOrgAdmin} + // cannot promote yourself to admin + // + // Description: The requested action to promote yourself to an administrator is prohibited. + // + // Description_ZH: 禁止将自身提升为管理员。 + // + // en-US: Cannot promote yourself to admin + // + // zh-CN: 不能将自身提升为管理员 + // + // zh-HK: 不能將自身提升為管理員 + ErrCannotPromoteSelfToAdmin = CustomError{prefix: errSysPrefix, code: cannotPromoteSelfToAdmin} + // cannot change repository privacy + // + // Description: The requested action to change the privacy setting of a repository is prohibited. Because sensitive check not passed. + // + // Description_ZH: 用户禁止更改存储库的隐私设置,由于敏感词检测没有通过。 + // + // en-US: Cannot change repository privacy + // + // zh-CN: 不能更改存储库的隐私 + // + // zh-HK: 不能更改存儲庫的隱私 + ErrCannotSetRepoPrivacy = CustomError{prefix: errSysPrefix, code: cannotSetRepoPrivacy} ) // Used in DB to convert db error to custom error @@ -188,3 +215,27 @@ func LastOrgAdmin(err error, ctx context) error { context: ctx, } } + +func CannotPromoteSelfToAdmin(err error, ctx context) error { + if err == nil { + return nil + } + return CustomError{ + prefix: errSysPrefix, + err: err, + code: cannotPromoteSelfToAdmin, + context: ctx, + } +} + +func CannotSetRepoPrivacy(err error, ctx context) error { + if err == nil { + return nil + } + return CustomError{ + prefix: errSysPrefix, + err: err, + code: cannotSetRepoPrivacy, + context: ctx, + } +} diff --git a/component/dataset.go b/component/dataset.go index 9b71585c..6a627e27 100644 --- a/component/dataset.go +++ b/component/dataset.go @@ -172,7 +172,7 @@ func (c *datasetComponentImpl) Create(ctx context.Context, req *types.CreateData Category: tag.Category, Group: tag.Group, BuiltIn: tag.BuiltIn, - ShowName: tag.I18nKey, // ShowName: tag.ShowName, + ShowName: tag.I18nKey, //ShowName: tag.ShowName, I18nKey: tag.I18nKey, CreatedAt: tag.CreatedAt, UpdatedAt: tag.UpdatedAt, @@ -267,7 +267,7 @@ func (c *datasetComponentImpl) commonIndex(ctx context.Context, filter *types.Re Category: tag.Category, Group: tag.Group, BuiltIn: tag.BuiltIn, - ShowName: tag.I18nKey, // ShowName: tag.ShowName, + ShowName: tag.I18nKey, //ShowName: tag.ShowName, I18nKey: tag.I18nKey, CreatedAt: tag.CreatedAt, UpdatedAt: tag.UpdatedAt, @@ -411,7 +411,7 @@ func (c *datasetComponentImpl) Show(ctx context.Context, namespace, name, curren Category: tag.Category, Group: tag.Group, BuiltIn: tag.BuiltIn, - ShowName: tag.I18nKey, // ShowName: tag.ShowName, + ShowName: tag.I18nKey, //ShowName: tag.ShowName, I18nKey: tag.I18nKey, CreatedAt: tag.CreatedAt, UpdatedAt: tag.UpdatedAt, diff --git a/component/evaluation.go b/component/evaluation.go index 00f1e58e..b9533c60 100644 --- a/component/evaluation.go +++ b/component/evaluation.go @@ -203,7 +203,7 @@ func (c *evaluationComponentImpl) GetEvaluation(ctx context.Context, req types.E Category: tag.Category, Group: tag.Group, BuiltIn: tag.BuiltIn, - ShowName: tag.I18nKey, // ShowName: tag.ShowName, + ShowName: tag.I18nKey, //ShowName: tag.ShowName, I18nKey: tag.I18nKey, CreatedAt: tag.CreatedAt, UpdatedAt: tag.UpdatedAt, diff --git a/component/list.go b/component/list.go index 1becc59c..3b143afa 100644 --- a/component/list.go +++ b/component/list.go @@ -44,7 +44,7 @@ func (c *listComponentImpl) ListModelsByPath(ctx context.Context, req *types.Lis Category: tag.Category, Group: tag.Group, BuiltIn: tag.BuiltIn, - ShowName: tag.I18nKey, // ShowName: tag.ShowName, + ShowName: tag.I18nKey, //ShowName: tag.ShowName, I18nKey: tag.I18nKey, CreatedAt: tag.CreatedAt, UpdatedAt: tag.UpdatedAt, @@ -81,7 +81,7 @@ func (c *listComponentImpl) ListDatasetsByPath(ctx context.Context, req *types.L Category: tag.Category, Group: tag.Group, BuiltIn: tag.BuiltIn, - ShowName: tag.I18nKey, // ShowName: tag.ShowName, + ShowName: tag.I18nKey, //ShowName: tag.ShowName, I18nKey: tag.I18nKey, CreatedAt: tag.CreatedAt, UpdatedAt: tag.UpdatedAt, diff --git a/component/mcp_server.go b/component/mcp_server.go index be7dde19..06807841 100644 --- a/component/mcp_server.go +++ b/component/mcp_server.go @@ -125,7 +125,7 @@ func (m *mcpServerComponentImpl) Create(ctx context.Context, req *types.CreateMC Category: tag.Category, Group: tag.Group, BuiltIn: tag.BuiltIn, - ShowName: tag.I18nKey, // ShowName: tag.ShowName, + ShowName: tag.I18nKey, //ShowName: tag.ShowName, I18nKey: tag.I18nKey, CreatedAt: tag.CreatedAt, UpdatedAt: tag.UpdatedAt, @@ -357,7 +357,7 @@ func (m *mcpServerComponentImpl) Show(ctx context.Context, namespace string, nam Category: tag.Category, Group: tag.Group, BuiltIn: tag.BuiltIn, - ShowName: tag.I18nKey, // ShowName: tag.ShowName, + ShowName: tag.I18nKey, //ShowName: tag.ShowName, I18nKey: tag.I18nKey, CreatedAt: tag.CreatedAt, UpdatedAt: tag.UpdatedAt, @@ -471,7 +471,7 @@ func (m *mcpServerComponentImpl) Index(ctx context.Context, filter *types.RepoFi Category: tag.Category, Group: tag.Group, BuiltIn: tag.BuiltIn, - ShowName: tag.I18nKey, // ShowName: tag.ShowName, + ShowName: tag.I18nKey, //ShowName: tag.ShowName, I18nKey: tag.I18nKey, CreatedAt: tag.CreatedAt, UpdatedAt: tag.UpdatedAt, @@ -550,7 +550,7 @@ func (m *mcpServerComponentImpl) Properties(ctx context.Context, req *types.MCPP Category: tag.Category, Group: tag.Group, BuiltIn: tag.BuiltIn, - ShowName: tag.I18nKey, // ShowName: tag.ShowName, + ShowName: tag.I18nKey, //ShowName: tag.ShowName, I18nKey: tag.I18nKey, CreatedAt: tag.CreatedAt, UpdatedAt: tag.UpdatedAt, diff --git a/component/multi_sync.go b/component/multi_sync.go index 8e4e90f8..f672b2fd 100644 --- a/component/multi_sync.go +++ b/component/multi_sync.go @@ -334,7 +334,7 @@ func (c *multiSyncComponentImpl) createLocalDataset(ctx context.Context, m *type Category: tag.Category, Group: tag.Group, BuiltIn: tag.BuiltIn, - ShowName: tag.ShowName, + I18nKey: tag.ShowName, // ShowName: tag.ShowName, Scope: types.DatasetTagScope, } t, err := c.tagStore.FindOrCreate(ctx, dbTag) @@ -473,7 +473,7 @@ func (c *multiSyncComponentImpl) createLocalModel(ctx context.Context, m *types. Category: tag.Category, Group: tag.Group, BuiltIn: tag.BuiltIn, - ShowName: tag.ShowName, + I18nKey: tag.ShowName, // ShowName: tag.ShowName, Scope: types.ModelTagScope, } t, err := c.tagStore.FindOrCreate(ctx, dbTag) @@ -612,7 +612,7 @@ func (c *multiSyncComponentImpl) createLocalCode(ctx context.Context, m *types.C Category: tag.Category, Group: tag.Group, BuiltIn: tag.BuiltIn, - ShowName: tag.ShowName, + I18nKey: tag.ShowName, // ShowName: tag.ShowName, Scope: types.CodeTagScope, } t, err := c.tagStore.FindOrCreate(ctx, dbTag) @@ -749,7 +749,7 @@ func (c *multiSyncComponentImpl) createLocalPrompt(ctx context.Context, m *types Category: tag.Category, Group: tag.Group, BuiltIn: tag.BuiltIn, - ShowName: tag.ShowName, + I18nKey: tag.ShowName, // ShowName: tag.ShowName, Scope: types.CodeTagScope, } t, err := c.tagStore.FindOrCreate(ctx, dbTag) @@ -886,7 +886,7 @@ func (c *multiSyncComponentImpl) createLocalMCPServer(ctx context.Context, m *ty Category: tag.Category, Group: tag.Group, BuiltIn: tag.BuiltIn, - ShowName: tag.ShowName, + I18nKey: tag.ShowName, // ShowName: tag.ShowName, Scope: types.CodeTagScope, } t, err := c.tagStore.FindOrCreate(ctx, dbTag) diff --git a/component/prompt.go b/component/prompt.go index c399de8b..5e2603d2 100644 --- a/component/prompt.go +++ b/component/prompt.go @@ -688,7 +688,7 @@ func (c *promptComponentImpl) CreatePromptRepo(ctx context.Context, req *types.C Category: tag.Category, Group: tag.Group, BuiltIn: tag.BuiltIn, - ShowName: tag.I18nKey, // ShowName: tag.ShowName, + ShowName: tag.I18nKey, //ShowName: tag.ShowName, I18nKey: tag.I18nKey, CreatedAt: tag.CreatedAt, UpdatedAt: tag.UpdatedAt, @@ -758,7 +758,7 @@ func (c *promptComponentImpl) IndexPromptRepo(ctx context.Context, filter *types Category: tag.Category, Group: tag.Group, BuiltIn: tag.BuiltIn, - ShowName: tag.I18nKey, // ShowName: tag.ShowName, + ShowName: tag.I18nKey, //ShowName: tag.ShowName, I18nKey: tag.I18nKey, CreatedAt: tag.CreatedAt, UpdatedAt: tag.UpdatedAt, @@ -879,7 +879,7 @@ func (c *promptComponentImpl) Show(ctx context.Context, namespace, name, current Category: tag.Category, Group: tag.Group, BuiltIn: tag.BuiltIn, - ShowName: tag.I18nKey, // ShowName: tag.ShowName, + ShowName: tag.I18nKey, //ShowName: tag.ShowName, I18nKey: tag.I18nKey, CreatedAt: tag.CreatedAt, UpdatedAt: tag.UpdatedAt, diff --git a/component/repo.go b/component/repo.go index 6f193190..312ce481 100644 --- a/component/repo.go +++ b/component/repo.go @@ -354,7 +354,13 @@ func (c *repoComponentImpl) UpdateRepo(ctx context.Context, req types.UpdateRepo return nil, errors.New("user does not exist") } - if !user.CanAdmin() { + // Admin users have full permissions. + if user.CanAdmin() { + if req.Private != nil { + repo.Private = *req.Private + } + } else { + // Handle permissions for non-admin users. if namespace.NamespaceType == database.OrgNamespace { canWrite, err := c.CheckCurrentUserPermission(ctx, req.Username, req.Namespace, membership.RoleWrite) if err != nil { @@ -363,23 +369,30 @@ func (c *repoComponentImpl) UpdateRepo(ctx context.Context, req types.UpdateRepo if !canWrite { return nil, errorx.ErrForbiddenMsg("users do not have permission to update repo in this organization") } + // Non-admins cannot change the privacy of an organization's repository. + if req.Private != nil { + return nil, errorx.ErrForbiddenMsg("only admins can change the privacy of an organization repository") + } } else { + // This is a user namespace. if namespace.Path != user.Username { return nil, errorx.ErrForbiddenMsg("users do not have permission to update repo in this namespace") } - } - } - - if req.Private != nil { - // try to public a repo - if !*req.Private { - allow, reason := c.allowPublic(repo) - if !allow { - return nil, errorx.ErrForbiddenMsg(reason) + // Users can change the privacy of their own repositories. + if req.Private != nil { + // Additional check if making the repository public. + if !*req.Private { + allow, reason := c.allowPublic(repo) + if !allow { + err := errors.New("cannot change repo to public: " + reason) + return nil, errorx.CannotSetRepoPrivacy(err, nil) + } + } + repo.Private = *req.Private } } - repo.Private = *req.Private } + if req.Nickname != nil { repo.Nickname = *req.Nickname } diff --git a/component/repo_test.go b/component/repo_test.go index 08d6f9f2..320d2029 100644 --- a/component/repo_test.go +++ b/component/repo_test.go @@ -1766,7 +1766,6 @@ func TestRepoComponent_Tree(t *testing.T) { actualTree, err := repoComp.Tree(context.Background(), &types.GetFileReq{}) require.Nil(t, actualTree) require.ErrorIs(t, err, errorx.ErrForbidden) - }) } @@ -2535,3 +2534,129 @@ func TestRepoComponent_GetMirrorTaskStatusAndSyncStatus(t *testing.T) { assert.Equal(t, types.MirrorTaskStatus(""), mirrorTaskStatus) assert.Equal(t, types.SyncStatusCompleted, syncStatus) } + +func TestRepoComponent_UpdateRepo_PermissionChecks(t *testing.T) { + ctx := context.Background() + nickname := "new-nickname" + description := "new-description" + + // Test cases + testCases := []struct { + name string + setupMocks func(repo *testRepoWithMocks, req types.UpdateRepoReq) + req types.UpdateRepoReq + expectError bool + expectedErrorMsg string + }{ + { + name: "Non-admin fails to change privacy of org repo", + req: types.UpdateRepoReq{ + Username: "test-user", + Namespace: "org-ns", + Name: "test-repo", + RepoType: types.ModelRepo, + Private: tea.Bool(true), + }, + setupMocks: func(repo *testRepoWithMocks, req types.UpdateRepoReq) { + repo.mocks.stores.RepoMock().EXPECT().Find(ctx, req.Namespace, string(req.RepoType), req.Name).Return(&database.Repository{}, nil) + repo.mocks.stores.NamespaceMock().EXPECT().FindByPath(ctx, req.Namespace).Return(database.Namespace{NamespaceType: database.OrgNamespace}, nil) + repo.mocks.stores.UserMock().EXPECT().FindByUsername(ctx, req.Username).Return(database.User{Username: "test-user"}, nil) + repo.mocks.userSvcClient.EXPECT().GetMemberRole(ctx, req.Namespace, req.Username).Return(membership.RoleWrite, nil) + }, + expectError: true, + expectedErrorMsg: "only admins can change the privacy of an organization repository", + }, + { + name: "Non-admin with write access updates org repo successfully without changing privacy", + req: types.UpdateRepoReq{ + Username: "test-user", + Namespace: "org-ns", + Name: "test-repo", + RepoType: types.ModelRepo, + Nickname: &nickname, + Description: &description, + }, + setupMocks: func(repo *testRepoWithMocks, req types.UpdateRepoReq) { + repo.mocks.stores.RepoMock().EXPECT().Find(ctx, req.Namespace, string(req.RepoType), req.Name).Return(&database.Repository{}, nil) + repo.mocks.stores.NamespaceMock().EXPECT().FindByPath(ctx, req.Namespace).Return(database.Namespace{NamespaceType: database.OrgNamespace}, nil) + repo.mocks.stores.UserMock().EXPECT().FindByUsername(ctx, req.Username).Return(database.User{Username: "test-user"}, nil) + repo.mocks.userSvcClient.EXPECT().GetMemberRole(ctx, req.Namespace, req.Username).Return(membership.RoleWrite, nil) + repo.mocks.gitServer.EXPECT().UpdateRepo(ctx, mock.Anything).Return(&gitserver.CreateRepoResp{}, nil) + repo.mocks.stores.RepoMock().EXPECT().UpdateRepo(ctx, mock.Anything).Return(&database.Repository{}, nil) + }, + expectError: false, + }, + { + name: "Non-admin fails to update org repo without write access", + req: types.UpdateRepoReq{ + Username: "test-user", + Namespace: "org-ns", + Name: "test-repo", + RepoType: types.ModelRepo, + }, + setupMocks: func(repo *testRepoWithMocks, req types.UpdateRepoReq) { + repo.mocks.stores.RepoMock().EXPECT().Find(ctx, req.Namespace, string(req.RepoType), req.Name).Return(&database.Repository{}, nil) + repo.mocks.stores.NamespaceMock().EXPECT().FindByPath(ctx, req.Namespace).Return(database.Namespace{NamespaceType: database.OrgNamespace}, nil) + repo.mocks.stores.UserMock().EXPECT().FindByUsername(ctx, req.Username).Return(database.User{Username: "test-user"}, nil) + repo.mocks.userSvcClient.EXPECT().GetMemberRole(ctx, req.Namespace, req.Username).Return(membership.RoleRead, nil) + }, + expectError: true, + expectedErrorMsg: "users do not have permission to update repo in this organization", + }, + { + name: "Non-admin fails to update another user's repo", + req: types.UpdateRepoReq{ + Username: "test-user", + Namespace: "another-user", + Name: "test-repo", + RepoType: types.ModelRepo, + }, + setupMocks: func(repo *testRepoWithMocks, req types.UpdateRepoReq) { + repo.mocks.stores.RepoMock().EXPECT().Find(ctx, req.Namespace, string(req.RepoType), req.Name).Return(&database.Repository{}, nil) + repo.mocks.stores.NamespaceMock().EXPECT().FindByPath(ctx, req.Namespace).Return(database.Namespace{Path: "another-user", NamespaceType: database.UserNamespace}, nil) + repo.mocks.stores.UserMock().EXPECT().FindByUsername(ctx, req.Username).Return(database.User{Username: "test-user"}, nil) + }, + expectError: true, + expectedErrorMsg: "users do not have permission to update repo in this namespace", + }, + { + name: "Non-admin updates their own repo to public successfully", + req: types.UpdateRepoReq{ + Username: "test-user", + Namespace: "test-user", + Name: "test-repo", + RepoType: types.ModelRepo, + Private: tea.Bool(false), + }, + setupMocks: func(repo *testRepoWithMocks, req types.UpdateRepoReq) { + repo.mocks.stores.RepoMock().EXPECT().Find(ctx, req.Namespace, string(req.RepoType), req.Name).Return(&database.Repository{}, nil) + repo.mocks.stores.NamespaceMock().EXPECT().FindByPath(ctx, req.Namespace).Return(database.Namespace{Path: "test-user", NamespaceType: database.UserNamespace}, nil) + repo.mocks.stores.UserMock().EXPECT().FindByUsername(ctx, req.Username).Return(database.User{Username: "test-user"}, nil) + // Mock allowPublic to return true + // As allowPublic is a private method, we can't mock it directly. + // We assume it returns true for this test case. + repo.mocks.gitServer.EXPECT().UpdateRepo(ctx, mock.Anything).Return(&gitserver.CreateRepoResp{}, nil) + repo.mocks.stores.RepoMock().EXPECT().UpdateRepo(ctx, mock.Anything).Return(&database.Repository{}, nil) + }, + expectError: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + repo := initializeTestRepoComponent(ctx, t) + tc.setupMocks(repo, tc.req) + + _, err := repo.UpdateRepo(ctx, tc.req) + + if tc.expectError { + require.Error(t, err) + if tc.expectedErrorMsg != "" { + require.Contains(t, err.Error(), tc.expectedErrorMsg) + } + } else { + require.NoError(t, err) + } + }) + } +} diff --git a/component/space.go b/component/space.go index f3cf6a3a..1778fdd0 100644 --- a/component/space.go +++ b/component/space.go @@ -611,7 +611,7 @@ func (c *spaceComponentImpl) Index(ctx context.Context, repoFilter *types.RepoFi Category: tag.Category, Group: tag.Group, BuiltIn: tag.BuiltIn, - ShowName: tag.I18nKey, // ShowName: tag.ShowName, + ShowName: tag.I18nKey, //ShowName: tag.ShowName, I18nKey: tag.I18nKey, CreatedAt: tag.CreatedAt, UpdatedAt: tag.UpdatedAt, @@ -768,7 +768,7 @@ func (c *spaceComponentImpl) ListByPath(ctx context.Context, paths []string) ([] Category: tag.Category, Group: tag.Group, BuiltIn: tag.BuiltIn, - ShowName: tag.I18nKey, // ShowName: tag.ShowName, + ShowName: tag.I18nKey, //ShowName: tag.ShowName, I18nKey: tag.I18nKey, CreatedAt: tag.CreatedAt, UpdatedAt: tag.UpdatedAt, diff --git a/component/tag.go b/component/tag.go index 05a9c11e..3930b78e 100644 --- a/component/tag.go +++ b/component/tag.go @@ -10,7 +10,6 @@ import ( "opencsg.com/csghub-server/builder/sensitive" "opencsg.com/csghub-server/builder/store/database" "opencsg.com/csghub-server/common/config" - "opencsg.com/csghub-server/common/errorx" "opencsg.com/csghub-server/common/types" "opencsg.com/csghub-server/component/tagparser" ) @@ -21,14 +20,14 @@ type TagComponent interface { UpdateMetaTags(ctx context.Context, tagScope types.TagScope, namespace, name, content string) ([]*database.RepositoryTag, error) UpdateLibraryTags(ctx context.Context, tagScope types.TagScope, namespace, name, oldFilePath, newFilePath string) error UpdateRepoTagsByCategory(ctx context.Context, tagScope types.TagScope, repoID int64, category string, tagNames []string) error - CreateTag(ctx context.Context, username string, req types.CreateTag) (*database.Tag, error) - GetTagByID(ctx context.Context, username string, id int64) (*database.Tag, error) - UpdateTag(ctx context.Context, username string, id int64, req types.UpdateTag) (*database.Tag, error) - DeleteTag(ctx context.Context, username string, id int64) error + CreateTag(ctx context.Context, req types.CreateTag) (*database.Tag, error) + GetTagByID(ctx context.Context, id int64) (*database.Tag, error) + UpdateTag(ctx context.Context, id int64, req types.UpdateTag) (*database.Tag, error) + DeleteTag(ctx context.Context, id int64) error AllCategories(ctx context.Context) ([]types.RepoTagCategory, error) - CreateCategory(ctx context.Context, username string, req types.CreateCategory) (*database.TagCategory, error) - UpdateCategory(ctx context.Context, username string, req types.UpdateCategory, id int64) (*database.TagCategory, error) - DeleteCategory(ctx context.Context, username string, id int64) error + CreateCategory(ctx context.Context, req types.CreateCategory) (*database.TagCategory, error) + UpdateCategory(ctx context.Context, req types.UpdateCategory, id int64) (*database.TagCategory, error) + DeleteCategory(ctx context.Context, id int64) error } func NewTagComponent(config *config.Config) (TagComponent, error) { @@ -230,15 +229,7 @@ func (c *tagComponentImpl) UpdateRepoTagsByCategory(ctx context.Context, tagScop return c.tagStore.UpsertRepoTags(ctx, repoID, oldTagIDs, tagIDs) } -func (c *tagComponentImpl) CreateTag(ctx context.Context, username string, req types.CreateTag) (*database.Tag, error) { - user, err := c.userStore.FindByUsername(ctx, username) - if err != nil { - return nil, fmt.Errorf("failed to get user, error: %w", err) - } - if !user.CanAdmin() { - return nil, fmt.Errorf("user %s do not allowed create tag", username) - } - +func (c *tagComponentImpl) CreateTag(ctx context.Context, req types.CreateTag) (*database.Tag, error) { if c.sensitiveChecker != nil { result, err := c.sensitiveChecker.PassTextCheck(ctx, string(sensitive.ScenarioNicknameDetection), req.Name) if err != nil { @@ -266,14 +257,7 @@ func (c *tagComponentImpl) CreateTag(ctx context.Context, username string, req t return tag, nil } -func (c *tagComponentImpl) GetTagByID(ctx context.Context, username string, id int64) (*database.Tag, error) { - user, err := c.userStore.FindByUsername(ctx, username) - if err != nil { - return nil, fmt.Errorf("failed to get user, error: %w", err) - } - if !user.CanAdmin() { - return nil, fmt.Errorf("user %s do not allowed create tag", username) - } +func (c *tagComponentImpl) GetTagByID(ctx context.Context, id int64) (*database.Tag, error) { tag, err := c.tagStore.FindTagByID(ctx, id) if err != nil { return nil, fmt.Errorf("failed to get tag id %d, error: %w", id, err) @@ -281,15 +265,7 @@ func (c *tagComponentImpl) GetTagByID(ctx context.Context, username string, id i return tag, nil } -func (c *tagComponentImpl) UpdateTag(ctx context.Context, username string, id int64, req types.UpdateTag) (*database.Tag, error) { - user, err := c.userStore.FindByUsername(ctx, username) - if err != nil { - return nil, fmt.Errorf("failed to get user, error: %w", err) - } - if !user.CanAdmin() { - return nil, fmt.Errorf("user %s do not allowed create tag", username) - } - +func (c *tagComponentImpl) UpdateTag(ctx context.Context, id int64, req types.UpdateTag) (*database.Tag, error) { if c.sensitiveChecker != nil { result, err := c.sensitiveChecker.PassTextCheck(ctx, string(sensitive.ScenarioNicknameDetection), req.Name) if err != nil { @@ -317,15 +293,8 @@ func (c *tagComponentImpl) UpdateTag(ctx context.Context, username string, id in return newTag, nil } -func (c *tagComponentImpl) DeleteTag(ctx context.Context, username string, id int64) error { - user, err := c.userStore.FindByUsername(ctx, username) - if err != nil { - return fmt.Errorf("failed to get user, error: %w", err) - } - if !user.CanAdmin() { - return fmt.Errorf("user %s do not allowed create tag", username) - } - err = c.tagStore.DeleteTagByID(ctx, id) +func (c *tagComponentImpl) DeleteTag(ctx context.Context, id int64) error { + err := c.tagStore.DeleteTagByID(ctx, id) if err != nil { return fmt.Errorf("failed to delete tag id %d, error: %w", id, err) } @@ -351,15 +320,7 @@ func (c *tagComponentImpl) AllCategories(ctx context.Context) ([]types.RepoTagCa return categories, nil } -func (c *tagComponentImpl) CreateCategory(ctx context.Context, username string, req types.CreateCategory) (*database.TagCategory, error) { - user, err := c.userStore.FindByUsername(ctx, username) - if err != nil { - return nil, fmt.Errorf("failed to get user, error: %w", err) - } - if !user.CanAdmin() { - return nil, errorx.ErrForbidden - } - +func (c *tagComponentImpl) CreateCategory(ctx context.Context, req types.CreateCategory) (*database.TagCategory, error) { newCategory := database.TagCategory{ Name: req.Name, ShowName: req.ShowName, @@ -375,15 +336,7 @@ func (c *tagComponentImpl) CreateCategory(ctx context.Context, username string, return category, nil } -func (c *tagComponentImpl) UpdateCategory(ctx context.Context, username string, req types.UpdateCategory, id int64) (*database.TagCategory, error) { - user, err := c.userStore.FindByUsername(ctx, username) - if err != nil { - return nil, fmt.Errorf("failed to get user, error: %w", err) - } - if !user.CanAdmin() { - return nil, errorx.ErrForbidden - } - +func (c *tagComponentImpl) UpdateCategory(ctx context.Context, req types.UpdateCategory, id int64) (*database.TagCategory, error) { newCategory := database.TagCategory{ ID: id, Name: req.Name, @@ -400,16 +353,8 @@ func (c *tagComponentImpl) UpdateCategory(ctx context.Context, username string, return category, nil } -func (c *tagComponentImpl) DeleteCategory(ctx context.Context, username string, id int64) error { - user, err := c.userStore.FindByUsername(ctx, username) - if err != nil { - return fmt.Errorf("failed to get user, error: %w", err) - } - if !user.CanAdmin() { - return errorx.ErrForbidden - } - - err = c.tagStore.DeleteCategory(ctx, id) +func (c *tagComponentImpl) DeleteCategory(ctx context.Context, id int64) error { + err := c.tagStore.DeleteCategory(ctx, id) if err != nil { return fmt.Errorf("failed to delete category, error: %w", err) } diff --git a/component/tag_test.go b/component/tag_test.go index ab01ac1e..96a0e468 100644 --- a/component/tag_test.go +++ b/component/tag_test.go @@ -13,9 +13,6 @@ import ( func TestTagComponent_CreateTag(t *testing.T) { ctx := context.TODO() - - username := "testUser" - req := types.CreateTag{ Name: "my first tag", Category: "testCategory", @@ -34,60 +31,33 @@ func TestTagComponent_CreateTag(t *testing.T) { t.Run("admin", func(t *testing.T) { tc := initializeTestTagComponent(ctx, t) - - tc.mocks.stores.UserMock().EXPECT().FindByUsername(ctx, username).Return(database.User{UUID: "testUUID", RoleMask: "admin"}, nil) tc.mocks.stores.TagMock().EXPECT().CreateTag(ctx, newTag).Return(&newTag, nil) tc.mocks.moderationClient.EXPECT().PassTextCheck(ctx, mock.Anything, req.Name).Return(&rpc.CheckResult{ IsSensitive: false, }, nil) - tag, err := tc.CreateTag(ctx, username, req) + tag, err := tc.CreateTag(ctx, req) require.Nil(t, err) require.Equal(t, req.Name, tag.Name) require.Equal(t, true, tag.BuiltIn) }) - - t.Run("non-admin", func(t *testing.T) { - tc := initializeTestTagComponent(ctx, t) - - tc.mocks.stores.UserMock().EXPECT().FindByUsername(ctx, username).Return(database.User{UUID: "testUUID", RoleMask: "persion"}, nil) - - tag, err := tc.CreateTag(ctx, username, req) - require.NotNil(t, err) - require.Nil(t, tag) - }) } func TestTagComponent_GetTagByID(t *testing.T) { ctx := context.TODO() - username := "testUser" t.Run("admin", func(t *testing.T) { tc := initializeTestTagComponent(ctx, t) - tc.mocks.stores.UserMock().EXPECT().FindByUsername(ctx, username).Return(database.User{UUID: "testUUID", RoleMask: "admin"}, nil) tc.mocks.stores.TagMock().EXPECT().FindTagByID(ctx, int64(1)).Return(&database.Tag{ID: int64(1), Name: "test-tag"}, nil) - tag, err := tc.GetTagByID(ctx, username, int64(1)) + tag, err := tc.GetTagByID(ctx, int64(1)) require.Nil(t, err) require.Equal(t, int64(1), tag.ID) require.Equal(t, "test-tag", tag.Name) }) - - t.Run("non-admin", func(t *testing.T) { - tc := initializeTestTagComponent(ctx, t) - - tc.mocks.stores.UserMock().EXPECT().FindByUsername(ctx, username).Return(database.User{UUID: "testUUID", RoleMask: "person"}, nil) - - tag, err := tc.GetTagByID(ctx, username, int64(1)) - require.NotNil(t, err) - require.Nil(t, tag) - }) } func TestTagComponent_UpdateTag(t *testing.T) { ctx := context.TODO() - - username := "testUser" - req := types.UpdateTag{ Name: "testTag", Category: "testCategory", @@ -107,53 +77,27 @@ func TestTagComponent_UpdateTag(t *testing.T) { t.Run("admin", func(t *testing.T) { tc := initializeTestTagComponent(ctx, t) - - tc.mocks.stores.UserMock().EXPECT().FindByUsername(ctx, username).Return(database.User{UUID: "testUUID", RoleMask: "admin"}, nil) tc.mocks.stores.TagMock().EXPECT().UpdateTagByID(ctx, &newTag).Return(&newTag, nil) tc.mocks.moderationClient.EXPECT().PassTextCheck(ctx, mock.Anything, req.Name).Return(&rpc.CheckResult{ IsSensitive: false, }, nil) - tag, err := tc.UpdateTag(ctx, username, int64(1), req) + tag, err := tc.UpdateTag(ctx, int64(1), req) require.Nil(t, err) require.Equal(t, req.Name, tag.Name) require.Equal(t, true, tag.BuiltIn) }) - - t.Run("non-admin", func(t *testing.T) { - tc := initializeTestTagComponent(ctx, t) - - tc.mocks.stores.UserMock().EXPECT().FindByUsername(ctx, username).Return(database.User{UUID: "testUUID", RoleMask: "persion"}, nil) - - tag, err := tc.UpdateTag(ctx, username, int64(1), req) - require.NotNil(t, err) - require.Nil(t, tag) - }) } func TestTagComponent_DeleteTag(t *testing.T) { ctx := context.TODO() - - username := "testUser" - t.Run("admin", func(t *testing.T) { tc := initializeTestTagComponent(ctx, t) - - tc.mocks.stores.UserMock().EXPECT().FindByUsername(ctx, username).Return(database.User{UUID: "testUUID", RoleMask: "admin"}, nil) tc.mocks.stores.TagMock().EXPECT().DeleteTagByID(ctx, int64(1)).Return(nil) - err := tc.DeleteTag(ctx, username, int64(1)) + err := tc.DeleteTag(ctx, int64(1)) require.Nil(t, err) }) - - t.Run("non-admin", func(t *testing.T) { - tc := initializeTestTagComponent(ctx, t) - - tc.mocks.stores.UserMock().EXPECT().FindByUsername(ctx, username).Return(database.User{UUID: "testUUID", RoleMask: "persion"}, nil) - - err := tc.DeleteTag(ctx, username, int64(1)) - require.NotNil(t, err) - }) } func TestTagComponent_ClearMetaTags(t *testing.T) { @@ -243,11 +187,6 @@ func TestTagComponent_CreateCategory(t *testing.T) { t.Run("admin", func(t *testing.T) { tc := initializeTestTagComponent(ctx, t) - - tc.mocks.stores.UserMock().EXPECT().FindByUsername(ctx, "admin").Return(database.User{ - Username: "admin", - RoleMask: "admin", - }, nil) tc.mocks.stores.TagMock().EXPECT().CreateCategory(ctx, database.TagCategory{ Name: "test-cate", Scope: types.TagScope("test-scope"), @@ -257,29 +196,13 @@ func TestTagComponent_CreateCategory(t *testing.T) { Scope: "test-scope", }, nil) - category, err := tc.CreateCategory(ctx, "admin", types.CreateCategory{ + category, err := tc.CreateCategory(ctx, types.CreateCategory{ Name: "test-cate", Scope: "test-scope", }) require.Nil(t, err) require.NotNil(t, category) }) - - t.Run("user", func(t *testing.T) { - tc := initializeTestTagComponent(ctx, t) - - tc.mocks.stores.UserMock().EXPECT().FindByUsername(ctx, "user").Return(database.User{ - Username: "user", - RoleMask: "user", - }, nil) - - category, err := tc.CreateCategory(ctx, "user", types.CreateCategory{ - Name: "test-cate", - Scope: "test-scope", - }) - require.NotNil(t, err) - require.Nil(t, category) - }) } func TestTagComponent_UpdateCategory(t *testing.T) { @@ -287,11 +210,6 @@ func TestTagComponent_UpdateCategory(t *testing.T) { t.Run("admin", func(t *testing.T) { tc := initializeTestTagComponent(ctx, t) - - tc.mocks.stores.UserMock().EXPECT().FindByUsername(ctx, "admin").Return(database.User{ - Username: "admin", - RoleMask: "admin", - }, nil) tc.mocks.stores.TagMock().EXPECT().UpdateCategory(ctx, database.TagCategory{ ID: int64(1), Name: "test-cate", @@ -302,29 +220,13 @@ func TestTagComponent_UpdateCategory(t *testing.T) { Scope: "test-scope", }, nil) - category, err := tc.UpdateCategory(ctx, "admin", types.UpdateCategory{ + category, err := tc.UpdateCategory(ctx, types.UpdateCategory{ Name: "test-cate", Scope: "test-scope", }, int64(1)) require.Nil(t, err) require.NotNil(t, category) }) - - t.Run("user", func(t *testing.T) { - tc := initializeTestTagComponent(ctx, t) - - tc.mocks.stores.UserMock().EXPECT().FindByUsername(ctx, "user").Return(database.User{ - Username: "user", - RoleMask: "user", - }, nil) - - category, err := tc.UpdateCategory(ctx, "user", types.UpdateCategory{ - Name: "test-cate", - Scope: "test-scope", - }, int64(1)) - require.NotNil(t, err) - require.Nil(t, category) - }) } func TestTagComponent_DeleteCategory(t *testing.T) { @@ -332,26 +234,9 @@ func TestTagComponent_DeleteCategory(t *testing.T) { t.Run("admin", func(t *testing.T) { tc := initializeTestTagComponent(ctx, t) - - tc.mocks.stores.UserMock().EXPECT().FindByUsername(ctx, "admin").Return(database.User{ - Username: "admin", - RoleMask: "admin", - }, nil) tc.mocks.stores.TagMock().EXPECT().DeleteCategory(ctx, int64(1)).Return(nil) - err := tc.DeleteCategory(ctx, "admin", int64(1)) + err := tc.DeleteCategory(ctx, int64(1)) require.Nil(t, err) }) - - t.Run("user", func(t *testing.T) { - tc := initializeTestTagComponent(ctx, t) - - tc.mocks.stores.UserMock().EXPECT().FindByUsername(ctx, "user").Return(database.User{ - Username: "user", - RoleMask: "user", - }, nil) - - err := tc.DeleteCategory(ctx, "user", int64(1)) - require.NotNil(t, err) - }) }