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:
Silvan
2021-03-09 10:30:11 +01:00
committed by GitHub
parent 9f417f3957
commit dabd5920dc
372 changed files with 17881 additions and 22036 deletions

View File

@@ -1,36 +0,0 @@
package admin
import (
"context"
"github.com/golang/protobuf/ptypes/empty"
view_model "github.com/caos/zitadel/internal/view/model"
"github.com/caos/zitadel/pkg/grpc/admin"
)
func (s *Server) GetViews(ctx context.Context, _ *empty.Empty) (_ *admin.Views, err error) {
views, err := s.administrator.GetViews()
if err != nil {
return nil, err
}
return &admin.Views{Views: viewsFromModel(views)}, nil
}
func (s *Server) ClearView(ctx context.Context, viewID *admin.ViewID) (_ *empty.Empty, err error) {
err = s.administrator.ClearView(ctx, viewID.Database, viewID.ViewName)
return &empty.Empty{}, err
}
func (s *Server) GetFailedEvents(ctx context.Context, _ *empty.Empty) (_ *admin.FailedEvents, err error) {
failedEvents, err := s.administrator.GetFailedEvents(ctx)
if err != nil {
return nil, err
}
return &admin.FailedEvents{FailedEvents: failedEventsFromModel(failedEvents)}, nil
}
func (s *Server) RemoveFailedEvent(ctx context.Context, failedEventID *admin.FailedEventID) (_ *empty.Empty, err error) {
err = s.administrator.RemoveFailedEvent(ctx, &view_model.FailedEvent{Database: failedEventID.Database, ViewName: failedEventID.ViewName, FailedSequence: failedEventID.FailedSequence})
return &empty.Empty{}, err
}

View File

@@ -1,51 +0,0 @@
package admin
import (
"github.com/caos/logging"
view_model "github.com/caos/zitadel/internal/view/model"
"github.com/caos/zitadel/pkg/grpc/admin"
"github.com/golang/protobuf/ptypes"
)
func viewsFromModel(views []*view_model.View) []*admin.View {
result := make([]*admin.View, len(views))
for i, view := range views {
result[i] = viewFromModel(view)
}
return result
}
func failedEventsFromModel(failedEvents []*view_model.FailedEvent) []*admin.FailedEvent {
result := make([]*admin.FailedEvent, len(failedEvents))
for i, view := range failedEvents {
result[i] = failedEventFromModel(view)
}
return result
}
func viewFromModel(view *view_model.View) *admin.View {
eventTimestamp, err := ptypes.TimestampProto(view.EventTimestamp)
logging.Log("GRPC-KSo03").OnError(err).Debug("unable to parse timestamp")
lastSpool, err := ptypes.TimestampProto(view.LastSuccessfulSpoolerRun)
logging.Log("GRPC-0oP87").OnError(err).Debug("unable to parse timestamp")
return &admin.View{
Database: view.Database,
ViewName: view.ViewName,
ProcessedSequence: view.CurrentSequence,
EventTimestamp: eventTimestamp,
LastSuccessfulSpoolerRun: lastSpool,
}
}
func failedEventFromModel(failedEvent *view_model.FailedEvent) *admin.FailedEvent {
return &admin.FailedEvent{
Database: failedEvent.Database,
ViewName: failedEvent.ViewName,
FailedSequence: failedEvent.FailedSequence,
FailureCount: failedEvent.FailureCount,
ErrorMessage: failedEvent.ErrMsg,
}
}

View File

@@ -0,0 +1,23 @@
package admin
import (
"context"
admin_pb "github.com/caos/zitadel/pkg/grpc/admin"
)
func (s *Server) ListFailedEvents(ctx context.Context, req *admin_pb.ListFailedEventsRequest) (*admin_pb.ListFailedEventsResponse, error) {
failedEvents, err := s.administrator.GetFailedEvents(ctx)
if err != nil {
return nil, err
}
return &admin_pb.ListFailedEventsResponse{Result: FailedEventsToPb(failedEvents)}, nil
}
func (s *Server) RemoveFailedEvent(ctx context.Context, req *admin_pb.RemoveFailedEventRequest) (*admin_pb.RemoveFailedEventResponse, error) {
err := s.administrator.RemoveFailedEvent(ctx, RemoveFailedEventRequestToModel(req))
if err != nil {
return nil, err
}
return &admin_pb.RemoveFailedEventResponse{}, nil
}

View File

@@ -0,0 +1,32 @@
package admin
import (
"github.com/caos/zitadel/internal/view/model"
admin_pb "github.com/caos/zitadel/pkg/grpc/admin"
)
func FailedEventsToPb(failedEvents []*model.FailedEvent) []*admin_pb.FailedEvent {
events := make([]*admin_pb.FailedEvent, len(failedEvents))
for i, failedEvent := range failedEvents {
events[i] = FailedEventToPb(failedEvent)
}
return events
}
func FailedEventToPb(failedEvent *model.FailedEvent) *admin_pb.FailedEvent {
return &admin_pb.FailedEvent{
Database: failedEvent.Database,
ViewName: failedEvent.ViewName,
FailedSequence: failedEvent.FailedSequence,
FailureCount: failedEvent.FailureCount,
ErrorMessage: failedEvent.ErrMsg,
}
}
func RemoveFailedEventRequestToModel(req *admin_pb.RemoveFailedEventRequest) *model.FailedEvent {
return &model.FailedEvent{
Database: req.Database,
ViewName: req.ViewName,
FailedSequence: req.FailedSequence,
}
}

View File

@@ -0,0 +1,95 @@
package admin_test
import (
"testing"
admin_grpc "github.com/caos/zitadel/internal/api/grpc/admin"
"github.com/caos/zitadel/internal/test"
"github.com/caos/zitadel/internal/view/model"
admin_pb "github.com/caos/zitadel/pkg/grpc/admin"
)
func TestFailedEventsToPbFields(t *testing.T) {
type args struct {
failedEvents []*model.FailedEvent
}
tests := []struct {
name string
args args
}{
{
name: "all fields",
args: args{
failedEvents: []*model.FailedEvent{
{
Database: "admin",
ViewName: "users",
FailedSequence: 456,
FailureCount: 5,
ErrMsg: "some error",
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := admin_grpc.FailedEventsToPb(tt.args.failedEvents)
for _, g := range got {
test.AssertFieldsMapped(t, g)
}
})
}
}
func TestFailedEventToPbFields(t *testing.T) {
type args struct {
failedEvent *model.FailedEvent
}
tests := []struct {
name string
args args
}{
{
"all fields",
args{
failedEvent: &model.FailedEvent{
Database: "admin",
ViewName: "users",
FailedSequence: 456,
FailureCount: 5,
ErrMsg: "some error",
},
},
},
}
for _, tt := range tests {
converted := admin_grpc.FailedEventToPb(tt.args.failedEvent)
test.AssertFieldsMapped(t, converted)
}
}
func TestRemoveFailedEventRequestToModelFields(t *testing.T) {
type args struct {
req *admin_pb.RemoveFailedEventRequest
}
tests := []struct {
name string
args args
}{
{
"all fields",
args{
req: &admin_pb.RemoveFailedEventRequest{
Database: "admin",
ViewName: "users",
FailedSequence: 456,
},
},
},
}
for _, tt := range tests {
converted := admin_grpc.RemoveFailedEventRequestToModel(tt.args.req)
test.AssertFieldsMapped(t, converted, "FailureCount", "ErrMsg")
}
}

View File

@@ -2,42 +2,65 @@ package admin
import (
"context"
"time"
"github.com/golang/protobuf/ptypes/empty"
"github.com/caos/zitadel/pkg/grpc/admin"
"github.com/caos/zitadel/internal/api/grpc/member"
"github.com/caos/zitadel/internal/api/grpc/object"
admin_pb "github.com/caos/zitadel/pkg/grpc/admin"
)
func (s *Server) GetIamMemberRoles(ctx context.Context, _ *empty.Empty) (*admin.IamMemberRoles, error) {
return &admin.IamMemberRoles{Roles: s.iam.GetIAMMemberRoles()}, nil
func (s *Server) ListIAMMemberRoles(ctx context.Context, req *admin_pb.ListIAMMemberRolesRequest) (*admin_pb.ListIAMMemberRolesResponse, error) {
roles := s.iam.GetIAMMemberRoles()
return &admin_pb.ListIAMMemberRolesResponse{
Details: object.ToListDetails(uint64(len(roles)), 0, time.Now()),
}, nil
}
func (s *Server) SearchIamMembers(ctx context.Context, in *admin.IamMemberSearchRequest) (*admin.IamMemberSearchResponse, error) {
members, err := s.iam.SearchIAMMembers(ctx, iamMemberSearchRequestToModel(in))
func (s *Server) ListIAMMembers(ctx context.Context, req *admin_pb.ListIAMMembersRequest) (*admin_pb.ListIAMMembersResponse, error) {
res, err := s.iam.SearchIAMMembers(ctx, ListIAMMemberRequestToModel(req))
if err != nil {
return nil, err
}
return iamMemberSearchResponseFromModel(members), nil
return &admin_pb.ListIAMMembersResponse{
Details: object.ToListDetails(res.TotalResult, res.Sequence, res.Timestamp),
Result: member.IAMMembersToPb(res.Result),
}, nil
}
func (s *Server) AddIamMember(ctx context.Context, member *admin.AddIamMemberRequest) (*admin.IamMember, error) {
addedMember, err := s.command.AddIAMMember(ctx, addIamMemberToDomain(member))
func (s *Server) AddIAMMember(ctx context.Context, req *admin_pb.AddIAMMemberRequest) (*admin_pb.AddIAMMemberResponse, error) {
member, err := s.command.AddIAMMember(ctx, AddIAMMemberToDomain(req))
if err != nil {
return nil, err
}
return iamMemberFromDomain(addedMember), nil
return &admin_pb.AddIAMMemberResponse{
Details: object.ToDetailsPb(
member.Sequence,
member.ChangeDate,
member.ResourceOwner,
),
}, nil
}
func (s *Server) ChangeIamMember(ctx context.Context, member *admin.ChangeIamMemberRequest) (*admin.IamMember, error) {
changedMember, err := s.command.ChangeIAMMember(ctx, changeIamMemberToDomain(member))
func (s *Server) UpdateIAMMember(ctx context.Context, req *admin_pb.UpdateIAMMemberRequest) (*admin_pb.UpdateIAMMemberResponse, error) {
member, err := s.command.ChangeIAMMember(ctx, UpdateIAMMemberToDomain(req))
if err != nil {
return nil, err
}
return iamMemberFromDomain(changedMember), nil
return &admin_pb.UpdateIAMMemberResponse{
Details: object.ToDetailsPb(
member.Sequence,
member.ChangeDate,
member.ResourceOwner,
),
}, nil
}
func (s *Server) RemoveIamMember(ctx context.Context, member *admin.RemoveIamMemberRequest) (*empty.Empty, error) {
err := s.command.RemoveIAMMember(ctx, member.UserId)
return &empty.Empty{}, err
func (s *Server) RemoveIAMMember(ctx context.Context, req *admin_pb.RemoveIAMMemberRequest) (*admin_pb.RemoveIAMMemberResponse, error) {
objectDetails, err := s.command.RemoveIAMMember(ctx, req.UserId)
if err != nil {
return nil, err
}
return &admin_pb.RemoveIAMMemberResponse{
Details: object.DomainToDetailsPb(objectDetails),
}, nil
}

View File

@@ -1,129 +1,32 @@
package admin
import (
"github.com/caos/logging"
member_grpc "github.com/caos/zitadel/internal/api/grpc/member"
"github.com/caos/zitadel/internal/domain"
"github.com/golang/protobuf/ptypes"
"google.golang.org/protobuf/types/known/timestamppb"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/pkg/grpc/admin"
"github.com/caos/zitadel/internal/iam/model"
admin_pb "github.com/caos/zitadel/pkg/grpc/admin"
)
func addIamMemberToDomain(member *admin.AddIamMemberRequest) *domain.Member {
return domain.NewMember(domain.IAMID, member.UserId, member.Roles...)
}
func changeIamMemberToDomain(member *admin.ChangeIamMemberRequest) *domain.Member {
return domain.NewMember(domain.IAMID, member.UserId, member.Roles...)
}
func iamMemberFromDomain(member *domain.Member) *admin.IamMember {
return &admin.IamMember{
UserId: member.UserID,
ChangeDate: timestamppb.New(member.ChangeDate),
Roles: member.Roles,
Sequence: member.Sequence,
func AddIAMMemberToDomain(req *admin_pb.AddIAMMemberRequest) *domain.Member {
return &domain.Member{
UserID: req.UserId,
Roles: req.Roles,
}
}
func iamMemberSearchRequestToModel(request *admin.IamMemberSearchRequest) *iam_model.IAMMemberSearchRequest {
return &iam_model.IAMMemberSearchRequest{
Limit: request.Limit,
Offset: request.Offset,
Queries: iamMemberSearchQueriesToModel(request.Queries),
func UpdateIAMMemberToDomain(req *admin_pb.UpdateIAMMemberRequest) *domain.Member {
return &domain.Member{
UserID: req.UserId,
Roles: req.Roles,
}
}
func iamMemberSearchQueriesToModel(queries []*admin.IamMemberSearchQuery) []*iam_model.IAMMemberSearchQuery {
modelQueries := make([]*iam_model.IAMMemberSearchQuery, len(queries))
for i, query := range queries {
modelQueries[i] = iamMemberSearchQueryToModel(query)
}
return modelQueries
}
func iamMemberSearchQueryToModel(query *admin.IamMemberSearchQuery) *iam_model.IAMMemberSearchQuery {
return &iam_model.IAMMemberSearchQuery{
Key: iamMemberSearchKeyToModel(query.Key),
Method: searchMethodToModel(query.Method),
Value: query.Value,
}
}
func iamMemberSearchKeyToModel(key admin.IamMemberSearchKey) iam_model.IAMMemberSearchKey {
switch key {
case admin.IamMemberSearchKey_IAMMEMBERSEARCHKEY_EMAIL:
return iam_model.IAMMemberSearchKeyEmail
case admin.IamMemberSearchKey_IAMMEMBERSEARCHKEY_FIRST_NAME:
return iam_model.IAMMemberSearchKeyFirstName
case admin.IamMemberSearchKey_IAMMEMBERSEARCHKEY_LAST_NAME:
return iam_model.IAMMemberSearchKeyLastName
case admin.IamMemberSearchKey_IAMMEMBERSEARCHKEY_USER_ID:
return iam_model.IAMMemberSearchKeyUserID
default:
return iam_model.IAMMemberSearchKeyUnspecified
}
}
func searchMethodToModel(key admin.SearchMethod) domain.SearchMethod {
switch key {
case admin.SearchMethod_SEARCHMETHOD_CONTAINS:
return domain.SearchMethodContains
case admin.SearchMethod_SEARCHMETHOD_CONTAINS_IGNORE_CASE:
return domain.SearchMethodContainsIgnoreCase
case admin.SearchMethod_SEARCHMETHOD_EQUALS:
return domain.SearchMethodEquals
case admin.SearchMethod_SEARCHMETHOD_EQUALS_IGNORE_CASE:
return domain.SearchMethodEqualsIgnoreCase
case admin.SearchMethod_SEARCHMETHOD_STARTS_WITH:
return domain.SearchMethodStartsWith
case admin.SearchMethod_SEARCHMETHOD_STARTS_WITH_IGNORE_CASE:
return domain.SearchMethodStartsWithIgnoreCase
default:
return -1
}
}
func iamMemberSearchResponseFromModel(resp *iam_model.IAMMemberSearchResponse) *admin.IamMemberSearchResponse {
timestamp, err := ptypes.TimestampProto(resp.Timestamp)
logging.Log("GRPC-5shu8").OnError(err).Debug("date parse failed")
return &admin.IamMemberSearchResponse{
Limit: resp.Limit,
Offset: resp.Offset,
TotalResult: resp.TotalResult,
Result: iamMembersFromView(resp.Result),
ProcessedSequence: resp.Sequence,
ViewTimestamp: timestamp,
}
}
func iamMembersFromView(viewMembers []*iam_model.IAMMemberView) []*admin.IamMemberView {
members := make([]*admin.IamMemberView, len(viewMembers))
for i, member := range viewMembers {
members[i] = iamMemberFromView(member)
}
return members
}
func iamMemberFromView(member *iam_model.IAMMemberView) *admin.IamMemberView {
changeDate, err := ptypes.TimestampProto(member.ChangeDate)
logging.Log("GRPC-Lso9c").OnError(err).Debug("unable to parse changedate")
creationDate, err := ptypes.TimestampProto(member.CreationDate)
logging.Log("GRPC-6szE").OnError(err).Debug("unable to parse creation date")
return &admin.IamMemberView{
ChangeDate: changeDate,
CreationDate: creationDate,
Roles: member.Roles,
Sequence: member.Sequence,
UserId: member.UserID,
UserName: member.UserName,
Email: member.Email,
FirstName: member.FirstName,
LastName: member.LastName,
DisplayName: member.DisplayName,
func ListIAMMemberRequestToModel(req *admin_pb.ListIAMMembersRequest) *model.IAMMemberSearchRequest {
return &model.IAMMemberSearchRequest{
Offset: req.Query.Offset,
Limit: uint64(req.Query.Limit),
Asc: req.Query.Asc,
// SortingColumn: model.IAMMemberSearchKey, //TOOD: not implemented in proto
Queries: member_grpc.MemberQueriesToIAMMember(req.Queries),
}
}

View File

@@ -0,0 +1,60 @@
package admin
import (
"testing"
"github.com/caos/zitadel/internal/test"
"github.com/caos/zitadel/pkg/grpc/admin"
)
func TestAddIAMMemberToDomain(t *testing.T) {
type args struct {
req *admin.AddIAMMemberRequest
}
tests := []struct {
name string
args args
}{
{
name: "all fields filled",
args: args{
req: &admin.AddIAMMemberRequest{
UserId: "1232452",
Roles: []string{"admin"},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := AddIAMMemberToDomain(tt.args.req)
test.AssertFieldsMapped(t, got, "ObjectRoot")
})
}
}
func TestUpdateIAMMemberToDomain(t *testing.T) {
type args struct {
req *admin.UpdateIAMMemberRequest
}
tests := []struct {
name string
args args
}{
{
name: "all fields filled",
args: args{
req: &admin.UpdateIAMMemberRequest{
UserId: "1232452",
Roles: []string{"admin"},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := UpdateIAMMemberToDomain(tt.args.req)
test.AssertFieldsMapped(t, got, "ObjectRoot")
})
}
}

View File

@@ -0,0 +1,103 @@
package admin
import (
"context"
idp_grpc "github.com/caos/zitadel/internal/api/grpc/idp"
object_pb "github.com/caos/zitadel/internal/api/grpc/object"
admin_pb "github.com/caos/zitadel/pkg/grpc/admin"
)
func (s *Server) GetIDPByID(ctx context.Context, req *admin_pb.GetIDPByIDRequest) (*admin_pb.GetIDPByIDResponse, error) {
idp, err := s.query.DefaultIDPConfigByID(ctx, req.Id)
if err != nil {
return nil, err
}
return &admin_pb.GetIDPByIDResponse{Idp: idp_grpc.IDPViewToPb(idp)}, nil
}
func (s *Server) ListIDPs(ctx context.Context, req *admin_pb.ListIDPsRequest) (*admin_pb.ListIDPsResponse, error) {
resp, err := s.iam.SearchIDPConfigs(ctx, listIDPsToModel(req))
if err != nil {
return nil, err
}
return &admin_pb.ListIDPsResponse{
Result: idp_grpc.IDPViewsToPb(resp.Result),
Details: object_pb.ToListDetails(resp.TotalResult, resp.Sequence, resp.Timestamp),
}, nil
}
func (s *Server) AddOIDCIDP(ctx context.Context, req *admin_pb.AddOIDCIDPRequest) (*admin_pb.AddOIDCIDPResponse, error) {
config, err := s.command.AddDefaultIDPConfig(ctx, addOIDCIDPRequestToDomain(req))
if err != nil {
return nil, err
}
return &admin_pb.AddOIDCIDPResponse{
IdpId: config.AggregateID,
Details: object_pb.ToDetailsPb(
config.Sequence,
config.ChangeDate,
config.ResourceOwner,
),
}, nil
}
func (s *Server) UpdateIDP(ctx context.Context, req *admin_pb.UpdateIDPRequest) (*admin_pb.UpdateIDPResponse, error) {
config, err := s.command.ChangeDefaultIDPConfig(ctx, updateIDPToDomain(req))
if err != nil {
return nil, err
}
return &admin_pb.UpdateIDPResponse{
Details: object_pb.ToDetailsPb(
config.Sequence,
config.ChangeDate,
config.ResourceOwner,
),
}, nil
}
func (s *Server) DeactivateIDP(ctx context.Context, req *admin_pb.DeactivateIDPRequest) (*admin_pb.DeactivateIDPResponse, error) {
objectDetails, err := s.command.DeactivateDefaultIDPConfig(ctx, req.IdpId)
if err != nil {
return nil, err
}
return &admin_pb.DeactivateIDPResponse{Details: object_pb.DomainToDetailsPb(objectDetails)}, nil
}
func (s *Server) ReactivateIDP(ctx context.Context, req *admin_pb.ReactivateIDPRequest) (*admin_pb.ReactivateIDPResponse, error) {
objectDetails, err := s.command.ReactivateDefaultIDPConfig(ctx, req.IdpId)
if err != nil {
return nil, err
}
return &admin_pb.ReactivateIDPResponse{Details: object_pb.DomainToDetailsPb(objectDetails)}, nil
}
func (s *Server) RemoveIDP(ctx context.Context, req *admin_pb.RemoveIDPRequest) (*admin_pb.RemoveIDPResponse, error) {
idpProviders, err := s.iam.IDPProvidersByIDPConfigID(ctx, req.IdpId)
if err != nil {
return nil, err
}
externalIDPs, err := s.iam.ExternalIDPsByIDPConfigID(ctx, req.IdpId)
if err != nil {
return nil, err
}
objectDetails, err := s.command.RemoveDefaultIDPConfig(ctx, req.IdpId, idpProviderViewsToDomain(idpProviders), externalIDPViewsToDomain(externalIDPs)...)
if err != nil {
return nil, err
}
return &admin_pb.RemoveIDPResponse{Details: object_pb.DomainToDetailsPb(objectDetails)}, nil
}
func (s *Server) UpdateIDPOIDCConfig(ctx context.Context, req *admin_pb.UpdateIDPOIDCConfigRequest) (*admin_pb.UpdateIDPOIDCConfigResponse, error) {
config, err := s.command.ChangeDefaultIDPOIDCConfig(ctx, updateOIDCConfigToDomain(req))
if err != nil {
return nil, err
}
return &admin_pb.UpdateIDPOIDCConfigResponse{
Details: object_pb.ToDetailsPb(
config.Sequence,
config.ChangeDate,
config.ResourceOwner,
),
}, nil
}

View File

@@ -1,71 +0,0 @@
package admin
import (
"context"
"github.com/golang/protobuf/ptypes/empty"
"github.com/caos/zitadel/pkg/grpc/admin"
)
func (s *Server) IdpByID(ctx context.Context, id *admin.IdpID) (*admin.IdpView, error) {
config, err := s.query.DefaultIDPConfigByID(ctx, id.Id)
if err != nil {
return nil, err
}
return idpViewFromDomain(config), nil
}
func (s *Server) CreateOidcIdp(ctx context.Context, oidcIdpConfig *admin.OidcIdpConfigCreate) (*admin.Idp, error) {
config, err := s.command.AddDefaultIDPConfig(ctx, createOIDCIDPToDomain(oidcIdpConfig))
if err != nil {
return nil, err
}
return idpFromDomain(config), nil
}
func (s *Server) UpdateIdpConfig(ctx context.Context, idpConfig *admin.IdpUpdate) (*admin.Idp, error) {
config, err := s.command.ChangeDefaultIDPConfig(ctx, updateIdpToDomain(idpConfig))
if err != nil {
return nil, err
}
return idpFromDomain(config), nil
}
func (s *Server) DeactivateIdpConfig(ctx context.Context, id *admin.IdpID) (*empty.Empty, error) {
err := s.command.DeactivateDefaultIDPConfig(ctx, id.Id)
return &empty.Empty{}, err
}
func (s *Server) ReactivateIdpConfig(ctx context.Context, id *admin.IdpID) (*empty.Empty, error) {
err := s.command.ReactivateDefaultIDPConfig(ctx, id.Id)
return &empty.Empty{}, err
}
func (s *Server) RemoveIdpConfig(ctx context.Context, id *admin.IdpID) (*empty.Empty, error) {
idpProviders, err := s.iam.IDPProvidersByIDPConfigID(ctx, id.Id)
if err != nil {
return &empty.Empty{}, err
}
externalIDPs, err := s.iam.ExternalIDPsByIDPConfigID(ctx, id.Id)
if err != nil {
return &empty.Empty{}, err
}
err = s.command.RemoveDefaultIDPConfig(ctx, id.Id, idpProviderViewsToDomain(idpProviders), externalIDPViewsToDomain(externalIDPs)...)
return &empty.Empty{}, err
}
func (s *Server) UpdateOidcIdpConfig(ctx context.Context, request *admin.OidcIdpConfigUpdate) (*admin.OidcIdpConfig, error) {
config, err := s.command.ChangeDefaultIDPOIDCConfig(ctx, updateOIDCIDPToDomain(request))
if err != nil {
return nil, err
}
return oidcIDPConfigFromDomain(config), nil
}
func (s *Server) SearchIdps(ctx context.Context, request *admin.IdpSearchRequest) (*admin.IdpSearchResponse, error) {
response, err := s.iam.SearchIDPConfigs(ctx, idpConfigSearchRequestToModel(request))
if err != nil {
return nil, err
}
return idpConfigSearchResponseFromModel(response), nil
}

View File

@@ -1,283 +0,0 @@
package admin
import (
"github.com/caos/logging"
"github.com/caos/zitadel/internal/domain"
"github.com/caos/zitadel/internal/eventstore/v1/models"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/pkg/grpc/admin"
"github.com/golang/protobuf/ptypes"
"google.golang.org/protobuf/types/known/timestamppb"
)
func createOIDCIDPToDomain(idp *admin.OidcIdpConfigCreate) *domain.IDPConfig {
return &domain.IDPConfig{
Name: idp.Name,
StylingType: idpConfigStylingTypeToDomain(idp.StylingType),
Type: domain.IDPConfigTypeOIDC,
OIDCConfig: &domain.OIDCIDPConfig{
ClientID: idp.ClientId,
ClientSecretString: idp.ClientSecret,
Issuer: idp.Issuer,
Scopes: idp.Scopes,
IDPDisplayNameMapping: oidcMappingFieldToDomain(idp.IdpDisplayNameMapping),
UsernameMapping: oidcMappingFieldToDomain(idp.UsernameMapping),
},
}
}
func updateIdpToDomain(idp *admin.IdpUpdate) *domain.IDPConfig {
return &domain.IDPConfig{
IDPConfigID: idp.Id,
Name: idp.Name,
StylingType: idpConfigStylingTypeToDomain(idp.StylingType),
}
}
func updateOIDCIDPToDomain(idp *admin.OidcIdpConfigUpdate) *domain.OIDCIDPConfig {
return &domain.OIDCIDPConfig{
IDPConfigID: idp.IdpId,
ClientID: idp.ClientId,
ClientSecretString: idp.ClientSecret,
Issuer: idp.Issuer,
Scopes: idp.Scopes,
IDPDisplayNameMapping: oidcMappingFieldToDomain(idp.IdpDisplayNameMapping),
UsernameMapping: oidcMappingFieldToDomain(idp.UsernameMapping),
}
}
func idpFromDomain(idp *domain.IDPConfig) *admin.Idp {
return &admin.Idp{
Id: idp.IDPConfigID,
ChangeDate: timestamppb.New(idp.ChangeDate),
Sequence: idp.Sequence,
Name: idp.Name,
StylingType: idpConfigStylingTypeFromDomain(idp.StylingType),
State: idpConfigStateFromDomain(idp.State),
IdpConfig: idpConfigFromDomain(idp),
}
}
func idpViewFromDomain(idp *domain.IDPConfigView) *admin.IdpView {
creationDate, err := ptypes.TimestampProto(idp.CreationDate)
logging.Log("GRPC-8dju8").OnError(err).Debug("date parse failed")
changeDate, err := ptypes.TimestampProto(idp.ChangeDate)
logging.Log("GRPC-Dsj8i").OnError(err).Debug("date parse failed")
return &admin.IdpView{
Id: idp.IDPConfigID,
CreationDate: creationDate,
ChangeDate: changeDate,
Sequence: idp.Sequence,
Name: idp.Name,
StylingType: admin.IdpStylingType(idp.StylingType),
State: admin.IdpState(idp.State),
IdpConfigView: idpConfigViewFromDomain(idp),
}
}
func idpViewFromModel(idp *iam_model.IDPConfigView) *admin.IdpView {
creationDate, err := ptypes.TimestampProto(idp.CreationDate)
logging.Log("GRPC-8dju8").OnError(err).Debug("date parse failed")
changeDate, err := ptypes.TimestampProto(idp.ChangeDate)
logging.Log("GRPC-Dsj8i").OnError(err).Debug("date parse failed")
return &admin.IdpView{
Id: idp.IDPConfigID,
CreationDate: creationDate,
ChangeDate: changeDate,
Sequence: idp.Sequence,
Name: idp.Name,
StylingType: admin.IdpStylingType(idp.StylingType),
State: admin.IdpState(idp.State),
IdpConfigView: idpConfigViewFromModel(idp),
}
}
func idpConfigFromDomain(idp *domain.IDPConfig) *admin.Idp_OidcConfig {
if idp.Type == domain.IDPConfigTypeOIDC {
return &admin.Idp_OidcConfig{
OidcConfig: oidcIDPConfigFromDomain(idp.OIDCConfig),
}
}
return nil
}
func oidcIDPConfigFromDomain(idp *domain.OIDCIDPConfig) *admin.OidcIdpConfig {
return &admin.OidcIdpConfig{
ClientId: idp.ClientID,
Issuer: idp.Issuer,
Scopes: idp.Scopes,
}
}
func idpConfigViewFromDomain(idp *domain.IDPConfigView) *admin.IdpView_OidcConfig {
if idp.IsOIDC {
return &admin.IdpView_OidcConfig{
OidcConfig: oidcIdpConfigViewFromDomain(idp),
}
}
return nil
}
func idpConfigViewFromModel(idp *iam_model.IDPConfigView) *admin.IdpView_OidcConfig {
if idp.IsOIDC {
return &admin.IdpView_OidcConfig{
OidcConfig: oidcIdpConfigViewFromModel(idp),
}
}
return nil
}
func oidcIdpConfigViewFromDomain(idp *domain.IDPConfigView) *admin.OidcIdpConfigView {
return &admin.OidcIdpConfigView{
ClientId: idp.OIDCClientID,
Issuer: idp.OIDCIssuer,
Scopes: idp.OIDCScopes,
IdpDisplayNameMapping: oidcMappingFieldFromDomain(idp.OIDCIDPDisplayNameMapping),
UsernameMapping: oidcMappingFieldFromDomain(idp.OIDCUsernameMapping),
}
}
func oidcIdpConfigViewFromModel(idp *iam_model.IDPConfigView) *admin.OidcIdpConfigView {
return &admin.OidcIdpConfigView{
ClientId: idp.OIDCClientID,
Issuer: idp.OIDCIssuer,
Scopes: idp.OIDCScopes,
IdpDisplayNameMapping: admin.OIDCMappingField(idp.OIDCIDPDisplayNameMapping),
UsernameMapping: admin.OIDCMappingField(idp.OIDCUsernameMapping),
}
}
func idpConfigStateFromDomain(state domain.IDPConfigState) admin.IdpState {
switch state {
case domain.IDPConfigStateActive:
return admin.IdpState_IDPCONFIGSTATE_ACTIVE
case domain.IDPConfigStateInactive:
return admin.IdpState_IDPCONFIGSTATE_INACTIVE
default:
return admin.IdpState_IDPCONFIGSTATE_UNSPECIFIED
}
}
func oidcMappingFieldFromDomain(field domain.OIDCMappingField) admin.OIDCMappingField {
switch field {
case domain.OIDCMappingFieldPreferredLoginName:
return admin.OIDCMappingField_OIDCMAPPINGFIELD_PREFERRED_USERNAME
case domain.OIDCMappingFieldEmail:
return admin.OIDCMappingField_OIDCMAPPINGFIELD_EMAIL
default:
return admin.OIDCMappingField_OIDCMAPPINGFIELD_UNSPECIFIED
}
}
func oidcMappingFieldToDomain(field admin.OIDCMappingField) domain.OIDCMappingField {
switch field {
case admin.OIDCMappingField_OIDCMAPPINGFIELD_PREFERRED_USERNAME:
return domain.OIDCMappingFieldPreferredLoginName
case admin.OIDCMappingField_OIDCMAPPINGFIELD_EMAIL:
return domain.OIDCMappingFieldEmail
default:
return domain.OIDCMappingFieldPreferredLoginName
}
}
func idpConfigSearchRequestToModel(request *admin.IdpSearchRequest) *iam_model.IDPConfigSearchRequest {
return &iam_model.IDPConfigSearchRequest{
Limit: request.Limit,
Offset: request.Offset,
Queries: idpConfigSearchQueriesToModel(request.Queries),
}
}
func idpConfigSearchQueriesToModel(queries []*admin.IdpSearchQuery) []*iam_model.IDPConfigSearchQuery {
modelQueries := make([]*iam_model.IDPConfigSearchQuery, len(queries))
for i, query := range queries {
modelQueries[i] = idpConfigSearchQueryToModel(query)
}
return modelQueries
}
func idpConfigSearchQueryToModel(query *admin.IdpSearchQuery) *iam_model.IDPConfigSearchQuery {
return &iam_model.IDPConfigSearchQuery{
Key: idpConfigSearchKeyToModel(query.Key),
Method: searchMethodToModel(query.Method),
Value: query.Value,
}
}
func idpConfigSearchKeyToModel(key admin.IdpSearchKey) iam_model.IDPConfigSearchKey {
switch key {
case admin.IdpSearchKey_IDPSEARCHKEY_IDP_CONFIG_ID:
return iam_model.IDPConfigSearchKeyIdpConfigID
case admin.IdpSearchKey_IDPSEARCHKEY_NAME:
return iam_model.IDPConfigSearchKeyName
default:
return iam_model.IDPConfigSearchKeyUnspecified
}
}
func idpConfigSearchResponseFromModel(resp *iam_model.IDPConfigSearchResponse) *admin.IdpSearchResponse {
timestamp, err := ptypes.TimestampProto(resp.Timestamp)
logging.Log("GRPC-KSi8c").OnError(err).Debug("date parse failed")
return &admin.IdpSearchResponse{
Limit: resp.Limit,
Offset: resp.Offset,
TotalResult: resp.TotalResult,
Result: idpConfigsFromView(resp.Result),
ProcessedSequence: resp.Sequence,
ViewTimestamp: timestamp,
}
}
func idpConfigsFromView(viewIdps []*iam_model.IDPConfigView) []*admin.IdpView {
idps := make([]*admin.IdpView, len(viewIdps))
for i, idp := range viewIdps {
idps[i] = idpViewFromModel(idp)
}
return idps
}
func idpConfigStylingTypeFromDomain(stylingType domain.IDPConfigStylingType) admin.IdpStylingType {
switch stylingType {
case domain.IDPConfigStylingTypeGoogle:
return admin.IdpStylingType_IDPSTYLINGTYPE_GOOGLE
default:
return admin.IdpStylingType_IDPSTYLINGTYPE_UNSPECIFIED
}
}
func idpConfigStylingTypeToDomain(stylingType admin.IdpStylingType) domain.IDPConfigStylingType {
switch stylingType {
case admin.IdpStylingType_IDPSTYLINGTYPE_GOOGLE:
return domain.IDPConfigStylingTypeGoogle
default:
return domain.IDPConfigStylingTypeUnspecified
}
}
func idpConfigTypeToDomain(idpType iam_model.IDPProviderType) domain.IdentityProviderType {
switch idpType {
case iam_model.IDPProviderTypeOrg:
return domain.IdentityProviderTypeOrg
default:
return domain.IdentityProviderTypeSystem
}
}
func idpProviderViewsToDomain(idps []*iam_model.IDPProviderView) []*domain.IDPProvider {
idpProvider := make([]*domain.IDPProvider, len(idps))
for i, idp := range idps {
idpProvider[i] = &domain.IDPProvider{
ObjectRoot: models.ObjectRoot{
AggregateID: idp.AggregateID,
},
IDPConfigID: idp.IDPConfigID,
Type: idpConfigTypeToDomain(idp.IDPProviderType),
}
}
return idpProvider
}

View File

@@ -0,0 +1,119 @@
package admin
import (
idp_grpc "github.com/caos/zitadel/internal/api/grpc/idp"
"github.com/caos/zitadel/internal/domain"
"github.com/caos/zitadel/internal/eventstore/v1/models"
iam_model "github.com/caos/zitadel/internal/iam/model"
user_model "github.com/caos/zitadel/internal/user/model"
admin_pb "github.com/caos/zitadel/pkg/grpc/admin"
)
func addOIDCIDPRequestToDomain(req *admin_pb.AddOIDCIDPRequest) *domain.IDPConfig {
return &domain.IDPConfig{
Name: req.Name,
OIDCConfig: addOIDCIDPRequestToDomainOIDCIDPConfig(req),
StylingType: idp_grpc.IDPStylingTypeToDomain(req.StylingType),
Type: domain.IDPConfigTypeOIDC,
}
}
func addOIDCIDPRequestToDomainOIDCIDPConfig(req *admin_pb.AddOIDCIDPRequest) *domain.OIDCIDPConfig {
return &domain.OIDCIDPConfig{
ClientID: req.ClientId,
ClientSecretString: req.ClientSecret,
Issuer: req.Issuer,
Scopes: req.Scopes,
IDPDisplayNameMapping: idp_grpc.MappingFieldToDomain(req.DisplayNameMapping),
UsernameMapping: idp_grpc.MappingFieldToDomain(req.UsernameMapping),
}
}
func updateIDPToDomain(req *admin_pb.UpdateIDPRequest) *domain.IDPConfig {
return &domain.IDPConfig{
IDPConfigID: req.IdpId,
Name: req.Name,
StylingType: idp_grpc.IDPStylingTypeToDomain(req.StylingType),
}
}
func updateOIDCConfigToDomain(req *admin_pb.UpdateIDPOIDCConfigRequest) *domain.OIDCIDPConfig {
return &domain.OIDCIDPConfig{
IDPConfigID: req.IdpId,
ClientID: req.ClientId,
ClientSecretString: req.ClientSecret,
Issuer: req.Issuer,
Scopes: req.Scopes,
IDPDisplayNameMapping: idp_grpc.MappingFieldToDomain(req.DisplayNameMapping),
UsernameMapping: idp_grpc.MappingFieldToDomain(req.UsernameMapping),
}
}
func listIDPsToModel(req *admin_pb.ListIDPsRequest) *iam_model.IDPConfigSearchRequest {
return &iam_model.IDPConfigSearchRequest{
Offset: req.Query.Offset,
Limit: uint64(req.Query.Limit),
Asc: req.Query.Asc,
SortingColumn: idp_grpc.FieldNameToModel(req.SortingColumn),
Queries: idpQueriesToModel(req.Queries),
}
}
func idpQueriesToModel(queries []*admin_pb.IDPQuery) []*iam_model.IDPConfigSearchQuery {
q := make([]*iam_model.IDPConfigSearchQuery, len(queries))
for i, query := range queries {
q[i] = idpQueryToModel(query)
}
return q
}
func idpQueryToModel(query *admin_pb.IDPQuery) *iam_model.IDPConfigSearchQuery {
switch q := query.Query.(type) {
case *admin_pb.IDPQuery_IdpNameQuery:
return idp_grpc.IDPNameQueryToModel(q.IdpNameQuery)
case *admin_pb.IDPQuery_IdpIdQuery:
return idp_grpc.IDPIDQueryToModel(q.IdpIdQuery)
default:
return nil
}
}
func idpProviderViewsToDomain(idps []*iam_model.IDPProviderView) []*domain.IDPProvider {
idpProvider := make([]*domain.IDPProvider, len(idps))
for i, idp := range idps {
idpProvider[i] = &domain.IDPProvider{
ObjectRoot: models.ObjectRoot{
AggregateID: idp.AggregateID,
},
IDPConfigID: idp.IDPConfigID,
Type: idpConfigTypeToDomain(idp.IDPProviderType),
}
}
return idpProvider
}
func idpConfigTypeToDomain(idpType iam_model.IDPProviderType) domain.IdentityProviderType {
switch idpType {
case iam_model.IDPProviderTypeOrg:
return domain.IdentityProviderTypeOrg
default:
return domain.IdentityProviderTypeSystem
}
}
func externalIDPViewsToDomain(idps []*user_model.ExternalIDPView) []*domain.ExternalIDP {
externalIDPs := make([]*domain.ExternalIDP, len(idps))
for i, idp := range idps {
externalIDPs[i] = &domain.ExternalIDP{
ObjectRoot: models.ObjectRoot{
AggregateID: idp.UserID,
ResourceOwner: idp.ResourceOwner,
},
IDPConfigID: idp.IDPConfigID,
ExternalUserID: idp.ExternalUserID,
DisplayName: idp.UserDisplayName,
}
}
return externalIDPs
}

View File

@@ -0,0 +1,149 @@
package admin
import (
"testing"
"github.com/caos/zitadel/internal/test"
admin_pb "github.com/caos/zitadel/pkg/grpc/admin"
"github.com/caos/zitadel/pkg/grpc/idp"
)
func Test_addOIDCIDPRequestToDomain(t *testing.T) {
type args struct {
req *admin_pb.AddOIDCIDPRequest
}
tests := []struct {
name string
args args
}{
{
name: "all fields filled",
args: args{
req: &admin_pb.AddOIDCIDPRequest{
Name: "ZITADEL",
StylingType: idp.IDPStylingType_STYLING_TYPE_GOOGLE,
ClientId: "test1234",
ClientSecret: "test4321",
Issuer: "zitadel.ch",
Scopes: []string{"email", "profile"},
DisplayNameMapping: idp.OIDCMappingField_OIDC_MAPPING_FIELD_EMAIL,
UsernameMapping: idp.OIDCMappingField_OIDC_MAPPING_FIELD_PREFERRED_USERNAME,
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := addOIDCIDPRequestToDomain(tt.args.req)
test.AssertFieldsMapped(t, got,
"ObjectRoot",
"OIDCConfig.ClientSecret",
"OIDCConfig.ObjectRoot",
"OIDCConfig.IDPConfigID",
"IDPConfigID",
"State",
"Type", //TODO: default (0) is oidc
)
})
}
}
func Test_addOIDCIDPRequestToDomainOIDCIDPConfig(t *testing.T) {
type args struct {
req *admin_pb.AddOIDCIDPRequest
}
tests := []struct {
name string
args args
}{
{
name: "all fields filled",
args: args{
req: &admin_pb.AddOIDCIDPRequest{
ClientId: "test1234",
ClientSecret: "test4321",
Issuer: "zitadel.ch",
Scopes: []string{"email", "profile"},
DisplayNameMapping: idp.OIDCMappingField_OIDC_MAPPING_FIELD_EMAIL,
UsernameMapping: idp.OIDCMappingField_OIDC_MAPPING_FIELD_PREFERRED_USERNAME,
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := addOIDCIDPRequestToDomainOIDCIDPConfig(tt.args.req)
test.AssertFieldsMapped(t, got,
"ObjectRoot",
"ClientSecret", //TODO: is client secret string enough for backend?
"IDPConfigID",
)
})
}
}
func Test_updateIDPToDomain(t *testing.T) {
type args struct {
req *admin_pb.UpdateIDPRequest
}
tests := []struct {
name string
args args
}{
{
name: "all fields filled",
args: args{
req: &admin_pb.UpdateIDPRequest{
Id: "13523",
Name: "new name",
StylingType: idp.IDPStylingType_STYLING_TYPE_GOOGLE,
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := updateIDPToDomain(tt.args.req)
test.AssertFieldsMapped(t, got,
"ObjectRoot",
"OIDCConfig",
"State",
"Type", //TODO: type should not be changeable
)
})
}
}
func Test_updateOIDCConfigToDomain(t *testing.T) {
type args struct {
req *admin_pb.UpdateIDPOIDCConfigRequest
}
tests := []struct {
name string
args args
}{
{
name: "all fields filled",
args: args{
req: &admin_pb.UpdateIDPOIDCConfigRequest{
IdpId: "4208",
Issuer: "zitadel.ch",
ClientId: "ZITEADEL",
ClientSecret: "i'm so secret",
Scopes: []string{"profile"},
DisplayNameMapping: idp.OIDCMappingField_OIDC_MAPPING_FIELD_EMAIL,
UsernameMapping: idp.OIDCMappingField_OIDC_MAPPING_FIELD_PREFERRED_USERNAME,
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := updateOIDCConfigToDomain(tt.args.req)
test.AssertFieldsMapped(t, got,
"ObjectRoot",
"ClientSecret",
)
})
}
}

View File

@@ -0,0 +1,11 @@
package admin
import (
"context"
"github.com/caos/zitadel/pkg/grpc/admin"
)
func (s *Server) Healthz(context.Context, *admin.HealthzRequest) (*admin.HealthzResponse, error) {
return &admin.HealthzResponse{}, nil
}

View File

@@ -3,22 +3,29 @@ package admin
import (
"context"
"github.com/caos/zitadel/pkg/grpc/admin"
"github.com/golang/protobuf/ptypes/empty"
"github.com/caos/zitadel/internal/api/grpc/object"
policy_grpc "github.com/caos/zitadel/internal/api/grpc/policy"
admin_pb "github.com/caos/zitadel/pkg/grpc/admin"
)
func (s *Server) GetDefaultLabelPolicy(ctx context.Context, _ *empty.Empty) (*admin.DefaultLabelPolicyView, error) {
result, err := s.iam.GetDefaultLabelPolicy(ctx)
func (s *Server) GetLabelPolicy(ctx context.Context, req *admin_pb.GetLabelPolicyRequest) (*admin_pb.GetLabelPolicyResponse, error) {
policy, err := s.iam.GetDefaultLabelPolicy(ctx)
if err != nil {
return nil, err
}
return labelPolicyViewFromModel(result), nil
return &admin_pb.GetLabelPolicyResponse{Policy: policy_grpc.ModelLabelPolicyToPb(policy)}, nil
}
func (s *Server) UpdateDefaultLabelPolicy(ctx context.Context, policy *admin.DefaultLabelPolicyUpdate) (*admin.DefaultLabelPolicy, error) {
result, err := s.command.ChangeDefaultLabelPolicy(ctx, labelPolicyToDomain(policy))
func (s *Server) UpdateLabelPolicy(ctx context.Context, req *admin_pb.UpdateLabelPolicyRequest) (*admin_pb.UpdateLabelPolicyResponse, error) {
policy, err := s.command.ChangeDefaultLabelPolicy(ctx, updateLabelPolicyToDomain(req))
if err != nil {
return nil, err
}
return labelPolicyFromDomain(result), nil
return &admin_pb.UpdateLabelPolicyResponse{
Details: object.ToDetailsPb(
policy.Sequence,
policy.ChangeDate,
policy.ResourceOwner,
),
}, nil
}

View File

@@ -1,40 +1,13 @@
package admin
import (
"github.com/caos/logging"
"github.com/caos/zitadel/internal/domain"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/pkg/grpc/admin"
"github.com/golang/protobuf/ptypes"
"google.golang.org/protobuf/types/known/timestamppb"
admin_pb "github.com/caos/zitadel/pkg/grpc/admin"
)
func labelPolicyToDomain(policy *admin.DefaultLabelPolicyUpdate) *domain.LabelPolicy {
func updateLabelPolicyToDomain(policy *admin_pb.UpdateLabelPolicyRequest) *domain.LabelPolicy {
return &domain.LabelPolicy{
PrimaryColor: policy.PrimaryColor,
SecondaryColor: policy.SecondaryColor,
}
}
func labelPolicyFromDomain(policy *domain.LabelPolicy) *admin.DefaultLabelPolicy {
return &admin.DefaultLabelPolicy{
PrimaryColor: policy.PrimaryColor,
SecondaryColor: policy.SecondaryColor,
ChangeDate: timestamppb.New(policy.ChangeDate),
}
}
func labelPolicyViewFromModel(policy *iam_model.LabelPolicyView) *admin.DefaultLabelPolicyView {
creationDate, err := ptypes.TimestampProto(policy.CreationDate)
logging.Log("ADMIN-zMnlF").OnError(err).Debug("date parse failed")
changeDate, err := ptypes.TimestampProto(policy.ChangeDate)
logging.Log("ADMIN-Vhvfp").OnError(err).Debug("date parse failed")
return &admin.DefaultLabelPolicyView{
PrimaryColor: policy.PrimaryColor,
SecondaryColor: policy.SecondaryColor,
CreationDate: creationDate,
ChangeDate: changeDate,
}
}

View File

@@ -2,89 +2,138 @@ package admin
import (
"context"
"github.com/caos/zitadel/pkg/grpc/admin"
"github.com/golang/protobuf/ptypes/empty"
"github.com/caos/zitadel/internal/api/grpc/user"
"time"
"github.com/caos/zitadel/internal/api/grpc/idp"
"github.com/caos/zitadel/internal/api/grpc/object"
"github.com/caos/zitadel/internal/api/grpc/policy"
policy_grpc "github.com/caos/zitadel/internal/api/grpc/policy"
"github.com/caos/zitadel/internal/domain"
admin_pb "github.com/caos/zitadel/pkg/grpc/admin"
)
func (s *Server) GetDefaultLoginPolicy(ctx context.Context, _ *empty.Empty) (*admin.DefaultLoginPolicyView, error) {
result, err := s.iam.GetDefaultLoginPolicy(ctx)
func (s *Server) GetLoginPolicy(ctx context.Context, _ *admin_pb.GetLoginPolicyRequest) (*admin_pb.GetLoginPolicyResponse, error) {
policy, err := s.iam.GetDefaultLoginPolicy(ctx)
if err != nil {
return nil, err
}
return loginPolicyViewFromModel(result), nil
return &admin_pb.GetLoginPolicyResponse{Policy: policy_grpc.ModelLoginPolicyToPb(policy)}, nil
}
func (s *Server) UpdateDefaultLoginPolicy(ctx context.Context, policy *admin.DefaultLoginPolicyRequest) (*admin.DefaultLoginPolicy, error) {
result, err := s.command.ChangeDefaultLoginPolicy(ctx, loginPolicyToDomain(policy))
func (s *Server) UpdateLoginPolicy(ctx context.Context, p *admin_pb.UpdateLoginPolicyRequest) (*admin_pb.UpdateLoginPolicyResponse, error) {
policy, err := s.command.ChangeDefaultLoginPolicy(ctx, updateLoginPolicyToDomain(p))
if err != nil {
return nil, err
}
return loginPolicyFromDomain(result), nil
return &admin_pb.UpdateLoginPolicyResponse{
Details: object.ToDetailsPb(
policy.Sequence,
policy.ChangeDate,
policy.ResourceOwner,
),
}, nil
}
func (s *Server) GetDefaultLoginPolicyIdpProviders(ctx context.Context, request *admin.IdpProviderSearchRequest) (*admin.IdpProviderSearchResponse, error) {
result, err := s.iam.SearchDefaultIDPProviders(ctx, idpProviderSearchRequestToModel(request))
func (s *Server) ListLoginPolicyIDPs(ctx context.Context, req *admin_pb.ListLoginPolicyIDPsRequest) (*admin_pb.ListLoginPolicyIDPsResponse, error) {
res, err := s.iam.SearchDefaultIDPProviders(ctx, ListLoginPolicyIDPsRequestToModel(req))
if err != nil {
return nil, err
}
return idpProviderSearchResponseFromModel(result), nil
return &admin_pb.ListLoginPolicyIDPsResponse{
Result: idp.ExternalIDPViewsToLoginPolicyLinkPb(res.Result),
Details: object.ToListDetails(res.TotalResult, res.Sequence, res.Timestamp),
}, nil
}
func (s *Server) AddIdpProviderToDefaultLoginPolicy(ctx context.Context, provider *admin.IdpProviderID) (*admin.IdpProviderID, error) {
result, err := s.command.AddIDPProviderToDefaultLoginPolicy(ctx, idpProviderToDomain(provider))
func (s *Server) AddIDPToLoginPolicy(ctx context.Context, req *admin_pb.AddIDPToLoginPolicyRequest) (*admin_pb.AddIDPToLoginPolicyResponse, error) {
idp, err := s.command.AddIDPProviderToDefaultLoginPolicy(ctx, &domain.IDPProvider{IDPConfigID: req.IdpId}) //TODO: old way was to also add type but this doesnt make sense in my point of view
if err != nil {
return nil, err
}
return idpProviderFromDomain(result), nil
return &admin_pb.AddIDPToLoginPolicyResponse{
Details: object.ToDetailsPb(
idp.Sequence,
idp.ChangeDate,
idp.ResourceOwner,
),
}, nil
}
func (s *Server) RemoveIdpProviderFromDefaultLoginPolicy(ctx context.Context, provider *admin.IdpProviderID) (*empty.Empty, error) {
externalIDPs, err := s.iam.ExternalIDPsByIDPConfigIDFromDefaultPolicy(ctx, provider.IdpConfigId)
func (s *Server) RemoveIDPFromLoginPolicy(ctx context.Context, req *admin_pb.RemoveIDPFromLoginPolicyRequest) (*admin_pb.RemoveIDPFromLoginPolicyResponse, error) {
externalIDPs, err := s.iam.ExternalIDPsByIDPConfigID(ctx, req.IdpId)
if err != nil {
return &empty.Empty{}, err
return nil, err
}
err = s.command.RemoveIDPProviderFromDefaultLoginPolicy(ctx, idpProviderToDomain(provider), externalIDPViewsToDomain(externalIDPs)...)
return &empty.Empty{}, err
objectDetails, err := s.command.RemoveIDPProviderFromDefaultLoginPolicy(ctx, &domain.IDPProvider{IDPConfigID: req.IdpId}, user.ExternalIDPViewsToExternalIDPs(externalIDPs)...)
if err != nil {
return nil, err
}
return &admin_pb.RemoveIDPFromLoginPolicyResponse{
Details: object.DomainToDetailsPb(objectDetails),
}, nil
}
func (s *Server) GetDefaultLoginPolicySecondFactors(ctx context.Context, _ *empty.Empty) (*admin.SecondFactorsResult, error) {
func (s *Server) ListLoginPolicySecondFactors(ctx context.Context, req *admin_pb.ListLoginPolicySecondFactorsRequest) (*admin_pb.ListLoginPolicySecondFactorsResponse, error) {
result, err := s.iam.SearchDefaultSecondFactors(ctx)
if err != nil {
return nil, err
}
return secondFactorsResultFromModel(result), nil
return &admin_pb.ListLoginPolicySecondFactorsResponse{
//TODO: missing values from res
Details: object.ToListDetails(result.TotalResult, 0, time.Time{}),
Result: policy.ModelSecondFactorTypesToPb(result.Result),
}, nil
}
func (s *Server) AddSecondFactorToDefaultLoginPolicy(ctx context.Context, mfa *admin.SecondFactor) (*admin.SecondFactor, error) {
result, err := s.command.AddSecondFactorToDefaultLoginPolicy(ctx, secondFactorTypeToDomain(mfa))
func (s *Server) AddSecondFactorToLoginPolicy(ctx context.Context, req *admin_pb.AddSecondFactorToLoginPolicyRequest) (*admin_pb.AddSecondFactorToLoginPolicyResponse, error) {
_, objectDetails, err := s.command.AddSecondFactorToDefaultLoginPolicy(ctx, policy.SecondFactorTypeToDomain(req.Type))
if err != nil {
return nil, err
}
return secondFactorFromDomain(result), nil
return &admin_pb.AddSecondFactorToLoginPolicyResponse{
Details: object.DomainToDetailsPb(objectDetails),
}, nil
}
func (s *Server) RemoveSecondFactorFromDefaultLoginPolicy(ctx context.Context, mfa *admin.SecondFactor) (*empty.Empty, error) {
err := s.command.RemoveSecondFactorFromDefaultLoginPolicy(ctx, secondFactorTypeToDomain(mfa))
return &empty.Empty{}, err
}
func (s *Server) GetDefaultLoginPolicyMultiFactors(ctx context.Context, _ *empty.Empty) (*admin.MultiFactorsResult, error) {
result, err := s.iam.SearchDefaultMultiFactors(ctx)
func (s *Server) RemoveSecondFactorFromLoginPolicy(ctx context.Context, req *admin_pb.RemoveSecondFactorFromLoginPolicyRequest) (*admin_pb.RemoveSecondFactorFromLoginPolicyResponse, error) {
objectDetails, err := s.command.RemoveSecondFactorFromDefaultLoginPolicy(ctx, policy.SecondFactorTypeToDomain(req.Type))
if err != nil {
return nil, err
}
return multiFactorResultFromModel(result), nil
return &admin_pb.RemoveSecondFactorFromLoginPolicyResponse{
Details: object.DomainToDetailsPb(objectDetails),
}, nil
}
func (s *Server) AddMultiFactorToDefaultLoginPolicy(ctx context.Context, mfa *admin.MultiFactor) (*admin.MultiFactor, error) {
result, err := s.command.AddMultiFactorToDefaultLoginPolicy(ctx, multiFactorTypeToDomain(mfa))
func (s *Server) ListLoginPolicyMultiFactors(ctx context.Context, req *admin_pb.ListLoginPolicyMultiFactorsRequest) (*admin_pb.ListLoginPolicyMultiFactorsResponse, error) {
res, err := s.iam.SearchDefaultMultiFactors(ctx)
if err != nil {
return nil, err
}
return multiFactorFromDomain(result), nil
return &admin_pb.ListLoginPolicyMultiFactorsResponse{
//TODO: additional values
Details: object.ToListDetails(res.TotalResult, 0, time.Time{}),
Result: policy.ModelMultiFactorTypesToPb(res.Result),
}, nil
}
func (s *Server) RemoveMultiFactorFromDefaultLoginPolicy(ctx context.Context, mfa *admin.MultiFactor) (*empty.Empty, error) {
err := s.command.RemoveMultiFactorFromDefaultLoginPolicy(ctx, multiFactorTypeToDomain(mfa))
return &empty.Empty{}, err
func (s *Server) AddMultiFactorToLoginPolicy(ctx context.Context, req *admin_pb.AddMultiFactorToLoginPolicyRequest) (*admin_pb.AddMultiFactorToLoginPolicyResponse, error) {
_, objectDetails, err := s.command.AddMultiFactorToDefaultLoginPolicy(ctx, policy_grpc.MultiFactorTypeToDomain(req.Type))
if err != nil {
return nil, err
}
return &admin_pb.AddMultiFactorToLoginPolicyResponse{
Details: object.DomainToDetailsPb(objectDetails),
}, nil
}
func (s *Server) RemoveMultiFactorFromLoginPolicy(ctx context.Context, req *admin_pb.RemoveMultiFactorFromLoginPolicyRequest) (*admin_pb.RemoveMultiFactorFromLoginPolicyResponse, error) {
objectDetails, err := s.command.RemoveMultiFactorFromDefaultLoginPolicy(ctx, policy.MultiFactorTypeToDomain(req.Type))
if err != nil {
return nil, err
}
return &admin_pb.RemoveMultiFactorFromLoginPolicyResponse{
Details: object.DomainToDetailsPb(objectDetails),
}, nil
}

View File

@@ -1,223 +1,28 @@
package admin
import (
"github.com/caos/logging"
policy_grpc "github.com/caos/zitadel/internal/api/grpc/policy"
"github.com/caos/zitadel/internal/domain"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/pkg/grpc/admin"
"github.com/golang/protobuf/ptypes"
"google.golang.org/protobuf/types/known/timestamppb"
"github.com/caos/zitadel/internal/iam/model"
admin_pb "github.com/caos/zitadel/pkg/grpc/admin"
)
func loginPolicyToDomain(policy *admin.DefaultLoginPolicyRequest) *domain.LoginPolicy {
func updateLoginPolicyToDomain(p *admin_pb.UpdateLoginPolicyRequest) *domain.LoginPolicy {
return &domain.LoginPolicy{
AllowUsernamePassword: policy.AllowUsernamePassword,
AllowExternalIDP: policy.AllowExternalIdp,
AllowRegister: policy.AllowRegister,
ForceMFA: policy.ForceMfa,
PasswordlessType: passwordlessTypeToDomain(policy.PasswordlessType),
AllowUsernamePassword: p.AllowUsernamePassword,
AllowRegister: p.AllowRegister,
AllowExternalIDP: p.AllowExternalIdp,
ForceMFA: p.ForceMfa,
PasswordlessType: policy_grpc.PasswordlessTypeToDomain(p.PasswordlessType),
}
}
func loginPolicyFromDomain(policy *domain.LoginPolicy) *admin.DefaultLoginPolicy {
return &admin.DefaultLoginPolicy{
AllowUsernamePassword: policy.AllowUsernamePassword,
AllowExternalIdp: policy.AllowExternalIDP,
AllowRegister: policy.AllowRegister,
ForceMfa: policy.ForceMFA,
PasswordlessType: passwordlessTypeFromDomain(policy.PasswordlessType),
ChangeDate: timestamppb.New(policy.ChangeDate),
}
}
func loginPolicyViewFromModel(policy *iam_model.LoginPolicyView) *admin.DefaultLoginPolicyView {
creationDate, err := ptypes.TimestampProto(policy.CreationDate)
logging.Log("GRPC-3Gk9s").OnError(err).Debug("date parse failed")
changeDate, err := ptypes.TimestampProto(policy.ChangeDate)
logging.Log("GRPC-6Jlos").OnError(err).Debug("date parse failed")
return &admin.DefaultLoginPolicyView{
AllowUsernamePassword: policy.AllowUsernamePassword,
AllowExternalIdp: policy.AllowExternalIDP,
AllowRegister: policy.AllowRegister,
ForceMfa: policy.ForceMFA,
PasswordlessType: admin.PasswordlessType(policy.PasswordlessType),
CreationDate: creationDate,
ChangeDate: changeDate,
}
}
func idpProviderSearchRequestToModel(request *admin.IdpProviderSearchRequest) *iam_model.IDPProviderSearchRequest {
return &iam_model.IDPProviderSearchRequest{
Limit: request.Limit,
Offset: request.Offset,
}
}
func idpProviderSearchResponseFromModel(response *iam_model.IDPProviderSearchResponse) *admin.IdpProviderSearchResponse {
return &admin.IdpProviderSearchResponse{
Limit: response.Limit,
Offset: response.Offset,
TotalResult: response.TotalResult,
Result: idpProviderViewsFromModel(response.Result),
}
}
func idpProviderToDomain(provider *admin.IdpProviderID) *domain.IDPProvider {
return &domain.IDPProvider{
IDPConfigID: provider.IdpConfigId,
Type: domain.IdentityProviderTypeSystem,
}
}
func idpProviderToModel(provider *admin.IdpProviderID) *iam_model.IDPProvider {
return &iam_model.IDPProvider{
IDPConfigID: provider.IdpConfigId,
Type: iam_model.IDPProviderTypeSystem,
}
}
func idpProviderFromDomain(provider *domain.IDPProvider) *admin.IdpProviderID {
return &admin.IdpProviderID{
IdpConfigId: provider.IDPConfigID,
}
}
func idpProviderViewsFromModel(providers []*iam_model.IDPProviderView) []*admin.IdpProviderView {
converted := make([]*admin.IdpProviderView, len(providers))
for i, provider := range providers {
converted[i] = idpProviderViewFromModel(provider)
}
return converted
}
func idpProviderViewFromModel(provider *iam_model.IDPProviderView) *admin.IdpProviderView {
return &admin.IdpProviderView{
IdpConfigId: provider.IDPConfigID,
Name: provider.Name,
Type: idpConfigTypeToModel(provider.IDPConfigType),
}
}
func idpConfigTypeToModel(providerType iam_model.IdpConfigType) admin.IdpType {
switch providerType {
case iam_model.IDPConfigTypeOIDC:
return admin.IdpType_IDPTYPE_OIDC
case iam_model.IDPConfigTypeSAML:
return admin.IdpType_IDPTYPE_SAML
default:
return admin.IdpType_IDPTYPE_UNSPECIFIED
}
}
func secondFactorsResultFromModel(result *iam_model.SecondFactorsSearchResponse) *admin.SecondFactorsResult {
converted := make([]admin.SecondFactorType, len(result.Result))
for i, mfaType := range result.Result {
converted[i] = secondFactorTypeFromModel(mfaType)
}
return &admin.SecondFactorsResult{
SecondFactors: converted,
}
}
func secondFactorFromDomain(mfaType domain.SecondFactorType) *admin.SecondFactor {
return &admin.SecondFactor{
SecondFactor: secondFactorTypeFromDomain(mfaType),
}
}
func secondFactorTypeFromDomain(mfaType domain.SecondFactorType) admin.SecondFactorType {
switch mfaType {
case domain.SecondFactorTypeOTP:
return admin.SecondFactorType_SECONDFACTORTYPE_OTP
case domain.SecondFactorTypeU2F:
return admin.SecondFactorType_SECONDFACTORTYPE_U2F
default:
return admin.SecondFactorType_SECONDFACTORTYPE_UNSPECIFIED
}
}
func secondFactorTypeFromModel(mfaType iam_model.SecondFactorType) admin.SecondFactorType {
switch mfaType {
case iam_model.SecondFactorTypeOTP:
return admin.SecondFactorType_SECONDFACTORTYPE_OTP
case iam_model.SecondFactorTypeU2F:
return admin.SecondFactorType_SECONDFACTORTYPE_U2F
default:
return admin.SecondFactorType_SECONDFACTORTYPE_UNSPECIFIED
}
}
func secondFactorTypeToDomain(mfaType *admin.SecondFactor) domain.SecondFactorType {
switch mfaType.SecondFactor {
case admin.SecondFactorType_SECONDFACTORTYPE_OTP:
return domain.SecondFactorTypeOTP
case admin.SecondFactorType_SECONDFACTORTYPE_U2F:
return domain.SecondFactorTypeU2F
default:
return domain.SecondFactorTypeUnspecified
}
}
func passwordlessTypeFromDomain(passwordlessType domain.PasswordlessType) admin.PasswordlessType {
switch passwordlessType {
case domain.PasswordlessTypeAllowed:
return admin.PasswordlessType_PASSWORDLESSTYPE_ALLOWED
default:
return admin.PasswordlessType_PASSWORDLESSTYPE_NOT_ALLOWED
}
}
func passwordlessTypeToDomain(passwordlessType admin.PasswordlessType) domain.PasswordlessType {
switch passwordlessType {
case admin.PasswordlessType_PASSWORDLESSTYPE_ALLOWED:
return domain.PasswordlessTypeAllowed
default:
return domain.PasswordlessTypeNotAllowed
}
}
func multiFactorResultFromModel(result *iam_model.MultiFactorsSearchResponse) *admin.MultiFactorsResult {
converted := make([]admin.MultiFactorType, len(result.Result))
for i, mfaType := range result.Result {
converted[i] = multiFactorTypeFromModel(mfaType)
}
return &admin.MultiFactorsResult{
MultiFactors: converted,
}
}
func multiFactorFromDomain(mfaType domain.MultiFactorType) *admin.MultiFactor {
return &admin.MultiFactor{
MultiFactor: multiFactorTypeFromDomain(mfaType),
}
}
func multiFactorTypeFromDomain(mfaType domain.MultiFactorType) admin.MultiFactorType {
switch mfaType {
case domain.MultiFactorTypeU2FWithPIN:
return admin.MultiFactorType_MULTIFACTORTYPE_U2F_WITH_PIN
default:
return admin.MultiFactorType_MULTIFACTORTYPE_UNSPECIFIED
}
}
func multiFactorTypeFromModel(mfaType iam_model.MultiFactorType) admin.MultiFactorType {
switch mfaType {
case iam_model.MultiFactorTypeU2FWithPIN:
return admin.MultiFactorType_MULTIFACTORTYPE_U2F_WITH_PIN
default:
return admin.MultiFactorType_MULTIFACTORTYPE_UNSPECIFIED
}
}
func multiFactorTypeToDomain(mfaType *admin.MultiFactor) domain.MultiFactorType {
switch mfaType.MultiFactor {
case admin.MultiFactorType_MULTIFACTORTYPE_U2F_WITH_PIN:
return domain.MultiFactorTypeU2FWithPIN
default:
return domain.MultiFactorTypeUnspecified
func ListLoginPolicyIDPsRequestToModel(req *admin_pb.ListLoginPolicyIDPsRequest) *model.IDPProviderSearchRequest {
return &model.IDPProviderSearchRequest{
Offset: req.Query.Offset,
Limit: uint64(req.Query.Limit),
Asc: req.Query.Asc,
// SortingColumn: model.IDPProviderSearchKey, //TODO: not in proto
// Queries: []*model.IDPProviderSearchQuery, //TODO: not in proto
}
}

View File

@@ -0,0 +1,6 @@
package admin
//IdpConfig is a type alias of the generated isIdp_IdpConfig config
//to make it public
// type IdpConfig = isIdp_IdpConfig
// type IdpConfigView = isIdpView_IdpConfigView

View File

@@ -2,85 +2,46 @@ package admin
import (
"context"
"github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/api/grpc/object"
"github.com/golang/protobuf/ptypes/empty"
"github.com/caos/zitadel/pkg/grpc/admin"
org_grpc "github.com/caos/zitadel/internal/api/grpc/org"
admin_pb "github.com/caos/zitadel/pkg/grpc/admin"
)
func (s *Server) GetOrgByID(ctx context.Context, orgID *admin.OrgID) (_ *admin.Org, err error) {
org, err := s.org.OrgByID(ctx, orgID.Id)
func (s *Server) IsOrgUnique(ctx context.Context, req *admin_pb.IsOrgUniqueRequest) (*admin_pb.IsOrgUniqueResponse, error) {
isUnique, err := s.org.IsOrgUnique(ctx, req.Name, req.Domain)
return &admin_pb.IsOrgUniqueResponse{IsUnique: isUnique}, err
}
func (s *Server) GetOrgByID(ctx context.Context, req *admin_pb.GetOrgByIDRequest) (*admin_pb.GetOrgByIDResponse, error) {
org, err := s.org.OrgByID(ctx, req.Id)
if err != nil {
return nil, err
}
return orgViewFromModel(org), nil
return &admin_pb.GetOrgByIDResponse{Org: org_grpc.OrgViewToPb(org)}, nil
}
func (s *Server) SearchOrgs(ctx context.Context, request *admin.OrgSearchRequest) (_ *admin.OrgSearchResponse, err error) {
result, err := s.org.SearchOrgs(ctx, orgSearchRequestToModel(request))
func (s *Server) ListOrgs(ctx context.Context, req *admin_pb.ListOrgsRequest) (*admin_pb.ListOrgsResponse, error) {
query, err := listOrgRequestToModel(req)
if err != nil {
return nil, err
}
return orgSearchResponseFromModel(result), nil
}
func (s *Server) IsOrgUnique(ctx context.Context, request *admin.UniqueOrgRequest) (org *admin.UniqueOrgResponse, err error) {
isUnique, err := s.org.IsOrgUnique(ctx, request.Name, request.Domain)
return &admin.UniqueOrgResponse{IsUnique: isUnique}, err
}
func (s *Server) SetUpOrg(ctx context.Context, orgSetUp *admin.OrgSetUpRequest) (_ *empty.Empty, err error) {
human, _ := userCreateRequestToDomain(orgSetUp.User)
if human == nil {
return &empty.Empty{}, errors.ThrowPreconditionFailed(nil, "ADMIN-4nd9f", "Errors.User.NotHuman")
}
err = s.command.SetUpOrg(ctx, orgCreateRequestToDomain(orgSetUp.Org), human)
return &empty.Empty{}, nil
}
func (s *Server) GetDefaultOrgIamPolicy(ctx context.Context, _ *empty.Empty) (_ *admin.OrgIamPolicyView, err error) {
policy, err := s.iam.GetDefaultOrgIAMPolicy(ctx)
orgs, err := s.org.SearchOrgs(ctx, query)
if err != nil {
return nil, err
}
return orgIAMPolicyViewFromModel(policy), err
return &admin_pb.ListOrgsResponse{Result: org_grpc.OrgViewsToPb(orgs.Result)}, nil
}
func (s *Server) UpdateDefaultOrgIamPolicy(ctx context.Context, in *admin.OrgIamPolicyRequest) (_ *admin.OrgIamPolicy, err error) {
policy, err := s.command.ChangeDefaultOrgIAMPolicy(ctx, orgIAMPolicyRequestToDomain(in))
func (s *Server) SetUpOrg(ctx context.Context, req *admin_pb.SetUpOrgRequest) (*admin_pb.SetUpOrgResponse, error) {
human := setUpOrgHumanToDomain(req.User.(*admin_pb.SetUpOrgRequest_Human_).Human) //TODO: handle machine
org := setUpOrgOrgToDomain(req.Org)
objectDetails, err := s.command.SetUpOrg(ctx, org, human)
if err != nil {
return nil, err
}
return orgIAMPolicyFromDomain(policy), err
}
func (s *Server) GetOrgIamPolicy(ctx context.Context, in *admin.OrgIamPolicyID) (_ *admin.OrgIamPolicyView, err error) {
policy, err := s.org.GetOrgIAMPolicyByID(ctx, in.OrgId)
if err != nil {
return nil, err
}
return orgIAMPolicyViewFromModel(policy), err
}
func (s *Server) CreateOrgIamPolicy(ctx context.Context, in *admin.OrgIamPolicyRequest) (_ *admin.OrgIamPolicy, err error) {
policy, err := s.command.AddOrgIAMPolicy(ctx, in.OrgId, orgIAMPolicyRequestToDomain(in))
if err != nil {
return nil, err
}
return orgIAMPolicyFromDomain(policy), err
}
func (s *Server) UpdateOrgIamPolicy(ctx context.Context, in *admin.OrgIamPolicyRequest) (_ *admin.OrgIamPolicy, err error) {
policy, err := s.command.ChangeOrgIAMPolicy(ctx, in.OrgId, orgIAMPolicyRequestToDomain(in))
if err != nil {
return nil, err
}
return orgIAMPolicyFromDomain(policy), err
}
func (s *Server) RemoveOrgIamPolicy(ctx context.Context, in *admin.OrgIamPolicyID) (_ *empty.Empty, err error) {
err = s.command.RemoveOrgIAMPolicy(ctx, in.OrgId)
return &empty.Empty{}, err
return &admin_pb.SetUpOrgResponse{
Details: object.DomainToDetailsPb(objectDetails),
}, nil
}

View File

@@ -1,209 +1,32 @@
package admin
import (
"github.com/caos/logging"
"github.com/golang/protobuf/ptypes"
"google.golang.org/protobuf/types/known/timestamppb"
org_grpc "github.com/caos/zitadel/internal/api/grpc/org"
"github.com/caos/zitadel/internal/domain"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/internal/eventstore/v1/models"
org_model "github.com/caos/zitadel/internal/org/model"
usr_model "github.com/caos/zitadel/internal/user/model"
"github.com/caos/zitadel/internal/org/model"
"github.com/caos/zitadel/pkg/grpc/admin"
)
func orgCreateRequestToDomain(org *admin.CreateOrgRequest) *domain.Org {
o := &domain.Org{
func listOrgRequestToModel(req *admin.ListOrgsRequest) (*model.OrgSearchRequest, error) {
queries, err := org_grpc.OrgQueriesToModel(req.Queries)
if err != nil {
return nil, err
}
return &model.OrgSearchRequest{
Offset: req.Query.Offset,
Limit: uint64(req.Query.Limit),
Asc: req.Query.Asc,
Queries: queries,
}, nil
}
func setUpOrgOrgToDomain(req *admin.SetUpOrgRequest_Org) *domain.Org {
org := &domain.Org{
Name: req.Name,
Domains: []*domain.OrgDomain{},
Name: org.Name,
}
if org.Domain != "" {
o.Domains = append(o.Domains, &domain.OrgDomain{Domain: org.Domain})
}
return o
}
func orgSearchResponseFromModel(request *org_model.OrgSearchResult) *admin.OrgSearchResponse {
timestamp, err := ptypes.TimestampProto(request.Timestamp)
logging.Log("GRPC-shu7s").OnError(err).Debug("unable to get timestamp from time")
return &admin.OrgSearchResponse{
Result: orgViewsFromModel(request.Result),
Limit: request.Limit,
Offset: request.Offset,
TotalResult: request.TotalResult,
ProcessedSequence: request.Sequence,
ViewTimestamp: timestamp,
}
}
func orgViewsFromModel(orgs []*org_model.OrgView) []*admin.Org {
result := make([]*admin.Org, len(orgs))
for i, org := range orgs {
result[i] = orgViewFromModel(org)
}
return result
}
func orgFromModel(org *org_model.Org) *admin.Org {
changeDate, err := ptypes.TimestampProto(org.ChangeDate)
logging.Log("GRPC-dVnoj").OnError(err).Debug("unable to get timestamp from time")
return &admin.Org{
ChangeDate: changeDate,
Id: org.AggregateID,
Name: org.Name,
State: orgStateFromModel(org.State),
}
}
func orgViewFromModel(org *org_model.OrgView) *admin.Org {
changeDate, err := ptypes.TimestampProto(org.ChangeDate)
logging.Log("GRPC-dVnoj").OnError(err).Debug("unable to get timestamp from time")
return &admin.Org{
ChangeDate: changeDate,
Id: org.ID,
Name: org.Name,
State: orgStateFromModel(org.State),
}
}
func orgStateFromModel(state org_model.OrgState) admin.OrgState {
switch state {
case org_model.OrgStateActive:
return admin.OrgState_ORGSTATE_ACTIVE
case org_model.OrgStateInactive:
return admin.OrgState_ORGSTATE_INACTIVE
default:
return admin.OrgState_ORGSTATE_UNSPECIFIED
}
}
func genderFromModel(gender usr_model.Gender) admin.Gender {
switch gender {
case usr_model.GenderFemale:
return admin.Gender_GENDER_FEMALE
case usr_model.GenderMale:
return admin.Gender_GENDER_MALE
case usr_model.GenderDiverse:
return admin.Gender_GENDER_DIVERSE
default:
return admin.Gender_GENDER_UNSPECIFIED
}
}
func genderToModel(gender admin.Gender) usr_model.Gender {
switch gender {
case admin.Gender_GENDER_FEMALE:
return usr_model.GenderFemale
case admin.Gender_GENDER_MALE:
return usr_model.GenderMale
case admin.Gender_GENDER_DIVERSE:
return usr_model.GenderDiverse
default:
return usr_model.GenderUnspecified
}
}
func userStateFromModel(state usr_model.UserState) admin.UserState {
switch state {
case usr_model.UserStateActive:
return admin.UserState_USERSTATE_ACTIVE
case usr_model.UserStateInactive:
return admin.UserState_USERSTATE_INACTIVE
case usr_model.UserStateLocked:
return admin.UserState_USERSTATE_LOCKED
default:
return admin.UserState_USERSTATE_UNSPECIFIED
}
}
func orgSearchRequestToModel(req *admin.OrgSearchRequest) *org_model.OrgSearchRequest {
return &org_model.OrgSearchRequest{
Limit: req.Limit,
Asc: req.Asc,
Offset: req.Offset,
Queries: orgQueriesToModel(req.Queries),
SortingColumn: orgQueryKeyToModel(req.SortingColumn),
}
}
func orgQueriesToModel(queries []*admin.OrgSearchQuery) []*org_model.OrgSearchQuery {
modelQueries := make([]*org_model.OrgSearchQuery, len(queries))
for i, query := range queries {
modelQueries[i] = orgQueryToModel(query)
}
return modelQueries
}
func orgQueryToModel(query *admin.OrgSearchQuery) *org_model.OrgSearchQuery {
return &org_model.OrgSearchQuery{
Key: orgQueryKeyToModel(query.Key),
Value: query.Value,
Method: orgQueryMethodToModel(query.Method),
}
}
func orgQueryKeyToModel(key admin.OrgSearchKey) org_model.OrgSearchKey {
switch key {
case admin.OrgSearchKey_ORGSEARCHKEY_DOMAIN:
return org_model.OrgSearchKeyOrgDomain
case admin.OrgSearchKey_ORGSEARCHKEY_NAME:
return org_model.OrgSearchKeyOrgName
case admin.OrgSearchKey_ORGSEARCHKEY_STATE:
return org_model.OrgSearchKeyState
default:
return org_model.OrgSearchKeyUnspecified
}
}
func orgQueryMethodToModel(method admin.OrgSearchMethod) domain.SearchMethod {
switch method {
case admin.OrgSearchMethod_ORGSEARCHMETHOD_CONTAINS:
return domain.SearchMethodContains
case admin.OrgSearchMethod_ORGSEARCHMETHOD_EQUALS:
return domain.SearchMethodEquals
case admin.OrgSearchMethod_ORGSEARCHMETHOD_STARTS_WITH:
return domain.SearchMethodStartsWith
default:
return 0
}
}
func orgIAMPolicyFromDomain(policy *domain.OrgIAMPolicy) *admin.OrgIamPolicy {
return &admin.OrgIamPolicy{
OrgId: policy.AggregateID,
UserLoginMustBeDomain: policy.UserLoginMustBeDomain,
ChangeDate: timestamppb.New(policy.ChangeDate),
}
}
func orgIAMPolicyViewFromModel(policy *iam_model.OrgIAMPolicyView) *admin.OrgIamPolicyView {
creationDate, err := ptypes.TimestampProto(policy.CreationDate)
logging.Log("GRPC-ush36").OnError(err).Debug("unable to get timestamp from time")
changeDate, err := ptypes.TimestampProto(policy.ChangeDate)
logging.Log("GRPC-Ps9fW").OnError(err).Debug("unable to get timestamp from time")
return &admin.OrgIamPolicyView{
OrgId: policy.AggregateID,
UserLoginMustBeDomain: policy.UserLoginMustBeDomain,
CreationDate: creationDate,
ChangeDate: changeDate,
}
}
func orgIAMPolicyRequestToDomain(policy *admin.OrgIamPolicyRequest) *domain.OrgIAMPolicy {
return &domain.OrgIAMPolicy{
ObjectRoot: models.ObjectRoot{
AggregateID: policy.OrgId,
},
UserLoginMustBeDomain: policy.UserLoginMustBeDomain,
if req.Domain != "" {
org.Domains = append(org.Domains, &domain.OrgDomain{Domain: req.Domain})
}
return org
}

View File

@@ -0,0 +1,101 @@
package admin
import (
"context"
"github.com/caos/zitadel/internal/api/grpc/object"
policy_grpc "github.com/caos/zitadel/internal/api/grpc/policy"
"github.com/caos/zitadel/internal/domain"
"github.com/caos/zitadel/internal/eventstore/v1/models"
admin_pb "github.com/caos/zitadel/pkg/grpc/admin"
)
func (s *Server) GetOrgIAMPolicy(ctx context.Context, _ *admin_pb.GetOrgIAMPolicyRequest) (*admin_pb.GetOrgIAMPolicyResponse, error) {
policy, err := s.iam.GetDefaultOrgIAMPolicy(ctx)
if err != nil {
return nil, err
}
return &admin_pb.GetOrgIAMPolicyResponse{Policy: policy_grpc.OrgIAMPolicyToPb(policy)}, nil
}
func (s *Server) GetCustomOrgIAMPolicy(ctx context.Context, req *admin_pb.GetCustomOrgIAMPolicyRequest) (*admin_pb.GetCustomOrgIAMPolicyResponse, error) {
policy, err := s.org.GetOrgIAMPolicyByID(ctx, req.OrgId)
if err != nil {
return nil, err
}
return &admin_pb.GetCustomOrgIAMPolicyResponse{Policy: policy_grpc.OrgIAMPolicyToPb(policy)}, nil
}
func (s *Server) AddCustomOrgIAMPolicy(ctx context.Context, req *admin_pb.AddCustomOrgIAMPolicyRequest) (*admin_pb.AddCustomOrgIAMPolicyResponse, error) {
policy, err := s.command.AddOrgIAMPolicy(ctx, req.OrgId, toDomainOrgIAMPolicy(req.UserLoginMustBeDomain))
if err != nil {
return nil, err
}
return &admin_pb.AddCustomOrgIAMPolicyResponse{
Details: object.ToDetailsPb(
policy.Sequence,
policy.ChangeDate,
policy.ResourceOwner,
),
}, nil
}
func (s *Server) UpdateOrgIAMPolicy(ctx context.Context, req *admin_pb.UpdateOrgIAMPolicyRequest) (*admin_pb.UpdateOrgIAMPolicyResponse, error) {
config, err := s.command.ChangeDefaultOrgIAMPolicy(ctx, updateOrgIAMPolicyToDomain(req))
if err != nil {
return nil, err
}
return &admin_pb.UpdateOrgIAMPolicyResponse{
Details: object.ToDetailsPb(
config.Sequence,
config.ChangeDate,
config.ResourceOwner,
),
}, nil
}
func (s *Server) UpdateCustomOrgIAMPolicy(ctx context.Context, req *admin_pb.UpdateCustomOrgIAMPolicyRequest) (*admin_pb.UpdateCustomOrgIAMPolicyResponse, error) {
config, err := s.command.ChangeOrgIAMPolicy(ctx, req.OrgId, updateCustomOrgIAMPolicyToDomain(req))
if err != nil {
return nil, err
}
return &admin_pb.UpdateCustomOrgIAMPolicyResponse{
Details: object.ToDetailsPb(
config.Sequence,
config.ChangeDate,
config.ResourceOwner,
),
}, nil
}
func (s *Server) ResetCustomOrgIAMPolicyTo(ctx context.Context, req *admin_pb.ResetCustomOrgIAMPolicyToDefaultRequest) (*admin_pb.ResetCustomOrgIAMPolicyToDefaultResponse, error) {
err := s.command.RemoveOrgIAMPolicy(ctx, req.OrgId)
if err != nil {
return nil, err
}
return nil, nil //TOOD: return data
}
func toDomainOrgIAMPolicy(userLoginMustBeDomain bool) *domain.OrgIAMPolicy {
return &domain.OrgIAMPolicy{
UserLoginMustBeDomain: userLoginMustBeDomain,
}
}
func updateOrgIAMPolicyToDomain(req *admin_pb.UpdateOrgIAMPolicyRequest) *domain.OrgIAMPolicy {
return &domain.OrgIAMPolicy{
// ObjectRoot: models.ObjectRoot{
// // AggreagateID: //TODO: there should only be ONE default
// },
UserLoginMustBeDomain: req.UserLoginMustBeDomain,
}
}
func updateCustomOrgIAMPolicyToDomain(req *admin_pb.UpdateCustomOrgIAMPolicyRequest) *domain.OrgIAMPolicy {
return &domain.OrgIAMPolicy{
ObjectRoot: models.ObjectRoot{
AggregateID: req.OrgId,
},
UserLoginMustBeDomain: req.UserLoginMustBeDomain,
}
}

View File

@@ -0,0 +1,33 @@
package admin
import (
"context"
"github.com/caos/zitadel/internal/api/grpc/object"
policy_grpc "github.com/caos/zitadel/internal/api/grpc/policy"
admin_pb "github.com/caos/zitadel/pkg/grpc/admin"
)
func (s *Server) GetPasswordAgePolicy(ctx context.Context, req *admin_pb.GetPasswordAgePolicyRequest) (*admin_pb.GetPasswordAgePolicyResponse, error) {
policy, err := s.iam.GetDefaultPasswordAgePolicy(ctx)
if err != nil {
return nil, err
}
return &admin_pb.GetPasswordAgePolicyResponse{
Policy: policy_grpc.ModelPasswordAgePolicyToPb(policy),
}, nil
}
func (s *Server) UpdatePasswordAgePolicy(ctx context.Context, req *admin_pb.UpdatePasswordAgePolicyRequest) (*admin_pb.UpdatePasswordAgePolicyResponse, error) {
result, err := s.command.ChangeDefaultPasswordAgePolicy(ctx, UpdatePasswordAgePolicyToDomain(req))
if err != nil {
return nil, err
}
return &admin_pb.UpdatePasswordAgePolicyResponse{
Details: object.ToDetailsPb(
result.Sequence,
result.ChangeDate,
result.ResourceOwner,
),
}, nil
}

View File

@@ -0,0 +1,13 @@
package admin
import (
"github.com/caos/zitadel/internal/domain"
admin_pb "github.com/caos/zitadel/pkg/grpc/admin"
)
func UpdatePasswordAgePolicyToDomain(policy *admin_pb.UpdatePasswordAgePolicyRequest) *domain.PasswordAgePolicy {
return &domain.PasswordAgePolicy{
MaxAgeDays: uint64(policy.MaxAgeDays),
ExpireWarnDays: uint64(policy.ExpireWarnDays),
}
}

View File

@@ -1,23 +0,0 @@
package admin
import (
"context"
"github.com/caos/zitadel/pkg/grpc/admin"
"github.com/golang/protobuf/ptypes/empty"
)
func (s *Server) GetDefaultPasswordAgePolicy(ctx context.Context, _ *empty.Empty) (*admin.DefaultPasswordAgePolicyView, error) {
result, err := s.iam.GetDefaultPasswordAgePolicy(ctx)
if err != nil {
return nil, err
}
return passwordAgePolicyViewFromModel(result), nil
}
func (s *Server) UpdateDefaultPasswordAgePolicy(ctx context.Context, policy *admin.DefaultPasswordAgePolicyRequest) (*admin.DefaultPasswordAgePolicy, error) {
result, err := s.command.ChangeDefaultPasswordAgePolicy(ctx, passwordAgePolicyToDomain(policy))
if err != nil {
return nil, err
}
return passwordAgePolicyFromDomain(result), nil
}

View File

@@ -1,40 +0,0 @@
package admin
import (
"github.com/caos/logging"
"github.com/caos/zitadel/internal/domain"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/pkg/grpc/admin"
"github.com/golang/protobuf/ptypes"
"google.golang.org/protobuf/types/known/timestamppb"
)
func passwordAgePolicyToDomain(policy *admin.DefaultPasswordAgePolicyRequest) *domain.PasswordAgePolicy {
return &domain.PasswordAgePolicy{
MaxAgeDays: policy.MaxAgeDays,
ExpireWarnDays: policy.ExpireWarnDays,
}
}
func passwordAgePolicyFromDomain(policy *domain.PasswordAgePolicy) *admin.DefaultPasswordAgePolicy {
return &admin.DefaultPasswordAgePolicy{
MaxAgeDays: policy.MaxAgeDays,
ExpireWarnDays: policy.ExpireWarnDays,
ChangeDate: timestamppb.New(policy.ChangeDate),
}
}
func passwordAgePolicyViewFromModel(policy *iam_model.PasswordAgePolicyView) *admin.DefaultPasswordAgePolicyView {
creationDate, err := ptypes.TimestampProto(policy.CreationDate)
logging.Log("GRPC-2Gs9o").OnError(err).Debug("date parse failed")
changeDate, err := ptypes.TimestampProto(policy.ChangeDate)
logging.Log("GRPC-8Hjss").OnError(err).Debug("date parse failed")
return &admin.DefaultPasswordAgePolicyView{
MaxAgeDays: policy.MaxAgeDays,
ExpireWarnDays: policy.ExpireWarnDays,
CreationDate: creationDate,
ChangeDate: changeDate,
}
}

View File

@@ -0,0 +1,31 @@
package admin
import (
"context"
"github.com/caos/zitadel/internal/api/grpc/object"
policy_grpc "github.com/caos/zitadel/internal/api/grpc/policy"
admin_pb "github.com/caos/zitadel/pkg/grpc/admin"
)
func (s *Server) GetPasswordComplexityPolicy(ctx context.Context, _ *admin_pb.GetPasswordComplexityPolicyRequest) (*admin_pb.GetPasswordComplexityPolicyResponse, error) {
policy, err := s.iam.GetDefaultPasswordComplexityPolicy(ctx)
if err != nil {
return nil, err
}
return &admin_pb.GetPasswordComplexityPolicyResponse{Policy: policy_grpc.ModelPasswordComplexityPolicyToPb(policy)}, nil
}
func (s *Server) UpdatePasswordComplexityPolicy(ctx context.Context, req *admin_pb.UpdatePasswordComplexityPolicyRequest) (*admin_pb.UpdatePasswordComplexityPolicyResponse, error) {
result, err := s.command.ChangeDefaultPasswordComplexityPolicy(ctx, UpdatePasswordComplexityPolicyToDomain(req))
if err != nil {
return nil, err
}
return &admin_pb.UpdatePasswordComplexityPolicyResponse{
Details: object.ToDetailsPb(
result.Sequence,
result.ChangeDate,
result.ResourceOwner,
),
}, nil
}

View File

@@ -0,0 +1,16 @@
package admin
import (
"github.com/caos/zitadel/internal/domain"
admin_pb "github.com/caos/zitadel/pkg/grpc/admin"
)
func UpdatePasswordComplexityPolicyToDomain(req *admin_pb.UpdatePasswordComplexityPolicyRequest) *domain.PasswordComplexityPolicy {
return &domain.PasswordComplexityPolicy{
MinLength: uint64(req.MinLength),
HasLowercase: req.HasLowercase,
HasUppercase: req.HasUppercase,
HasNumber: req.HasNumber,
HasSymbol: req.HasSymbol,
}
}

View File

@@ -1,23 +0,0 @@
package admin
import (
"context"
"github.com/caos/zitadel/pkg/grpc/admin"
"github.com/golang/protobuf/ptypes/empty"
)
func (s *Server) GetDefaultPasswordComplexityPolicy(ctx context.Context, _ *empty.Empty) (*admin.DefaultPasswordComplexityPolicyView, error) {
result, err := s.iam.GetDefaultPasswordComplexityPolicy(ctx)
if err != nil {
return nil, err
}
return passwordComplexityPolicyViewFromModel(result), nil
}
func (s *Server) UpdateDefaultPasswordComplexityPolicy(ctx context.Context, policy *admin.DefaultPasswordComplexityPolicyRequest) (*admin.DefaultPasswordComplexityPolicy, error) {
result, err := s.command.ChangeDefaultPasswordComplexityPolicy(ctx, passwordComplexityPolicyToDomain(policy))
if err != nil {
return nil, err
}
return passwordComplexityPolicyFromDomain(result), nil
}

View File

@@ -1,49 +0,0 @@
package admin
import (
"github.com/caos/logging"
"github.com/caos/zitadel/internal/domain"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/pkg/grpc/admin"
"github.com/golang/protobuf/ptypes"
"google.golang.org/protobuf/types/known/timestamppb"
)
func passwordComplexityPolicyToDomain(policy *admin.DefaultPasswordComplexityPolicyRequest) *domain.PasswordComplexityPolicy {
return &domain.PasswordComplexityPolicy{
MinLength: policy.MinLength,
HasUppercase: policy.HasUppercase,
HasLowercase: policy.HasLowercase,
HasNumber: policy.HasNumber,
HasSymbol: policy.HasSymbol,
}
}
func passwordComplexityPolicyFromDomain(policy *domain.PasswordComplexityPolicy) *admin.DefaultPasswordComplexityPolicy {
return &admin.DefaultPasswordComplexityPolicy{
MinLength: policy.MinLength,
HasUppercase: policy.HasUppercase,
HasLowercase: policy.HasLowercase,
HasNumber: policy.HasNumber,
HasSymbol: policy.HasSymbol,
ChangeDate: timestamppb.New(policy.ChangeDate),
}
}
func passwordComplexityPolicyViewFromModel(policy *iam_model.PasswordComplexityPolicyView) *admin.DefaultPasswordComplexityPolicyView {
creationDate, err := ptypes.TimestampProto(policy.CreationDate)
logging.Log("GRPC-rTs9f").OnError(err).Debug("date parse failed")
changeDate, err := ptypes.TimestampProto(policy.ChangeDate)
logging.Log("GRPC-ks9Zt").OnError(err).Debug("date parse failed")
return &admin.DefaultPasswordComplexityPolicyView{
MinLength: policy.MinLength,
HasUppercase: policy.HasUppercase,
HasLowercase: policy.HasLowercase,
HasNumber: policy.HasNumber,
HasSymbol: policy.HasSymbol,
CreationDate: creationDate,
ChangeDate: changeDate,
}
}

View File

@@ -0,0 +1,31 @@
package admin
import (
"context"
"github.com/caos/zitadel/internal/api/grpc/object"
policy_grpc "github.com/caos/zitadel/internal/api/grpc/policy"
admin_pb "github.com/caos/zitadel/pkg/grpc/admin"
)
func (s *Server) GetPasswordLockoutPolicy(ctx context.Context, req *admin_pb.GetPasswordLockoutPolicyRequest) (*admin_pb.GetPasswordLockoutPolicyResponse, error) {
policy, err := s.iam.GetDefaultPasswordLockoutPolicy(ctx)
if err != nil {
return nil, err
}
return &admin_pb.GetPasswordLockoutPolicyResponse{Policy: policy_grpc.ModelPasswordLockoutPolicyToPb(policy)}, nil
}
func (s *Server) UpdatePasswordLockoutPolicy(ctx context.Context, req *admin_pb.UpdatePasswordLockoutPolicyRequest) (*admin_pb.UpdatePasswordLockoutPolicyResponse, error) {
policy, err := s.command.ChangeDefaultPasswordLockoutPolicy(ctx, UpdatePasswordLockoutPolicyToDomain(req))
if err != nil {
return nil, err
}
return &admin_pb.UpdatePasswordLockoutPolicyResponse{
Details: object.ToDetailsPb(
policy.Sequence,
policy.ChangeDate,
policy.ResourceOwner,
),
}, nil
}

View File

@@ -0,0 +1,13 @@
package admin
import (
"github.com/caos/zitadel/internal/domain"
"github.com/caos/zitadel/pkg/grpc/admin"
)
func UpdatePasswordLockoutPolicyToDomain(p *admin.UpdatePasswordLockoutPolicyRequest) *domain.PasswordLockoutPolicy {
return &domain.PasswordLockoutPolicy{
MaxAttempts: uint64(p.MaxAttempts),
ShowLockOutFailures: p.ShowLockoutFailure,
}
}

View File

@@ -1,23 +0,0 @@
package admin
import (
"context"
"github.com/caos/zitadel/pkg/grpc/admin"
"github.com/golang/protobuf/ptypes/empty"
)
func (s *Server) GetDefaultPasswordLockoutPolicy(ctx context.Context, _ *empty.Empty) (*admin.DefaultPasswordLockoutPolicyView, error) {
result, err := s.iam.GetDefaultPasswordLockoutPolicy(ctx)
if err != nil {
return nil, err
}
return passwordLockoutPolicyViewFromModel(result), nil
}
func (s *Server) UpdateDefaultPasswordLockoutPolicy(ctx context.Context, policy *admin.DefaultPasswordLockoutPolicyRequest) (*admin.DefaultPasswordLockoutPolicy, error) {
result, err := s.command.ChangeDefaultPasswordLockoutPolicy(ctx, passwordLockoutPolicyToDomain(policy))
if err != nil {
return nil, err
}
return passwordLockoutPolicyFromDomain(result), nil
}

View File

@@ -1,40 +0,0 @@
package admin
import (
"github.com/caos/logging"
"github.com/caos/zitadel/internal/domain"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/pkg/grpc/admin"
"github.com/golang/protobuf/ptypes"
"google.golang.org/protobuf/types/known/timestamppb"
)
func passwordLockoutPolicyToDomain(policy *admin.DefaultPasswordLockoutPolicyRequest) *domain.PasswordLockoutPolicy {
return &domain.PasswordLockoutPolicy{
MaxAttempts: policy.MaxAttempts,
ShowLockOutFailures: policy.ShowLockoutFailure,
}
}
func passwordLockoutPolicyFromDomain(policy *domain.PasswordLockoutPolicy) *admin.DefaultPasswordLockoutPolicy {
return &admin.DefaultPasswordLockoutPolicy{
MaxAttempts: policy.MaxAttempts,
ShowLockoutFailure: policy.ShowLockOutFailures,
ChangeDate: timestamppb.New(policy.ChangeDate),
}
}
func passwordLockoutPolicyViewFromModel(policy *iam_model.PasswordLockoutPolicyView) *admin.DefaultPasswordLockoutPolicyView {
creationDate, err := ptypes.TimestampProto(policy.CreationDate)
logging.Log("GRPC-7Hmlo").OnError(err).Debug("date parse failed")
changeDate, err := ptypes.TimestampProto(policy.ChangeDate)
logging.Log("GRPC-0oLgs").OnError(err).Debug("date parse failed")
return &admin.DefaultPasswordLockoutPolicyView{
MaxAttempts: policy.MaxAttempts,
ShowLockoutFailure: policy.ShowLockOutFailures,
CreationDate: creationDate,
ChangeDate: changeDate,
}
}

View File

@@ -1,10 +0,0 @@
package admin
import (
"context"
"github.com/golang/protobuf/ptypes/empty"
)
func (s *Server) Healthz(_ context.Context, e *empty.Empty) (*empty.Empty, error) {
return &empty.Empty{}, nil
}

View File

@@ -1,15 +1,14 @@
package admin
import (
"github.com/caos/zitadel/internal/command"
"github.com/caos/zitadel/internal/query"
"google.golang.org/grpc"
"github.com/caos/zitadel/internal/admin/repository"
"github.com/caos/zitadel/internal/admin/repository/eventsourcing"
"github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/internal/api/grpc/server"
"github.com/caos/zitadel/internal/command"
"github.com/caos/zitadel/internal/query"
"github.com/caos/zitadel/pkg/grpc/admin"
"google.golang.org/grpc"
)
const (
@@ -19,6 +18,7 @@ const (
var _ admin.AdminServiceServer = (*Server)(nil)
type Server struct {
admin.UnimplementedAdminServiceServer
command *command.Commands
query *query.Queries
org repository.OrgRepository

View File

@@ -1,24 +0,0 @@
package admin
import (
"context"
"github.com/caos/zitadel/pkg/grpc/admin"
"github.com/golang/protobuf/ptypes/empty"
)
func (s *Server) GetDefaultMailTemplate(ctx context.Context, _ *empty.Empty) (*admin.DefaultMailTemplateView, error) {
result, err := s.iam.GetDefaultMailTemplate(ctx)
if err != nil {
return nil, err
}
return templateViewFromModel(result), nil
}
func (s *Server) UpdateDefaultMailTemplate(ctx context.Context, policy *admin.DefaultMailTemplateUpdate) (*admin.DefaultMailTemplate, error) {
result, err := s.command.ChangeDefaultMailTemplate(ctx, templateToDomain(policy))
if err != nil {
return nil, err
}
return templateFromDomain(result), nil
}

View File

@@ -1,30 +0,0 @@
package admin
import (
"github.com/caos/zitadel/internal/domain"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/pkg/grpc/admin"
"google.golang.org/protobuf/types/known/timestamppb"
)
func templateToDomain(policy *admin.DefaultMailTemplateUpdate) *domain.MailTemplate {
return &domain.MailTemplate{
Template: policy.Template,
}
}
func templateFromDomain(policy *domain.MailTemplate) *admin.DefaultMailTemplate {
return &admin.DefaultMailTemplate{
Template: policy.Template,
CreationDate: timestamppb.New(policy.CreationDate),
ChangeDate: timestamppb.New(policy.ChangeDate),
}
}
func templateViewFromModel(policy *iam_model.MailTemplateView) *admin.DefaultMailTemplateView {
return &admin.DefaultMailTemplateView{
Template: policy.Template,
CreationDate: timestamppb.New(policy.CreationDate),
ChangeDate: timestamppb.New(policy.ChangeDate),
}
}

View File

@@ -1,32 +0,0 @@
package admin
import (
"context"
"github.com/caos/zitadel/pkg/grpc/admin"
"github.com/golang/protobuf/ptypes/empty"
)
func (s *Server) GetDefaultMailTexts(ctx context.Context, _ *empty.Empty) (*admin.DefaultMailTextsView, error) {
result, err := s.iam.GetDefaultMailTexts(ctx)
if err != nil {
return nil, err
}
return textsViewFromModel(result), nil
}
func (s *Server) GetDefaultMailText(ctx context.Context, textType string, language string) (*admin.DefaultMailTextView, error) {
result, err := s.iam.GetDefaultMailText(ctx, textType, language)
if err != nil {
return nil, err
}
return textViewFromModel(result), nil
}
func (s *Server) UpdateDefaultMailText(ctx context.Context, text *admin.DefaultMailTextUpdate) (*admin.DefaultMailText, error) {
result, err := s.command.ChangeDefaultMailText(ctx, textToDomain(text))
if err != nil {
return nil, err
}
return textFromDomain(result), nil
}

View File

@@ -1,66 +0,0 @@
package admin
import (
"github.com/caos/zitadel/internal/domain"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/pkg/grpc/admin"
"google.golang.org/protobuf/types/known/timestamppb"
)
func textToDomain(text *admin.DefaultMailTextUpdate) *domain.MailText {
return &domain.MailText{
MailTextType: text.MailTextType,
Language: text.Language,
Title: text.Title,
PreHeader: text.PreHeader,
Subject: text.Subject,
Greeting: text.Greeting,
Text: text.Text,
ButtonText: text.ButtonText,
}
}
func textFromDomain(text *domain.MailText) *admin.DefaultMailText {
return &admin.DefaultMailText{
MailTextType: text.MailTextType,
Language: text.Language,
Title: text.Title,
PreHeader: text.PreHeader,
Subject: text.Subject,
Greeting: text.Greeting,
Text: text.Text,
ButtonText: text.ButtonText,
CreationDate: timestamppb.New(text.CreationDate),
ChangeDate: timestamppb.New(text.ChangeDate),
}
}
func textsViewFromModel(textsin *iam_model.MailTextsView) *admin.DefaultMailTextsView {
return &admin.DefaultMailTextsView{
Texts: textsViewToModel(textsin.Texts),
}
}
func textsViewToModel(queries []*iam_model.MailTextView) []*admin.DefaultMailTextView {
modelQueries := make([]*admin.DefaultMailTextView, len(queries))
for i, query := range queries {
modelQueries[i] = textViewFromModel(query)
}
return modelQueries
}
func textViewFromModel(text *iam_model.MailTextView) *admin.DefaultMailTextView {
return &admin.DefaultMailTextView{
MailTextType: text.MailTextType,
Language: text.Language,
Title: text.Title,
PreHeader: text.PreHeader,
Subject: text.Subject,
Greeting: text.Greeting,
Text: text.Text,
ButtonText: text.ButtonText,
CreationDate: timestamppb.New(text.CreationDate),
ChangeDate: timestamppb.New(text.ChangeDate),
}
}

View File

@@ -2,92 +2,46 @@ package admin
import (
"github.com/caos/logging"
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/admin"
admin_grpc "github.com/caos/zitadel/pkg/grpc/admin"
"golang.org/x/text/language"
)
func userCreateRequestToDomain(user *admin.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 humanCreateToDomain(u *admin.CreateHumanRequest) *domain.Human {
preferredLanguage, err := language.Parse(u.PreferredLanguage)
logging.Log("GRPC-1ouQc").OnError(err).Debug("language malformed")
human := &domain.Human{
Profile: &domain.Profile{
FirstName: u.FirstName,
LastName: u.LastName,
NickName: u.NickName,
PreferredLanguage: preferredLanguage,
Gender: genderToDomain(u.Gender),
},
Email: &domain.Email{
EmailAddress: u.Email,
IsEmailVerified: u.IsEmailVerified,
},
Address: &domain.Address{
Country: u.Country,
Locality: u.Locality,
PostalCode: u.PostalCode,
Region: u.Region,
StreetAddress: u.StreetAddress,
},
}
if u.Password != "" {
human.Password = &domain.Password{SecretString: u.Password}
}
if u.Phone != "" {
human.Phone = &domain.Phone{PhoneNumber: u.Phone, IsPhoneVerified: u.IsPhoneVerified}
}
return human
}
func genderToDomain(gender admin.Gender) domain.Gender {
switch gender {
case admin.Gender_GENDER_FEMALE:
return domain.GenderFemale
case admin.Gender_GENDER_MALE:
return domain.GenderMale
case admin.Gender_GENDER_DIVERSE:
return domain.GenderDiverse
default:
return domain.GenderUnspecified
func setUpOrgHumanToDomain(human *admin_grpc.SetUpOrgRequest_Human) *domain.Human {
return &domain.Human{
Username: human.UserName,
Profile: setUpOrgHumanProfileToDomain(human.Profile),
Email: setUpOrgHumanEmailToDomain(human.Email),
Phone: setUpOrgHumanPhoneToDomain(human.Phone),
}
}
func machineCreateToDomain(machine *admin.CreateMachineRequest) *domain.Machine {
return &domain.Machine{
Name: machine.Name,
Description: machine.Description,
func setUpOrgHumanProfileToDomain(profile *admin_grpc.SetUpOrgRequest_Human_Profile) *domain.Profile {
var lang language.Tag
lang, err := language.Parse(profile.PreferredLanguage)
logging.Log("ADMIN-tiMWs").OnError(err).Debug("unable to parse language")
return &domain.Profile{
FirstName: profile.FirstName,
LastName: profile.LastName,
NickName: profile.NickName,
DisplayName: profile.DisplayName,
PreferredLanguage: lang,
Gender: user_grpc.GenderToDomain(profile.Gender),
}
}
func externalIDPViewsToDomain(idps []*usr_model.ExternalIDPView) []*domain.ExternalIDP {
externalIDPs := make([]*domain.ExternalIDP, len(idps))
for i, idp := range idps {
externalIDPs[i] = &domain.ExternalIDP{
ObjectRoot: models.ObjectRoot{
AggregateID: idp.UserID,
ResourceOwner: idp.ResourceOwner,
},
IDPConfigID: idp.IDPConfigID,
ExternalUserID: idp.ExternalUserID,
DisplayName: idp.UserDisplayName,
}
func setUpOrgHumanEmailToDomain(email *admin_grpc.SetUpOrgRequest_Human_Email) *domain.Email {
return &domain.Email{
EmailAddress: email.Email,
IsEmailVerified: email.IsEmailVerified,
}
}
func setUpOrgHumanPhoneToDomain(phone *admin_grpc.SetUpOrgRequest_Human_Phone) *domain.Phone {
return &domain.Phone{
PhoneNumber: phone.Phone,
IsPhoneVerified: phone.IsPhoneVerified,
}
return externalIDPs
}

View File

@@ -0,0 +1,23 @@
package admin
import (
"context"
admin_pb "github.com/caos/zitadel/pkg/grpc/admin"
)
func (s *Server) ListViews(context.Context, *admin_pb.ListViewsRequest) (*admin_pb.ListViewsResponse, error) {
views, err := s.administrator.GetViews()
if err != nil {
return nil, err
}
return &admin_pb.ListViewsResponse{Result: ViewsToPb(views)}, nil
}
func (s *Server) ClearView(ctx context.Context, req *admin_pb.ClearViewRequest) (*admin_pb.ClearViewResponse, error) {
err := s.administrator.ClearView(ctx, req.Database, req.ViewName)
if err != nil {
return nil, err
}
return &admin_pb.ClearViewResponse{}, nil
}

View File

@@ -0,0 +1,32 @@
package admin
import (
"github.com/caos/logging"
"github.com/caos/zitadel/internal/view/model"
admin_pb "github.com/caos/zitadel/pkg/grpc/admin"
"github.com/golang/protobuf/ptypes"
)
func ViewsToPb(views []*model.View) []*admin_pb.View {
v := make([]*admin_pb.View, len(views))
for i, view := range views {
v[i] = ViewToPb(view)
}
return v
}
func ViewToPb(view *model.View) *admin_pb.View {
lastSuccessfulSpoolerRun, err := ptypes.TimestampProto(view.LastSuccessfulSpoolerRun)
logging.Log("ADMIN-4zs01").OnError(err).Debug("unable to parse last successful spooler run")
eventTs, err := ptypes.TimestampProto(view.EventTimestamp)
logging.Log("ADMIN-q2Wzj").OnError(err).Debug("unable to parse event timestamp")
return &admin_pb.View{
Database: view.Database,
ViewName: view.ViewName,
LastSuccessfulSpoolerRun: lastSuccessfulSpoolerRun,
ProcessedSequence: view.CurrentSequence,
EventTimestamp: eventTs,
}
}

View File

@@ -0,0 +1,61 @@
package auth
import (
"context"
"github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/internal/api/grpc/object"
"github.com/caos/zitadel/internal/api/grpc/user"
auth_pb "github.com/caos/zitadel/pkg/grpc/auth"
)
func (s *Server) GetMyEmail(ctx context.Context, _ *auth_pb.GetMyEmailRequest) (*auth_pb.GetMyEmailResponse, error) {
email, err := s.repo.MyEmail(ctx)
if err != nil {
return nil, err
}
return &auth_pb.GetMyEmailResponse{
Email: user.ModelEmailToPb(email),
Details: object.ToDetailsPb(
email.Sequence,
email.ChangeDate,
email.ResourceOwner,
),
}, nil
}
func (s *Server) SetMyEmail(ctx context.Context, req *auth_pb.SetMyEmailRequest) (*auth_pb.SetMyEmailResponse, error) {
email, err := s.command.ChangeHumanEmail(ctx, UpdateMyEmailToDomain(ctx, req))
if err != nil {
return nil, err
}
return &auth_pb.SetMyEmailResponse{
Details: object.ToDetailsPb(
email.Sequence,
email.ChangeDate,
email.ResourceOwner,
),
}, nil
}
func (s *Server) VerifyMyEmail(ctx context.Context, req *auth_pb.VerifyMyEmailRequest) (*auth_pb.VerifyMyEmailResponse, error) {
ctxData := authz.GetCtxData(ctx)
objectDetails, err := s.command.VerifyHumanEmail(ctx, ctxData.UserID, req.Code, ctxData.OrgID)
if err != nil {
return nil, err
}
return &auth_pb.VerifyMyEmailResponse{
Details: object.DomainToDetailsPb(objectDetails),
}, nil
}
func (s *Server) ResendMyEmailVerification(ctx context.Context, _ *auth_pb.ResendMyEmailVerificationRequest) (*auth_pb.ResendMyEmailVerificationResponse, error) {
ctxData := authz.GetCtxData(ctx)
objectDetails, err := s.command.CreateHumanEmailVerificationCode(ctx, ctxData.UserID, ctxData.ResourceOwner)
if err != nil {
return nil, err
}
return &auth_pb.ResendMyEmailVerificationResponse{
Details: object.DomainToDetailsPb(objectDetails),
}, nil
}

View File

@@ -0,0 +1,15 @@
package auth
import (
"context"
"github.com/caos/zitadel/internal/domain"
"github.com/caos/zitadel/pkg/grpc/auth"
)
func UpdateMyEmailToDomain(ctx context.Context, email *auth.SetMyEmailRequest) *domain.Email {
return &domain.Email{
ObjectRoot: ctxToObjectRoot(ctx),
EmailAddress: email.Email,
}
}

View File

@@ -1,50 +0,0 @@
package auth
import (
"strings"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
grpc_util "github.com/caos/zitadel/internal/api/grpc"
"github.com/caos/zitadel/internal/api/grpc/server"
"github.com/caos/zitadel/pkg/grpc/auth"
)
type Gateway struct {
grpcEndpoint string
port string
cutomHeaders []string
}
func StartGateway(conf grpc_util.GatewayConfig) *Gateway {
return &Gateway{
grpcEndpoint: conf.GRPCEndpoint,
port: conf.Port,
cutomHeaders: conf.CustomHeaders,
}
}
func (gw *Gateway) Gateway() server.GatewayFunc {
return auth.RegisterAuthServiceHandlerFromEndpoint
}
func (gw *Gateway) GRPCEndpoint() string {
return ":" + gw.grpcEndpoint
}
func (gw *Gateway) GatewayPort() string {
return gw.port
}
func (gw *Gateway) GatewayServeMuxOptions() []runtime.ServeMuxOption {
return []runtime.ServeMuxOption{
runtime.WithIncomingHeaderMatcher(func(header string) (string, bool) {
for _, customHeader := range gw.cutomHeaders {
if strings.HasPrefix(strings.ToLower(header), customHeader) {
return header, true
}
}
return runtime.DefaultHeaderMatcher(header)
}),
}
}

View File

@@ -0,0 +1,34 @@
package auth
import (
"context"
idp_grpc "github.com/caos/zitadel/internal/api/grpc/idp"
"github.com/caos/zitadel/internal/api/grpc/object"
auth_pb "github.com/caos/zitadel/pkg/grpc/auth"
)
func (s *Server) ListMyLinkedIDPs(ctx context.Context, req *auth_pb.ListMyLinkedIDPsRequest) (*auth_pb.ListMyLinkedIDPsResponse, error) {
idps, err := s.repo.SearchMyExternalIDPs(ctx, ListMyLinkedIDPsRequestToModel(req))
if err != nil {
return nil, err
}
return &auth_pb.ListMyLinkedIDPsResponse{
Result: idp_grpc.IDPsToUserLinkPb(idps.Result),
Details: object.ToListDetails(
idps.TotalResult,
idps.Sequence,
idps.Timestamp,
),
}, nil
}
func (s *Server) RemoveMyLinkedIDP(ctx context.Context, req *auth_pb.RemoveMyLinkedIDPRequest) (*auth_pb.RemoveMyLinkedIDPResponse, error) {
objectDetails, err := s.command.RemoveHumanExternalIDP(ctx, RemoveMyLinkedIDPRequestToDomain(ctx, req))
if err != nil {
return nil, err
}
return &auth_pb.RemoveMyLinkedIDPResponse{
Details: object.DomainToDetailsPb(objectDetails),
}, nil
}

View File

@@ -0,0 +1,24 @@
package auth
import (
"context"
"github.com/caos/zitadel/internal/domain"
"github.com/caos/zitadel/internal/user/model"
auth_pb "github.com/caos/zitadel/pkg/grpc/auth"
)
func ListMyLinkedIDPsRequestToModel(req *auth_pb.ListMyLinkedIDPsRequest) *model.ExternalIDPSearchRequest {
return &model.ExternalIDPSearchRequest{
Offset: req.Query.Offset,
Limit: uint64(req.Query.Limit),
}
}
func RemoveMyLinkedIDPRequestToDomain(ctx context.Context, req *auth_pb.RemoveMyLinkedIDPRequest) *domain.ExternalIDP {
return &domain.ExternalIDP{
ObjectRoot: ctxToObjectRoot(ctx),
IDPConfigID: req.IdpId,
ExternalUserID: req.LinkedUserId,
}
}

View File

@@ -0,0 +1,11 @@
package auth
import (
"context"
"github.com/caos/zitadel/pkg/grpc/auth"
)
func (s *Server) Healthz(context.Context, *auth.HealthzRequest) (*auth.HealthzResponse, error) {
return &auth.HealthzResponse{}, nil
}

View File

@@ -0,0 +1,101 @@
package auth
import (
"context"
"github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/internal/api/grpc/object"
user_grpc "github.com/caos/zitadel/internal/api/grpc/user"
auth_pb "github.com/caos/zitadel/pkg/grpc/auth"
user_pb "github.com/caos/zitadel/pkg/grpc/user"
)
func (s *Server) ListMyAuthFactors(ctx context.Context, _ *auth_pb.ListMyAuthFactorsRequest) (*auth_pb.ListMyAuthFactorsResponse, error) {
mfas, err := s.repo.MyUserMFAs(ctx)
if err != nil {
return nil, err
}
return &auth_pb.ListMyAuthFactorsResponse{
Result: user_grpc.AuthFactorsToPb(mfas),
}, nil
}
func (s *Server) AddMyAuthFactorOTP(ctx context.Context, _ *auth_pb.AddMyAuthFactorOTPRequest) (*auth_pb.AddMyAuthFactorOTPResponse, error) {
ctxData := authz.GetCtxData(ctx)
otp, err := s.command.AddHumanOTP(ctx, ctxData.UserID, ctxData.OrgID)
if err != nil {
return nil, err
}
return &auth_pb.AddMyAuthFactorOTPResponse{
Url: otp.Url,
Secret: otp.SecretString,
Details: object.ToDetailsPb(
otp.Sequence,
otp.ChangeDate,
otp.ResourceOwner,
),
}, nil
}
func (s *Server) VerifyMyAuthFactorOTP(ctx context.Context, req *auth_pb.VerifyMyAuthFactorOTPRequest) (*auth_pb.VerifyMyAuthFactorOTPResponse, error) {
ctxData := authz.GetCtxData(ctx)
objectDetails, err := s.command.HumanCheckMFAOTPSetup(ctx, ctxData.UserID, req.Code, "", ctxData.ResourceOwner)
if err != nil {
return nil, err
}
return &auth_pb.VerifyMyAuthFactorOTPResponse{
Details: object.DomainToDetailsPb(objectDetails),
}, nil
}
func (s *Server) RemoveMyAuthFactorOTP(ctx context.Context, _ *auth_pb.RemoveMyAuthFactorOTPRequest) (*auth_pb.RemoveMyAuthFactorOTPResponse, error) {
ctxData := authz.GetCtxData(ctx)
objectDetails, err := s.command.HumanRemoveOTP(ctx, ctxData.UserID, ctxData.OrgID)
if err != nil {
return nil, err
}
return &auth_pb.RemoveMyAuthFactorOTPResponse{
Details: object.DomainToDetailsPb(objectDetails),
}, nil
}
func (s *Server) AddMyAuthFactorU2F(ctx context.Context, _ *auth_pb.AddMyAuthFactorU2FRequest) (*auth_pb.AddMyAuthFactorU2FResponse, error) {
ctxData := authz.GetCtxData(ctx)
u2f, err := s.command.HumanAddU2FSetup(ctx, ctxData.UserID, ctxData.ResourceOwner, false)
if err != nil {
return nil, err
}
return &auth_pb.AddMyAuthFactorU2FResponse{
Key: &user_pb.WebAuthNKey{
Id: u2f.WebAuthNTokenID,
PublicKey: u2f.CredentialCreationData,
},
Details: object.ToDetailsPb(
u2f.Sequence,
u2f.ChangeDate,
u2f.ResourceOwner,
),
}, nil
}
func (s *Server) VerifyMyAuthFactorU2F(ctx context.Context, req *auth_pb.VerifyMyAuthFactorU2FRequest) (*auth_pb.VerifyMyAuthFactorU2FResponse, error) {
ctxData := authz.GetCtxData(ctx)
objectDetails, err := s.command.HumanVerifyU2FSetup(ctx, ctxData.UserID, ctxData.OrgID, req.Verification.TokenName, "", req.Verification.PublicKeyCredential)
if err != nil {
return nil, err
}
return &auth_pb.VerifyMyAuthFactorU2FResponse{
Details: object.DomainToDetailsPb(objectDetails),
}, nil
}
func (s *Server) RemoveMyAuthFactorU2F(ctx context.Context, req *auth_pb.RemoveMyAuthFactorU2FRequest) (*auth_pb.RemoveMyAuthFactorU2FResponse, error) {
ctxData := authz.GetCtxData(ctx)
objectDetails, err := s.command.HumanRemovePasswordless(ctx, ctxData.UserID, req.TokenId, ctxData.ResourceOwner)
if err != nil {
return nil, err
}
return &auth_pb.RemoveMyAuthFactorU2FResponse{
Details: object.DomainToDetailsPb(objectDetails),
}, nil
}

View File

@@ -0,0 +1,20 @@
package auth
import (
"context"
"github.com/caos/zitadel/internal/api/grpc/object"
"github.com/caos/zitadel/internal/api/authz"
auth_pb "github.com/caos/zitadel/pkg/grpc/auth"
)
func (s *Server) UpdateMyPassword(ctx context.Context, req *auth_pb.UpdateMyPasswordRequest) (*auth_pb.UpdateMyPasswordResponse, error) {
ctxData := authz.GetCtxData(ctx)
objectDetails, err := s.command.ChangePassword(ctx, ctxData.OrgID, ctxData.UserID, req.OldPassword, req.NewPassword, "")
if err != nil {
return nil, err
}
return &auth_pb.UpdateMyPasswordResponse{
Details: object.DomainToDetailsPb(objectDetails),
}, nil
}

View File

@@ -0,0 +1,16 @@
package auth
import (
"context"
policy_grpc "github.com/caos/zitadel/internal/api/grpc/policy"
auth_pb "github.com/caos/zitadel/pkg/grpc/auth"
)
func (s *Server) GetMyPasswordComplexityPolicy(ctx context.Context, _ *auth_pb.GetMyPasswordComplexityPolicyRequest) (*auth_pb.GetMyPasswordComplexityPolicyResponse, error) {
policy, err := s.repo.GetMyPasswordComplexityPolicy(ctx)
if err != nil {
return nil, err
}
return &auth_pb.GetMyPasswordComplexityPolicyResponse{Policy: policy_grpc.ModelPasswordComplexityPolicyToPb(policy)}, nil
}

View File

@@ -0,0 +1,58 @@
package auth
import (
"context"
"github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/internal/api/grpc/object"
user_grpc "github.com/caos/zitadel/internal/api/grpc/user"
auth_pb "github.com/caos/zitadel/pkg/grpc/auth"
)
func (s *Server) ListMyPasswordless(ctx context.Context, _ *auth_pb.ListMyPasswordlessRequest) (*auth_pb.ListMyPasswordlessResponse, error) {
tokens, err := s.repo.GetMyPasswordless(ctx)
if err != nil {
return nil, err
}
return &auth_pb.ListMyPasswordlessResponse{
Result: user_grpc.WebAuthNTokensViewToPb(tokens),
}, nil
}
func (s *Server) AddMyPasswordless(ctx context.Context, _ *auth_pb.AddMyPasswordlessRequest) (*auth_pb.AddMyPasswordlessResponse, error) {
ctxData := authz.GetCtxData(ctx)
u2f, err := s.command.HumanAddPasswordlessSetup(ctx, ctxData.UserID, ctxData.ResourceOwner, false)
if err != nil {
return nil, err
}
return &auth_pb.AddMyPasswordlessResponse{
Key: user_grpc.WebAuthNTokenToWebAuthNKeyPb(u2f),
Details: object.ToDetailsPb(
u2f.Sequence,
u2f.ChangeDate,
u2f.ResourceOwner,
),
}, nil
}
func (s *Server) VerifyMyPasswordless(ctx context.Context, req *auth_pb.VerifyMyPasswordlessRequest) (*auth_pb.VerifyMyPasswordlessResponse, error) {
ctxData := authz.GetCtxData(ctx)
objectDetails, err := s.command.HumanHumanPasswordlessSetup(ctx, ctxData.UserID, ctxData.OrgID, req.Verification.TokenName, "", req.Verification.PublicKeyCredential)
if err != nil {
return nil, err
}
return &auth_pb.VerifyMyPasswordlessResponse{
Details: object.DomainToDetailsPb(objectDetails),
}, nil
}
func (s *Server) RemoveMyPasswordless(ctx context.Context, req *auth_pb.RemoveMyPasswordlessRequest) (*auth_pb.RemoveMyPasswordlessResponse, error) {
ctxData := authz.GetCtxData(ctx)
objectDetails, err := s.command.HumanRemovePasswordless(ctx, ctxData.UserID, req.TokenId, ctxData.ResourceOwner)
if err != nil {
return nil, err
}
return &auth_pb.RemoveMyPasswordlessResponse{
Details: object.DomainToDetailsPb(objectDetails),
}, nil
}

View File

@@ -0,0 +1,27 @@
package auth
import (
"context"
auth_pb "github.com/caos/zitadel/pkg/grpc/auth"
)
func (s *Server) ListMyZitadelPermissions(ctx context.Context, _ *auth_pb.ListMyZitadelPermissionsRequest) (*auth_pb.ListMyZitadelPermissionsResponse, error) {
perms, err := s.repo.SearchMyZitadelPermissions(ctx)
if err != nil {
return nil, err
}
return &auth_pb.ListMyZitadelPermissionsResponse{
Result: perms,
}, nil
}
func (s *Server) ListMyProjectPermissions(ctx context.Context, _ *auth_pb.ListMyProjectPermissionsRequest) (*auth_pb.ListMyProjectPermissionsResponse, error) {
perms, err := s.repo.SearchMyProjectPermissions(ctx)
if err != nil {
return nil, err
}
return &auth_pb.ListMyProjectPermissionsResponse{
Result: perms,
}, nil
}

View File

@@ -0,0 +1,74 @@
package auth
import (
"context"
"github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/internal/api/grpc/object"
"github.com/caos/zitadel/internal/api/grpc/user"
auth_pb "github.com/caos/zitadel/pkg/grpc/auth"
)
func (s *Server) GetMyPhone(ctx context.Context, _ *auth_pb.GetMyPhoneRequest) (*auth_pb.GetMyPhoneResponse, error) {
phone, err := s.repo.MyPhone(ctx)
if err != nil {
return nil, err
}
return &auth_pb.GetMyPhoneResponse{
Phone: user.ModelPhoneToPb(phone),
Details: object.ToDetailsPb(
phone.Sequence,
phone.ChangeDate,
phone.ResourceOwner,
),
}, nil
}
func (s *Server) SetMyPhone(ctx context.Context, req *auth_pb.SetMyPhoneRequest) (*auth_pb.SetMyPhoneResponse, error) {
phone, err := s.command.ChangeHumanPhone(ctx, UpdateMyPhoneToDomain(ctx, req))
if err != nil {
return nil, err
}
return &auth_pb.SetMyPhoneResponse{
Details: object.ToDetailsPb(
phone.Sequence,
phone.ChangeDate,
phone.ResourceOwner,
),
}, nil
}
func (s *Server) VerifyMyPhone(ctx context.Context, req *auth_pb.VerifyMyPhoneRequest) (*auth_pb.VerifyMyPhoneResponse, error) {
ctxData := authz.GetCtxData(ctx)
_, err := s.command.VerifyHumanPhone(ctx, ctxData.UserID, req.Code, ctxData.OrgID)
if err != nil {
return nil, err
}
//TODO: response from business
return &auth_pb.VerifyMyPhoneResponse{
//Details: object.DomainToDetailsPb(objectDetails),
}, nil
}
func (s *Server) ResendMyPhoneVerification(ctx context.Context, _ *auth_pb.ResendMyPhoneVerificationRequest) (*auth_pb.ResendMyPhoneVerificationResponse, error) {
ctxData := authz.GetCtxData(ctx)
objectDetails, err := s.command.CreateHumanPhoneVerificationCode(ctx, ctxData.UserID, ctxData.ResourceOwner)
if err != nil {
return nil, err
}
return &auth_pb.ResendMyPhoneVerificationResponse{
Details: object.DomainToDetailsPb(objectDetails),
}, nil
}
func (s *Server) RemoveMyPhone(ctx context.Context, _ *auth_pb.RemoveMyPhoneRequest) (*auth_pb.RemoveMyPhoneResponse, error) {
ctxData := authz.GetCtxData(ctx)
objectDetails, err := s.command.RemoveHumanPhone(ctx, ctxData.UserID, ctxData.ResourceOwner)
if err != nil {
return nil, err
}
return &auth_pb.RemoveMyPhoneResponse{
Details: object.DomainToDetailsPb(objectDetails),
}, nil
}

View File

@@ -0,0 +1,15 @@
package auth
import (
"context"
"github.com/caos/zitadel/internal/domain"
"github.com/caos/zitadel/pkg/grpc/auth"
)
func UpdateMyPhoneToDomain(ctx context.Context, phone *auth.SetMyPhoneRequest) *domain.Phone {
return &domain.Phone{
ObjectRoot: ctxToObjectRoot(ctx),
PhoneNumber: phone.Phone,
}
}

View File

@@ -1,30 +0,0 @@
package auth
import (
"github.com/caos/logging"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/golang/protobuf/ptypes"
"github.com/caos/zitadel/pkg/grpc/auth"
)
func passwordComplexityPolicyFromModel(policy *iam_model.PasswordComplexityPolicyView) *auth.PasswordComplexityPolicy {
creationDate, err := ptypes.TimestampProto(policy.CreationDate)
logging.Log("GRPC-Lsi3d").OnError(err).Debug("unable to parse timestamp")
changeDate, err := ptypes.TimestampProto(policy.ChangeDate)
logging.Log("GRPC-P0wr4").OnError(err).Debug("unable to parse timestamp")
return &auth.PasswordComplexityPolicy{
Id: policy.AggregateID,
CreationDate: creationDate,
ChangeDate: changeDate,
Sequence: policy.Sequence,
MinLength: policy.MinLength,
HasLowercase: policy.HasLowercase,
HasUppercase: policy.HasUppercase,
HasNumber: policy.HasNumber,
HasSymbol: policy.HasSymbol,
IsDefault: policy.AggregateID == "",
}
}

View File

@@ -1,11 +0,0 @@
package auth
import (
"context"
"github.com/golang/protobuf/ptypes/empty"
)
func (s *Server) Healthz(_ context.Context, e *empty.Empty) (*empty.Empty, error) {
return &empty.Empty{}, nil
}

View File

@@ -0,0 +1,38 @@
package auth
import (
"context"
object_grpc "github.com/caos/zitadel/internal/api/grpc/object"
user_grpc "github.com/caos/zitadel/internal/api/grpc/user"
auth_pb "github.com/caos/zitadel/pkg/grpc/auth"
)
func (s *Server) GetMyProfile(ctx context.Context, req *auth_pb.GetMyProfileRequest) (*auth_pb.GetMyProfileResponse, error) {
profile, err := s.repo.MyProfile(ctx)
if err != nil {
return nil, err
}
return &auth_pb.GetMyProfileResponse{
Profile: user_grpc.ProfileToPb(profile),
Details: object_grpc.ToDetailsPb(
profile.Sequence,
profile.ChangeDate,
profile.ResourceOwner,
),
}, nil
}
func (s *Server) UpdateMyProfile(ctx context.Context, req *auth_pb.UpdateMyProfileRequest) (*auth_pb.UpdateMyProfileResponse, error) {
profile, err := s.command.ChangeHumanProfile(ctx, UpdateProfileToDomain(ctx, req))
if err != nil {
return nil, err
}
return &auth_pb.UpdateMyProfileResponse{
Details: object_grpc.ToDetailsPb(
profile.Sequence,
profile.ChangeDate,
profile.ResourceOwner,
),
}, nil
}

View File

@@ -0,0 +1,25 @@
package auth
import (
"context"
"github.com/caos/logging"
"github.com/caos/zitadel/internal/api/grpc/user"
"github.com/caos/zitadel/internal/domain"
"github.com/caos/zitadel/pkg/grpc/auth"
"golang.org/x/text/language"
)
func UpdateProfileToDomain(ctx context.Context, profile *auth.UpdateMyProfileRequest) *domain.Profile {
lang, err := language.Parse(profile.PreferredLanguage)
logging.Log("AUTH-x19v6").OnError(err).Debug("unable to parse preferred language")
return &domain.Profile{
ObjectRoot: ctxToObjectRoot(ctx),
FirstName: profile.FirstName,
LastName: profile.LastName,
NickName: profile.NickName,
PreferredLanguage: lang,
Gender: user.GenderToDomain(profile.Gender),
}
}

View File

@@ -1,25 +0,0 @@
package auth
import (
"github.com/caos/zitadel/internal/domain"
"github.com/caos/zitadel/pkg/grpc/auth"
)
func searchMethodToModel(method auth.SearchMethod) domain.SearchMethod {
switch method {
case auth.SearchMethod_SEARCHMETHOD_EQUALS:
return domain.SearchMethodEquals
case auth.SearchMethod_SEARCHMETHOD_CONTAINS:
return domain.SearchMethodContains
case auth.SearchMethod_SEARCHMETHOD_STARTS_WITH:
return domain.SearchMethodStartsWith
case auth.SearchMethod_SEARCHMETHOD_EQUALS_IGNORE_CASE:
return domain.SearchMethodEqualsIgnoreCase
case auth.SearchMethod_SEARCHMETHOD_CONTAINS_IGNORE_CASE:
return domain.SearchMethodContainsIgnoreCase
case auth.SearchMethod_SEARCHMETHOD_STARTS_WITH_IGNORE_CASE:
return domain.SearchMethodStartsWithIgnoreCase
default:
return domain.SearchMethodEquals
}
}

View File

@@ -1,15 +1,14 @@
package auth
import (
"github.com/caos/zitadel/internal/command"
"github.com/caos/zitadel/internal/query"
"google.golang.org/grpc"
"github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/internal/api/grpc/server"
"github.com/caos/zitadel/internal/auth/repository"
"github.com/caos/zitadel/internal/auth/repository/eventsourcing"
"github.com/caos/zitadel/internal/command"
"github.com/caos/zitadel/internal/query"
"github.com/caos/zitadel/pkg/grpc/auth"
"google.golang.org/grpc"
)
var _ auth.AuthServiceServer = (*Server)(nil)
@@ -19,6 +18,7 @@ const (
)
type Server struct {
auth.UnimplementedAuthServiceServer
command *command.Commands
query *query.Queries
repo repository.Repository

View File

@@ -2,240 +2,97 @@ package auth
import (
"context"
"github.com/golang/protobuf/ptypes/empty"
"time"
"github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/pkg/grpc/auth"
"github.com/caos/zitadel/internal/api/grpc/change"
"github.com/caos/zitadel/internal/api/grpc/object"
"github.com/caos/zitadel/internal/api/grpc/org"
user_grpc "github.com/caos/zitadel/internal/api/grpc/user"
"github.com/caos/zitadel/internal/eventstore/v1/models"
grant_model "github.com/caos/zitadel/internal/usergrant/model"
auth_pb "github.com/caos/zitadel/pkg/grpc/auth"
)
func (s *Server) GetMyUser(ctx context.Context, _ *empty.Empty) (*auth.UserView, error) {
func (s *Server) GetMyUser(ctx context.Context, _ *auth_pb.GetMyUserRequest) (*auth_pb.GetMyUserResponse, error) {
user, err := s.repo.MyUser(ctx)
if err != nil {
return nil, err
}
return userViewFromModel(user), nil
return &auth_pb.GetMyUserResponse{User: user_grpc.UserToPb(user)}, nil
}
func (s *Server) GetMyUserProfile(ctx context.Context, _ *empty.Empty) (*auth.UserProfileView, error) {
profile, err := s.repo.MyProfile(ctx)
func (s *Server) ListMyUserChanges(ctx context.Context, req *auth_pb.ListMyUserChangesRequest) (*auth_pb.ListMyUserChangesResponse, error) {
changes, err := s.repo.MyUserChanges(ctx, req.Query.Offset, uint64(req.Query.Limit), req.Query.Asc)
if err != nil {
return nil, err
}
return profileViewFromModel(profile), nil
return &auth_pb.ListMyUserChangesResponse{
Result: change.UserChangesToPb(changes.Changes),
}, nil
}
func (s *Server) GetMyUserEmail(ctx context.Context, _ *empty.Empty) (*auth.UserEmailView, error) {
email, err := s.repo.MyEmail(ctx)
func (s *Server) ListMyUserSessions(ctx context.Context, req *auth_pb.ListMyUserSessionsRequest) (*auth_pb.ListMyUserSessionsResponse, error) {
userSessions, err := s.repo.GetMyUserSessions(ctx)
if err != nil {
return nil, err
}
return emailViewFromModel(email), nil
return &auth_pb.ListMyUserSessionsResponse{
Result: user_grpc.UserSessionsToPb(userSessions),
}, nil
}
func (s *Server) GetMyUserPhone(ctx context.Context, _ *empty.Empty) (*auth.UserPhoneView, error) {
phone, err := s.repo.MyPhone(ctx)
if err != nil {
return nil, err
}
return phoneViewFromModel(phone), nil
}
func (s *Server) RemoveMyUserPhone(ctx context.Context, _ *empty.Empty) (*empty.Empty, error) {
func (s *Server) UpdateMyUserName(ctx context.Context, req *auth_pb.UpdateMyUserNameRequest) (*auth_pb.UpdateMyUserNameResponse, error) {
ctxData := authz.GetCtxData(ctx)
err := s.command.RemoveHumanPhone(ctx, ctxData.UserID, ctxData.ResourceOwner)
return &empty.Empty{}, err
}
func (s *Server) GetMyUserAddress(ctx context.Context, _ *empty.Empty) (*auth.UserAddressView, error) {
address, err := s.repo.MyAddress(ctx)
objectDetails, err := s.command.ChangeUsername(ctx, ctxData.ResourceOwner, ctxData.UserID, req.UserName)
if err != nil {
return nil, err
}
return addressViewFromModel(address), nil
return &auth_pb.UpdateMyUserNameResponse{
Details: object.DomainToDetailsPb(objectDetails),
}, nil
}
func (s *Server) GetMyMfas(ctx context.Context, _ *empty.Empty) (*auth.MultiFactors, error) {
mfas, err := s.repo.MyUserMFAs(ctx)
func ctxToObjectRoot(ctx context.Context) models.ObjectRoot {
ctxData := authz.GetCtxData(ctx)
return models.ObjectRoot{
AggregateID: ctxData.UserID,
ResourceOwner: ctxData.ResourceOwner,
}
}
func (s *Server) ListMyUserGrants(ctx context.Context, req *auth_pb.ListMyUserGrantsRequest) (*auth_pb.ListMyUserGrantsResponse, error) {
res, err := s.repo.SearchMyUserGrants(ctx, ListMyUserGrantsRequestToModel(req))
if err != nil {
return nil, err
}
return &auth.MultiFactors{Mfas: mfasFromModel(mfas)}, nil
return &auth_pb.ListMyUserGrantsResponse{
Result: UserGrantsToPb(res.Result),
Details: object.ToListDetails(
res.TotalResult,
res.Sequence,
res.Timestamp,
),
}, nil
}
func (s *Server) UpdateMyUserProfile(ctx context.Context, request *auth.UpdateUserProfileRequest) (*auth.UserProfile, error) {
profile, err := s.command.ChangeHumanProfile(ctx, updateProfileToDomain(ctx, request))
func (s *Server) ListMyProjectOrgs(ctx context.Context, req *auth_pb.ListMyProjectOrgsRequest) (*auth_pb.ListMyProjectOrgsResponse, error) {
res, err := s.repo.SearchMyProjectOrgs(ctx, ListMyProjectOrgsRequestToModel(req))
if err != nil {
return nil, err
}
return profileFromDomain(profile), nil
return &auth_pb.ListMyProjectOrgsResponse{
//TODO: not all details
Details: object.ToListDetails(res.TotalResult, 0, time.Time{}),
Result: org.OrgsToPb(res.Result),
}, nil
}
func (s *Server) ChangeMyUserName(ctx context.Context, request *auth.ChangeUserNameRequest) (*empty.Empty, error) {
ctxData := authz.GetCtxData(ctx)
return &empty.Empty{}, s.command.ChangeUsername(ctx, ctxData.ResourceOwner, ctxData.UserID, request.UserName)
}
func (s *Server) ChangeMyUserEmail(ctx context.Context, request *auth.UpdateUserEmailRequest) (*auth.UserEmail, error) {
email, err := s.command.ChangeHumanEmail(ctx, updateEmailToDomain(ctx, request))
if err != nil {
return nil, err
func ListMyProjectOrgsRequestToModel(req *auth_pb.ListMyProjectOrgsRequest) *grant_model.UserGrantSearchRequest {
return &grant_model.UserGrantSearchRequest{
Offset: req.Query.Offset,
Limit: uint64(req.Query.Limit),
Asc: req.Query.Asc,
// Queries: queries,//TODO:user grant queries missing in proto
}
return emailFromDomain(email), nil
}
func (s *Server) VerifyMyUserEmail(ctx context.Context, request *auth.VerifyMyUserEmailRequest) (*empty.Empty, error) {
ctxData := authz.GetCtxData(ctx)
err := s.command.VerifyHumanEmail(ctx, ctxData.UserID, request.Code, ctxData.OrgID)
return &empty.Empty{}, err
}
func (s *Server) ResendMyEmailVerificationMail(ctx context.Context, _ *empty.Empty) (*empty.Empty, error) {
ctxData := authz.GetCtxData(ctx)
err := s.command.CreateHumanEmailVerificationCode(ctx, ctxData.UserID, ctxData.ResourceOwner)
return &empty.Empty{}, err
}
func (s *Server) ChangeMyUserPhone(ctx context.Context, request *auth.UpdateUserPhoneRequest) (*auth.UserPhone, error) {
phone, err := s.command.ChangeHumanPhone(ctx, updatePhoneToDomain(ctx, request))
if err != nil {
return nil, err
}
return phoneFromDomain(phone), nil
}
func (s *Server) VerifyMyUserPhone(ctx context.Context, request *auth.VerifyUserPhoneRequest) (*empty.Empty, error) {
ctxData := authz.GetCtxData(ctx)
err := s.command.VerifyHumanPhone(ctx, ctxData.UserID, request.Code, ctxData.ResourceOwner)
return &empty.Empty{}, err
}
func (s *Server) ResendMyPhoneVerificationCode(ctx context.Context, _ *empty.Empty) (*empty.Empty, error) {
ctxData := authz.GetCtxData(ctx)
err := s.command.CreateHumanPhoneVerificationCode(ctx, ctxData.UserID, ctxData.ResourceOwner)
return &empty.Empty{}, err
}
func (s *Server) UpdateMyUserAddress(ctx context.Context, request *auth.UpdateUserAddressRequest) (*auth.UserAddress, error) {
address, err := s.command.ChangeHumanAddress(ctx, updateAddressToDomain(ctx, request))
if err != nil {
return nil, err
}
return addressFromDomain(address), nil
}
func (s *Server) ChangeMyPassword(ctx context.Context, request *auth.PasswordChange) (*empty.Empty, error) {
ctxData := authz.GetCtxData(ctx)
err := s.command.ChangePassword(ctx, ctxData.OrgID, ctxData.UserID, request.OldPassword, request.NewPassword, "")
return &empty.Empty{}, err
}
func (s *Server) SearchMyExternalIDPs(ctx context.Context, request *auth.ExternalIDPSearchRequest) (*auth.ExternalIDPSearchResponse, error) {
externalIDP, err := s.repo.SearchMyExternalIDPs(ctx, externalIDPSearchRequestToModel(request))
if err != nil {
return nil, err
}
return externalIDPSearchResponseFromModel(externalIDP), nil
}
func (s *Server) RemoveMyExternalIDP(ctx context.Context, request *auth.ExternalIDPRemoveRequest) (*empty.Empty, error) {
err := s.command.RemoveHumanExternalIDP(ctx, externalIDPRemoveToDomain(ctx, request))
return &empty.Empty{}, err
}
func (s *Server) GetMyPasswordComplexityPolicy(ctx context.Context, _ *empty.Empty) (*auth.PasswordComplexityPolicy, error) {
policy, err := s.repo.GetMyPasswordComplexityPolicy(ctx)
if err != nil {
return nil, err
}
return passwordComplexityPolicyFromModel(policy), nil
}
func (s *Server) AddMfaOTP(ctx context.Context, _ *empty.Empty) (_ *auth.MfaOtpResponse, err error) {
ctxData := authz.GetCtxData(ctx)
otp, err := s.command.AddHumanOTP(ctx, ctxData.UserID, ctxData.OrgID)
if err != nil {
return nil, err
}
return otpFromDomain(otp), nil
}
func (s *Server) VerifyMfaOTP(ctx context.Context, request *auth.VerifyMfaOtp) (*empty.Empty, error) {
ctxData := authz.GetCtxData(ctx)
err := s.command.HumanCheckMFAOTPSetup(ctx, ctxData.UserID, request.Code, "", ctxData.ResourceOwner)
return &empty.Empty{}, err
}
func (s *Server) RemoveMfaOTP(ctx context.Context, _ *empty.Empty) (_ *empty.Empty, err error) {
ctxData := authz.GetCtxData(ctx)
err = s.command.HumanRemoveOTP(ctx, ctxData.UserID, ctxData.OrgID)
return &empty.Empty{}, err
}
func (s *Server) AddMyMfaU2F(ctx context.Context, _ *empty.Empty) (_ *auth.WebAuthNResponse, err error) {
ctxData := authz.GetCtxData(ctx)
u2f, err := s.command.HumanAddU2FSetup(ctx, ctxData.UserID, ctxData.ResourceOwner, false)
if err != nil {
return nil, err
}
return verifyWebAuthNFromDomain(u2f), err
}
func (s *Server) VerifyMyMfaU2F(ctx context.Context, request *auth.VerifyWebAuthN) (*empty.Empty, error) {
ctxData := authz.GetCtxData(ctx)
err := s.command.HumanVerifyU2FSetup(ctx, ctxData.UserID, ctxData.OrgID, request.TokenName, "", request.PublicKeyCredential)
return &empty.Empty{}, err
}
func (s *Server) RemoveMyMfaU2F(ctx context.Context, id *auth.WebAuthNTokenID) (*empty.Empty, error) {
ctxData := authz.GetCtxData(ctx)
err := s.command.HumanRemoveU2F(ctx, ctxData.UserID, id.Id, ctxData.OrgID)
return &empty.Empty{}, err
}
func (s *Server) GetMyPasswordless(ctx context.Context, _ *empty.Empty) (_ *auth.WebAuthNTokens, err error) {
tokens, err := s.repo.GetMyPasswordless(ctx)
if err != nil {
return nil, err
}
return webAuthNTokensFromModel(tokens), err
}
func (s *Server) AddMyPasswordless(ctx context.Context, _ *empty.Empty) (_ *auth.WebAuthNResponse, err error) {
ctxData := authz.GetCtxData(ctx)
u2f, err := s.command.HumanAddPasswordlessSetup(ctx, ctxData.UserID, ctxData.ResourceOwner, false)
if err != nil {
return nil, err
}
return verifyWebAuthNFromDomain(u2f), err
}
func (s *Server) VerifyMyPasswordless(ctx context.Context, request *auth.VerifyWebAuthN) (*empty.Empty, error) {
ctxData := authz.GetCtxData(ctx)
err := s.command.HumanHumanPasswordlessSetup(ctx, ctxData.UserID, ctxData.OrgID, request.TokenName, "", request.PublicKeyCredential)
return &empty.Empty{}, err
}
func (s *Server) RemoveMyPasswordless(ctx context.Context, id *auth.WebAuthNTokenID) (*empty.Empty, error) {
ctxData := authz.GetCtxData(ctx)
err := s.command.HumanRemovePasswordless(ctx, ctxData.UserID, id.Id, ctxData.ResourceOwner)
return &empty.Empty{}, err
}
func (s *Server) GetMyUserChanges(ctx context.Context, request *auth.ChangesRequest) (*auth.Changes, error) {
changes, err := s.repo.MyUserChanges(ctx, request.SequenceOffset, request.Limit, request.Asc)
if err != nil {
return nil, err
}
return userChangesToResponse(changes, request.GetSequenceOffset(), request.GetLimit()), nil
}
func (s *Server) SearchMyUserMemberships(ctx context.Context, in *auth.UserMembershipSearchRequest) (*auth.UserMembershipSearchResponse, error) {
request := userMembershipSearchRequestsToModel(in)
request.AppendUserIDQuery(authz.GetCtxData(ctx).UserID)
response, err := s.repo.SearchMyUserMemberships(ctx, request)
if err != nil {
return nil, err
}
return userMembershipSearchResponseFromModel(response), nil
}

View File

@@ -1,565 +0,0 @@
package auth
import (
"context"
"encoding/json"
"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/domain"
"github.com/caos/zitadel/internal/eventstore/v1/models"
"github.com/caos/zitadel/internal/telemetry/tracing"
usr_model "github.com/caos/zitadel/internal/user/model"
"github.com/caos/zitadel/pkg/grpc/auth"
"github.com/caos/zitadel/pkg/grpc/message"
)
func userViewFromModel(user *usr_model.UserView) *auth.UserView {
creationDate, err := ptypes.TimestampProto(user.CreationDate)
logging.Log("GRPC-sd32g").OnError(err).Debug("unable to parse timestamp")
changeDate, err := ptypes.TimestampProto(user.ChangeDate)
logging.Log("GRPC-FJKq1").OnError(err).Debug("unable to parse timestamp")
lastLogin, err := ptypes.TimestampProto(user.LastLogin)
logging.Log("GRPC-Gteh2").OnError(err).Debug("unable to parse timestamp")
userView := &auth.UserView{
Id: user.ID,
State: userStateFromModel(user.State),
CreationDate: creationDate,
ChangeDate: changeDate,
LastLogin: lastLogin,
UserName: user.UserName,
Sequence: user.Sequence,
ResourceOwner: user.ResourceOwner,
LoginNames: user.LoginNames,
PreferredLoginName: user.PreferredLoginName,
}
if user.HumanView != nil {
userView.User = &auth.UserView_Human{Human: humanViewFromModel(user.HumanView)}
}
if user.MachineView != nil {
userView.User = &auth.UserView_Machine{Machine: machineViewFromModel(user.MachineView)}
}
return userView
}
func profileFromDomain(profile *domain.Profile) *auth.UserProfile {
creationDate, err := ptypes.TimestampProto(profile.CreationDate)
logging.Log("GRPC-56t5s").OnError(err).Debug("unable to parse timestamp")
changeDate, err := ptypes.TimestampProto(profile.ChangeDate)
logging.Log("GRPC-K58ds").OnError(err).Debug("unable to parse timestamp")
return &auth.UserProfile{
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: genderFromDomain(profile.Gender),
}
}
func profileViewFromModel(profile *usr_model.Profile) *auth.UserProfileView {
creationDate, err := ptypes.TimestampProto(profile.CreationDate)
logging.Log("GRPC-s9iKs").OnError(err).Debug("unable to parse timestamp")
changeDate, err := ptypes.TimestampProto(profile.ChangeDate)
logging.Log("GRPC-9sujE").OnError(err).Debug("unable to parse timestamp")
return &auth.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: genderFromModel(profile.Gender),
LoginNames: profile.LoginNames,
PreferredLoginName: profile.PreferredLoginName,
}
}
func updateProfileToDomain(ctx context.Context, u *auth.UpdateUserProfileRequest) *domain.Profile {
preferredLanguage, err := language.Parse(u.PreferredLanguage)
logging.Log("GRPC-lk73L").OnError(err).WithField("traceID", tracing.TraceIDFromCtx(ctx)).Debug("language malformed")
return &domain.Profile{
ObjectRoot: ctxToObjectRoot(ctx),
FirstName: u.FirstName,
LastName: u.LastName,
NickName: u.NickName,
PreferredLanguage: preferredLanguage,
Gender: genderToDomain(u.Gender),
}
}
func emailFromDomain(email *domain.Email) *auth.UserEmail {
creationDate, err := ptypes.TimestampProto(email.CreationDate)
logging.Log("GRPC-sdoi3").OnError(err).Debug("unable to parse timestamp")
changeDate, err := ptypes.TimestampProto(email.ChangeDate)
logging.Log("GRPC-klJK3").OnError(err).Debug("unable to parse timestamp")
return &auth.UserEmail{
Id: email.AggregateID,
CreationDate: creationDate,
ChangeDate: changeDate,
Sequence: email.Sequence,
Email: email.EmailAddress,
IsEmailVerified: email.IsEmailVerified,
}
}
func emailViewFromModel(email *usr_model.Email) *auth.UserEmailView {
creationDate, err := ptypes.TimestampProto(email.CreationDate)
logging.Log("GRPC-LSp8s").OnError(err).Debug("unable to parse timestamp")
changeDate, err := ptypes.TimestampProto(email.ChangeDate)
logging.Log("GRPC-6szJe").OnError(err).Debug("unable to parse timestamp")
return &auth.UserEmailView{
Id: email.AggregateID,
CreationDate: creationDate,
ChangeDate: changeDate,
Sequence: email.Sequence,
Email: email.EmailAddress,
IsEmailVerified: email.IsEmailVerified,
}
}
func updateEmailToDomain(ctx context.Context, e *auth.UpdateUserEmailRequest) *domain.Email {
return &domain.Email{
ObjectRoot: ctxToObjectRoot(ctx),
EmailAddress: e.Email,
}
}
func phoneFromDomain(phone *domain.Phone) *auth.UserPhone {
creationDate, err := ptypes.TimestampProto(phone.CreationDate)
logging.Log("GRPC-kjn5J").OnError(err).Debug("unable to parse timestamp")
changeDate, err := ptypes.TimestampProto(phone.ChangeDate)
logging.Log("GRPC-LKA9S").OnError(err).Debug("unable to parse timestamp")
return &auth.UserPhone{
Id: phone.AggregateID,
CreationDate: creationDate,
ChangeDate: changeDate,
Sequence: phone.Sequence,
Phone: phone.PhoneNumber,
IsPhoneVerified: phone.IsPhoneVerified,
}
}
func phoneViewFromModel(phone *usr_model.Phone) *auth.UserPhoneView {
creationDate, err := ptypes.TimestampProto(phone.CreationDate)
logging.Log("GRPC-s5zJS").OnError(err).Debug("unable to parse timestamp")
changeDate, err := ptypes.TimestampProto(phone.ChangeDate)
logging.Log("GRPC-s9kLe").OnError(err).Debug("unable to parse timestamp")
return &auth.UserPhoneView{
Id: phone.AggregateID,
CreationDate: creationDate,
ChangeDate: changeDate,
Sequence: phone.Sequence,
Phone: phone.PhoneNumber,
IsPhoneVerified: phone.IsPhoneVerified,
}
}
func updatePhoneToDomain(ctx context.Context, e *auth.UpdateUserPhoneRequest) *domain.Phone {
return &domain.Phone{
ObjectRoot: ctxToObjectRoot(ctx),
PhoneNumber: e.Phone,
}
}
func addressFromDomain(address *domain.Address) *auth.UserAddress {
creationDate, err := ptypes.TimestampProto(address.CreationDate)
logging.Log("GRPC-65FRs").OnError(err).Debug("unable to parse timestamp")
changeDate, err := ptypes.TimestampProto(address.ChangeDate)
logging.Log("GRPC-aslk4").OnError(err).Debug("unable to parse timestamp")
return &auth.UserAddress{
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 addressViewFromModel(address *usr_model.Address) *auth.UserAddressView {
creationDate, err := ptypes.TimestampProto(address.CreationDate)
logging.Log("GRPC-sk4fS").OnError(err).Debug("unable to parse timestamp")
changeDate, err := ptypes.TimestampProto(address.ChangeDate)
logging.Log("GRPC-9siEs").OnError(err).Debug("unable to parse timestamp")
return &auth.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(ctx context.Context, address *auth.UpdateUserAddressRequest) *domain.Address {
return &domain.Address{
ObjectRoot: ctxToObjectRoot(ctx),
Country: address.Country,
StreetAddress: address.StreetAddress,
Region: address.Region,
PostalCode: address.PostalCode,
Locality: address.Locality,
}
}
func externalIDPSearchRequestToModel(request *auth.ExternalIDPSearchRequest) *usr_model.ExternalIDPSearchRequest {
return &usr_model.ExternalIDPSearchRequest{
Limit: request.Limit,
Offset: request.Offset,
}
}
func externalIDPRemoveToDomain(ctx context.Context, idp *auth.ExternalIDPRemoveRequest) *domain.ExternalIDP {
return &domain.ExternalIDP{
ObjectRoot: ctxToObjectRoot(ctx),
IDPConfigID: idp.IdpConfigId,
ExternalUserID: idp.ExternalUserId,
}
}
func externalIDPResponseFromModel(idp *usr_model.ExternalIDP) *auth.ExternalIDPResponse {
return &auth.ExternalIDPResponse{
IdpConfigId: idp.IDPConfigID,
UserId: idp.UserID,
DisplayName: idp.DisplayName,
}
}
func externalIDPSearchResponseFromModel(response *usr_model.ExternalIDPSearchResponse) *auth.ExternalIDPSearchResponse {
viewTimestamp, err := ptypes.TimestampProto(response.Timestamp)
logging.Log("GRPC-3h8is").OnError(err).Debug("unable to parse timestamp")
return &auth.ExternalIDPSearchResponse{
Offset: response.Offset,
Limit: response.Limit,
TotalResult: response.TotalResult,
ProcessedSequence: response.Sequence,
ViewTimestamp: viewTimestamp,
Result: externalIDPViewsFromModel(response.Result),
}
}
func externalIDPViewsFromModel(externalIDPs []*usr_model.ExternalIDPView) []*auth.ExternalIDPView {
converted := make([]*auth.ExternalIDPView, len(externalIDPs))
for i, externalIDP := range externalIDPs {
converted[i] = externalIDPViewFromModel(externalIDP)
}
return converted
}
func externalIDPViewFromModel(externalIDP *usr_model.ExternalIDPView) *auth.ExternalIDPView {
creationDate, err := ptypes.TimestampProto(externalIDP.CreationDate)
logging.Log("GRPC-Sj8dw").OnError(err).Debug("unable to parse timestamp")
changeDate, err := ptypes.TimestampProto(externalIDP.ChangeDate)
logging.Log("GRPC-Nf8ue").OnError(err).Debug("unable to parse timestamp")
return &auth.ExternalIDPView{
UserId: externalIDP.UserID,
IdpConfigId: externalIDP.IDPConfigID,
ExternalUserId: externalIDP.ExternalUserID,
ExternalUserDisplayName: externalIDP.UserDisplayName,
IdpName: externalIDP.IDPName,
CreationDate: creationDate,
ChangeDate: changeDate,
}
}
func otpFromDomain(otp *domain.OTP) *auth.MfaOtpResponse {
return &auth.MfaOtpResponse{
UserId: otp.AggregateID,
Url: otp.Url,
Secret: otp.SecretString,
State: mfaStateFromDomain(otp.State),
}
}
func userStateFromModel(state usr_model.UserState) auth.UserState {
switch state {
case usr_model.UserStateActive:
return auth.UserState_USERSTATE_ACTIVE
case usr_model.UserStateInactive:
return auth.UserState_USERSTATE_INACTIVE
case usr_model.UserStateLocked:
return auth.UserState_USERSTATE_LOCKED
case usr_model.UserStateInitial:
return auth.UserState_USERSTATE_INITIAL
case usr_model.UserStateSuspend:
return auth.UserState_USERSTATE_SUSPEND
default:
return auth.UserState_USERSTATE_UNSPECIFIED
}
}
func genderFromDomain(gender domain.Gender) auth.Gender {
switch gender {
case domain.GenderFemale:
return auth.Gender_GENDER_FEMALE
case domain.GenderMale:
return auth.Gender_GENDER_MALE
case domain.GenderDiverse:
return auth.Gender_GENDER_DIVERSE
default:
return auth.Gender_GENDER_UNSPECIFIED
}
}
func genderFromModel(gender usr_model.Gender) auth.Gender {
switch gender {
case usr_model.GenderFemale:
return auth.Gender_GENDER_FEMALE
case usr_model.GenderMale:
return auth.Gender_GENDER_MALE
case usr_model.GenderDiverse:
return auth.Gender_GENDER_DIVERSE
default:
return auth.Gender_GENDER_UNSPECIFIED
}
}
func genderToDomain(gender auth.Gender) domain.Gender {
switch gender {
case auth.Gender_GENDER_FEMALE:
return domain.GenderFemale
case auth.Gender_GENDER_MALE:
return domain.GenderMale
case auth.Gender_GENDER_DIVERSE:
return domain.GenderDiverse
default:
return domain.GenderUnspecified
}
}
func mfaStateFromDomain(state domain.MFAState) auth.MFAState {
switch state {
case domain.MFAStateReady:
return auth.MFAState_MFASTATE_READY
case domain.MFAStateNotReady:
return auth.MFAState_MFASTATE_NOT_READY
default:
return auth.MFAState_MFASTATE_UNSPECIFIED
}
}
func mfasFromModel(mfas []*usr_model.MultiFactor) []*auth.MultiFactor {
converted := make([]*auth.MultiFactor, len(mfas))
for i, mfa := range mfas {
converted[i] = mfaFromModel(mfa)
}
return converted
}
func mfaFromModel(mfa *usr_model.MultiFactor) *auth.MultiFactor {
return &auth.MultiFactor{
State: auth.MFAState(mfa.State),
Type: mfaTypeFromModel(mfa.Type),
Attribute: mfa.Attribute,
Id: mfa.ID,
}
}
func mfaTypeFromModel(mfaType usr_model.MFAType) auth.MfaType {
switch mfaType {
case usr_model.MFATypeOTP:
return auth.MfaType_MFATYPE_OTP
case usr_model.MFATypeU2F:
return auth.MfaType_MFATYPE_U2F
default:
return auth.MfaType_MFATYPE_UNSPECIFIED
}
}
func userChangesToResponse(response *usr_model.UserChanges, offset uint64, limit uint64) (_ *auth.Changes) {
return &auth.Changes{
Limit: limit,
Offset: offset,
Changes: userChangesToAPI(response),
}
}
func userChangesToAPI(changes *usr_model.UserChanges) (_ []*auth.Change) {
result := make([]*auth.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-0kRsY").OnError(err).Debug("unable to marshal changed data to struct")
}
result[i] = &auth.Change{
ChangeDate: change.ChangeDate,
EventType: message.NewLocalizedEventType(change.EventType),
Sequence: change.Sequence,
Data: data,
EditorId: change.ModifierID,
Editor: change.ModifierName,
}
}
return result
}
func verifyWebAuthNFromDomain(u2f *domain.WebAuthNToken) *auth.WebAuthNResponse {
return &auth.WebAuthNResponse{
Id: u2f.WebAuthNTokenID,
PublicKey: u2f.CredentialCreationData,
State: mfaStateFromDomain(u2f.State),
}
}
func webAuthNTokensFromModel(tokens []*usr_model.WebAuthNView) *auth.WebAuthNTokens {
result := make([]*auth.WebAuthNToken, len(tokens))
for i, token := range tokens {
result[i] = webAuthNTokenFromModel(token)
}
return &auth.WebAuthNTokens{Tokens: result}
}
func webAuthNTokenFromModel(token *usr_model.WebAuthNView) *auth.WebAuthNToken {
return &auth.WebAuthNToken{
Id: token.TokenID,
Name: token.Name,
State: auth.MFAState(token.State),
}
}
func ctxToObjectRoot(ctx context.Context) models.ObjectRoot {
ctxData := authz.GetCtxData(ctx)
return models.ObjectRoot{
AggregateID: ctxData.UserID,
ResourceOwner: ctxData.ResourceOwner,
}
}
func userMembershipSearchResponseFromModel(response *usr_model.UserMembershipSearchResponse) *auth.UserMembershipSearchResponse {
timestamp, err := ptypes.TimestampProto(response.Timestamp)
logging.Log("GRPC-Hs8jd").OnError(err).Debug("unable to parse timestamp")
return &auth.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) []*auth.UserMembershipView {
converted := make([]*auth.UserMembershipView, len(memberships))
for i, membership := range memberships {
converted[i] = userMembershipViewFromModel(membership)
}
return converted
}
func userMembershipViewFromModel(membership *usr_model.UserMembershipView) *auth.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 &auth.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 userMembershipSearchRequestsToModel(request *auth.UserMembershipSearchRequest) *usr_model.UserMembershipSearchRequest {
return &usr_model.UserMembershipSearchRequest{
Offset: request.Offset,
Limit: request.Limit,
Queries: userMembershipSearchQueriesToModel(request.Queries),
}
}
func userMembershipSearchQueriesToModel(queries []*auth.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 *auth.UserMembershipSearchQuery) *usr_model.UserMembershipSearchQuery {
return &usr_model.UserMembershipSearchQuery{
Key: userMembershipSearchKeyToModel(query.Key),
Method: searchMethodToModel(query.Method),
Value: query.Value,
}
}
func userMembershipSearchKeyToModel(key auth.UserMembershipSearchKey) usr_model.UserMembershipSearchKey {
switch key {
case auth.UserMembershipSearchKey_USERMEMBERSHIPSEARCHKEY_TYPE:
return usr_model.UserMembershipSearchKeyMemberType
case auth.UserMembershipSearchKey_USERMEMBERSHIPSEARCHKEY_OBJECT_ID:
return usr_model.UserMembershipSearchKeyObjectID
default:
return usr_model.UserMembershipSearchKeyUnspecified
}
}
func memberTypeFromModel(memberType usr_model.MemberType) auth.MemberType {
switch memberType {
case usr_model.MemberTypeOrganisation:
return auth.MemberType_MEMBERTYPE_ORGANISATION
case usr_model.MemberTypeProject:
return auth.MemberType_MEMBERTYPE_PROJECT
case usr_model.MemberTypeProjectGrant:
return auth.MemberType_MEMBERTYPE_PROJECT_GRANT
default:
return auth.MemberType_MEMBERTYPE_UNSPECIFIED
}
}

View File

@@ -1,41 +1,33 @@
package auth
import (
"context"
"github.com/golang/protobuf/ptypes/empty"
"github.com/caos/zitadel/pkg/grpc/auth"
"github.com/caos/zitadel/internal/usergrant/model"
auth_pb "github.com/caos/zitadel/pkg/grpc/auth"
)
func (s *Server) SearchMyUserGrant(ctx context.Context, in *auth.UserGrantSearchRequest) (*auth.UserGrantSearchResponse, error) {
response, err := s.repo.SearchMyUserGrants(ctx, userGrantSearchRequestsToModel(in))
if err != nil {
return nil, err
func ListMyUserGrantsRequestToModel(req *auth_pb.ListMyUserGrantsRequest) *model.UserGrantSearchRequest {
return &model.UserGrantSearchRequest{
Offset: req.Query.Offset,
Limit: uint64(req.Query.Limit),
Asc: req.Query.Asc,
}
return userGrantSearchResponseFromModel(response), nil
}
func (s *Server) SearchMyProjectOrgs(ctx context.Context, in *auth.MyProjectOrgSearchRequest) (*auth.MyProjectOrgSearchResponse, error) {
response, err := s.repo.SearchMyProjectOrgs(ctx, myProjectOrgSearchRequestRequestsToModel(in))
if err != nil {
return nil, err
func UserGrantsToPb(grants []*model.UserGrantView) []*auth_pb.UserGrant {
userGrants := make([]*auth_pb.UserGrant, len(grants))
for i, grant := range grants {
userGrants[i] = UserGrantToPb(grant)
}
return projectOrgSearchResponseFromModel(response), nil
return userGrants
}
func (s *Server) GetMyZitadelPermissions(ctx context.Context, _ *empty.Empty) (*auth.MyPermissions, error) {
perms, err := s.repo.SearchMyZitadelPermissions(ctx)
if err != nil {
return nil, err
func UserGrantToPb(grant *model.UserGrantView) *auth_pb.UserGrant {
return &auth_pb.UserGrant{
GrantId: grant.ID,
OrgId: grant.ResourceOwner,
OrgName: grant.OrgName,
ProjectId: grant.ProjectID,
UserId: grant.UserID,
Roles: grant.RoleKeys,
}
return &auth.MyPermissions{Permissions: perms}, nil
}
func (s *Server) GetMyProjectPermissions(ctx context.Context, _ *empty.Empty) (*auth.MyPermissions, error) {
perms, err := s.repo.SearchMyProjectPermissions(ctx)
if err != nil {
return nil, err
}
return &auth.MyPermissions{Permissions: perms}, nil
}

View File

@@ -1,135 +0,0 @@
package auth
import (
"github.com/caos/logging"
grant_model "github.com/caos/zitadel/internal/usergrant/model"
"github.com/caos/zitadel/pkg/grpc/auth"
"github.com/golang/protobuf/ptypes"
)
func userGrantSearchRequestsToModel(request *auth.UserGrantSearchRequest) *grant_model.UserGrantSearchRequest {
return &grant_model.UserGrantSearchRequest{
Offset: request.Offset,
Limit: request.Limit,
Queries: userGrantSearchQueriesToModel(request.Queries),
}
}
func userGrantSearchQueriesToModel(queries []*auth.UserGrantSearchQuery) []*grant_model.UserGrantSearchQuery {
converted := make([]*grant_model.UserGrantSearchQuery, len(queries))
for i, q := range queries {
converted[i] = userGrantSearchQueryToModel(q)
}
return converted
}
func userGrantSearchQueryToModel(query *auth.UserGrantSearchQuery) *grant_model.UserGrantSearchQuery {
return &grant_model.UserGrantSearchQuery{
Key: userGrantSearchKeyToModel(query.Key),
Method: searchMethodToModel(query.Method),
Value: query.Value,
}
}
func userGrantSearchKeyToModel(key auth.UserGrantSearchKey) grant_model.UserGrantSearchKey {
switch key {
case auth.UserGrantSearchKey_UserGrantSearchKey_ORG_ID:
return grant_model.UserGrantSearchKeyResourceOwner
case auth.UserGrantSearchKey_UserGrantSearchKey_PROJECT_ID:
return grant_model.UserGrantSearchKeyProjectID
default:
return grant_model.UserGrantSearchKeyUnspecified
}
}
func myProjectOrgSearchRequestRequestsToModel(request *auth.MyProjectOrgSearchRequest) *grant_model.UserGrantSearchRequest {
return &grant_model.UserGrantSearchRequest{
Offset: request.Offset,
Limit: request.Limit,
Asc: request.Asc,
SortingColumn: grant_model.UserGrantSearchKeyResourceOwner,
Queries: myProjectOrgSearchQueriesToModel(request.Queries),
}
}
func myProjectOrgSearchQueriesToModel(queries []*auth.MyProjectOrgSearchQuery) []*grant_model.UserGrantSearchQuery {
converted := make([]*grant_model.UserGrantSearchQuery, len(queries))
for i, q := range queries {
converted[i] = myProjectOrgSearchQueryToModel(q)
}
return converted
}
func myProjectOrgSearchQueryToModel(query *auth.MyProjectOrgSearchQuery) *grant_model.UserGrantSearchQuery {
return &grant_model.UserGrantSearchQuery{
Key: myProjectOrgSearchKeyToModel(query.Key),
Method: searchMethodToModel(query.Method),
Value: query.Value,
}
}
func myProjectOrgSearchKeyToModel(key auth.MyProjectOrgSearchKey) grant_model.UserGrantSearchKey {
switch key {
case auth.MyProjectOrgSearchKey_MYPROJECTORGSEARCHKEY_ORG_NAME:
return grant_model.UserGrantSearchKeyOrgName
default:
return grant_model.UserGrantSearchKeyUnspecified
}
}
func userGrantSearchResponseFromModel(response *grant_model.UserGrantSearchResponse) *auth.UserGrantSearchResponse {
timestamp, err := ptypes.TimestampProto(response.Timestamp)
logging.Log("GRPC-Lsp0d").OnError(err).Debug("unable to parse timestamp")
return &auth.UserGrantSearchResponse{
Offset: response.Offset,
Limit: response.Limit,
TotalResult: response.TotalResult,
Result: userGrantViewsFromModel(response.Result),
ProcessedSequence: response.Sequence,
ViewTimestamp: timestamp,
}
}
func userGrantViewsFromModel(users []*grant_model.UserGrantView) []*auth.UserGrantView {
converted := make([]*auth.UserGrantView, len(users))
for i, user := range users {
converted[i] = userGrantViewFromModel(user)
}
return converted
}
func userGrantViewFromModel(grant *grant_model.UserGrantView) *auth.UserGrantView {
return &auth.UserGrantView{
UserId: grant.UserID,
OrgId: grant.ResourceOwner,
OrgName: grant.OrgName,
ProjectId: grant.ProjectID,
Roles: grant.RoleKeys,
GrantId: grant.GrantID,
}
}
func projectOrgSearchResponseFromModel(response *grant_model.ProjectOrgSearchResponse) *auth.MyProjectOrgSearchResponse {
return &auth.MyProjectOrgSearchResponse{
Offset: response.Offset,
Limit: response.Limit,
TotalResult: response.TotalResult,
Result: projectOrgsFromModel(response.Result),
}
}
func projectOrgsFromModel(projectOrgs []*grant_model.Org) []*auth.Org {
converted := make([]*auth.Org, len(projectOrgs))
for i, org := range projectOrgs {
converted[i] = projectOrgFromModel(org)
}
return converted
}
func projectOrgFromModel(org *grant_model.Org) *auth.Org {
return &auth.Org{
Id: org.OrgID,
Name: org.OrgName,
}
}

View File

@@ -1,32 +0,0 @@
package auth
import (
"github.com/caos/logging"
usr_model "github.com/caos/zitadel/internal/user/model"
"github.com/caos/zitadel/pkg/grpc/auth"
"github.com/golang/protobuf/ptypes"
)
func humanViewFromModel(user *usr_model.HumanView) *auth.HumanView {
passwordChanged, err := ptypes.TimestampProto(user.PasswordChanged)
logging.Log("MANAG-h4ByY").OnError(err).Debug("unable to parse date")
return &auth.HumanView{
FirstName: user.FirstName,
LastName: user.LastName,
DisplayName: user.DisplayName,
NickName: user.NickName,
PreferredLanguage: user.PreferredLanguage,
Gender: genderFromModel(user.Gender),
Email: user.Email,
IsEmailVerified: user.IsEmailVerified,
Phone: user.Phone,
IsPhoneVerified: user.IsPhoneVerified,
Country: user.Country,
Locality: user.Locality,
PostalCode: user.PostalCode,
Region: user.Region,
StreetAddress: user.StreetAddress,
PasswordChanged: passwordChanged,
}
}

View File

@@ -1,19 +0,0 @@
package auth
import (
"github.com/caos/logging"
"github.com/golang/protobuf/ptypes"
usr_model "github.com/caos/zitadel/internal/user/model"
"github.com/caos/zitadel/pkg/grpc/auth"
)
func machineViewFromModel(machine *usr_model.MachineView) *auth.MachineView {
lastKeyAdded, err := ptypes.TimestampProto(machine.LastKeyAdded)
logging.Log("MANAG-wGcAQ").OnError(err).Debug("unable to parse date")
return &auth.MachineView{
Description: machine.Description,
Name: machine.Name,
LastKeyAdded: lastKeyAdded,
}
}

View File

@@ -1,17 +0,0 @@
package auth
import (
"context"
"github.com/golang/protobuf/ptypes/empty"
"github.com/caos/zitadel/pkg/grpc/auth"
)
func (s *Server) GetMyUserSessions(ctx context.Context, _ *empty.Empty) (_ *auth.UserSessionViews, err error) {
userSessions, err := s.repo.GetMyUserSessions(ctx)
if err != nil {
return nil, err
}
return &auth.UserSessionViews{UserSessions: userSessionViewsFromModel(userSessions)}, nil
}

View File

@@ -1,38 +0,0 @@
package auth
import (
auth_req_model "github.com/caos/zitadel/internal/auth_request/model"
usr_model "github.com/caos/zitadel/internal/user/model"
"github.com/caos/zitadel/pkg/grpc/auth"
)
func userSessionViewsFromModel(userSessions []*usr_model.UserSessionView) []*auth.UserSessionView {
converted := make([]*auth.UserSessionView, len(userSessions))
for i, s := range userSessions {
converted[i] = userSessionViewFromModel(s)
}
return converted
}
func userSessionViewFromModel(userSession *usr_model.UserSessionView) *auth.UserSessionView {
return &auth.UserSessionView{
Sequence: userSession.Sequence,
AgentId: userSession.UserAgentID,
UserId: userSession.UserID,
UserName: userSession.UserName,
LoginName: userSession.LoginName,
DisplayName: userSession.DisplayName,
AuthState: userSessionStateFromModel(userSession.State),
}
}
func userSessionStateFromModel(state auth_req_model.UserSessionState) auth.UserSessionState {
switch state {
case auth_req_model.UserSessionStateActive:
return auth.UserSessionState_USERSESSIONSTATE_ACTIVE
case auth_req_model.UserSessionStateTerminated:
return auth.UserSessionState_USERSESSIONSTATE_TERMINATED
default:
return auth.UserSessionState_USERSESSIONSTATE_UNSPECIFIED
}
}

View File

@@ -0,0 +1,69 @@
package authn
import (
"github.com/caos/logging"
"github.com/golang/protobuf/ptypes"
"github.com/caos/zitadel/internal/api/grpc/object"
"github.com/caos/zitadel/internal/domain"
key_model "github.com/caos/zitadel/internal/key/model"
"github.com/caos/zitadel/pkg/grpc/authn"
)
func KeyViewsToPb(keys []*key_model.AuthNKeyView) []*authn.Key {
k := make([]*authn.Key, len(keys))
for i, key := range keys {
k[i] = KeyViewToPb(key)
}
return k
}
func KeyViewToPb(key *key_model.AuthNKeyView) *authn.Key {
expDate, err := ptypes.TimestampProto(key.ExpirationDate)
logging.Log("AUTHN-uhYmM").OnError(err).Debug("unable to parse expiry")
return &authn.Key{
Id: key.ID,
Type: authn.KeyType_KEY_TYPE_JSON,
ExpirationDate: expDate,
Details: object.ToDetailsPb(
key.Sequence,
key.CreationDate, //TODO: details
"key.ResourceOwner", //TODO: details
),
}
}
func KeyToPb(key *key_model.AuthNKeyView) *authn.Key {
expDate, err := ptypes.TimestampProto(key.ExpirationDate)
logging.Log("AUTHN-4n12g").OnError(err).Debug("unable to parse expiration date")
return &authn.Key{
Id: key.ID,
Type: KeyTypeToPb(key.Type),
ExpirationDate: expDate,
Details: object.ToDetailsPb(
key.Sequence,
key.CreationDate, //TODO: not very pretty
"key.ResourceOwner", //TODO: details
),
}
}
func KeyTypeToPb(typ key_model.AuthNKeyType) authn.KeyType {
switch typ {
case key_model.AuthNKeyTypeJSON:
return authn.KeyType_KEY_TYPE_JSON
default:
return authn.KeyType_KEY_TYPE_UNSPECIFIED
}
}
func KeyTypeToDomain(typ authn.KeyType) domain.AuthNKeyType {
switch typ {
case authn.KeyType_KEY_TYPE_JSON:
return domain.AuthNKeyTypeJSON
default:
return domain.AuthNKeyTypeNONE
}
}

View File

@@ -0,0 +1,85 @@
package change
import (
org_model "github.com/caos/zitadel/internal/org/model"
proj_model "github.com/caos/zitadel/internal/project/model"
user_model "github.com/caos/zitadel/internal/user/model"
change_pb "github.com/caos/zitadel/pkg/grpc/change"
"github.com/caos/zitadel/pkg/grpc/message"
)
func UserChangesToPb(changes []*user_model.UserChange) []*change_pb.Change {
c := make([]*change_pb.Change, len(changes))
for i, change := range changes {
c[i] = UserChangeToPb(change)
}
return c
}
func UserChangeToPb(change *user_model.UserChange) *change_pb.Change {
return &change_pb.Change{
ChangeDate: change.ChangeDate,
EventType: message.NewLocalizedEventType(change.EventType),
Sequence: change.Sequence,
EditorId: change.ModifierID,
EditorDisplayName: change.ModifierName,
// ResourceOwnerId: change.,TODO: resource owner not returned
}
}
func OrgChangesToPb(changes []*org_model.OrgChange) []*change_pb.Change {
c := make([]*change_pb.Change, len(changes))
for i, change := range changes {
c[i] = OrgChangeToPb(change)
}
return c
}
func OrgChangeToPb(change *org_model.OrgChange) *change_pb.Change {
return &change_pb.Change{
ChangeDate: change.ChangeDate,
EventType: message.NewLocalizedEventType(change.EventType),
Sequence: change.Sequence,
EditorId: change.ModifierId,
EditorDisplayName: change.ModifierName,
// ResourceOwnerId: change.,TODO: resource owner not returned
}
}
func ProjectChangesToPb(changes []*proj_model.ProjectChange) []*change_pb.Change {
c := make([]*change_pb.Change, len(changes))
for i, change := range changes {
c[i] = ProjectChangeToPb(change)
}
return c
}
func ProjectChangeToPb(change *proj_model.ProjectChange) *change_pb.Change {
return &change_pb.Change{
ChangeDate: change.ChangeDate,
EventType: message.NewLocalizedEventType(change.EventType),
Sequence: change.Sequence,
EditorId: change.ModifierId,
EditorDisplayName: change.ModifierName,
// ResourceOwnerId: change.,TODO: resource owner not returned
}
}
func AppChangesToPb(changes []*proj_model.ApplicationChange) []*change_pb.Change {
c := make([]*change_pb.Change, len(changes))
for i, change := range changes {
c[i] = AppChangeToPb(change)
}
return c
}
func AppChangeToPb(change *proj_model.ApplicationChange) *change_pb.Change {
return &change_pb.Change{
ChangeDate: change.ChangeDate,
EventType: message.NewLocalizedEventType(change.EventType),
Sequence: change.Sequence,
EditorId: change.ModifierId,
EditorDisplayName: change.ModifierName,
// ResourceOwnerId: change.,TODO: resource owner not returned
}
}

View File

@@ -0,0 +1,237 @@
package idp
import (
obj_grpc "github.com/caos/zitadel/internal/api/grpc/object"
"github.com/caos/zitadel/internal/domain"
iam_model "github.com/caos/zitadel/internal/iam/model"
user_model "github.com/caos/zitadel/internal/user/model"
idp_pb "github.com/caos/zitadel/pkg/grpc/idp"
)
func IDPViewsToPb(idps []*iam_model.IDPConfigView) []*idp_pb.IDP {
resp := make([]*idp_pb.IDP, len(idps))
for i, idp := range idps {
resp[i] = ModelIDPViewToPb(idp)
}
return resp
}
func ModelIDPViewToPb(idp *iam_model.IDPConfigView) *idp_pb.IDP {
return &idp_pb.IDP{
Id: idp.IDPConfigID,
State: ModelIDPStateToPb(idp.State),
Name: idp.Name,
StylingType: ModelIDPStylingTypeToPb(idp.StylingType),
Owner: ModelIDPProviderTypeToPb(idp.IDPProviderType),
Config: ModelIDPViewToConfigPb(idp),
Details: obj_grpc.ToDetailsPb(
idp.Sequence,
idp.ChangeDate,
"idp.ResourceOwner", //TODO: backend
),
}
}
func IDPViewToPb(idp *domain.IDPConfigView) *idp_pb.IDP {
mapped := &idp_pb.IDP{
Id: idp.AggregateID,
State: IDPStateToPb(idp.State),
Name: idp.Name,
StylingType: IDPStylingTypeToPb(idp.StylingType),
Config: IDPViewToConfigPb(idp),
Details: obj_grpc.ToDetailsPb(idp.Sequence, idp.ChangeDate, "idp.ResourceOwner"), //TODO: resource owner in view
}
return mapped
}
func ExternalIDPViewsToLoginPolicyLinkPb(links []*iam_model.IDPProviderView) []*idp_pb.IDPLoginPolicyLink {
l := make([]*idp_pb.IDPLoginPolicyLink, len(links))
for i, link := range links {
l[i] = ExternalIDPViewToLoginPolicyLinkPb(link)
}
return l
}
func ExternalIDPViewToLoginPolicyLinkPb(link *iam_model.IDPProviderView) *idp_pb.IDPLoginPolicyLink {
return &idp_pb.IDPLoginPolicyLink{
IdpId: link.IDPConfigID,
IdpName: link.Name,
IdpType: idp_pb.IDPType_IDP_TYPE_OIDC,
}
}
func IDPsToUserLinkPb(res []*user_model.ExternalIDPView) []*idp_pb.IDPUserLink {
links := make([]*idp_pb.IDPUserLink, len(res))
for i, link := range res {
links[i] = ExternalIDPViewToUserLinkPb(link)
}
return links
}
func ExternalIDPViewToUserLinkPb(link *user_model.ExternalIDPView) *idp_pb.IDPUserLink {
return &idp_pb.IDPUserLink{
UserId: link.UserID,
IdpId: link.IDPConfigID,
IdpName: link.IDPName,
ProvidedUserId: link.ExternalUserID,
ProvidedUserName: link.UserDisplayName,
//TODO: as soon as saml is implemented we need to switch here
IdpType: idp_pb.IDPType_IDP_TYPE_OIDC,
}
}
func IDPStateToPb(state domain.IDPConfigState) idp_pb.IDPState {
switch state {
case domain.IDPConfigStateActive:
return idp_pb.IDPState_IDP_STATE_ACTIVE
case domain.IDPConfigStateInactive:
return idp_pb.IDPState_IDP_STATE_INACTIVE
default:
return idp_pb.IDPState_IDP_STATE_UNSPECIFIED
}
}
func ModelIDPStateToPb(state iam_model.IDPConfigState) idp_pb.IDPState {
switch state {
case iam_model.IDPConfigStateActive:
return idp_pb.IDPState_IDP_STATE_ACTIVE
case iam_model.IDPConfigStateInactive:
return idp_pb.IDPState_IDP_STATE_INACTIVE
default:
return idp_pb.IDPState_IDP_STATE_UNSPECIFIED
}
}
func IDPStylingTypeToDomain(stylingType idp_pb.IDPStylingType) domain.IDPConfigStylingType {
switch stylingType {
case idp_pb.IDPStylingType_STYLING_TYPE_GOOGLE:
return domain.IDPConfigStylingTypeGoogle
default:
return domain.IDPConfigStylingTypeUnspecified
}
}
func ModelIDPStylingTypeToPb(stylingType iam_model.IDPStylingType) idp_pb.IDPStylingType {
switch stylingType {
case iam_model.IDPStylingTypeGoogle:
return idp_pb.IDPStylingType_STYLING_TYPE_GOOGLE
default:
return idp_pb.IDPStylingType_STYLING_TYPE_UNSPECIFIED
}
}
func IDPStylingTypeToPb(stylingType domain.IDPConfigStylingType) idp_pb.IDPStylingType {
switch stylingType {
case domain.IDPConfigStylingTypeGoogle:
return idp_pb.IDPStylingType_STYLING_TYPE_GOOGLE
default:
return idp_pb.IDPStylingType_STYLING_TYPE_UNSPECIFIED
}
}
func ModelIDPViewToConfigPb(config *iam_model.IDPConfigView) *idp_pb.IDP_OidcConfig {
return &idp_pb.IDP_OidcConfig{
OidcConfig: &idp_pb.OIDCConfig{
ClientId: config.OIDCClientID,
Issuer: config.OIDCIssuer,
Scopes: config.OIDCScopes,
DisplayNameMapping: ModelMappingFieldToPb(config.OIDCIDPDisplayNameMapping),
UsernameMapping: ModelMappingFieldToPb(config.OIDCUsernameMapping),
},
}
}
func IDPViewToConfigPb(config *domain.IDPConfigView) *idp_pb.IDP_OidcConfig {
return &idp_pb.IDP_OidcConfig{
OidcConfig: &idp_pb.OIDCConfig{
ClientId: config.OIDCClientID,
Issuer: config.OIDCIssuer,
Scopes: config.OIDCScopes,
DisplayNameMapping: MappingFieldToPb(config.OIDCIDPDisplayNameMapping),
UsernameMapping: MappingFieldToPb(config.OIDCUsernameMapping),
},
}
}
func OIDCConfigToPb(config *domain.OIDCIDPConfig) *idp_pb.IDP_OidcConfig {
return &idp_pb.IDP_OidcConfig{
OidcConfig: &idp_pb.OIDCConfig{
ClientId: config.ClientID,
Issuer: config.Issuer,
Scopes: config.Scopes,
DisplayNameMapping: MappingFieldToPb(config.IDPDisplayNameMapping),
UsernameMapping: MappingFieldToPb(config.UsernameMapping),
},
}
}
func FieldNameToModel(fieldName idp_pb.IDPFieldName) iam_model.IDPConfigSearchKey {
switch fieldName {
// case admin.IdpSearchKey_IDPSEARCHKEY_IDP_CONFIG_ID: //TODO: not implemented in proto
// return iam_model.IDPConfigSearchKeyIdpConfigID
case idp_pb.IDPFieldName_IDP_FIELD_NAME_NAME:
return iam_model.IDPConfigSearchKeyName
default:
return iam_model.IDPConfigSearchKeyUnspecified
}
}
func ModelMappingFieldToPb(mappingField iam_model.OIDCMappingField) idp_pb.OIDCMappingField {
switch mappingField {
case iam_model.OIDCMappingFieldEmail:
return idp_pb.OIDCMappingField_OIDC_MAPPING_FIELD_EMAIL
case iam_model.OIDCMappingFieldPreferredLoginName:
return idp_pb.OIDCMappingField_OIDC_MAPPING_FIELD_PREFERRED_USERNAME
default:
return idp_pb.OIDCMappingField_OIDC_MAPPING_FIELD_UNSPECIFIED
}
}
func MappingFieldToPb(mappingField domain.OIDCMappingField) idp_pb.OIDCMappingField {
switch mappingField {
case domain.OIDCMappingFieldEmail:
return idp_pb.OIDCMappingField_OIDC_MAPPING_FIELD_EMAIL
case domain.OIDCMappingFieldPreferredLoginName:
return idp_pb.OIDCMappingField_OIDC_MAPPING_FIELD_PREFERRED_USERNAME
default:
return idp_pb.OIDCMappingField_OIDC_MAPPING_FIELD_UNSPECIFIED
}
}
func MappingFieldToDomain(mappingField idp_pb.OIDCMappingField) domain.OIDCMappingField {
switch mappingField {
case idp_pb.OIDCMappingField_OIDC_MAPPING_FIELD_EMAIL:
return domain.OIDCMappingFieldEmail
case idp_pb.OIDCMappingField_OIDC_MAPPING_FIELD_PREFERRED_USERNAME:
return domain.OIDCMappingFieldPreferredLoginName
default:
return domain.OIDCMappingFieldUnspecified
}
}
func ModelIDPProviderTypeToPb(typ iam_model.IDPProviderType) idp_pb.IDPOwnerType {
switch typ {
case iam_model.IDPProviderTypeOrg:
return idp_pb.IDPOwnerType_IDP_OWNER_TYPE_ORG
case iam_model.IDPProviderTypeSystem:
return idp_pb.IDPOwnerType_IDP_OWNER_TYPE_SYSTEM
default:
return idp_pb.IDPOwnerType_IDP_OWNER_TYPE_UNSPECIFIED
}
}
func IDPIDQueryToModel(query *idp_pb.IDPIDQuery) *iam_model.IDPConfigSearchQuery {
return &iam_model.IDPConfigSearchQuery{
Key: iam_model.IDPConfigSearchKeyIdpConfigID, //TODO: whats the difference between idpconfigid and aggregateid search key?
Method: domain.SearchMethodEquals,
Value: query.Id,
}
}
func IDPNameQueryToModel(query *idp_pb.IDPNameQuery) *iam_model.IDPConfigSearchQuery {
return &iam_model.IDPConfigSearchQuery{
Key: iam_model.IDPConfigSearchKeyName,
Method: obj_grpc.TextMethodToModel(query.Method),
Value: query.Name,
}
}

View File

@@ -1,135 +0,0 @@
package management
import (
"context"
"github.com/caos/zitadel/internal/api/authz"
"github.com/golang/protobuf/ptypes/empty"
"github.com/caos/zitadel/pkg/grpc/management"
)
func (s *Server) SearchApplications(ctx context.Context, in *management.ApplicationSearchRequest) (*management.ApplicationSearchResponse, error) {
response, err := s.project.SearchApplications(ctx, applicationSearchRequestsToModel(in))
if err != nil {
return nil, err
}
return applicationSearchResponseFromModel(response), nil
}
func (s *Server) ApplicationByID(ctx context.Context, in *management.ApplicationID) (*management.ApplicationView, error) {
app, err := s.project.ApplicationByID(ctx, in.ProjectId, in.Id)
if err != nil {
return nil, err
}
return applicationViewFromModel(app), nil
}
func (s *Server) CreateOIDCApplication(ctx context.Context, in *management.OIDCApplicationCreate) (*management.Application, error) {
app, err := s.command.AddOIDCApplication(ctx, oidcAppCreateToDomain(in), authz.GetCtxData(ctx).OrgID)
if err != nil {
return nil, err
}
return oidcAppFromDomain(app), nil
}
func (s *Server) CreateAPIApplication(ctx context.Context, in *management.APIApplicationCreate) (*management.Application, error) {
app, err := s.command.AddAPIApplication(ctx, apiAppCreateToModel(in), authz.GetCtxData(ctx).OrgID)
if err != nil {
return nil, err
}
return apiAppFromDomain(app), nil
}
func (s *Server) UpdateApplication(ctx context.Context, in *management.ApplicationUpdate) (*management.Application, error) {
app, err := s.command.ChangeApplication(ctx, in.ProjectId, appUpdateToDomain(in), authz.GetCtxData(ctx).OrgID)
if err != nil {
return nil, err
}
return appFromDomain(app), nil
}
func (s *Server) DeactivateApplication(ctx context.Context, in *management.ApplicationID) (*empty.Empty, error) {
err := s.command.DeactivateApplication(ctx, in.ProjectId, in.Id, authz.GetCtxData(ctx).OrgID)
return &empty.Empty{}, err
}
func (s *Server) ReactivateApplication(ctx context.Context, in *management.ApplicationID) (*empty.Empty, error) {
err := s.command.ReactivateApplication(ctx, in.ProjectId, in.Id, authz.GetCtxData(ctx).OrgID)
return &empty.Empty{}, err
}
func (s *Server) RemoveApplication(ctx context.Context, in *management.ApplicationID) (*empty.Empty, error) {
err := s.command.RemoveApplication(ctx, in.ProjectId, in.Id, authz.GetCtxData(ctx).OrgID)
return &empty.Empty{}, err
}
func (s *Server) UpdateApplicationOIDCConfig(ctx context.Context, in *management.OIDCConfigUpdate) (*management.OIDCConfig, error) {
config, err := s.command.ChangeOIDCApplication(ctx, oidcConfigUpdateToDomain(in), authz.GetCtxData(ctx).OrgID)
if err != nil {
return nil, err
}
return oidcConfigFromDomain(config), nil
}
func (s *Server) UpdateApplicationAPIConfig(ctx context.Context, in *management.APIConfigUpdate) (*management.APIConfig, error) {
config, err := s.command.ChangeAPIApplication(ctx, apiConfigUpdateToDomain(in), authz.GetCtxData(ctx).OrgID)
if err != nil {
return nil, err
}
return apiConfigFromDomain(config), nil
}
func (s *Server) RegenerateOIDCClientSecret(ctx context.Context, in *management.ApplicationID) (*management.ClientSecret, error) {
config, err := s.command.ChangeOIDCApplicationSecret(ctx, in.ProjectId, in.Id, authz.GetCtxData(ctx).OrgID)
if err != nil {
return nil, err
}
return &management.ClientSecret{ClientSecret: config.ClientSecretString}, nil
}
func (s *Server) RegenerateAPIClientSecret(ctx context.Context, in *management.ApplicationID) (*management.ClientSecret, error) {
config, err := s.command.ChangeAPIApplicationSecret(ctx, in.ProjectId, in.Id, authz.GetCtxData(ctx).OrgID)
if err != nil {
return nil, err
}
return &management.ClientSecret{ClientSecret: config.ClientSecretString}, nil
}
func (s *Server) ApplicationChanges(ctx context.Context, changesRequest *management.ChangeRequest) (*management.Changes, error) {
response, err := s.project.ApplicationChanges(ctx, changesRequest.Id, changesRequest.SecId, changesRequest.SequenceOffset, changesRequest.Limit, changesRequest.Asc)
if err != nil {
return nil, err
}
return appChangesToResponse(response, changesRequest.GetSequenceOffset(), changesRequest.GetLimit()), nil
}
func (s *Server) SearchClientKeys(ctx context.Context, req *management.ClientKeySearchRequest) (*management.ClientKeySearchResponse, error) {
result, err := s.project.SearchClientKeys(ctx, clientKeySearchRequestToModel(req))
if err != nil {
return nil, err
}
return clientKeySearchResponseFromModel(result), nil
}
func (s *Server) GetClientKey(ctx context.Context, req *management.ClientKeyIDRequest) (*management.ClientKeyView, error) {
key, err := s.project.GetClientKey(ctx, req.ProjectId, req.ApplicationId, req.KeyId)
if err != nil {
return nil, err
}
return clientKeyViewFromModel(key), nil
}
func (s *Server) AddClientKey(ctx context.Context, req *management.AddClientKeyRequest) (*management.AddClientKeyResponse, error) {
key, err := s.command.AddApplicationKey(ctx, addClientKeyToDomain(req), authz.GetCtxData(ctx).OrgID)
if err != nil {
return nil, err
}
return addClientKeyFromDomain(key), nil
}
func (s *Server) DeleteClientKey(ctx context.Context, req *management.ClientKeyIDRequest) (*empty.Empty, error) {
err := s.command.RemoveApplicationKey(ctx, req.ProjectId, req.ApplicationId, req.KeyId, authz.GetCtxData(ctx).OrgID)
return &empty.Empty{}, err
}

View File

@@ -1,736 +0,0 @@
package management
import (
"encoding/json"
"time"
"github.com/caos/logging"
"github.com/golang/protobuf/ptypes"
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/types/known/durationpb"
"google.golang.org/protobuf/types/known/structpb"
"google.golang.org/protobuf/types/known/timestamppb"
"github.com/caos/zitadel/internal/domain"
"github.com/caos/zitadel/internal/eventstore/v1/models"
key_model "github.com/caos/zitadel/internal/key/model"
proj_model "github.com/caos/zitadel/internal/project/model"
"github.com/caos/zitadel/pkg/grpc/management"
"github.com/caos/zitadel/pkg/grpc/message"
)
func appFromDomain(app domain.Application) *management.Application {
return &management.Application{
Id: app.GetAppID(),
State: appStateFromDomain(app.GetState()),
Name: app.GetApplicationName(),
}
}
func appFromModel(app *proj_model.Application) *management.Application {
changeDate, err := ptypes.TimestampProto(app.ChangeDate)
logging.Log("GRPC-di7rw").OnError(err).Debug("unable to parse timestamp")
return &management.Application{
Id: app.AppID,
State: appStateFromModel(app.State),
ChangeDate: changeDate,
Name: app.Name,
Sequence: app.Sequence,
AppConfig: appConfigFromModel(app),
}
}
func appConfigFromModel(app *proj_model.Application) management.AppConfig {
if app.Type == proj_model.AppTypeAPI {
return &management.Application_ApiConfig{
ApiConfig: apiConfigFromModel(app.APIConfig),
}
}
return nil
}
func oidcAppFromDomain(app *domain.OIDCApp) *management.Application {
return &management.Application{
Id: app.AppID,
State: appStateFromDomain(app.State),
ChangeDate: timestamppb.New(app.ChangeDate),
Name: app.AppName,
Sequence: app.Sequence,
AppConfig: oidcAppConfigFromDomain(app),
}
}
func apiAppFromDomain(app *domain.APIApp) *management.Application {
return &management.Application{
Id: app.AppID,
State: appStateFromDomain(app.State),
ChangeDate: timestamppb.New(app.ChangeDate),
Name: app.AppName,
Sequence: app.Sequence,
AppConfig: apiAppConfigFromDomain(app),
}
}
func oidcAppConfigFromDomain(app *domain.OIDCApp) management.AppConfig {
return &management.Application_OidcConfig{
OidcConfig: oidcConfigFromDomain(app),
}
}
func apiAppConfigFromDomain(app *domain.APIApp) management.AppConfig {
return &management.Application_ApiConfig{
ApiConfig: apiConfigFromDomain(app),
}
}
func oidcConfigFromDomain(config *domain.OIDCApp) *management.OIDCConfig {
return &management.OIDCConfig{
RedirectUris: config.RedirectUris,
ResponseTypes: oidcResponseTypesFromDomain(config.ResponseTypes),
GrantTypes: oidcGrantTypesFromDomain(config.GrantTypes),
ApplicationType: oidcApplicationTypeFromDomain(config.ApplicationType),
ClientId: config.ClientID,
ClientSecret: config.ClientSecretString,
AuthMethodType: oidcAuthMethodTypeFromDomain(config.AuthMethodType),
PostLogoutRedirectUris: config.PostLogoutRedirectUris,
Version: oidcVersionFromDomain(config.OIDCVersion),
NoneCompliant: config.Compliance.NoneCompliant,
ComplianceProblems: complianceProblemsToLocalizedMessages(config.Compliance.Problems),
DevMode: config.DevMode,
AccessTokenType: oidcTokenTypeFromDomain(config.AccessTokenType),
AccessTokenRoleAssertion: config.AccessTokenRoleAssertion,
IdTokenRoleAssertion: config.IDTokenRoleAssertion,
IdTokenUserinfoAssertion: config.IDTokenUserinfoAssertion,
ClockSkew: durationpb.New(config.ClockSkew),
}
}
func apiConfigFromDomain(config *domain.APIApp) *management.APIConfig {
return &management.APIConfig{
ClientId: config.ClientID,
ClientSecret: config.ClientSecretString,
AuthMethodType: apiAuthMethodTypeFromDomain(config.AuthMethodType),
}
}
func apiConfigFromModel(config *proj_model.APIConfig) *management.APIConfig {
return &management.APIConfig{
ClientId: config.ClientID,
ClientSecret: config.ClientSecretString,
AuthMethodType: apiAuthMethodTypeFromModel(config.AuthMethodType),
}
}
func oidcConfigFromApplicationViewModel(app *proj_model.ApplicationView) *management.OIDCConfig {
return &management.OIDCConfig{
RedirectUris: app.OIDCRedirectUris,
ResponseTypes: oidcResponseTypesFromModel(app.OIDCResponseTypes),
GrantTypes: oidcGrantTypesFromModel(app.OIDCGrantTypes),
ApplicationType: oidcApplicationTypeFromModel(app.OIDCApplicationType),
ClientId: app.OIDCClientID,
AuthMethodType: oidcAuthMethodTypeFromModel(app.OIDCAuthMethodType),
PostLogoutRedirectUris: app.OIDCPostLogoutRedirectUris,
Version: oidcVersionFromDomain(domain.OIDCVersion(app.OIDCVersion)),
NoneCompliant: app.NoneCompliant,
ComplianceProblems: complianceProblemsToLocalizedMessages(app.ComplianceProblems),
DevMode: app.DevMode,
AccessTokenType: oidcTokenTypeFromDomain(domain.OIDCTokenType(app.AccessTokenType)),
AccessTokenRoleAssertion: app.AccessTokenRoleAssertion,
IdTokenRoleAssertion: app.IDTokenRoleAssertion,
IdTokenUserinfoAssertion: app.IDTokenUserinfoAssertion,
ClockSkew: durationpb.New(app.ClockSkew),
}
}
func apiConfigFromApplicationViewModel(app *proj_model.ApplicationView) *management.APIConfig {
return &management.APIConfig{
ClientId: app.OIDCClientID,
AuthMethodType: apiAuthMethodTypeFromModel(proj_model.APIAuthMethodType(app.OIDCAuthMethodType)),
}
}
func complianceProblemsToLocalizedMessages(problems []string) []*message.LocalizedMessage {
converted := make([]*message.LocalizedMessage, len(problems))
for i, p := range problems {
converted[i] = message.NewLocalizedMessage(p)
}
return converted
}
func oidcAppCreateToDomain(app *management.OIDCApplicationCreate) *domain.OIDCApp {
return &domain.OIDCApp{
ObjectRoot: models.ObjectRoot{
AggregateID: app.ProjectId,
},
AppName: app.Name,
OIDCVersion: oidcVersionToDomain(app.Version),
RedirectUris: app.RedirectUris,
ResponseTypes: oidcResponseTypesToDomain(app.ResponseTypes),
GrantTypes: oidcGrantTypesToDomain(app.GrantTypes),
ApplicationType: oidcApplicationTypeToDomain(app.ApplicationType),
AuthMethodType: oidcAuthMethodTypeToDomain(app.AuthMethodType),
PostLogoutRedirectUris: app.PostLogoutRedirectUris,
DevMode: app.DevMode,
AccessTokenType: oidcTokenTypeToDomain(app.AccessTokenType),
AccessTokenRoleAssertion: app.AccessTokenRoleAssertion,
IDTokenRoleAssertion: app.IdTokenRoleAssertion,
IDTokenUserinfoAssertion: app.IdTokenUserinfoAssertion,
ClockSkew: app.ClockSkew.AsDuration(),
}
}
func apiAppCreateToModel(app *management.APIApplicationCreate) *domain.APIApp {
return &domain.APIApp{
ObjectRoot: models.ObjectRoot{
AggregateID: app.ProjectId,
},
AppName: app.Name,
AuthMethodType: apiAuthMethodTypeToDomain(app.AuthMethodType),
}
}
func appUpdateToDomain(app *management.ApplicationUpdate) domain.Application {
return &domain.ChangeApp{
AppID: app.Id,
AppName: app.Name,
}
}
func oidcConfigUpdateToDomain(app *management.OIDCConfigUpdate) *domain.OIDCApp {
return &domain.OIDCApp{
ObjectRoot: models.ObjectRoot{
AggregateID: app.ProjectId,
},
AppID: app.ApplicationId,
RedirectUris: app.RedirectUris,
ResponseTypes: oidcResponseTypesToDomain(app.ResponseTypes),
GrantTypes: oidcGrantTypesToDomain(app.GrantTypes),
ApplicationType: oidcApplicationTypeToDomain(app.ApplicationType),
AuthMethodType: oidcAuthMethodTypeToDomain(app.AuthMethodType),
PostLogoutRedirectUris: app.PostLogoutRedirectUris,
DevMode: app.DevMode,
AccessTokenType: oidcTokenTypeToDomain(app.AccessTokenType),
AccessTokenRoleAssertion: app.AccessTokenRoleAssertion,
IDTokenRoleAssertion: app.IdTokenRoleAssertion,
IDTokenUserinfoAssertion: app.IdTokenUserinfoAssertion,
ClockSkew: app.ClockSkew.AsDuration(),
}
}
func apiConfigUpdateToDomain(app *management.APIConfigUpdate) *domain.APIApp {
return &domain.APIApp{
ObjectRoot: models.ObjectRoot{
AggregateID: app.ProjectId,
},
AppID: app.ApplicationId,
AuthMethodType: apiAuthMethodTypeToDomain(app.AuthMethodType),
}
}
func addClientKeyToDomain(key *management.AddClientKeyRequest) *domain.ApplicationKey {
expirationDate := time.Time{}
if key.ExpirationDate != nil {
expirationDate = key.ExpirationDate.AsTime()
}
return &domain.ApplicationKey{
ObjectRoot: models.ObjectRoot{
AggregateID: key.ProjectId,
},
ExpirationDate: expirationDate,
Type: authNKeyTypeToDomain(key.Type),
ApplicationID: key.ApplicationId,
}
}
func addClientKeyFromDomain(key *domain.ApplicationKey) *management.AddClientKeyResponse {
detail, err := key.Detail()
logging.Log("MANAG-adt42").OnError(err).Warn("unable to marshal key")
return &management.AddClientKeyResponse{
Id: key.KeyID,
CreationDate: timestamppb.New(key.CreationDate),
ExpirationDate: timestamppb.New(key.ExpirationDate),
Sequence: key.Sequence,
KeyDetails: detail,
Type: authNKeyTypeFromDomain(key.Type),
}
}
func applicationSearchRequestsToModel(request *management.ApplicationSearchRequest) *proj_model.ApplicationSearchRequest {
return &proj_model.ApplicationSearchRequest{
Offset: request.Offset,
Limit: request.Limit,
Queries: applicationSearchQueriesToModel(request.ProjectId, request.Queries),
}
}
func applicationSearchQueriesToModel(projectID string, queries []*management.ApplicationSearchQuery) []*proj_model.ApplicationSearchQuery {
converted := make([]*proj_model.ApplicationSearchQuery, len(queries)+1)
for i, q := range queries {
converted[i] = applicationSearchQueryToModel(q)
}
converted[len(queries)] = &proj_model.ApplicationSearchQuery{Key: proj_model.AppSearchKeyProjectID, Method: domain.SearchMethodEquals, Value: projectID}
return converted
}
func applicationSearchQueryToModel(query *management.ApplicationSearchQuery) *proj_model.ApplicationSearchQuery {
return &proj_model.ApplicationSearchQuery{
Key: applicationSearchKeyToModel(query.Key),
Method: searchMethodToModel(query.Method),
Value: query.Value,
}
}
func applicationSearchKeyToModel(key management.ApplicationSearchKey) proj_model.AppSearchKey {
switch key {
case management.ApplicationSearchKey_APPLICATIONSEARCHKEY_APP_NAME:
return proj_model.AppSearchKeyName
default:
return proj_model.AppSearchKeyUnspecified
}
}
func applicationSearchResponseFromModel(response *proj_model.ApplicationSearchResponse) *management.ApplicationSearchResponse {
timestamp, err := ptypes.TimestampProto(response.Timestamp)
logging.Log("GRPC-Lp06f").OnError(err).Debug("unable to parse timestamp")
return &management.ApplicationSearchResponse{
Offset: response.Offset,
Limit: response.Limit,
TotalResult: response.TotalResult,
Result: applicationViewsFromModel(response.Result),
ProcessedSequence: response.Sequence,
ViewTimestamp: timestamp,
}
}
func applicationViewsFromModel(apps []*proj_model.ApplicationView) []*management.ApplicationView {
converted := make([]*management.ApplicationView, len(apps))
for i, app := range apps {
converted[i] = applicationViewFromModel(app)
}
return converted
}
func applicationViewFromModel(application *proj_model.ApplicationView) *management.ApplicationView {
creationDate, err := ptypes.TimestampProto(application.CreationDate)
logging.Log("GRPC-lo9sw").OnError(err).Debug("unable to parse timestamp")
changeDate, err := ptypes.TimestampProto(application.ChangeDate)
logging.Log("GRPC-8uwsd").OnError(err).Debug("unable to parse timestamp")
converted := &management.ApplicationView{
Id: application.ID,
State: appStateFromModel(application.State),
CreationDate: creationDate,
ChangeDate: changeDate,
Name: application.Name,
Sequence: application.Sequence,
}
if application.IsOIDC {
converted.AppConfig = &management.ApplicationView_OidcConfig{
OidcConfig: oidcConfigFromApplicationViewModel(application),
}
} else {
converted.AppConfig = &management.ApplicationView_ApiConfig{
ApiConfig: apiConfigFromApplicationViewModel(application),
}
}
return converted
}
func appStateFromDomain(state domain.AppState) management.AppState {
switch state {
case domain.AppStateActive:
return management.AppState_APPSTATE_ACTIVE
case domain.AppStateInactive:
return management.AppState_APPSTATE_INACTIVE
default:
return management.AppState_APPSTATE_UNSPECIFIED
}
}
func appStateFromModel(state proj_model.AppState) management.AppState {
switch state {
case proj_model.AppStateActive:
return management.AppState_APPSTATE_ACTIVE
case proj_model.AppStateInactive:
return management.AppState_APPSTATE_INACTIVE
default:
return management.AppState_APPSTATE_UNSPECIFIED
}
}
func oidcResponseTypesToDomain(responseTypes []management.OIDCResponseType) []domain.OIDCResponseType {
if responseTypes == nil || len(responseTypes) == 0 {
return []domain.OIDCResponseType{domain.OIDCResponseTypeCode}
}
oidcResponseTypes := make([]domain.OIDCResponseType, len(responseTypes))
for i, responseType := range responseTypes {
switch responseType {
case management.OIDCResponseType_OIDCRESPONSETYPE_CODE:
oidcResponseTypes[i] = domain.OIDCResponseTypeCode
case management.OIDCResponseType_OIDCRESPONSETYPE_ID_TOKEN:
oidcResponseTypes[i] = domain.OIDCResponseTypeIDToken
case management.OIDCResponseType_OIDCRESPONSETYPE_ID_TOKEN_TOKEN:
oidcResponseTypes[i] = domain.OIDCResponseTypeIDTokenToken
}
}
return oidcResponseTypes
}
func oidcResponseTypesFromDomain(responseTypes []domain.OIDCResponseType) []management.OIDCResponseType {
oidcResponseTypes := make([]management.OIDCResponseType, len(responseTypes))
for i, responseType := range responseTypes {
switch responseType {
case domain.OIDCResponseTypeCode:
oidcResponseTypes[i] = management.OIDCResponseType_OIDCRESPONSETYPE_CODE
case domain.OIDCResponseTypeIDToken:
oidcResponseTypes[i] = management.OIDCResponseType_OIDCRESPONSETYPE_ID_TOKEN
case domain.OIDCResponseTypeIDTokenToken:
oidcResponseTypes[i] = management.OIDCResponseType_OIDCRESPONSETYPE_ID_TOKEN_TOKEN
}
}
return oidcResponseTypes
}
func oidcResponseTypesFromModel(responseTypes []proj_model.OIDCResponseType) []management.OIDCResponseType {
oidcResponseTypes := make([]management.OIDCResponseType, len(responseTypes))
for i, responseType := range responseTypes {
switch responseType {
case proj_model.OIDCResponseTypeCode:
oidcResponseTypes[i] = management.OIDCResponseType_OIDCRESPONSETYPE_CODE
case proj_model.OIDCResponseTypeIDToken:
oidcResponseTypes[i] = management.OIDCResponseType_OIDCRESPONSETYPE_ID_TOKEN
case proj_model.OIDCResponseTypeIDTokenToken:
oidcResponseTypes[i] = management.OIDCResponseType_OIDCRESPONSETYPE_ID_TOKEN_TOKEN
}
}
return oidcResponseTypes
}
func oidcGrantTypesToDomain(grantTypes []management.OIDCGrantType) []domain.OIDCGrantType {
if grantTypes == nil || len(grantTypes) == 0 {
return []domain.OIDCGrantType{domain.OIDCGrantTypeAuthorizationCode}
}
oidcGrantTypes := make([]domain.OIDCGrantType, len(grantTypes))
for i, grantType := range grantTypes {
switch grantType {
case management.OIDCGrantType_OIDCGRANTTYPE_AUTHORIZATION_CODE:
oidcGrantTypes[i] = domain.OIDCGrantTypeAuthorizationCode
case management.OIDCGrantType_OIDCGRANTTYPE_IMPLICIT:
oidcGrantTypes[i] = domain.OIDCGrantTypeImplicit
case management.OIDCGrantType_OIDCGRANTTYPE_REFRESH_TOKEN:
oidcGrantTypes[i] = domain.OIDCGrantTypeRefreshToken
}
}
return oidcGrantTypes
}
func oidcGrantTypesFromDomain(grantTypes []domain.OIDCGrantType) []management.OIDCGrantType {
oidcGrantTypes := make([]management.OIDCGrantType, len(grantTypes))
for i, grantType := range grantTypes {
switch grantType {
case domain.OIDCGrantTypeAuthorizationCode:
oidcGrantTypes[i] = management.OIDCGrantType_OIDCGRANTTYPE_AUTHORIZATION_CODE
case domain.OIDCGrantTypeImplicit:
oidcGrantTypes[i] = management.OIDCGrantType_OIDCGRANTTYPE_IMPLICIT
case domain.OIDCGrantTypeRefreshToken:
oidcGrantTypes[i] = management.OIDCGrantType_OIDCGRANTTYPE_REFRESH_TOKEN
}
}
return oidcGrantTypes
}
func oidcGrantTypesFromModel(grantTypes []proj_model.OIDCGrantType) []management.OIDCGrantType {
oidcGrantTypes := make([]management.OIDCGrantType, len(grantTypes))
for i, grantType := range grantTypes {
switch grantType {
case proj_model.OIDCGrantTypeAuthorizationCode:
oidcGrantTypes[i] = management.OIDCGrantType_OIDCGRANTTYPE_AUTHORIZATION_CODE
case proj_model.OIDCGrantTypeImplicit:
oidcGrantTypes[i] = management.OIDCGrantType_OIDCGRANTTYPE_IMPLICIT
case proj_model.OIDCGrantTypeRefreshToken:
oidcGrantTypes[i] = management.OIDCGrantType_OIDCGRANTTYPE_REFRESH_TOKEN
}
}
return oidcGrantTypes
}
func oidcApplicationTypeToDomain(appType management.OIDCApplicationType) domain.OIDCApplicationType {
switch appType {
case management.OIDCApplicationType_OIDCAPPLICATIONTYPE_WEB:
return domain.OIDCApplicationTypeWeb
case management.OIDCApplicationType_OIDCAPPLICATIONTYPE_USER_AGENT:
return domain.OIDCApplicationTypeUserAgent
case management.OIDCApplicationType_OIDCAPPLICATIONTYPE_NATIVE:
return domain.OIDCApplicationTypeNative
}
return domain.OIDCApplicationTypeWeb
}
func oidcVersionToDomain(version management.OIDCVersion) domain.OIDCVersion {
switch version {
case management.OIDCVersion_OIDCV1_0:
return domain.OIDCVersionV1
}
return domain.OIDCVersionV1
}
func oidcApplicationTypeFromDomain(appType domain.OIDCApplicationType) management.OIDCApplicationType {
switch appType {
case domain.OIDCApplicationTypeWeb:
return management.OIDCApplicationType_OIDCAPPLICATIONTYPE_WEB
case domain.OIDCApplicationTypeUserAgent:
return management.OIDCApplicationType_OIDCAPPLICATIONTYPE_USER_AGENT
case domain.OIDCApplicationTypeNative:
return management.OIDCApplicationType_OIDCAPPLICATIONTYPE_NATIVE
default:
return management.OIDCApplicationType_OIDCAPPLICATIONTYPE_WEB
}
}
func oidcApplicationTypeFromModel(appType proj_model.OIDCApplicationType) management.OIDCApplicationType {
switch appType {
case proj_model.OIDCApplicationTypeWeb:
return management.OIDCApplicationType_OIDCAPPLICATIONTYPE_WEB
case proj_model.OIDCApplicationTypeUserAgent:
return management.OIDCApplicationType_OIDCAPPLICATIONTYPE_USER_AGENT
case proj_model.OIDCApplicationTypeNative:
return management.OIDCApplicationType_OIDCAPPLICATIONTYPE_NATIVE
default:
return management.OIDCApplicationType_OIDCAPPLICATIONTYPE_WEB
}
}
func oidcAuthMethodTypeToDomain(authType management.OIDCAuthMethodType) domain.OIDCAuthMethodType {
switch authType {
case management.OIDCAuthMethodType_OIDCAUTHMETHODTYPE_BASIC:
return domain.OIDCAuthMethodTypeBasic
case management.OIDCAuthMethodType_OIDCAUTHMETHODTYPE_POST:
return domain.OIDCAuthMethodTypePost
case management.OIDCAuthMethodType_OIDCAUTHMETHODTYPE_NONE:
return domain.OIDCAuthMethodTypeNone
case management.OIDCAuthMethodType_OIDCAUTHMETHODTYPE_PRIVATE_KEY_JWT:
return domain.OIDCAuthMethodTypePrivateKeyJWT
default:
return domain.OIDCAuthMethodTypeBasic
}
}
func oidcAuthMethodTypeFromDomain(authType domain.OIDCAuthMethodType) management.OIDCAuthMethodType {
switch authType {
case domain.OIDCAuthMethodTypeBasic:
return management.OIDCAuthMethodType_OIDCAUTHMETHODTYPE_BASIC
case domain.OIDCAuthMethodTypePost:
return management.OIDCAuthMethodType_OIDCAUTHMETHODTYPE_POST
case domain.OIDCAuthMethodTypeNone:
return management.OIDCAuthMethodType_OIDCAUTHMETHODTYPE_NONE
case domain.OIDCAuthMethodTypePrivateKeyJWT:
return management.OIDCAuthMethodType_OIDCAUTHMETHODTYPE_PRIVATE_KEY_JWT
default:
return management.OIDCAuthMethodType_OIDCAUTHMETHODTYPE_BASIC
}
}
func apiAuthMethodTypeToDomain(authType management.APIAuthMethodType) domain.APIAuthMethodType {
switch authType {
case management.APIAuthMethodType_APIAUTHMETHODTYPE_BASIC:
return domain.APIAuthMethodTypeBasic
case management.APIAuthMethodType_APIAUTHMETHODTYPE_PRIVATE_KEY_JWT:
return domain.APIAuthMethodTypePrivateKeyJWT
default:
return domain.APIAuthMethodTypeBasic
}
}
func apiAuthMethodTypeFromDomain(authType domain.APIAuthMethodType) management.APIAuthMethodType {
switch authType {
case domain.APIAuthMethodTypeBasic:
return management.APIAuthMethodType_APIAUTHMETHODTYPE_BASIC
case domain.APIAuthMethodTypePrivateKeyJWT:
return management.APIAuthMethodType_APIAUTHMETHODTYPE_PRIVATE_KEY_JWT
default:
return management.APIAuthMethodType_APIAUTHMETHODTYPE_BASIC
}
}
func oidcAuthMethodTypeFromModel(authType proj_model.OIDCAuthMethodType) management.OIDCAuthMethodType {
switch authType {
case proj_model.OIDCAuthMethodTypeBasic:
return management.OIDCAuthMethodType_OIDCAUTHMETHODTYPE_BASIC
case proj_model.OIDCAuthMethodTypePost:
return management.OIDCAuthMethodType_OIDCAUTHMETHODTYPE_POST
case proj_model.OIDCAuthMethodTypeNone:
return management.OIDCAuthMethodType_OIDCAUTHMETHODTYPE_NONE
case proj_model.OIDCAuthMethodTypePrivateKeyJWT:
return management.OIDCAuthMethodType_OIDCAUTHMETHODTYPE_PRIVATE_KEY_JWT
default:
return management.OIDCAuthMethodType_OIDCAUTHMETHODTYPE_BASIC
}
}
func oidcTokenTypeToDomain(tokenType management.OIDCTokenType) domain.OIDCTokenType {
switch tokenType {
case management.OIDCTokenType_OIDCTokenType_Bearer:
return domain.OIDCTokenTypeBearer
case management.OIDCTokenType_OIDCTokenType_JWT:
return domain.OIDCTokenTypeJWT
default:
return domain.OIDCTokenTypeBearer
}
}
func oidcTokenTypeFromDomain(tokenType domain.OIDCTokenType) management.OIDCTokenType {
switch tokenType {
case domain.OIDCTokenTypeBearer:
return management.OIDCTokenType_OIDCTokenType_Bearer
case domain.OIDCTokenTypeJWT:
return management.OIDCTokenType_OIDCTokenType_JWT
default:
return management.OIDCTokenType_OIDCTokenType_Bearer
}
}
func apiAuthMethodTypeFromModel(authType proj_model.APIAuthMethodType) management.APIAuthMethodType {
switch authType {
case proj_model.APIAuthMethodTypeBasic:
return management.APIAuthMethodType_APIAUTHMETHODTYPE_BASIC
case proj_model.APIAuthMethodTypePrivateKeyJWT:
return management.APIAuthMethodType_APIAUTHMETHODTYPE_PRIVATE_KEY_JWT
default:
return management.APIAuthMethodType_APIAUTHMETHODTYPE_BASIC
}
}
func oidcVersionFromDomain(version domain.OIDCVersion) management.OIDCVersion {
switch version {
case domain.OIDCVersionV1:
return management.OIDCVersion_OIDCV1_0
default:
return management.OIDCVersion_OIDCV1_0
}
}
func authNKeyTypeToDomain(keyType management.AuthNKeyType) domain.AuthNKeyType {
switch keyType {
case management.AuthNKeyType_AUTHNKEY_JSON:
return domain.AuthNKeyTypeJSON
default:
return domain.AuthNKeyTypeNONE
}
}
func authNKeyTypeFromDomain(typ domain.AuthNKeyType) management.AuthNKeyType {
switch typ {
case domain.AuthNKeyTypeJSON:
return management.AuthNKeyType_AUTHNKEY_JSON
default:
return management.AuthNKeyType_AUTHNKEY_UNSPECIFIED
}
}
func appChangesToResponse(response *proj_model.ApplicationChanges, offset uint64, limit uint64) (_ *management.Changes) {
return &management.Changes{
Limit: limit,
Offset: offset,
Changes: appChangesToMgtAPI(response),
}
}
func appChangesToMgtAPI(changes *proj_model.ApplicationChanges) (_ []*management.Change) {
result := make([]*management.Change, len(changes.Changes))
for i, change := range changes.Changes {
b, err := json.Marshal(change.Data)
data := &structpb.Struct{}
err = protojson.Unmarshal(b, data)
if err != nil {
}
result[i] = &management.Change{
ChangeDate: change.ChangeDate,
EventType: message.NewLocalizedEventType(change.EventType),
Sequence: change.Sequence,
Editor: change.ModifierName,
EditorId: change.ModifierId,
Data: data,
}
}
return result
}
func clientKeyViewsFromModel(keys ...*key_model.AuthNKeyView) []*management.ClientKeyView {
keyViews := make([]*management.ClientKeyView, len(keys))
for i, key := range keys {
keyViews[i] = clientKeyViewFromModel(key)
}
return keyViews
}
func clientKeyViewFromModel(key *key_model.AuthNKeyView) *management.ClientKeyView {
creationDate, err := ptypes.TimestampProto(key.CreationDate)
logging.Log("MANAG-DAs2t").OnError(err).Debug("unable to parse timestamp")
expirationDate, err := ptypes.TimestampProto(key.ExpirationDate)
logging.Log("MANAG-BDgh4").OnError(err).Debug("unable to parse timestamp")
return &management.ClientKeyView{
Id: key.ID,
CreationDate: creationDate,
ExpirationDate: expirationDate,
Sequence: key.Sequence,
Type: authNKeyTypeFromModel(key.Type),
}
}
func authNKeyTypeFromModel(typ key_model.AuthNKeyType) management.AuthNKeyType {
switch typ {
case key_model.AuthNKeyTypeJSON:
return management.AuthNKeyType_AUTHNKEY_JSON
default:
return management.AuthNKeyType_AUTHNKEY_UNSPECIFIED
}
}
func clientKeySearchRequestToModel(req *management.ClientKeySearchRequest) *key_model.AuthNKeySearchRequest {
return &key_model.AuthNKeySearchRequest{
Offset: req.Offset,
Limit: req.Limit,
Asc: req.Asc,
Queries: []*key_model.AuthNKeySearchQuery{
{
Key: key_model.AuthNKeyObjectType,
Method: domain.SearchMethodEquals,
Value: key_model.AuthNKeyObjectTypeApplication,
}, {
Key: key_model.AuthNKeyObjectID,
Method: domain.SearchMethodEquals,
Value: req.ApplicationId,
},
},
}
}
func clientKeySearchResponseFromModel(req *key_model.AuthNKeySearchResponse) *management.ClientKeySearchResponse {
viewTimestamp, err := ptypes.TimestampProto(req.Timestamp)
logging.Log("MANAG-Sk9ds").OnError(err).Debug("unable to parse cretaion date")
return &management.ClientKeySearchResponse{
Offset: req.Offset,
Limit: req.Limit,
TotalResult: req.TotalResult,
ProcessedSequence: req.Sequence,
ViewTimestamp: viewTimestamp,
Result: clientKeyViewsFromModel(req.Result...),
}
}

View File

@@ -1,50 +0,0 @@
package management
import (
"strings"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
grpc_util "github.com/caos/zitadel/internal/api/grpc"
"github.com/caos/zitadel/internal/api/grpc/server"
"github.com/caos/zitadel/pkg/grpc/management"
)
type Gateway struct {
grpcEndpoint string
port string
cutomHeaders []string
}
func StartGateway(conf grpc_util.GatewayConfig) *Gateway {
return &Gateway{
grpcEndpoint: conf.GRPCEndpoint,
port: conf.Port,
cutomHeaders: conf.CustomHeaders,
}
}
func (gw *Gateway) Gateway() server.GatewayFunc {
return management.RegisterManagementServiceHandlerFromEndpoint
}
func (gw *Gateway) GRPCEndpoint() string {
return ":" + gw.grpcEndpoint
}
func (gw *Gateway) GatewayPort() string {
return gw.port
}
func (gw *Gateway) GatewayServeMuxOptions() []runtime.ServeMuxOption {
return []runtime.ServeMuxOption{
runtime.WithIncomingHeaderMatcher(func(header string) (string, bool) {
for _, customHeader := range gw.cutomHeaders {
if strings.HasPrefix(strings.ToLower(header), customHeader) {
return header, true
}
}
return runtime.DefaultHeaderMatcher(header)
}),
}
}

View File

@@ -3,15 +3,16 @@ package management
import (
"context"
"github.com/golang/protobuf/ptypes/empty"
"github.com/caos/zitadel/pkg/grpc/management"
mgmt_pb "github.com/caos/zitadel/pkg/grpc/management"
)
func (s *Server) GetIam(ctx context.Context, _ *empty.Empty) (*management.Iam, error) {
func (s *Server) GetIAM(ctx context.Context, req *mgmt_pb.GetIAMRequest) (*mgmt_pb.GetIAMResponse, error) {
iam, err := s.project.GetIAMByID(ctx)
if err != nil {
return nil, err
}
return iamFromModel(iam), nil
return &mgmt_pb.GetIAMResponse{
GlobalOrgId: iam.GlobalOrgID,
IamProjectId: iam.IAMProjectID,
}, nil
}

View File

@@ -1,36 +0,0 @@
package management
import (
"github.com/caos/zitadel/internal/domain"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/pkg/grpc/management"
)
func iamFromModel(iam *iam_model.IAM) *management.Iam {
return &management.Iam{
IamProjectId: iam.IAMProjectID,
GlobalOrgId: iam.GlobalOrgID,
SetUpDone: iamSetupStepFromModel(iam.SetUpDone),
SetUpStarted: iamSetupStepFromModel(iam.SetUpStarted),
}
}
func iamSetupStepFromModel(step domain.Step) management.IamSetupStep {
switch step {
case domain.Step1:
return management.IamSetupStep_iam_setup_step_1
case domain.Step2:
return management.IamSetupStep_iam_setup_step_2
// case iam_model.Step3:
// return management.IamSetupStep_iam_setup_step_3
// case iam_model.Step4:
// return management.IamSetupStep_iam_setup_step_4
// case iam_model.Step5:
// return management.IamSetupStep_iam_setup_step_5
// case iam_model.Step6:
// return management.IamSetupStep_iam_setup_step_6
default:
return management.IamSetupStep_iam_setup_step_UNDEFINED
}
}

View File

@@ -0,0 +1,35 @@
package management
import (
"context"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
mgmt_pb "github.com/caos/zitadel/pkg/grpc/management"
)
func (s *Server) GetOrgIDPByID(ctx context.Context, req *mgmt_pb.GetOrgIDPByIDRequest) (*mgmt_pb.GetOrgIDPByIDResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetOrgIDPByID not implemented")
}
func (s *Server) ListOrgIDPs(ctx context.Context, req *mgmt_pb.ListOrgIDPsRequest) (*mgmt_pb.ListOrgIDPsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ListOrgIDPs not implemented")
}
func (s *Server) AddOrgOIDCIDP(ctx context.Context, req *mgmt_pb.AddOrgOIDCIDPRequest) (*mgmt_pb.AddOrgOIDCIDPResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method AddOrgOIDCIDP not implemented")
}
func (s *Server) DeactivateOrgIDP(ctx context.Context, req *mgmt_pb.DeactivateOrgIDPRequest) (*mgmt_pb.DeactivateOrgIDPResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method DeactivateOrgIDP not implemented")
}
func (s *Server) ReactivateOrgIDP(ctx context.Context, req *mgmt_pb.ReactivateOrgIDPRequest) (*mgmt_pb.ReactivateOrgIDPResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ReactivateOrgIDP not implemented")
}
func (s *Server) RemoveOrgIDP(ctx context.Context, req *mgmt_pb.RemoveOrgIDPRequest) (*mgmt_pb.RemoveOrgIDPResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method RemoveOrgIDP not implemented")
}
func (s *Server) UpdateOrgIDP(ctx context.Context, req *mgmt_pb.UpdateOrgIDPRequest) (*mgmt_pb.UpdateOrgIDPResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method UpdateOrgIDP not implemented")
}
func (s *Server) UpdateOrgIDPOIDCConfig(ctx context.Context, req *mgmt_pb.UpdateOrgIDPOIDCConfigRequest) (*mgmt_pb.UpdateOrgIDPOIDCConfigResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method UpdateOrgIDPOIDCConfig not implemented")
}

View File

@@ -1,77 +0,0 @@
package management
import (
"context"
"github.com/golang/protobuf/ptypes/empty"
"github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/pkg/grpc/management"
)
func (s *Server) IdpByID(ctx context.Context, id *management.IdpID) (*management.IdpView, error) {
config, err := s.org.IDPConfigByID(ctx, id.Id)
if err != nil {
return nil, err
}
return idpViewFromModel(config), nil
}
func (s *Server) CreateOidcIdp(ctx context.Context, oidcIdpConfig *management.OidcIdpConfigCreate) (*management.Idp, error) {
config, err := s.command.AddIDPConfig(ctx, createOidcIdpToDomain(oidcIdpConfig))
if err != nil {
return nil, err
}
return idpFromDomain(config), nil
}
func (s *Server) UpdateIdpConfig(ctx context.Context, idpConfig *management.IdpUpdate) (*management.Idp, error) {
config, err := s.command.ChangeIDPConfig(ctx, updateIdpToDomain(ctx, idpConfig))
if err != nil {
return nil, err
}
return idpFromDomain(config), nil
}
func (s *Server) DeactivateIdpConfig(ctx context.Context, id *management.IdpID) (*empty.Empty, error) {
err := s.command.DeactivateIDPConfig(ctx, id.Id, authz.GetCtxData(ctx).OrgID)
return &empty.Empty{}, err
}
func (s *Server) ReactivateIdpConfig(ctx context.Context, id *management.IdpID) (*empty.Empty, error) {
err := s.command.ReactivateIDPConfig(ctx, id.Id, authz.GetCtxData(ctx).OrgID)
return &empty.Empty{}, err
}
func (s *Server) RemoveIdpConfig(ctx context.Context, id *management.IdpID) (*empty.Empty, error) {
externalIdps, err := s.user.ExternalIDPsByIDPConfigIDAndResourceOwner(ctx, id.Id, authz.GetCtxData(ctx).OrgID)
if err != nil {
return &empty.Empty{}, err
}
providers, err := s.org.GetIDPProvidersByIDPConfigID(ctx, authz.GetCtxData(ctx).OrgID, id.Id)
if err != nil {
return &empty.Empty{}, err
}
err = s.command.RemoveIDPConfig(ctx, id.Id, authz.GetCtxData(ctx).OrgID, len(providers) > 0, externalIDPViewsToDomain(externalIdps)...)
return &empty.Empty{}, err
}
func (s *Server) UpdateOidcIdpConfig(ctx context.Context, request *management.OidcIdpConfigUpdate) (*management.OidcIdpConfig, error) {
config, err := s.command.ChangeIDPOIDCConfig(ctx, updateOidcIdpToDomain(ctx, request))
if err != nil {
return nil, err
}
return oidcIdpConfigFromDomain(config), nil
}
func (s *Server) SearchIdps(ctx context.Context, request *management.IdpSearchRequest) (*management.IdpSearchResponse, error) {
searchRequest, err := idpConfigSearchRequestToModel(request)
if err != nil {
return nil, err
}
response, err := s.org.SearchIDPConfigs(ctx, searchRequest)
if err != nil {
return nil, err
}
return idpConfigSearchResponseFromModel(response), nil
}

View File

@@ -1,347 +0,0 @@
package management
import (
"context"
"github.com/caos/zitadel/internal/user/model"
"github.com/caos/logging"
"github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/internal/domain"
caos_errors "github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/eventstore/v1/models"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/pkg/grpc/management"
"github.com/golang/protobuf/ptypes"
"google.golang.org/protobuf/types/known/timestamppb"
"strconv"
)
func createOidcIdpToDomain(idp *management.OidcIdpConfigCreate) *domain.IDPConfig {
return &domain.IDPConfig{
Name: idp.Name,
StylingType: idpConfigStylingTypeToDomain(idp.StylingType),
Type: domain.IDPConfigTypeOIDC,
OIDCConfig: &domain.OIDCIDPConfig{
ClientID: idp.ClientId,
ClientSecretString: idp.ClientSecret,
Issuer: idp.Issuer,
Scopes: idp.Scopes,
IDPDisplayNameMapping: oidcMappingFieldToDomain(idp.IdpDisplayNameMapping),
UsernameMapping: oidcMappingFieldToDomain(idp.UsernameMapping),
},
}
}
func updateIdpToDomain(ctx context.Context, idp *management.IdpUpdate) *domain.IDPConfig {
return &domain.IDPConfig{
ObjectRoot: models.ObjectRoot{
AggregateID: authz.GetCtxData(ctx).OrgID,
},
IDPConfigID: idp.Id,
Name: idp.Name,
StylingType: idpConfigStylingTypeToDomain(idp.StylingType),
}
}
func updateOidcIdpToDomain(ctx context.Context, idp *management.OidcIdpConfigUpdate) *domain.OIDCIDPConfig {
return &domain.OIDCIDPConfig{
ObjectRoot: models.ObjectRoot{
AggregateID: authz.GetCtxData(ctx).OrgID,
},
IDPConfigID: idp.IdpId,
ClientID: idp.ClientId,
ClientSecretString: idp.ClientSecret,
Issuer: idp.Issuer,
Scopes: idp.Scopes,
IDPDisplayNameMapping: oidcMappingFieldToDomain(idp.IdpDisplayNameMapping),
UsernameMapping: oidcMappingFieldToDomain(idp.UsernameMapping),
}
}
func idpFromDomain(idp *domain.IDPConfig) *management.Idp {
return &management.Idp{
Id: idp.IDPConfigID,
ChangeDate: timestamppb.New(idp.ChangeDate),
Sequence: idp.Sequence,
Name: idp.Name,
StylingType: idpConfigStylingTypeFromDomain(idp.StylingType),
State: idpConfigStateFromDomain(idp.State),
IdpConfig: idpConfigFromDomain(idp),
}
}
func idpViewFromModel(idp *iam_model.IDPConfigView) *management.IdpView {
creationDate, err := ptypes.TimestampProto(idp.CreationDate)
logging.Log("GRPC-8dju8").OnError(err).Debug("date parse failed")
changeDate, err := ptypes.TimestampProto(idp.ChangeDate)
logging.Log("GRPC-Dsj8i").OnError(err).Debug("date parse failed")
return &management.IdpView{
Id: idp.IDPConfigID,
CreationDate: creationDate,
ChangeDate: changeDate,
Sequence: idp.Sequence,
ProviderType: idpProviderTypeFromModel(idp.IDPProviderType),
Name: idp.Name,
StylingType: idpConfigStylingTypeFromModel(idp.StylingType),
State: idpConfigStateFromModel(idp.State),
IdpConfigView: idpConfigViewFromModel(idp),
}
}
func idpConfigFromDomain(idp *domain.IDPConfig) *management.Idp_OidcConfig {
if idp.Type == domain.IDPConfigTypeOIDC {
return &management.Idp_OidcConfig{
OidcConfig: oidcIdpConfigFromDomain(idp.OIDCConfig),
}
}
return nil
}
func idpConfigFromModel(idp *iam_model.IDPConfig) *management.Idp_OidcConfig {
if idp.Type == iam_model.IDPConfigTypeOIDC {
return &management.Idp_OidcConfig{
OidcConfig: oidcIdpConfigFromModel(idp.OIDCConfig),
}
}
return nil
}
func oidcIdpConfigFromDomain(idp *domain.OIDCIDPConfig) *management.OidcIdpConfig {
return &management.OidcIdpConfig{
ClientId: idp.ClientID,
Issuer: idp.Issuer,
Scopes: idp.Scopes,
IdpDisplayNameMapping: oidcMappingFieldFromDomain(idp.IDPDisplayNameMapping),
UsernameMapping: oidcMappingFieldFromDomain(idp.UsernameMapping),
}
}
func oidcIdpConfigFromModel(idp *iam_model.OIDCIDPConfig) *management.OidcIdpConfig {
return &management.OidcIdpConfig{
ClientId: idp.ClientID,
Issuer: idp.Issuer,
Scopes: idp.Scopes,
IdpDisplayNameMapping: oidcMappingFieldFromModel(idp.IDPDisplayNameMapping),
UsernameMapping: oidcMappingFieldFromModel(idp.UsernameMapping),
}
}
func idpConfigViewFromModel(idp *iam_model.IDPConfigView) *management.IdpView_OidcConfig {
if idp.IsOIDC {
return &management.IdpView_OidcConfig{
OidcConfig: oidcIdpConfigViewFromModel(idp),
}
}
return nil
}
func oidcIdpConfigViewFromModel(idp *iam_model.IDPConfigView) *management.OidcIdpConfigView {
return &management.OidcIdpConfigView{
ClientId: idp.OIDCClientID,
Issuer: idp.OIDCIssuer,
Scopes: idp.OIDCScopes,
IdpDisplayNameMapping: oidcMappingFieldFromModel(idp.OIDCIDPDisplayNameMapping),
UsernameMapping: oidcMappingFieldFromModel(idp.OIDCUsernameMapping),
}
}
func idpConfigStateFromDomain(state domain.IDPConfigState) management.IdpState {
switch state {
case domain.IDPConfigStateActive:
return management.IdpState_IDPCONFIGSTATE_ACTIVE
case domain.IDPConfigStateInactive:
return management.IdpState_IDPCONFIGSTATE_INACTIVE
default:
return management.IdpState_IDPCONFIGSTATE_UNSPECIFIED
}
}
func idpConfigStateFromModel(state iam_model.IDPConfigState) management.IdpState {
switch state {
case iam_model.IDPConfigStateActive:
return management.IdpState_IDPCONFIGSTATE_ACTIVE
case iam_model.IDPConfigStateInactive:
return management.IdpState_IDPCONFIGSTATE_INACTIVE
default:
return management.IdpState_IDPCONFIGSTATE_UNSPECIFIED
}
}
func idpConfigSearchRequestToModel(request *management.IdpSearchRequest) (*iam_model.IDPConfigSearchRequest, error) {
convertedSearchRequest := &iam_model.IDPConfigSearchRequest{
Limit: request.Limit,
Offset: request.Offset,
}
convertedQueries, err := idpConfigSearchQueriesToModel(request.Queries)
if err != nil {
return nil, err
}
convertedSearchRequest.Queries = convertedQueries
return convertedSearchRequest, nil
}
func idpConfigSearchQueriesToModel(queries []*management.IdpSearchQuery) ([]*iam_model.IDPConfigSearchQuery, error) {
modelQueries := make([]*iam_model.IDPConfigSearchQuery, len(queries))
for i, query := range queries {
converted, err := idpConfigSearchQueryToModel(query)
if err != nil {
return nil, err
}
modelQueries[i] = converted
}
return modelQueries, nil
}
func idpConfigSearchQueryToModel(query *management.IdpSearchQuery) (*iam_model.IDPConfigSearchQuery, error) {
converted := &iam_model.IDPConfigSearchQuery{
Key: idpConfigSearchKeyToModel(query.Key),
Method: searchMethodToModel(query.Method),
Value: query.Value,
}
if query.Key != management.IdpSearchKey_IDPSEARCHKEY_PROVIDER_TYPE {
return converted, nil
}
value, err := idpProviderTypeStringToModel(query.Value)
if err != nil {
return nil, err
}
converted.Value = value
return converted, nil
}
func idpConfigSearchKeyToModel(key management.IdpSearchKey) iam_model.IDPConfigSearchKey {
switch key {
case management.IdpSearchKey_IDPSEARCHKEY_IDP_CONFIG_ID:
return iam_model.IDPConfigSearchKeyIdpConfigID
case management.IdpSearchKey_IDPSEARCHKEY_NAME:
return iam_model.IDPConfigSearchKeyName
case management.IdpSearchKey_IDPSEARCHKEY_PROVIDER_TYPE:
return iam_model.IDPConfigSearchKeyIdpProviderType
default:
return iam_model.IDPConfigSearchKeyUnspecified
}
}
func idpConfigSearchResponseFromModel(resp *iam_model.IDPConfigSearchResponse) *management.IdpSearchResponse {
timestamp, err := ptypes.TimestampProto(resp.Timestamp)
logging.Log("GRPC-KSi8c").OnError(err).Debug("date parse failed")
return &management.IdpSearchResponse{
Limit: resp.Limit,
Offset: resp.Offset,
TotalResult: resp.TotalResult,
Result: idpConfigsFromView(resp.Result),
ProcessedSequence: resp.Sequence,
ViewTimestamp: timestamp,
}
}
func idpConfigsFromView(viewIdps []*iam_model.IDPConfigView) []*management.IdpView {
idps := make([]*management.IdpView, len(viewIdps))
for i, idp := range viewIdps {
idps[i] = idpViewFromModel(idp)
}
return idps
}
func oidcMappingFieldFromDomain(field domain.OIDCMappingField) management.OIDCMappingField {
switch field {
case domain.OIDCMappingFieldPreferredLoginName:
return management.OIDCMappingField_OIDCMAPPINGFIELD_PREFERRED_USERNAME
case domain.OIDCMappingFieldEmail:
return management.OIDCMappingField_OIDCMAPPINGFIELD_EMAIL
default:
return management.OIDCMappingField_OIDCMAPPINGFIELD_UNSPECIFIED
}
}
func oidcMappingFieldFromModel(field iam_model.OIDCMappingField) management.OIDCMappingField {
switch field {
case iam_model.OIDCMappingFieldPreferredLoginName:
return management.OIDCMappingField_OIDCMAPPINGFIELD_PREFERRED_USERNAME
case iam_model.OIDCMappingFieldEmail:
return management.OIDCMappingField_OIDCMAPPINGFIELD_EMAIL
default:
return management.OIDCMappingField_OIDCMAPPINGFIELD_UNSPECIFIED
}
}
func oidcMappingFieldToDomain(field management.OIDCMappingField) domain.OIDCMappingField {
switch field {
case management.OIDCMappingField_OIDCMAPPINGFIELD_PREFERRED_USERNAME:
return domain.OIDCMappingFieldPreferredLoginName
case management.OIDCMappingField_OIDCMAPPINGFIELD_EMAIL:
return domain.OIDCMappingFieldEmail
default:
return domain.OIDCMappingFieldUnspecified
}
}
func oidcMappingFieldToModel(field management.OIDCMappingField) iam_model.OIDCMappingField {
switch field {
case management.OIDCMappingField_OIDCMAPPINGFIELD_PREFERRED_USERNAME:
return iam_model.OIDCMappingFieldPreferredLoginName
case management.OIDCMappingField_OIDCMAPPINGFIELD_EMAIL:
return iam_model.OIDCMappingFieldEmail
default:
return iam_model.OIDCMappingFieldUnspecified
}
}
func idpConfigStylingTypeFromDomain(stylingType domain.IDPConfigStylingType) management.IdpStylingType {
switch stylingType {
case domain.IDPConfigStylingTypeGoogle:
return management.IdpStylingType_IDPSTYLINGTYPE_GOOGLE
default:
return management.IdpStylingType_IDPSTYLINGTYPE_UNSPECIFIED
}
}
func idpConfigStylingTypeFromModel(stylingType iam_model.IDPStylingType) management.IdpStylingType {
switch stylingType {
case iam_model.IDPStylingTypeGoogle:
return management.IdpStylingType_IDPSTYLINGTYPE_GOOGLE
default:
return management.IdpStylingType_IDPSTYLINGTYPE_UNSPECIFIED
}
}
func idpConfigStylingTypeToDomain(stylingType management.IdpStylingType) domain.IDPConfigStylingType {
switch stylingType {
case management.IdpStylingType_IDPSTYLINGTYPE_GOOGLE:
return domain.IDPConfigStylingTypeGoogle
default:
return domain.IDPConfigStylingTypeUnspecified
}
}
func idpProviderTypeStringToModel(providerType string) (iam_model.IDPProviderType, error) {
i, _ := strconv.ParseInt(providerType, 10, 32)
switch management.IdpProviderType(i) {
case management.IdpProviderType_IDPPROVIDERTYPE_SYSTEM:
return iam_model.IDPProviderTypeSystem, nil
case management.IdpProviderType_IDPPROVIDERTYPE_ORG:
return iam_model.IDPProviderTypeOrg, nil
default:
return 0, caos_errors.ThrowPreconditionFailed(nil, "MGMT-6is9f", "Errors.Org.IDP.InvalidSearchQuery")
}
}
func externalIDPViewsToDomain(idps []*model.ExternalIDPView) []*domain.ExternalIDP {
externalIDPs := make([]*domain.ExternalIDP, len(idps))
for i, idp := range idps {
externalIDPs[i] = &domain.ExternalIDP{
ObjectRoot: models.ObjectRoot{
AggregateID: idp.UserID,
ResourceOwner: idp.ResourceOwner,
},
IDPConfigID: idp.IDPConfigID,
ExternalUserID: idp.ExternalUserID,
DisplayName: idp.UserDisplayName,
}
}
return externalIDPs
}

View File

@@ -0,0 +1,18 @@
package management
import (
"context"
mgmt_pb "github.com/caos/zitadel/pkg/grpc/management"
)
func (s *Server) Healthz(context.Context, *mgmt_pb.HealthzRequest) (*mgmt_pb.HealthzResponse, error) {
return &mgmt_pb.HealthzResponse{}, nil
}
func (s *Server) GetOIDCInformation(ctx context.Context, req *mgmt_pb.GetOIDCInformationRequest) (*mgmt_pb.GetOIDCInformationResponse, error) {
return &mgmt_pb.GetOIDCInformationResponse{
Issuer: s.systemDefaults.ZitadelDocs.Issuer,
DiscoveryEndpoint: s.systemDefaults.ZitadelDocs.DiscoveryEndpoint,
}, nil
}

View File

@@ -1,114 +0,0 @@
package management
import (
"context"
"github.com/golang/protobuf/ptypes/empty"
"github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/pkg/grpc/management"
)
func (s *Server) GetLoginPolicy(ctx context.Context, _ *empty.Empty) (*management.LoginPolicyView, error) {
result, err := s.org.GetLoginPolicy(ctx)
if err != nil {
return nil, err
}
return loginPolicyViewFromModel(result), nil
}
func (s *Server) GetDefaultLoginPolicy(ctx context.Context, _ *empty.Empty) (*management.LoginPolicyView, error) {
result, err := s.org.GetDefaultLoginPolicy(ctx)
if err != nil {
return nil, err
}
return loginPolicyViewFromModel(result), nil
}
func (s *Server) CreateLoginPolicy(ctx context.Context, policy *management.LoginPolicyRequest) (*management.LoginPolicy, error) {
result, err := s.command.AddLoginPolicy(ctx, authz.GetCtxData(ctx).OrgID, loginPolicyRequestToDomain(ctx, policy))
if err != nil {
return nil, err
}
return loginPolicyFromDomain(result), nil
}
func (s *Server) UpdateLoginPolicy(ctx context.Context, policy *management.LoginPolicyRequest) (*management.LoginPolicy, error) {
result, err := s.command.ChangeLoginPolicy(ctx, authz.GetCtxData(ctx).OrgID, loginPolicyRequestToDomain(ctx, policy))
if err != nil {
return nil, err
}
return loginPolicyFromDomain(result), nil
}
func (s *Server) RemoveLoginPolicy(ctx context.Context, _ *empty.Empty) (*empty.Empty, error) {
err := s.command.RemoveLoginPolicy(ctx, authz.GetCtxData(ctx).OrgID)
return &empty.Empty{}, err
}
func (s *Server) GetLoginPolicyIdpProviders(ctx context.Context, request *management.IdpProviderSearchRequest) (*management.IdpProviderSearchResponse, error) {
result, err := s.org.SearchIDPProviders(ctx, idpProviderSearchRequestToModel(request))
if err != nil {
return nil, err
}
return idpProviderSearchResponseFromModel(result), nil
}
func (s *Server) AddIdpProviderToLoginPolicy(ctx context.Context, provider *management.IdpProviderAdd) (*management.IdpProvider, error) {
result, err := s.command.AddIDPProviderToLoginPolicy(ctx, authz.GetCtxData(ctx).OrgID, idpProviderAddToDomain(ctx, provider))
if err != nil {
return nil, err
}
return idpProviderFromDomain(result), nil
}
func (s *Server) RemoveIdpProviderFromLoginPolicy(ctx context.Context, provider *management.IdpProviderID) (*empty.Empty, error) {
externalIDPs, err := s.user.ExternalIDPsByIDPConfigIDAndResourceOwner(ctx, provider.IdpConfigId, authz.GetCtxData(ctx).OrgID)
if err != nil {
return &empty.Empty{}, err
}
err = s.command.RemoveIDPProviderFromLoginPolicy(ctx, authz.GetCtxData(ctx).OrgID, idpProviderIDToDomain(ctx, provider), externalIDPViewsToDomain(externalIDPs)...)
return &empty.Empty{}, err
}
func (s *Server) GetLoginPolicySecondFactors(ctx context.Context, _ *empty.Empty) (*management.SecondFactorsResult, error) {
result, err := s.org.SearchSecondFactors(ctx)
if err != nil {
return nil, err
}
return secondFactorResultFromModel(result), nil
}
func (s *Server) AddSecondFactorToLoginPolicy(ctx context.Context, mfa *management.SecondFactor) (*management.SecondFactor, error) {
result, err := s.command.AddSecondFactorToLoginPolicy(ctx, secondFactorTypeToDomain(mfa), authz.GetCtxData(ctx).OrgID)
if err != nil {
return nil, err
}
return secondFactorFromDomain(result), nil
}
func (s *Server) RemoveSecondFactorFromLoginPolicy(ctx context.Context, mfa *management.SecondFactor) (*empty.Empty, error) {
err := s.command.RemoveSecondFactorFromLoginPolicy(ctx, secondFactorTypeToDomain(mfa), authz.GetCtxData(ctx).OrgID)
return &empty.Empty{}, err
}
func (s *Server) GetLoginPolicyMultiFactors(ctx context.Context, _ *empty.Empty) (*management.MultiFactorsResult, error) {
result, err := s.org.SearchMultiFactors(ctx)
if err != nil {
return nil, err
}
return multiFactorResultFromModel(result), nil
}
func (s *Server) AddMultiFactorToLoginPolicy(ctx context.Context, mfa *management.MultiFactor) (*management.MultiFactor, error) {
result, err := s.command.AddMultiFactorToLoginPolicy(ctx, multiFactorTypeToDomain(mfa), authz.GetCtxData(ctx).OrgID)
if err != nil {
return nil, err
}
return multiFactorFromDomain(result), nil
}
func (s *Server) RemoveMultiFactorFromLoginPolicy(ctx context.Context, mfa *management.MultiFactor) (*empty.Empty, error) {
err := s.command.RemoveMultiFactorFromLoginPolicy(ctx, multiFactorTypeToDomain(mfa), authz.GetCtxData(ctx).OrgID)
return &empty.Empty{}, err
}

View File

@@ -1,292 +0,0 @@
package management
import (
"context"
"github.com/caos/logging"
"github.com/golang/protobuf/ptypes"
"google.golang.org/protobuf/types/known/timestamppb"
"github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/internal/domain"
"github.com/caos/zitadel/internal/eventstore/v1/models"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/pkg/grpc/management"
)
func loginPolicyRequestToDomain(ctx context.Context, policy *management.LoginPolicyRequest) *domain.LoginPolicy {
return &domain.LoginPolicy{
ObjectRoot: models.ObjectRoot{
AggregateID: authz.GetCtxData(ctx).OrgID,
},
AllowUsernamePassword: policy.AllowUsernamePassword,
AllowExternalIDP: policy.AllowExternalIdp,
AllowRegister: policy.AllowRegister,
ForceMFA: policy.ForceMfa,
PasswordlessType: passwordlessTypeToDomain(policy.PasswordlessType),
}
}
func loginPolicyFromDomain(policy *domain.LoginPolicy) *management.LoginPolicy {
return &management.LoginPolicy{
AllowUsernamePassword: policy.AllowUsernamePassword,
AllowExternalIdp: policy.AllowExternalIDP,
AllowRegister: policy.AllowRegister,
ChangeDate: timestamppb.New(policy.ChangeDate),
ForceMfa: policy.ForceMFA,
PasswordlessType: passwordlessTypeFromDomain(policy.PasswordlessType),
}
}
func loginPolicyViewFromModel(policy *iam_model.LoginPolicyView) *management.LoginPolicyView {
creationDate, err := ptypes.TimestampProto(policy.CreationDate)
logging.Log("GRPC-5Tsm8").OnError(err).Debug("date parse failed")
changeDate, err := ptypes.TimestampProto(policy.ChangeDate)
logging.Log("GRPC-8dJgs").OnError(err).Debug("date parse failed")
return &management.LoginPolicyView{
Default: policy.Default,
AllowUsernamePassword: policy.AllowUsernamePassword,
AllowExternalIdp: policy.AllowExternalIDP,
AllowRegister: policy.AllowRegister,
CreationDate: creationDate,
ChangeDate: changeDate,
ForceMfa: policy.ForceMFA,
PasswordlessType: passwordlessTypeFromModel(policy.PasswordlessType),
}
}
func idpProviderSearchRequestToModel(request *management.IdpProviderSearchRequest) *iam_model.IDPProviderSearchRequest {
return &iam_model.IDPProviderSearchRequest{
Limit: request.Limit,
Offset: request.Offset,
}
}
func idpProviderSearchResponseFromModel(response *iam_model.IDPProviderSearchResponse) *management.IdpProviderSearchResponse {
return &management.IdpProviderSearchResponse{
Limit: response.Limit,
Offset: response.Offset,
TotalResult: response.TotalResult,
Result: idpProviderViewsFromModel(response.Result),
}
}
func idpProviderIDToDomain(ctx context.Context, provider *management.IdpProviderID) *domain.IDPProvider {
return &domain.IDPProvider{
ObjectRoot: models.ObjectRoot{
AggregateID: authz.GetCtxData(ctx).OrgID,
},
IDPConfigID: provider.IdpConfigId,
}
}
func idpProviderAddToDomain(ctx context.Context, provider *management.IdpProviderAdd) *domain.IDPProvider {
return &domain.IDPProvider{
ObjectRoot: models.ObjectRoot{
AggregateID: authz.GetCtxData(ctx).OrgID,
},
IDPConfigID: provider.IdpConfigId,
Type: idpProviderTypeToDomain(provider.IdpProviderType),
}
}
func idpProviderIDFromModel(provider *iam_model.IDPProvider) *management.IdpProviderID {
return &management.IdpProviderID{
IdpConfigId: provider.IDPConfigID,
}
}
func idpProviderFromDomain(provider *domain.IDPProvider) *management.IdpProvider {
return &management.IdpProvider{
IdpConfigId: provider.IDPConfigID,
IdpProvider_Type: idpProviderTypeFromDomain(provider.Type),
}
}
func idpProviderViewsFromModel(providers []*iam_model.IDPProviderView) []*management.IdpProviderView {
converted := make([]*management.IdpProviderView, len(providers))
for i, provider := range providers {
converted[i] = idpProviderViewFromModel(provider)
}
return converted
}
func idpProviderViewFromModel(provider *iam_model.IDPProviderView) *management.IdpProviderView {
return &management.IdpProviderView{
IdpConfigId: provider.IDPConfigID,
Name: provider.Name,
Type: idpProviderTypeFromModel(provider.IDPProviderType),
}
}
func idpConfigTypeToModel(providerType iam_model.IdpConfigType) management.IdpType {
switch providerType {
case iam_model.IDPConfigTypeOIDC:
return management.IdpType_IDPTYPE_OIDC
case iam_model.IDPConfigTypeSAML:
return management.IdpType_IDPTYPE_SAML
default:
return management.IdpType_IDPTYPE_UNSPECIFIED
}
}
func idpProviderTypeToDomain(providerType management.IdpProviderType) domain.IdentityProviderType {
switch providerType {
case management.IdpProviderType_IDPPROVIDERTYPE_SYSTEM:
return domain.IdentityProviderTypeSystem
case management.IdpProviderType_IDPPROVIDERTYPE_ORG:
return domain.IdentityProviderTypeOrg
default:
return domain.IdentityProviderTypeSystem
}
}
func idpProviderTypeFromDomain(providerType domain.IdentityProviderType) management.IdpProviderType {
switch providerType {
case domain.IdentityProviderTypeSystem:
return management.IdpProviderType_IDPPROVIDERTYPE_SYSTEM
case domain.IdentityProviderTypeOrg:
return management.IdpProviderType_IDPPROVIDERTYPE_ORG
default:
return management.IdpProviderType_IDPPROVIDERTYPE_UNSPECIFIED
}
}
func idpProviderTypeFromModel(providerType iam_model.IDPProviderType) management.IdpProviderType {
switch providerType {
case iam_model.IDPProviderTypeSystem:
return management.IdpProviderType_IDPPROVIDERTYPE_SYSTEM
case iam_model.IDPProviderTypeOrg:
return management.IdpProviderType_IDPPROVIDERTYPE_ORG
default:
return management.IdpProviderType_IDPPROVIDERTYPE_UNSPECIFIED
}
}
func secondFactorResultFromModel(result *iam_model.SecondFactorsSearchResponse) *management.SecondFactorsResult {
converted := make([]management.SecondFactorType, len(result.Result))
for i, mfaType := range result.Result {
converted[i] = secondFactorTypeFromModel(mfaType)
}
return &management.SecondFactorsResult{
SecondFactors: converted,
}
}
func secondFactorFromDomain(mfaType domain.SecondFactorType) *management.SecondFactor {
return &management.SecondFactor{
SecondFactor: secondFactorTypeFromDomain(mfaType),
}
}
func secondFactorFromModel(mfaType iam_model.SecondFactorType) *management.SecondFactor {
return &management.SecondFactor{
SecondFactor: secondFactorTypeFromModel(mfaType),
}
}
func secondFactorTypeFromDomain(mfaType domain.SecondFactorType) management.SecondFactorType {
switch mfaType {
case domain.SecondFactorTypeOTP:
return management.SecondFactorType_SECONDFACTORTYPE_OTP
case domain.SecondFactorTypeU2F:
return management.SecondFactorType_SECONDFACTORTYPE_U2F
default:
return management.SecondFactorType_SECONDFACTORTYPE_UNSPECIFIED
}
}
func secondFactorTypeFromModel(mfaType iam_model.SecondFactorType) management.SecondFactorType {
switch mfaType {
case iam_model.SecondFactorTypeOTP:
return management.SecondFactorType_SECONDFACTORTYPE_OTP
case iam_model.SecondFactorTypeU2F:
return management.SecondFactorType_SECONDFACTORTYPE_U2F
default:
return management.SecondFactorType_SECONDFACTORTYPE_UNSPECIFIED
}
}
func secondFactorTypeToDomain(mfaType *management.SecondFactor) domain.SecondFactorType {
switch mfaType.SecondFactor {
case management.SecondFactorType_SECONDFACTORTYPE_OTP:
return domain.SecondFactorTypeOTP
case management.SecondFactorType_SECONDFACTORTYPE_U2F:
return domain.SecondFactorTypeU2F
default:
return domain.SecondFactorTypeUnspecified
}
}
func multiFactorResultFromModel(result *iam_model.MultiFactorsSearchResponse) *management.MultiFactorsResult {
converted := make([]management.MultiFactorType, len(result.Result))
for i, mfaType := range result.Result {
converted[i] = multiFactorTypeFromModel(mfaType)
}
return &management.MultiFactorsResult{
MultiFactors: converted,
}
}
func multiFactorFromDomain(mfaType domain.MultiFactorType) *management.MultiFactor {
return &management.MultiFactor{
MultiFactor: multiFactorTypeFromDomain(mfaType),
}
}
func multiFactorTypeFromDomain(mfaType domain.MultiFactorType) management.MultiFactorType {
switch mfaType {
case domain.MultiFactorTypeU2FWithPIN:
return management.MultiFactorType_MULTIFACTORTYPE_U2F_WITH_PIN
default:
return management.MultiFactorType_MULTIFACTORTYPE_UNSPECIFIED
}
}
func multiFactorTypeFromModel(mfaType iam_model.MultiFactorType) management.MultiFactorType {
switch mfaType {
case iam_model.MultiFactorTypeU2FWithPIN:
return management.MultiFactorType_MULTIFACTORTYPE_U2F_WITH_PIN
default:
return management.MultiFactorType_MULTIFACTORTYPE_UNSPECIFIED
}
}
func multiFactorTypeToDomain(mfaType *management.MultiFactor) domain.MultiFactorType {
switch mfaType.MultiFactor {
case management.MultiFactorType_MULTIFACTORTYPE_U2F_WITH_PIN:
return domain.MultiFactorTypeU2FWithPIN
default:
return domain.MultiFactorTypeUnspecified
}
}
func passwordlessTypeFromModel(passwordlessType iam_model.PasswordlessType) management.PasswordlessType {
switch passwordlessType {
case iam_model.PasswordlessTypeAllowed:
return management.PasswordlessType_PASSWORDLESSTYPE_ALLOWED
default:
return management.PasswordlessType_PASSWORDLESSTYPE_NOT_ALLOWED
}
}
func passwordlessTypeFromDomain(passwordlessType domain.PasswordlessType) management.PasswordlessType {
switch passwordlessType {
case domain.PasswordlessTypeAllowed:
return management.PasswordlessType_PASSWORDLESSTYPE_ALLOWED
default:
return management.PasswordlessType_PASSWORDLESSTYPE_NOT_ALLOWED
}
}
func passwordlessTypeToDomain(passwordlessType management.PasswordlessType) domain.PasswordlessType {
switch passwordlessType {
case management.PasswordlessType_PASSWORDLESSTYPE_ALLOWED:
return domain.PasswordlessTypeAllowed
default:
return domain.PasswordlessTypeNotAllowed
}
}

View File

@@ -1,46 +0,0 @@
package management
import (
"context"
"github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/pkg/grpc/management"
"github.com/golang/protobuf/ptypes/empty"
)
func (s *Server) GetMailTemplate(ctx context.Context, _ *empty.Empty) (*management.MailTemplateView, error) {
result, err := s.org.GetMailTemplate(ctx)
if err != nil {
return nil, err
}
return mailTemplateViewFromModel(result), nil
}
func (s *Server) GetDefaultMailTemplate(ctx context.Context, _ *empty.Empty) (*management.MailTemplateView, error) {
result, err := s.org.GetDefaultMailTemplate(ctx)
if err != nil {
return nil, err
}
return mailTemplateViewFromModel(result), nil
}
func (s *Server) CreateMailTemplate(ctx context.Context, template *management.MailTemplateUpdate) (*management.MailTemplate, error) {
result, err := s.command.AddMailTemplate(ctx, authz.GetCtxData(ctx).OrgID, mailTemplateRequestToDomain(template))
if err != nil {
return nil, err
}
return mailTemplateFromDomain(result), nil
}
func (s *Server) UpdateMailTemplate(ctx context.Context, template *management.MailTemplateUpdate) (*management.MailTemplate, error) {
result, err := s.command.ChangeMailTemplate(ctx, authz.GetCtxData(ctx).OrgID, mailTemplateRequestToDomain(template))
if err != nil {
return nil, err
}
return mailTemplateFromDomain(result), nil
}
func (s *Server) RemoveMailTemplate(ctx context.Context, _ *empty.Empty) (*empty.Empty, error) {
err := s.command.RemoveMailTemplate(ctx, authz.GetCtxData(ctx).OrgID)
return &empty.Empty{}, err
}

View File

@@ -1,31 +0,0 @@
package management
import (
"github.com/caos/zitadel/internal/domain"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/pkg/grpc/management"
"google.golang.org/protobuf/types/known/timestamppb"
)
func mailTemplateRequestToDomain(mailTemplate *management.MailTemplateUpdate) *domain.MailTemplate {
return &domain.MailTemplate{
Template: mailTemplate.Template,
}
}
func mailTemplateFromDomain(mailTemplate *domain.MailTemplate) *management.MailTemplate {
return &management.MailTemplate{
Template: mailTemplate.Template,
CreationDate: timestamppb.New(mailTemplate.CreationDate),
ChangeDate: timestamppb.New(mailTemplate.ChangeDate),
}
}
func mailTemplateViewFromModel(mailTemplate *iam_model.MailTemplateView) *management.MailTemplateView {
return &management.MailTemplateView{
Default: mailTemplate.Default,
Template: mailTemplate.Template,
CreationDate: timestamppb.New(mailTemplate.CreationDate),
ChangeDate: timestamppb.New(mailTemplate.ChangeDate),
}
}

View File

@@ -1,46 +0,0 @@
package management
import (
"context"
"github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/pkg/grpc/management"
"github.com/golang/protobuf/ptypes/empty"
)
func (s *Server) GetMailTexts(ctx context.Context, _ *empty.Empty) (*management.MailTextsView, error) {
result, err := s.org.GetMailTexts(ctx)
if err != nil {
return nil, err
}
return mailTextsViewFromModel(result.Texts), nil
}
func (s *Server) GetDefaultMailTexts(ctx context.Context, _ *empty.Empty) (*management.MailTextsView, error) {
result, err := s.org.GetDefaultMailTexts(ctx)
if err != nil {
return nil, err
}
return mailTextsViewFromModel(result.Texts), nil
}
func (s *Server) CreateMailText(ctx context.Context, mailText *management.MailTextUpdate) (*management.MailText, error) {
result, err := s.command.AddMailText(ctx, authz.GetCtxData(ctx).OrgID, mailTextRequestToDomain(mailText))
if err != nil {
return nil, err
}
return mailTextFromDoamin(result), nil
}
func (s *Server) UpdateMailText(ctx context.Context, mailText *management.MailTextUpdate) (*management.MailText, error) {
result, err := s.command.ChangeMailText(ctx, authz.GetCtxData(ctx).OrgID, mailTextRequestToDomain(mailText))
if err != nil {
return nil, err
}
return mailTextFromDoamin(result), nil
}
func (s *Server) RemoveMailText(ctx context.Context, mailText *management.MailTextRemove) (*empty.Empty, error) {
err := s.command.RemoveMailText(ctx, authz.GetCtxData(ctx).OrgID, mailText.MailTextType, mailText.Language)
return &empty.Empty{}, err
}

View File

@@ -1,71 +0,0 @@
package management
import (
"github.com/caos/logging"
"github.com/caos/zitadel/internal/domain"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/pkg/grpc/management"
"github.com/golang/protobuf/ptypes"
"google.golang.org/protobuf/types/known/timestamppb"
)
func mailTextRequestToDomain(mailText *management.MailTextUpdate) *domain.MailText {
return &domain.MailText{
MailTextType: mailText.MailTextType,
Language: mailText.Language,
Title: mailText.Title,
PreHeader: mailText.PreHeader,
Subject: mailText.Subject,
Greeting: mailText.Greeting,
Text: mailText.Text,
ButtonText: mailText.ButtonText,
}
}
func mailTextFromDoamin(mailText *domain.MailText) *management.MailText {
return &management.MailText{
MailTextType: mailText.MailTextType,
Language: mailText.Language,
Title: mailText.Title,
PreHeader: mailText.PreHeader,
Subject: mailText.Subject,
Greeting: mailText.Greeting,
Text: mailText.Text,
ButtonText: mailText.ButtonText,
CreationDate: timestamppb.New(mailText.CreationDate),
ChangeDate: timestamppb.New(mailText.ChangeDate),
}
}
func mailTextsViewFromModel(queries []*iam_model.MailTextView) *management.MailTextsView {
modelQueries := make([]*management.MailTextView, len(queries))
for i, query := range queries {
modelQueries[i] = mailTextViewFromModel(query)
}
return &management.MailTextsView{
Texts: modelQueries,
}
}
func mailTextViewFromModel(mailText *iam_model.MailTextView) *management.MailTextView {
creationDate, err := ptypes.TimestampProto(mailText.CreationDate)
logging.Log("MANAG-koQnB").OnError(err).Debug("date parse failed")
changeDate, err := ptypes.TimestampProto(mailText.ChangeDate)
logging.Log("MANAG-ToDhD").OnError(err).Debug("date parse failed")
return &management.MailTextView{
Default: mailText.Default,
MailTextType: mailText.MailTextType,
Language: mailText.Language,
Title: mailText.Title,
PreHeader: mailText.PreHeader,
Subject: mailText.Subject,
Greeting: mailText.Greeting,
Text: mailText.Text,
ButtonText: mailText.ButtonText,
CreationDate: creationDate,
ChangeDate: changeDate,
}
}

View File

@@ -0,0 +1,5 @@
package management
//AppConfig is a type alias of the generated isApplication_AppConfig config
//to make it public
// type AppConfig = isApplication_AppConfig

View File

@@ -3,100 +3,246 @@ package management
import (
"context"
"github.com/golang/protobuf/ptypes/empty"
"github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/pkg/grpc/management"
change_grpc "github.com/caos/zitadel/internal/api/grpc/change"
member_grpc "github.com/caos/zitadel/internal/api/grpc/member"
"github.com/caos/zitadel/internal/api/grpc/object"
org_grpc "github.com/caos/zitadel/internal/api/grpc/org"
policy_grpc "github.com/caos/zitadel/internal/api/grpc/policy"
"github.com/caos/zitadel/internal/domain"
"github.com/caos/zitadel/internal/eventstore/v1/models"
org_model "github.com/caos/zitadel/internal/org/model"
mgmt_pb "github.com/caos/zitadel/pkg/grpc/management"
)
func (s *Server) CreateOrg(ctx context.Context, request *management.OrgCreateRequest) (_ *management.Org, err error) {
ctxData := authz.GetCtxData(ctx)
org, err := s.command.AddOrg(ctx, request.Name, ctxData.UserID, ctxData.ResourceOwner)
if err != nil {
return nil, err
}
return orgFromDomain(org), err
}
func (s *Server) GetMyOrg(ctx context.Context, _ *empty.Empty) (*management.OrgView, error) {
func (s *Server) GetMyOrg(ctx context.Context, req *mgmt_pb.GetMyOrgRequest) (*mgmt_pb.GetMyOrgResponse, error) {
org, err := s.org.OrgByID(ctx, authz.GetCtxData(ctx).OrgID)
if err != nil {
return nil, err
}
return orgViewFromModel(org), nil
return &mgmt_pb.GetMyOrgResponse{Org: org_grpc.OrgViewToPb(org)}, nil
}
func (s *Server) GetOrgByDomainGlobal(ctx context.Context, in *management.Domain) (*management.OrgView, error) {
org, err := s.org.OrgByDomainGlobal(ctx, in.Domain)
func (s *Server) GetOrgByDomainGlobal(ctx context.Context, req *mgmt_pb.GetOrgByDomainGlobalRequest) (*mgmt_pb.GetOrgByDomainGlobalResponse, error) {
org, err := s.org.OrgByDomainGlobal(ctx, req.Domain)
if err != nil {
return nil, err
}
return orgViewFromModel(org), nil
return &mgmt_pb.GetOrgByDomainGlobalResponse{Org: org_grpc.OrgViewToPb(org)}, nil
}
func (s *Server) DeactivateMyOrg(ctx context.Context, _ *empty.Empty) (*empty.Empty, error) {
err := s.command.DeactivateOrg(ctx, authz.GetCtxData(ctx).OrgID)
return &empty.Empty{}, err
}
func (s *Server) ReactivateMyOrg(ctx context.Context, _ *empty.Empty) (*empty.Empty, error) {
err := s.command.ReactivateOrg(ctx, authz.GetCtxData(ctx).OrgID)
return &empty.Empty{}, err
}
func (s *Server) SearchMyOrgDomains(ctx context.Context, in *management.OrgDomainSearchRequest) (*management.OrgDomainSearchResponse, error) {
domains, err := s.org.SearchMyOrgDomains(ctx, orgDomainSearchRequestToModel(in))
func (s *Server) ListOrgChanges(ctx context.Context, req *mgmt_pb.ListOrgChangesRequest) (*mgmt_pb.ListOrgChangesResponse, error) {
response, err := s.org.OrgChanges(ctx, authz.GetCtxData(ctx).OrgID, req.Query.Offset, uint64(req.Query.Limit), req.Query.Asc)
if err != nil {
return nil, err
}
return orgDomainSearchResponseFromModel(domains), nil
}
func (s *Server) AddMyOrgDomain(ctx context.Context, in *management.AddOrgDomainRequest) (*management.OrgDomain, error) {
domain, err := s.command.AddOrgDomain(ctx, addOrgDomainToDomain(ctx, in))
if err != nil {
return nil, err
}
return orgDomainFromDomain(domain), nil
}
func (s *Server) GenerateMyOrgDomainValidation(ctx context.Context, in *management.OrgDomainValidationRequest) (*management.OrgDomainValidationResponse, error) {
token, url, err := s.command.GenerateOrgDomainValidation(ctx, orgDomainValidationToDomain(ctx, in))
if err != nil {
return nil, err
}
return &management.OrgDomainValidationResponse{
Token: token,
Url: url,
return &mgmt_pb.ListOrgChangesResponse{
Result: change_grpc.OrgChangesToPb(response.Changes),
}, nil
}
func (s *Server) ValidateMyOrgDomain(ctx context.Context, in *management.ValidateOrgDomainRequest) (*empty.Empty, error) {
err := s.command.ValidateOrgDomain(ctx, validateOrgDomainToDomain(ctx, in))
return &empty.Empty{}, err
}
func (s *Server) SetMyPrimaryOrgDomain(ctx context.Context, in *management.PrimaryOrgDomainRequest) (*empty.Empty, error) {
err := s.command.SetPrimaryOrgDomain(ctx, primaryOrgDomainToDomain(ctx, in))
return &empty.Empty{}, err
}
func (s *Server) RemoveMyOrgDomain(ctx context.Context, in *management.RemoveOrgDomainRequest) (*empty.Empty, error) {
err := s.command.RemoveOrgDomain(ctx, removeOrgDomainToDomain(ctx, in))
return &empty.Empty{}, err
}
func (s *Server) OrgChanges(ctx context.Context, changesRequest *management.ChangeRequest) (*management.Changes, error) {
response, err := s.org.OrgChanges(ctx, changesRequest.Id, changesRequest.SequenceOffset, changesRequest.Limit, changesRequest.Asc)
func (s *Server) AddOrg(ctx context.Context, req *mgmt_pb.AddOrgRequest) (*mgmt_pb.AddOrgResponse, error) {
ctxData := authz.GetCtxData(ctx)
org, err := s.command.AddOrg(ctx, req.Name, ctxData.UserID, ctxData.ResourceOwner)
if err != nil {
return nil, err
}
return orgChangesToResponse(response, changesRequest.GetSequenceOffset(), changesRequest.GetLimit()), nil
return &mgmt_pb.AddOrgResponse{
Id: org.AggregateID,
Details: object.ToDetailsPb(
org.Sequence,
org.ChangeDate,
org.ResourceOwner,
),
}, err
}
func (s *Server) GetMyOrgIamPolicy(ctx context.Context, _ *empty.Empty) (_ *management.OrgIamPolicyView, err error) {
func (s *Server) DeactivateOrg(ctx context.Context, req *mgmt_pb.DeactivateOrgRequest) (*mgmt_pb.DeactivateOrgResponse, error) {
objectDetails, err := s.command.DeactivateOrg(ctx, authz.GetCtxData(ctx).OrgID)
if err != nil {
return nil, err
}
return &mgmt_pb.DeactivateOrgResponse{
Details: object.DomainToDetailsPb(objectDetails),
}, nil
}
func (s *Server) ReactivateOrg(ctx context.Context, req *mgmt_pb.ReactivateOrgRequest) (*mgmt_pb.ReactivateOrgResponse, error) {
objectDetails, err := s.command.ReactivateOrg(ctx, authz.GetCtxData(ctx).OrgID)
if err != nil {
return nil, err
}
return &mgmt_pb.ReactivateOrgResponse{
Details: object.DomainToDetailsPb(objectDetails),
}, err
}
func (s *Server) GetOrgIAMPolicy(ctx context.Context, req *mgmt_pb.GetOrgIAMPolicyRequest) (*mgmt_pb.GetOrgIAMPolicyResponse, error) {
policy, err := s.org.GetMyOrgIamPolicy(ctx)
if err != nil {
return nil, err
}
return orgIamPolicyViewFromModel(policy), err
return &mgmt_pb.GetOrgIAMPolicyResponse{
Policy: policy_grpc.OrgIAMPolicyToPb(policy),
}, nil
}
func (s *Server) ListOrgDomains(ctx context.Context, req *mgmt_pb.ListOrgDomainsRequest) (*mgmt_pb.ListOrgDomainsResponse, error) {
queries, err := ListOrgDomainsRequestToModel(req)
if err != nil {
return nil, err
}
domains, err := s.org.SearchMyOrgDomains(ctx, queries)
if err != nil {
return nil, err
}
return &mgmt_pb.ListOrgDomainsResponse{
Result: org_grpc.DomainsToPb(domains.Result),
Details: object.ToListDetails(
domains.TotalResult,
domains.Sequence,
domains.Timestamp,
),
}, nil
}
func (s *Server) AddOrgDomain(ctx context.Context, req *mgmt_pb.AddOrgDomainRequest) (*mgmt_pb.AddOrgDomainResponse, error) {
domain, err := s.command.AddOrgDomain(ctx, AddOrgDomainRequestToDomain(ctx, req))
if err != nil {
return nil, err
}
return &mgmt_pb.AddOrgDomainResponse{
Details: object.ToDetailsPb(
domain.Sequence,
domain.ChangeDate,
domain.ResourceOwner,
),
}, nil
}
func (s *Server) RemoveOrgDomain(ctx context.Context, req *mgmt_pb.RemoveOrgDomainRequest) (*mgmt_pb.RemoveOrgDomainResponse, error) {
details, err := s.command.RemoveOrgDomain(ctx, RemoveOrgDomainRequestToDomain(ctx, req))
if err != nil {
return nil, err
}
return &mgmt_pb.RemoveOrgDomainResponse{
Details: object.DomainToDetailsPb(details),
}, err
}
func (s *Server) GenerateOrgDomainValidation(ctx context.Context, req *mgmt_pb.GenerateOrgDomainValidationRequest) (*mgmt_pb.GenerateOrgDomainValidationResponse, error) {
token, url, err := s.command.GenerateOrgDomainValidation(ctx, GenerateOrgDomainValidationRequestToDomain(ctx, req))
if err != nil {
return nil, err
}
return &mgmt_pb.GenerateOrgDomainValidationResponse{
Token: token,
Url: url,
//TODO: remove details from proto
}, nil
}
func GenerateOrgDomainValidationRequestToDomain(ctx context.Context, req *mgmt_pb.GenerateOrgDomainValidationRequest) *domain.OrgDomain {
return &domain.OrgDomain{
ObjectRoot: models.ObjectRoot{
AggregateID: authz.GetCtxData(ctx).OrgID,
},
Domain: req.Domain,
ValidationType: org_grpc.DomainValidationTypeToDomain(req.Type),
}
}
func (s *Server) ValidateOrgDomain(ctx context.Context, req *mgmt_pb.ValidateOrgDomainRequest) (*mgmt_pb.ValidateOrgDomainResponse, error) {
details, err := s.command.ValidateOrgDomain(ctx, ValidateOrgDomainRequestToDomain(ctx, req))
if err != nil {
return nil, err
}
return &mgmt_pb.ValidateOrgDomainResponse{
Details: object.DomainToDetailsPb(details),
}, nil
}
func (s *Server) SetPrimaryOrgDomain(ctx context.Context, req *mgmt_pb.SetPrimaryOrgDomainRequest) (*mgmt_pb.SetPrimaryOrgDomainResponse, error) {
details, err := s.command.SetPrimaryOrgDomain(ctx, SetPrimaryOrgDomainRequestToDomain(ctx, req))
if err != nil {
return nil, err
}
return &mgmt_pb.SetPrimaryOrgDomainResponse{
Details: object.DomainToDetailsPb(details),
}, nil
}
func (s *Server) ListOrgMemberRoles(ctx context.Context, req *mgmt_pb.ListOrgMemberRolesRequest) (*mgmt_pb.ListOrgMemberRolesResponse, error) {
roles := s.org.GetOrgMemberRoles()
return &mgmt_pb.ListOrgMemberRolesResponse{
Result: roles,
}, nil
}
func (s *Server) ListOrgMembers(ctx context.Context, req *mgmt_pb.ListOrgMembersRequest) (*mgmt_pb.ListOrgMembersResponse, error) {
queries, err := ListOrgMembersRequestToModel(req)
if err != nil {
return nil, err
}
members, err := s.org.SearchMyOrgMembers(ctx, queries)
if err != nil {
return nil, err
}
return &mgmt_pb.ListOrgMembersResponse{
Result: member_grpc.OrgMembersToPb(members.Result),
Details: object.ToListDetails(
members.TotalResult,
members.Sequence,
members.Timestamp,
),
}, nil
}
func ListOrgMembersRequestToModel(req *mgmt_pb.ListOrgMembersRequest) (*org_model.OrgMemberSearchRequest, error) {
queries := member_grpc.MemberQueriesToOrgMember(req.Queries)
return &org_model.OrgMemberSearchRequest{
Offset: req.Query.Offset,
Limit: uint64(req.Query.Limit),
Asc: req.Query.Asc,
//SortingColumn: //TODO: sorting
Queries: queries,
}, nil
}
func (s *Server) AddOrgMember(ctx context.Context, req *mgmt_pb.AddOrgMemberRequest) (*mgmt_pb.AddOrgMemberResponse, error) {
addedMember, err := s.command.AddOrgMember(ctx, AddOrgMemberRequestToDomain(ctx, req))
if err != nil {
return nil, err
}
return &mgmt_pb.AddOrgMemberResponse{
Details: object.ToDetailsPb(
addedMember.Sequence,
addedMember.ChangeDate,
addedMember.ResourceOwner,
),
}, nil
}
func (s *Server) UpdateOrgMember(ctx context.Context, req *mgmt_pb.UpdateOrgMemberRequest) (*mgmt_pb.UpdateOrgMemberResponse, error) {
changedMember, err := s.command.ChangeOrgMember(ctx, UpdateOrgMemberRequestToDomain(ctx, req))
if err != nil {
return nil, err
}
return &mgmt_pb.UpdateOrgMemberResponse{
Details: object.ToDetailsPb(
changedMember.Sequence,
changedMember.ChangeDate,
changedMember.ResourceOwner,
),
}, nil
}
func (s *Server) RemoveOrgMember(ctx context.Context, req *mgmt_pb.RemoveOrgMemberRequest) (*mgmt_pb.RemoveOrgMemberResponse, error) {
details, err := s.command.RemoveOrgMember(ctx, authz.GetCtxData(ctx).OrgID, req.UserId)
if err != nil {
return nil, err
}
return &mgmt_pb.RemoveOrgMemberResponse{
Details: object.DomainToDetailsPb(details),
}, nil
}

View File

@@ -2,258 +2,69 @@ package management
import (
"context"
"encoding/json"
"google.golang.org/protobuf/types/known/timestamppb"
"github.com/caos/zitadel/internal/api/authz"
org_grpc "github.com/caos/zitadel/internal/api/grpc/org"
"github.com/caos/zitadel/internal/domain"
"github.com/caos/zitadel/internal/eventstore/v1/models"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/logging"
"github.com/golang/protobuf/ptypes"
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/types/known/structpb"
org_model "github.com/caos/zitadel/internal/org/model"
"github.com/caos/zitadel/pkg/grpc/management"
"github.com/caos/zitadel/pkg/grpc/message"
mgmt_pb "github.com/caos/zitadel/pkg/grpc/management"
)
func orgFromDomain(org *domain.Org) *management.Org {
return &management.Org{
ChangeDate: timestamppb.New(org.ChangeDate),
Id: org.AggregateID,
Name: org.Name,
State: orgStateFromDomain(org.State),
func ListOrgDomainsRequestToModel(req *mgmt_pb.ListOrgDomainsRequest) (*org_model.OrgDomainSearchRequest, error) {
queries, err := org_grpc.DomainQueriesToModel(req.Queries)
if err != nil {
return nil, err
}
}
func orgViewFromModel(org *org_model.OrgView) *management.OrgView {
creationDate, err := ptypes.TimestampProto(org.CreationDate)
logging.Log("GRPC-GTHsZ").OnError(err).Debug("unable to get timestamp from time")
changeDate, err := ptypes.TimestampProto(org.ChangeDate)
logging.Log("GRPC-dVnoj").OnError(err).Debug("unable to get timestamp from time")
return &management.OrgView{
ChangeDate: changeDate,
CreationDate: creationDate,
Id: org.ID,
Name: org.Name,
State: orgStateFromModel(org.State),
}
}
func orgStateFromDomain(state domain.OrgState) management.OrgState {
switch state {
case domain.OrgStateActive:
return management.OrgState_ORGSTATE_ACTIVE
case domain.OrgStateInactive:
return management.OrgState_ORGSTATE_INACTIVE
default:
return management.OrgState_ORGSTATE_UNSPECIFIED
}
}
func orgStateFromModel(state org_model.OrgState) management.OrgState {
switch state {
case org_model.OrgStateActive:
return management.OrgState_ORGSTATE_ACTIVE
case org_model.OrgStateInactive:
return management.OrgState_ORGSTATE_INACTIVE
default:
return management.OrgState_ORGSTATE_UNSPECIFIED
}
}
func addOrgDomainToDomain(ctx context.Context, orgDomain *management.AddOrgDomainRequest) *domain.OrgDomain {
return &domain.OrgDomain{
ObjectRoot: models.ObjectRoot{
AggregateID: authz.GetCtxData(ctx).OrgID,
},
Domain: orgDomain.Domain,
}
}
func orgDomainValidationToDomain(ctx context.Context, orgDomain *management.OrgDomainValidationRequest) *domain.OrgDomain {
return &domain.OrgDomain{
ObjectRoot: models.ObjectRoot{
AggregateID: authz.GetCtxData(ctx).OrgID,
},
Domain: orgDomain.Domain,
ValidationType: orgDomainValidationTypeToDomain(orgDomain.Type),
}
}
func validateOrgDomainToDomain(ctx context.Context, orgDomain *management.ValidateOrgDomainRequest) *domain.OrgDomain {
return &domain.OrgDomain{
ObjectRoot: models.ObjectRoot{
AggregateID: authz.GetCtxData(ctx).OrgID,
},
Domain: orgDomain.Domain,
}
}
func orgDomainValidationTypeToDomain(validationType management.OrgDomainValidationType) domain.OrgDomainValidationType {
switch validationType {
case management.OrgDomainValidationType_ORGDOMAINVALIDATIONTYPE_HTTP:
return domain.OrgDomainValidationTypeHTTP
case management.OrgDomainValidationType_ORGDOMAINVALIDATIONTYPE_DNS:
return domain.OrgDomainValidationTypeDNS
default:
return domain.OrgDomainValidationTypeUnspecified
}
}
func orgDomainValidationTypeFromModel(key org_model.OrgDomainValidationType) management.OrgDomainValidationType {
switch key {
case org_model.OrgDomainValidationTypeHTTP:
return management.OrgDomainValidationType_ORGDOMAINVALIDATIONTYPE_HTTP
case org_model.OrgDomainValidationTypeDNS:
return management.OrgDomainValidationType_ORGDOMAINVALIDATIONTYPE_DNS
default:
return management.OrgDomainValidationType_ORGDOMAINVALIDATIONTYPE_UNSPECIFIED
}
}
func primaryOrgDomainToDomain(ctx context.Context, ordDomain *management.PrimaryOrgDomainRequest) *domain.OrgDomain {
return &domain.OrgDomain{
ObjectRoot: models.ObjectRoot{
AggregateID: authz.GetCtxData(ctx).OrgID,
},
Domain: ordDomain.Domain,
}
}
func removeOrgDomainToDomain(ctx context.Context, ordDomain *management.RemoveOrgDomainRequest) *domain.OrgDomain {
return &domain.OrgDomain{
ObjectRoot: models.ObjectRoot{
AggregateID: authz.GetCtxData(ctx).OrgID,
},
Domain: ordDomain.Domain,
}
}
func orgDomainFromDomain(orgDomain *domain.OrgDomain) *management.OrgDomain {
return &management.OrgDomain{
ChangeDate: timestamppb.New(orgDomain.ChangeDate),
OrgId: orgDomain.AggregateID,
Domain: orgDomain.Domain,
Verified: orgDomain.Verified,
Primary: orgDomain.Primary,
}
}
func orgDomainViewFromModel(domain *org_model.OrgDomainView) *management.OrgDomainView {
creationDate, err := ptypes.TimestampProto(domain.CreationDate)
logging.Log("GRPC-7sjDs").OnError(err).Debug("unable to get timestamp from time")
changeDate, err := ptypes.TimestampProto(domain.ChangeDate)
logging.Log("GRPC-8iSji").OnError(err).Debug("unable to get timestamp from time")
return &management.OrgDomainView{
ChangeDate: changeDate,
CreationDate: creationDate,
OrgId: domain.OrgID,
Domain: domain.Domain,
Verified: domain.Verified,
Primary: domain.Primary,
ValidationType: orgDomainValidationTypeFromModel(domain.ValidationType),
}
}
func orgDomainSearchRequestToModel(request *management.OrgDomainSearchRequest) *org_model.OrgDomainSearchRequest {
return &org_model.OrgDomainSearchRequest{
Limit: request.Limit,
Offset: request.Offset,
Queries: orgDomainSearchQueriesToModel(request.Queries),
Offset: req.Query.Offset,
Limit: uint64(req.Query.Limit),
Asc: req.Query.Asc,
//SortingColumn: //TODO: sorting
Queries: queries,
}, nil
}
func AddOrgDomainRequestToDomain(ctx context.Context, req *mgmt_pb.AddOrgDomainRequest) *domain.OrgDomain {
return &domain.OrgDomain{
ObjectRoot: models.ObjectRoot{
AggregateID: authz.GetCtxData(ctx).OrgID,
},
Domain: req.Domain,
}
}
func orgDomainSearchQueriesToModel(queries []*management.OrgDomainSearchQuery) []*org_model.OrgDomainSearchQuery {
modelQueries := make([]*org_model.OrgDomainSearchQuery, len(queries))
for i, query := range queries {
modelQueries[i] = orgDomainSearchQueryToModel(query)
}
return modelQueries
}
func orgDomainSearchQueryToModel(query *management.OrgDomainSearchQuery) *org_model.OrgDomainSearchQuery {
return &org_model.OrgDomainSearchQuery{
Key: orgDomainSearchKeyToModel(query.Key),
Method: searchMethodToModel(query.Method),
Value: query.Value,
func RemoveOrgDomainRequestToDomain(ctx context.Context, req *mgmt_pb.RemoveOrgDomainRequest) *domain.OrgDomain {
return &domain.OrgDomain{
ObjectRoot: models.ObjectRoot{
AggregateID: authz.GetCtxData(ctx).OrgID,
},
Domain: req.Domain,
}
}
func orgDomainSearchKeyToModel(key management.OrgDomainSearchKey) org_model.OrgDomainSearchKey {
switch key {
case management.OrgDomainSearchKey_ORGDOMAINSEARCHKEY_DOMAIN:
return org_model.OrgDomainSearchKeyDomain
default:
return org_model.OrgDomainSearchKeyUnspecified
func ValidateOrgDomainRequestToDomain(ctx context.Context, req *mgmt_pb.ValidateOrgDomainRequest) *domain.OrgDomain {
return &domain.OrgDomain{
ObjectRoot: models.ObjectRoot{
AggregateID: authz.GetCtxData(ctx).OrgID,
},
Domain: req.Domain,
}
}
func orgDomainSearchResponseFromModel(resp *org_model.OrgDomainSearchResponse) *management.OrgDomainSearchResponse {
timestamp, err := ptypes.TimestampProto(resp.Timestamp)
logging.Log("GRPC-Mxi9w").OnError(err).Debug("unable to get timestamp from time")
return &management.OrgDomainSearchResponse{
Limit: resp.Limit,
Offset: resp.Offset,
TotalResult: resp.TotalResult,
Result: orgDomainsFromModel(resp.Result),
ProcessedSequence: resp.Sequence,
ViewTimestamp: timestamp,
}
}
func orgDomainsFromModel(viewDomains []*org_model.OrgDomainView) []*management.OrgDomainView {
domains := make([]*management.OrgDomainView, len(viewDomains))
for i, domain := range viewDomains {
domains[i] = orgDomainViewFromModel(domain)
}
return domains
}
func orgChangesToResponse(response *org_model.OrgChanges, offset uint64, limit uint64) (_ *management.Changes) {
return &management.Changes{
Limit: limit,
Offset: offset,
Changes: orgChangesToMgtAPI(response),
func SetPrimaryOrgDomainRequestToDomain(ctx context.Context, req *mgmt_pb.SetPrimaryOrgDomainRequest) *domain.OrgDomain {
return &domain.OrgDomain{
ObjectRoot: models.ObjectRoot{
AggregateID: authz.GetCtxData(ctx).OrgID,
},
Domain: req.Domain,
}
}
func orgChangesToMgtAPI(changes *org_model.OrgChanges) (_ []*management.Change) {
result := make([]*management.Change, len(changes.Changes))
for i, change := range changes.Changes {
b, err := json.Marshal(change.Data)
data := &structpb.Struct{}
err = protojson.Unmarshal(b, data)
if err != nil {
}
result[i] = &management.Change{
ChangeDate: change.ChangeDate,
EventType: message.NewLocalizedEventType(change.EventType),
Sequence: change.Sequence,
Data: data,
Editor: change.ModifierName,
EditorId: change.ModifierId,
}
}
return result
func AddOrgMemberRequestToDomain(ctx context.Context, req *mgmt_pb.AddOrgMemberRequest) *domain.Member {
return domain.NewMember(authz.GetCtxData(ctx).OrgID, req.UserId, req.Roles...)
}
func orgIamPolicyViewFromModel(policy *iam_model.OrgIAMPolicyView) *management.OrgIamPolicyView {
return &management.OrgIamPolicyView{
UserLoginMustBeDomain: policy.UserLoginMustBeDomain,
Default: policy.Default,
}
func UpdateOrgMemberRequestToDomain(ctx context.Context, req *mgmt_pb.UpdateOrgMemberRequest) *domain.Member {
return domain.NewMember(authz.GetCtxData(ctx).OrgID, req.UserId, req.Roles...)
}

View File

@@ -1,44 +0,0 @@
package management
import (
"context"
"github.com/golang/protobuf/ptypes/empty"
"github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/pkg/grpc/management"
)
func (s *Server) GetOrgMemberRoles(ctx context.Context, _ *empty.Empty) (*management.OrgMemberRoles, error) {
return &management.OrgMemberRoles{Roles: s.org.GetOrgMemberRoles()}, nil
}
func (s *Server) SearchMyOrgMembers(ctx context.Context, in *management.OrgMemberSearchRequest) (*management.OrgMemberSearchResponse, error) {
members, err := s.org.SearchMyOrgMembers(ctx, orgMemberSearchRequestToModel(in))
if err != nil {
return nil, err
}
return orgMemberSearchResponseFromModel(members), nil
}
func (s *Server) AddMyOrgMember(ctx context.Context, member *management.AddOrgMemberRequest) (*management.OrgMember, error) {
addedMember, err := s.command.AddOrgMember(ctx, addOrgMemberToDomain(ctx, member))
if err != nil {
return nil, err
}
return orgMemberFromDomain(addedMember), nil
}
func (s *Server) ChangeMyOrgMember(ctx context.Context, member *management.ChangeOrgMemberRequest) (*management.OrgMember, error) {
changedMember, err := s.command.ChangeOrgMember(ctx, changeOrgMemberToModel(ctx, member))
if err != nil {
return nil, err
}
return orgMemberFromDomain(changedMember), nil
}
func (s *Server) RemoveMyOrgMember(ctx context.Context, member *management.RemoveOrgMemberRequest) (*empty.Empty, error) {
err := s.command.RemoveOrgMember(ctx, authz.GetCtxData(ctx).OrgID, member.UserId)
return &empty.Empty{}, err
}

View File

@@ -1,133 +0,0 @@
package management
import (
"context"
"github.com/caos/logging"
"github.com/golang/protobuf/ptypes"
"google.golang.org/protobuf/types/known/timestamppb"
"github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/internal/domain"
org_model "github.com/caos/zitadel/internal/org/model"
"github.com/caos/zitadel/pkg/grpc/management"
)
func addOrgMemberToDomain(ctx context.Context, member *management.AddOrgMemberRequest) *domain.Member {
return domain.NewMember(authz.GetCtxData(ctx).OrgID, member.UserId, member.Roles...)
}
func changeOrgMemberToModel(ctx context.Context, member *management.ChangeOrgMemberRequest) *domain.Member {
return domain.NewMember(authz.GetCtxData(ctx).OrgID, member.UserId, member.Roles...)
}
func orgMemberFromDomain(member *domain.Member) *management.OrgMember {
return &management.OrgMember{
UserId: member.UserID,
ChangeDate: timestamppb.New(member.ChangeDate),
Roles: member.Roles,
Sequence: member.Sequence,
}
}
func orgMemberSearchRequestToModel(request *management.OrgMemberSearchRequest) *org_model.OrgMemberSearchRequest {
return &org_model.OrgMemberSearchRequest{
Limit: request.Limit,
Offset: request.Offset,
Queries: orgMemberSearchQueriesToModel(request.Queries),
}
}
func orgMemberSearchQueriesToModel(queries []*management.OrgMemberSearchQuery) []*org_model.OrgMemberSearchQuery {
modelQueries := make([]*org_model.OrgMemberSearchQuery, len(queries)+1)
for i, query := range queries {
modelQueries[i] = orgMemberSearchQueryToModel(query)
}
return modelQueries
}
func orgMemberSearchQueryToModel(query *management.OrgMemberSearchQuery) *org_model.OrgMemberSearchQuery {
return &org_model.OrgMemberSearchQuery{
Key: orgMemberSearchKeyToModel(query.Key),
Method: orgMemberSearchMethodToModel(query.Method),
Value: query.Value,
}
}
func orgMemberSearchKeyToModel(key management.OrgMemberSearchKey) org_model.OrgMemberSearchKey {
switch key {
case management.OrgMemberSearchKey_ORGMEMBERSEARCHKEY_EMAIL:
return org_model.OrgMemberSearchKeyEmail
case management.OrgMemberSearchKey_ORGMEMBERSEARCHKEY_FIRST_NAME:
return org_model.OrgMemberSearchKeyFirstName
case management.OrgMemberSearchKey_ORGMEMBERSEARCHKEY_LAST_NAME:
return org_model.OrgMemberSearchKeyLastName
case management.OrgMemberSearchKey_ORGMEMBERSEARCHKEY_USER_ID:
return org_model.OrgMemberSearchKeyUserID
default:
return org_model.OrgMemberSearchKeyUnspecified
}
}
func orgMemberSearchMethodToModel(key management.SearchMethod) domain.SearchMethod {
switch key {
case management.SearchMethod_SEARCHMETHOD_CONTAINS:
return domain.SearchMethodContains
case management.SearchMethod_SEARCHMETHOD_CONTAINS_IGNORE_CASE:
return domain.SearchMethodContainsIgnoreCase
case management.SearchMethod_SEARCHMETHOD_EQUALS:
return domain.SearchMethodEquals
case management.SearchMethod_SEARCHMETHOD_EQUALS_IGNORE_CASE:
return domain.SearchMethodEqualsIgnoreCase
case management.SearchMethod_SEARCHMETHOD_STARTS_WITH:
return domain.SearchMethodStartsWith
case management.SearchMethod_SEARCHMETHOD_STARTS_WITH_IGNORE_CASE:
return domain.SearchMethodStartsWithIgnoreCase
default:
return -1
}
}
func orgMemberSearchResponseFromModel(resp *org_model.OrgMemberSearchResponse) *management.OrgMemberSearchResponse {
timestamp, err := ptypes.TimestampProto(resp.Timestamp)
logging.Log("GRPC-Swmr6").OnError(err).Debug("date parse failed")
return &management.OrgMemberSearchResponse{
Limit: resp.Limit,
Offset: resp.Offset,
TotalResult: resp.TotalResult,
Result: orgMembersFromView(resp.Result),
ProcessedSequence: resp.Sequence,
ViewTimestamp: timestamp,
}
}
func orgMembersFromView(viewMembers []*org_model.OrgMemberView) []*management.OrgMemberView {
members := make([]*management.OrgMemberView, len(viewMembers))
for i, member := range viewMembers {
members[i] = orgMemberFromView(member)
}
return members
}
func orgMemberFromView(member *org_model.OrgMemberView) *management.OrgMemberView {
changeDate, err := ptypes.TimestampProto(member.ChangeDate)
logging.Log("GRPC-S9LAZ").OnError(err).Debug("unable to parse changedate")
creationDate, err := ptypes.TimestampProto(member.CreationDate)
logging.Log("GRPC-oJN56").OnError(err).Debug("unable to parse creation date")
return &management.OrgMemberView{
ChangeDate: changeDate,
CreationDate: creationDate,
Roles: member.Roles,
Sequence: member.Sequence,
UserId: member.UserID,
UserName: member.UserName,
Email: member.Email,
FirstName: member.FirstName,
LastName: member.LastName,
DisplayName: member.DisplayName,
}
}

View File

@@ -1,45 +0,0 @@
package management
import (
"context"
"github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/pkg/grpc/management"
"github.com/golang/protobuf/ptypes/empty"
)
func (s *Server) GetPasswordAgePolicy(ctx context.Context, _ *empty.Empty) (*management.PasswordAgePolicyView, error) {
result, err := s.org.GetPasswordAgePolicy(ctx)
if err != nil {
return nil, err
}
return passwordAgePolicyViewFromModel(result), nil
}
func (s *Server) GetDefaultPasswordAgePolicy(ctx context.Context, _ *empty.Empty) (*management.PasswordAgePolicyView, error) {
result, err := s.org.GetDefaultPasswordAgePolicy(ctx)
if err != nil {
return nil, err
}
return passwordAgePolicyViewFromModel(result), nil
}
func (s *Server) CreatePasswordAgePolicy(ctx context.Context, policy *management.PasswordAgePolicyRequest) (*management.PasswordAgePolicy, error) {
result, err := s.command.AddPasswordAgePolicy(ctx, authz.GetCtxData(ctx).OrgID, passwordAgePolicyRequestToDomain(ctx, policy))
if err != nil {
return nil, err
}
return passwordAgePolicyFromDomain(result), nil
}
func (s *Server) UpdatePasswordAgePolicy(ctx context.Context, policy *management.PasswordAgePolicyRequest) (*management.PasswordAgePolicy, error) {
result, err := s.command.ChangePasswordAgePolicy(ctx, authz.GetCtxData(ctx).OrgID, passwordAgePolicyRequestToDomain(ctx, policy))
if err != nil {
return nil, err
}
return passwordAgePolicyFromDomain(result), nil
}
func (s *Server) RemovePasswordAgePolicy(ctx context.Context, _ *empty.Empty) (*empty.Empty, error) {
err := s.command.RemovePasswordAgePolicy(ctx, authz.GetCtxData(ctx).OrgID)
return &empty.Empty{}, err
}

View File

@@ -1,48 +0,0 @@
package management
import (
"context"
"github.com/caos/logging"
"github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/internal/domain"
"github.com/caos/zitadel/internal/eventstore/v1/models"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/pkg/grpc/management"
"github.com/golang/protobuf/ptypes"
"google.golang.org/protobuf/types/known/timestamppb"
)
func passwordAgePolicyRequestToDomain(ctx context.Context, policy *management.PasswordAgePolicyRequest) *domain.PasswordAgePolicy {
return &domain.PasswordAgePolicy{
ObjectRoot: models.ObjectRoot{
AggregateID: authz.GetCtxData(ctx).OrgID,
},
MaxAgeDays: policy.MaxAgeDays,
ExpireWarnDays: policy.ExpireWarnDays,
}
}
func passwordAgePolicyFromDomain(policy *domain.PasswordAgePolicy) *management.PasswordAgePolicy {
return &management.PasswordAgePolicy{
MaxAgeDays: policy.MaxAgeDays,
ExpireWarnDays: policy.ExpireWarnDays,
ChangeDate: timestamppb.New(policy.ChangeDate),
}
}
func passwordAgePolicyViewFromModel(policy *iam_model.PasswordAgePolicyView) *management.PasswordAgePolicyView {
creationDate, err := ptypes.TimestampProto(policy.CreationDate)
logging.Log("GRPC-4Bms9").OnError(err).Debug("date parse failed")
changeDate, err := ptypes.TimestampProto(policy.ChangeDate)
logging.Log("GRPC-6Hmlo").OnError(err).Debug("date parse failed")
return &management.PasswordAgePolicyView{
Default: policy.Default,
MaxAgeDays: policy.MaxAgeDays,
ExpireWarnDays: policy.ExpireWarnDays,
ChangeDate: changeDate,
CreationDate: creationDate,
}
}

View File

@@ -1,45 +0,0 @@
package management
import (
"context"
"github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/pkg/grpc/management"
"github.com/golang/protobuf/ptypes/empty"
)
func (s *Server) GetPasswordComplexityPolicy(ctx context.Context, _ *empty.Empty) (*management.PasswordComplexityPolicyView, error) {
result, err := s.org.GetPasswordComplexityPolicy(ctx)
if err != nil {
return nil, err
}
return passwordComplexityPolicyViewFromModel(result), nil
}
func (s *Server) GetDefaultPasswordComplexityPolicy(ctx context.Context, _ *empty.Empty) (*management.PasswordComplexityPolicyView, error) {
result, err := s.org.GetDefaultPasswordComplexityPolicy(ctx)
if err != nil {
return nil, err
}
return passwordComplexityPolicyViewFromModel(result), nil
}
func (s *Server) CreatePasswordComplexityPolicy(ctx context.Context, policy *management.PasswordComplexityPolicyRequest) (*management.PasswordComplexityPolicy, error) {
result, err := s.command.AddPasswordComplexityPolicy(ctx, authz.GetCtxData(ctx).OrgID, passwordComplexityPolicyRequestToDomain(ctx, policy))
if err != nil {
return nil, err
}
return passwordComplexityPolicyFromDomain(result), nil
}
func (s *Server) UpdatePasswordComplexityPolicy(ctx context.Context, policy *management.PasswordComplexityPolicyRequest) (*management.PasswordComplexityPolicy, error) {
result, err := s.command.ChangePasswordComplexityPolicy(ctx, authz.GetCtxData(ctx).OrgID, passwordComplexityPolicyRequestToDomain(ctx, policy))
if err != nil {
return nil, err
}
return passwordComplexityPolicyFromDomain(result), nil
}
func (s *Server) RemovePasswordComplexityPolicy(ctx context.Context, _ *empty.Empty) (*empty.Empty, error) {
err := s.command.RemovePasswordComplexityPolicy(ctx, authz.GetCtxData(ctx).OrgID)
return &empty.Empty{}, err
}

View File

@@ -1,57 +0,0 @@
package management
import (
"context"
"github.com/caos/logging"
"github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/internal/domain"
"github.com/caos/zitadel/internal/eventstore/v1/models"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/pkg/grpc/management"
"github.com/golang/protobuf/ptypes"
"google.golang.org/protobuf/types/known/timestamppb"
)
func passwordComplexityPolicyRequestToDomain(ctx context.Context, policy *management.PasswordComplexityPolicyRequest) *domain.PasswordComplexityPolicy {
return &domain.PasswordComplexityPolicy{
ObjectRoot: models.ObjectRoot{
AggregateID: authz.GetCtxData(ctx).OrgID,
},
MinLength: policy.MinLength,
HasLowercase: policy.HasLowercase,
HasUppercase: policy.HasUppercase,
HasSymbol: policy.HasSymbol,
HasNumber: policy.HasNumber,
}
}
func passwordComplexityPolicyFromDomain(policy *domain.PasswordComplexityPolicy) *management.PasswordComplexityPolicy {
return &management.PasswordComplexityPolicy{
MinLength: policy.MinLength,
HasLowercase: policy.HasLowercase,
HasUppercase: policy.HasUppercase,
HasSymbol: policy.HasSymbol,
HasNumber: policy.HasNumber,
ChangeDate: timestamppb.New(policy.ChangeDate),
}
}
func passwordComplexityPolicyViewFromModel(policy *iam_model.PasswordComplexityPolicyView) *management.PasswordComplexityPolicyView {
creationDate, err := ptypes.TimestampProto(policy.CreationDate)
logging.Log("GRPC-wmi8f").OnError(err).Debug("date parse failed")
changeDate, err := ptypes.TimestampProto(policy.ChangeDate)
logging.Log("GRPC-dmOp0").OnError(err).Debug("date parse failed")
return &management.PasswordComplexityPolicyView{
Default: policy.Default,
MinLength: policy.MinLength,
HasLowercase: policy.HasLowercase,
HasUppercase: policy.HasUppercase,
HasSymbol: policy.HasSymbol,
HasNumber: policy.HasNumber,
CreationDate: changeDate,
ChangeDate: creationDate,
}
}

View File

@@ -1,45 +0,0 @@
package management
import (
"context"
"github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/pkg/grpc/management"
"github.com/golang/protobuf/ptypes/empty"
)
func (s *Server) GetPasswordLockoutPolicy(ctx context.Context, _ *empty.Empty) (*management.PasswordLockoutPolicyView, error) {
result, err := s.org.GetPasswordLockoutPolicy(ctx)
if err != nil {
return nil, err
}
return passwordLockoutPolicyViewFromModel(result), nil
}
func (s *Server) GetDefaultPasswordLockoutPolicy(ctx context.Context, _ *empty.Empty) (*management.PasswordLockoutPolicyView, error) {
result, err := s.org.GetDefaultPasswordLockoutPolicy(ctx)
if err != nil {
return nil, err
}
return passwordLockoutPolicyViewFromModel(result), nil
}
func (s *Server) CreatePasswordLockoutPolicy(ctx context.Context, policy *management.PasswordLockoutPolicyRequest) (*management.PasswordLockoutPolicy, error) {
result, err := s.command.AddPasswordLockoutPolicy(ctx, authz.GetCtxData(ctx).OrgID, passwordLockoutPolicyRequestToDomain(ctx, policy))
if err != nil {
return nil, err
}
return passwordLockoutPolicyFromDomain(result), nil
}
func (s *Server) UpdatePasswordLockoutPolicy(ctx context.Context, policy *management.PasswordLockoutPolicyRequest) (*management.PasswordLockoutPolicy, error) {
result, err := s.command.ChangePasswordLockoutPolicy(ctx, authz.GetCtxData(ctx).OrgID, passwordLockoutPolicyRequestToDomain(ctx, policy))
if err != nil {
return nil, err
}
return passwordLockoutPolicyFromDomain(result), nil
}
func (s *Server) RemovePasswordLockoutPolicy(ctx context.Context, _ *empty.Empty) (*empty.Empty, error) {
err := s.command.RemovePasswordLockoutPolicy(ctx, authz.GetCtxData(ctx).OrgID)
return &empty.Empty{}, err
}

View File

@@ -1,48 +0,0 @@
package management
import (
"context"
"github.com/caos/logging"
"github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/internal/domain"
"github.com/caos/zitadel/internal/eventstore/v1/models"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/pkg/grpc/management"
"github.com/golang/protobuf/ptypes"
"google.golang.org/protobuf/types/known/timestamppb"
)
func passwordLockoutPolicyRequestToDomain(ctx context.Context, policy *management.PasswordLockoutPolicyRequest) *domain.PasswordLockoutPolicy {
return &domain.PasswordLockoutPolicy{
ObjectRoot: models.ObjectRoot{
AggregateID: authz.GetCtxData(ctx).OrgID,
},
MaxAttempts: policy.MaxAttempts,
ShowLockOutFailures: policy.ShowLockoutFailure,
}
}
func passwordLockoutPolicyFromDomain(policy *domain.PasswordLockoutPolicy) *management.PasswordLockoutPolicy {
return &management.PasswordLockoutPolicy{
MaxAttempts: policy.MaxAttempts,
ShowLockoutFailure: policy.ShowLockOutFailures,
ChangeDate: timestamppb.New(policy.ChangeDate),
}
}
func passwordLockoutPolicyViewFromModel(policy *iam_model.PasswordLockoutPolicyView) *management.PasswordLockoutPolicyView {
creationDate, err := ptypes.TimestampProto(policy.CreationDate)
logging.Log("GRPC-4Bms9").OnError(err).Debug("date parse failed")
changeDate, err := ptypes.TimestampProto(policy.ChangeDate)
logging.Log("GRPC-6Hmlo").OnError(err).Debug("date parse failed")
return &management.PasswordLockoutPolicyView{
Default: policy.Default,
MaxAttempts: policy.MaxAttempts,
ShowLockoutFailure: policy.ShowLockOutFailures,
ChangeDate: changeDate,
CreationDate: creationDate,
}
}

View File

@@ -0,0 +1,171 @@
package management
import (
"context"
"github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/internal/api/grpc/idp"
"github.com/caos/zitadel/internal/api/grpc/object"
policy_grpc "github.com/caos/zitadel/internal/api/grpc/policy"
"github.com/caos/zitadel/internal/api/grpc/user"
"github.com/caos/zitadel/internal/domain"
"time"
mgmt_pb "github.com/caos/zitadel/pkg/grpc/management"
)
func (s *Server) GetLoginPolicy(ctx context.Context, req *mgmt_pb.GetLoginPolicyRequest) (*mgmt_pb.GetLoginPolicyResponse, error) {
policy, err := s.org.GetLoginPolicy(ctx)
if err != nil {
return nil, err
}
return &mgmt_pb.GetLoginPolicyResponse{Policy: policy_grpc.ModelLoginPolicyToPb(policy)}, nil
}
func (s *Server) GetDefaultLoginPolicy(ctx context.Context, req *mgmt_pb.GetDefaultLoginPolicyRequest) (*mgmt_pb.GetDefaultLoginPolicyResponse, error) {
policy, err := s.org.GetDefaultLoginPolicy(ctx)
if err != nil {
return nil, err
}
return &mgmt_pb.GetDefaultLoginPolicyResponse{Policy: policy_grpc.ModelLoginPolicyToPb(policy)}, nil
}
func (s *Server) AddCustomLoginPolicy(ctx context.Context, req *mgmt_pb.AddCustomLoginPolicyRequest) (*mgmt_pb.AddCustomLoginPolicyResponse, error) {
policy, err := s.command.AddLoginPolicy(ctx, authz.GetCtxData(ctx).OrgID, addLoginPolicyToDomain(req))
if err != nil {
return nil, err
}
return &mgmt_pb.AddCustomLoginPolicyResponse{
Details: object.ToDetailsPb(
policy.Sequence,
policy.ChangeDate,
policy.ResourceOwner,
),
}, nil
}
func (s *Server) UpdateCustomLoginPolicy(ctx context.Context, req *mgmt_pb.UpdateCustomLoginPolicyRequest) (*mgmt_pb.UpdateCustomLoginPolicyResponse, error) {
policy, err := s.command.ChangeLoginPolicy(ctx, authz.GetCtxData(ctx).OrgID, updateLoginPolicyToDomain(req))
if err != nil {
return nil, err
}
return &mgmt_pb.UpdateCustomLoginPolicyResponse{
Details: object.ToDetailsPb(
policy.Sequence,
policy.ChangeDate,
policy.ResourceOwner,
),
}, nil
}
func (s *Server) ResetLoginPolicyToDefault(ctx context.Context, req *mgmt_pb.ResetLoginPolicyToDefaultRequest) (*mgmt_pb.ResetLoginPolicyToDefaultResponse, error) {
objectDetails, err := s.command.RemoveLoginPolicy(ctx, authz.GetCtxData(ctx).OrgID)
if err != nil {
return nil, err
}
return &mgmt_pb.ResetLoginPolicyToDefaultResponse{
Details: object.DomainToDetailsPb(objectDetails),
}, nil
}
func (s *Server) ListLoginPolicyIDPs(ctx context.Context, req *mgmt_pb.ListLoginPolicyIDPsRequest) (*mgmt_pb.ListLoginPolicyIDPsResponse, error) {
res, err := s.org.SearchIDPProviders(ctx, ListLoginPolicyIDPsRequestToModel(req))
if err != nil {
return nil, err
}
return &mgmt_pb.ListLoginPolicyIDPsResponse{
Result: idp.ExternalIDPViewsToLoginPolicyLinkPb(res.Result),
Details: object.ToListDetails(res.TotalResult, res.Sequence, res.Timestamp),
}, nil
}
func (s *Server) AddIDPToLoginPolicy(ctx context.Context, req *mgmt_pb.AddIDPToLoginPolicyRequest) (*mgmt_pb.AddIDPToLoginPolicyResponse, error) {
idp, err := s.command.AddIDPProviderToLoginPolicy(ctx, authz.GetCtxData(ctx).OrgID, &domain.IDPProvider{IDPConfigID: req.IdpId}) //TODO: old way was to also add type but this doesnt make sense in my point of view
if err != nil {
return nil, err
}
return &mgmt_pb.AddIDPToLoginPolicyResponse{
Details: object.ToDetailsPb(
idp.Sequence,
idp.ChangeDate,
idp.ResourceOwner,
),
}, nil
}
func (s *Server) RemoveIDPFromLoginPolicy(ctx context.Context, req *mgmt_pb.RemoveIDPFromLoginPolicyRequest) (*mgmt_pb.RemoveIDPFromLoginPolicyResponse, error) {
externalIDPs, err := s.user.ExternalIDPsByIDPConfigID(ctx, req.IdpId)
if err != nil {
return nil, err
}
objectDetails, err := s.command.RemoveIDPProviderFromLoginPolicy(ctx, authz.GetCtxData(ctx).OrgID, &domain.IDPProvider{IDPConfigID: req.IdpId}, user.ExternalIDPViewsToExternalIDPs(externalIDPs)...)
if err != nil {
return nil, err
}
return &mgmt_pb.RemoveIDPFromLoginPolicyResponse{
Details: object.DomainToDetailsPb(objectDetails),
}, nil
}
func (s *Server) ListLoginPolicySecondFactors(ctx context.Context, req *mgmt_pb.ListLoginPolicySecondFactorsRequest) (*mgmt_pb.ListLoginPolicySecondFactorsResponse, error) {
result, err := s.org.SearchSecondFactors(ctx)
if err != nil {
return nil, err
}
return &mgmt_pb.ListLoginPolicySecondFactorsResponse{
//TODO: missing values from res
Details: object.ToListDetails(result.TotalResult, 0, time.Time{}),
Result: policy_grpc.ModelSecondFactorTypesToPb(result.Result),
}, nil
}
func (s *Server) AddSecondFactorToLoginPolicy(ctx context.Context, req *mgmt_pb.AddSecondFactorToLoginPolicyRequest) (*mgmt_pb.AddSecondFactorToLoginPolicyResponse, error) {
_, objectDetails, err := s.command.AddSecondFactorToDefaultLoginPolicy(ctx, policy_grpc.SecondFactorTypeToDomain(req.Type))
if err != nil {
return nil, err
}
return &mgmt_pb.AddSecondFactorToLoginPolicyResponse{
Details: object.DomainToDetailsPb(objectDetails),
}, nil
}
func (s *Server) RemoveSecondFactorFromLoginPolicy(ctx context.Context, req *mgmt_pb.RemoveSecondFactorFromLoginPolicyRequest) (*mgmt_pb.RemoveSecondFactorFromLoginPolicyResponse, error) {
objectDetails, err := s.command.RemoveSecondFactorFromDefaultLoginPolicy(ctx, policy_grpc.SecondFactorTypeToDomain(req.Type))
if err != nil {
return nil, err
}
return &mgmt_pb.RemoveSecondFactorFromLoginPolicyResponse{
Details: object.DomainToDetailsPb(objectDetails),
}, nil
}
func (s *Server) ListLoginPolicyMultiFactors(ctx context.Context, req *mgmt_pb.ListLoginPolicyMultiFactorsRequest) (*mgmt_pb.ListLoginPolicyMultiFactorsResponse, error) {
res, err := s.org.SearchMultiFactors(ctx)
if err != nil {
return nil, err
}
return &mgmt_pb.ListLoginPolicyMultiFactorsResponse{
//TODO: additional values
Details: object.ToListDetails(res.TotalResult, 0, time.Time{}),
Result: policy_grpc.ModelMultiFactorTypesToPb(res.Result),
}, nil
}
func (s *Server) AddMultiFactorToLoginPolicy(ctx context.Context, req *mgmt_pb.AddMultiFactorToLoginPolicyRequest) (*mgmt_pb.AddMultiFactorToLoginPolicyResponse, error) {
_, objectDetails, err := s.command.AddMultiFactorToDefaultLoginPolicy(ctx, policy_grpc.MultiFactorTypeToDomain(req.Type))
if err != nil {
return nil, err
}
return &mgmt_pb.AddMultiFactorToLoginPolicyResponse{
Details: object.DomainToDetailsPb(objectDetails),
}, nil
}
func (s *Server) RemoveMultiFactorFromLoginPolicy(ctx context.Context, req *mgmt_pb.RemoveMultiFactorFromLoginPolicyRequest) (*mgmt_pb.RemoveMultiFactorFromLoginPolicyResponse, error) {
objectDetails, err := s.command.RemoveMultiFactorFromDefaultLoginPolicy(ctx, policy_grpc.MultiFactorTypeToDomain(req.Type))
if err != nil {
return nil, err
}
return &mgmt_pb.RemoveMultiFactorFromLoginPolicyResponse{
Details: object.DomainToDetailsPb(objectDetails),
}, nil
}

Some files were not shown because too many files have changed in this diff Show More