mirror of
https://github.com/zitadel/zitadel.git
synced 2024-12-04 23:45:07 +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 <fabienne.gerschwiler@gmail.com>
This commit is contained in:
parent
7facd78026
commit
9e32740eb8
6
.gitignore
vendored
6
.gitignore
vendored
@ -25,5 +25,9 @@ debug
|
||||
# credential
|
||||
google-credentials
|
||||
key.json
|
||||
.keys/*
|
||||
|
||||
cockroach-data/*
|
||||
cockroach-data/*
|
||||
|
||||
#binaries
|
||||
cmd/zitadel/zitadel
|
@ -56,7 +56,7 @@ func main() {
|
||||
logging.Log("MAIN-53RF2").OnError(err).Fatal("error starting login ui")
|
||||
}
|
||||
if *adminEnabled {
|
||||
admin.Start(ctx, conf.Admin, conf.AuthZ)
|
||||
admin.Start(ctx, conf.Admin, conf.AuthZ, conf.SystemDefaults)
|
||||
}
|
||||
if *consoleEnabled {
|
||||
err = console.Start(ctx, conf.Console)
|
||||
|
@ -26,7 +26,7 @@ Mgmt:
|
||||
Host: $ZITADEL_EVENTSTORE_HOST
|
||||
Port: $ZITADEL_EVENTSTORE_PORT
|
||||
User: 'management'
|
||||
Database: 'management'
|
||||
Database: 'eventstore'
|
||||
SSLmode: disable
|
||||
Cache:
|
||||
Type: 'fastcache'
|
||||
@ -61,6 +61,20 @@ Admin:
|
||||
GatewayPort: 50041
|
||||
CustomHeaders:
|
||||
- x-zitadel-
|
||||
Repository:
|
||||
Eventstore:
|
||||
ServiceName: 'Admin'
|
||||
Repository:
|
||||
SQL:
|
||||
Host: $ZITADEL_EVENTSTORE_HOST
|
||||
Port: $ZITADEL_EVENTSTORE_PORT
|
||||
User: 'admin_api'
|
||||
Database: 'eventstore'
|
||||
SSLmode: disable
|
||||
Cache:
|
||||
Type: 'fastcache'
|
||||
Config:
|
||||
MaxCacheSizeInByte: 10485760 #10mb
|
||||
|
||||
Console:
|
||||
Port: 50050
|
||||
|
25
go.mod
25
go.mod
@ -3,7 +3,7 @@ module github.com/caos/zitadel
|
||||
go 1.14
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.56.0 // indirect
|
||||
cloud.google.com/go v0.57.0 // indirect
|
||||
contrib.go.opencensus.io/exporter/stackdriver v0.13.1
|
||||
github.com/BurntSushi/toml v0.3.1
|
||||
github.com/DATA-DOG/go-sqlmock v1.4.1
|
||||
@ -12,10 +12,10 @@ require (
|
||||
github.com/Masterminds/sprig v2.22.0+incompatible
|
||||
github.com/VictoriaMetrics/fastcache v1.5.7
|
||||
github.com/allegro/bigcache v1.2.1
|
||||
github.com/aws/aws-sdk-go v1.30.16 // indirect
|
||||
github.com/aws/aws-sdk-go v1.30.25 // indirect
|
||||
github.com/caos/logging v0.0.1
|
||||
github.com/cockroachdb/cockroach-go v0.0.0-20200411195601-6f5842749cfc
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0
|
||||
github.com/cockroachdb/cockroach-go v0.0.0-20200504194139-73ffeee90b62
|
||||
github.com/envoyproxy/protoc-gen-validate v0.3.0
|
||||
github.com/ghodss/yaml v1.0.0
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
|
||||
github.com/golang/mock v1.4.3
|
||||
@ -27,27 +27,24 @@ require (
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.14.5
|
||||
github.com/huandu/xstrings v1.3.1 // indirect
|
||||
github.com/imdario/mergo v0.3.9 // indirect
|
||||
github.com/jackc/pgconn v1.5.0 // indirect
|
||||
github.com/jinzhu/gorm v1.9.12
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3 // indirect
|
||||
github.com/lib/pq v1.5.2
|
||||
github.com/mitchellh/copystructure v1.0.0 // indirect
|
||||
github.com/mitchellh/reflectwalk v1.0.1 // indirect
|
||||
github.com/nicksnyder/go-i18n/v2 v2.0.3
|
||||
github.com/pquerna/otp v1.2.0
|
||||
github.com/rs/cors v1.7.0
|
||||
github.com/sirupsen/logrus v1.5.0 // indirect
|
||||
github.com/sirupsen/logrus v1.6.0 // indirect
|
||||
github.com/sony/sonyflake v1.0.0
|
||||
github.com/stretchr/testify v1.5.1
|
||||
go.opencensus.io v0.22.3
|
||||
golang.org/x/crypto v0.0.0-20200427165652-729f1e841bcc
|
||||
golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0 // indirect
|
||||
golang.org/x/sys v0.0.0-20200428200454-593003d681fa // indirect
|
||||
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37
|
||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f // indirect
|
||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25 // indirect
|
||||
golang.org/x/text v0.3.2
|
||||
golang.org/x/tools v0.0.0-20200428211428-0c9eba77bc32
|
||||
google.golang.org/api v0.22.0 // indirect
|
||||
google.golang.org/appengine v1.6.6 // indirect
|
||||
google.golang.org/genproto v0.0.0-20200428115010-c45acf45369a
|
||||
golang.org/x/tools v0.0.0-20200512001501-aaeff5de670a
|
||||
google.golang.org/api v0.24.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380
|
||||
google.golang.org/grpc v1.29.1
|
||||
google.golang.org/protobuf v1.22.0
|
||||
gopkg.in/yaml.v2 v2.2.8 // indirect
|
||||
|
136
go.sum
136
go.sum
@ -11,6 +11,8 @@ cloud.google.com/go v0.53.0 h1:MZQCQQaRwOrAcuKjiHWHrgKykt4fZyuwF2dtiG3fGW8=
|
||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
||||
cloud.google.com/go v0.56.0 h1:WRz29PgAsVEyPSDHyk+0fpEkwEFyfhHn+JbksT6gIL4=
|
||||
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
|
||||
cloud.google.com/go v0.57.0 h1:EpMNVUorLiZIELdMZbCYX/ByTFCdoYopYAGxaGVz9ms=
|
||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
@ -50,10 +52,8 @@ github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQY
|
||||
github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q=
|
||||
github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go v1.30.4 h1:dpQgypC3rld2Uuz+/2u+0nbfmmyEWxau6v1hdAlvoc8=
|
||||
github.com/aws/aws-sdk-go v1.30.4/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
|
||||
github.com/aws/aws-sdk-go v1.30.16 h1:1eabOZiVGl+XB02/VG9NpR+3fngaNc74pgb5RmyzgLY=
|
||||
github.com/aws/aws-sdk-go v1.30.16/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
|
||||
github.com/aws/aws-sdk-go v1.30.25 h1:89NXJkfpjnMEnsxkP8MVX+LDsoiLCSqevraLb5y4Mjk=
|
||||
github.com/aws/aws-sdk-go v1.30.25/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
|
||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI=
|
||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
||||
github.com/caos/logging v0.0.1 h1:YSGtO2/+5OWdwilBCou50akoDHAT/OhkbrolkVlR6U0=
|
||||
@ -70,14 +70,8 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
||||
github.com/cockroachdb/cockroach-go v0.0.0-20200312223839-f565e4789405 h1:i1XXyBMAGL7NqogtoS6NHQ/IJwCbG0R725hAhEhldOI=
|
||||
github.com/cockroachdb/cockroach-go v0.0.0-20200312223839-f565e4789405/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk=
|
||||
github.com/cockroachdb/cockroach-go v0.0.0-20200411195601-6f5842749cfc h1:8pe9G3mY+h/qW3ysdFz9Eht4kbIsL0BS5FWih1Sn6JU=
|
||||
github.com/cockroachdb/cockroach-go v0.0.0-20200411195601-6f5842749cfc/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk=
|
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/cockroachdb/cockroach-go v0.0.0-20200504194139-73ffeee90b62 h1:eqJbq0A8ev6101p/zV72eOM+Z3WZkgb66S7PVJQR9wI=
|
||||
github.com/cockroachdb/cockroach-go v0.0.0-20200504194139-73ffeee90b62/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@ -131,8 +125,6 @@ github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgj
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4 h1:+EOh4OY6tjM6ZueeUKinl1f0U2820HzQOuf1iqMnsks=
|
||||
github.com/golang/protobuf v1.4.0-rc.4/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0 h1:oOuy+ugB+P/kBdUnG5QaMXSIyJ1q38wWSojYCb3z5VQ=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
@ -153,6 +145,7 @@ github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OI
|
||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
@ -166,56 +159,16 @@ github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyC
|
||||
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.2.0 h1:0IKlLyQ3Hs9nDaiK5cSHAGmcQEIC8l2Ts1u6x5Dfrqg=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.2.0/go.mod h1:mJzapYve32yjrKlk9GbyCZHuPgZsrbyIbyKhSzOpg6s=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.14.3 h1:OCJlWkOUoTnl0neNGlf4fUm3TmbEtguw7vR+nGtnDjY=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.14.3/go.mod h1:6CwZWGDSPRJidgKAtJVvND6soZe6fT7iteq8wDPdhb0=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.14.4 h1:IOPK2xMPP3aV6/NPt4jt//ELFo3Vv8sDVD8j3+tleDU=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.14.4/go.mod h1:6CwZWGDSPRJidgKAtJVvND6soZe6fT7iteq8wDPdhb0=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.14.5 h1:aiLxiiVzAXb7wb3lAmubA69IokWOoUNe+E7TdGKh8yw=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.14.5/go.mod h1:UJ0EZAp832vCd54Wev9N1BMKEyvcZ5+IM0AwDrnlkEc=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/huandu/xstrings v1.3.0 h1:gvV6jG9dTgFEncxo+AF7PH6MZXi/vZl25owA/8Dg8Wo=
|
||||
github.com/huandu/xstrings v1.3.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||
github.com/huandu/xstrings v1.3.1 h1:4jgBlKK6tLKFvO8u5pmYjG91cqytmDCDvGh7ECVFfFs=
|
||||
github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg=
|
||||
github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0=
|
||||
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
|
||||
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
|
||||
github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8=
|
||||
github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
|
||||
github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA=
|
||||
github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE=
|
||||
github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s=
|
||||
github.com/jackc/pgconn v1.5.0 h1:oFSOilzIZkyg787M1fEmyMfOUUvwj0daqYMfaWwNL4o=
|
||||
github.com/jackc/pgconn v1.5.0/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI=
|
||||
github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
|
||||
github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
|
||||
github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2 h1:JVX6jT/XfzNqIjye4717ITLaNwV9mWbJx0dLCpcRzdA=
|
||||
github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE=
|
||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||
github.com/jackc/pgproto3 v1.1.0 h1:FYYE4yRw+AgI8wXIinMlNjBbp/UitDJwfj5LqqewP1A=
|
||||
github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78=
|
||||
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA=
|
||||
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg=
|
||||
github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
|
||||
github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
|
||||
github.com/jackc/pgproto3/v2 v2.0.1 h1:Rdjp4NFjwHnEslx2b66FfCI2S0LhO4itac3hXz6WX9M=
|
||||
github.com/jackc/pgproto3/v2 v2.0.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
||||
github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8 h1:Q3tB+ExeflWUW7AFcAhXqk40s9mnNYLk1nOkKNZ5GnU=
|
||||
github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
|
||||
github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg=
|
||||
github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc=
|
||||
github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw=
|
||||
github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=
|
||||
github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
|
||||
github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc=
|
||||
github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jinzhu/gorm v1.9.12 h1:Drgk1clyWT9t9ERbzHza6Mj/8FY/CqMyVzOiHviMo6Q=
|
||||
github.com/jinzhu/gorm v1.9.12/go.mod h1:vhTjlKSJUTWNtcbQtrMBFCxy7eXTzeCAzfL5fBZT/Qs=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
@ -239,22 +192,11 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU=
|
||||
github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.4.0 h1:TmtCFbH+Aw0AixwyttznSMQDgbR5Yed/Gg6S8Funrhc=
|
||||
github.com/lib/pq v1.4.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.5.2 h1:yTSXVswvWUOQ3k1sd7vJfDrbSl8lKuscqFJRqjC0ifw=
|
||||
github.com/lib/pq v1.5.2/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
||||
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-sqlite3 v2.0.1+incompatible h1:xQ15muvnzGBHpIpdrNi1DA5x0+TcBZzsIDwmw9uTHzw=
|
||||
github.com/mattn/go-sqlite3 v2.0.1+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ=
|
||||
@ -278,21 +220,14 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
|
||||
github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
|
||||
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
||||
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
|
||||
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.5.0 h1:1N5EYkVAPEywqZRJd7cwnRtCb6xJx7NH3T3WUTF980Q=
|
||||
github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo=
|
||||
github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/sony/sonyflake v1.0.0 h1:MpU6Ro7tfXwgn2l5eluf9xQvQJDROTBImNCfRXn/YeM=
|
||||
github.com/sony/sonyflake v1.0.0/go.mod h1:Jv3cfhf/UFtolOTTRd3q4Nl6ENqM+KfyZ5PseKfZGF4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
@ -301,36 +236,27 @@ github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3 h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||
golang.org/x/crypto v0.0.0-20190506204251-e1dfcc566284/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59 h1:3zb4D3T4G8jdExgVU/95+vQXfpEPiMdCaZgmGVxjNHM=
|
||||
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200403201458-baeed622b8d8 h1:fpnn/HnJONpIu6hkXi1u/7rR0NzilgWr4T0JmWkEitk=
|
||||
golang.org/x/crypto v0.0.0-20200403201458-baeed622b8d8/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200427165652-729f1e841bcc h1:ZGI/fILM2+ueot/UixBSoj9188jCAxVHEZEGhqq67I4=
|
||||
golang.org/x/crypto v0.0.0-20200427165652-729f1e841bcc/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 h1:cg5LA/zNPRzIXIWSCxQW10Rvpy94aQh3LT/ShoCpkHw=
|
||||
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@ -373,7 +299,6 @@ golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
@ -383,8 +308,9 @@ golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0 h1:Jcxah/M+oLZ/R4/z5RzfPzGbPXnVDPkEDtf2JnuxN+U=
|
||||
golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f h1:QBjCr1Fz5kw158VqdE9JfI9cJnl/ymnJWAdMuinqL7Y=
|
||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@ -401,12 +327,9 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a h1:WXEvlFVvvGxCJLG6REjsT03iWnKLEWinaScsxF2Vm2o=
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -414,7 +337,6 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191206220618-eeba5f6aabab h1:FvshnhkKW+LO3HWHodML8kuVX8rnJTxKm9dFPuI68UM=
|
||||
@ -429,8 +351,9 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20u
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d h1:nc5K6ox/4lTFbMVSL9WRR81ixkcwXThoiF6yf+R9scA=
|
||||
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200428200454-593003d681fa h1:yMbJOvnfYkO1dSAviTu/ZguZWLBTXx4xE3LYrxUCCiA=
|
||||
golang.org/x/sys v0.0.0-20200428200454-593003d681fa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25 h1:OKbAoGs4fGM5cPLlVQLZGYkFC8OnOfgo6tt0Smf9XhM=
|
||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@ -447,7 +370,6 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3
|
||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135 h1:5Beo0mZN8dRzgrMMkDp0jc8YXQKx9DiJ2k1dkvGsn5A=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
@ -455,7 +377,6 @@ golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgw
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
@ -476,12 +397,9 @@ golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapK
|
||||
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4 h1:kDtqNkeBrZb8B+atrj50B5XLHpzXXqcCdZPP/ApQ5NY=
|
||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||
golang.org/x/tools v0.0.0-20200403190813-44a64ad78b9b h1:AFZdJUT7jJYXQEC29hYH/WZkoV7+KhwxQGmdZ19yYoY=
|
||||
golang.org/x/tools v0.0.0-20200403190813-44a64ad78b9b/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200428211428-0c9eba77bc32 h1:Xvf3ZQTm5bjXPxhI7g+dwqsCqadK1rcNtwtszuatetk=
|
||||
golang.org/x/tools v0.0.0-20200428211428-0c9eba77bc32/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200512001501-aaeff5de670a h1:vAa2fXRLbiVN3N/xCnodIT36K4QKZQNyQFq3hQJfQ1U=
|
||||
golang.org/x/tools v0.0.0-20200512001501-aaeff5de670a/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
@ -498,10 +416,10 @@ google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/
|
||||
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.20.0 h1:jz2KixHX7EcCPiQrySzPdnYT7DbINAypCqKZ1Z7GM40=
|
||||
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.21.0 h1:zS+Q/CJJnVlXpXQVIz+lH0ZT2lBuT2ac7XD8Y/3w6hY=
|
||||
google.golang.org/api v0.21.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.22.0 h1:J1Pl9P2lnmYFSJvgs70DKELqHNh8CNWXPbud4njEE2s=
|
||||
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.24.0 h1:cG03eaksBzhfSIk7JRGctfp3lanklcOM/mTGvow7BbQ=
|
||||
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
@ -531,10 +449,9 @@ google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfG
|
||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940 h1:MRHtG0U6SnaUb+s+LhNE1qt1FQ1wlhqr5E4usBKC0uA=
|
||||
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200403120447-c50568487044 h1:112OPFAnKD+XtZhdffFnz17dEbiCTCKfnNQCAWmwFzA=
|
||||
google.golang.org/genproto v0.0.0-20200403120447-c50568487044/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200428115010-c45acf45369a h1:ykRcNp3dotYGpAEIYeWCGaefklVjVy/rnSvM3zNh6j8=
|
||||
google.golang.org/genproto v0.0.0-20200428115010-c45acf45369a/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380 h1:xriR1EgvKfkKxIoU2uUvrMVl+H26359loFFUleSMXFo=
|
||||
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
@ -553,8 +470,6 @@ google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLY
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.20.1 h1:ESRXHgpUBG5D2I5mmsQIyYxB/tQIZfSZ8wLyFDf/N/U=
|
||||
google.golang.org/protobuf v1.20.1/go.mod h1:KqelGeouBkcbcuB3HCk4/YH2tmNLk6YSWA5LIWeI/lY=
|
||||
google.golang.org/protobuf v1.21.0 h1:qdOKuR/EIArgaWNjetjgTzgVTAZ+S/WXVrq9HW9zimw=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.22.0 h1:cJv5/xdbk1NnMPR1VP9+HU6gupuG9MLBoH1r6RHZ2MY=
|
||||
@ -563,7 +478,6 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
25
internal/admin/auth/token_verifier.go
Normal file
25
internal/admin/auth/token_verifier.go
Normal file
@ -0,0 +1,25 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/zitadel/internal/api/auth"
|
||||
)
|
||||
|
||||
type TokenVerifier struct {
|
||||
}
|
||||
|
||||
func Start() (v *TokenVerifier) {
|
||||
return new(TokenVerifier)
|
||||
}
|
||||
|
||||
func (v *TokenVerifier) VerifyAccessToken(ctx context.Context, token string) (string, string, string, error) {
|
||||
return "", "", "", nil
|
||||
}
|
||||
|
||||
func (v *TokenVerifier) ResolveGrants(ctx context.Context, userID, orgID string) ([]*auth.Grant, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (v *TokenVerifier) GetProjectIDByClientID(ctx context.Context, clientID string) (string, error) {
|
||||
return "", nil
|
||||
}
|
11
internal/admin/model/setup_org.go
Normal file
11
internal/admin/model/setup_org.go
Normal file
@ -0,0 +1,11 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
)
|
||||
|
||||
type SetupOrg struct {
|
||||
*org_model.Org
|
||||
*usr_model.User
|
||||
}
|
60
internal/admin/repository/eventsourcing/eventstore/org.go
Normal file
60
internal/admin/repository/eventsourcing/eventstore/org.go
Normal file
@ -0,0 +1,60 @@
|
||||
package eventstore
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
admin_model "github.com/caos/zitadel/internal/admin/model"
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/eventstore/sdk"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
org_es "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
usr_es "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
)
|
||||
|
||||
type OrgRepo struct {
|
||||
Eventstore eventstore.Eventstore
|
||||
OrgEventstore *org_es.OrgEventstore
|
||||
UserEventstore *usr_es.UserEventstore
|
||||
}
|
||||
|
||||
func (repo *OrgRepo) SetUpOrg(ctx context.Context, setUp *admin_model.SetupOrg) (*admin_model.SetupOrg, error) {
|
||||
org, aggregates, err := repo.OrgEventstore.PrepareCreateOrg(ctx, setUp.Org)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
user, userAggregate, err := repo.UserEventstore.PrepareCreateUser(ctx, setUp.User, org.AggregateID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
aggregates = append(aggregates, userAggregate)
|
||||
setupModel := &Setup{Org: org, User: user}
|
||||
|
||||
member := org_model.NewOrgMemberWithRoles(org.AggregateID, user.AggregateID, "ORG_ADMIN") //TODO: role as const
|
||||
_, memberAggregate, err := repo.OrgEventstore.PrepareAddOrgMember(ctx, member)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
aggregates = append(aggregates, memberAggregate)
|
||||
|
||||
err = sdk.PushAggregates(ctx, repo.Eventstore.PushAggregates, setupModel.AppendEvents, aggregates...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return SetupToModel(setupModel), nil
|
||||
}
|
||||
|
||||
func (repo *OrgRepo) OrgByID(ctx context.Context, id string) (*org_model.Org, error) {
|
||||
return repo.OrgEventstore.OrgByID(ctx, org_model.NewOrg(id))
|
||||
}
|
||||
|
||||
func (repo *OrgRepo) SearchOrgs(ctx context.Context) ([]*org_model.Org, error) {
|
||||
return nil, errors.ThrowUnimplemented(nil, "EVENT-hFIHK", "search not implemented")
|
||||
}
|
||||
|
||||
func (repo *OrgRepo) IsOrgUnique(ctx context.Context, name, domain string) (isUnique bool, err error) {
|
||||
return repo.OrgEventstore.IsOrgUnique(ctx, name, domain)
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package eventstore
|
||||
|
||||
import (
|
||||
admin_model "github.com/caos/zitadel/internal/admin/model"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
org_es "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
usr_es "github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
)
|
||||
|
||||
type Setup struct {
|
||||
*org_es.Org
|
||||
*usr_es.User
|
||||
}
|
||||
|
||||
func (s *Setup) AppendEvents(events ...*es_models.Event) error {
|
||||
for _, event := range events {
|
||||
var err error
|
||||
switch event.AggregateType {
|
||||
case org_model.OrgAggregate:
|
||||
err = s.Org.AppendEvent(event)
|
||||
case usr_es.UserAggregate:
|
||||
err = s.User.AppendEvent(event)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func SetupToModel(setup *Setup) *admin_model.SetupOrg {
|
||||
return &admin_model.SetupOrg{
|
||||
Org: org_es.OrgToModel(setup.Org),
|
||||
User: usr_es.UserToModel(setup.User),
|
||||
}
|
||||
}
|
23
internal/admin/repository/eventsourcing/eventstore/user.go
Normal file
23
internal/admin/repository/eventsourcing/eventstore/user.go
Normal file
@ -0,0 +1,23 @@
|
||||
package eventstore
|
||||
|
||||
import (
|
||||
"context"
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
usr_event "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
)
|
||||
|
||||
type UserRepo struct {
|
||||
UserEvents *usr_event.UserEventstore
|
||||
}
|
||||
|
||||
func (repo *UserRepo) UserByID(ctx context.Context, id string) (project *usr_model.User, err error) {
|
||||
return repo.UserEvents.UserByID(ctx, id)
|
||||
}
|
||||
|
||||
func (repo *UserRepo) CreateUser(ctx context.Context, user *usr_model.User) (*usr_model.User, error) {
|
||||
return repo.UserEvents.CreateUser(ctx, user)
|
||||
}
|
||||
|
||||
func (repo *UserRepo) RegisterUser(ctx context.Context, user *usr_model.User, resourceOwner string) (*usr_model.User, error) {
|
||||
return repo.UserEvents.RegisterUser(ctx, user, resourceOwner)
|
||||
}
|
68
internal/admin/repository/eventsourcing/repository.go
Normal file
68
internal/admin/repository/eventsourcing/repository.go
Normal file
@ -0,0 +1,68 @@
|
||||
package eventsourcing
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/admin/repository/eventsourcing/eventstore"
|
||||
sd "github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
es_int "github.com/caos/zitadel/internal/eventstore"
|
||||
es_org "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
es_usr "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Eventstore es_int.Config
|
||||
//View view.ViewConfig
|
||||
//Spooler spooler.SpoolerConfig
|
||||
}
|
||||
|
||||
type EsRepository struct {
|
||||
//spooler *es_spooler.Spooler
|
||||
eventstore.OrgRepo
|
||||
}
|
||||
|
||||
func Start(conf Config, systemDefaults sd.SystemDefaults) (*EsRepository, error) {
|
||||
es, err := es_int.Start(conf.Eventstore)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
//view, sql, err := mgmt_view.StartView(conf.View)
|
||||
//if err != nil {
|
||||
// return nil, err
|
||||
//}
|
||||
|
||||
//conf.Spooler.View = view
|
||||
//conf.Spooler.EsClient = es.Client
|
||||
//conf.Spooler.SQL = sql
|
||||
//spool := spooler.StartSpooler(conf.Spooler)
|
||||
|
||||
org := es_org.StartOrg(es_org.OrgConfig{Eventstore: es})
|
||||
|
||||
user, err := es_usr.StartUser(es_usr.UserConfig{
|
||||
Eventstore: es,
|
||||
Cache: conf.Eventstore.Cache,
|
||||
}, systemDefaults)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &EsRepository{
|
||||
OrgRepo: eventstore.OrgRepo{
|
||||
Eventstore: es,
|
||||
OrgEventstore: org,
|
||||
UserEventstore: user,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (repo *EsRepository) Health(ctx context.Context) error {
|
||||
err := repo.Eventstore.Health(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = repo.UserEventstore.Health(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return repo.OrgEventstore.Health(ctx)
|
||||
}
|
15
internal/admin/repository/org.go
Normal file
15
internal/admin/repository/org.go
Normal file
@ -0,0 +1,15 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
admin_model "github.com/caos/zitadel/internal/admin/model"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
)
|
||||
|
||||
type OrgRepository interface {
|
||||
SetUpOrg(context.Context, *admin_model.SetupOrg) (*admin_model.SetupOrg, error)
|
||||
IsOrgUnique(ctx context.Context, name, domain string) (bool, error)
|
||||
OrgByID(ctx context.Context, id string) (*org_model.Org, error)
|
||||
SearchOrgs(ctx context.Context) ([]*org_model.Org, error)
|
||||
}
|
8
internal/admin/repository/repository.go
Normal file
8
internal/admin/repository/repository.go
Normal file
@ -0,0 +1,8 @@
|
||||
package repository
|
||||
|
||||
import "context"
|
||||
|
||||
type Repository interface {
|
||||
Health(ctx context.Context) error
|
||||
OrgRepository
|
||||
}
|
@ -74,5 +74,5 @@ func readerFuncForFile(configFile string) (ReaderFunc, error) {
|
||||
case ".toml":
|
||||
return TOMLReader, nil
|
||||
}
|
||||
return nil, errors.ThrowUnimplementedf(nil, "file extension (%s) not supported", ext)
|
||||
return nil, errors.ThrowUnimplementedf(nil, "CONFI-ZLk4u", "file extension (%s) not supported", ext)
|
||||
}
|
||||
|
25
internal/eventstore/internal/repository/sql/data.go
Normal file
25
internal/eventstore/internal/repository/sql/data.go
Normal file
@ -0,0 +1,25 @@
|
||||
package sql
|
||||
|
||||
import "database/sql/driver"
|
||||
|
||||
// Data represents a byte array that may be null.
|
||||
// Data implements the sql.Scanner interface
|
||||
type Data []byte
|
||||
|
||||
// Scan implements the Scanner interface.
|
||||
func (data *Data) Scan(value interface{}) error {
|
||||
if value == nil {
|
||||
*data = nil
|
||||
return nil
|
||||
}
|
||||
*data = Data(value.([]byte))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Value implements the driver Valuer interface.
|
||||
func (data Data) Value() (driver.Value, error) {
|
||||
if len(data) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
return []byte(data), nil
|
||||
}
|
@ -24,16 +24,13 @@ var (
|
||||
expectedFilterEventsAggregateIDTypeLimit = regexp.MustCompile(selectEscaped + ` WHERE aggregate_id = \$1 AND aggregate_type = ANY\(\$2\) ORDER BY event_sequence LIMIT \$3`).String()
|
||||
expectedGetAllEvents = regexp.MustCompile(selectEscaped + ` ORDER BY event_sequence`).String()
|
||||
|
||||
expectedInsertStatement = regexp.MustCompile(`insert into eventstore\.events ` +
|
||||
expectedInsertStatement = regexp.MustCompile(`INSERT INTO eventstore\.events ` +
|
||||
`\(event_type, aggregate_type, aggregate_id, aggregate_version, creation_date, event_data, editor_user, editor_service, resource_owner, previous_sequence\) ` +
|
||||
`select \$1, \$2, \$3, \$4, coalesce\(\$5, now\(\)\), \$6, \$7, \$8, \$9, ` +
|
||||
`case \(select exists\(select event_sequence from eventstore\.events where aggregate_type = \$10 AND aggregate_id = \$11\)\) ` +
|
||||
`WHEN true then \(select event_sequence from eventstore\.events where aggregate_type = \$12 AND aggregate_id = \$13 order by event_sequence desc limit 1\) ` +
|
||||
`ELSE NULL ` +
|
||||
`end ` +
|
||||
`where \(` +
|
||||
`\(select count\(id\) from eventstore\.events where event_sequence >= COALESCE\(\$14, 0\) AND aggregate_type = \$15 AND aggregate_id = \$16\) = 1 OR ` +
|
||||
`\(\(select count\(id\) from eventstore\.events where aggregate_type = \$17 and aggregate_id = \$18\) = 0 AND COALESCE\(\$19, 0\) = 0\)\) RETURNING id, event_sequence, creation_date`).String()
|
||||
`SELECT \$1, \$2, \$3, \$4, COALESCE\(\$5, now\(\)\), \$6, \$7, \$8, \$9, \$10 ` +
|
||||
`WHERE EXISTS \(SELECT 1 WHERE ` +
|
||||
`EXISTS \(SELECT 1 FROM eventstore\.events WHERE event_sequence = COALESCE\(\$11, 0\) AND aggregate_type = \$12 AND aggregate_id = \$13\) OR ` +
|
||||
`NOT EXISTS \(SELECT 1 FROM eventstore\.events WHERE aggregate_type = \$14 AND aggregate_id = \$15\) AND COALESCE\(\$16, 0\) = 0\) ` +
|
||||
`RETURNING id, event_sequence, creation_date`).String()
|
||||
)
|
||||
|
||||
type dbMock struct {
|
||||
@ -105,9 +102,7 @@ func (db *dbMock) expectRollback(err error) *dbMock {
|
||||
func (db *dbMock) expectInsertEvent(e *models.Event, returnedID string, returnedSequence uint64) *dbMock {
|
||||
db.mock.ExpectQuery(expectedInsertStatement).
|
||||
WithArgs(
|
||||
e.Type, e.AggregateType, e.AggregateID, e.AggregateVersion, sqlmock.AnyArg(), e.Data, e.EditorUser, e.EditorService, e.ResourceOwner,
|
||||
e.AggregateType, e.AggregateID,
|
||||
e.AggregateType, e.AggregateID,
|
||||
e.Type, e.AggregateType, e.AggregateID, e.AggregateVersion, sqlmock.AnyArg(), Data(e.Data), e.EditorUser, e.EditorService, e.ResourceOwner, Sequence(e.PreviousSequence),
|
||||
Sequence(e.PreviousSequence), e.AggregateType, e.AggregateID,
|
||||
e.AggregateType, e.AggregateID, Sequence(e.PreviousSequence),
|
||||
).
|
||||
@ -122,9 +117,7 @@ func (db *dbMock) expectInsertEvent(e *models.Event, returnedID string, returned
|
||||
func (db *dbMock) expectInsertEventError(e *models.Event) *dbMock {
|
||||
db.mock.ExpectQuery(expectedInsertStatement).
|
||||
WithArgs(
|
||||
e.Type, e.AggregateType, e.AggregateID, e.AggregateVersion, sqlmock.AnyArg(), e.Data, e.EditorUser, e.EditorService, e.ResourceOwner,
|
||||
e.AggregateType, e.AggregateID,
|
||||
e.AggregateType, e.AggregateID,
|
||||
e.Type, e.AggregateType, e.AggregateID, e.AggregateVersion, sqlmock.AnyArg(), Data(e.Data), e.EditorUser, e.EditorService, e.ResourceOwner, Sequence(e.PreviousSequence),
|
||||
Sequence(e.PreviousSequence), e.AggregateType, e.AggregateID,
|
||||
e.AggregateType, e.AggregateID, Sequence(e.PreviousSequence),
|
||||
).
|
||||
|
@ -54,6 +54,7 @@ func filter(querier Querier, searchQuery *es_models.SearchQuery) (events []*es_m
|
||||
for rows.Next() {
|
||||
event := new(models.Event)
|
||||
var previousSequence Sequence
|
||||
data := make(Data, 0)
|
||||
|
||||
err = rows.Scan(
|
||||
&event.ID,
|
||||
@ -61,7 +62,7 @@ func filter(querier Querier, searchQuery *es_models.SearchQuery) (events []*es_m
|
||||
&event.Type,
|
||||
&event.Sequence,
|
||||
&previousSequence,
|
||||
&event.Data,
|
||||
&data,
|
||||
&event.EditorService,
|
||||
&event.EditorUser,
|
||||
&event.ResourceOwner,
|
||||
@ -76,6 +77,10 @@ func filter(querier Querier, searchQuery *es_models.SearchQuery) (events []*es_m
|
||||
}
|
||||
|
||||
event.PreviousSequence = uint64(previousSequence)
|
||||
|
||||
event.Data = make([]byte, len(data))
|
||||
copy(event.Data, data)
|
||||
|
||||
events = append(events, event)
|
||||
}
|
||||
|
||||
|
@ -11,19 +11,14 @@ import (
|
||||
"github.com/cockroachdb/cockroach-go/crdb"
|
||||
)
|
||||
|
||||
const insertStmt = "insert into eventstore.events " +
|
||||
const insertStmt = "INSERT INTO eventstore.events " +
|
||||
"(event_type, aggregate_type, aggregate_id, aggregate_version, creation_date, event_data, editor_user, editor_service, resource_owner, previous_sequence) " +
|
||||
"select $1, $2, $3, $4, coalesce($5, now()), $6, $7, $8, $9, " +
|
||||
// case is to set the highest sequence or NULL in previous_sequence
|
||||
"case (select exists(select event_sequence from eventstore.events where aggregate_type = $10 AND aggregate_id = $11)) " +
|
||||
"WHEN true then (select event_sequence from eventstore.events where aggregate_type = $12 AND aggregate_id = $13 order by event_sequence desc limit 1) " +
|
||||
"ELSE NULL " +
|
||||
"end " +
|
||||
"where (" +
|
||||
// exactly one event of requested aggregate must have a >= sequence (last inserted event)
|
||||
"(select count(id) from eventstore.events where event_sequence >= COALESCE($14, 0) AND aggregate_type = $15 AND aggregate_id = $16) = 1 OR " +
|
||||
// previous sequence = 0, no events must exist for the requested aggregate
|
||||
"((select count(id) from eventstore.events where aggregate_type = $17 and aggregate_id = $18) = 0 AND COALESCE($19, 0) = 0)) " +
|
||||
"SELECT $1, $2, $3, $4, COALESCE($5, now()), $6, $7, $8, $9, $10 " +
|
||||
"WHERE EXISTS (SELECT 1 WHERE " +
|
||||
// exactly one event of requested aggregate must have the given previous sequence as sequence (last inserted event)
|
||||
"EXISTS (SELECT 1 FROM eventstore.events WHERE event_sequence = COALESCE($11, 0) AND aggregate_type = $12 AND aggregate_id = $13) OR " +
|
||||
// if previous sequence = 0, no events must exist for the requested aggregate
|
||||
"NOT EXISTS (SELECT 1 FROM eventstore.events WHERE aggregate_type = $14 AND aggregate_id = $15) AND COALESCE($16, 0) = 0) " +
|
||||
"RETURNING id, event_sequence, creation_date"
|
||||
|
||||
func (db *SQL) PushAggregates(ctx context.Context, aggregates ...*models.Aggregate) (err error) {
|
||||
@ -74,14 +69,7 @@ func precondtion(tx *sql.Tx, aggregate *models.Aggregate) error {
|
||||
|
||||
func insertEvents(stmt *sql.Stmt, previousSequence Sequence, events []*models.Event) error {
|
||||
for _, event := range events {
|
||||
if event.Data == nil || len(event.Data) == 0 {
|
||||
//json decoder failes with EOF if json text is empty
|
||||
event.Data = []byte("{}")
|
||||
}
|
||||
|
||||
rows, err := stmt.Query(event.Type, event.AggregateType, event.AggregateID, event.AggregateVersion, event.CreationDate, event.Data, event.EditorUser, event.EditorService, event.ResourceOwner,
|
||||
event.AggregateType, event.AggregateID,
|
||||
event.AggregateType, event.AggregateID,
|
||||
rows, err := stmt.Query(event.Type, event.AggregateType, event.AggregateID, event.AggregateVersion, event.CreationDate, Data(event.Data), event.EditorUser, event.EditorService, event.ResourceOwner, previousSequence,
|
||||
previousSequence, event.AggregateType, event.AggregateID,
|
||||
event.AggregateType, event.AggregateID, previousSequence)
|
||||
|
||||
@ -99,6 +87,7 @@ func insertEvents(stmt *sql.Stmt, previousSequence Sequence, events []*models.Ev
|
||||
}
|
||||
|
||||
if !rowInserted {
|
||||
logging.LogWithFields("SQL-5aATu", "aggregate", event.AggregateType, "id", event.AggregateID).Info("wrong sequence")
|
||||
return caos_errs.ThrowAlreadyExists(nil, "SQL-GKcAa", "wrong sequence")
|
||||
}
|
||||
|
||||
|
@ -89,7 +89,6 @@ func TestSQL_PushAggregates(t *testing.T) {
|
||||
ResourceOwner: "ro",
|
||||
PreviousSequence: 34,
|
||||
Type: "eventTyp",
|
||||
Data: []byte("{}"),
|
||||
AggregateVersion: "v0.0.1",
|
||||
},
|
||||
"asdfölk-234", 45).
|
||||
@ -101,7 +100,6 @@ func TestSQL_PushAggregates(t *testing.T) {
|
||||
ResourceOwner: "ro2",
|
||||
PreviousSequence: 45,
|
||||
Type: "eventTyp",
|
||||
Data: []byte("{}"),
|
||||
AggregateVersion: "v0.0.1",
|
||||
}, "asdfölk-233", 46).
|
||||
expectReleaseSavepoint(nil).
|
||||
@ -151,7 +149,6 @@ func TestSQL_PushAggregates(t *testing.T) {
|
||||
EditorUser: "usr",
|
||||
ResourceOwner: "ro",
|
||||
PreviousSequence: 34,
|
||||
Data: []byte("{}"),
|
||||
Type: "eventTyp",
|
||||
AggregateVersion: "v0.0.1",
|
||||
}, "asdfölk-233", 47).
|
||||
@ -162,7 +159,6 @@ func TestSQL_PushAggregates(t *testing.T) {
|
||||
EditorUser: "usr",
|
||||
ResourceOwner: "ro",
|
||||
PreviousSequence: 40,
|
||||
Data: []byte("{}"),
|
||||
Type: "eventTyp",
|
||||
AggregateVersion: "v0.0.1",
|
||||
}, "asdfölk-233", 48).
|
||||
@ -410,8 +406,11 @@ func Test_precondtion(t *testing.T) {
|
||||
t.FailNow()
|
||||
}
|
||||
err = precondtion(tx, tt.args.aggregate)
|
||||
if (tt.isErr != nil && err == nil) || (tt.isErr != nil && !tt.isErr(err)) {
|
||||
t.Error("precondtion() wrong error", err)
|
||||
if (err != nil) && (tt.isErr == nil) {
|
||||
t.Errorf("no error expected got: %v", err)
|
||||
}
|
||||
if tt.isErr != nil && !tt.isErr(err) {
|
||||
t.Errorf("precondtion() wrong error %T, %v", err, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -5,16 +5,16 @@ import (
|
||||
)
|
||||
|
||||
// Sequence represents a number that may be null.
|
||||
// Sequence implements the sql.Scanner interface so
|
||||
// Sequence implements the sql.Scanner interface
|
||||
type Sequence uint64
|
||||
|
||||
// Scan implements the Scanner interface.
|
||||
func (n *Sequence) Scan(value interface{}) error {
|
||||
func (seq *Sequence) Scan(value interface{}) error {
|
||||
if value == nil {
|
||||
*n = 0
|
||||
*seq = 0
|
||||
return nil
|
||||
}
|
||||
*n = Sequence(value.(int64))
|
||||
*seq = Sequence(value.(int64))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@ func (at AggregateType) String() string {
|
||||
type Aggregates []*Aggregate
|
||||
|
||||
type Aggregate struct {
|
||||
id string
|
||||
ID string
|
||||
typ AggregateType
|
||||
PreviousSequence uint64
|
||||
version Version
|
||||
@ -45,7 +45,7 @@ func (a *Aggregate) AppendEvent(typ EventType, payload interface{}) (*Aggregate,
|
||||
CreationDate: time.Now(),
|
||||
Data: data,
|
||||
Type: typ,
|
||||
AggregateID: a.id,
|
||||
AggregateID: a.ID,
|
||||
AggregateType: a.typ,
|
||||
AggregateVersion: a.version,
|
||||
EditorService: a.editorService,
|
||||
@ -66,7 +66,7 @@ func (a *Aggregate) Validate() error {
|
||||
if a == nil {
|
||||
return errors.ThrowPreconditionFailed(nil, "MODEL-yi5AC", "aggregate is nil")
|
||||
}
|
||||
if a.id == "" {
|
||||
if a.ID == "" {
|
||||
return errors.ThrowPreconditionFailed(nil, "MODEL-FSjKV", "id not set")
|
||||
}
|
||||
if string(a.typ) == "" {
|
||||
|
@ -22,7 +22,7 @@ func (c *AggregateCreator) NewAggregate(ctx context.Context, id string, typ Aggr
|
||||
resourceOwner := ctxData.OrgID
|
||||
|
||||
aggregate := &Aggregate{
|
||||
id: id,
|
||||
ID: id,
|
||||
typ: typ,
|
||||
PreviousSequence: previousSequence,
|
||||
version: version,
|
||||
|
@ -83,7 +83,7 @@ func TestAggregateCreator_NewAggregate(t *testing.T) {
|
||||
creator: &AggregateCreator{serviceName: "admin"},
|
||||
wantErr: false,
|
||||
want: &Aggregate{
|
||||
id: "hodor",
|
||||
ID: "hodor",
|
||||
Events: make([]*Event, 0, 2),
|
||||
typ: "user",
|
||||
version: "v1.0.0",
|
||||
|
@ -114,7 +114,7 @@ func TestAggregate_Validate(t *testing.T) {
|
||||
name: "no type error",
|
||||
wantErr: true,
|
||||
fields: fields{aggregate: &Aggregate{
|
||||
id: "aggID",
|
||||
ID: "aggID",
|
||||
version: "v1.0.0",
|
||||
editorService: "svc",
|
||||
editorUser: "hodor",
|
||||
@ -135,7 +135,7 @@ func TestAggregate_Validate(t *testing.T) {
|
||||
name: "invalid version error",
|
||||
wantErr: true,
|
||||
fields: fields{aggregate: &Aggregate{
|
||||
id: "aggID",
|
||||
ID: "aggID",
|
||||
typ: "user",
|
||||
editorService: "svc",
|
||||
editorUser: "hodor",
|
||||
@ -156,7 +156,7 @@ func TestAggregate_Validate(t *testing.T) {
|
||||
name: "no query in precondition error",
|
||||
wantErr: true,
|
||||
fields: fields{aggregate: &Aggregate{
|
||||
id: "aggID",
|
||||
ID: "aggID",
|
||||
typ: "user",
|
||||
version: "v1.0.0",
|
||||
editorService: "svc",
|
||||
@ -182,7 +182,7 @@ func TestAggregate_Validate(t *testing.T) {
|
||||
name: "no func in precondition error",
|
||||
wantErr: true,
|
||||
fields: fields{aggregate: &Aggregate{
|
||||
id: "aggID",
|
||||
ID: "aggID",
|
||||
typ: "user",
|
||||
version: "v1.0.0",
|
||||
editorService: "svc",
|
||||
@ -208,7 +208,7 @@ func TestAggregate_Validate(t *testing.T) {
|
||||
name: "validation without precondition ok",
|
||||
wantErr: false,
|
||||
fields: fields{aggregate: &Aggregate{
|
||||
id: "aggID",
|
||||
ID: "aggID",
|
||||
typ: "user",
|
||||
version: "v1.0.0",
|
||||
editorService: "svc",
|
||||
@ -231,7 +231,7 @@ func TestAggregate_Validate(t *testing.T) {
|
||||
name: "validation with precondition ok",
|
||||
wantErr: false,
|
||||
fields: fields{aggregate: &Aggregate{
|
||||
id: "aggID",
|
||||
ID: "aggID",
|
||||
typ: "user",
|
||||
version: "v1.0.0",
|
||||
editorService: "svc",
|
||||
|
@ -1,6 +1,8 @@
|
||||
package models
|
||||
|
||||
import "github.com/caos/zitadel/internal/errors"
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
)
|
||||
|
||||
type SearchQuery struct {
|
||||
Limit uint64
|
||||
@ -33,6 +35,10 @@ func (q *SearchQuery) AggregateIDFilter(id string) *SearchQuery {
|
||||
return q.setFilter(NewFilter(Field_AggregateID, id, Operation_Equals))
|
||||
}
|
||||
|
||||
func (q *SearchQuery) AggregateIDsFilter(ids ...string) *SearchQuery {
|
||||
return q.setFilter(NewFilter(Field_AggregateID, ids, Operation_In))
|
||||
}
|
||||
|
||||
func (q *SearchQuery) AggregateTypeFilter(types ...AggregateType) *SearchQuery {
|
||||
return q.setFilter(NewFilter(Field_AggregateType, types, Operation_In))
|
||||
}
|
||||
|
@ -0,0 +1,52 @@
|
||||
package eventstore
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
org_es "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
)
|
||||
|
||||
type OrgRepository struct {
|
||||
*org_es.OrgEventstore
|
||||
}
|
||||
|
||||
func (repo *OrgRepository) OrgByID(ctx context.Context, id string) (*org_model.Org, error) {
|
||||
org := org_model.NewOrg(id)
|
||||
return repo.OrgEventstore.OrgByID(ctx, org)
|
||||
}
|
||||
|
||||
func (repo *OrgRepository) OrgByDomainGlobal(ctx context.Context, domain string) (*org_model.Org, error) {
|
||||
return nil, errors.ThrowUnimplemented(nil, "EVENT-GQoS8", "not implemented")
|
||||
}
|
||||
|
||||
func (repo *OrgRepository) UpdateOrg(ctx context.Context, org *org_model.Org) (*org_model.Org, error) {
|
||||
return nil, errors.ThrowUnimplemented(nil, "EVENT-RkurR", "not implemented")
|
||||
}
|
||||
|
||||
func (repo *OrgRepository) DeactivateOrg(ctx context.Context, id string) (*org_model.Org, error) {
|
||||
return repo.OrgEventstore.DeactivateOrg(ctx, id)
|
||||
}
|
||||
|
||||
func (repo *OrgRepository) ReactivateOrg(ctx context.Context, id string) (*org_model.Org, error) {
|
||||
return repo.OrgEventstore.ReactivateOrg(ctx, id)
|
||||
}
|
||||
|
||||
func (repo *OrgRepository) OrgMemberByID(ctx context.Context, orgID, userID string) (member *org_model.OrgMember, err error) {
|
||||
member = org_model.NewOrgMember(orgID, userID)
|
||||
return repo.OrgEventstore.OrgMemberByIDs(ctx, member)
|
||||
}
|
||||
|
||||
func (repo *OrgRepository) AddOrgMember(ctx context.Context, member *org_model.OrgMember) (*org_model.OrgMember, error) {
|
||||
return repo.OrgEventstore.AddOrgMember(ctx, member)
|
||||
}
|
||||
|
||||
func (repo *OrgRepository) ChangeOrgMember(ctx context.Context, member *org_model.OrgMember) (*org_model.OrgMember, error) {
|
||||
return repo.OrgEventstore.ChangeOrgMember(ctx, member)
|
||||
}
|
||||
|
||||
func (repo *OrgRepository) RemoveOrgMember(ctx context.Context, orgID, userID string) error {
|
||||
member := org_model.NewOrgMember(orgID, userID)
|
||||
return repo.OrgEventstore.RemoveOrgMember(ctx, member)
|
||||
}
|
@ -2,6 +2,7 @@ package eventsourcing
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
sd "github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
"github.com/caos/zitadel/internal/config/types"
|
||||
es_int "github.com/caos/zitadel/internal/eventstore"
|
||||
@ -10,6 +11,7 @@ import (
|
||||
"github.com/caos/zitadel/internal/management/repository/eventsourcing/handler"
|
||||
"github.com/caos/zitadel/internal/management/repository/eventsourcing/spooler"
|
||||
mgmt_view "github.com/caos/zitadel/internal/management/repository/eventsourcing/view"
|
||||
es_org "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
es_proj "github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
||||
es_usr "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
es_grant "github.com/caos/zitadel/internal/usergrant/repository/eventsourcing"
|
||||
@ -24,6 +26,7 @@ type Config struct {
|
||||
|
||||
type EsRepository struct {
|
||||
spooler *es_spol.Spooler
|
||||
eventstore.OrgRepository
|
||||
eventstore.ProjectRepo
|
||||
eventstore.UserRepo
|
||||
eventstore.UserGrantRepo
|
||||
@ -65,14 +68,17 @@ func Start(conf Config, systemDefaults sd.SystemDefaults) (*EsRepository, error)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
org := es_org.StartOrg(es_org.OrgConfig{Eventstore: es})
|
||||
|
||||
eventstoreRepos := handler.EventstoreRepos{ProjectEvents: project}
|
||||
spool := spooler.StartSpooler(conf.Spooler, es, view, sqlClient, eventstoreRepos)
|
||||
|
||||
return &EsRepository{
|
||||
spool,
|
||||
eventstore.ProjectRepo{conf.SearchLimit, project, view},
|
||||
eventstore.UserRepo{conf.SearchLimit, user, view},
|
||||
eventstore.UserGrantRepo{conf.SearchLimit, usergrant, view},
|
||||
spooler: spool,
|
||||
OrgRepository: eventstore.OrgRepository{org},
|
||||
ProjectRepo: eventstore.ProjectRepo{conf.SearchLimit, project, view},
|
||||
UserRepo: eventstore.UserRepo{conf.SearchLimit, user, view},
|
||||
UserGrantRepo: eventstore.UserGrantRepo{conf.SearchLimit, usergrant, view},
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
21
internal/management/repository/org.go
Normal file
21
internal/management/repository/org.go
Normal file
@ -0,0 +1,21 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
)
|
||||
|
||||
type OrgRepository interface {
|
||||
OrgByID(ctx context.Context, id string) (*org_model.Org, error)
|
||||
OrgByDomainGlobal(ctx context.Context, domain string) (*org_model.Org, error)
|
||||
UpdateOrg(ctx context.Context, org *org_model.Org) (*org_model.Org, error)
|
||||
DeactivateOrg(ctx context.Context, id string) (*org_model.Org, error)
|
||||
ReactivateOrg(ctx context.Context, id string) (*org_model.Org, error)
|
||||
}
|
||||
|
||||
type OrgMemberRepository interface {
|
||||
AddOrgMember(ctx context.Context, member *org_model.OrgMember) (*org_model.OrgMember, error)
|
||||
ChangeOrgMember(ctx context.Context, member *org_model.OrgMember) (*org_model.OrgMember, error)
|
||||
RemoveOrgMember(ctx context.Context, orgID, userID string) error
|
||||
}
|
@ -3,6 +3,8 @@ package repository
|
||||
type Repository interface {
|
||||
Health() error
|
||||
ProjectRepository
|
||||
OrgRepository
|
||||
OrgMemberRepository
|
||||
UserRepository
|
||||
UserGrantRepository
|
||||
}
|
||||
|
21
internal/org/model/member.go
Normal file
21
internal/org/model/member.go
Normal file
@ -0,0 +1,21 @@
|
||||
package model
|
||||
|
||||
import es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
|
||||
type OrgMember struct {
|
||||
es_models.ObjectRoot
|
||||
UserID string
|
||||
Roles []string
|
||||
}
|
||||
|
||||
func NewOrgMember(orgID, userID string) *OrgMember {
|
||||
return &OrgMember{ObjectRoot: es_models.ObjectRoot{AggregateID: orgID}, UserID: userID}
|
||||
}
|
||||
|
||||
func NewOrgMemberWithRoles(orgID, userID string, roles ...string) *OrgMember {
|
||||
return &OrgMember{ObjectRoot: es_models.ObjectRoot{AggregateID: orgID}, UserID: userID, Roles: roles}
|
||||
}
|
||||
|
||||
func (member *OrgMember) IsValid() bool {
|
||||
return member.AggregateID != "" && member.UserID != ""
|
||||
}
|
43
internal/org/model/org.go
Normal file
43
internal/org/model/org.go
Normal file
@ -0,0 +1,43 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
)
|
||||
|
||||
type Org struct {
|
||||
es_models.ObjectRoot
|
||||
|
||||
State OrgState
|
||||
Name string
|
||||
Domain string
|
||||
|
||||
Members []*OrgMember
|
||||
}
|
||||
|
||||
type OrgState int32
|
||||
|
||||
const (
|
||||
ORGSTATE_ACTIVE OrgState = iota
|
||||
ORGSTATE_INACTIVE
|
||||
)
|
||||
|
||||
func NewOrg(id string) *Org {
|
||||
return &Org{ObjectRoot: es_models.ObjectRoot{AggregateID: id}, State: ORGSTATE_ACTIVE}
|
||||
}
|
||||
|
||||
func (o *Org) IsActive() bool {
|
||||
return o.State == ORGSTATE_ACTIVE
|
||||
}
|
||||
|
||||
func (o *Org) IsValid() bool {
|
||||
return o.Name != "" && o.Domain != ""
|
||||
}
|
||||
|
||||
func (o *Org) ContainsMember(userID string) bool {
|
||||
for _, member := range o.Members {
|
||||
if member.UserID == userID {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
24
internal/org/model/types.go
Normal file
24
internal/org/model/types.go
Normal file
@ -0,0 +1,24 @@
|
||||
package model
|
||||
|
||||
import "github.com/caos/zitadel/internal/eventstore/models"
|
||||
|
||||
const (
|
||||
OrgAggregate models.AggregateType = "org"
|
||||
OrgDomainAggregate models.AggregateType = "org.domain"
|
||||
OrgNameAggregate models.AggregateType = "org.name"
|
||||
|
||||
OrgAdded models.EventType = "org.added"
|
||||
OrgChanged models.EventType = "org.changed"
|
||||
OrgDeactivated models.EventType = "org.deactivated"
|
||||
OrgReactivated models.EventType = "org.reactivated"
|
||||
|
||||
OrgNameReserved models.EventType = "org.name.reserved"
|
||||
OrgNameReleased models.EventType = "org.name.released"
|
||||
|
||||
OrgDomainReserved models.EventType = "org.domain.reserved"
|
||||
OrgDomainReleased models.EventType = "org.domain.released"
|
||||
|
||||
OrgMemberAdded models.EventType = "org.member.added"
|
||||
OrgMemberChanged models.EventType = "org.member.changed"
|
||||
OrgMemberRemoved models.EventType = "org.member.removed"
|
||||
)
|
215
internal/org/repository/eventsourcing/eventstore.go
Normal file
215
internal/org/repository/eventsourcing/eventstore.go
Normal file
@ -0,0 +1,215 @@
|
||||
package eventsourcing
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
es_sdk "github.com/caos/zitadel/internal/eventstore/sdk"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
)
|
||||
|
||||
type OrgEventstore struct {
|
||||
eventstore.Eventstore
|
||||
}
|
||||
|
||||
type OrgConfig struct {
|
||||
eventstore.Eventstore
|
||||
}
|
||||
|
||||
func StartOrg(conf OrgConfig) *OrgEventstore {
|
||||
return &OrgEventstore{Eventstore: conf.Eventstore}
|
||||
}
|
||||
|
||||
func (es *OrgEventstore) PrepareCreateOrg(ctx context.Context, orgModel *org_model.Org) (*Org, []*es_models.Aggregate, error) {
|
||||
if orgModel == nil || !orgModel.IsValid() {
|
||||
return nil, nil, errors.ThrowInvalidArgument(nil, "EVENT-OeLSk", "org not valid")
|
||||
}
|
||||
id, err := idGenerator.NextID()
|
||||
if err != nil {
|
||||
return nil, nil, errors.ThrowInternal(err, "EVENT-OwciI", "id gen failed")
|
||||
}
|
||||
orgModel.AggregateID = strconv.FormatUint(id, 10)
|
||||
org := OrgFromModel(orgModel)
|
||||
|
||||
aggregates, err := orgCreatedAggregates(ctx, es.AggregateCreator(), org)
|
||||
|
||||
return org, aggregates, err
|
||||
}
|
||||
|
||||
func (es *OrgEventstore) CreateOrg(ctx context.Context, orgModel *org_model.Org) (*org_model.Org, error) {
|
||||
org, aggregates, err := es.PrepareCreateOrg(ctx, orgModel)
|
||||
err = es_sdk.PushAggregates(ctx, es.PushAggregates, org.AppendEvents, aggregates...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return OrgToModel(org), nil
|
||||
}
|
||||
|
||||
func (es *OrgEventstore) OrgByID(ctx context.Context, org *org_model.Org) (*org_model.Org, error) {
|
||||
if org == nil {
|
||||
return nil, errors.ThrowInvalidArgument(nil, "EVENT-gQTYP", "org not set")
|
||||
}
|
||||
query, err := OrgByIDQuery(org.AggregateID, org.Sequence)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
esOrg := OrgFromModel(org)
|
||||
err = es_sdk.Filter(ctx, es.FilterEvents, esOrg.AppendEvents, query)
|
||||
if err != nil && !errors.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
if esOrg.Sequence == 0 {
|
||||
return nil, errors.ThrowNotFound(nil, "EVENT-kVLb2", "org not found")
|
||||
}
|
||||
|
||||
return OrgToModel(esOrg), nil
|
||||
}
|
||||
|
||||
func (es *OrgEventstore) IsOrgUnique(ctx context.Context, name, domain string) (isUnique bool, err error) {
|
||||
var found bool
|
||||
err = es_sdk.Filter(ctx, es.FilterEvents, isUniqueValidation(&found), OrgNameUniqueQuery(name))
|
||||
if (err != nil && !errors.IsNotFound(err)) || found {
|
||||
return false, err
|
||||
}
|
||||
|
||||
err = es_sdk.Filter(ctx, es.FilterEvents, isUniqueValidation(&found), OrgDomainUniqueQuery(domain))
|
||||
if err != nil && !errors.IsNotFound(err) {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return !found, nil
|
||||
}
|
||||
|
||||
func isUniqueValidation(unique *bool) func(events ...*es_models.Event) error {
|
||||
return func(events ...*es_models.Event) error {
|
||||
if len(events) == 0 {
|
||||
return nil
|
||||
}
|
||||
*unique = *unique || events[0].Type == org_model.OrgDomainReserved || events[0].Type == org_model.OrgNameReserved
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (es *OrgEventstore) DeactivateOrg(ctx context.Context, orgID string) (*org_model.Org, error) {
|
||||
existingOrg, err := es.OrgByID(ctx, org_model.NewOrg(orgID))
|
||||
if err != nil {
|
||||
return nil, errors.ThrowInvalidArgument(nil, "EVENT-oL9nT", "org not found")
|
||||
}
|
||||
org := OrgFromModel(existingOrg)
|
||||
|
||||
aggregate := orgDeactivateAggregate(es.AggregateCreator(), org)
|
||||
err = es_sdk.Push(ctx, es.PushAggregates, org.AppendEvents, aggregate)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return OrgToModel(org), nil
|
||||
}
|
||||
|
||||
func (es *OrgEventstore) ReactivateOrg(ctx context.Context, orgID string) (*org_model.Org, error) {
|
||||
existingOrg, err := es.OrgByID(ctx, org_model.NewOrg(orgID))
|
||||
if err != nil {
|
||||
return nil, errors.ThrowInvalidArgument(nil, "EVENT-oL9nT", "org not set")
|
||||
}
|
||||
org := OrgFromModel(existingOrg)
|
||||
|
||||
aggregate := orgReactivateAggregate(es.AggregateCreator(), org)
|
||||
err = es_sdk.Push(ctx, es.PushAggregates, org.AppendEvents, aggregate)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
}
|
||||
return OrgToModel(org), nil
|
||||
}
|
||||
|
||||
func (es *OrgEventstore) OrgMemberByIDs(ctx context.Context, member *org_model.OrgMember) (*org_model.OrgMember, error) {
|
||||
if member == nil || member.UserID == "" || member.AggregateID == "" {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-ld93d", "member not set")
|
||||
}
|
||||
|
||||
org, err := es.OrgByID(ctx, &org_model.Org{ObjectRoot: member.ObjectRoot, Members: []*org_model.OrgMember{member}})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, currentMember := range org.Members {
|
||||
if currentMember.UserID == member.UserID {
|
||||
return currentMember, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, errors.ThrowNotFound(nil, "EVENT-SXji6", "member not found")
|
||||
}
|
||||
|
||||
func (es *OrgEventstore) PrepareAddOrgMember(ctx context.Context, member *org_model.OrgMember) (*OrgMember, *es_models.Aggregate, error) {
|
||||
if member == nil || !member.IsValid() {
|
||||
return nil, nil, errors.ThrowPreconditionFailed(nil, "EVENT-9dk45", "UserID and Roles are required")
|
||||
}
|
||||
|
||||
repoMember := OrgMemberFromModel(member)
|
||||
addAggregate, err := orgMemberAddedAggregate(ctx, es.Eventstore.AggregateCreator(), repoMember)
|
||||
|
||||
return repoMember, addAggregate, err
|
||||
}
|
||||
|
||||
func (es *OrgEventstore) AddOrgMember(ctx context.Context, member *org_model.OrgMember) (*org_model.OrgMember, error) {
|
||||
repoMember, addAggregate, err := es.PrepareAddOrgMember(ctx, member)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = es_sdk.PushAggregates(ctx, es.PushAggregates, repoMember.AppendEvents, addAggregate)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return OrgMemberToModel(repoMember), nil
|
||||
}
|
||||
|
||||
func (es *OrgEventstore) ChangeOrgMember(ctx context.Context, member *org_model.OrgMember) (*org_model.OrgMember, error) {
|
||||
if member == nil || !member.IsValid() {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-9dk45", "UserID and Roles are required")
|
||||
}
|
||||
|
||||
existingMember, err := es.OrgMemberByIDs(ctx, member)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
member.ObjectRoot = existingMember.ObjectRoot
|
||||
repoMember := OrgMemberFromModel(member)
|
||||
repoExistingMember := OrgMemberFromModel(existingMember)
|
||||
|
||||
orgAggregate := orgMemberChangedAggregate(es.Eventstore.AggregateCreator(), repoExistingMember, repoMember)
|
||||
err = es_sdk.Push(ctx, es.PushAggregates, repoMember.AppendEvents, orgAggregate)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return OrgMemberToModel(repoMember), nil
|
||||
}
|
||||
|
||||
func (es *OrgEventstore) RemoveOrgMember(ctx context.Context, member *org_model.OrgMember) error {
|
||||
if member == nil || member.UserID == "" {
|
||||
return errors.ThrowInvalidArgument(nil, "EVENT-d43fs", "UserID is required")
|
||||
}
|
||||
|
||||
existingMember, err := es.OrgMemberByIDs(ctx, member)
|
||||
if errors.IsNotFound(err) {
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
member.ObjectRoot = existingMember.ObjectRoot
|
||||
repoMember := OrgMemberFromModel(member)
|
||||
|
||||
orgAggregate := orgMemberRemovedAggregate(es.Eventstore.AggregateCreator(), repoMember)
|
||||
return es_sdk.Push(ctx, es.PushAggregates, repoMember.AppendEvents, orgAggregate)
|
||||
}
|
1026
internal/org/repository/eventsourcing/eventstore_test.go
Normal file
1026
internal/org/repository/eventsourcing/eventstore_test.go
Normal file
File diff suppressed because it is too large
Load Diff
96
internal/org/repository/eventsourcing/member_model.go
Normal file
96
internal/org/repository/eventsourcing/member_model.go
Normal file
@ -0,0 +1,96 @@
|
||||
package eventsourcing
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/org/model"
|
||||
)
|
||||
|
||||
type OrgMember struct {
|
||||
es_models.ObjectRoot `json:"-"`
|
||||
|
||||
UserID string `json:"userId,omitempty"`
|
||||
Roles []string `json:"roles,omitempty"`
|
||||
}
|
||||
|
||||
func (m *OrgMember) AppendEvents(events ...*es_models.Event) error {
|
||||
for _, event := range events {
|
||||
err := m.AppendEvent(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *OrgMember) AppendEvent(event *es_models.Event) error {
|
||||
m.ObjectRoot.AppendEvent(event)
|
||||
|
||||
return m.setData(event)
|
||||
}
|
||||
|
||||
func (m *OrgMember) setData(event *es_models.Event) error {
|
||||
err := json.Unmarshal(event.Data, m)
|
||||
if err != nil {
|
||||
return errors.ThrowInternal(err, "EVENT-Hz7Mb", "unable to unmarshal data")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *OrgMember) Changes(updatedMember *OrgMember) map[string]interface{} {
|
||||
changes := make(map[string]interface{}, 2)
|
||||
|
||||
if !reflect.DeepEqual(m.Roles, updatedMember.Roles) {
|
||||
changes["roles"] = updatedMember.Roles
|
||||
changes["userId"] = m.UserID
|
||||
}
|
||||
|
||||
return changes
|
||||
}
|
||||
|
||||
func OrgMemberFromEvent(member *OrgMember, event *es_models.Event) (*OrgMember, error) {
|
||||
if member == nil {
|
||||
member = new(OrgMember)
|
||||
}
|
||||
member.ObjectRoot.AppendEvent(event)
|
||||
err := json.Unmarshal(event.Data, member)
|
||||
if err != nil {
|
||||
return nil, errors.ThrowInternal(err, "EVENT-D4qxo", "invalid event data")
|
||||
}
|
||||
return member, nil
|
||||
}
|
||||
|
||||
func OrgMembersFromModel(members []*model.OrgMember) []*OrgMember {
|
||||
convertedMembers := make([]*OrgMember, len(members))
|
||||
for i, m := range members {
|
||||
convertedMembers[i] = OrgMemberFromModel(m)
|
||||
}
|
||||
return convertedMembers
|
||||
}
|
||||
|
||||
func OrgMemberFromModel(member *model.OrgMember) *OrgMember {
|
||||
return &OrgMember{
|
||||
ObjectRoot: member.ObjectRoot,
|
||||
UserID: member.UserID,
|
||||
Roles: member.Roles,
|
||||
}
|
||||
}
|
||||
|
||||
func OrgMembersToModel(members []*OrgMember) []*model.OrgMember {
|
||||
convertedMembers := make([]*model.OrgMember, len(members))
|
||||
for i, m := range members {
|
||||
convertedMembers[i] = OrgMemberToModel(m)
|
||||
}
|
||||
return convertedMembers
|
||||
}
|
||||
|
||||
func OrgMemberToModel(member *OrgMember) *model.OrgMember {
|
||||
return &model.OrgMember{
|
||||
ObjectRoot: member.ObjectRoot,
|
||||
UserID: member.UserID,
|
||||
Roles: member.Roles,
|
||||
}
|
||||
}
|
195
internal/org/repository/eventsourcing/org.go
Normal file
195
internal/org/repository/eventsourcing/org.go
Normal file
@ -0,0 +1,195 @@
|
||||
package eventsourcing
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
"github.com/sony/sonyflake"
|
||||
)
|
||||
|
||||
var idGenerator = sonyflake.NewSonyflake(sonyflake.Settings{})
|
||||
|
||||
func OrgByIDQuery(id string, latestSequence uint64) (*es_models.SearchQuery, error) {
|
||||
if id == "" {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-dke74", "id should be filled")
|
||||
}
|
||||
return OrgQuery(latestSequence).
|
||||
AggregateIDFilter(id), nil
|
||||
}
|
||||
|
||||
func OrgDomainUniqueQuery(domain string) *es_models.SearchQuery {
|
||||
return es_models.NewSearchQuery().
|
||||
AggregateTypeFilter(org_model.OrgDomainAggregate).
|
||||
AggregateIDFilter(domain).
|
||||
OrderDesc().
|
||||
SetLimit(1)
|
||||
}
|
||||
|
||||
func OrgNameUniqueQuery(name string) *es_models.SearchQuery {
|
||||
return es_models.NewSearchQuery().
|
||||
AggregateTypeFilter(org_model.OrgNameAggregate).
|
||||
AggregateIDFilter(name).
|
||||
OrderDesc().
|
||||
SetLimit(1)
|
||||
}
|
||||
|
||||
func OrgQuery(latestSequence uint64) *es_models.SearchQuery {
|
||||
return es_models.NewSearchQuery().
|
||||
AggregateTypeFilter(org_model.OrgAggregate).
|
||||
LatestSequenceFilter(latestSequence)
|
||||
}
|
||||
|
||||
func OrgAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, id string, sequence uint64) (*es_models.Aggregate, error) {
|
||||
return aggCreator.NewAggregate(ctx, id, org_model.OrgAggregate, orgVersion, sequence)
|
||||
}
|
||||
|
||||
func orgCreatedAggregates(ctx context.Context, aggCreator *es_models.AggregateCreator, org *Org) (_ []*es_models.Aggregate, err error) {
|
||||
if org == nil {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-kdie7", "org should not be nil")
|
||||
}
|
||||
|
||||
domainAgrregate, err := uniqueDomainAggregate(ctx, aggCreator, org.Domain)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nameAggregate, err := uniqueNameAggregate(ctx, aggCreator, org.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
agg, err := aggCreator.NewAggregate(ctx, org.AggregateID, org_model.OrgAggregate, orgVersion, org.Sequence, es_models.OverwriteResourceOwner(org.AggregateID))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
agg, err = agg.AppendEvent(org_model.OrgAdded, org)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return []*es_models.Aggregate{
|
||||
agg,
|
||||
domainAgrregate,
|
||||
nameAggregate,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func OrgUpdateAggregates(ctx context.Context, aggCreator *es_models.AggregateCreator, existing *Org, updated *Org) ([]*es_models.Aggregate, error) {
|
||||
if existing == nil {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-dk83d", "existing org must not be nil")
|
||||
}
|
||||
if updated == nil {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-dhr74", "updated org must not be nil")
|
||||
}
|
||||
changes := existing.Changes(updated)
|
||||
if len(changes) == 0 {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-E0hc5", "no changes")
|
||||
}
|
||||
|
||||
aggregates := make([]*es_models.Aggregate, 0, 3)
|
||||
|
||||
if name, ok := changes["name"]; ok {
|
||||
nameAggregate, err := uniqueNameAggregate(ctx, aggCreator, name.(string))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
aggregates = append(aggregates, nameAggregate)
|
||||
}
|
||||
|
||||
if name, ok := changes["domain"]; ok {
|
||||
domainAggregate, err := uniqueDomainAggregate(ctx, aggCreator, name.(string))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
aggregates = append(aggregates, domainAggregate)
|
||||
}
|
||||
|
||||
orgAggregate, err := OrgAggregate(ctx, aggCreator, existing.AggregateID, existing.Sequence)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
orgAggregate, err = orgAggregate.AppendEvent(org_model.OrgChanged, changes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
aggregates = append(aggregates, orgAggregate)
|
||||
|
||||
return aggregates, nil
|
||||
}
|
||||
|
||||
func orgDeactivateAggregate(aggCreator *es_models.AggregateCreator, org *Org) func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||
return func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||
if org == nil {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-R03z8", "existing org must not be nil")
|
||||
}
|
||||
if org.State == int32(org_model.ORGSTATE_INACTIVE) {
|
||||
return nil, errors.ThrowInvalidArgument(nil, "EVENT-mcPH0", "org already inactive")
|
||||
}
|
||||
agg, err := OrgAggregate(ctx, aggCreator, org.AggregateID, org.Sequence)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return agg.AppendEvent(org_model.OrgDeactivated, nil)
|
||||
}
|
||||
}
|
||||
|
||||
func orgReactivateAggregate(aggCreator *es_models.AggregateCreator, org *Org) func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||
return func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||
if org == nil {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-cTHLd", "existing org must not be nil")
|
||||
}
|
||||
if org.State == int32(org_model.ORGSTATE_ACTIVE) {
|
||||
return nil, errors.ThrowInvalidArgument(nil, "EVENT-pUSMs", "org already active")
|
||||
}
|
||||
agg, err := OrgAggregate(ctx, aggCreator, org.AggregateID, org.Sequence)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return agg.AppendEvent(org_model.OrgReactivated, nil)
|
||||
}
|
||||
}
|
||||
|
||||
func uniqueDomainAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, domain string) (*es_models.Aggregate, error) {
|
||||
aggregate, err := aggCreator.NewAggregate(ctx, domain, org_model.OrgDomainAggregate, orgVersion, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
aggregate, err = aggregate.AppendEvent(org_model.OrgDomainReserved, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return aggregate.SetPrecondition(OrgDomainUniqueQuery(domain), isReservedValidation(aggregate, org_model.OrgDomainReserved)), nil
|
||||
}
|
||||
|
||||
func uniqueNameAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, name string) (*es_models.Aggregate, error) {
|
||||
aggregate, err := aggCreator.NewAggregate(ctx, name, org_model.OrgNameAggregate, orgVersion, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
aggregate, err = aggregate.AppendEvent(org_model.OrgNameReserved, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return aggregate.SetPrecondition(OrgNameUniqueQuery(name), isReservedValidation(aggregate, org_model.OrgNameReserved)), nil
|
||||
}
|
||||
|
||||
func isReservedValidation(aggregate *es_models.Aggregate, resevedEventType es_models.EventType) func(...*es_models.Event) error {
|
||||
return func(events ...*es_models.Event) error {
|
||||
if len(events) == 0 {
|
||||
aggregate.PreviousSequence = 0
|
||||
return nil
|
||||
}
|
||||
if events[0].Type == resevedEventType {
|
||||
return errors.ThrowPreconditionFailed(nil, "EVENT-eJQqe", "org already reseved")
|
||||
}
|
||||
aggregate.PreviousSequence = events[0].Sequence
|
||||
return nil
|
||||
}
|
||||
}
|
93
internal/org/repository/eventsourcing/org_member.go
Normal file
93
internal/org/repository/eventsourcing/org_member.go
Normal file
@ -0,0 +1,93 @@
|
||||
package eventsourcing
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
usr_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
)
|
||||
|
||||
func orgMemberAddedAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, member *OrgMember) (*es_models.Aggregate, error) {
|
||||
if member == nil {
|
||||
return nil, errors.ThrowInvalidArgument(nil, "EVENT-c63Ap", "member must not be nil")
|
||||
}
|
||||
|
||||
aggregate, err := aggCreator.NewAggregate(ctx, member.AggregateID, org_model.OrgAggregate, orgVersion, member.Sequence)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
validationQuery := es_models.NewSearchQuery().
|
||||
AggregateTypeFilter("org", "user").
|
||||
AggregateIDsFilter(member.AggregateID, member.UserID)
|
||||
|
||||
validation := addMemberValidation(aggregate, member)
|
||||
|
||||
return aggregate.SetPrecondition(validationQuery, validation).AppendEvent(org_model.OrgMemberAdded, member)
|
||||
}
|
||||
|
||||
func orgMemberChangedAggregate(aggCreator *es_models.AggregateCreator, existingMember *OrgMember, member *OrgMember) func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||
return func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||
if member == nil || existingMember == nil {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-d34fs", "member must not be nil")
|
||||
}
|
||||
|
||||
changes := existingMember.Changes(member)
|
||||
if len(changes) == 0 {
|
||||
return nil, errors.ThrowInvalidArgument(nil, "EVENT-VLMGn", "nothing changed")
|
||||
}
|
||||
|
||||
agg, err := OrgAggregate(ctx, aggCreator, existingMember.AggregateID, existingMember.Sequence)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return agg.AppendEvent(org_model.OrgMemberChanged, changes)
|
||||
}
|
||||
}
|
||||
|
||||
func orgMemberRemovedAggregate(aggCreator *es_models.AggregateCreator, member *OrgMember) func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||
return func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||
if member == nil {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-dieu7", "member must not be nil")
|
||||
}
|
||||
|
||||
agg, err := OrgAggregate(ctx, aggCreator, member.AggregateID, member.Sequence)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return agg.AppendEvent(org_model.OrgMemberRemoved, member)
|
||||
}
|
||||
}
|
||||
|
||||
func addMemberValidation(aggregate *es_models.Aggregate, member *OrgMember) func(...*es_models.Event) error {
|
||||
return func(events ...*es_models.Event) error {
|
||||
existsOrg := false
|
||||
existsUser := false
|
||||
isMember := false
|
||||
for _, event := range events {
|
||||
switch event.AggregateType {
|
||||
case usr_model.UserAggregate:
|
||||
existsUser = true
|
||||
case org_model.OrgAggregate:
|
||||
aggregate.PreviousSequence = event.Sequence
|
||||
existsOrg = true
|
||||
switch event.Type {
|
||||
case org_model.OrgMemberAdded, org_model.OrgMemberRemoved:
|
||||
manipulatedMember, err := OrgMemberFromEvent(new(OrgMember), event)
|
||||
if err != nil {
|
||||
return errors.ThrowInternal(err, "EVENT-Eg8St", "unable to validate object")
|
||||
}
|
||||
if manipulatedMember.UserID == member.UserID {
|
||||
isMember = event.Type == org_model.OrgMemberAdded
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if existsOrg && existsUser && !isMember {
|
||||
return nil
|
||||
}
|
||||
return errors.ThrowPreconditionFailed(nil, "EVENT-3OfIm", "conditions not met")
|
||||
}
|
||||
}
|
397
internal/org/repository/eventsourcing/org_member_test.go
Normal file
397
internal/org/repository/eventsourcing/org_member_test.go
Normal file
@ -0,0 +1,397 @@
|
||||
package eventsourcing
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/caos/zitadel/internal/api/auth"
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
usr_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
)
|
||||
|
||||
func TestOrgMemberAddedAggregate(t *testing.T) {
|
||||
type res struct {
|
||||
isErr func(error) bool
|
||||
eventCount int
|
||||
}
|
||||
type args struct {
|
||||
aggCreator *es_models.AggregateCreator
|
||||
member *OrgMember
|
||||
ctx context.Context
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
res res
|
||||
}{
|
||||
{
|
||||
name: "no member",
|
||||
args: args{
|
||||
aggCreator: es_models.NewAggregateCreator("test"),
|
||||
ctx: auth.NewMockContext("org", "user"),
|
||||
member: nil,
|
||||
},
|
||||
res: res{
|
||||
isErr: errors.IsErrorInvalidArgument,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "member added sucessfully",
|
||||
args: args{
|
||||
aggCreator: es_models.NewAggregateCreator("test"),
|
||||
ctx: auth.NewMockContext("org", "user"),
|
||||
member: &OrgMember{
|
||||
ObjectRoot: es_models.ObjectRoot{AggregateID: "asdf", Sequence: 234},
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
isErr: nil,
|
||||
eventCount: 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
aggregate, err := orgMemberAddedAggregate(tt.args.ctx, tt.args.aggCreator, tt.args.member)
|
||||
if tt.res.isErr == nil && err != nil {
|
||||
t.Errorf("no error expected got: %v", err)
|
||||
}
|
||||
if tt.res.isErr != nil && !tt.res.isErr(err) {
|
||||
t.Errorf("wrong error got %T: %v", err, err)
|
||||
}
|
||||
if tt.res.isErr == nil && aggregate == nil {
|
||||
t.Error("aggregate must not be nil")
|
||||
}
|
||||
if tt.res.isErr == nil && len(aggregate.Events) != tt.res.eventCount {
|
||||
t.Error("wrong amount of events")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestOrgMemberChangedAggregate(t *testing.T) {
|
||||
type res struct {
|
||||
isErr func(error) bool
|
||||
eventCount int
|
||||
}
|
||||
type args struct {
|
||||
aggCreator *es_models.AggregateCreator
|
||||
existingMember *OrgMember
|
||||
member *OrgMember
|
||||
ctx context.Context
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
res res
|
||||
}{
|
||||
{
|
||||
name: "no member",
|
||||
args: args{
|
||||
aggCreator: es_models.NewAggregateCreator("test"),
|
||||
ctx: auth.NewMockContext("org", "user"),
|
||||
member: nil,
|
||||
existingMember: &OrgMember{},
|
||||
},
|
||||
res: res{
|
||||
isErr: errors.IsPreconditionFailed,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "no existing member",
|
||||
args: args{
|
||||
aggCreator: es_models.NewAggregateCreator("test"),
|
||||
ctx: auth.NewMockContext("org", "user"),
|
||||
existingMember: nil,
|
||||
member: &OrgMember{},
|
||||
},
|
||||
res: res{
|
||||
isErr: errors.IsPreconditionFailed,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "no changes",
|
||||
args: args{
|
||||
aggCreator: es_models.NewAggregateCreator("test"),
|
||||
ctx: auth.NewMockContext("org", "user"),
|
||||
member: &OrgMember{
|
||||
ObjectRoot: es_models.ObjectRoot{AggregateID: "asdf", Sequence: 234},
|
||||
},
|
||||
existingMember: &OrgMember{
|
||||
ObjectRoot: es_models.ObjectRoot{AggregateID: "asdf", Sequence: 234},
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
isErr: errors.IsErrorInvalidArgument,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with changes success",
|
||||
args: args{
|
||||
aggCreator: es_models.NewAggregateCreator("test"),
|
||||
ctx: auth.NewMockContext("org", "user"),
|
||||
member: &OrgMember{
|
||||
ObjectRoot: es_models.ObjectRoot{AggregateID: "asdf", Sequence: 234},
|
||||
Roles: []string{"asdf"},
|
||||
},
|
||||
existingMember: &OrgMember{
|
||||
ObjectRoot: es_models.ObjectRoot{AggregateID: "asdf", Sequence: 234},
|
||||
Roles: []string{"asdf", "woeri"},
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
isErr: nil,
|
||||
eventCount: 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
aggregateCreator := orgMemberChangedAggregate(tt.args.aggCreator, tt.args.existingMember, tt.args.member)
|
||||
aggregate, err := aggregateCreator(tt.args.ctx)
|
||||
if tt.res.isErr == nil && err != nil {
|
||||
t.Errorf("no error expected got: %v", err)
|
||||
}
|
||||
if tt.res.isErr != nil && !tt.res.isErr(err) {
|
||||
t.Errorf("wrong error got %T: %v", err, err)
|
||||
}
|
||||
if tt.res.isErr == nil && aggregate == nil {
|
||||
t.Error("aggregate must not be nil")
|
||||
}
|
||||
if tt.res.isErr == nil && len(aggregate.Events) != tt.res.eventCount {
|
||||
t.Error("wrong amount of events")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestOrgMemberRemovedAggregate(t *testing.T) {
|
||||
type res struct {
|
||||
isErr func(error) bool
|
||||
eventCount int
|
||||
}
|
||||
type args struct {
|
||||
aggCreator *es_models.AggregateCreator
|
||||
member *OrgMember
|
||||
ctx context.Context
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
res res
|
||||
}{
|
||||
{
|
||||
name: "no member",
|
||||
args: args{
|
||||
aggCreator: es_models.NewAggregateCreator("test"),
|
||||
ctx: auth.NewMockContext("org", "user"),
|
||||
member: nil,
|
||||
},
|
||||
res: res{
|
||||
isErr: errors.IsPreconditionFailed,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "member added sucessfully",
|
||||
args: args{
|
||||
aggCreator: es_models.NewAggregateCreator("test"),
|
||||
ctx: auth.NewMockContext("org", "user"),
|
||||
member: &OrgMember{
|
||||
ObjectRoot: es_models.ObjectRoot{AggregateID: "asdf", Sequence: 234},
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
isErr: nil,
|
||||
eventCount: 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
aggregateCreator := orgMemberRemovedAggregate(tt.args.aggCreator, tt.args.member)
|
||||
aggregate, err := aggregateCreator(tt.args.ctx)
|
||||
if tt.res.isErr == nil && err != nil {
|
||||
t.Errorf("no error expected got: %v", err)
|
||||
}
|
||||
if tt.res.isErr != nil && !tt.res.isErr(err) {
|
||||
t.Errorf("wrong error got %T: %v", err, err)
|
||||
}
|
||||
if tt.res.isErr == nil && aggregate == nil {
|
||||
t.Error("aggregate must not be nil")
|
||||
}
|
||||
if tt.res.isErr == nil && len(aggregate.Events) != tt.res.eventCount {
|
||||
t.Error("wrong amount of events")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_addMemberValidation(t *testing.T) {
|
||||
type res struct {
|
||||
isErr func(error) bool
|
||||
preivousSequence uint64
|
||||
}
|
||||
type args struct {
|
||||
aggregate *es_models.Aggregate
|
||||
events []*es_models.Event
|
||||
member *OrgMember
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
res res
|
||||
}{
|
||||
{
|
||||
name: "no events",
|
||||
args: args{
|
||||
aggregate: &es_models.Aggregate{},
|
||||
},
|
||||
res: res{
|
||||
isErr: errors.IsPreconditionFailed,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "only org events",
|
||||
args: args{
|
||||
aggregate: &es_models.Aggregate{},
|
||||
events: []*es_models.Event{
|
||||
{
|
||||
AggregateType: org_model.OrgAggregate,
|
||||
Sequence: 13,
|
||||
},
|
||||
{
|
||||
AggregateType: org_model.OrgAggregate,
|
||||
Sequence: 142,
|
||||
},
|
||||
{
|
||||
AggregateType: org_model.OrgAggregate,
|
||||
Sequence: 1234,
|
||||
Type: org_model.OrgMemberAdded,
|
||||
Data: []byte(`{"userId":"hodor"}`),
|
||||
},
|
||||
},
|
||||
member: &OrgMember{UserID: "hodor"},
|
||||
},
|
||||
res: res{
|
||||
isErr: errors.IsPreconditionFailed,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "only user events",
|
||||
args: args{
|
||||
aggregate: &es_models.Aggregate{},
|
||||
events: []*es_models.Event{
|
||||
{
|
||||
AggregateType: usr_model.UserAggregate,
|
||||
Sequence: 13,
|
||||
},
|
||||
{
|
||||
AggregateType: usr_model.UserAggregate,
|
||||
Sequence: 142,
|
||||
},
|
||||
},
|
||||
member: &OrgMember{UserID: "hodor"},
|
||||
},
|
||||
res: res{
|
||||
isErr: errors.IsPreconditionFailed,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "user, org events success",
|
||||
args: args{
|
||||
aggregate: &es_models.Aggregate{},
|
||||
events: []*es_models.Event{
|
||||
{
|
||||
AggregateType: usr_model.UserAggregate,
|
||||
Sequence: 13,
|
||||
},
|
||||
{
|
||||
AggregateType: org_model.OrgAggregate,
|
||||
Sequence: 142,
|
||||
},
|
||||
},
|
||||
member: &OrgMember{UserID: "hodor"},
|
||||
},
|
||||
res: res{
|
||||
isErr: nil,
|
||||
preivousSequence: 142,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "user, org and member events success",
|
||||
args: args{
|
||||
aggregate: &es_models.Aggregate{},
|
||||
events: []*es_models.Event{
|
||||
{
|
||||
AggregateType: usr_model.UserAggregate,
|
||||
Sequence: 13,
|
||||
},
|
||||
{
|
||||
AggregateType: org_model.OrgAggregate,
|
||||
Sequence: 142,
|
||||
},
|
||||
{
|
||||
AggregateType: org_model.OrgAggregate,
|
||||
Sequence: 1234,
|
||||
Type: org_model.OrgMemberAdded,
|
||||
Data: []byte(`{"userId":"hodor"}`),
|
||||
},
|
||||
{
|
||||
AggregateType: org_model.OrgAggregate,
|
||||
Sequence: 1236,
|
||||
Type: org_model.OrgMemberRemoved,
|
||||
Data: []byte(`{"userId":"hodor"}`),
|
||||
},
|
||||
},
|
||||
member: &OrgMember{UserID: "hodor"},
|
||||
},
|
||||
res: res{
|
||||
isErr: nil,
|
||||
preivousSequence: 1236,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "user, org and member added events fail",
|
||||
args: args{
|
||||
aggregate: &es_models.Aggregate{},
|
||||
events: []*es_models.Event{
|
||||
{
|
||||
AggregateType: usr_model.UserAggregate,
|
||||
Sequence: 13,
|
||||
},
|
||||
{
|
||||
AggregateType: org_model.OrgAggregate,
|
||||
Sequence: 142,
|
||||
},
|
||||
{
|
||||
AggregateType: org_model.OrgAggregate,
|
||||
Sequence: 1234,
|
||||
Type: org_model.OrgMemberAdded,
|
||||
Data: []byte(`{"userId":"hodor"}`),
|
||||
},
|
||||
},
|
||||
member: &OrgMember{UserID: "hodor"},
|
||||
},
|
||||
res: res{
|
||||
isErr: errors.IsPreconditionFailed,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
validaiton := addMemberValidation(tt.args.aggregate, tt.args.member)
|
||||
err := validaiton(tt.args.events...)
|
||||
if tt.res.isErr == nil && err != nil {
|
||||
t.Errorf("no error expected got: %v", err)
|
||||
}
|
||||
if tt.res.isErr != nil && !tt.res.isErr(err) {
|
||||
t.Errorf("wrong error got %T: %v", err, err)
|
||||
}
|
||||
if tt.res.isErr == nil && tt.args.aggregate.PreviousSequence != tt.res.preivousSequence {
|
||||
t.Errorf("wrong previous sequence got: %d want %d", tt.args.aggregate.PreviousSequence, tt.res.preivousSequence)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
160
internal/org/repository/eventsourcing/org_model.go
Normal file
160
internal/org/repository/eventsourcing/org_model.go
Normal file
@ -0,0 +1,160 @@
|
||||
package eventsourcing
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
)
|
||||
|
||||
const (
|
||||
orgVersion = "v1"
|
||||
)
|
||||
|
||||
type Org struct {
|
||||
es_models.ObjectRoot `json:"-"`
|
||||
|
||||
Name string `json:"name,omitempty"`
|
||||
Domain string `json:"domain,omitempty"`
|
||||
State int32 `json:"-"`
|
||||
|
||||
Members []*OrgMember `json:"-"`
|
||||
}
|
||||
|
||||
func OrgFromModel(org *org_model.Org) *Org {
|
||||
members := OrgMembersFromModel(org.Members)
|
||||
|
||||
return &Org{
|
||||
ObjectRoot: org.ObjectRoot,
|
||||
Domain: org.Domain,
|
||||
Name: org.Name,
|
||||
State: int32(org.State),
|
||||
Members: members,
|
||||
}
|
||||
}
|
||||
|
||||
func OrgToModel(org *Org) *org_model.Org {
|
||||
return &org_model.Org{
|
||||
ObjectRoot: org.ObjectRoot,
|
||||
Domain: org.Domain,
|
||||
Name: org.Name,
|
||||
State: org_model.OrgState(org.State),
|
||||
Members: OrgMembersToModel(org.Members),
|
||||
}
|
||||
}
|
||||
|
||||
func OrgFromEvents(org *Org, events ...*es_models.Event) (*Org, error) {
|
||||
if org == nil {
|
||||
org = new(Org)
|
||||
}
|
||||
|
||||
return org, org.AppendEvents(events...)
|
||||
}
|
||||
|
||||
func (o *Org) AppendEvents(events ...*es_models.Event) error {
|
||||
for _, event := range events {
|
||||
err := o.AppendEvent(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *Org) AppendEvent(event *es_models.Event) error {
|
||||
switch event.Type {
|
||||
case org_model.OrgAdded:
|
||||
*o = Org{}
|
||||
err := o.setData(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case org_model.OrgChanged:
|
||||
err := o.setData(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case org_model.OrgDeactivated:
|
||||
o.State = int32(org_model.ORGSTATE_INACTIVE)
|
||||
case org_model.OrgReactivated:
|
||||
o.State = int32(org_model.ORGSTATE_ACTIVE)
|
||||
case org_model.OrgMemberAdded:
|
||||
member, err := OrgMemberFromEvent(nil, event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
member.CreationDate = event.CreationDate
|
||||
|
||||
o.setMember(member)
|
||||
case org_model.OrgMemberChanged:
|
||||
member, err := OrgMemberFromEvent(nil, event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
existingMember := o.getMember(member.UserID)
|
||||
member.CreationDate = existingMember.CreationDate
|
||||
|
||||
o.setMember(member)
|
||||
case org_model.OrgMemberRemoved:
|
||||
member, err := OrgMemberFromEvent(nil, event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.removeMember(member.UserID)
|
||||
}
|
||||
|
||||
o.ObjectRoot.AppendEvent(event)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *Org) setData(event *es_models.Event) error {
|
||||
err := json.Unmarshal(event.Data, o)
|
||||
if err != nil {
|
||||
return errors.ThrowInternal(err, "EVENT-BpbQZ", "unable to unmarshal event")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *Org) getMember(userID string) *OrgMember {
|
||||
for _, member := range o.Members {
|
||||
if member.UserID == userID {
|
||||
return member
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *Org) setMember(member *OrgMember) {
|
||||
for i, existingMember := range o.Members {
|
||||
if existingMember.UserID == member.UserID {
|
||||
o.Members[i] = member
|
||||
return
|
||||
}
|
||||
}
|
||||
o.Members = append(o.Members, member)
|
||||
}
|
||||
|
||||
func (o *Org) removeMember(userID string) {
|
||||
for i := len(o.Members) - 1; i >= 0; i-- {
|
||||
if o.Members[i].UserID == userID {
|
||||
copy(o.Members[i:], o.Members[i+1:])
|
||||
o.Members[len(o.Members)-1] = nil
|
||||
o.Members = o.Members[:len(o.Members)-1]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Org) Changes(changed *Org) map[string]interface{} {
|
||||
changes := make(map[string]interface{}, 2)
|
||||
|
||||
if changed.Name != "" && changed.Name != o.Name {
|
||||
changes["name"] = changed.Name
|
||||
}
|
||||
if changed.Domain != "" && changed.Domain != o.Domain {
|
||||
changes["domain"] = changed.Domain
|
||||
}
|
||||
|
||||
return changes
|
||||
}
|
170
internal/org/repository/eventsourcing/org_model_test.go
Normal file
170
internal/org/repository/eventsourcing/org_model_test.go
Normal file
@ -0,0 +1,170 @@
|
||||
package eventsourcing
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/org/model"
|
||||
)
|
||||
|
||||
func TestOrgFromEvents(t *testing.T) {
|
||||
type args struct {
|
||||
event []*es_models.Event
|
||||
org *Org
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
result *Org
|
||||
}{
|
||||
{
|
||||
name: "org from events, ok",
|
||||
args: args{
|
||||
event: []*es_models.Event{
|
||||
{AggregateID: "ID", Sequence: 1, Type: model.OrgAdded},
|
||||
},
|
||||
org: &Org{Name: "OrgName"},
|
||||
},
|
||||
result: &Org{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID"}, State: int32(model.ORGSTATE_ACTIVE), Name: "OrgName"},
|
||||
},
|
||||
{
|
||||
name: "org from events, nil org",
|
||||
args: args{
|
||||
event: []*es_models.Event{
|
||||
{AggregateID: "ID", Sequence: 1, Type: model.OrgAdded},
|
||||
},
|
||||
org: nil,
|
||||
},
|
||||
result: &Org{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID"}, State: int32(model.ORGSTATE_ACTIVE)},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.args.org != nil {
|
||||
data, _ := json.Marshal(tt.args.org)
|
||||
tt.args.event[0].Data = data
|
||||
}
|
||||
result, _ := OrgFromEvents(tt.args.org, tt.args.event...)
|
||||
if result.Name != tt.result.Name {
|
||||
t.Errorf("got wrong result name: expected: %v, actual: %v ", tt.result.Name, result.Name)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppendEvent(t *testing.T) {
|
||||
type args struct {
|
||||
event *es_models.Event
|
||||
org *Org
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
result *Org
|
||||
}{
|
||||
{
|
||||
name: "append added event",
|
||||
args: args{
|
||||
event: &es_models.Event{AggregateID: "ID", Sequence: 1, Type: model.OrgAdded},
|
||||
org: &Org{Name: "OrgName"},
|
||||
},
|
||||
result: &Org{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID"}, State: int32(model.ORGSTATE_ACTIVE), Name: "OrgName"},
|
||||
},
|
||||
{
|
||||
name: "append change event",
|
||||
args: args{
|
||||
event: &es_models.Event{AggregateID: "ID", Sequence: 1, Type: model.OrgChanged, Data: []byte(`{"domain": "OrgDomain"}`)},
|
||||
org: &Org{Name: "OrgName", Domain: "asdf"},
|
||||
},
|
||||
result: &Org{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID"}, State: int32(model.ORGSTATE_ACTIVE), Name: "OrgName", Domain: "OrgDomain"},
|
||||
},
|
||||
{
|
||||
name: "append deactivate event",
|
||||
args: args{
|
||||
event: &es_models.Event{AggregateID: "ID", Sequence: 1, Type: model.OrgDeactivated},
|
||||
},
|
||||
result: &Org{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID"}, State: int32(model.ORGSTATE_INACTIVE)},
|
||||
},
|
||||
{
|
||||
name: "append reactivate event",
|
||||
args: args{
|
||||
event: &es_models.Event{AggregateID: "ID", Sequence: 1, Type: model.OrgReactivated},
|
||||
},
|
||||
result: &Org{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID"}, State: int32(model.ORGSTATE_ACTIVE)},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.args.org != nil {
|
||||
data, _ := json.Marshal(tt.args.org)
|
||||
tt.args.event.Data = data
|
||||
}
|
||||
result := &Org{}
|
||||
result.AppendEvent(tt.args.event)
|
||||
if result.State != tt.result.State {
|
||||
t.Errorf("got wrong result state: expected: %v, actual: %v ", tt.result.State, result.State)
|
||||
}
|
||||
if result.Name != tt.result.Name {
|
||||
t.Errorf("got wrong result name: expected: %v, actual: %v ", tt.result.Name, result.Name)
|
||||
}
|
||||
if result.ObjectRoot.AggregateID != tt.result.ObjectRoot.AggregateID {
|
||||
t.Errorf("got wrong result id: expected: %v, actual: %v ", tt.result.ObjectRoot.AggregateID, result.ObjectRoot.AggregateID)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestChanges(t *testing.T) {
|
||||
type args struct {
|
||||
existing *Org
|
||||
new *Org
|
||||
}
|
||||
type res struct {
|
||||
changesLen int
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
res res
|
||||
}{
|
||||
{
|
||||
name: "org name changes",
|
||||
args: args{
|
||||
existing: &Org{Name: "Name"},
|
||||
new: &Org{Name: "NameChanged"},
|
||||
},
|
||||
res: res{
|
||||
changesLen: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "org domain changes",
|
||||
args: args{
|
||||
existing: &Org{Name: "Name", Domain: "old domain"},
|
||||
new: &Org{Name: "Name", Domain: "new domain"},
|
||||
},
|
||||
res: res{
|
||||
changesLen: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "no changes",
|
||||
args: args{
|
||||
existing: &Org{Name: "Name"},
|
||||
new: &Org{Name: "Name"},
|
||||
},
|
||||
res: res{
|
||||
changesLen: 0,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
changes := tt.args.existing.Changes(tt.args.new)
|
||||
if len(changes) != tt.res.changesLen {
|
||||
t.Errorf("got wrong changes len: expected: %v, actual: %v ", tt.res.changesLen, len(changes))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
585
internal/org/repository/eventsourcing/org_test.go
Normal file
585
internal/org/repository/eventsourcing/org_test.go
Normal file
@ -0,0 +1,585 @@
|
||||
package eventsourcing
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/caos/zitadel/internal/api/auth"
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
)
|
||||
|
||||
func Test_isReservedValidation(t *testing.T) {
|
||||
type res struct {
|
||||
isErr func(error) bool
|
||||
agggregateSequence uint64
|
||||
}
|
||||
type args struct {
|
||||
aggregate *es_models.Aggregate
|
||||
eventType es_models.EventType
|
||||
Events []*es_models.Event
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
res res
|
||||
}{
|
||||
{
|
||||
name: "no events success",
|
||||
args: args{
|
||||
aggregate: &es_models.Aggregate{},
|
||||
eventType: "object.reserved",
|
||||
Events: []*es_models.Event{},
|
||||
},
|
||||
res: res{
|
||||
isErr: nil,
|
||||
agggregateSequence: 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "not reseved success",
|
||||
args: args{
|
||||
aggregate: &es_models.Aggregate{},
|
||||
eventType: "object.reserved",
|
||||
Events: []*es_models.Event{
|
||||
{
|
||||
AggregateID: "asdf",
|
||||
AggregateType: "org",
|
||||
Sequence: 45,
|
||||
Type: "object.released",
|
||||
},
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
isErr: nil,
|
||||
agggregateSequence: 45,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "reseved error",
|
||||
args: args{
|
||||
aggregate: &es_models.Aggregate{},
|
||||
eventType: "object.reserved",
|
||||
Events: []*es_models.Event{
|
||||
{
|
||||
AggregateID: "asdf",
|
||||
AggregateType: "org",
|
||||
Sequence: 45,
|
||||
Type: "object.reserved",
|
||||
},
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
isErr: errors.IsPreconditionFailed,
|
||||
agggregateSequence: 0,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
validate := isReservedValidation(tt.args.aggregate, tt.args.eventType)
|
||||
|
||||
err := validate(tt.args.Events...)
|
||||
|
||||
if tt.res.isErr == nil && err != nil {
|
||||
t.Errorf("no error expected got: %v", err)
|
||||
}
|
||||
if tt.res.isErr != nil && !tt.res.isErr(err) {
|
||||
t.Errorf("wrong error got: %v", err)
|
||||
}
|
||||
if err == nil && tt.args.aggregate.PreviousSequence != tt.res.agggregateSequence {
|
||||
t.Errorf("expected sequence %d got %d", tt.res.agggregateSequence, tt.args.aggregate.PreviousSequence)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func aggregateWithPrecondition() *es_models.Aggregate {
|
||||
return nil
|
||||
}
|
||||
|
||||
func Test_uniqueNameAggregate(t *testing.T) {
|
||||
type res struct {
|
||||
expected *es_models.Aggregate
|
||||
isErr func(error) bool
|
||||
}
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
aggCreator *es_models.AggregateCreator
|
||||
orgName string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
res res
|
||||
}{
|
||||
{
|
||||
name: "no org name error",
|
||||
args: args{
|
||||
ctx: auth.NewMockContext("orgID", "userID"),
|
||||
aggCreator: es_models.NewAggregateCreator("test"),
|
||||
orgName: "",
|
||||
},
|
||||
res: res{
|
||||
expected: nil,
|
||||
isErr: errors.IsPreconditionFailed,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "aggregate created",
|
||||
args: args{
|
||||
ctx: auth.NewMockContext("orgID", "userID"),
|
||||
aggCreator: es_models.NewAggregateCreator("test"),
|
||||
orgName: "asdf",
|
||||
},
|
||||
res: res{
|
||||
expected: aggregateWithPrecondition(),
|
||||
isErr: nil,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := uniqueNameAggregate(tt.args.ctx, tt.args.aggCreator, tt.args.orgName)
|
||||
if tt.res.isErr == nil && err != nil {
|
||||
t.Errorf("no error expected got: %v", err)
|
||||
}
|
||||
if tt.res.isErr != nil && !tt.res.isErr(err) {
|
||||
t.Errorf("wrong error got %T: %v", err, err)
|
||||
}
|
||||
if tt.res.isErr == nil && (got.Precondition == nil || got.Precondition.Query == nil || got.Precondition.Validation == nil) {
|
||||
t.Errorf("precondition is not set correctly")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_uniqueDomainAggregate(t *testing.T) {
|
||||
type res struct {
|
||||
expected *es_models.Aggregate
|
||||
isErr func(error) bool
|
||||
}
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
aggCreator *es_models.AggregateCreator
|
||||
orgDomain string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
res res
|
||||
}{
|
||||
{
|
||||
name: "no org domain error",
|
||||
args: args{
|
||||
ctx: auth.NewMockContext("orgID", "userID"),
|
||||
aggCreator: es_models.NewAggregateCreator("test"),
|
||||
orgDomain: "",
|
||||
},
|
||||
res: res{
|
||||
expected: nil,
|
||||
isErr: errors.IsPreconditionFailed,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "aggregate created",
|
||||
args: args{
|
||||
ctx: auth.NewMockContext("orgID", "userID"),
|
||||
aggCreator: es_models.NewAggregateCreator("test"),
|
||||
orgDomain: "asdf",
|
||||
},
|
||||
res: res{
|
||||
expected: aggregateWithPrecondition(),
|
||||
isErr: nil,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := uniqueDomainAggregate(tt.args.ctx, tt.args.aggCreator, tt.args.orgDomain)
|
||||
if tt.res.isErr == nil && err != nil {
|
||||
t.Errorf("no error expected got: %v", err)
|
||||
}
|
||||
if tt.res.isErr != nil && !tt.res.isErr(err) {
|
||||
t.Errorf("wrong error got %T: %v", err, err)
|
||||
}
|
||||
if tt.res.isErr == nil && (got.Precondition == nil || got.Precondition.Query == nil || got.Precondition.Validation == nil) {
|
||||
t.Errorf("precondition is not set correctly")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestOrgReactivateAggregate(t *testing.T) {
|
||||
type res struct {
|
||||
isErr func(error) bool
|
||||
}
|
||||
type args struct {
|
||||
aggCreator *es_models.AggregateCreator
|
||||
org *Org
|
||||
ctx context.Context
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
res res
|
||||
}{
|
||||
{
|
||||
name: "correct",
|
||||
args: args{
|
||||
aggCreator: es_models.NewAggregateCreator("test"),
|
||||
ctx: auth.NewMockContext("org", "user"),
|
||||
org: &Org{
|
||||
ObjectRoot: es_models.ObjectRoot{
|
||||
AggregateID: "orgID",
|
||||
Sequence: 2,
|
||||
},
|
||||
State: int32(org_model.ORGSTATE_INACTIVE),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "already active error",
|
||||
args: args{
|
||||
aggCreator: es_models.NewAggregateCreator("test"),
|
||||
ctx: auth.NewMockContext("org", "user"),
|
||||
org: &Org{
|
||||
ObjectRoot: es_models.ObjectRoot{
|
||||
AggregateID: "orgID",
|
||||
Sequence: 2,
|
||||
},
|
||||
State: int32(org_model.ORGSTATE_ACTIVE),
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
isErr: errors.IsErrorInvalidArgument,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "org nil error",
|
||||
args: args{
|
||||
aggCreator: es_models.NewAggregateCreator("test"),
|
||||
ctx: auth.NewMockContext("org", "user"),
|
||||
org: nil,
|
||||
},
|
||||
res: res{
|
||||
isErr: errors.IsPreconditionFailed,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
aggregateCreator := orgReactivateAggregate(tt.args.aggCreator, tt.args.org)
|
||||
aggregate, err := aggregateCreator(tt.args.ctx)
|
||||
if tt.res.isErr == nil && err != nil {
|
||||
t.Errorf("no error expected got: %v", err)
|
||||
}
|
||||
if tt.res.isErr != nil && !tt.res.isErr(err) {
|
||||
t.Errorf("wrong error got %T: %v", err, err)
|
||||
}
|
||||
if tt.res.isErr == nil && aggregate == nil {
|
||||
t.Error("aggregate must not be nil")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestOrgDeactivateAggregate(t *testing.T) {
|
||||
type res struct {
|
||||
isErr func(error) bool
|
||||
}
|
||||
type args struct {
|
||||
aggCreator *es_models.AggregateCreator
|
||||
org *Org
|
||||
ctx context.Context
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
res res
|
||||
}{
|
||||
{
|
||||
name: "correct",
|
||||
args: args{
|
||||
aggCreator: es_models.NewAggregateCreator("test"),
|
||||
ctx: auth.NewMockContext("org", "user"),
|
||||
org: &Org{
|
||||
ObjectRoot: es_models.ObjectRoot{
|
||||
AggregateID: "orgID",
|
||||
Sequence: 2,
|
||||
},
|
||||
State: int32(org_model.ORGSTATE_ACTIVE),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "already inactive error",
|
||||
args: args{
|
||||
aggCreator: es_models.NewAggregateCreator("test"),
|
||||
ctx: auth.NewMockContext("org", "user"),
|
||||
org: &Org{
|
||||
ObjectRoot: es_models.ObjectRoot{
|
||||
AggregateID: "orgID",
|
||||
Sequence: 2,
|
||||
},
|
||||
State: int32(org_model.ORGSTATE_INACTIVE),
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
isErr: errors.IsErrorInvalidArgument,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "org nil error",
|
||||
args: args{
|
||||
aggCreator: es_models.NewAggregateCreator("test"),
|
||||
ctx: auth.NewMockContext("org", "user"),
|
||||
org: nil,
|
||||
},
|
||||
res: res{
|
||||
isErr: errors.IsPreconditionFailed,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
aggregateCreator := orgDeactivateAggregate(tt.args.aggCreator, tt.args.org)
|
||||
aggregate, err := aggregateCreator(tt.args.ctx)
|
||||
if tt.res.isErr == nil && err != nil {
|
||||
t.Errorf("no error expected got: %v", err)
|
||||
}
|
||||
if tt.res.isErr != nil && !tt.res.isErr(err) {
|
||||
t.Errorf("wrong error got %T: %v", err, err)
|
||||
}
|
||||
if tt.res.isErr == nil && aggregate == nil {
|
||||
t.Error("aggregate must not be nil")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestOrgUpdateAggregates(t *testing.T) {
|
||||
type res struct {
|
||||
aggregateCount int
|
||||
isErr func(error) bool
|
||||
}
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
aggCreator *es_models.AggregateCreator
|
||||
existing *Org
|
||||
updated *Org
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
res res
|
||||
}{
|
||||
{
|
||||
name: "no existing org error",
|
||||
args: args{
|
||||
ctx: auth.NewMockContext("org", "user"),
|
||||
aggCreator: es_models.NewAggregateCreator("test"),
|
||||
existing: nil,
|
||||
updated: &Org{},
|
||||
},
|
||||
res: res{
|
||||
aggregateCount: 0,
|
||||
isErr: errors.IsPreconditionFailed,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "no updated org error",
|
||||
args: args{
|
||||
ctx: auth.NewMockContext("org", "user"),
|
||||
aggCreator: es_models.NewAggregateCreator("test"),
|
||||
existing: &Org{},
|
||||
updated: nil,
|
||||
},
|
||||
res: res{
|
||||
aggregateCount: 0,
|
||||
isErr: errors.IsPreconditionFailed,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "no changes",
|
||||
args: args{
|
||||
ctx: auth.NewMockContext("org", "user"),
|
||||
aggCreator: es_models.NewAggregateCreator("test"),
|
||||
existing: &Org{},
|
||||
updated: &Org{},
|
||||
},
|
||||
res: res{
|
||||
aggregateCount: 0,
|
||||
isErr: errors.IsPreconditionFailed,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "name changed",
|
||||
args: args{
|
||||
ctx: auth.NewMockContext("org", "user"),
|
||||
aggCreator: es_models.NewAggregateCreator("test"),
|
||||
existing: &Org{
|
||||
ObjectRoot: es_models.ObjectRoot{
|
||||
AggregateID: "sdaf",
|
||||
Sequence: 5,
|
||||
},
|
||||
Domain: "caos.ch",
|
||||
Name: "coas",
|
||||
},
|
||||
updated: &Org{
|
||||
ObjectRoot: es_models.ObjectRoot{
|
||||
AggregateID: "sdaf",
|
||||
Sequence: 5,
|
||||
},
|
||||
Domain: "caos.ch",
|
||||
Name: "caos",
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
aggregateCount: 2,
|
||||
isErr: nil,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "domain changed",
|
||||
args: args{
|
||||
ctx: auth.NewMockContext("org", "user"),
|
||||
aggCreator: es_models.NewAggregateCreator("test"),
|
||||
existing: &Org{
|
||||
ObjectRoot: es_models.ObjectRoot{
|
||||
AggregateID: "sdaf",
|
||||
Sequence: 5,
|
||||
},
|
||||
Domain: "caos.swiss",
|
||||
Name: "caos",
|
||||
},
|
||||
updated: &Org{
|
||||
ObjectRoot: es_models.ObjectRoot{
|
||||
AggregateID: "sdaf",
|
||||
Sequence: 5,
|
||||
},
|
||||
Domain: "caos.ch",
|
||||
Name: "caos",
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
aggregateCount: 2,
|
||||
isErr: nil,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := OrgUpdateAggregates(tt.args.ctx, tt.args.aggCreator, tt.args.existing, tt.args.updated)
|
||||
if tt.res.isErr == nil && err != nil {
|
||||
t.Errorf("no error expected got: %v", err)
|
||||
}
|
||||
if tt.res.isErr != nil && !tt.res.isErr(err) {
|
||||
t.Errorf("wrong error got %T: %v", err, err)
|
||||
}
|
||||
if tt.res.isErr == nil && len(got) != tt.res.aggregateCount {
|
||||
t.Errorf("OrgUpdateAggregates() aggregate count = %d, wanted count %d", len(got), tt.res.aggregateCount)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestOrgCreatedAggregates(t *testing.T) {
|
||||
type res struct {
|
||||
aggregateCount int
|
||||
isErr func(error) bool
|
||||
}
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
aggCreator *es_models.AggregateCreator
|
||||
org *Org
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
res res
|
||||
}{
|
||||
{
|
||||
name: "no org error",
|
||||
args: args{
|
||||
ctx: auth.NewMockContext("org", "user"),
|
||||
aggCreator: es_models.NewAggregateCreator("test"),
|
||||
org: nil,
|
||||
},
|
||||
res: res{
|
||||
aggregateCount: 0,
|
||||
isErr: errors.IsPreconditionFailed,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "org successful",
|
||||
args: args{
|
||||
ctx: auth.NewMockContext("org", "user"),
|
||||
aggCreator: es_models.NewAggregateCreator("test"),
|
||||
org: &Org{
|
||||
ObjectRoot: es_models.ObjectRoot{
|
||||
AggregateID: "sdaf",
|
||||
Sequence: 5,
|
||||
},
|
||||
Domain: "caos.ch",
|
||||
Name: "caos",
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
aggregateCount: 3,
|
||||
isErr: nil,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "no domain error",
|
||||
args: args{
|
||||
ctx: auth.NewMockContext("org", "user"),
|
||||
aggCreator: es_models.NewAggregateCreator("test"),
|
||||
org: &Org{
|
||||
ObjectRoot: es_models.ObjectRoot{
|
||||
AggregateID: "sdaf",
|
||||
Sequence: 5,
|
||||
},
|
||||
Name: "caos",
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
aggregateCount: 2,
|
||||
isErr: errors.IsPreconditionFailed,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "no name error",
|
||||
args: args{
|
||||
ctx: auth.NewMockContext("org", "user"),
|
||||
aggCreator: es_models.NewAggregateCreator("test"),
|
||||
org: &Org{
|
||||
ObjectRoot: es_models.ObjectRoot{
|
||||
AggregateID: "sdaf",
|
||||
Sequence: 5,
|
||||
},
|
||||
Domain: "caos.ch",
|
||||
},
|
||||
},
|
||||
res: res{
|
||||
aggregateCount: 2,
|
||||
isErr: errors.IsPreconditionFailed,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := orgCreatedAggregates(tt.args.ctx, tt.args.aggCreator, tt.args.org)
|
||||
if tt.res.isErr == nil && err != nil {
|
||||
t.Errorf("no error expected got %T: %v", err, err)
|
||||
}
|
||||
if tt.res.isErr != nil && !tt.res.isErr(err) {
|
||||
t.Errorf("wrong error got %T: %v", err, err)
|
||||
}
|
||||
if tt.res.isErr == nil && len(got) != tt.res.aggregateCount {
|
||||
t.Errorf("OrgUpdateAggregates() aggregate count = %d, wanted count %d", len(got), tt.res.aggregateCount)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
10
internal/org/repository/model.go
Normal file
10
internal/org/repository/model.go
Normal file
@ -0,0 +1,10 @@
|
||||
package repository
|
||||
|
||||
import es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
|
||||
type Org struct {
|
||||
es_models.ObjectRoot
|
||||
|
||||
Name string
|
||||
Domain string
|
||||
}
|
@ -1,9 +1,10 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
"time"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
@ -92,26 +93,26 @@ func (u *User) HashPasswordIfExisting(passwordAlg crypto.HashAlgorithm, onetime
|
||||
}
|
||||
|
||||
func (u *User) GenerateInitCodeIfNeeded(initGenerator crypto.Generator) error {
|
||||
u.InitCode = new(InitUserCode)
|
||||
if !u.IsInitialState() {
|
||||
return nil
|
||||
}
|
||||
u.InitCode = new(InitUserCode)
|
||||
return u.InitCode.GenerateInitUserCode(initGenerator)
|
||||
}
|
||||
|
||||
func (u *User) GeneratePhoneCodeIfNeeded(phoneGenerator crypto.Generator) error {
|
||||
u.PhoneCode = new(PhoneCode)
|
||||
if u.Phone == nil || u.IsPhoneVerified {
|
||||
return nil
|
||||
}
|
||||
u.PhoneCode = new(PhoneCode)
|
||||
return u.PhoneCode.GeneratePhoneCode(phoneGenerator)
|
||||
}
|
||||
|
||||
func (u *User) GenerateEmailCodeIfNeeded(emailGenerator crypto.Generator) error {
|
||||
u.EmailCode = new(EmailCode)
|
||||
if u.Email == nil || u.IsEmailVerified {
|
||||
return nil
|
||||
}
|
||||
u.EmailCode = new(EmailCode)
|
||||
return u.EmailCode.GenerateEmailCode(emailGenerator)
|
||||
}
|
||||
|
||||
|
@ -2,18 +2,20 @@ package eventsourcing
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
|
||||
"github.com/caos/zitadel/internal/cache/config"
|
||||
sd "github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
es_int "github.com/caos/zitadel/internal/eventstore"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
es_sdk "github.com/caos/zitadel/internal/eventstore/sdk"
|
||||
global_model "github.com/caos/zitadel/internal/model"
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
"github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
"github.com/pquerna/otp/totp"
|
||||
"github.com/sony/sonyflake"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type UserEventstore struct {
|
||||
@ -49,6 +51,7 @@ func StartUser(conf UserConfig, systemDefaults sd.SystemDefaults) (*UserEventsto
|
||||
phoneVerificationCode := crypto.NewEncryptionGenerator(systemDefaults.SecretGenerators.PhoneVerificationCode, aesCrypto)
|
||||
passwordVerificationCode := crypto.NewEncryptionGenerator(systemDefaults.SecretGenerators.PasswordVerificationCode, aesCrypto)
|
||||
aesOtpCrypto, err := crypto.NewAESCrypto(systemDefaults.Multifactors.OTP.VerificationKey)
|
||||
passwordAlg := crypto.NewBCrypt(systemDefaults.SecretGenerators.PasswordSaltCost)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -67,6 +70,7 @@ func StartUser(conf UserConfig, systemDefaults sd.SystemDefaults) (*UserEventsto
|
||||
PhoneVerificationCode: phoneVerificationCode,
|
||||
PasswordVerificationCode: passwordVerificationCode,
|
||||
Multifactors: mfa,
|
||||
PasswordAlg: passwordAlg,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -85,37 +89,47 @@ func (es *UserEventstore) UserByID(ctx context.Context, id string) (*usr_model.U
|
||||
return model.UserToModel(user), nil
|
||||
}
|
||||
|
||||
func (es *UserEventstore) CreateUser(ctx context.Context, user *usr_model.User) (*usr_model.User, error) {
|
||||
func (es *UserEventstore) PrepareCreateUser(ctx context.Context, user *usr_model.User, resourceOwner string) (*model.User, *es_models.Aggregate, error) {
|
||||
user.SetEmailAsUsername()
|
||||
if !user.IsValid() {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9dk45", "Name is required")
|
||||
return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9dk45", "Name is required")
|
||||
}
|
||||
//TODO: Check Uniqueness
|
||||
id, err := es.idGenerator.NextID()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
user.AggregateID = strconv.FormatUint(id, 10)
|
||||
|
||||
err = user.HashPasswordIfExisting(es.PasswordAlg, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
err = user.GenerateInitCodeIfNeeded(es.InitializeUserCode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
err = user.GeneratePhoneCodeIfNeeded(es.PhoneVerificationCode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
repoUser := model.UserFromModel(user)
|
||||
repoInitCode := model.InitCodeFromModel(user.InitCode)
|
||||
repoPhoneCode := model.PhoneCodeFromModel(user.PhoneCode)
|
||||
|
||||
createAggregate := UserCreateAggregate(es.AggregateCreator(), repoUser, repoInitCode, repoPhoneCode)
|
||||
err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, createAggregate)
|
||||
createAggregate, err := UserCreateAggregate(ctx, es.AggregateCreator(), repoUser, repoInitCode, repoPhoneCode, resourceOwner)
|
||||
|
||||
return repoUser, createAggregate, err
|
||||
}
|
||||
|
||||
func (es *UserEventstore) CreateUser(ctx context.Context, user *usr_model.User) (*usr_model.User, error) {
|
||||
repoUser, aggregate, err := es.PrepareCreateUser(ctx, user, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = es_sdk.PushAggregates(ctx, es.PushAggregates, repoUser.AppendEvents, aggregate)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -124,32 +138,41 @@ func (es *UserEventstore) CreateUser(ctx context.Context, user *usr_model.User)
|
||||
return model.UserToModel(repoUser), nil
|
||||
}
|
||||
|
||||
func (es *UserEventstore) RegisterUser(ctx context.Context, user *usr_model.User, resourceOwner string) (*usr_model.User, error) {
|
||||
func (es *UserEventstore) PrepareRegisterUser(ctx context.Context, user *usr_model.User, resourceOwner string) (*model.User, *es_models.Aggregate, error) {
|
||||
user.SetEmailAsUsername()
|
||||
if !user.IsValid() || user.Password == nil || user.SecretString == "" {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9dk45", "user is invalid")
|
||||
return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9dk45", "user is invalid")
|
||||
}
|
||||
//TODO: Check Uniqueness
|
||||
id, err := es.idGenerator.NextID()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
user.AggregateID = strconv.FormatUint(id, 10)
|
||||
|
||||
err = user.HashPasswordIfExisting(es.PasswordAlg, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
err = user.GenerateEmailCodeIfNeeded(es.EmailVerificationCode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
repoUser := model.UserFromModel(user)
|
||||
repoEmailCode := model.EmailCodeFromModel(user.EmailCode)
|
||||
|
||||
createAggregate := UserRegisterAggregate(es.AggregateCreator(), repoUser, resourceOwner, repoEmailCode)
|
||||
err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, createAggregate)
|
||||
aggregate, err := UserRegisterAggregate(ctx, es.AggregateCreator(), repoUser, resourceOwner, repoEmailCode)
|
||||
return repoUser, aggregate, err
|
||||
}
|
||||
|
||||
func (es *UserEventstore) RegisterUser(ctx context.Context, user *usr_model.User, resourceOwner string) (*usr_model.User, error) {
|
||||
repoUser, createAggregate, err := es.PrepareRegisterUser(ctx, user, resourceOwner)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = es_sdk.PushAggregates(ctx, es.PushAggregates, repoUser.AppendEvents, createAggregate)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -2,12 +2,13 @@ package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/user/model"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -22,11 +23,11 @@ type User struct {
|
||||
*Email
|
||||
*Phone
|
||||
*Address
|
||||
InitCode *InitUserCode
|
||||
EmailCode *EmailCode
|
||||
PhoneCode *PhoneCode
|
||||
PasswordCode *PasswordCode
|
||||
OTP *OTP
|
||||
InitCode *InitUserCode `json:"-"`
|
||||
EmailCode *EmailCode `json:"-"`
|
||||
PhoneCode *PhoneCode `json:"-"`
|
||||
PasswordCode *PasswordCode `json:"-"`
|
||||
OTP *OTP `json:"-"`
|
||||
}
|
||||
|
||||
type InitUserCode struct {
|
||||
|
@ -2,6 +2,7 @@ package eventsourcing
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
@ -36,72 +37,72 @@ func UserAggregateOverwriteContext(ctx context.Context, aggCreator *es_models.Ag
|
||||
return aggCreator.NewAggregate(ctx, user.AggregateID, model.UserAggregate, model.UserVersion, user.Sequence, es_models.OverwriteResourceOwner(resourceOwnerID), es_models.OverwriteEditorUser(userID))
|
||||
}
|
||||
|
||||
func UserCreateAggregate(aggCreator *es_models.AggregateCreator, user *model.User, initCode *model.InitUserCode, phoneCode *model.PhoneCode) func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||
return func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||
if user == nil {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-duxk2", "user should not be nil")
|
||||
}
|
||||
|
||||
agg, err := UserAggregate(ctx, aggCreator, user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
agg, err = agg.AppendEvent(model.UserAdded, user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if user.Email != nil && user.EmailAddress != "" && user.IsEmailVerified {
|
||||
agg, err = agg.AppendEvent(model.UserEmailVerified, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if user.Phone != nil && user.PhoneNumber != "" && user.IsPhoneVerified {
|
||||
agg, err = agg.AppendEvent(model.UserPhoneVerified, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if user.Password != nil {
|
||||
agg, err = agg.AppendEvent(model.UserPasswordCodeAdded, user.Password)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if initCode != nil {
|
||||
agg, err = agg.AppendEvent(model.InitializedUserCodeAdded, initCode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if phoneCode != nil {
|
||||
agg, err = agg.AppendEvent(model.UserPhoneCodeAdded, phoneCode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return agg, err
|
||||
func UserCreateAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, user *model.User, initCode *model.InitUserCode, phoneCode *model.PhoneCode, resourceOwner string) (agg *es_models.Aggregate, err error) {
|
||||
if user == nil {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-duxk2", "user should not be nil")
|
||||
}
|
||||
|
||||
if resourceOwner != "" {
|
||||
agg, err = UserAggregateOverwriteContext(ctx, aggCreator, user, user.AggregateID, resourceOwner)
|
||||
} else {
|
||||
agg, err = UserAggregate(ctx, aggCreator, user)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
agg, err = agg.AppendEvent(model.UserAdded, user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if user.Email != nil && user.EmailAddress != "" && user.IsEmailVerified {
|
||||
agg, err = agg.AppendEvent(model.UserEmailVerified, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if user.Phone != nil && user.PhoneNumber != "" && user.IsPhoneVerified {
|
||||
agg, err = agg.AppendEvent(model.UserPhoneVerified, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if user.Password != nil {
|
||||
agg, err = agg.AppendEvent(model.UserPasswordCodeAdded, user.Password)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if initCode != nil {
|
||||
agg, err = agg.AppendEvent(model.InitializedUserCodeAdded, initCode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if phoneCode != nil {
|
||||
agg, err = agg.AppendEvent(model.UserPhoneCodeAdded, phoneCode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return agg, err
|
||||
}
|
||||
|
||||
func UserRegisterAggregate(aggCreator *es_models.AggregateCreator, user *model.User, resourceOwner string, emailCode *model.EmailCode) func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||
return func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||
if user == nil || resourceOwner == "" || emailCode == nil {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-duxk2", "user, resourceowner, emailcode should not be nothing")
|
||||
}
|
||||
|
||||
agg, err := UserAggregateOverwriteContext(ctx, aggCreator, user, resourceOwner, user.AggregateID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
agg, err = agg.AppendEvent(model.UserRegistered, user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return agg.AppendEvent(model.UserEmailCodeAdded, emailCode)
|
||||
func UserRegisterAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, user *model.User, resourceOwner string, emailCode *model.EmailCode) (*es_models.Aggregate, error) {
|
||||
if user == nil || resourceOwner == "" || emailCode == nil {
|
||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-duxk2", "user, resourceowner, emailcode should not be nothing")
|
||||
}
|
||||
|
||||
agg, err := UserAggregateOverwriteContext(ctx, aggCreator, user, resourceOwner, user.AggregateID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
agg, err = agg.AppendEvent(model.UserRegistered, user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return agg.AppendEvent(model.UserEmailCodeAdded, emailCode)
|
||||
}
|
||||
|
||||
func UserDeactivateAggregate(aggCreator *es_models.AggregateCreator, user *model.User) func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||
|
@ -2,12 +2,13 @@ package eventsourcing
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/caos/zitadel/internal/api/auth"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestUserByIDQuery(t *testing.T) {
|
||||
@ -212,7 +213,7 @@ func TestUserCreateAggregate(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
agg, err := UserCreateAggregate(tt.args.aggCreator, tt.args.new, tt.args.initCode, tt.args.phoneCode)(tt.args.ctx)
|
||||
agg, err := UserCreateAggregate(tt.args.ctx, tt.args.aggCreator, tt.args.new, tt.args.initCode, tt.args.phoneCode, "")
|
||||
|
||||
if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen {
|
||||
t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events))
|
||||
@ -329,7 +330,7 @@ func TestUserRegisterAggregate(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
agg, err := UserRegisterAggregate(tt.args.aggCreator, tt.args.new, tt.args.resourceOwner, tt.args.emailCode)(tt.args.ctx)
|
||||
agg, err := UserRegisterAggregate(tt.args.ctx, tt.args.aggCreator, tt.args.new, tt.args.resourceOwner, tt.args.emailCode)
|
||||
|
||||
if tt.res.errFunc == nil && len(agg.Events) != tt.res.eventLen {
|
||||
t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events))
|
||||
|
8
migrations/cockroach/V1.4__admin_user_grants.sql
Normal file
8
migrations/cockroach/V1.4__admin_user_grants.sql
Normal file
@ -0,0 +1,8 @@
|
||||
BEGIN;
|
||||
|
||||
CREATE USER admin_api;
|
||||
|
||||
GRANT SELECT, INSERT, UPDATE ON DATABASE eventstore TO admin_api;
|
||||
GRANT SELECT, INSERT, UPDATE ON TABLE eventstore.* TO admin_api;
|
||||
|
||||
COMMIT;
|
@ -2,16 +2,22 @@ package admin
|
||||
|
||||
import (
|
||||
"context"
|
||||
app "github.com/caos/zitadel/internal/admin"
|
||||
sd "github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"github.com/caos/zitadel/internal/admin/repository/eventsourcing"
|
||||
"github.com/caos/zitadel/internal/api/auth"
|
||||
"github.com/caos/zitadel/pkg/admin/api"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
App app.Config
|
||||
API api.Config
|
||||
Repository eventsourcing.Config
|
||||
API api.Config
|
||||
}
|
||||
|
||||
func Start(ctx context.Context, config Config, authZ auth.Config) {
|
||||
api.Start(ctx, config.API)
|
||||
func Start(ctx context.Context, config Config, authZ auth.Config, systemDefaults sd.SystemDefaults) {
|
||||
repo, err := eventsourcing.Start(config.Repository, systemDefaults)
|
||||
logging.Log("MAIN-9uBxp").OnError(err).Panic("unable to start app")
|
||||
|
||||
api.Start(ctx, config.API, authZ, repo)
|
||||
}
|
||||
|
@ -2,6 +2,9 @@ package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/admin/repository"
|
||||
"github.com/caos/zitadel/internal/api/auth"
|
||||
grpc_util "github.com/caos/zitadel/internal/api/grpc"
|
||||
"github.com/caos/zitadel/internal/api/grpc/server"
|
||||
"github.com/caos/zitadel/pkg/admin/api/grpc"
|
||||
@ -11,8 +14,8 @@ type Config struct {
|
||||
GRPC grpc_util.Config
|
||||
}
|
||||
|
||||
func Start(ctx context.Context, conf Config) {
|
||||
grpcServer := grpc.StartServer(conf.GRPC.ToServerConfig())
|
||||
func Start(ctx context.Context, conf Config, authZ auth.Config, repo repository.Repository) {
|
||||
grpcServer := grpc.StartServer(conf.GRPC.ToServerConfig(), authZ, repo)
|
||||
grpcGateway := grpc.StartGateway(conf.GRPC.ToGatewayConfig())
|
||||
|
||||
server.StartServer(ctx, grpcServer)
|
||||
|
@ -583,11 +583,11 @@ func (m *OrgSearchResponse) GetResult() []*Org {
|
||||
}
|
||||
|
||||
type OrgSetUpRequest struct {
|
||||
Org *CreateOrgRequest `protobuf:"bytes,1,opt,name=org,proto3" json:"org,omitempty"`
|
||||
User *RegisterUserRequest `protobuf:"bytes,2,opt,name=user,proto3" json:"user,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
Org *CreateOrgRequest `protobuf:"bytes,1,opt,name=org,proto3" json:"org,omitempty"`
|
||||
User *CreateUserRequest `protobuf:"bytes,2,opt,name=user,proto3" json:"user,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *OrgSetUpRequest) Reset() { *m = OrgSetUpRequest{} }
|
||||
@ -622,7 +622,7 @@ func (m *OrgSetUpRequest) GetOrg() *CreateOrgRequest {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *OrgSetUpRequest) GetUser() *RegisterUserRequest {
|
||||
func (m *OrgSetUpRequest) GetUser() *CreateUserRequest {
|
||||
if m != nil {
|
||||
return m.User
|
||||
}
|
||||
@ -676,105 +676,169 @@ func (m *OrgSetUpResponse) GetUser() *User {
|
||||
return nil
|
||||
}
|
||||
|
||||
type RegisterUserRequest struct {
|
||||
Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"`
|
||||
type CreateUserRequest struct {
|
||||
UserName string `protobuf:"bytes,1,opt,name=user_name,json=userName,proto3" json:"user_name,omitempty"`
|
||||
FirstName string `protobuf:"bytes,2,opt,name=first_name,json=firstName,proto3" json:"first_name,omitempty"`
|
||||
LastName string `protobuf:"bytes,3,opt,name=last_name,json=lastName,proto3" json:"last_name,omitempty"`
|
||||
NickName string `protobuf:"bytes,4,opt,name=nick_name,json=nickName,proto3" json:"nick_name,omitempty"`
|
||||
DisplayName string `protobuf:"bytes,5,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"`
|
||||
PreferredLanguage string `protobuf:"bytes,6,opt,name=preferred_language,json=preferredLanguage,proto3" json:"preferred_language,omitempty"`
|
||||
Gender Gender `protobuf:"varint,7,opt,name=gender,proto3,enum=zitadel.admin.api.v1.Gender" json:"gender,omitempty"`
|
||||
Password string `protobuf:"bytes,8,opt,name=password,proto3" json:"password,omitempty"`
|
||||
OrgId string `protobuf:"bytes,9,opt,name=org_id,json=orgId,proto3" json:"org_id,omitempty"`
|
||||
Email string `protobuf:"bytes,8,opt,name=email,proto3" json:"email,omitempty"`
|
||||
IsEmailVerified bool `protobuf:"varint,9,opt,name=is_email_verified,json=isEmailVerified,proto3" json:"is_email_verified,omitempty"`
|
||||
Phone string `protobuf:"bytes,11,opt,name=phone,proto3" json:"phone,omitempty"`
|
||||
IsPhoneVerified bool `protobuf:"varint,12,opt,name=is_phone_verified,json=isPhoneVerified,proto3" json:"is_phone_verified,omitempty"`
|
||||
Country string `protobuf:"bytes,13,opt,name=country,proto3" json:"country,omitempty"`
|
||||
Locality string `protobuf:"bytes,14,opt,name=locality,proto3" json:"locality,omitempty"`
|
||||
PostalCode string `protobuf:"bytes,15,opt,name=postal_code,json=postalCode,proto3" json:"postal_code,omitempty"`
|
||||
Region string `protobuf:"bytes,16,opt,name=region,proto3" json:"region,omitempty"`
|
||||
StreetAddress string `protobuf:"bytes,17,opt,name=street_address,json=streetAddress,proto3" json:"street_address,omitempty"`
|
||||
Password string `protobuf:"bytes,18,opt,name=password,proto3" json:"password,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *RegisterUserRequest) Reset() { *m = RegisterUserRequest{} }
|
||||
func (m *RegisterUserRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*RegisterUserRequest) ProtoMessage() {}
|
||||
func (*RegisterUserRequest) Descriptor() ([]byte, []int) {
|
||||
func (m *CreateUserRequest) Reset() { *m = CreateUserRequest{} }
|
||||
func (m *CreateUserRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*CreateUserRequest) ProtoMessage() {}
|
||||
func (*CreateUserRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_73a7fc70dcc2027c, []int{9}
|
||||
}
|
||||
|
||||
func (m *RegisterUserRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_RegisterUserRequest.Unmarshal(m, b)
|
||||
func (m *CreateUserRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_CreateUserRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *RegisterUserRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_RegisterUserRequest.Marshal(b, m, deterministic)
|
||||
func (m *CreateUserRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_CreateUserRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *RegisterUserRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_RegisterUserRequest.Merge(m, src)
|
||||
func (m *CreateUserRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_CreateUserRequest.Merge(m, src)
|
||||
}
|
||||
func (m *RegisterUserRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_RegisterUserRequest.Size(m)
|
||||
func (m *CreateUserRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_CreateUserRequest.Size(m)
|
||||
}
|
||||
func (m *RegisterUserRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_RegisterUserRequest.DiscardUnknown(m)
|
||||
func (m *CreateUserRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_CreateUserRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_RegisterUserRequest proto.InternalMessageInfo
|
||||
var xxx_messageInfo_CreateUserRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *RegisterUserRequest) GetEmail() string {
|
||||
func (m *CreateUserRequest) GetUserName() string {
|
||||
if m != nil {
|
||||
return m.Email
|
||||
return m.UserName
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *RegisterUserRequest) GetFirstName() string {
|
||||
func (m *CreateUserRequest) GetFirstName() string {
|
||||
if m != nil {
|
||||
return m.FirstName
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *RegisterUserRequest) GetLastName() string {
|
||||
func (m *CreateUserRequest) GetLastName() string {
|
||||
if m != nil {
|
||||
return m.LastName
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *RegisterUserRequest) GetNickName() string {
|
||||
func (m *CreateUserRequest) GetNickName() string {
|
||||
if m != nil {
|
||||
return m.NickName
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *RegisterUserRequest) GetDisplayName() string {
|
||||
func (m *CreateUserRequest) GetDisplayName() string {
|
||||
if m != nil {
|
||||
return m.DisplayName
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *RegisterUserRequest) GetPreferredLanguage() string {
|
||||
func (m *CreateUserRequest) GetPreferredLanguage() string {
|
||||
if m != nil {
|
||||
return m.PreferredLanguage
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *RegisterUserRequest) GetGender() Gender {
|
||||
func (m *CreateUserRequest) GetGender() Gender {
|
||||
if m != nil {
|
||||
return m.Gender
|
||||
}
|
||||
return Gender_GENDER_UNSPECIFIED
|
||||
}
|
||||
|
||||
func (m *RegisterUserRequest) GetPassword() string {
|
||||
func (m *CreateUserRequest) GetEmail() string {
|
||||
if m != nil {
|
||||
return m.Password
|
||||
return m.Email
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *RegisterUserRequest) GetOrgId() string {
|
||||
func (m *CreateUserRequest) GetIsEmailVerified() bool {
|
||||
if m != nil {
|
||||
return m.OrgId
|
||||
return m.IsEmailVerified
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *CreateUserRequest) GetPhone() string {
|
||||
if m != nil {
|
||||
return m.Phone
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *CreateUserRequest) GetIsPhoneVerified() bool {
|
||||
if m != nil {
|
||||
return m.IsPhoneVerified
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *CreateUserRequest) GetCountry() string {
|
||||
if m != nil {
|
||||
return m.Country
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *CreateUserRequest) GetLocality() string {
|
||||
if m != nil {
|
||||
return m.Locality
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *CreateUserRequest) GetPostalCode() string {
|
||||
if m != nil {
|
||||
return m.PostalCode
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *CreateUserRequest) GetRegion() string {
|
||||
if m != nil {
|
||||
return m.Region
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *CreateUserRequest) GetStreetAddress() string {
|
||||
if m != nil {
|
||||
return m.StreetAddress
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *CreateUserRequest) GetPassword() string {
|
||||
if m != nil {
|
||||
return m.Password
|
||||
}
|
||||
return ""
|
||||
}
|
||||
@ -800,6 +864,7 @@ type User struct {
|
||||
PostalCode string `protobuf:"bytes,18,opt,name=postal_code,json=postalCode,proto3" json:"postal_code,omitempty"`
|
||||
Region string `protobuf:"bytes,19,opt,name=region,proto3" json:"region,omitempty"`
|
||||
StreetAddress string `protobuf:"bytes,20,opt,name=street_address,json=streetAddress,proto3" json:"street_address,omitempty"`
|
||||
Sequence uint64 `protobuf:"varint,21,opt,name=sequence,proto3" json:"sequence,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
@ -970,6 +1035,13 @@ func (m *User) GetStreetAddress() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *User) GetSequence() uint64 {
|
||||
if m != nil {
|
||||
return m.Sequence
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type CreateOrgRequest struct {
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Domain string `protobuf:"bytes,2,opt,name=domain,proto3" json:"domain,omitempty"`
|
||||
@ -1032,7 +1104,7 @@ func init() {
|
||||
proto.RegisterType((*OrgSearchResponse)(nil), "zitadel.admin.api.v1.OrgSearchResponse")
|
||||
proto.RegisterType((*OrgSetUpRequest)(nil), "zitadel.admin.api.v1.OrgSetUpRequest")
|
||||
proto.RegisterType((*OrgSetUpResponse)(nil), "zitadel.admin.api.v1.OrgSetUpResponse")
|
||||
proto.RegisterType((*RegisterUserRequest)(nil), "zitadel.admin.api.v1.RegisterUserRequest")
|
||||
proto.RegisterType((*CreateUserRequest)(nil), "zitadel.admin.api.v1.CreateUserRequest")
|
||||
proto.RegisterType((*User)(nil), "zitadel.admin.api.v1.User")
|
||||
proto.RegisterType((*CreateOrgRequest)(nil), "zitadel.admin.api.v1.CreateOrgRequest")
|
||||
}
|
||||
@ -1040,112 +1112,119 @@ func init() {
|
||||
func init() { proto.RegisterFile("admin.proto", fileDescriptor_73a7fc70dcc2027c) }
|
||||
|
||||
var fileDescriptor_73a7fc70dcc2027c = []byte{
|
||||
// 1667 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0x4f, 0x73, 0x1b, 0x49,
|
||||
0x15, 0xcf, 0xe8, 0x9f, 0x47, 0x4f, 0xfe, 0x33, 0xee, 0x78, 0x9d, 0x59, 0x39, 0xbb, 0xf6, 0x0e,
|
||||
0x9b, 0x90, 0xd5, 0x12, 0x69, 0x23, 0x96, 0x2a, 0xca, 0xd4, 0x2e, 0x25, 0x5b, 0xb3, 0x8e, 0x2a,
|
||||
0xb6, 0xe4, 0x1d, 0xc9, 0xe1, 0xcf, 0x45, 0x4c, 0x34, 0xed, 0x51, 0x93, 0xd1, 0xcc, 0xa4, 0xbb,
|
||||
0x95, 0xa0, 0xa5, 0x38, 0x90, 0x2a, 0x2e, 0x1c, 0x38, 0xc0, 0x81, 0x4f, 0xc0, 0x99, 0x13, 0x57,
|
||||
0xbe, 0x04, 0x1f, 0x80, 0x0b, 0x55, 0x5c, 0x38, 0x70, 0xe1, 0xb2, 0x27, 0xaa, 0xbb, 0x47, 0xb2,
|
||||
0x46, 0x96, 0x62, 0x52, 0x5c, 0xf6, 0x64, 0xf5, 0xef, 0xf7, 0x7b, 0xaf, 0x5f, 0xbf, 0x7e, 0xfd,
|
||||
0xa6, 0xdb, 0x50, 0x72, 0xbd, 0x11, 0x09, 0xab, 0x31, 0x8d, 0x78, 0x84, 0x76, 0xbe, 0x22, 0xdc,
|
||||
0xf5, 0x70, 0x50, 0x55, 0xa0, 0x1b, 0x93, 0xea, 0xcb, 0x47, 0xe5, 0xbb, 0x7e, 0x14, 0xf9, 0x01,
|
||||
0xae, 0xb9, 0x31, 0xa9, 0xb9, 0x61, 0x18, 0x71, 0x97, 0x93, 0x28, 0x64, 0xca, 0xa6, 0xbc, 0x97,
|
||||
0xb0, 0x72, 0xf4, 0x6c, 0x7c, 0x59, 0xc3, 0xa3, 0x98, 0x4f, 0x12, 0x72, 0x7f, 0x91, 0xe4, 0x64,
|
||||
0x84, 0x19, 0x77, 0x47, 0x71, 0x22, 0xb8, 0xbb, 0x28, 0x60, 0x9c, 0x8e, 0x07, 0x3c, 0x61, 0xef,
|
||||
0xbc, 0x74, 0x03, 0xe2, 0xb9, 0x1c, 0xd7, 0xa6, 0x3f, 0x12, 0xe2, 0x3b, 0xf2, 0xcf, 0xe0, 0xa1,
|
||||
0x8f, 0xc3, 0x87, 0xec, 0x95, 0xeb, 0xfb, 0x98, 0xd6, 0xa2, 0x58, 0x86, 0xb5, 0x24, 0x44, 0xd3,
|
||||
0x1d, 0xf3, 0xa1, 0xa2, 0xa7, 0x2a, 0xc5, 0x58, 0x77, 0x20, 0xdf, 0xa1, 0x7e, 0xab, 0x89, 0x36,
|
||||
0x21, 0x43, 0x3c, 0x53, 0x3b, 0xd0, 0x1e, 0x14, 0x9d, 0x0c, 0xf1, 0xac, 0x73, 0x30, 0x2e, 0x42,
|
||||
0xf2, 0x62, 0x8c, 0x3b, 0xd4, 0x77, 0xf0, 0x8b, 0x31, 0x66, 0x1c, 0xed, 0x41, 0x2e, 0x74, 0x47,
|
||||
0x58, 0xa9, 0x8e, 0xd6, 0xbe, 0x3e, 0xca, 0xd1, 0x8c, 0xa1, 0x39, 0x12, 0x44, 0xfb, 0x50, 0xf0,
|
||||
0xa2, 0x91, 0x4b, 0x42, 0x33, 0x93, 0xa6, 0x13, 0xd8, 0xfa, 0x04, 0xb6, 0xe7, 0x3c, 0xb2, 0x38,
|
||||
0x0a, 0x19, 0x46, 0x7b, 0x50, 0x24, 0xac, 0x3f, 0x96, 0xb8, 0xf4, 0xab, 0x3b, 0x3a, 0x61, 0x4a,
|
||||
0x67, 0xfd, 0x47, 0x83, 0x6c, 0x87, 0xfa, 0x8b, 0xb1, 0xa1, 0x4f, 0x21, 0xcf, 0xb8, 0xcb, 0xb1,
|
||||
0x9c, 0x69, 0xb3, 0xfe, 0x7e, 0x75, 0xd9, 0xae, 0x55, 0x3b, 0xd4, 0xef, 0x0a, 0x95, 0xa3, 0xc4,
|
||||
0xe8, 0x87, 0xb0, 0x31, 0xa0, 0x58, 0xe6, 0xa5, 0x2f, 0x32, 0x69, 0x66, 0x0f, 0xb4, 0x07, 0xa5,
|
||||
0x7a, 0xb9, 0xaa, 0x76, 0xa0, 0x3a, 0xdd, 0x81, 0x6a, 0x6f, 0xba, 0x45, 0xce, 0xfa, 0xd4, 0xa0,
|
||||
0x29, 0x1c, 0xfc, 0x00, 0x4a, 0x83, 0xa1, 0x1b, 0xfa, 0x58, 0x99, 0xe7, 0x6e, 0x34, 0x07, 0x25,
|
||||
0x97, 0xc6, 0x28, 0xc9, 0x5d, 0x5e, 0xae, 0x42, 0xa5, 0x6c, 0x77, 0x96, 0xb2, 0x82, 0x44, 0xa7,
|
||||
0x99, 0xfa, 0xa7, 0x06, 0x86, 0x88, 0x1e, 0xbb, 0x74, 0x30, 0x9c, 0x26, 0x7f, 0x17, 0x0a, 0xd1,
|
||||
0xe5, 0x25, 0xc3, 0x5c, 0x26, 0x22, 0xe7, 0x24, 0x23, 0xb4, 0x03, 0xf9, 0x80, 0x8c, 0x08, 0x97,
|
||||
0xc9, 0xc8, 0x39, 0x6a, 0x80, 0xba, 0xb0, 0xc9, 0x22, 0xca, 0x49, 0xe8, 0xf7, 0x07, 0x51, 0x30,
|
||||
0x1e, 0x85, 0x72, 0xb5, 0x9b, 0x75, 0x6b, 0x75, 0xae, 0xe4, 0x6c, 0x4f, 0xf0, 0xe4, 0x48, 0xff,
|
||||
0xfa, 0x28, 0xff, 0x5a, 0xcb, 0x1c, 0xdc, 0x72, 0x36, 0x12, 0x1f, 0xc7, 0xd2, 0x05, 0x32, 0x20,
|
||||
0xeb, 0xb2, 0x81, 0x5c, 0xb8, 0xee, 0x88, 0x9f, 0xe8, 0x73, 0x58, 0x7b, 0x31, 0xc6, 0x94, 0x60,
|
||||
0x66, 0xe6, 0x0f, 0xb2, 0x0f, 0x4a, 0xf5, 0x0f, 0x6f, 0xf0, 0xff, 0xe5, 0x18, 0xd3, 0x89, 0x33,
|
||||
0x35, 0xb2, 0xfe, 0xa4, 0xc1, 0x66, 0x9a, 0x43, 0x9f, 0x43, 0xf6, 0x39, 0x9e, 0xc8, 0x45, 0xbe,
|
||||
0x6d, 0xb8, 0xc2, 0x10, 0x7d, 0x06, 0x85, 0x11, 0xe6, 0xc3, 0xc8, 0x4b, 0xaa, 0xe3, 0xde, 0x0d,
|
||||
0x2e, 0xce, 0xa4, 0xd8, 0x49, 0x8c, 0x44, 0x3a, 0x5f, 0xba, 0xc1, 0x58, 0x55, 0x47, 0xd1, 0x51,
|
||||
0x03, 0xeb, 0x8f, 0x1a, 0x6c, 0xcf, 0xed, 0x48, 0x52, 0xbc, 0x6f, 0xb7, 0x25, 0x1f, 0xc0, 0x3a,
|
||||
0x8f, 0xb8, 0x1b, 0xf4, 0x29, 0x66, 0xe3, 0x80, 0xcb, 0x09, 0x72, 0x4e, 0x49, 0x62, 0x8e, 0x84,
|
||||
0xd0, 0x23, 0x28, 0x24, 0x64, 0x4e, 0x66, 0xf3, 0xdd, 0x95, 0xb1, 0x3b, 0x89, 0xd0, 0xfa, 0xad,
|
||||
0x06, 0x5b, 0x32, 0x32, 0x7e, 0x11, 0x4f, 0x4b, 0xe5, 0xfb, 0x90, 0x8d, 0xa8, 0x2f, 0x83, 0x2a,
|
||||
0xd5, 0xef, 0x2f, 0xf7, 0x71, 0x2c, 0x2a, 0x7b, 0xee, 0x70, 0x3b, 0xc2, 0x04, 0x7d, 0x06, 0xb9,
|
||||
0x31, 0xc3, 0x54, 0x06, 0x5e, 0xaa, 0x7f, 0xb4, 0xdc, 0xd4, 0xc1, 0x3e, 0x61, 0x1c, 0xd3, 0x0b,
|
||||
0x86, 0xe9, 0xd4, 0x5a, 0x9a, 0x59, 0x51, 0x52, 0xb7, 0x32, 0x96, 0x24, 0x49, 0x1f, 0xcf, 0x07,
|
||||
0xf3, 0x86, 0x05, 0xc9, 0xf9, 0xab, 0xa9, 0xf9, 0xcb, 0xcb, 0xd5, 0x72, 0x5e, 0x35, 0xe1, 0xbf,
|
||||
0x32, 0x70, 0x7b, 0x49, 0x38, 0xe8, 0x3d, 0xc8, 0xe3, 0x91, 0x4b, 0x82, 0x54, 0xab, 0xfa, 0x99,
|
||||
0xe6, 0x28, 0x14, 0xdd, 0x07, 0xb8, 0x24, 0x94, 0xf1, 0xbe, 0x3c, 0x92, 0x0b, 0xfd, 0xaa, 0x28,
|
||||
0xa9, 0xb6, 0x38, 0xa0, 0x1f, 0x42, 0x31, 0x70, 0xa7, 0xb2, 0x6c, 0x5a, 0xa6, 0x0b, 0x46, 0xaa,
|
||||
0xf6, 0xa0, 0x18, 0x92, 0xc1, 0x73, 0xa5, 0xca, 0xc9, 0xb2, 0xd1, 0x05, 0x20, 0xc9, 0x0f, 0x60,
|
||||
0xdd, 0x23, 0x2c, 0x0e, 0xdc, 0x49, 0x7f, 0xee, 0xfc, 0x97, 0x12, 0x4c, 0x4a, 0x1e, 0x02, 0x8a,
|
||||
0x29, 0xbe, 0xc4, 0x94, 0x62, 0xaf, 0x1f, 0xb8, 0xa1, 0x3f, 0x76, 0x7d, 0x9c, 0xb4, 0x84, 0xed,
|
||||
0x19, 0x73, 0x9a, 0x10, 0xe8, 0x53, 0x28, 0xf8, 0x38, 0xf4, 0x30, 0x35, 0xd7, 0x64, 0x81, 0xdf,
|
||||
0x5d, 0x9e, 0xa5, 0x13, 0xa9, 0x71, 0x12, 0x2d, 0xfa, 0x16, 0xe8, 0xb1, 0xcb, 0xd8, 0xab, 0x88,
|
||||
0x7a, 0xa6, 0xbe, 0xb0, 0x92, 0x29, 0x81, 0xde, 0x87, 0x42, 0x44, 0xfd, 0x3e, 0xf1, 0xcc, 0x62,
|
||||
0x5a, 0x92, 0x8f, 0xa8, 0xdf, 0xf2, 0xac, 0xbf, 0xe7, 0x21, 0x27, 0xd2, 0x7c, 0xad, 0x23, 0x7f,
|
||||
0x2f, 0xdd, 0x91, 0xf7, 0x57, 0x6f, 0xdc, 0x37, 0xa8, 0x25, 0xef, 0x41, 0x51, 0x14, 0xd1, 0xfc,
|
||||
0xbe, 0xe8, 0x02, 0x90, 0x9b, 0xf2, 0x5e, 0xaa, 0x44, 0xd4, 0x66, 0xcc, 0x55, 0xc6, 0xde, 0x7c,
|
||||
0x65, 0xac, 0x29, 0xdb, 0xe5, 0x05, 0xa1, 0xdf, 0x50, 0x10, 0xc5, 0xff, 0xb5, 0x20, 0xe0, 0xe6,
|
||||
0x82, 0x28, 0xbd, 0x45, 0x41, 0xec, 0x4c, 0x8f, 0xc8, 0xba, 0x6a, 0x74, 0xea, 0x64, 0x3c, 0x80,
|
||||
0x2d, 0xc2, 0x6c, 0xf1, 0xf3, 0x29, 0xa6, 0xe4, 0x92, 0x60, 0xcf, 0xdc, 0x90, 0xed, 0x7e, 0x11,
|
||||
0x16, 0xf6, 0xf1, 0x30, 0x0a, 0xb1, 0xb9, 0xa9, 0xec, 0xe5, 0x40, 0xd9, 0x9f, 0x8b, 0x9f, 0x33,
|
||||
0xfb, 0xad, 0xa9, 0x7d, 0x0a, 0x46, 0x26, 0xac, 0x0d, 0xa2, 0x71, 0xc8, 0xe9, 0xc4, 0x34, 0xa4,
|
||||
0x87, 0xe9, 0x10, 0x95, 0x41, 0x0f, 0xa2, 0x81, 0x1b, 0x10, 0x3e, 0x31, 0xb7, 0x93, 0xd4, 0x26,
|
||||
0x63, 0xb4, 0x0f, 0xa5, 0x38, 0x62, 0xa2, 0x8b, 0x0e, 0x22, 0x0f, 0x9b, 0x48, 0xd2, 0xa0, 0xa0,
|
||||
0xe3, 0xc8, 0x93, 0x3d, 0x99, 0x62, 0x9f, 0x44, 0xa1, 0x79, 0x5b, 0x7d, 0x53, 0xd5, 0x08, 0xdd,
|
||||
0x83, 0x4d, 0xc6, 0x29, 0xc6, 0xbc, 0xef, 0x7a, 0x1e, 0xc5, 0x8c, 0x99, 0x3b, 0x92, 0xdf, 0x50,
|
||||
0x68, 0x43, 0x81, 0xe2, 0xda, 0xb3, 0xd8, 0x19, 0xff, 0xbf, 0x6b, 0x4f, 0xe5, 0x1c, 0xf4, 0xe9,
|
||||
0x4d, 0x04, 0x99, 0xb0, 0xd3, 0x71, 0x4e, 0xba, 0xbd, 0x46, 0xcf, 0xee, 0x5f, 0xb4, 0xbb, 0xe7,
|
||||
0xf6, 0x71, 0xeb, 0x8b, 0x96, 0xdd, 0x34, 0x6e, 0xa1, 0xdb, 0xb0, 0x35, 0x63, 0x1a, 0xc7, 0xbd,
|
||||
0xd6, 0x53, 0xdb, 0xd0, 0xd0, 0x3b, 0xb0, 0x3d, 0x03, 0x5b, 0xed, 0x04, 0xce, 0x54, 0x7e, 0x01,
|
||||
0xeb, 0xf3, 0x1f, 0x40, 0x74, 0x17, 0x4c, 0x21, 0xb3, 0x1b, 0xce, 0xf1, 0xe3, 0x27, 0xf6, 0x4f,
|
||||
0x16, 0x3c, 0xbf, 0x0b, 0xef, 0xa4, 0xd8, 0x8e, 0x73, 0xd2, 0x6f, 0x37, 0xce, 0x84, 0xff, 0x3b,
|
||||
0x70, 0x3b, 0x45, 0x35, 0x3b, 0x67, 0x8d, 0x56, 0xdb, 0xc8, 0xa0, 0x5d, 0x40, 0x29, 0x42, 0x86,
|
||||
0x60, 0x64, 0x2b, 0x41, 0xf2, 0xad, 0xb9, 0xfa, 0x6e, 0xa2, 0x32, 0xec, 0xce, 0xa4, 0x67, 0x76,
|
||||
0xef, 0x71, 0xa7, 0xd9, 0xb7, 0xbf, 0xbc, 0x68, 0x9c, 0x76, 0x8d, 0x5b, 0x68, 0x1f, 0xf6, 0x16,
|
||||
0xb9, 0x6e, 0xaf, 0xe1, 0xf4, 0xba, 0xfd, 0x1f, 0xb5, 0x7a, 0x8f, 0x0d, 0x2d, 0x15, 0x79, 0x22,
|
||||
0x38, 0xee, 0xb4, 0x7b, 0x8d, 0x56, 0xbb, 0x6b, 0x64, 0x2a, 0x7f, 0xd6, 0xa0, 0x38, 0x6b, 0x19,
|
||||
0x62, 0x1d, 0x17, 0x5d, 0xdb, 0x59, 0x96, 0xbc, 0x1d, 0x30, 0xae, 0xa8, 0x59, 0xf6, 0x76, 0x01,
|
||||
0x5d, 0xa1, 0x57, 0xe9, 0x13, 0x59, 0xbd, 0xc2, 0x9b, 0xf6, 0xa9, 0xdd, 0xb3, 0x9b, 0x46, 0x36,
|
||||
0xed, 0xe4, 0xb4, 0x73, 0xfc, 0xc4, 0x6e, 0x1a, 0xb9, 0xb4, 0xb8, 0x7b, 0xd1, 0x3d, 0xb7, 0xdb,
|
||||
0x4d, 0x23, 0x9f, 0x86, 0x5b, 0xed, 0x56, 0xaf, 0xd5, 0x38, 0x35, 0x0a, 0x95, 0x1f, 0x43, 0x41,
|
||||
0x9d, 0x32, 0x31, 0xf9, 0x89, 0xdd, 0x6e, 0xda, 0xce, 0x42, 0xa8, 0xdb, 0xb0, 0x91, 0xe0, 0x5f,
|
||||
0xd8, 0x67, 0x8d, 0x53, 0x11, 0xe7, 0x16, 0x94, 0x12, 0x48, 0x02, 0x19, 0x84, 0x60, 0x33, 0x01,
|
||||
0x9a, 0xad, 0xa7, 0xb6, 0xd3, 0xb5, 0x8d, 0x6c, 0xfd, 0xdf, 0x79, 0x58, 0x6f, 0x88, 0xd3, 0xdc,
|
||||
0xc5, 0xf4, 0x25, 0x19, 0x60, 0xf4, 0x04, 0xd6, 0x1e, 0x63, 0x37, 0xe0, 0xc3, 0xaf, 0xd0, 0xee,
|
||||
0xb5, 0x7e, 0x67, 0x8b, 0x17, 0x48, 0x79, 0x05, 0x6e, 0x19, 0xaf, 0xff, 0xf6, 0x8f, 0x3f, 0x64,
|
||||
0x00, 0xe9, 0xb5, 0x61, 0xe2, 0xe1, 0x04, 0xf2, 0x0e, 0x76, 0xbd, 0xc9, 0x5b, 0xbb, 0xda, 0x94,
|
||||
0xae, 0x74, 0x54, 0xa8, 0x51, 0x69, 0xdf, 0x06, 0xfd, 0x69, 0xf2, 0x50, 0x59, 0xe9, 0xeb, 0xce,
|
||||
0x35, 0xbc, 0x2b, 0x9f, 0x3c, 0xd6, 0xb6, 0x74, 0x56, 0x42, 0xc5, 0xd9, 0x63, 0x07, 0xfd, 0x46,
|
||||
0x83, 0x52, 0x8b, 0x75, 0xa8, 0xaf, 0x5e, 0x04, 0x68, 0xc5, 0x65, 0x66, 0xf1, 0xa5, 0x52, 0xfe,
|
||||
0xf6, 0x8d, 0x3a, 0x75, 0x3b, 0xb1, 0xee, 0xbd, 0xfe, 0x8b, 0x09, 0xa0, 0x13, 0x77, 0x54, 0x15,
|
||||
0x2b, 0x90, 0x11, 0x6c, 0xa3, 0xad, 0x5a, 0x44, 0x7d, 0x56, 0xeb, 0x13, 0xa6, 0x5e, 0x26, 0xe8,
|
||||
0x12, 0xe0, 0x04, 0xf3, 0x0e, 0xf5, 0x8f, 0x26, 0xad, 0x26, 0xda, 0x5b, 0x79, 0x8b, 0x69, 0x35,
|
||||
0xcb, 0xab, 0xaf, 0x38, 0xd6, 0xc1, 0x92, 0xc9, 0xd6, 0x11, 0xa8, 0xc9, 0x7e, 0x49, 0xbc, 0x5f,
|
||||
0x89, 0xf5, 0x82, 0x3a, 0x5e, 0x1d, 0xea, 0xb3, 0x55, 0xcb, 0x5d, 0x7c, 0x1b, 0xac, 0x5a, 0xee,
|
||||
0xb5, 0x1b, 0xab, 0x75, 0x7f, 0x49, 0x04, 0xc8, 0xda, 0x48, 0x96, 0xcb, 0xa4, 0xf8, 0x50, 0xab,
|
||||
0xa0, 0x5f, 0x6b, 0xa0, 0xcb, 0x6b, 0x9c, 0x78, 0x7e, 0xbd, 0xe9, 0x06, 0x7d, 0x75, 0xeb, 0x2c,
|
||||
0xdf, 0xbf, 0x49, 0x36, 0x17, 0x43, 0x09, 0x8a, 0x22, 0x86, 0x57, 0x94, 0x70, 0xac, 0x72, 0x6e,
|
||||
0xad, 0xcf, 0x82, 0xe0, 0xe3, 0xf8, 0x50, 0xab, 0x1c, 0xfd, 0x55, 0xfb, 0x7d, 0xe3, 0x77, 0x1a,
|
||||
0x6a, 0xc0, 0x86, 0xf4, 0x77, 0xc0, 0x54, 0xe5, 0x5b, 0x1f, 0xa3, 0x8f, 0x86, 0x9c, 0xc7, 0xec,
|
||||
0xb0, 0x56, 0xf3, 0x09, 0x1f, 0x8e, 0x9f, 0x55, 0x07, 0xd1, 0xa8, 0x36, 0x70, 0x23, 0x56, 0x4b,
|
||||
0x02, 0xa8, 0xc5, 0xcf, 0xfd, 0x9a, 0x34, 0xaa, 0x67, 0x3f, 0xa9, 0x3e, 0xaa, 0x68, 0x99, 0xba,
|
||||
0xe1, 0xc6, 0x71, 0x40, 0x06, 0xf2, 0xe6, 0x50, 0xfb, 0x39, 0x8b, 0xc2, 0x34, 0xe2, 0xd3, 0x78,
|
||||
0x70, 0x78, 0x4d, 0x73, 0x78, 0x4d, 0xf3, 0xd3, 0xca, 0x8d, 0x53, 0xca, 0xff, 0x12, 0x08, 0xed,
|
||||
0xb3, 0x82, 0x2c, 0xf0, 0xef, 0xfe, 0x37, 0x00, 0x00, 0xff, 0xff, 0x70, 0xfd, 0x92, 0x95, 0x62,
|
||||
0x10, 0x00, 0x00,
|
||||
// 1785 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0x4b, 0x73, 0x1b, 0x59,
|
||||
0x15, 0x4e, 0xeb, 0x65, 0xe9, 0x48, 0x96, 0x5b, 0x37, 0x8e, 0xd3, 0x23, 0x67, 0xb0, 0xa7, 0x99,
|
||||
0xbc, 0x14, 0x22, 0x4d, 0xc4, 0x50, 0x50, 0x9e, 0x62, 0x28, 0xd9, 0xea, 0xb1, 0x55, 0xb1, 0x25,
|
||||
0x4f, 0x4b, 0x0e, 0x8f, 0x8d, 0xe8, 0xa8, 0xaf, 0x5b, 0x4d, 0xa4, 0xee, 0xce, 0xbd, 0x2d, 0x07,
|
||||
0x85, 0x62, 0x41, 0xaa, 0xa8, 0x62, 0xc5, 0x02, 0x16, 0xfc, 0x02, 0xd6, 0xac, 0xd8, 0xb2, 0x66,
|
||||
0xcf, 0x92, 0x2d, 0x55, 0x6c, 0xd9, 0xb0, 0x09, 0x1b, 0xea, 0x3e, 0x5a, 0x6f, 0xc5, 0xe5, 0x62,
|
||||
0xc3, 0xca, 0xea, 0xf3, 0x7d, 0xe7, 0xdc, 0x73, 0xcf, 0x3d, 0xdf, 0x7d, 0x18, 0xb2, 0x96, 0x3d,
|
||||
0x74, 0xbd, 0x72, 0x40, 0xfc, 0xd0, 0x47, 0xdb, 0x6f, 0xdd, 0xd0, 0xb2, 0xf1, 0xa0, 0x2c, 0x8c,
|
||||
0x56, 0xe0, 0x96, 0xaf, 0x9e, 0x15, 0xef, 0x39, 0xbe, 0xef, 0x0c, 0x70, 0xc5, 0x0a, 0xdc, 0x8a,
|
||||
0xe5, 0x79, 0x7e, 0x68, 0x85, 0xae, 0xef, 0x51, 0xe1, 0x53, 0xdc, 0x95, 0x28, 0xff, 0x7a, 0x39,
|
||||
0xba, 0xac, 0xe0, 0x61, 0x10, 0x8e, 0x25, 0xb8, 0xb7, 0x08, 0x86, 0xee, 0x10, 0xd3, 0xd0, 0x1a,
|
||||
0x06, 0x92, 0x70, 0x6f, 0x91, 0x40, 0x43, 0x32, 0xea, 0x85, 0x12, 0xbd, 0x7b, 0x65, 0x0d, 0x5c,
|
||||
0xdb, 0x0a, 0x71, 0x25, 0xfa, 0x21, 0x81, 0x6f, 0xf1, 0x3f, 0xbd, 0xa7, 0x0e, 0xf6, 0x9e, 0xd2,
|
||||
0x37, 0x96, 0xe3, 0x60, 0x52, 0xf1, 0x03, 0x9e, 0xd6, 0x8a, 0x14, 0x35, 0x6b, 0x14, 0xf6, 0x05,
|
||||
0x1c, 0xb1, 0x04, 0xa2, 0xdf, 0x85, 0x64, 0x8b, 0x38, 0x8d, 0x3a, 0xca, 0x43, 0xcc, 0xb5, 0x35,
|
||||
0x65, 0x5f, 0x79, 0x94, 0x31, 0x63, 0xae, 0xad, 0x9f, 0x83, 0x7a, 0xe1, 0xb9, 0xaf, 0x47, 0xb8,
|
||||
0x45, 0x1c, 0x13, 0xbf, 0x1e, 0x61, 0x1a, 0xa2, 0x5d, 0x48, 0x78, 0xd6, 0x10, 0x0b, 0xd6, 0xe1,
|
||||
0xc6, 0xfb, 0xc3, 0x04, 0x89, 0xa9, 0x8a, 0xc9, 0x8d, 0x68, 0x0f, 0x52, 0xb6, 0x3f, 0xb4, 0x5c,
|
||||
0x4f, 0x8b, 0xcd, 0xc3, 0xd2, 0xac, 0x7f, 0x06, 0x85, 0x99, 0x88, 0x34, 0xf0, 0x3d, 0x8a, 0xd1,
|
||||
0x2e, 0x64, 0x5c, 0xda, 0x1d, 0x71, 0x3b, 0x8f, 0x9b, 0x36, 0xd3, 0x2e, 0x15, 0x3c, 0xfd, 0xdf,
|
||||
0x0a, 0xc4, 0x5b, 0xc4, 0x59, 0xcc, 0x0d, 0x7d, 0x0e, 0x49, 0x1a, 0x5a, 0x21, 0xe6, 0x23, 0xe5,
|
||||
0xab, 0xdf, 0x28, 0xaf, 0x5a, 0xb5, 0x72, 0x8b, 0x38, 0x6d, 0xc6, 0x32, 0x05, 0x19, 0xfd, 0x00,
|
||||
0x36, 0x7b, 0x04, 0xf3, 0xba, 0x74, 0x59, 0x25, 0xb5, 0xf8, 0xbe, 0xf2, 0x28, 0x5b, 0x2d, 0x96,
|
||||
0xc5, 0x0a, 0x94, 0xa3, 0x15, 0x28, 0x77, 0xa2, 0x25, 0x32, 0x73, 0x91, 0x43, 0x9d, 0x05, 0xf8,
|
||||
0x02, 0xb2, 0xbd, 0xbe, 0xe5, 0x39, 0x58, 0xb8, 0x27, 0xae, 0x75, 0x07, 0x41, 0xe7, 0xce, 0x48,
|
||||
0xd6, 0x2e, 0xc9, 0x67, 0x21, 0x4a, 0xb6, 0x33, 0x29, 0x59, 0x8a, 0x5b, 0xa3, 0x4a, 0xfd, 0x53,
|
||||
0x01, 0x95, 0x65, 0x8f, 0x2d, 0xd2, 0xeb, 0x47, 0xc5, 0xdf, 0x81, 0x94, 0x7f, 0x79, 0x49, 0x71,
|
||||
0xc8, 0x0b, 0x91, 0x30, 0xe5, 0x17, 0xda, 0x86, 0xe4, 0xc0, 0x1d, 0xba, 0x21, 0x2f, 0x46, 0xc2,
|
||||
0x14, 0x1f, 0xa8, 0x0d, 0x79, 0xea, 0x93, 0xd0, 0xf5, 0x9c, 0x6e, 0xcf, 0x1f, 0x8c, 0x86, 0x1e,
|
||||
0x9f, 0x6d, 0xbe, 0xaa, 0xaf, 0xaf, 0x15, 0x1f, 0xed, 0x39, 0x1e, 0x1f, 0xa6, 0xdf, 0x1f, 0x26,
|
||||
0xdf, 0x29, 0xb1, 0xfd, 0x5b, 0xe6, 0xa6, 0x8c, 0x71, 0xc4, 0x43, 0x20, 0x15, 0xe2, 0x16, 0xed,
|
||||
0xf1, 0x89, 0xa7, 0x4d, 0xf6, 0x13, 0x7d, 0x09, 0x1b, 0xaf, 0x47, 0x98, 0xb8, 0x98, 0x6a, 0xc9,
|
||||
0xfd, 0xf8, 0xa3, 0x6c, 0xf5, 0xd3, 0x6b, 0xe2, 0x7f, 0x3d, 0xc2, 0x64, 0x6c, 0x46, 0x4e, 0xfa,
|
||||
0x1f, 0x15, 0xc8, 0xcf, 0x63, 0xe8, 0x4b, 0x88, 0xbf, 0xc2, 0x63, 0x3e, 0xc9, 0x9b, 0xa6, 0xcb,
|
||||
0x1c, 0xd1, 0xf7, 0x21, 0x35, 0xc4, 0x61, 0xdf, 0xb7, 0x65, 0x77, 0xdc, 0xbf, 0x26, 0xc4, 0x19,
|
||||
0x27, 0x9b, 0xd2, 0x89, 0x95, 0xf3, 0xca, 0x1a, 0x8c, 0x44, 0x77, 0x64, 0x4c, 0xf1, 0xa1, 0xff,
|
||||
0x41, 0x81, 0xc2, 0xcc, 0x8a, 0xc8, 0xe6, 0xbd, 0xd9, 0x92, 0x7c, 0x02, 0xb9, 0xd0, 0x0f, 0xad,
|
||||
0x41, 0x97, 0x60, 0x3a, 0x1a, 0x84, 0x7c, 0x80, 0x84, 0x99, 0xe5, 0x36, 0x93, 0x9b, 0xd0, 0x33,
|
||||
0x48, 0x49, 0x30, 0xc1, 0xab, 0xf9, 0xd1, 0xda, 0xdc, 0x4d, 0x49, 0xd4, 0x7f, 0xa3, 0xc0, 0x16,
|
||||
0xcf, 0x2c, 0xbc, 0x08, 0xa2, 0x56, 0xf9, 0x1e, 0xc4, 0x7d, 0xe2, 0xf0, 0xa4, 0xb2, 0xd5, 0x07,
|
||||
0xab, 0x63, 0x1c, 0xb1, 0xce, 0x9e, 0x11, 0xb7, 0xc9, 0x5c, 0xd0, 0x17, 0x90, 0x18, 0x51, 0x4c,
|
||||
0x78, 0xe2, 0xd9, 0xea, 0xc3, 0x0f, 0xb9, 0x5e, 0x50, 0x4c, 0x22, 0x5f, 0xee, 0xa4, 0xfb, 0xb2,
|
||||
0x6b, 0x79, 0x26, 0xb2, 0x44, 0x4f, 0x66, 0x53, 0xf9, 0xc0, 0x74, 0xf8, 0xe8, 0xe5, 0xb9, 0xd1,
|
||||
0x8b, 0xab, 0xd9, 0x7c, 0x5c, 0x31, 0xe0, 0xdf, 0x93, 0x50, 0x58, 0x4a, 0x06, 0x3d, 0x84, 0x0c,
|
||||
0x43, 0xbb, 0x33, 0x5b, 0x15, 0xbc, 0x3f, 0xdc, 0x20, 0x49, 0x55, 0xd1, 0xfe, 0xaa, 0x98, 0x69,
|
||||
0x06, 0x36, 0x99, 0xfc, 0x1e, 0x03, 0x5c, 0xba, 0x84, 0x86, 0x82, 0x19, 0x5b, 0x62, 0x66, 0x38,
|
||||
0xca, 0xa9, 0x0f, 0x21, 0x33, 0xb0, 0x22, 0x66, 0x7c, 0x39, 0x26, 0x03, 0x39, 0xf1, 0x3e, 0x64,
|
||||
0x3c, 0xb7, 0xf7, 0x4a, 0x10, 0x13, 0x9c, 0xc8, 0xfa, 0x93, 0xc4, 0x39, 0x8d, 0x41, 0x9c, 0xf6,
|
||||
0x04, 0x72, 0xb6, 0x4b, 0x83, 0x81, 0x35, 0xee, 0x4e, 0x77, 0x85, 0x19, 0x66, 0x56, 0xa2, 0x9c,
|
||||
0xfc, 0x5d, 0x40, 0x01, 0xc1, 0x97, 0x98, 0x10, 0x6c, 0x77, 0x07, 0x96, 0xe7, 0x8c, 0x2c, 0x07,
|
||||
0x8b, 0x2d, 0x63, 0xc6, 0xa5, 0x30, 0xe1, 0x9c, 0x4a, 0x0a, 0xfa, 0x1c, 0x52, 0x0e, 0xf6, 0x6c,
|
||||
0x4c, 0xb4, 0x0d, 0x2e, 0x85, 0x7b, 0xab, 0x2b, 0x7a, 0xcc, 0x39, 0xa6, 0xe4, 0x22, 0x1d, 0x92,
|
||||
0x78, 0x68, 0xb9, 0x03, 0x2d, 0xcd, 0x47, 0xc8, 0xbd, 0x3f, 0xcc, 0x90, 0x0d, 0x3e, 0xcf, 0x9f,
|
||||
0x2a, 0xa6, 0x80, 0x50, 0x09, 0x0a, 0x2e, 0xed, 0xf2, 0xdf, 0xdd, 0x2b, 0x4c, 0xdc, 0x4b, 0x17,
|
||||
0xdb, 0x5a, 0x86, 0xef, 0x0b, 0x5b, 0x2e, 0x35, 0x98, 0xfd, 0x85, 0x34, 0xa3, 0x8f, 0x21, 0x19,
|
||||
0xf4, 0x7d, 0x0f, 0x6b, 0xd9, 0x99, 0x73, 0x41, 0xdb, 0x36, 0x85, 0x55, 0x86, 0xe2, 0xbf, 0xa7,
|
||||
0xa1, 0x72, 0x51, 0xa8, 0x73, 0x66, 0x9f, 0x84, 0xd2, 0x61, 0xa3, 0xe7, 0x8f, 0xbc, 0x90, 0x8c,
|
||||
0xb5, 0xcd, 0x85, 0xe9, 0x47, 0x00, 0xfa, 0x14, 0xd2, 0x03, 0xbf, 0x67, 0x0d, 0xdc, 0x70, 0xac,
|
||||
0xe5, 0x17, 0x17, 0x20, 0x42, 0xd0, 0x63, 0xc8, 0x06, 0x3e, 0x65, 0x6a, 0xec, 0xf9, 0x36, 0xd6,
|
||||
0xb6, 0x16, 0x88, 0x20, 0xc0, 0x23, 0xdf, 0xc6, 0x68, 0x9f, 0x89, 0xd2, 0x71, 0x7d, 0x4f, 0x53,
|
||||
0x17, 0x58, 0xd2, 0x8e, 0x2a, 0x90, 0xa7, 0x21, 0xc1, 0x38, 0xec, 0x5a, 0xb6, 0x4d, 0x30, 0xa5,
|
||||
0x5a, 0x61, 0x81, 0xb9, 0x29, 0xf0, 0x9a, 0x80, 0xd1, 0x37, 0x21, 0x1d, 0x58, 0x94, 0xbe, 0xf1,
|
||||
0x89, 0xad, 0xa1, 0xd9, 0xaa, 0x9c, 0x98, 0x13, 0x40, 0xff, 0x4f, 0x12, 0x12, 0xac, 0xaf, 0x97,
|
||||
0x8e, 0xbf, 0xef, 0xcc, 0x1f, 0x7f, 0x7b, 0xeb, 0x75, 0xf2, 0x7f, 0x74, 0xfe, 0xed, 0xce, 0xaa,
|
||||
0x52, 0x1c, 0x82, 0x53, 0x25, 0x7e, 0x3c, 0xa7, 0x44, 0x71, 0x18, 0xce, 0xa8, 0x6f, 0x77, 0x56,
|
||||
0x7d, 0x1b, 0xc2, 0x77, 0xa2, 0xb8, 0xdd, 0x59, 0xc5, 0xa5, 0x05, 0x38, 0xd1, 0xd9, 0x27, 0x0b,
|
||||
0x3a, 0xcb, 0x70, 0x7c, 0x4e, 0x5d, 0x4f, 0x57, 0xaa, 0x0b, 0x38, 0xf1, 0x83, 0x9a, 0xca, 0xde,
|
||||
0x40, 0x53, 0xdb, 0x91, 0xa6, 0x72, 0xe2, 0x54, 0x11, 0x2a, 0x7a, 0x04, 0x8b, 0x62, 0xe1, 0x6d,
|
||||
0xbd, 0x42, 0x43, 0xdb, 0x91, 0x86, 0xf2, 0xc2, 0x5f, 0x48, 0x87, 0xfb, 0xcf, 0x29, 0x84, 0x37,
|
||||
0xf2, 0x0a, 0xe1, 0x68, 0x53, 0xe1, 0xf0, 0x26, 0x9e, 0xca, 0xa5, 0x38, 0x23, 0x97, 0x82, 0x2c,
|
||||
0x6d, 0x24, 0x92, 0xbd, 0x79, 0x91, 0xf0, 0x4e, 0x9d, 0x93, 0xc6, 0xce, 0x44, 0x1a, 0xb7, 0xc5,
|
||||
0x05, 0x46, 0x0a, 0xe2, 0xfe, 0x92, 0x20, 0xb6, 0x39, 0xbe, 0x20, 0x83, 0x22, 0xa4, 0x29, 0xdb,
|
||||
0xb4, 0xbd, 0x1e, 0xd6, 0xee, 0xf0, 0xd3, 0x70, 0xf2, 0xcd, 0xee, 0x9f, 0x8b, 0x47, 0xd4, 0xff,
|
||||
0x76, 0xff, 0x2c, 0x9d, 0x43, 0x3a, 0xba, 0x12, 0x22, 0x0d, 0xb6, 0x5b, 0xe6, 0x71, 0xbb, 0x53,
|
||||
0xeb, 0x18, 0xdd, 0x8b, 0x66, 0xfb, 0xdc, 0x38, 0x6a, 0x7c, 0xd5, 0x30, 0xea, 0xea, 0x2d, 0x74,
|
||||
0x1b, 0xb6, 0x26, 0x48, 0xed, 0xa8, 0xd3, 0x78, 0x61, 0xa8, 0x0a, 0xba, 0x03, 0x85, 0x89, 0xb1,
|
||||
0xd1, 0x94, 0xe6, 0x58, 0xe9, 0xe7, 0x90, 0x9b, 0xbd, 0x89, 0xa0, 0x7b, 0xa0, 0x31, 0x9a, 0x51,
|
||||
0x33, 0x8f, 0x4e, 0x9e, 0x1b, 0x3f, 0x5e, 0x88, 0xfc, 0x11, 0xdc, 0x99, 0x43, 0x5b, 0xe6, 0x71,
|
||||
0xb7, 0x59, 0x3b, 0x63, 0xf1, 0xef, 0xc2, 0xed, 0x39, 0xa8, 0xde, 0x3a, 0xab, 0x35, 0x9a, 0x6a,
|
||||
0x0c, 0xed, 0x00, 0x9a, 0x03, 0x78, 0x0a, 0x6a, 0xbc, 0x34, 0x90, 0x87, 0xfe, 0xf4, 0x02, 0x83,
|
||||
0x8a, 0xb0, 0x33, 0xa1, 0x9e, 0x19, 0x9d, 0x93, 0x56, 0xbd, 0x6b, 0x7c, 0x7d, 0x51, 0x3b, 0x6d,
|
||||
0xab, 0xb7, 0xd0, 0x1e, 0xec, 0x2e, 0x62, 0xed, 0x4e, 0xcd, 0xec, 0xb4, 0xbb, 0x3f, 0x6c, 0x74,
|
||||
0x4e, 0x54, 0x65, 0x2e, 0x73, 0x49, 0x38, 0x6a, 0x35, 0x3b, 0xb5, 0x46, 0xb3, 0xad, 0xc6, 0x4a,
|
||||
0x7f, 0x52, 0x20, 0x33, 0xd9, 0x4e, 0xd8, 0x3c, 0x2e, 0xda, 0x86, 0xb9, 0xaa, 0x78, 0xdb, 0xa0,
|
||||
0x4e, 0xa1, 0x49, 0xf5, 0x76, 0x00, 0x4d, 0xad, 0xd3, 0xf2, 0xb1, 0xaa, 0x4e, 0xed, 0x75, 0xe3,
|
||||
0xd4, 0xe8, 0x18, 0x75, 0x35, 0x3e, 0x1f, 0xe4, 0xb4, 0x75, 0xf4, 0xdc, 0xa8, 0xab, 0x89, 0x79,
|
||||
0x72, 0xfb, 0xa2, 0x7d, 0x6e, 0x34, 0xeb, 0x6a, 0x72, 0xde, 0xdc, 0x68, 0x36, 0x3a, 0x8d, 0xda,
|
||||
0xa9, 0x9a, 0x2a, 0xfd, 0x08, 0x52, 0x42, 0x81, 0x6c, 0xf0, 0x63, 0xa3, 0x59, 0x37, 0xcc, 0x85,
|
||||
0x54, 0x0b, 0xb0, 0x29, 0xed, 0x5f, 0x19, 0x67, 0xb5, 0x53, 0x96, 0xe7, 0x16, 0x64, 0xa5, 0x89,
|
||||
0x1b, 0x62, 0x08, 0x41, 0x5e, 0x1a, 0xea, 0x8d, 0x17, 0x86, 0xd9, 0x36, 0xd4, 0x78, 0xf5, 0x5f,
|
||||
0x49, 0xc8, 0xd5, 0x98, 0xd2, 0xdb, 0x98, 0x5c, 0xb9, 0x3d, 0x8c, 0x9e, 0xc3, 0xc6, 0x09, 0xb6,
|
||||
0x06, 0x61, 0xff, 0x2d, 0xda, 0x59, 0xda, 0x0b, 0x0d, 0xf6, 0x14, 0x2c, 0xae, 0xb1, 0xeb, 0xea,
|
||||
0xbb, 0xbf, 0xfd, 0xe3, 0xf7, 0x31, 0x40, 0xe9, 0x4a, 0x5f, 0x46, 0x38, 0x86, 0xa4, 0x89, 0x2d,
|
||||
0x7b, 0x7c, 0xe3, 0x50, 0x79, 0x1e, 0x2a, 0x8d, 0x52, 0x15, 0xc2, 0xfd, 0x9b, 0x90, 0x7e, 0x21,
|
||||
0x5f, 0x8c, 0x6b, 0x63, 0xdd, 0x5d, 0xb2, 0xb7, 0xf9, 0xdb, 0x53, 0x2f, 0xf0, 0x60, 0x59, 0x94,
|
||||
0x99, 0xbc, 0x3a, 0xd1, 0xaf, 0x15, 0xc8, 0x36, 0x68, 0x8b, 0x38, 0xe2, 0x69, 0x86, 0xd6, 0xdc,
|
||||
0x2a, 0x17, 0x9f, 0x8c, 0xc5, 0x87, 0xd7, 0xf2, 0xc4, 0x45, 0x51, 0xbf, 0xff, 0xee, 0xcf, 0x1a,
|
||||
0x40, 0xda, 0xb5, 0x86, 0x65, 0x36, 0x03, 0x9e, 0x41, 0x01, 0x6d, 0x55, 0x7c, 0xe2, 0xd0, 0x4a,
|
||||
0xd7, 0xa5, 0xe2, 0x89, 0x88, 0x2e, 0x01, 0x8e, 0x71, 0xd8, 0x22, 0xce, 0xe1, 0xb8, 0x51, 0x47,
|
||||
0xbb, 0x6b, 0x2f, 0x94, 0x8d, 0x7a, 0x71, 0xfd, 0x6d, 0x53, 0xdf, 0x5f, 0x31, 0x58, 0x0e, 0x81,
|
||||
0x18, 0xec, 0x17, 0xae, 0xfd, 0x4b, 0x36, 0x5f, 0x10, 0xf2, 0x6a, 0x11, 0x87, 0xae, 0x9b, 0xee,
|
||||
0xe2, 0x23, 0x6d, 0xdd, 0x74, 0x97, 0x9e, 0x0e, 0xfa, 0x83, 0x15, 0x19, 0x20, 0x7d, 0x53, 0x4e,
|
||||
0x97, 0x72, 0xf2, 0x81, 0x52, 0x42, 0xbf, 0x52, 0x20, 0xcd, 0x6f, 0xd4, 0xec, 0x1d, 0xfc, 0xa1,
|
||||
0xa7, 0xcc, 0xf4, 0xfa, 0x5f, 0x7c, 0x70, 0x1d, 0x6d, 0x26, 0x87, 0x2c, 0x64, 0x58, 0x0e, 0x6f,
|
||||
0x88, 0x1b, 0x62, 0x51, 0x73, 0x3d, 0x37, 0x49, 0x22, 0x1c, 0x05, 0x07, 0x4a, 0xe9, 0xf0, 0x2f,
|
||||
0xca, 0xef, 0x6a, 0xbf, 0x55, 0x50, 0x0d, 0x36, 0x79, 0xbc, 0x7d, 0x2a, 0x3a, 0x5f, 0x7f, 0x82,
|
||||
0x1e, 0xf7, 0xc3, 0x30, 0xa0, 0x07, 0x95, 0x8a, 0xe3, 0x86, 0xfd, 0xd1, 0xcb, 0x72, 0xcf, 0x1f,
|
||||
0x56, 0x7a, 0x96, 0x4f, 0x2b, 0x32, 0x81, 0x4a, 0xf0, 0xca, 0xa9, 0x70, 0xa7, 0x6a, 0xfc, 0xb3,
|
||||
0xf2, 0xb3, 0x92, 0x12, 0xab, 0xaa, 0x56, 0x10, 0x0c, 0xdc, 0x1e, 0xbf, 0x55, 0x54, 0x7e, 0x46,
|
||||
0x7d, 0x6f, 0xde, 0xe2, 0x90, 0xa0, 0x77, 0xb0, 0xc4, 0x39, 0x58, 0xe2, 0xfc, 0xa4, 0x74, 0xed,
|
||||
0x90, 0xfc, 0xdf, 0x35, 0x8c, 0xfb, 0x32, 0xc5, 0x1b, 0xfc, 0xdb, 0xff, 0x0d, 0x00, 0x00, 0xff,
|
||||
0xff, 0xd2, 0xa3, 0xeb, 0x34, 0xeb, 0x11, 0x00, 0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
|
@ -197,6 +197,64 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1CreateUserRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"user_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"first_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"last_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"nick_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"display_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"preferred_language": {
|
||||
"type": "string"
|
||||
},
|
||||
"gender": {
|
||||
"$ref": "#/definitions/v1Gender"
|
||||
},
|
||||
"email": {
|
||||
"type": "string"
|
||||
},
|
||||
"is_email_verified": {
|
||||
"type": "boolean",
|
||||
"format": "boolean"
|
||||
},
|
||||
"phone": {
|
||||
"type": "string"
|
||||
},
|
||||
"is_phone_verified": {
|
||||
"type": "boolean",
|
||||
"format": "boolean"
|
||||
},
|
||||
"country": {
|
||||
"type": "string"
|
||||
},
|
||||
"locality": {
|
||||
"type": "string"
|
||||
},
|
||||
"postal_code": {
|
||||
"type": "string"
|
||||
},
|
||||
"region": {
|
||||
"type": "string"
|
||||
},
|
||||
"street_address": {
|
||||
"type": "string"
|
||||
},
|
||||
"password": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1Gender": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
@ -321,7 +379,7 @@
|
||||
"$ref": "#/definitions/v1CreateOrgRequest"
|
||||
},
|
||||
"user": {
|
||||
"$ref": "#/definitions/v1RegisterUserRequest"
|
||||
"$ref": "#/definitions/v1CreateUserRequest"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -345,38 +403,6 @@
|
||||
],
|
||||
"default": "ORGSTATE_UNSPECIFIED"
|
||||
},
|
||||
"v1RegisterUserRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"email": {
|
||||
"type": "string"
|
||||
},
|
||||
"first_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"last_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"nick_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"display_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"preferred_language": {
|
||||
"type": "string"
|
||||
},
|
||||
"gender": {
|
||||
"$ref": "#/definitions/v1Gender"
|
||||
},
|
||||
"password": {
|
||||
"type": "string"
|
||||
},
|
||||
"org_id": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1UniqueOrgResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@ -452,6 +478,10 @@
|
||||
},
|
||||
"street_address": {
|
||||
"type": "string"
|
||||
},
|
||||
"sequence": {
|
||||
"type": "string",
|
||||
"format": "uint64"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -2,21 +2,38 @@ package grpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
)
|
||||
|
||||
func (s *Server) GetOrgByID(ctx context.Context, orgID *OrgID) (_ *Org, err error) {
|
||||
return nil, errors.ThrowUnimplemented(nil, "GRPC-mvn3R", "Not implemented")
|
||||
org, err := s.org.OrgByID(ctx, orgID.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return orgFromModel(org), nil
|
||||
}
|
||||
|
||||
func (s *Server) SearchOrgs(ctx context.Context, request *OrgSearchRequest) (_ *OrgSearchResponse, err error) {
|
||||
return nil, errors.ThrowUnimplemented(nil, "GRPC-Po9Hd", "Not implemented")
|
||||
orgs, err := s.org.SearchOrgs(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &OrgSearchResponse{Result: orgsFromModel(orgs),
|
||||
Limit: request.Limit,
|
||||
Offset: request.Offset,
|
||||
// TotalResult: , TODO: total result from search
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) IsOrgUnique(ctx context.Context, request *UniqueOrgRequest) (org *UniqueOrgResponse, err error) {
|
||||
return nil, errors.ThrowUnimplemented(nil, "GRPC-0p6Fw", "Not implemented")
|
||||
isUnique, err := s.org.IsOrgUnique(ctx, request.Name, request.Domain)
|
||||
|
||||
return &UniqueOrgResponse{IsUnique: isUnique}, err
|
||||
}
|
||||
|
||||
func (s *Server) SetUpOrg(ctx context.Context, orgSetUp *OrgSetUpRequest) (_ *OrgSetUpResponse, err error) {
|
||||
return nil, errors.ThrowUnimplemented(nil, "GRPC-hdj5D", "Not implemented")
|
||||
setUp, err := s.org.SetUpOrg(ctx, setUpRequestToModel(orgSetUp))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return setUpOrgResponseFromModel(setUp), err
|
||||
}
|
||||
|
181
pkg/admin/api/grpc/org_converter.go
Normal file
181
pkg/admin/api/grpc/org_converter.go
Normal file
@ -0,0 +1,181 @@
|
||||
package grpc
|
||||
|
||||
import (
|
||||
"github.com/caos/logging"
|
||||
admin_model "github.com/caos/zitadel/internal/admin/model"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
func setUpRequestToModel(setUp *OrgSetUpRequest) *admin_model.SetupOrg {
|
||||
return &admin_model.SetupOrg{
|
||||
Org: orgCreateRequestToModel(setUp.Org),
|
||||
User: userCreateRequestToModel(setUp.User),
|
||||
}
|
||||
}
|
||||
|
||||
func orgCreateRequestToModel(org *CreateOrgRequest) *org_model.Org {
|
||||
return &org_model.Org{
|
||||
Domain: org.Domain,
|
||||
Name: org.Name,
|
||||
}
|
||||
}
|
||||
|
||||
func userCreateRequestToModel(user *CreateUserRequest) *usr_model.User {
|
||||
preferredLanguage, err := language.Parse(user.PreferredLanguage)
|
||||
logging.Log("GRPC-30hwz").OnError(err).Debug("unable to parse language")
|
||||
|
||||
return &usr_model.User{
|
||||
Profile: &usr_model.Profile{
|
||||
UserName: user.UserName,
|
||||
DisplayName: user.DisplayName,
|
||||
FirstName: user.FirstName,
|
||||
LastName: user.LastName,
|
||||
NickName: user.NickName,
|
||||
PreferredLanguage: preferredLanguage,
|
||||
Gender: genderToModel(user.Gender),
|
||||
},
|
||||
Password: &usr_model.Password{
|
||||
SecretString: user.Password,
|
||||
},
|
||||
Email: &usr_model.Email{
|
||||
EmailAddress: user.Email,
|
||||
IsEmailVerified: user.IsEmailVerified,
|
||||
},
|
||||
Phone: &usr_model.Phone{
|
||||
IsPhoneVerified: user.IsPhoneVerified,
|
||||
PhoneNumber: user.Phone,
|
||||
},
|
||||
Address: &usr_model.Address{
|
||||
Country: user.Country,
|
||||
Locality: user.Locality,
|
||||
PostalCode: user.PostalCode,
|
||||
Region: user.Region,
|
||||
StreetAddress: user.StreetAddress,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func setUpOrgResponseFromModel(setUp *admin_model.SetupOrg) *OrgSetUpResponse {
|
||||
return &OrgSetUpResponse{
|
||||
Org: orgFromModel(setUp.Org),
|
||||
User: userFromModel(setUp.User),
|
||||
}
|
||||
}
|
||||
|
||||
func orgsFromModel(orgs []*org_model.Org) []*Org {
|
||||
result := make([]*Org, len(orgs))
|
||||
for i, org := range orgs {
|
||||
result[i] = orgFromModel(org)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
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 userFromModel(user *usr_model.User) *User {
|
||||
creationDate, err := ptypes.TimestampProto(user.CreationDate)
|
||||
logging.Log("GRPC-8duwe").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
changeDate, err := ptypes.TimestampProto(user.ChangeDate)
|
||||
logging.Log("GRPC-ckoe3d").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
converted := &User{
|
||||
Id: user.AggregateID,
|
||||
State: userStateFromModel(user.State),
|
||||
CreationDate: creationDate,
|
||||
ChangeDate: changeDate,
|
||||
Sequence: user.Sequence,
|
||||
UserName: user.UserName,
|
||||
FirstName: user.FirstName,
|
||||
LastName: user.LastName,
|
||||
DisplayName: user.DisplayName,
|
||||
NickName: user.NickName,
|
||||
PreferredLanguage: user.PreferredLanguage.String(),
|
||||
Gender: genderFromModel(user.Gender),
|
||||
}
|
||||
if user.Email != nil {
|
||||
converted.Email = user.EmailAddress
|
||||
converted.IsEmailVerified = user.IsEmailVerified
|
||||
}
|
||||
if user.Phone != nil {
|
||||
converted.Phone = user.PhoneNumber
|
||||
converted.IsPhoneVerified = user.IsPhoneVerified
|
||||
}
|
||||
if user.Address != nil {
|
||||
converted.Country = user.Country
|
||||
converted.Locality = user.Locality
|
||||
converted.PostalCode = user.PostalCode
|
||||
converted.Region = user.Region
|
||||
converted.StreetAddress = user.StreetAddress
|
||||
}
|
||||
return converted
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
func genderFromModel(gender usr_model.Gender) Gender {
|
||||
switch gender {
|
||||
case usr_model.GENDER_FEMALE:
|
||||
return Gender_GENDER_FEMALE
|
||||
case usr_model.GENDER_MALE:
|
||||
return Gender_GENDER_MALE
|
||||
case usr_model.GENDER_DIVERSE:
|
||||
return Gender_GENDER_DIVERSE
|
||||
default:
|
||||
return Gender_GENDER_UNSPECIFIED
|
||||
}
|
||||
}
|
||||
|
||||
func genderToModel(gender Gender) usr_model.Gender {
|
||||
switch gender {
|
||||
case Gender_GENDER_FEMALE:
|
||||
return usr_model.GENDER_FEMALE
|
||||
case Gender_GENDER_MALE:
|
||||
return usr_model.GENDER_MALE
|
||||
case Gender_GENDER_DIVERSE:
|
||||
return usr_model.GENDER_DIVERSE
|
||||
default:
|
||||
return usr_model.GENDER_UNDEFINED
|
||||
}
|
||||
}
|
||||
|
||||
func userStateFromModel(state usr_model.UserState) UserState {
|
||||
switch state {
|
||||
case usr_model.USERSTATE_ACTIVE:
|
||||
return UserState_USERSTATE_ACTIVE
|
||||
case usr_model.USERSTATE_INACTIVE:
|
||||
return UserState_USERSTATE_INACTIVE
|
||||
case usr_model.USERSTATE_LOCKED:
|
||||
return UserState_USERSTATE_LOCKED
|
||||
default:
|
||||
return UserState_USERSTATE_UNSPECIFIED
|
||||
}
|
||||
}
|
@ -2,17 +2,18 @@ package grpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/golang/protobuf/ptypes/empty"
|
||||
pb_struct "github.com/golang/protobuf/ptypes/struct"
|
||||
)
|
||||
|
||||
func (s *Server) Healthz(_ context.Context, e *empty.Empty) (*empty.Empty, error) {
|
||||
return nil, errors.ThrowUnimplemented(nil, "GRPC-ruc8e", "Not implemented")
|
||||
return &empty.Empty{}, nil
|
||||
}
|
||||
|
||||
func (s *Server) Ready(ctx context.Context, e *empty.Empty) (*empty.Empty, error) {
|
||||
return nil, errors.ThrowUnimplemented(nil, "GRPC-bw3vR", "Not implemented")
|
||||
return &empty.Empty{}, s.repo.Health(ctx)
|
||||
}
|
||||
|
||||
func (s *Server) Validate(ctx context.Context, _ *empty.Empty) (*pb_struct.Struct, error) {
|
||||
|
@ -1,28 +1,32 @@
|
||||
package grpc
|
||||
|
||||
import (
|
||||
grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
|
||||
"google.golang.org/grpc"
|
||||
|
||||
admin_auth "github.com/caos/zitadel/internal/admin/auth"
|
||||
"github.com/caos/zitadel/internal/admin/repository"
|
||||
"github.com/caos/zitadel/internal/api/auth"
|
||||
grpc_util "github.com/caos/zitadel/internal/api/grpc"
|
||||
"github.com/caos/zitadel/internal/api/grpc/server/middleware"
|
||||
grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
var _ AdminServiceServer = (*Server)(nil)
|
||||
|
||||
type Config struct {
|
||||
Port string
|
||||
SearchLimit int
|
||||
}
|
||||
|
||||
type Server struct {
|
||||
port string
|
||||
searchLimit int
|
||||
port string
|
||||
org repository.OrgRepository
|
||||
verifier auth.TokenVerifier
|
||||
authZ auth.Config
|
||||
repo repository.Repository
|
||||
}
|
||||
|
||||
func StartServer(conf grpc_util.ServerConfig) *Server {
|
||||
func StartServer(conf grpc_util.ServerConfig, authZ auth.Config, repo repository.Repository) *Server {
|
||||
return &Server{
|
||||
port: conf.Port,
|
||||
port: conf.Port,
|
||||
org: repo,
|
||||
repo: repo,
|
||||
authZ: authZ,
|
||||
verifier: admin_auth.Start(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,6 +40,7 @@ func (s *Server) GRPCServer() (*grpc.Server, error) {
|
||||
grpc.UnaryInterceptor(
|
||||
grpc_middleware.ChainUnaryServer(
|
||||
middleware.ErrorHandler(),
|
||||
AdminService_Authorization_Interceptor(s.verifier, &s.authZ),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
@ -164,7 +164,7 @@ enum OrgSearchMethod {
|
||||
|
||||
message OrgSetUpRequest {
|
||||
CreateOrgRequest org = 1;
|
||||
RegisterUserRequest user = 2;
|
||||
CreateUserRequest user = 2;
|
||||
}
|
||||
|
||||
message OrgSetUpResponse {
|
||||
@ -172,16 +172,24 @@ message OrgSetUpResponse {
|
||||
User user = 2;
|
||||
}
|
||||
|
||||
message RegisterUserRequest {
|
||||
string email = 1 [(validate.rules).string.email = true];
|
||||
string first_name = 2 [(validate.rules).string.min_len = 1];
|
||||
string last_name = 3 [(validate.rules).string.min_len = 1];
|
||||
string nick_name = 4;
|
||||
string display_name = 5;
|
||||
string preferred_language = 6;
|
||||
message CreateUserRequest {
|
||||
string user_name = 1 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
||||
string first_name = 2 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
||||
string last_name = 3 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
||||
string nick_name = 4 [(validate.rules).string = {max_len: 200}];
|
||||
string display_name = 5 [(validate.rules).string = {max_len: 200}];
|
||||
string preferred_language = 6 [(validate.rules).string = {max_len: 200}];
|
||||
Gender gender = 7;
|
||||
string password = 8 [(validate.rules).string.min_len = 1];
|
||||
string org_id = 9 [(validate.rules).string.min_len = 1];
|
||||
string email = 8 [(validate.rules).string = {min_len: 1, max_len: 200, email: true}];
|
||||
bool is_email_verified = 9;
|
||||
string phone = 11 [(validate.rules).string = {max_len: 20}];
|
||||
bool is_phone_verified = 12;
|
||||
string country = 13 [(validate.rules).string = {max_len: 200}];
|
||||
string locality = 14 [(validate.rules).string = {max_len: 200}];
|
||||
string postal_code = 15 [(validate.rules).string = {max_len: 200}];
|
||||
string region = 16 [(validate.rules).string = {max_len: 200}];
|
||||
string street_address = 17 [(validate.rules).string = {max_len: 200}];
|
||||
string password = 18 [(validate.rules).string = {max_len: 72}];
|
||||
}
|
||||
|
||||
message User {
|
||||
@ -205,6 +213,7 @@ message User {
|
||||
string postal_code = 18;
|
||||
string region = 19;
|
||||
string street_address = 20;
|
||||
uint64 sequence = 21;
|
||||
}
|
||||
|
||||
enum UserState {
|
||||
|
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")
|
||||
}
|
||||
|
43
pkg/management/api/grpc/org_converter.go
Normal file
43
pkg/management/api/grpc/org_converter.go
Normal 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
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
|
37
pkg/management/api/grpc/org_member_converter.go
Normal file
37
pkg/management/api/grpc/org_member_converter.go
Normal file
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user