mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-12 03:57:32 +00:00
feat: protos refactoring
* start with user * user first try done in all services * user, org, idp for discussion * remove unused stuff * bla * dockerbuild * rename search, get multiple to list... * add annotation * update proto dependencies * update proto dependencies * change proto imports * replace all old imports * fix go out * remove unused lines * correct protoc flags * grpc and openapi flags * go out source path relative * -p * remove dead code * sourcepath relative * ls * is onenapi the problem? * hobla * authoption output * wrong field name * gopf * correct option, add correct flags * small improvments * SIMPLYFY * relative path * gopf bin ich en tubel * correct path * default policies in admin * grpc generation in one file * remove non ascii * metadata on manipulations * correct auth_option import * fixes * larry * idp provider to idp * fix generate * admin and auth nearly done * admin and auth nearly done * gen * healthz * imports * deleted too much imports * fix org * add import * imports * import * naming * auth_opt * gopf * management * imports * _TYPE_UNSPECIFIED * improts * auth opts * management policies * imports * passwordlessType to MFAType * auth_opt * add user grant calls * add missing messages * result * fix option * improvements * ids * fix http * imports * fixes * fields * body * add fields * remove wrong member query * fix request response * fixes * add copy files * variable versions * generate all files * improvements * add dependencies * factors * user session * oidc information, iam * remove unused file * changes * enums * dockerfile * fix build * remove unused folder * update readme for build * move old server impl * add event type to change * some changes * start admin * remove wrong field * admin only list calls missing * fix proto numbers * surprisingly it compiles * service ts changes * admin mgmt * mgmt * auth manipulation and gets done, lists missing * validations and some field changes * validations * enum validations * remove todo * move proto files to proto/zitadel * change proto path in dockerfile * it compiles! * add validate import * remove duplicate import * fix protos * fix import * tests * cleanup * remove unimplemented methods * iam member multiple queries * all auth and admin calls * add initial password on crate human * message names * management user server * machine done * fix: todos (#1346) * fix: pub sub in new eventstore * fix: todos * fix: todos * fix: todos * fix: todos * fix: todos * fix tests * fix: search method domain * admin service, user import type typescript * admin changes * admin changes * fix: search method domain * more user grpc and begin org, fix configs * fix: return object details * org grpc * remove creation date add details * app * fix: return object details * fix: return object details * mgmt service, project members * app * fix: convert policies * project, members, granted projects, searches * fix: convert usergrants * fix: convert usergrants * auth user detail, user detail, mfa, second factor, auth * fix: convert usergrants * mfa, memberships, password, owned proj detail * fix: convert usergrants * project grant * missing details * changes, userview * idp table, keys * org list and user table filter * unify rest paths (#1381) * unify rest paths * post for all searches, mfa to multi_factor, secondfactor to second_factor * remove v1 * fix tests * rename api client key to app key * machine keys, age policy * user list, machine keys, changes * fix: org states * add default flag to policy * second factor to type * idp id * app type * unify ListQuery, ListDetails, ObjectDetails field names * user grants, apps, memberships * fix type params * metadata to detail, linke idps * api create, membership, app detail, create * idp, app, policy * queries, multi -> auth factors and missing fields * update converters * provider to user, remove old mgmt refs * temp remove authfactor dialog, build finish Co-authored-by: Max Peintner <max@caos.ch> Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com> Co-authored-by: Livio Amstutz <livio.a@gmail.com> Co-authored-by: Fabiennne <fabienne.gerschwiler@gmail.com>
This commit is contained in:
@@ -1,653 +1,200 @@
|
||||
package management
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
"golang.org/x/text/language"
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
"google.golang.org/protobuf/types/known/structpb"
|
||||
|
||||
"github.com/caos/zitadel/internal/api/authz"
|
||||
"github.com/caos/zitadel/internal/api/grpc/authn"
|
||||
user_grpc "github.com/caos/zitadel/internal/api/grpc/user"
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
|
||||
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
"github.com/caos/zitadel/pkg/grpc/management"
|
||||
"github.com/caos/zitadel/pkg/grpc/message"
|
||||
key_model "github.com/caos/zitadel/internal/key/model"
|
||||
user_model "github.com/caos/zitadel/internal/user/model"
|
||||
mgmt_pb "github.com/caos/zitadel/pkg/grpc/management"
|
||||
user_pb "github.com/caos/zitadel/pkg/grpc/user"
|
||||
)
|
||||
|
||||
func userMachineFromDomain(machine *domain.Machine) *management.UserResponse {
|
||||
changeDate, err := ptypes.TimestampProto(machine.ChangeDate)
|
||||
logging.Log("GRPC-ckoe3d").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
userResp := &management.UserResponse{
|
||||
Id: machine.AggregateID,
|
||||
State: userStateFromDomain(machine.GetState()),
|
||||
ChangeDate: changeDate,
|
||||
Sequence: machine.Sequence,
|
||||
UserName: machine.GetUsername(),
|
||||
}
|
||||
userResp.User = &management.UserResponse_Machine{Machine: machineFromDomain(machine)}
|
||||
return userResp
|
||||
}
|
||||
|
||||
func userHumanFromDomain(human *domain.Human) *management.UserResponse {
|
||||
changeDate, err := ptypes.TimestampProto(human.ChangeDate)
|
||||
logging.Log("GRPC-ckoe3d").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
userResp := &management.UserResponse{
|
||||
Id: human.AggregateID,
|
||||
State: userStateFromDomain(human.GetState()),
|
||||
ChangeDate: changeDate,
|
||||
Sequence: human.Sequence,
|
||||
UserName: human.GetUsername(),
|
||||
}
|
||||
userResp.User = &management.UserResponse_Human{Human: humanFromDomain(human)}
|
||||
return userResp
|
||||
}
|
||||
|
||||
func userCreateToDomain(user *management.CreateUserRequest) (*domain.Human, *domain.Machine) {
|
||||
if h := user.GetHuman(); h != nil {
|
||||
human := humanCreateToDomain(h)
|
||||
human.Username = user.UserName
|
||||
return human, nil
|
||||
}
|
||||
if m := user.GetMachine(); m != nil {
|
||||
machine := machineCreateToDomain(m)
|
||||
machine.Username = user.UserName
|
||||
return nil, machine
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func passwordRequestToModel(r *management.PasswordRequest) *usr_model.Password {
|
||||
return &usr_model.Password{
|
||||
ObjectRoot: models.ObjectRoot{AggregateID: r.Id},
|
||||
SecretString: r.Password,
|
||||
}
|
||||
}
|
||||
|
||||
func externalIDPSearchRequestToModel(request *management.ExternalIDPSearchRequest) *usr_model.ExternalIDPSearchRequest {
|
||||
return &usr_model.ExternalIDPSearchRequest{
|
||||
Limit: request.Limit,
|
||||
Offset: request.Offset,
|
||||
Queries: []*usr_model.ExternalIDPSearchQuery{{Key: usr_model.ExternalIDPSearchKeyUserID, Method: domain.SearchMethodEquals, Value: request.UserId}},
|
||||
}
|
||||
}
|
||||
|
||||
func externalIDPRemoveToDomain(ctxData authz.CtxData, idp *management.ExternalIDPRemoveRequest) *domain.ExternalIDP {
|
||||
return &domain.ExternalIDP{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: idp.UserId,
|
||||
ResourceOwner: ctxData.ResourceOwner,
|
||||
func ListUsersRequestToModel(ctx context.Context, req *mgmt_pb.ListUsersRequest) *user_model.UserSearchRequest {
|
||||
req.Queries = append(req.Queries, &user_pb.SearchQuery{
|
||||
Query: &user_pb.SearchQuery_ResourceOwner{
|
||||
ResourceOwner: &user_pb.ResourceOwnerQuery{
|
||||
OrgID: authz.GetCtxData(ctx).OrgID,
|
||||
},
|
||||
},
|
||||
IDPConfigID: idp.IdpConfigId,
|
||||
ExternalUserID: idp.ExternalUserId,
|
||||
})
|
||||
|
||||
return &user_model.UserSearchRequest{
|
||||
Offset: req.Query.Offset,
|
||||
Limit: uint64(req.Query.Limit),
|
||||
Asc: req.Query.Asc,
|
||||
Queries: user_grpc.UserQueriesToModel(req.Queries),
|
||||
}
|
||||
}
|
||||
|
||||
func externalIDPSearchResponseFromModel(response *usr_model.ExternalIDPSearchResponse) *management.ExternalIDPSearchResponse {
|
||||
viewTimestamp, err := ptypes.TimestampProto(response.Timestamp)
|
||||
logging.Log("GRPC-3h8is").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
return &management.ExternalIDPSearchResponse{
|
||||
Offset: response.Offset,
|
||||
Limit: response.Limit,
|
||||
TotalResult: response.TotalResult,
|
||||
ProcessedSequence: response.Sequence,
|
||||
ViewTimestamp: viewTimestamp,
|
||||
Result: externalIDPViewsFromModel(response.Result),
|
||||
func AddHumanUserRequestToDomain(req *mgmt_pb.AddHumanUserRequest) *domain.Human {
|
||||
h := &domain.Human{
|
||||
Username: req.UserName,
|
||||
}
|
||||
}
|
||||
|
||||
func externalIDPViewsFromModel(externalIDPs []*usr_model.ExternalIDPView) []*management.ExternalIDPView {
|
||||
converted := make([]*management.ExternalIDPView, len(externalIDPs))
|
||||
for i, externalIDP := range externalIDPs {
|
||||
converted[i] = externalIDPViewFromModel(externalIDP)
|
||||
}
|
||||
return converted
|
||||
}
|
||||
|
||||
func externalIDPViewFromModel(externalIDP *usr_model.ExternalIDPView) *management.ExternalIDPView {
|
||||
creationDate, err := ptypes.TimestampProto(externalIDP.CreationDate)
|
||||
logging.Log("GRPC-Fdu8s").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
changeDate, err := ptypes.TimestampProto(externalIDP.ChangeDate)
|
||||
logging.Log("GRPC-Was7u").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
return &management.ExternalIDPView{
|
||||
UserId: externalIDP.UserID,
|
||||
IdpConfigId: externalIDP.IDPConfigID,
|
||||
ExternalUserId: externalIDP.ExternalUserID,
|
||||
ExternalUserDisplayName: externalIDP.UserDisplayName,
|
||||
IdpName: externalIDP.IDPName,
|
||||
CreationDate: creationDate,
|
||||
ChangeDate: changeDate,
|
||||
}
|
||||
}
|
||||
|
||||
func userSearchRequestsToModel(project *management.UserSearchRequest) *usr_model.UserSearchRequest {
|
||||
return &usr_model.UserSearchRequest{
|
||||
Offset: project.Offset,
|
||||
Limit: project.Limit,
|
||||
Queries: userSearchQueriesToModel(project.Queries),
|
||||
}
|
||||
}
|
||||
|
||||
func userSearchQueriesToModel(queries []*management.UserSearchQuery) []*usr_model.UserSearchQuery {
|
||||
converted := make([]*usr_model.UserSearchQuery, len(queries))
|
||||
for i, q := range queries {
|
||||
converted[i] = userSearchQueryToModel(q)
|
||||
}
|
||||
return converted
|
||||
}
|
||||
|
||||
func userSearchQueryToModel(query *management.UserSearchQuery) *usr_model.UserSearchQuery {
|
||||
return &usr_model.UserSearchQuery{
|
||||
Key: userSearchKeyToModel(query.Key),
|
||||
Method: searchMethodToModel(query.Method),
|
||||
Value: query.Value,
|
||||
}
|
||||
}
|
||||
|
||||
func userSearchKeyToModel(key management.UserSearchKey) usr_model.UserSearchKey {
|
||||
switch key {
|
||||
case management.UserSearchKey_USERSEARCHKEY_USER_NAME:
|
||||
return usr_model.UserSearchKeyUserName
|
||||
case management.UserSearchKey_USERSEARCHKEY_FIRST_NAME:
|
||||
return usr_model.UserSearchKeyFirstName
|
||||
case management.UserSearchKey_USERSEARCHKEY_LAST_NAME:
|
||||
return usr_model.UserSearchKeyLastName
|
||||
case management.UserSearchKey_USERSEARCHKEY_NICK_NAME:
|
||||
return usr_model.UserSearchKeyNickName
|
||||
case management.UserSearchKey_USERSEARCHKEY_DISPLAY_NAME:
|
||||
return usr_model.UserSearchKeyDisplayName
|
||||
case management.UserSearchKey_USERSEARCHKEY_EMAIL:
|
||||
return usr_model.UserSearchKeyEmail
|
||||
case management.UserSearchKey_USERSEARCHKEY_STATE:
|
||||
return usr_model.UserSearchKeyState
|
||||
case management.UserSearchKey_USERSEARCHKEY_TYPE:
|
||||
return usr_model.UserSearchKeyType
|
||||
default:
|
||||
return usr_model.UserSearchKeyUnspecified
|
||||
}
|
||||
}
|
||||
|
||||
func userMembershipSearchRequestsToModel(request *management.UserMembershipSearchRequest) *usr_model.UserMembershipSearchRequest {
|
||||
return &usr_model.UserMembershipSearchRequest{
|
||||
Offset: request.Offset,
|
||||
Limit: request.Limit,
|
||||
Queries: userMembershipSearchQueriesToModel(request.Queries),
|
||||
}
|
||||
}
|
||||
|
||||
func userMembershipSearchQueriesToModel(queries []*management.UserMembershipSearchQuery) []*usr_model.UserMembershipSearchQuery {
|
||||
converted := make([]*usr_model.UserMembershipSearchQuery, len(queries))
|
||||
for i, q := range queries {
|
||||
converted[i] = userMembershipSearchQueryToModel(q)
|
||||
}
|
||||
return converted
|
||||
}
|
||||
|
||||
func userMembershipSearchQueryToModel(query *management.UserMembershipSearchQuery) *usr_model.UserMembershipSearchQuery {
|
||||
return &usr_model.UserMembershipSearchQuery{
|
||||
Key: userMembershipSearchKeyToModel(query.Key),
|
||||
Method: searchMethodToModel(query.Method),
|
||||
Value: query.Value,
|
||||
}
|
||||
}
|
||||
|
||||
func userMembershipSearchKeyToModel(key management.UserMembershipSearchKey) usr_model.UserMembershipSearchKey {
|
||||
switch key {
|
||||
case management.UserMembershipSearchKey_USERMEMBERSHIPSEARCHKEY_TYPE:
|
||||
return usr_model.UserMembershipSearchKeyMemberType
|
||||
case management.UserMembershipSearchKey_USERMEMBERSHIPSEARCHKEY_OBJECT_ID:
|
||||
return usr_model.UserMembershipSearchKeyObjectID
|
||||
default:
|
||||
return usr_model.UserMembershipSearchKeyUnspecified
|
||||
}
|
||||
}
|
||||
|
||||
func profileFromDomain(profile *domain.Profile) *management.UserProfile {
|
||||
changeDate, err := ptypes.TimestampProto(profile.ChangeDate)
|
||||
logging.Log("GRPC-ski8d").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
return &management.UserProfile{
|
||||
Id: profile.AggregateID,
|
||||
ChangeDate: changeDate,
|
||||
Sequence: profile.Sequence,
|
||||
FirstName: profile.FirstName,
|
||||
LastName: profile.LastName,
|
||||
DisplayName: profile.DisplayName,
|
||||
NickName: profile.NickName,
|
||||
PreferredLanguage: profile.PreferredLanguage.String(),
|
||||
Gender: management.Gender(profile.Gender),
|
||||
}
|
||||
}
|
||||
|
||||
func profileViewFromModel(profile *usr_model.Profile) *management.UserProfileView {
|
||||
creationDate, err := ptypes.TimestampProto(profile.CreationDate)
|
||||
logging.Log("GRPC-sk8sk").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
changeDate, err := ptypes.TimestampProto(profile.ChangeDate)
|
||||
logging.Log("GRPC-s30Ks'").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
return &management.UserProfileView{
|
||||
Id: profile.AggregateID,
|
||||
CreationDate: creationDate,
|
||||
ChangeDate: changeDate,
|
||||
Sequence: profile.Sequence,
|
||||
FirstName: profile.FirstName,
|
||||
LastName: profile.LastName,
|
||||
DisplayName: profile.DisplayName,
|
||||
NickName: profile.NickName,
|
||||
PreferredLanguage: profile.PreferredLanguage.String(),
|
||||
Gender: management.Gender(profile.Gender),
|
||||
LoginNames: profile.LoginNames,
|
||||
PreferredLoginName: profile.PreferredLoginName,
|
||||
}
|
||||
}
|
||||
|
||||
func updateProfileToDomain(u *management.UpdateUserProfileRequest) *domain.Profile {
|
||||
preferredLanguage, err := language.Parse(u.PreferredLanguage)
|
||||
logging.Log("GRPC-d8k2s").OnError(err).Debug("language malformed")
|
||||
|
||||
return &domain.Profile{
|
||||
ObjectRoot: models.ObjectRoot{AggregateID: u.Id},
|
||||
FirstName: u.FirstName,
|
||||
LastName: u.LastName,
|
||||
NickName: u.NickName,
|
||||
preferredLanguage, err := language.Parse(req.Profile.PreferredLanguage)
|
||||
logging.Log("MANAG-3GUFJ").OnError(err).Debug("language malformed")
|
||||
h.Profile = &domain.Profile{
|
||||
FirstName: req.Profile.FirstName,
|
||||
LastName: req.Profile.LastName,
|
||||
NickName: req.Profile.NickName,
|
||||
DisplayName: req.Profile.DisplayName,
|
||||
PreferredLanguage: preferredLanguage,
|
||||
Gender: genderToDomain(u.Gender),
|
||||
Gender: user_grpc.GenderToDomain(req.Profile.Gender),
|
||||
}
|
||||
h.Email = &domain.Email{
|
||||
EmailAddress: req.Email.Email,
|
||||
IsEmailVerified: req.Email.IsEmailVerified,
|
||||
}
|
||||
if req.Phone != nil {
|
||||
h.Phone = &domain.Phone{
|
||||
PhoneNumber: req.Phone.Phone,
|
||||
IsPhoneVerified: req.Phone.IsPhoneVerified,
|
||||
}
|
||||
}
|
||||
if req.InitialPassword != "" {
|
||||
h.Password = &domain.Password{SecretString: req.InitialPassword}
|
||||
}
|
||||
|
||||
return h
|
||||
}
|
||||
|
||||
func AddMachineUserRequestToDomain(req *mgmt_pb.AddMachineUserRequest) *domain.Machine {
|
||||
return &domain.Machine{
|
||||
Username: req.UserName,
|
||||
Name: req.Name,
|
||||
Description: req.Description,
|
||||
}
|
||||
}
|
||||
|
||||
func emailFromDomain(email *domain.Email) *management.UserEmail {
|
||||
changeDate, err := ptypes.TimestampProto(email.ChangeDate)
|
||||
logging.Log("GRPC-s0dkw").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
return &management.UserEmail{
|
||||
Id: email.AggregateID,
|
||||
ChangeDate: changeDate,
|
||||
Sequence: email.Sequence,
|
||||
Email: email.EmailAddress,
|
||||
IsEmailVerified: email.IsEmailVerified,
|
||||
func UpdateHumanProfileRequestToDomain(req *mgmt_pb.UpdateHumanProfileRequest) *domain.Profile {
|
||||
preferredLanguage, err := language.Parse(req.PreferredLanguage)
|
||||
logging.Log("MANAG-GPcYv").OnError(err).Debug("language malformed")
|
||||
return &domain.Profile{
|
||||
ObjectRoot: models.ObjectRoot{AggregateID: req.UserId},
|
||||
FirstName: req.FirstName,
|
||||
LastName: req.LastName,
|
||||
NickName: req.NickName,
|
||||
DisplayName: req.DisplayName,
|
||||
PreferredLanguage: preferredLanguage,
|
||||
Gender: user_grpc.GenderToDomain(req.Gender),
|
||||
}
|
||||
}
|
||||
|
||||
func emailViewFromModel(email *usr_model.Email) *management.UserEmailView {
|
||||
creationDate, err := ptypes.TimestampProto(email.CreationDate)
|
||||
logging.Log("GRPC-sKefs").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
changeDate, err := ptypes.TimestampProto(email.ChangeDate)
|
||||
logging.Log("GRPC-0isjD").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
return &management.UserEmailView{
|
||||
Id: email.AggregateID,
|
||||
CreationDate: creationDate,
|
||||
ChangeDate: changeDate,
|
||||
Sequence: email.Sequence,
|
||||
Email: email.EmailAddress,
|
||||
IsEmailVerified: email.IsEmailVerified,
|
||||
}
|
||||
}
|
||||
|
||||
func updateEmailToDomain(e *management.UpdateUserEmailRequest) *domain.Email {
|
||||
func UpdateHumanEmailRequestToDomain(req *mgmt_pb.UpdateHumanEmailRequest) *domain.Email {
|
||||
return &domain.Email{
|
||||
ObjectRoot: models.ObjectRoot{AggregateID: e.Id},
|
||||
EmailAddress: e.Email,
|
||||
IsEmailVerified: e.IsEmailVerified,
|
||||
EmailAddress: req.Email,
|
||||
IsEmailVerified: req.IsEmailVerified,
|
||||
}
|
||||
}
|
||||
|
||||
func phoneFromDomain(phone *domain.Phone) *management.UserPhone {
|
||||
changeDate, err := ptypes.TimestampProto(phone.ChangeDate)
|
||||
logging.Log("GRPC-09ewq").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
return &management.UserPhone{
|
||||
Id: phone.AggregateID,
|
||||
ChangeDate: changeDate,
|
||||
Sequence: phone.Sequence,
|
||||
Phone: phone.PhoneNumber,
|
||||
IsPhoneVerified: phone.IsPhoneVerified,
|
||||
}
|
||||
}
|
||||
|
||||
func phoneViewFromModel(phone *usr_model.Phone) *management.UserPhoneView {
|
||||
creationDate, err := ptypes.TimestampProto(phone.CreationDate)
|
||||
logging.Log("GRPC-6gSj").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
changeDate, err := ptypes.TimestampProto(phone.ChangeDate)
|
||||
logging.Log("GRPC-lKs8f").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
return &management.UserPhoneView{
|
||||
Id: phone.AggregateID,
|
||||
CreationDate: creationDate,
|
||||
ChangeDate: changeDate,
|
||||
Sequence: phone.Sequence,
|
||||
Phone: phone.PhoneNumber,
|
||||
IsPhoneVerified: phone.IsPhoneVerified,
|
||||
}
|
||||
}
|
||||
func updatePhoneToDomain(e *management.UpdateUserPhoneRequest) *domain.Phone {
|
||||
func UpdateHumanPhoneRequestToDomain(req *mgmt_pb.UpdateHumanPhoneRequest) *domain.Phone {
|
||||
return &domain.Phone{
|
||||
ObjectRoot: models.ObjectRoot{AggregateID: e.Id},
|
||||
PhoneNumber: e.Phone,
|
||||
IsPhoneVerified: e.IsPhoneVerified,
|
||||
PhoneNumber: req.Phone,
|
||||
IsPhoneVerified: req.IsPhoneVerified,
|
||||
}
|
||||
}
|
||||
|
||||
func addressFromDomain(address *domain.Address) *management.UserAddress {
|
||||
changeDate, err := ptypes.TimestampProto(address.ChangeDate)
|
||||
logging.Log("GRPC-si9ws").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
return &management.UserAddress{
|
||||
Id: address.AggregateID,
|
||||
ChangeDate: changeDate,
|
||||
Sequence: address.Sequence,
|
||||
Country: address.Country,
|
||||
StreetAddress: address.StreetAddress,
|
||||
Region: address.Region,
|
||||
PostalCode: address.PostalCode,
|
||||
Locality: address.Locality,
|
||||
}
|
||||
}
|
||||
|
||||
func addressViewFromModel(address *usr_model.Address) *management.UserAddressView {
|
||||
creationDate, err := ptypes.TimestampProto(address.CreationDate)
|
||||
logging.Log("GRPC-67stC").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
changeDate, err := ptypes.TimestampProto(address.ChangeDate)
|
||||
logging.Log("GRPC-0jSfs").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
return &management.UserAddressView{
|
||||
Id: address.AggregateID,
|
||||
CreationDate: creationDate,
|
||||
ChangeDate: changeDate,
|
||||
Sequence: address.Sequence,
|
||||
Country: address.Country,
|
||||
StreetAddress: address.StreetAddress,
|
||||
Region: address.Region,
|
||||
PostalCode: address.PostalCode,
|
||||
Locality: address.Locality,
|
||||
}
|
||||
}
|
||||
|
||||
func updateAddressToDomain(ctxData authz.CtxData, address *management.UpdateUserAddressRequest) *domain.Address {
|
||||
return &domain.Address{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: address.Id,
|
||||
ResourceOwner: ctxData.OrgID,
|
||||
},
|
||||
Country: address.Country,
|
||||
StreetAddress: address.StreetAddress,
|
||||
Region: address.Region,
|
||||
PostalCode: address.PostalCode,
|
||||
Locality: address.Locality,
|
||||
}
|
||||
}
|
||||
|
||||
func userSearchResponseFromModel(response *usr_model.UserSearchResponse) *management.UserSearchResponse {
|
||||
timestamp, err := ptypes.TimestampProto(response.Timestamp)
|
||||
logging.Log("GRPC-aBezr").OnError(err).Debug("unable to parse timestamp")
|
||||
return &management.UserSearchResponse{
|
||||
Offset: response.Offset,
|
||||
Limit: response.Limit,
|
||||
TotalResult: response.TotalResult,
|
||||
Result: userViewsFromModel(response.Result),
|
||||
ProcessedSequence: response.Sequence,
|
||||
ViewTimestamp: timestamp,
|
||||
}
|
||||
}
|
||||
|
||||
func userViewsFromModel(users []*usr_model.UserView) []*management.UserView {
|
||||
converted := make([]*management.UserView, len(users))
|
||||
for i, user := range users {
|
||||
converted[i] = userViewFromModel(user)
|
||||
}
|
||||
return converted
|
||||
}
|
||||
|
||||
func userViewFromModel(user *usr_model.UserView) *management.UserView {
|
||||
creationDate, err := ptypes.TimestampProto(user.CreationDate)
|
||||
logging.Log("GRPC-dl9we").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
changeDate, err := ptypes.TimestampProto(user.ChangeDate)
|
||||
logging.Log("GRPC-lpsg5").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
lastLogin, err := ptypes.TimestampProto(user.LastLogin)
|
||||
logging.Log("GRPC-dksi3").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
userView := &management.UserView{
|
||||
Id: user.ID,
|
||||
State: management.UserState(user.State),
|
||||
CreationDate: creationDate,
|
||||
ChangeDate: changeDate,
|
||||
LastLogin: lastLogin,
|
||||
Sequence: user.Sequence,
|
||||
ResourceOwner: user.ResourceOwner,
|
||||
LoginNames: user.LoginNames,
|
||||
PreferredLoginName: user.PreferredLoginName,
|
||||
UserName: user.UserName,
|
||||
}
|
||||
if user.HumanView != nil {
|
||||
userView.User = &management.UserView_Human{Human: humanViewFromModel(user.HumanView)}
|
||||
}
|
||||
if user.MachineView != nil {
|
||||
userView.User = &management.UserView_Machine{Machine: machineViewFromModel(user.MachineView)}
|
||||
|
||||
}
|
||||
return userView
|
||||
}
|
||||
|
||||
func userMembershipSearchResponseFromModel(response *usr_model.UserMembershipSearchResponse) *management.UserMembershipSearchResponse {
|
||||
timestamp, err := ptypes.TimestampProto(response.Timestamp)
|
||||
logging.Log("GRPC-Hs8jd").OnError(err).Debug("unable to parse timestamp")
|
||||
return &management.UserMembershipSearchResponse{
|
||||
Offset: response.Offset,
|
||||
Limit: response.Limit,
|
||||
TotalResult: response.TotalResult,
|
||||
Result: userMembershipViewsFromModel(response.Result),
|
||||
ProcessedSequence: response.Sequence,
|
||||
ViewTimestamp: timestamp,
|
||||
}
|
||||
}
|
||||
|
||||
func userMembershipViewsFromModel(memberships []*usr_model.UserMembershipView) []*management.UserMembershipView {
|
||||
converted := make([]*management.UserMembershipView, len(memberships))
|
||||
for i, membership := range memberships {
|
||||
converted[i] = userMembershipViewFromModel(membership)
|
||||
}
|
||||
return converted
|
||||
}
|
||||
|
||||
func userMembershipViewFromModel(membership *usr_model.UserMembershipView) *management.UserMembershipView {
|
||||
creationDate, err := ptypes.TimestampProto(membership.CreationDate)
|
||||
logging.Log("GRPC-Msnu8").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
changeDate, err := ptypes.TimestampProto(membership.ChangeDate)
|
||||
logging.Log("GRPC-Slco9").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
return &management.UserMembershipView{
|
||||
UserId: membership.UserID,
|
||||
AggregateId: membership.AggregateID,
|
||||
ObjectId: membership.ObjectID,
|
||||
MemberType: memberTypeFromModel(membership.MemberType),
|
||||
DisplayName: membership.DisplayName,
|
||||
Roles: membership.Roles,
|
||||
CreationDate: creationDate,
|
||||
ChangeDate: changeDate,
|
||||
Sequence: membership.Sequence,
|
||||
ResourceOwner: membership.ResourceOwner,
|
||||
}
|
||||
}
|
||||
|
||||
func mfasFromModel(mfas []*usr_model.MultiFactor) []*management.UserMultiFactor {
|
||||
converted := make([]*management.UserMultiFactor, len(mfas))
|
||||
for i, mfa := range mfas {
|
||||
converted[i] = mfaFromModel(mfa)
|
||||
}
|
||||
return converted
|
||||
}
|
||||
|
||||
func mfaFromModel(mfa *usr_model.MultiFactor) *management.UserMultiFactor {
|
||||
return &management.UserMultiFactor{
|
||||
State: mfaStateFromModel(mfa.State),
|
||||
Type: mfaTypeFromModel(mfa.Type),
|
||||
Attribute: mfa.Attribute,
|
||||
Id: mfa.ID,
|
||||
}
|
||||
}
|
||||
|
||||
func notifyTypeToDomain(state management.NotificationType) domain.NotificationType {
|
||||
func notifyTypeToDomain(state mgmt_pb.SendHumanResetPasswordNotificationRequest_Type) domain.NotificationType {
|
||||
switch state {
|
||||
case management.NotificationType_NOTIFICATIONTYPE_EMAIL:
|
||||
case mgmt_pb.SendHumanResetPasswordNotificationRequest_TYPE_EMAIL:
|
||||
return domain.NotificationTypeEmail
|
||||
case management.NotificationType_NOTIFICATIONTYPE_SMS:
|
||||
case mgmt_pb.SendHumanResetPasswordNotificationRequest_TYPE_SMS:
|
||||
return domain.NotificationTypeSms
|
||||
default:
|
||||
return domain.NotificationTypeEmail
|
||||
}
|
||||
}
|
||||
|
||||
func userStateFromDomain(state domain.UserState) management.UserState {
|
||||
switch state {
|
||||
case domain.UserStateActive:
|
||||
return management.UserState_USERSTATE_ACTIVE
|
||||
case domain.UserStateInactive:
|
||||
return management.UserState_USERSTATE_INACTIVE
|
||||
case domain.UserStateLocked:
|
||||
return management.UserState_USERSTATE_LOCKED
|
||||
case domain.UserStateInitial:
|
||||
return management.UserState_USERSTATE_INITIAL
|
||||
case domain.UserStateSuspend:
|
||||
return management.UserState_USERSTATE_SUSPEND
|
||||
default:
|
||||
return management.UserState_USERSTATE_UNSPECIFIED
|
||||
func UpdateMachineRequestToDomain(ctx context.Context, req *mgmt_pb.UpdateMachineRequest) *domain.Machine {
|
||||
return &domain.Machine{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: req.UserId,
|
||||
ResourceOwner: authz.GetCtxData(ctx).OrgID,
|
||||
},
|
||||
Name: req.Name,
|
||||
Description: req.Description,
|
||||
}
|
||||
}
|
||||
|
||||
func genderFromDomain(gender domain.Gender) management.Gender {
|
||||
switch gender {
|
||||
case domain.GenderFemale:
|
||||
return management.Gender_GENDER_FEMALE
|
||||
case domain.GenderMale:
|
||||
return management.Gender_GENDER_MALE
|
||||
case domain.GenderDiverse:
|
||||
return management.Gender_GENDER_DIVERSE
|
||||
default:
|
||||
return management.Gender_GENDER_UNSPECIFIED
|
||||
func ListMachineKeysRequestToModel(req *mgmt_pb.ListMachineKeysRequest) *key_model.AuthNKeySearchRequest {
|
||||
return &key_model.AuthNKeySearchRequest{
|
||||
Offset: req.Query.Offset,
|
||||
Limit: uint64(req.Query.Limit),
|
||||
Asc: req.Query.Asc,
|
||||
Queries: []*key_model.AuthNKeySearchQuery{
|
||||
{
|
||||
Key: key_model.AuthNKeyObjectType,
|
||||
Method: domain.SearchMethodEquals,
|
||||
Value: key_model.AuthNKeyObjectTypeUser,
|
||||
}, {
|
||||
Key: key_model.AuthNKeyObjectID,
|
||||
Method: domain.SearchMethodEquals,
|
||||
Value: req.UserId,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func genderFromModel(gender usr_model.Gender) management.Gender {
|
||||
switch gender {
|
||||
case usr_model.GenderFemale:
|
||||
return management.Gender_GENDER_FEMALE
|
||||
case usr_model.GenderMale:
|
||||
return management.Gender_GENDER_MALE
|
||||
case usr_model.GenderDiverse:
|
||||
return management.Gender_GENDER_DIVERSE
|
||||
default:
|
||||
return management.Gender_GENDER_UNSPECIFIED
|
||||
func AddMachineKeyRequestToDomain(req *mgmt_pb.AddMachineKeyRequest) *domain.MachineKey {
|
||||
expDate := time.Time{}
|
||||
if req.ExpirationDate != nil {
|
||||
var err error
|
||||
expDate, err = ptypes.Timestamp(req.ExpirationDate)
|
||||
logging.Log("MANAG-iNshR").OnError(err).Debug("unable to parse expiration date")
|
||||
}
|
||||
|
||||
return &domain.MachineKey{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: req.UserId,
|
||||
},
|
||||
ExpirationDate: expDate,
|
||||
Type: authn.KeyTypeToDomain(req.Type),
|
||||
}
|
||||
}
|
||||
|
||||
func memberTypeFromModel(memberType usr_model.MemberType) management.MemberType {
|
||||
switch memberType {
|
||||
case usr_model.MemberTypeOrganisation:
|
||||
return management.MemberType_MEMBERTYPE_ORGANISATION
|
||||
case usr_model.MemberTypeProject:
|
||||
return management.MemberType_MEMBERTYPE_PROJECT
|
||||
case usr_model.MemberTypeProjectGrant:
|
||||
return management.MemberType_MEMBERTYPE_PROJECT_GRANT
|
||||
default:
|
||||
return management.MemberType_MEMBERTYPE_UNSPECIFIED
|
||||
func RemoveHumanLinkedIDPRequestToDomain(ctx context.Context, req *mgmt_pb.RemoveHumanLinkedIDPRequest) *domain.ExternalIDP {
|
||||
return &domain.ExternalIDP{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: req.UserId,
|
||||
ResourceOwner: authz.GetCtxData(ctx).OrgID,
|
||||
},
|
||||
IDPConfigID: req.IdpId,
|
||||
ExternalUserID: req.LinkedUserId,
|
||||
}
|
||||
}
|
||||
|
||||
func genderToDomain(gender management.Gender) domain.Gender {
|
||||
switch gender {
|
||||
case management.Gender_GENDER_FEMALE:
|
||||
return domain.GenderFemale
|
||||
case management.Gender_GENDER_MALE:
|
||||
return domain.GenderMale
|
||||
case management.Gender_GENDER_DIVERSE:
|
||||
return domain.GenderDiverse
|
||||
default:
|
||||
return domain.GenderUnspecified
|
||||
func ListHumanLinkedIDPsRequestToModel(req *mgmt_pb.ListHumanLinkedIDPsRequest) *user_model.ExternalIDPSearchRequest {
|
||||
return &user_model.ExternalIDPSearchRequest{
|
||||
Limit: uint64(req.Query.Limit),
|
||||
Offset: req.Query.Offset,
|
||||
Queries: []*user_model.ExternalIDPSearchQuery{{Key: user_model.ExternalIDPSearchKeyUserID, Method: domain.SearchMethodEquals, Value: req.UserId}},
|
||||
}
|
||||
}
|
||||
|
||||
func mfaTypeFromModel(mfatype usr_model.MFAType) management.MfaType {
|
||||
switch mfatype {
|
||||
case usr_model.MFATypeOTP:
|
||||
return management.MfaType_MFATYPE_OTP
|
||||
case usr_model.MFATypeU2F:
|
||||
return management.MfaType_MFATYPE_U2F
|
||||
default:
|
||||
return management.MfaType_MFATYPE_UNSPECIFIED
|
||||
}
|
||||
}
|
||||
|
||||
func mfaStateFromModel(state usr_model.MFAState) management.MFAState {
|
||||
switch state {
|
||||
case usr_model.MFAStateReady:
|
||||
return management.MFAState_MFASTATE_READY
|
||||
case usr_model.MFAStateNotReady:
|
||||
return management.MFAState_MFASTATE_NOT_READY
|
||||
default:
|
||||
return management.MFAState_MFASTATE_UNSPECIFIED
|
||||
}
|
||||
}
|
||||
|
||||
func userChangesToResponse(response *usr_model.UserChanges, offset uint64, limit uint64) (_ *management.Changes) {
|
||||
return &management.Changes{
|
||||
Limit: limit,
|
||||
Offset: offset,
|
||||
Changes: userChangesToMgtAPI(response),
|
||||
}
|
||||
}
|
||||
|
||||
func userChangesToMgtAPI(changes *usr_model.UserChanges) (_ []*management.Change) {
|
||||
result := make([]*management.Change, len(changes.Changes))
|
||||
|
||||
for i, change := range changes.Changes {
|
||||
var data *structpb.Struct
|
||||
changedData, err := json.Marshal(change.Data)
|
||||
if err == nil {
|
||||
data = new(structpb.Struct)
|
||||
err = protojson.Unmarshal(changedData, data)
|
||||
logging.Log("GRPC-a7F54").OnError(err).Debug("unable to marshal changed data to struct")
|
||||
}
|
||||
|
||||
result[i] = &management.Change{
|
||||
ChangeDate: change.ChangeDate,
|
||||
EventType: message.NewLocalizedEventType(change.EventType),
|
||||
Sequence: change.Sequence,
|
||||
Data: data,
|
||||
EditorId: change.ModifierID,
|
||||
Editor: change.ModifierName,
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func webAuthNTokensFromModel(tokens []*usr_model.WebAuthNView) *management.WebAuthNTokens {
|
||||
result := make([]*management.WebAuthNToken, len(tokens))
|
||||
for i, token := range tokens {
|
||||
result[i] = webAuthNTokenFromModel(token)
|
||||
}
|
||||
return &management.WebAuthNTokens{Tokens: result}
|
||||
}
|
||||
|
||||
func webAuthNTokenFromModel(token *usr_model.WebAuthNView) *management.WebAuthNToken {
|
||||
return &management.WebAuthNToken{
|
||||
Id: token.TokenID,
|
||||
Name: token.Name,
|
||||
State: mfaStateFromModel(token.State),
|
||||
func ListUserMembershipsRequestToModel(req *mgmt_pb.ListUserMembershipsRequest) (*user_model.UserMembershipSearchRequest, error) {
|
||||
queries, err := user_grpc.MembershipQueriesToModel(req.Queries)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
queries = append(queries, &user_model.UserMembershipSearchQuery{
|
||||
Key: user_model.UserMembershipSearchKeyUserID,
|
||||
Method: domain.SearchMethodEquals,
|
||||
Value: req.UserId,
|
||||
})
|
||||
return &user_model.UserMembershipSearchRequest{
|
||||
Offset: req.Query.Offset,
|
||||
Limit: uint64(req.Query.Limit),
|
||||
Asc: req.Query.Asc,
|
||||
//SortingColumn: //TODO: sorting
|
||||
Queries: queries,
|
||||
}, nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user