mirror of
https://github.com/harness/drone.git
synced 2025-05-10 22:21:22 +08:00
Merge branch 'mg/memberships/spaces_list_filter' of _OKE5H2PQKOUfzFFDuD4FA/default/CODE/gitness (#368)
This commit is contained in:
commit
e8c1ac6ba3
@ -58,12 +58,12 @@ import (
|
||||
// Injectors from wire.go:
|
||||
|
||||
func initSystem(ctx context.Context, config *types.Config) (*server.System, error) {
|
||||
principalUID := check.ProvidePrincipalUIDCheck()
|
||||
databaseConfig := server.ProvideDatabaseConfig(config)
|
||||
db, err := database.ProvideDatabase(ctx, databaseConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
principalUID := check.ProvidePrincipalUIDCheck()
|
||||
pathTransformation := store.ProvidePathTransformation()
|
||||
pathStore := database.ProvidePathStore(db, pathTransformation)
|
||||
pathCache := cache.ProvidePathCache(pathStore, pathTransformation)
|
||||
@ -76,7 +76,7 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
|
||||
principalUIDTransformation := store.ProvidePrincipalUIDTransformation()
|
||||
principalStore := database.ProvidePrincipalStore(db, principalUIDTransformation)
|
||||
tokenStore := database.ProvideTokenStore(db)
|
||||
controller := user.NewController(principalUID, authorizer, principalStore, tokenStore, membershipStore)
|
||||
controller := user.ProvideController(db, principalUID, authorizer, principalStore, tokenStore, membershipStore)
|
||||
serviceController := service.NewController(principalUID, authorizer, principalStore)
|
||||
bootstrapBootstrap := bootstrap.ProvideBootstrap(config, controller, serviceController)
|
||||
authenticator := authn.ProvideAuthenticator(principalStore, tokenStore)
|
||||
|
@ -19,7 +19,7 @@ import (
|
||||
func (c *Controller) MembershipList(ctx context.Context,
|
||||
session *auth.Session,
|
||||
spaceRef string,
|
||||
opts types.MembershipFilter,
|
||||
filter types.MembershipUserFilter,
|
||||
) ([]types.MembershipUser, int64, error) {
|
||||
space, err := c.spaceStore.FindByRef(ctx, spaceRef)
|
||||
if err != nil {
|
||||
@ -34,17 +34,17 @@ func (c *Controller) MembershipList(ctx context.Context,
|
||||
var membershipsCount int64
|
||||
|
||||
err = dbtx.New(c.db).WithTx(ctx, func(ctx context.Context) error {
|
||||
memberships, err = c.membershipStore.ListUsers(ctx, space.ID, opts)
|
||||
memberships, err = c.membershipStore.ListUsers(ctx, space.ID, filter)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to list memberships for space: %w", err)
|
||||
}
|
||||
|
||||
if opts.Page == 1 && len(memberships) < opts.Size {
|
||||
if filter.Page == 1 && len(memberships) < filter.Size {
|
||||
membershipsCount = int64(len(memberships))
|
||||
return nil
|
||||
}
|
||||
|
||||
membershipsCount, err = c.membershipStore.CountUsers(ctx, space.ID, opts)
|
||||
membershipsCount, err = c.membershipStore.CountUsers(ctx, space.ID, filter)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to count memberships for space: %w", err)
|
||||
}
|
||||
|
@ -13,10 +13,12 @@ import (
|
||||
"github.com/harness/gitness/types/check"
|
||||
"github.com/harness/gitness/types/enum"
|
||||
|
||||
"github.com/jmoiron/sqlx"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
type Controller struct {
|
||||
db *sqlx.DB
|
||||
principalUIDCheck check.PrincipalUID
|
||||
authorizer authz.Authorizer
|
||||
principalStore store.PrincipalStore
|
||||
@ -25,6 +27,7 @@ type Controller struct {
|
||||
}
|
||||
|
||||
func NewController(
|
||||
db *sqlx.DB,
|
||||
principalUIDCheck check.PrincipalUID,
|
||||
authorizer authz.Authorizer,
|
||||
principalStore store.PrincipalStore,
|
||||
@ -32,6 +35,7 @@ func NewController(
|
||||
membershipStore store.MembershipStore,
|
||||
) *Controller {
|
||||
return &Controller{
|
||||
db: db,
|
||||
principalUIDCheck: principalUIDCheck,
|
||||
authorizer: authorizer,
|
||||
principalStore: principalStore,
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
|
||||
apiauth "github.com/harness/gitness/internal/api/auth"
|
||||
"github.com/harness/gitness/internal/auth"
|
||||
"github.com/harness/gitness/store/database/dbtx"
|
||||
"github.com/harness/gitness/types"
|
||||
"github.com/harness/gitness/types/enum"
|
||||
)
|
||||
@ -18,21 +19,42 @@ import (
|
||||
func (c *Controller) MembershipSpaces(ctx context.Context,
|
||||
session *auth.Session,
|
||||
userUID string,
|
||||
) ([]types.MembershipSpace, error) {
|
||||
filter types.MembershipSpaceFilter,
|
||||
) ([]types.MembershipSpace, int64, error) {
|
||||
user, err := findUserFromUID(ctx, c.principalStore, userUID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to find user by UID: %w", err)
|
||||
return nil, 0, fmt.Errorf("failed to find user by UID: %w", err)
|
||||
}
|
||||
|
||||
// Ensure principal has required permissions.
|
||||
if err = apiauth.CheckUser(ctx, c.authorizer, session, user, enum.PermissionUserView); err != nil {
|
||||
return nil, err
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
membershipSpaces, err := c.membershipStore.ListSpaces(ctx, user.ID)
|
||||
var membershipSpaces []types.MembershipSpace
|
||||
var membershipsCount int64
|
||||
|
||||
err = dbtx.New(c.db).WithTx(ctx, func(ctx context.Context) error {
|
||||
membershipSpaces, err = c.membershipStore.ListSpaces(ctx, user.ID, filter)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to list membership spaces for user: %w", err)
|
||||
}
|
||||
|
||||
if filter.Page == 1 && len(membershipSpaces) < filter.Size {
|
||||
membershipsCount = int64(len(membershipSpaces))
|
||||
return nil
|
||||
}
|
||||
|
||||
membershipsCount, err = c.membershipStore.CountSpaces(ctx, user.ID, filter)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to count memberships for user: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}, dbtx.TxDefaultReadOnly)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list membership spaces for user: %w", err)
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
return membershipSpaces, nil
|
||||
return membershipSpaces, membershipsCount, nil
|
||||
}
|
||||
|
@ -10,14 +10,16 @@ import (
|
||||
"github.com/harness/gitness/types/check"
|
||||
|
||||
"github.com/google/wire"
|
||||
"github.com/jmoiron/sqlx"
|
||||
)
|
||||
|
||||
// WireSet provides a wire set for this package.
|
||||
var WireSet = wire.NewSet(
|
||||
NewController,
|
||||
ProvideController,
|
||||
)
|
||||
|
||||
func ProvideController(
|
||||
db *sqlx.DB,
|
||||
principalUIDCheck check.PrincipalUID,
|
||||
authorizer authz.Authorizer,
|
||||
principalStore store.PrincipalStore,
|
||||
@ -25,6 +27,7 @@ func ProvideController(
|
||||
membershipStore store.MembershipStore,
|
||||
) *Controller {
|
||||
return NewController(
|
||||
db,
|
||||
principalUIDCheck,
|
||||
authorizer,
|
||||
principalStore,
|
||||
|
@ -24,7 +24,7 @@ func HandleMembershipList(spaceCtrl *space.Controller) http.HandlerFunc {
|
||||
return
|
||||
}
|
||||
|
||||
filter := request.ParseMembershipFilter(r)
|
||||
filter := request.ParseMembershipUserFilter(r)
|
||||
|
||||
memberships, membershipsCount, err := spaceCtrl.MembershipList(ctx, session, spaceRef, filter)
|
||||
if err != nil {
|
||||
|
@ -18,12 +18,15 @@ func HandleMembershipSpaces(userCtrl *user.Controller) http.HandlerFunc {
|
||||
session, _ := request.AuthSessionFrom(ctx)
|
||||
userUID := session.Principal.UID
|
||||
|
||||
membershipSpaces, err := userCtrl.MembershipSpaces(ctx, session, userUID)
|
||||
filter := request.ParseMembershipSpaceFilter(r)
|
||||
|
||||
membershipSpaces, membershipSpaceCount, err := userCtrl.MembershipSpaces(ctx, session, userUID, filter)
|
||||
if err != nil {
|
||||
render.TranslatedUserError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
render.Pagination(r, w, filter.Page, filter.Size, int(membershipSpaceCount))
|
||||
render.JSON(w, http.StatusOK, membershipSpaces)
|
||||
}
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ var queryParameterQuerySpace = openapi3.ParameterOrRef{
|
||||
},
|
||||
}
|
||||
|
||||
var queryParameterSpaceMembers = openapi3.ParameterOrRef{
|
||||
var queryParameterMembershipUsers = openapi3.ParameterOrRef{
|
||||
Parameter: &openapi3.Parameter{
|
||||
Name: request.QueryParamQuery,
|
||||
In: openapi3.ParameterInQuery,
|
||||
@ -129,7 +129,7 @@ var queryParameterSpaceMembers = openapi3.ParameterOrRef{
|
||||
},
|
||||
}
|
||||
|
||||
var queryParameterSortSpaceMembers = openapi3.ParameterOrRef{
|
||||
var queryParameterSortMembershipUsers = openapi3.ParameterOrRef{
|
||||
Parameter: &openapi3.Parameter{
|
||||
Name: request.QueryParamSort,
|
||||
In: openapi3.ParameterInQuery,
|
||||
@ -138,8 +138,8 @@ var queryParameterSortSpaceMembers = openapi3.ParameterOrRef{
|
||||
Schema: &openapi3.SchemaOrRef{
|
||||
Schema: &openapi3.Schema{
|
||||
Type: ptrSchemaType(openapi3.SchemaTypeString),
|
||||
Default: ptrptr(enum.MembershipSortName),
|
||||
Enum: enum.MembershipSort("").Enum(),
|
||||
Default: ptrptr(enum.MembershipUserSortName),
|
||||
Enum: enum.MembershipUserSort("").Enum(),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -370,8 +370,8 @@ func spaceOperations(reflector *openapi3.Reflector) {
|
||||
opMembershipList.WithTags("space")
|
||||
opMembershipList.WithMapOfAnything(map[string]interface{}{"operationId": "membershipList"})
|
||||
opMembershipList.WithParameters(
|
||||
queryParameterSpaceMembers,
|
||||
queryParameterOrder, queryParameterSortSpaceMembers,
|
||||
queryParameterMembershipUsers,
|
||||
queryParameterOrder, queryParameterSortMembershipUsers,
|
||||
queryParameterPage, queryParameterLimit)
|
||||
_ = reflector.SetRequest(&opMembershipList, &struct {
|
||||
spaceRequest
|
||||
|
@ -8,9 +8,12 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/harness/gitness/internal/api/controller/user"
|
||||
"github.com/harness/gitness/internal/api/request"
|
||||
"github.com/harness/gitness/internal/api/usererror"
|
||||
"github.com/harness/gitness/types"
|
||||
"github.com/harness/gitness/types/enum"
|
||||
|
||||
"github.com/gotidy/ptr"
|
||||
"github.com/swaggest/openapi-go/openapi3"
|
||||
)
|
||||
|
||||
@ -18,6 +21,36 @@ type createTokenRequest struct {
|
||||
user.CreateTokenInput
|
||||
}
|
||||
|
||||
var queryParameterMembershipSpaces = openapi3.ParameterOrRef{
|
||||
Parameter: &openapi3.Parameter{
|
||||
Name: request.QueryParamQuery,
|
||||
In: openapi3.ParameterInQuery,
|
||||
Description: ptr.String("The substring by which the spaces the users is a member of are filtered."),
|
||||
Required: ptr.Bool(false),
|
||||
Schema: &openapi3.SchemaOrRef{
|
||||
Schema: &openapi3.Schema{
|
||||
Type: ptrSchemaType(openapi3.SchemaTypeString),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var queryParameterSortMembershipSpaces = openapi3.ParameterOrRef{
|
||||
Parameter: &openapi3.Parameter{
|
||||
Name: request.QueryParamSort,
|
||||
In: openapi3.ParameterInQuery,
|
||||
Description: ptr.String("The field by which the spaces the user is a member of are sorted."),
|
||||
Required: ptr.Bool(false),
|
||||
Schema: &openapi3.SchemaOrRef{
|
||||
Schema: &openapi3.Schema{
|
||||
Type: ptrSchemaType(openapi3.SchemaTypeString),
|
||||
Default: ptrptr(enum.MembershipSpaceSortUID),
|
||||
Enum: enum.MembershipSpaceSort("").Enum(),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// helper function that constructs the openapi specification
|
||||
// for user account resources.
|
||||
func buildUser(reflector *openapi3.Reflector) {
|
||||
@ -48,6 +81,10 @@ func buildUser(reflector *openapi3.Reflector) {
|
||||
opMemberSpaces := openapi3.Operation{}
|
||||
opMemberSpaces.WithTags("user")
|
||||
opMemberSpaces.WithMapOfAnything(map[string]interface{}{"operationId": "membershipSpaces"})
|
||||
opMemberSpaces.WithParameters(
|
||||
queryParameterMembershipSpaces,
|
||||
queryParameterOrder, queryParameterSortMembershipSpaces,
|
||||
queryParameterPage, queryParameterLimit)
|
||||
_ = reflector.SetRequest(&opMemberSpaces, struct{}{}, http.MethodGet)
|
||||
_ = reflector.SetJSONResponse(&opMemberSpaces, new([]types.MembershipSpace), http.StatusOK)
|
||||
_ = reflector.SetJSONResponse(&opMemberSpaces, new(usererror.Error), http.StatusInternalServerError)
|
||||
|
@ -11,20 +11,34 @@ import (
|
||||
"github.com/harness/gitness/types/enum"
|
||||
)
|
||||
|
||||
// ParseMembershipSort extracts the membership sort parameter from the url.
|
||||
func ParseMembershipSort(r *http.Request) enum.MembershipSort {
|
||||
return enum.ParseMembershipSort(
|
||||
// ParseMembershipUserSort extracts the membership sort parameter from the url.
|
||||
func ParseMembershipUserSort(r *http.Request) enum.MembershipUserSort {
|
||||
return enum.ParseMembershipUserSort(
|
||||
r.URL.Query().Get(QueryParamSort),
|
||||
)
|
||||
}
|
||||
|
||||
// ParseMembershipFilter extracts the membership filter from the url.
|
||||
func ParseMembershipFilter(r *http.Request) types.MembershipFilter {
|
||||
return types.MembershipFilter{
|
||||
Page: ParsePage(r),
|
||||
Size: ParseLimit(r),
|
||||
Query: ParseQuery(r),
|
||||
Sort: ParseMembershipSort(r),
|
||||
Order: ParseOrder(r),
|
||||
// ParseMembershipUserFilter extracts the membership filter from the url.
|
||||
func ParseMembershipUserFilter(r *http.Request) types.MembershipUserFilter {
|
||||
return types.MembershipUserFilter{
|
||||
ListQueryFilter: ParseListQueryFilterFromRequest(r),
|
||||
Sort: ParseMembershipUserSort(r),
|
||||
Order: ParseOrder(r),
|
||||
}
|
||||
}
|
||||
|
||||
// ParseMembershipSpaceSort extracts the membership space sort parameter from the url.
|
||||
func ParseMembershipSpaceSort(r *http.Request) enum.MembershipSpaceSort {
|
||||
return enum.ParseMembershipSpaceSort(
|
||||
r.URL.Query().Get(QueryParamSort),
|
||||
)
|
||||
}
|
||||
|
||||
// ParseMembershipSpaceFilter extracts the membership space filter from the url.
|
||||
func ParseMembershipSpaceFilter(r *http.Request) types.MembershipSpaceFilter {
|
||||
return types.MembershipSpaceFilter{
|
||||
ListQueryFilter: ParseListQueryFilterFromRequest(r),
|
||||
Sort: ParseMembershipSpaceSort(r),
|
||||
Order: ParseOrder(r),
|
||||
}
|
||||
}
|
||||
|
@ -230,9 +230,10 @@ type (
|
||||
Create(ctx context.Context, membership *types.Membership) error
|
||||
Update(ctx context.Context, membership *types.Membership) error
|
||||
Delete(ctx context.Context, key types.MembershipKey) error
|
||||
CountUsers(ctx context.Context, spaceID int64, filter types.MembershipFilter) (int64, error)
|
||||
ListUsers(ctx context.Context, spaceID int64, filter types.MembershipFilter) ([]types.MembershipUser, error)
|
||||
ListSpaces(ctx context.Context, userID int64) ([]types.MembershipSpace, error)
|
||||
CountUsers(ctx context.Context, spaceID int64, filter types.MembershipUserFilter) (int64, error)
|
||||
ListUsers(ctx context.Context, spaceID int64, filter types.MembershipUserFilter) ([]types.MembershipUser, error)
|
||||
CountSpaces(ctx context.Context, userID int64, filter types.MembershipSpaceFilter) (int64, error)
|
||||
ListSpaces(ctx context.Context, userID int64, filter types.MembershipSpaceFilter) ([]types.MembershipSpace, error)
|
||||
}
|
||||
|
||||
// TokenStore defines the token data storage.
|
||||
|
@ -183,7 +183,7 @@ func (s *MembershipStore) Delete(ctx context.Context, key types.MembershipKey) e
|
||||
// CountUsers returns a number of users memberships that matches the provided filter.
|
||||
func (s *MembershipStore) CountUsers(ctx context.Context,
|
||||
spaceID int64,
|
||||
filter types.MembershipFilter,
|
||||
filter types.MembershipUserFilter,
|
||||
) (int64, error) {
|
||||
stmt := database.Builder.
|
||||
Select("count(*)").
|
||||
@ -191,11 +191,11 @@ func (s *MembershipStore) CountUsers(ctx context.Context,
|
||||
InnerJoin("principals ON membership_principal_id = principal_id").
|
||||
Where("membership_space_id = ?", spaceID)
|
||||
|
||||
stmt = prepareMembershipListUsersStmt(stmt, filter)
|
||||
stmt = applyMembershipUserFilter(stmt, filter)
|
||||
|
||||
sql, args, err := stmt.ToSql()
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("failed to convert membership count query to sql: %w", err)
|
||||
return 0, fmt.Errorf("failed to convert membership users count query to sql: %w", err)
|
||||
}
|
||||
|
||||
db := dbtx.GetAccessor(ctx, s.db)
|
||||
@ -203,7 +203,7 @@ func (s *MembershipStore) CountUsers(ctx context.Context,
|
||||
var count int64
|
||||
err = db.QueryRowContext(ctx, sql, args...).Scan(&count)
|
||||
if err != nil {
|
||||
return 0, database.ProcessSQLErrorf(err, "Failed executing membership count query")
|
||||
return 0, database.ProcessSQLErrorf(err, "Failed executing membership users count query")
|
||||
}
|
||||
|
||||
return count, nil
|
||||
@ -212,7 +212,7 @@ func (s *MembershipStore) CountUsers(ctx context.Context,
|
||||
// ListUsers returns a list of memberships for a space or a user.
|
||||
func (s *MembershipStore) ListUsers(ctx context.Context,
|
||||
spaceID int64,
|
||||
filter types.MembershipFilter,
|
||||
filter types.MembershipUserFilter,
|
||||
) ([]types.MembershipUser, error) {
|
||||
const columns = membershipColumns + "," + principalInfoCommonColumns
|
||||
stmt := database.Builder.
|
||||
@ -221,7 +221,7 @@ func (s *MembershipStore) ListUsers(ctx context.Context,
|
||||
InnerJoin("principals ON membership_principal_id = principal_id").
|
||||
Where("membership_space_id = ?", spaceID)
|
||||
|
||||
stmt = prepareMembershipListUsersStmt(stmt, filter)
|
||||
stmt = applyMembershipUserFilter(stmt, filter)
|
||||
stmt = stmt.Limit(database.Limit(filter.Size))
|
||||
stmt = stmt.Offset(database.Offset(filter.Page, filter.Size))
|
||||
|
||||
@ -231,9 +231,9 @@ func (s *MembershipStore) ListUsers(ctx context.Context,
|
||||
}
|
||||
|
||||
switch filter.Sort {
|
||||
case enum.MembershipSortName:
|
||||
case enum.MembershipUserSortName:
|
||||
stmt = stmt.OrderBy("principal_display_name " + order.String())
|
||||
case enum.MembershipSortCreated:
|
||||
case enum.MembershipUserSortCreated:
|
||||
stmt = stmt.OrderBy("membership_created " + order.String())
|
||||
}
|
||||
|
||||
@ -258,9 +258,9 @@ func (s *MembershipStore) ListUsers(ctx context.Context,
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func prepareMembershipListUsersStmt(
|
||||
func applyMembershipUserFilter(
|
||||
stmt squirrel.SelectBuilder,
|
||||
opts types.MembershipFilter,
|
||||
opts types.MembershipUserFilter,
|
||||
) squirrel.SelectBuilder {
|
||||
if opts.Query != "" {
|
||||
searchTerm := "%%" + strings.ToLower(opts.Query) + "%%"
|
||||
@ -270,9 +270,38 @@ func prepareMembershipListUsersStmt(
|
||||
return stmt
|
||||
}
|
||||
|
||||
func (s *MembershipStore) CountSpaces(ctx context.Context,
|
||||
userID int64,
|
||||
filter types.MembershipSpaceFilter,
|
||||
) (int64, error) {
|
||||
stmt := database.Builder.
|
||||
Select("count(*)").
|
||||
From("memberships").
|
||||
InnerJoin("spaces ON spaces.space_id = membership_space_id").
|
||||
Where("membership_principal_id = ?", userID)
|
||||
|
||||
stmt = applyMembershipSpaceFilter(stmt, filter)
|
||||
|
||||
sql, args, err := stmt.ToSql()
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("failed to convert membership spaces count query to sql: %w", err)
|
||||
}
|
||||
|
||||
db := dbtx.GetAccessor(ctx, s.db)
|
||||
|
||||
var count int64
|
||||
err = db.QueryRowContext(ctx, sql, args...).Scan(&count)
|
||||
if err != nil {
|
||||
return 0, database.ProcessSQLErrorf(err, "Failed executing membership spaces count query")
|
||||
}
|
||||
|
||||
return count, nil
|
||||
}
|
||||
|
||||
// ListSpaces returns a list of spaces in which the provided user is a member.
|
||||
func (s *MembershipStore) ListSpaces(ctx context.Context,
|
||||
userID int64,
|
||||
filter types.MembershipSpaceFilter,
|
||||
) ([]types.MembershipSpace, error) {
|
||||
const columns = membershipColumns + "," + spaceColumnsForJoin
|
||||
stmt := database.Builder.
|
||||
@ -280,8 +309,25 @@ func (s *MembershipStore) ListSpaces(ctx context.Context,
|
||||
From("memberships").
|
||||
InnerJoin("spaces ON spaces.space_id = membership_space_id").
|
||||
InnerJoin(`paths ON spaces.space_id=paths.path_space_id AND paths.path_is_primary=true`).
|
||||
Where("membership_principal_id = ?", userID).
|
||||
OrderBy("space_path asc")
|
||||
Where("membership_principal_id = ?", userID)
|
||||
|
||||
stmt = applyMembershipSpaceFilter(stmt, filter)
|
||||
stmt = stmt.Limit(database.Limit(filter.Size))
|
||||
stmt = stmt.Offset(database.Offset(filter.Page, filter.Size))
|
||||
|
||||
order := filter.Order
|
||||
if order == enum.OrderDefault {
|
||||
order = enum.OrderAsc
|
||||
}
|
||||
|
||||
switch filter.Sort {
|
||||
case enum.MembershipSpaceSortUID:
|
||||
stmt = stmt.OrderBy("space_uid " + order.String())
|
||||
case enum.MembershipSpaceSortPath:
|
||||
stmt = stmt.OrderBy("space_path " + order.String())
|
||||
case enum.MembershipSpaceSortCreated:
|
||||
stmt = stmt.OrderBy("membership_created " + order.String())
|
||||
}
|
||||
|
||||
sql, args, err := stmt.ToSql()
|
||||
if err != nil {
|
||||
@ -303,6 +349,18 @@ func (s *MembershipStore) ListSpaces(ctx context.Context,
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func applyMembershipSpaceFilter(
|
||||
stmt squirrel.SelectBuilder,
|
||||
opts types.MembershipSpaceFilter,
|
||||
) squirrel.SelectBuilder {
|
||||
if opts.Query != "" {
|
||||
searchTerm := "%%" + strings.ToLower(opts.Query) + "%%"
|
||||
stmt = stmt.Where("LOWER(space_uid) LIKE ?", searchTerm)
|
||||
}
|
||||
|
||||
return stmt
|
||||
}
|
||||
|
||||
func mapToMembership(m *membership) types.Membership {
|
||||
return types.Membership{
|
||||
MembershipKey: types.MembershipKey{
|
||||
|
@ -8,45 +8,100 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// MembershipSort represents membership sort order.
|
||||
type MembershipSort string
|
||||
// MembershipUserSort represents membership user sort order.
|
||||
type MembershipUserSort string
|
||||
|
||||
// Order enumeration.
|
||||
// MembershipUserSort enumeration.
|
||||
const (
|
||||
MembershipSortName = name
|
||||
MembershipSortCreated = created
|
||||
MembershipUserSortName MembershipUserSort = name
|
||||
MembershipUserSortCreated MembershipUserSort = created
|
||||
)
|
||||
|
||||
var membershipSorts = sortEnum([]MembershipSort{
|
||||
MembershipSortName,
|
||||
MembershipSortCreated,
|
||||
var membershipUserSorts = sortEnum([]MembershipUserSort{
|
||||
MembershipUserSortName,
|
||||
MembershipUserSortCreated,
|
||||
})
|
||||
|
||||
func (MembershipSort) Enum() []interface{} { return toInterfaceSlice(membershipSorts) }
|
||||
func (s MembershipSort) Sanitize() (MembershipSort, bool) { return Sanitize(s, GetAllMembershipSorts) }
|
||||
func GetAllMembershipSorts() ([]MembershipSort, MembershipSort) {
|
||||
return membershipSorts, MembershipSortName
|
||||
func (MembershipUserSort) Enum() []interface{} { return toInterfaceSlice(membershipUserSorts) }
|
||||
func (s MembershipUserSort) Sanitize() (MembershipUserSort, bool) {
|
||||
return Sanitize(s, GetAllMembershipUserSorts)
|
||||
}
|
||||
func GetAllMembershipUserSorts() ([]MembershipUserSort, MembershipUserSort) {
|
||||
return membershipUserSorts, MembershipUserSortName
|
||||
}
|
||||
|
||||
// ParseMembershipSort parses the membership sort attribute string
|
||||
// ParseMembershipUserSort parses the membership user sort attribute string
|
||||
// and returns the equivalent enumeration.
|
||||
func ParseMembershipSort(s string) MembershipSort {
|
||||
func ParseMembershipUserSort(s string) MembershipUserSort {
|
||||
switch strings.ToLower(s) {
|
||||
case name:
|
||||
return MembershipSortName
|
||||
return MembershipUserSortName
|
||||
case created, createdAt:
|
||||
return MembershipSortCreated
|
||||
return MembershipUserSortCreated
|
||||
default:
|
||||
return MembershipSortName
|
||||
return MembershipUserSortName
|
||||
}
|
||||
}
|
||||
|
||||
// String returns the string representation of the attribute.
|
||||
func (s MembershipSort) String() string {
|
||||
func (s MembershipUserSort) String() string {
|
||||
switch s {
|
||||
case MembershipSortName:
|
||||
case MembershipUserSortName:
|
||||
return name
|
||||
case MembershipSortCreated:
|
||||
case MembershipUserSortCreated:
|
||||
return created
|
||||
default:
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
// MembershipSpaceSort represents membership space sort order.
|
||||
type MembershipSpaceSort string
|
||||
|
||||
// MembershipSpaceSort enumeration.
|
||||
const (
|
||||
MembershipSpaceSortUID MembershipSpaceSort = uid
|
||||
MembershipSpaceSortPath MembershipSpaceSort = path
|
||||
MembershipSpaceSortCreated MembershipSpaceSort = created
|
||||
)
|
||||
|
||||
var membershipSpaceSorts = sortEnum([]MembershipSpaceSort{
|
||||
MembershipSpaceSortUID,
|
||||
MembershipSpaceSortPath,
|
||||
MembershipSpaceSortCreated,
|
||||
})
|
||||
|
||||
func (MembershipSpaceSort) Enum() []interface{} { return toInterfaceSlice(membershipSpaceSorts) }
|
||||
func (s MembershipSpaceSort) Sanitize() (MembershipSpaceSort, bool) {
|
||||
return Sanitize(s, GetAllMembershipSpaceSorts)
|
||||
}
|
||||
func GetAllMembershipSpaceSorts() ([]MembershipSpaceSort, MembershipSpaceSort) {
|
||||
return membershipSpaceSorts, MembershipSpaceSortPath
|
||||
}
|
||||
|
||||
// ParseMembershipSpaceSort parses the membership space sort attribute string
|
||||
// and returns the equivalent enumeration.
|
||||
func ParseMembershipSpaceSort(s string) MembershipSpaceSort {
|
||||
switch strings.ToLower(s) {
|
||||
case name:
|
||||
return MembershipSpaceSortUID
|
||||
case path:
|
||||
return MembershipSpaceSortPath
|
||||
case created, createdAt:
|
||||
return MembershipSpaceSortCreated
|
||||
default:
|
||||
return MembershipSpaceSortUID
|
||||
}
|
||||
}
|
||||
|
||||
// String returns the string representation of the attribute.
|
||||
func (s MembershipSpaceSort) String() string {
|
||||
switch s {
|
||||
case MembershipSpaceSortUID:
|
||||
return uid
|
||||
case MembershipSpaceSortPath:
|
||||
return path
|
||||
case MembershipSpaceSortCreated:
|
||||
return created
|
||||
default:
|
||||
return undefined
|
||||
|
@ -32,6 +32,13 @@ type MembershipUser struct {
|
||||
AddedBy PrincipalInfo `json:"added_by"`
|
||||
}
|
||||
|
||||
// MembershipUserFilter holds membership user query parameters.
|
||||
type MembershipUserFilter struct {
|
||||
ListQueryFilter
|
||||
Sort enum.MembershipUserSort `json:"sort"`
|
||||
Order enum.Order `json:"order"`
|
||||
}
|
||||
|
||||
// MembershipSpace adds space info to the Membership data.
|
||||
type MembershipSpace struct {
|
||||
Membership
|
||||
@ -39,11 +46,9 @@ type MembershipSpace struct {
|
||||
AddedBy PrincipalInfo `json:"added_by"`
|
||||
}
|
||||
|
||||
// MembershipFilter holds membership query parameters.
|
||||
type MembershipFilter struct {
|
||||
Page int `json:"page"`
|
||||
Size int `json:"size"`
|
||||
Query string `json:"query"`
|
||||
Sort enum.MembershipSort `json:"sort"`
|
||||
Order enum.Order `json:"order"`
|
||||
// MembershipSpaceFilter holds membership space query parameters.
|
||||
type MembershipSpaceFilter struct {
|
||||
ListQueryFilter
|
||||
Sort enum.MembershipSpaceSort `json:"sort"`
|
||||
Order enum.Order `json:"order"`
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user