mirror of
https://github.com/andwati/zitadel.git
synced 2026-11-07 06:42:15 +00:00
feat: org command sides (#96)
* start org * refactor(eventstore): filter in sql for querier * feat(eventstore): Aggregate precondition preconditions are checked right before insert. Insert is still transaction save * feat(eventstore): check preconditions in repository * test(eventstore): test precondition in models * test(eventstore): precondition-tests * start org * refactor(eventstore): filter in sql for querier * feat(eventstore): Aggregate precondition preconditions are checked right before insert. Insert is still transaction save * feat(admin): start implement org * feat(eventstore): check preconditions in repository * fix(eventstore): data as NULL if empty refactor(eventstore): naming in sequence methods * feat(admin): org command side * feat(management): start org-repo * feat(org): member * fix: replace ObjectRoot.ID with ObjectRoot.AggregateID * aggregateID * add remove,change member * refactor(org): namings * refactor(eventstore): querier as type * fix(precondition): rename validation from precondition to validation * test(eventstore): isErr func instead of wantErr bool * fix(tests): Data * fix(eventstore): correct check for existing events in push, simplify insert statement * fix(eventstore): aggregate id public * test(org): eventsourcing * test(org): eventstore * test(org): deactivate, reactivate, orgbyid * test(org): getMemberByIDs * tests * running tests * add user repo to admin * thorw not found if no org found * eventstore tests done * lauft * validate if user is already member of org * modules * delete unused file * add member validation test * return error if unable to validat member * generate org id once, set resourceowner of org * Update internal/admin/repository/eventsourcing/eventstore/org.go * Update internal/admin/repository/eventsourcing/eventstore/org.go * Update internal/org/repository/eventsourcing/member_model.go * Update internal/org/repository/eventsourcing/org.go * Update internal/org/repository/eventsourcing/org.go * Update internal/org/repository/eventsourcing/org_member.go * Update internal/org/repository/eventsourcing/org_member.go * Update internal/org/repository/eventsourcing/org_model.go * Update internal/org/repository/eventsourcing/org.go * Update internal/org/repository/eventsourcing/org_model.go * Update internal/org/repository/eventsourcing/org_model.go * typo * correct user events * usercreate for setuporg instead of userregister * set data * mod * mod * tests * cleanup code * code styling * return member on add and change * change username in startup * girignore * orgID as parameter in re-/deactive org * startup config * migration for admin_api-user * probes fro admin * move unique org Co-authored-by: Fabiennne <[email protected]>
This commit is contained in:
+6426
-12327
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -358,7 +358,7 @@
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"properties": {}
|
||||
"$ref": "#/definitions/v1OrgMember"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -450,7 +450,7 @@
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"properties": {}
|
||||
"$ref": "#/definitions/v1OrgMember"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -3339,7 +3339,7 @@
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/protobufStruct"
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -3350,19 +3350,6 @@
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"protobufListValue": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"values": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/protobufValue"
|
||||
},
|
||||
"description": "Repeated field of dynamically typed values."
|
||||
}
|
||||
},
|
||||
"description": "`ListValue` is a wrapper around a repeated field of values.\n\nThe JSON representation for `ListValue` is JSON array."
|
||||
},
|
||||
"protobufNullValue": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
@@ -3371,51 +3358,6 @@
|
||||
"default": "NULL_VALUE",
|
||||
"description": "`NullValue` is a singleton enumeration to represent the null value for the\n`Value` type union.\n\n The JSON representation for `NullValue` is JSON `null`.\n\n - NULL_VALUE: Null value."
|
||||
},
|
||||
"protobufStruct": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"fields": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/protobufValue"
|
||||
},
|
||||
"description": "Unordered map of dynamically typed values."
|
||||
}
|
||||
},
|
||||
"description": "`Struct` represents a structured data value, consisting of fields\nwhich map to dynamically typed values. In some languages, `Struct`\nmight be supported by a native representation. For example, in\nscripting languages like JS a struct is represented as an\nobject. The details of that representation are described together\nwith the proto support for the language.\n\nThe JSON representation for `Struct` is JSON object."
|
||||
},
|
||||
"protobufValue": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"null_value": {
|
||||
"$ref": "#/definitions/protobufNullValue",
|
||||
"description": "Represents a null value."
|
||||
},
|
||||
"number_value": {
|
||||
"type": "number",
|
||||
"format": "double",
|
||||
"description": "Represents a double value."
|
||||
},
|
||||
"string_value": {
|
||||
"type": "string",
|
||||
"description": "Represents a string value."
|
||||
},
|
||||
"bool_value": {
|
||||
"type": "boolean",
|
||||
"format": "boolean",
|
||||
"description": "Represents a boolean value."
|
||||
},
|
||||
"struct_value": {
|
||||
"$ref": "#/definitions/protobufStruct",
|
||||
"description": "Represents a structured value."
|
||||
},
|
||||
"list_value": {
|
||||
"$ref": "#/definitions/protobufListValue",
|
||||
"description": "Represents a repeated `Value`."
|
||||
}
|
||||
},
|
||||
"description": "`Value` represents a dynamically typed value which can be either\nnull, a number, a string, a boolean, a recursive struct value, or a\nlist of values. A producer of value is expected to set one of that\nvariants, absence of any variant indicates an error.\n\nThe JSON representation for `Value` is JSON value."
|
||||
},
|
||||
"v1AddOrgMemberRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -3703,7 +3645,7 @@
|
||||
"type": "string"
|
||||
},
|
||||
"data": {
|
||||
"$ref": "#/definitions/protobufStruct"
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -4178,18 +4120,6 @@
|
||||
"user_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"user_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"email": {
|
||||
"type": "string"
|
||||
},
|
||||
"first_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"last_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"roles": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
|
||||
@@ -38,14 +38,14 @@ func (m *MockManagementServiceClient) EXPECT() *MockManagementServiceClientMockR
|
||||
}
|
||||
|
||||
// AddOrgMember mocks base method
|
||||
func (m *MockManagementServiceClient) AddOrgMember(arg0 context.Context, arg1 *grpc.AddOrgMemberRequest, arg2 ...grpc0.CallOption) (*emptypb.Empty, error) {
|
||||
func (m *MockManagementServiceClient) AddOrgMember(arg0 context.Context, arg1 *grpc.AddOrgMemberRequest, arg2 ...grpc0.CallOption) (*grpc.OrgMember, error) {
|
||||
m.ctrl.T.Helper()
|
||||
varargs := []interface{}{arg0, arg1}
|
||||
for _, a := range arg2 {
|
||||
varargs = append(varargs, a)
|
||||
}
|
||||
ret := m.ctrl.Call(m, "AddOrgMember", varargs...)
|
||||
ret0, _ := ret[0].(*emptypb.Empty)
|
||||
ret0, _ := ret[0].(*grpc.OrgMember)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
@@ -158,14 +158,14 @@ func (mr *MockManagementServiceClientMockRecorder) ApplicationChanges(arg0, arg1
|
||||
}
|
||||
|
||||
// ChangeOrgMember mocks base method
|
||||
func (m *MockManagementServiceClient) ChangeOrgMember(arg0 context.Context, arg1 *grpc.ChangeOrgMemberRequest, arg2 ...grpc0.CallOption) (*emptypb.Empty, error) {
|
||||
func (m *MockManagementServiceClient) ChangeOrgMember(arg0 context.Context, arg1 *grpc.ChangeOrgMemberRequest, arg2 ...grpc0.CallOption) (*grpc.OrgMember, error) {
|
||||
m.ctrl.T.Helper()
|
||||
varargs := []interface{}{arg0, arg1}
|
||||
for _, a := range arg2 {
|
||||
varargs = append(varargs, a)
|
||||
}
|
||||
ret := m.ctrl.Call(m, "ChangeOrgMember", varargs...)
|
||||
ret0, _ := ret[0].(*emptypb.Empty)
|
||||
ret0, _ := ret[0].(*grpc.OrgMember)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
@@ -2,25 +2,42 @@ package grpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
)
|
||||
|
||||
func (s *Server) GetOrgByID(ctx context.Context, in *OrgID) (*Org, error) {
|
||||
return nil, errors.ThrowUnimplemented(nil, "GRPC-sdo5g", "Not implemented")
|
||||
func (s *Server) GetOrgByID(ctx context.Context, orgID *OrgID) (*Org, error) {
|
||||
org, err := s.org.OrgByID(ctx, orgID.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return orgFromModel(org), nil
|
||||
}
|
||||
|
||||
func (s *Server) GetOrgByDomainGlobal(ctx context.Context, in *OrgDomain) (*Org, error) {
|
||||
return nil, errors.ThrowUnimplemented(nil, "GRPC-mop4s", "Not implemented")
|
||||
org, err := s.org.OrgByDomainGlobal(ctx, in.Domain)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return orgFromModel(org), nil
|
||||
}
|
||||
|
||||
func (s *Server) DeactivateOrg(ctx context.Context, in *OrgID) (*Org, error) {
|
||||
return nil, errors.ThrowUnimplemented(nil, "GRPC-vel3X", "Not implemented")
|
||||
org, err := s.org.DeactivateOrg(ctx, in.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return orgFromModel(org), nil
|
||||
}
|
||||
|
||||
func (s *Server) ReactivateOrg(ctx context.Context, in *OrgID) (*Org, error) {
|
||||
return nil, errors.ThrowUnimplemented(nil, "GRPC-Scmk3", "Not implemented")
|
||||
org, err := s.org.ReactivateOrg(ctx, in.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return orgFromModel(org), nil
|
||||
}
|
||||
|
||||
func (s *Server) OrgChanges(ctx context.Context, changesRequest *ChangeRequest) (*Changes, error) {
|
||||
return nil, errors.ThrowUnimplemented(nil, "GRPC-mfiF4", "Not implemented")
|
||||
return nil, errors.ThrowUnimplemented(nil, "GRPC-DNiIq", "unimplemented")
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package grpc
|
||||
|
||||
import (
|
||||
"github.com/caos/logging"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
)
|
||||
|
||||
func orgsFromModel(orgs []*org_model.Org) []*Org {
|
||||
orgList := make([]*Org, len(orgs))
|
||||
for i, org := range orgs {
|
||||
orgList[i] = orgFromModel(org)
|
||||
}
|
||||
return orgList
|
||||
}
|
||||
|
||||
func orgFromModel(org *org_model.Org) *Org {
|
||||
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 &Org{
|
||||
Domain: org.Domain,
|
||||
ChangeDate: changeDate,
|
||||
CreationDate: creationDate,
|
||||
Id: org.AggregateID,
|
||||
Name: org.Name,
|
||||
State: orgStateFromModel(org.State),
|
||||
}
|
||||
}
|
||||
|
||||
func orgStateFromModel(state org_model.OrgState) OrgState {
|
||||
switch state {
|
||||
case org_model.ORGSTATE_ACTIVE:
|
||||
return OrgState_ORGSTATE_ACTIVE
|
||||
case org_model.ORGSTATE_INACTIVE:
|
||||
return OrgState_ORGSTATE_INACTIVE
|
||||
default:
|
||||
return OrgState_ORGSTATE_UNSPECIFIED
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package grpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/golang/protobuf/ptypes/empty"
|
||||
)
|
||||
@@ -14,14 +15,27 @@ func (s *Server) SearchOrgMembers(ctx context.Context, in *OrgMemberSearchReques
|
||||
return nil, errors.ThrowUnimplemented(nil, "GRPC-wkdl3", "Not implemented")
|
||||
}
|
||||
|
||||
func (s *Server) AddOrgMember(ctx context.Context, member *AddOrgMemberRequest) (*empty.Empty, error) {
|
||||
return nil, errors.ThrowUnimplemented(nil, "GRPC-Moe56", "Not implemented")
|
||||
func (s *Server) AddOrgMember(ctx context.Context, member *AddOrgMemberRequest) (*OrgMember, error) {
|
||||
repositoryMember := addOrgMemberToModel(member)
|
||||
|
||||
addedMember, err := s.orgMember.AddOrgMember(ctx, repositoryMember)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return orgMemberFromModel(addedMember), nil
|
||||
}
|
||||
|
||||
func (s *Server) ChangeOrgMember(ctx context.Context, member *ChangeOrgMemberRequest) (*empty.Empty, error) {
|
||||
return nil, errors.ThrowUnimplemented(nil, "GRPC-eod34", "Not implemented")
|
||||
func (s *Server) ChangeOrgMember(ctx context.Context, member *ChangeOrgMemberRequest) (*OrgMember, error) {
|
||||
repositoryMember := changeOrgMemberToModel(member)
|
||||
changedMember, err := s.orgMember.ChangeOrgMember(ctx, repositoryMember)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return orgMemberFromModel(changedMember), nil
|
||||
}
|
||||
|
||||
func (s *Server) RemoveOrgMember(ctx context.Context, member *RemoveOrgMemberRequest) (*empty.Empty, error) {
|
||||
return nil, errors.ThrowUnimplemented(nil, "GRPC-poeSw", "Not implemented")
|
||||
err := s.orgMember.RemoveOrgMember(ctx, member.OrgId, member.UserId)
|
||||
return &empty.Empty{}, err
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
package grpc
|
||||
|
||||
import (
|
||||
"github.com/caos/logging"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
)
|
||||
|
||||
func addOrgMemberToModel(member *AddOrgMemberRequest) *org_model.OrgMember {
|
||||
memberModel := org_model.NewOrgMember(member.OrgId, member.UserId)
|
||||
memberModel.Roles = member.Roles
|
||||
|
||||
return memberModel
|
||||
}
|
||||
|
||||
func changeOrgMemberToModel(member *ChangeOrgMemberRequest) *org_model.OrgMember {
|
||||
memberModel := org_model.NewOrgMember(member.OrgId, member.UserId)
|
||||
memberModel.Roles = member.Roles
|
||||
|
||||
return memberModel
|
||||
}
|
||||
|
||||
func orgMemberFromModel(member *org_model.OrgMember) *OrgMember {
|
||||
creationDate, err := ptypes.TimestampProto(member.CreationDate)
|
||||
logging.Log("GRPC-jC5wY").OnError(err).Debug("date parse failed")
|
||||
|
||||
changeDate, err := ptypes.TimestampProto(member.ChangeDate)
|
||||
logging.Log("GRPC-Nc2jJ").OnError(err).Debug("date parse failed")
|
||||
|
||||
return &OrgMember{
|
||||
UserId: member.UserID,
|
||||
CreationDate: creationDate,
|
||||
ChangeDate: changeDate,
|
||||
Roles: member.Roles,
|
||||
Sequence: member.Sequence,
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,8 @@ var _ ManagementServiceServer = (*Server)(nil)
|
||||
type Server struct {
|
||||
port string
|
||||
project repository.ProjectRepository
|
||||
org repository.OrgRepository
|
||||
orgMember repository.OrgMemberRepository
|
||||
user repository.UserRepository
|
||||
usergrant repository.UserGrantRepository
|
||||
verifier *mgmt_auth.TokenVerifier
|
||||
@@ -25,6 +27,8 @@ func StartServer(conf grpc_util.ServerConfig, authZ auth.Config, repo repository
|
||||
return &Server{
|
||||
port: conf.Port,
|
||||
project: repo,
|
||||
org: repo,
|
||||
orgMember: repo,
|
||||
user: repo,
|
||||
usergrant: repo,
|
||||
authZ: authZ,
|
||||
|
||||
@@ -527,7 +527,7 @@ service ManagementService {
|
||||
};
|
||||
}
|
||||
|
||||
rpc AddOrgMember(AddOrgMemberRequest) returns (google.protobuf.Empty) {
|
||||
rpc AddOrgMember(AddOrgMemberRequest) returns (OrgMember) {
|
||||
option (google.api.http) = {
|
||||
post: "/orgs/{org_id}/members"
|
||||
body: "*"
|
||||
@@ -538,7 +538,7 @@ service ManagementService {
|
||||
};
|
||||
}
|
||||
|
||||
rpc ChangeOrgMember(ChangeOrgMemberRequest) returns (google.protobuf.Empty) {
|
||||
rpc ChangeOrgMember(ChangeOrgMemberRequest) returns (OrgMember) {
|
||||
option (google.api.http) = {
|
||||
put: "/orgs/{org_id}/members/{user_id}"
|
||||
body: "*"
|
||||
@@ -1646,14 +1646,10 @@ message OrgMemberRoles {
|
||||
|
||||
message OrgMember {
|
||||
string user_id = 1;
|
||||
string user_name = 2;
|
||||
string email = 3;
|
||||
string first_name = 4;
|
||||
string last_name = 5;
|
||||
repeated string roles = 6;
|
||||
google.protobuf.Timestamp change_date = 7;
|
||||
google.protobuf.Timestamp creation_date = 8;
|
||||
uint64 sequence = 9;
|
||||
repeated string roles = 2;
|
||||
google.protobuf.Timestamp change_date = 3;
|
||||
google.protobuf.Timestamp creation_date = 4;
|
||||
uint64 sequence = 5;
|
||||
}
|
||||
|
||||
message AddOrgMemberRequest {
|
||||
|
||||
Reference in New Issue
Block a user