mirror of
https://github.com/zitadel/zitadel.git
synced 2025-12-06 07:32:24 +00:00
# Which Problems Are Solved
This PR fixes the self-management of users for metadata and own removal
and improves the corresponding permission checks.
While looking into the problems, I also noticed that there's a bug in
the metadata mapping when using `api.metadata.push` in actions v1 and
that re-adding a previously existing key after its removal was not
possible.
# How the Problems Are Solved
- Added a parameter `allowSelfManagement` to checkPermissionOnUser to
not require a permission if a user is changing its own data.
- Updated use of `NewPermissionCheckUserWrite` including prevention of
self-management for metadata.
- Pass permission check to the command side (for metadata functions) to
allow it implicitly for login v1 and actions v1.
- Use of json.Marshal for the metadata mapping (as with
`AppendMetadata`)
- Check the metadata state when comparing the value.
# Additional Changes
- added a variadic `roles` parameter to the `CreateOrgMembership`
integration test helper function to allow defining specific roles.
# Additional Context
- noted internally while testing v4.1.x
- requires backport to v4.x
- closes https://github.com/zitadel/zitadel/issues/10470
- relates to https://github.com/zitadel/zitadel/pull/10426
(cherry picked from commit 5329d50509)
81 lines
2.8 KiB
Go
81 lines
2.8 KiB
Go
package user
|
|
|
|
import (
|
|
"context"
|
|
|
|
"connectrpc.com/connect"
|
|
"google.golang.org/protobuf/types/known/timestamppb"
|
|
|
|
"github.com/zitadel/zitadel/internal/api/grpc/filter/v2"
|
|
"github.com/zitadel/zitadel/internal/api/grpc/metadata/v2"
|
|
"github.com/zitadel/zitadel/internal/domain"
|
|
"github.com/zitadel/zitadel/internal/query"
|
|
"github.com/zitadel/zitadel/pkg/grpc/user/v2"
|
|
)
|
|
|
|
func (s *Server) ListUserMetadata(ctx context.Context, req *connect.Request[user.ListUserMetadataRequest]) (*connect.Response[user.ListUserMetadataResponse], error) {
|
|
metadataQueries, err := s.listUserMetadataRequestToModel(req.Msg)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
res, err := s.query.SearchUserMetadata(ctx, true, req.Msg.UserId, metadataQueries, s.checkPermission)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return connect.NewResponse(&user.ListUserMetadataResponse{
|
|
Metadata: metadata.UserMetadataListToPb(res.Metadata),
|
|
Pagination: filter.QueryToPaginationPb(metadataQueries.SearchRequest, res.SearchResponse),
|
|
}), nil
|
|
}
|
|
|
|
func (s *Server) listUserMetadataRequestToModel(req *user.ListUserMetadataRequest) (*query.UserMetadataSearchQueries, error) {
|
|
offset, limit, asc, err := filter.PaginationPbToQuery(s.systemDefaults, req.Pagination)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
queries, err := metadata.UserMetadataFiltersToQuery(req.Filters)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &query.UserMetadataSearchQueries{
|
|
SearchRequest: query.SearchRequest{
|
|
Offset: offset,
|
|
Limit: limit,
|
|
Asc: asc,
|
|
SortingColumn: query.UserMetadataCreationDateCol,
|
|
},
|
|
Queries: queries,
|
|
}, nil
|
|
}
|
|
|
|
func (s *Server) SetUserMetadata(ctx context.Context, req *connect.Request[user.SetUserMetadataRequest]) (*connect.Response[user.SetUserMetadataResponse], error) {
|
|
result, err := s.command.BulkSetUserMetadata(ctx, req.Msg.UserId, "", s.command.NewPermissionCheckUserWrite(ctx, false), setUserMetadataToDomain(req.Msg)...)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return connect.NewResponse(&user.SetUserMetadataResponse{
|
|
SetDate: timestamppb.New(result.EventDate),
|
|
}), nil
|
|
}
|
|
|
|
func setUserMetadataToDomain(req *user.SetUserMetadataRequest) []*domain.Metadata {
|
|
metadata := make([]*domain.Metadata, len(req.Metadata))
|
|
for i, data := range req.Metadata {
|
|
metadata[i] = &domain.Metadata{
|
|
Key: data.Key,
|
|
Value: data.Value,
|
|
}
|
|
}
|
|
return metadata
|
|
}
|
|
|
|
func (s *Server) DeleteUserMetadata(ctx context.Context, req *connect.Request[user.DeleteUserMetadataRequest]) (*connect.Response[user.DeleteUserMetadataResponse], error) {
|
|
result, err := s.command.BulkRemoveUserMetadata(ctx, req.Msg.UserId, "", s.command.NewPermissionCheckUserWrite(ctx, false), req.Msg.Keys...)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return connect.NewResponse(&user.DeleteUserMetadataResponse{
|
|
DeletionDate: timestamppb.New(result.EventDate),
|
|
}), nil
|
|
}
|