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:
Silvan
2020-05-13 14:22:29 +02:00
committed by GitHub
co-authored by Fabiennne
parent 7facd78026
commit 9e32740eb8
67 changed files with 16694 additions and 13035 deletions
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
}
+23 -6
View File
@@ -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")
}
+43
View File
@@ -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
}
}
+19 -5
View File
@@ -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,
}
}
+4
View File
@@ -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,
+6 -10
View File
@@ -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 {