1
0
mirror of https://github.com/goharbor/harbor synced 2025-04-25 19:49:31 +00:00
stonezdj 97a64d551d Update usergroups API to support search by group_name
Add group_name parameter to GET usergroups API
  Related to issue 
  UI should also switch from search api to usergroups list api

Signed-off-by: stonezdj <stonezdj@gmail.com>
2022-03-30 10:59:56 +08:00

211 lines
7.1 KiB
Go

// Copyright Project Harbor Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package handler
import (
"context"
"fmt"
"github.com/go-openapi/runtime/middleware"
"github.com/goharbor/harbor/src/common"
"github.com/goharbor/harbor/src/common/rbac"
ugCtl "github.com/goharbor/harbor/src/controller/usergroup"
"github.com/goharbor/harbor/src/lib/config"
"github.com/goharbor/harbor/src/lib/errors"
"github.com/goharbor/harbor/src/lib/q"
"github.com/goharbor/harbor/src/pkg/usergroup/model"
"github.com/goharbor/harbor/src/server/v2.0/models"
operation "github.com/goharbor/harbor/src/server/v2.0/restapi/operations/usergroup"
"strings"
)
type userGroupAPI struct {
BaseAPI
ctl ugCtl.Controller
}
func newUserGroupAPI() *userGroupAPI {
return &userGroupAPI{ctl: ugCtl.Ctl}
}
func (u *userGroupAPI) CreateUserGroup(ctx context.Context, params operation.CreateUserGroupParams) middleware.Responder {
if err := u.RequireSystemAccess(ctx, rbac.ActionCreate, rbac.ResourceUserGroup); err != nil {
return u.SendError(ctx, err)
}
if params.Usergroup == nil {
return operation.NewCreateUserGroupBadRequest()
}
if len(params.Usergroup.GroupName) == 0 {
return operation.NewCreateUserGroupBadRequest()
}
ug := model.UserGroup{
GroupName: params.Usergroup.GroupName,
GroupType: int(params.Usergroup.GroupType),
LdapGroupDN: params.Usergroup.LdapGroupDn,
}
id, err := u.ctl.Create(ctx, ug)
if err != nil {
return u.SendError(ctx, err)
}
location := fmt.Sprintf("%s/%d", strings.TrimSuffix(params.HTTPRequest.URL.Path, "/"), id)
return operation.NewCreateUserGroupCreated().WithLocation(location)
}
func (u *userGroupAPI) DeleteUserGroup(ctx context.Context, params operation.DeleteUserGroupParams) middleware.Responder {
if err := u.RequireSystemAccess(ctx, rbac.ActionDelete, rbac.ResourceUserGroup); err != nil {
return u.SendError(ctx, err)
}
if params.GroupID <= 0 {
return u.SendError(ctx, errors.BadRequestError(nil).WithMessage("the group id should be provided"))
}
err := u.ctl.Delete(ctx, int(params.GroupID))
if err != nil {
return u.SendError(ctx, err)
}
return operation.NewDeleteUserGroupOK()
}
func (u *userGroupAPI) GetUserGroup(ctx context.Context, params operation.GetUserGroupParams) middleware.Responder {
if err := u.RequireSystemAccess(ctx, rbac.ActionRead, rbac.ResourceUserGroup); err != nil {
return u.SendError(ctx, err)
}
if params.GroupID <= 0 {
return u.SendError(ctx, errors.BadRequestError(nil).WithMessage("the group id should be provided"))
}
ug, err := u.ctl.Get(ctx, int(params.GroupID))
if err != nil {
return u.SendError(ctx, err)
}
if ug == nil {
return u.SendError(ctx, errors.NotFoundError(nil).WithMessage("the user group with id %v is not found", params.GroupID))
}
userGroup := &models.UserGroup{
GroupName: ug.GroupName,
GroupType: int64(ug.GroupType),
LdapGroupDn: ug.LdapGroupDN,
}
return operation.NewGetUserGroupOK().WithPayload(userGroup)
}
func (u *userGroupAPI) ListUserGroups(ctx context.Context, params operation.ListUserGroupsParams) middleware.Responder {
if err := u.RequireSystemAccess(ctx, rbac.ActionList, rbac.ResourceUserGroup); err != nil {
return u.SendError(ctx, err)
}
authMode, err := config.AuthMode(ctx)
if err != nil {
return u.SendError(ctx, err)
}
query, err := u.BuildQuery(ctx, nil, nil, params.Page, params.PageSize)
if err != nil {
return u.SendError(ctx, err)
}
if params.GroupName != nil && len(*params.GroupName) > 0 {
query.Keywords["GroupName"] = &q.FuzzyMatchValue{Value: *params.GroupName}
}
switch authMode {
case common.LDAPAuth:
query.Keywords["GroupType"] = common.LDAPGroupType
if params.LdapGroupDn != nil && len(*params.LdapGroupDn) > 0 {
query.Keywords["LdapGroupDN"] = *params.LdapGroupDn
}
case common.HTTPAuth:
query.Keywords["GroupType"] = common.HTTPGroupType
}
total, err := u.ctl.Count(ctx, query)
if err != nil {
return u.SendError(ctx, err)
}
if total == 0 {
return operation.NewListUserGroupsOK().WithXTotalCount(0).WithPayload([]*models.UserGroup{})
}
ug, err := u.ctl.List(ctx, query)
if err != nil {
return u.SendError(ctx, err)
}
return operation.NewListUserGroupsOK().
WithXTotalCount(total).
WithPayload(getUserGroupResp(ug)).
WithLink(u.Links(ctx, params.HTTPRequest.URL, total, query.PageNumber, query.PageSize).String())
}
func getUserGroupResp(ug []*model.UserGroup) []*models.UserGroup {
result := make([]*models.UserGroup, 0)
for _, u := range ug {
ug := &models.UserGroup{
GroupName: u.GroupName,
GroupType: int64(u.GroupType),
LdapGroupDn: u.LdapGroupDN,
ID: int64(u.ID),
}
result = append(result, ug)
}
return result
}
func getUserGroupSearchItem(ug []*model.UserGroup) []*models.UserGroupSearchItem {
result := make([]*models.UserGroupSearchItem, 0)
for _, u := range ug {
ug := &models.UserGroupSearchItem{
GroupName: u.GroupName,
GroupType: int64(u.GroupType),
ID: int64(u.ID),
}
result = append(result, ug)
}
return result
}
func (u *userGroupAPI) UpdateUserGroup(ctx context.Context, params operation.UpdateUserGroupParams) middleware.Responder {
if err := u.RequireSystemAccess(ctx, rbac.ActionUpdate, rbac.ResourceUserGroup); err != nil {
return u.SendError(ctx, err)
}
if params.GroupID <= 0 {
return operation.NewUpdateUserGroupBadRequest()
}
if params.Usergroup == nil || len(params.Usergroup.GroupName) == 0 {
return operation.NewUpdateUserGroupBadRequest()
}
err := u.ctl.Update(ctx, int(params.GroupID), params.Usergroup.GroupName)
if err != nil {
return u.SendError(ctx, err)
}
return operation.NewUpdateUserGroupOK()
}
func (u *userGroupAPI) SearchUserGroups(ctx context.Context, params operation.SearchUserGroupsParams) middleware.Responder {
if err := u.RequireAuthenticated(ctx); err != nil {
return u.SendError(ctx, err)
}
query, err := u.BuildQuery(ctx, nil, nil, params.Page, params.PageSize)
if err != nil {
return u.SendError(ctx, err)
}
if len(params.Groupname) == 0 {
return u.SendError(ctx, errors.BadRequestError(nil).WithMessage("need to provide groupname to search user group"))
}
query.Keywords["GroupName"] = &q.FuzzyMatchValue{Value: params.Groupname}
total, err := u.ctl.Count(ctx, query)
if err != nil {
return u.SendError(ctx, err)
}
if total == 0 {
return operation.NewSearchUserGroupsOK().WithXTotalCount(0).WithPayload([]*models.UserGroupSearchItem{})
}
ug, err := u.ctl.List(ctx, query)
if err != nil {
return u.SendError(ctx, err)
}
return operation.NewSearchUserGroupsOK().WithXTotalCount(total).
WithPayload(getUserGroupSearchItem(ug)).
WithLink(u.Links(ctx, params.HTTPRequest.URL, total, query.PageNumber, query.PageSize).String())
}