diff --git a/cmd/zitadel/setup.yaml b/cmd/zitadel/setup.yaml
index 379a71f040..45b954926d 100644
--- a/cmd/zitadel/setup.yaml
+++ b/cmd/zitadel/setup.yaml
@@ -29,7 +29,7 @@ SetUp:
DefaultLoginPolicy:
AllowUsernamePassword: true
AllowRegister: true
- AllowExternalIdp: true
+ AllowExternalIdp: true
Orgs:
- Name: 'Global'
Domain: 'global.caos.ch'
@@ -90,4 +90,8 @@ SetUp:
ShowLockOutFailures: false
Step5:
DefaultOrgIAMPolicy:
- UserLoginMustBeDomain: true
\ No newline at end of file
+ UserLoginMustBeDomain: true
+ Step6:
+ DefaultLabelPolicy:
+ PrimaryColor: '#222324'
+ SecondaryColor: '#ffffff'
diff --git a/go.mod b/go.mod
index 8901430692..fe5dd596e5 100644
--- a/go.mod
+++ b/go.mod
@@ -58,4 +58,5 @@ require (
google.golang.org/grpc v1.32.0
google.golang.org/protobuf v1.25.0
gopkg.in/square/go-jose.v2 v2.5.1
+ gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c // indirect
)
diff --git a/go.sum b/go.sum
index 99b2f75be5..097b61fe59 100644
--- a/go.sum
+++ b/go.sum
@@ -22,26 +22,32 @@ cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNF
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
+cloud.google.com/go/bigquery v1.8.0 h1:PQcPefKFdaIzjQFbiyOgAqyx8q5djaE7x9Sqe712DPA=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
+cloud.google.com/go/datastore v1.1.0 h1:/May9ojXjRkPBNVrq+oWLqmWCkr4OU5uRY29bu0mRyQ=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
+cloud.google.com/go/pubsub v1.3.1 h1:ukjixP1wl0LpnZ6LWtZJ0mX5tBmjp1f8Sqer8Z2OMUU=
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
+cloud.google.com/go/storage v1.10.0 h1:STgFzyU5/8miMl0//zKh2aQeTyeaUH3WN9bSUiJ09bA=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
contrib.go.opencensus.io/exporter/stackdriver v0.13.4 h1:ksUxwH3OD5sxkjzEqGxNTl+Xjsmu3BnC/300MhSVTSc=
contrib.go.opencensus.io/exporter/stackdriver v0.13.4/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc=
+dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9 h1:VpgP7xuJadIUuKccphEpTJnWhS2jkQyMt6Y7pJCD7fY=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 h1:1BDTz0u9nC3//pOCMdNH+CiXJVYJh5UQNCOBG7jbELc=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
@@ -52,6 +58,7 @@ github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3Q
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60=
github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
+github.com/PuerkitoBio/goquery v1.5.1 h1:PSPBGne8NIUWw+/7vFBV+kG2J/5MOjbzc7154OaKCSE=
github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
github.com/VictoriaMetrics/fastcache v1.5.7 h1:4y6y0G8PRzszQUYIQHHssv/jgPHAb5qQuuDNdCbyAgw=
github.com/VictoriaMetrics/fastcache v1.5.7/go.mod h1:ptDBkNMQI4RtmVo8VS/XwRY6RoTu1dAWCbrk+6WsEM8=
@@ -60,15 +67,21 @@ github.com/ajstarks/svgo v0.0.0-20200725142600-7a3c8b57fecb/go.mod h1:K08gAheRH3
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
github.com/allegro/bigcache v1.2.1 h1:hg1sY1raCwic3Vnsvje6TT7/pnZba83LeFck5NrFKSc=
github.com/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
+github.com/andybalholm/cascadia v1.1.0 h1:BuuO6sSfQNFRu1LppgbD25Hr2vLYW25JvxHs5zzsLTo=
github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
+github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
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.34.24 h1:eTBgLksUJNLk5EwBl/lUweXjBZHbxvfcvqUxAJu7Fqg=
github.com/aws/aws-sdk-go v1.34.24/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 h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI=
+github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
github.com/caos/logging v0.0.2 h1:ebg5C/HN0ludYR+WkvnFjwSExF4wvyiWPyWGcKMYsoo=
+github.com/caos/logging v0.0.2 h1:ebg5C/HN0ludYR+WkvnFjwSExF4wvyiWPyWGcKMYsoo=
+github.com/caos/logging v0.0.2/go.mod h1:9LKiDE2ChuGv6CHYif/kiugrfEXu9AwDiFWSreX7Wp0=
github.com/caos/logging v0.0.2/go.mod h1:9LKiDE2ChuGv6CHYif/kiugrfEXu9AwDiFWSreX7Wp0=
github.com/caos/oidc v0.12.1 h1:ZNnviScAedQ6W9SV3k58c/mJCR3NI9KWUW//TjZ74T0=
github.com/caos/oidc v0.12.1/go.mod h1:R9UKITZmSo5vNhSLUYcTDH8pAaV2xwPASXg8wpEs2xQ=
@@ -79,16 +92,24 @@ github.com/census-instrumentation/opencensus-proto v0.3.0 h1:t/LhUZLVitR1Ow2YOnd
github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
+github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
+github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
+github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f h1:WBZRG4aNOuI15bLRrCgN8fCq8E5Xuty6jGbmSNEvSsU=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
+github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
github.com/cockroachdb/cockroach-go/v2 v2.0.8 h1:50C/7ptrrfdxDccCjDU0xsdeBca+S0/AYW4Mo8RyzFE=
github.com/cockroachdb/cockroach-go/v2 v2.0.8/go.mod h1:nkf7rUmgPdawp3EwRjXIumihI2AYg9usGNWbJ2hsJqI=
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 h1:JOrtw2xFKzlg+cbHpyrpLDmnN1HqhBfnX7WDiW7eG2c=
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/creack/pty v1.1.7 h1:6pwm8kMQKCmgUg0ZHTm5+/YvRK0s3THD/28+T6/kk4A=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
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=
@@ -99,6 +120,7 @@ github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd h1:83Wprp6RO
github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
+github.com/envoyproxy/go-control-plane v0.9.4 h1:rEvIZUSZ3fx39WIi3JkQqQBitGwpELBIYWeBVh6wn+E=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
@@ -110,10 +132,14 @@ github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8S
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
+github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1 h1:QbL/5oDUmRBzO9/Z7Seo6zf912W/a6Sr4Eu0G/3Jho0=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
+github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4 h1:WtGNWLvXpe6ZudgnXrq0barxBImvnnJoMEhXAzcbM0I=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
+github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
+github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
@@ -123,7 +149,9 @@ github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LB
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE=
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
+github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
@@ -162,6 +190,7 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
@@ -176,9 +205,13 @@ github.com/google/go-cmp v0.5.1 h1:JFrFEBb2xKufg6XkJsJr+WbKb4FQlURi5RUcBveYu9k=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-github/v31 v31.0.0 h1:JJUxlP9lFK+ziXKimTCprajMApV1ecWD4NB6CCb0plo=
github.com/google/go-github/v31 v31.0.0/go.mod h1:NQPZol8/1sMoWYGN2yaALIBytu17gAWfhbweiEed3pM=
+github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
+github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
+github.com/google/martian/v3 v3.0.0 h1:pMen7vLs8nvgEYhywH3KDWJIJTeEr2ULsVWHWYHQyBs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
@@ -186,7 +219,9 @@ github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hf
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/pprof v0.0.0-20200708004538-1a94d8640e99 h1:Ak8CrdlwwXwAZxzS66vgPt4U8yUZX7JwLvVR58FN5jM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@@ -199,6 +234,8 @@ github.com/gorilla/csrf v1.7.0/go.mod h1:+a/4tCmqhG6/w4oafeAZ9pEa3/NZOWYVbD9fV0F
github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4=
github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
+github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
+github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/schema v1.2.0 h1:YufUaxZYCKGFuAq3c96BOhjgd5nmXiOY9NGzF247Tsc=
github.com/gorilla/schema v1.2.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU=
@@ -206,49 +243,63 @@ 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.2 h1:FlFbCRLd5Jr4iYXZufAvgWN6Ao0JrI5chLINnUXDDr0=
github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI=
-github.com/grpc-ecosystem/grpc-gateway v1.14.8 h1:hXClj+iFpmLM8i3lkO6i4Psli4P2qObQuQReiII26U8=
-github.com/grpc-ecosystem/grpc-gateway v1.14.8/go.mod h1:NZE8t6vs6TnwLL/ITkaK8W3ecMLGAbh2jXTclvpiwYo=
github.com/grpc-ecosystem/grpc-gateway v1.15.2 h1:HC+hWRWf+v5zTMPyoaYTKIJih+4sd4XRWmj0qlG87Co=
github.com/grpc-ecosystem/grpc-gateway v1.15.2/go.mod h1:vO11I9oWA+KsxmfFQPhLnnIb1VDE24M+pdxZFiuZcA8=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw=
github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
+github.com/iancoleman/strcase v0.0.0-20180726023541-3605ed457bf7 h1:ux/56T2xqZO/3cP1I2F86qpeoYPCOzk+KF/UH/Ar+lk=
github.com/iancoleman/strcase v0.0.0-20180726023541-3605ed457bf7/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE=
+github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6 h1:UDMh68UUwekSh5iP2OMhRRZJiiBccgV7axzUG8vi56c=
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.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA=
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/inconshreveable/log15 v0.0.0-20200109203555-b30bc20e4fd1 h1:KUDFlmBg2buRWNzIcwLlKvfcnujcHQRQ1As1LoaCLAM=
github.com/inconshreveable/log15 v0.0.0-20200109203555-b30bc20e4fd1/go.mod h1:cOaXtrgN4ScfRrD9Bre7U1thNq5RtJ8ZoP4iXVGRj6o=
+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/pgtype v1.3.0 h1:l8JvKrby3RI7Kg3bYEeU9TA4vqC38QDpFCfcrC7KuN0=
github.com/jackc/pgtype v1.3.0/go.mod h1:b0JqxHvPmljG+HQ5IsvQ0yqeSi4nGcDTVjFoiLDb0Ik=
+github.com/jackc/pgx v3.6.2+incompatible h1:2zP5OD7kiyR3xzRYMhOcXVvkDZsImVXfj+yIyTQf3/o=
github.com/jackc/pgx v3.6.2+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I=
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/pgx/v4 v4.6.0 h1:Fh0O9GdlG4gYpjpwOqjdEodJUQM9jzN3Hdv7PN0xmm0=
github.com/jackc/pgx/v4 v4.6.0/go.mod h1:vPh43ZzxijXUVJ+t/EmXBtFmbFVO72cuneCT9oAlxAg=
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/jackc/puddle v1.1.0 h1:musOWczZC/rSbqut475Vfcczg7jJsdUQf0D6oKPLgNU=
github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jinzhu/gorm v1.9.12/go.mod h1:vhTjlKSJUTWNtcbQtrMBFCxy7eXTzeCAzfL5fBZT/Qs=
github.com/jinzhu/gorm v1.9.16 h1:+IyIjPEABKRpsu/F8OvDPy9fyQlgsg2luMV2ZIH5i5o=
@@ -261,8 +312,10 @@ github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5i
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.3.0 h1:OS12ieG61fsCg5+qLJ+SsW9NicxNkg3b25OyT2yCeUc=
github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik=
+github.com/jmoiron/sqlx v1.2.0 h1:41Ip0zITnmWNR/vHV+S4m+VoUivnWY5E4OJfLZjCJMA=
github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
+github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/kevinburke/go-types v0.0.0-20200309064045-f2d4aea18a7a h1:Z7+SSApKiwPjNic+NF9+j7h657Uyvdp/jA3iTKhpj4E=
github.com/kevinburke/go-types v0.0.0-20200309064045-f2d4aea18a7a/go.mod h1:/Pk5i/SqYdYv1cie5wGwoZ4P6TpgMi+Yf58mtJSHdOw=
@@ -272,16 +325,21 @@ github.com/kevinburke/rest v0.0.0-20200429221318-0d2892b400f8 h1:KpuDJTaTPQAyWqE
github.com/kevinburke/rest v0.0.0-20200429221318-0d2892b400f8/go.mod h1:pD+iEcdAGVXld5foVN4e24zb/6fnb60tgZPZ3P/3T/I=
github.com/kevinburke/twilio-go v0.0.0-20200810163702-320748330fac h1:qQ7NAZEHpTyDfmZBH79KEiH3OK47Z+KvYVSR4sS3650=
github.com/kevinburke/twilio-go v0.0.0-20200810163702-320748330fac/go.mod h1:Fm9alkN1/LPVY1eqD/psyMwPWE4VWl4P01/nTYZKzBk=
+github.com/kisielk/errcheck v1.1.0 h1:ZqfnKyx9KGpRcW04j5nnPDgRgoXUeLh2YFBeFzphcA0=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
+github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
+github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
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 h1:AkaSdXYQOWeaO3neb8EM634ahkXXe3jYbVh/F9lq+GI=
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=
@@ -292,6 +350,7 @@ github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.4.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.8.0 h1:9xohqzkUwzR4Ga4ivdTcawVS89YSDVxXMa3xJX3cGzg=
github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
+github.com/lyft/protoc-gen-star v0.5.1 h1:sImehRT+p7lW9n6R7MQc5hVgzWGEkDVZU4AsBQ4Isu8=
github.com/lyft/protoc-gen-star v0.5.1/go.mod h1:9toiA3cC7z5uVbODF7kEQ91Xn7XNFkVUl+SrEe+ZORU=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
@@ -318,28 +377,37 @@ github.com/nicksnyder/go-i18n/v2 v2.1.1 h1:ATCOanRDlrfKVB4WHAdJnLEqZtDmKYsweqsOU
github.com/nicksnyder/go-i18n/v2 v2.1.1/go.mod h1:d++QJC9ZVf7pa48qrsRWhMJ5pSHIPmS3OLqK1niyLxs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
+github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/sftp v1.10.1 h1:VasscCm72135zRysgrJDKsntdmPN+OuU3+nnHYA9wyc=
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pquerna/otp v1.2.0 h1:/A3+Jn+cagqayeR3iHs/L62m5ue7710D35zl1zJ1kok=
github.com/pquerna/otp v1.2.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
+github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ=
github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc=
+github.com/rogpeppe/fastuuid v1.2.0 h1:Ppwyp6VYCF1nvBTXL3trRso7mXMlRrw9ooo375wvi2s=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
+github.com/rogpeppe/go-internal v1.3.0 h1:RR9dF3JtopPvtkroDZuVD7qquD0bnHlKSqaQhgwt8yk=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
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 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc=
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 h1:uPRuwkWF4J6fGsJ2R0Gn2jB1EQiav9k3S6CSdygQJXY=
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
+github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
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/shopspring/decimal v0.0.0-20200419222939-1884f454f8ea h1:jaXWVFZ98/ihXniiDzqNXQgMSgklX4kjfDWZTE3ZtdU=
github.com/shopspring/decimal v0.0.0-20200419222939-1884f454f8ea/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
@@ -349,10 +417,12 @@ github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic
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/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4=
+github.com/spf13/afero v1.3.4 h1:8q6vk3hthlpb2SouZcnBVKboxWQWMDNF38bwholZrJc=
github.com/spf13/afero v1.3.4/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
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=
@@ -368,8 +438,10 @@ github.com/ttacon/libphonenumber v1.1.0 h1:tC6kE4t8UI4OqQVQjW5q8gSWhG2wnY5moEpSE
github.com/ttacon/libphonenumber v1.1.0/go.mod h1:E0TpmdVMq5dyVlQ7oenAkhsLu86OkUl+yR4OAxyEg/M=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.1.32 h1:5tjfNdR2ki3yYQ842+eX2sQHeiwpKJ0RnHO4IYOc4V8=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/zenazn/goji v0.9.0 h1:RSQQAbXGArQ0dIDEq+PI6WqN6if+5KHu6x2Cx/GXLTQ=
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=
@@ -381,9 +453,12 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.5 h1:dntmOdLpSpHlVqbW5Eay97DelsZHe+55D+xC6i0dDS0=
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
+go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
+go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
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 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
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=
@@ -410,9 +485,11 @@ golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
+golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6 h1:QE6XYQK6naiK1EPAe1g/ILLxN5RBoH5xkJk3CqlMI/Y=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
+golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
@@ -427,6 +504,7 @@ golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPI
golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
+golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
@@ -543,6 +621,7 @@ golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -688,7 +767,6 @@ google.golang.org/grpc v1.30.0 h1:M5a8xTlYTxwMn5ZFkwhRabsygDY5G8TYLyQDBxJNAxE=
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0 h1:T7P4R73V3SSDPhH7WW7ATbfViLtmamH0DKrP3f9AuDI=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
-google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.32.0 h1:zWTV+LMdc3kaiJMSTOFz2UgSBgx8RNQoTGiZu3fR9S0=
google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
@@ -710,7 +788,9 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U=
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
+gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec h1:RlWgLqCMMIYYEVcAR5MDsuHlVkaIPDAF+5Dehzg8L5A=
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w=
gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
@@ -722,6 +802,8 @@ gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c h1:grhR+C34yXImVGp7EzNk+DTIk+323eIUWOmEevy6bDo=
+gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
@@ -729,7 +811,9 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
+honnef.co/go/tools v0.0.1-2020.1.4 h1:UoveltGrhghAA7ePc+e+QYDHXrBps2PqFZiHkGR/xK8=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
+rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0 h1:9JKUTTIUgS6kzR9mK1YuGKv6Nl+DijDNIc0ghT58FaY=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
diff --git a/internal/admin/repository/eventsourcing/eventstore/iam.go b/internal/admin/repository/eventsourcing/eventstore/iam.go
index 065c2bea63..4144e62fd7 100644
--- a/internal/admin/repository/eventsourcing/eventstore/iam.go
+++ b/internal/admin/repository/eventsourcing/eventstore/iam.go
@@ -2,6 +2,8 @@ package eventstore
import (
"context"
+ "strings"
+
"github.com/caos/logging"
admin_view "github.com/caos/zitadel/internal/admin/repository/eventsourcing/view"
"github.com/caos/zitadel/internal/config/systemdefaults"
@@ -11,7 +13,6 @@ import (
org_es "github.com/caos/zitadel/internal/org/repository/eventsourcing"
usr_model "github.com/caos/zitadel/internal/user/model"
usr_es "github.com/caos/zitadel/internal/user/repository/eventsourcing"
- "strings"
iam_model "github.com/caos/zitadel/internal/iam/model"
iam_es "github.com/caos/zitadel/internal/iam/repository/eventsourcing"
@@ -173,6 +174,24 @@ func (repo *IAMRepository) SearchIDPConfigs(ctx context.Context, request *iam_mo
return result, nil
}
+func (repo *IAMRepository) GetDefaultLabelPolicy(ctx context.Context) (*iam_model.LabelPolicyView, error) {
+ policy, err := repo.View.LabelPolicyByAggregateID(repo.SystemDefaults.IamID)
+ if err != nil {
+ return nil, err
+ }
+ return iam_es_model.LabelPolicyViewToModel(policy), err
+}
+
+func (repo *IAMRepository) AddDefaultLabelPolicy(ctx context.Context, policy *iam_model.LabelPolicy) (*iam_model.LabelPolicy, error) {
+ policy.AggregateID = repo.SystemDefaults.IamID
+ return repo.IAMEventstore.AddLabelPolicy(ctx, policy)
+}
+
+func (repo *IAMRepository) ChangeDefaultLabelPolicy(ctx context.Context, policy *iam_model.LabelPolicy) (*iam_model.LabelPolicy, error) {
+ policy.AggregateID = repo.SystemDefaults.IamID
+ return repo.IAMEventstore.ChangeLabelPolicy(ctx, policy)
+}
+
func (repo *IAMRepository) GetDefaultLoginPolicy(ctx context.Context) (*iam_model.LoginPolicyView, error) {
policy, err := repo.View.LoginPolicyByAggregateID(repo.SystemDefaults.IamID)
if err != nil {
diff --git a/internal/admin/repository/eventsourcing/handler/handler.go b/internal/admin/repository/eventsourcing/handler/handler.go
index bf32438ad2..31115d9878 100644
--- a/internal/admin/repository/eventsourcing/handler/handler.go
+++ b/internal/admin/repository/eventsourcing/handler/handler.go
@@ -1,9 +1,10 @@
package handler
import (
+ "time"
+
"github.com/caos/zitadel/internal/config/systemdefaults"
iam_event "github.com/caos/zitadel/internal/iam/repository/eventsourcing"
- "time"
"github.com/caos/zitadel/internal/admin/repository/eventsourcing/view"
"github.com/caos/zitadel/internal/config/types"
@@ -38,6 +39,7 @@ func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, ev
&IamMember{handler: handler{view, bulkLimit, configs.cycleDuration("IamMember"), errorCount},
userEvents: repos.UserEvents},
&IDPConfig{handler: handler{view, bulkLimit, configs.cycleDuration("IDPConfig"), errorCount}},
+ &LabelPolicy{handler: handler{view, bulkLimit, configs.cycleDuration("LabelPolicy"), errorCount}},
&LoginPolicy{handler: handler{view, bulkLimit, configs.cycleDuration("LoginPolicy"), errorCount}},
&IDPProvider{handler: handler{view, bulkLimit, configs.cycleDuration("LoginPolicy"), errorCount},
systemDefaults: defaults, iamEvents: repos.IamEvents, orgEvents: repos.OrgEvents},
diff --git a/internal/admin/repository/eventsourcing/handler/label_policy.go b/internal/admin/repository/eventsourcing/handler/label_policy.go
new file mode 100644
index 0000000000..5226b5e3dd
--- /dev/null
+++ b/internal/admin/repository/eventsourcing/handler/label_policy.go
@@ -0,0 +1,66 @@
+package handler
+
+import (
+ "github.com/caos/logging"
+
+ "github.com/caos/zitadel/internal/eventstore/models"
+ es_models "github.com/caos/zitadel/internal/eventstore/models"
+ "github.com/caos/zitadel/internal/eventstore/spooler"
+ "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
+ iam_model "github.com/caos/zitadel/internal/iam/repository/view/model"
+)
+
+type LabelPolicy struct {
+ handler
+}
+
+const (
+ labelPolicyTable = "adminapi.label_policies"
+)
+
+func (m *LabelPolicy) ViewModel() string {
+ return labelPolicyTable
+}
+
+func (m *LabelPolicy) EventQuery() (*models.SearchQuery, error) {
+ sequence, err := m.view.GetLatestLabelPolicySequence()
+ if err != nil {
+ return nil, err
+ }
+ return es_models.NewSearchQuery().
+ AggregateTypeFilter(model.IAMAggregate).
+ LatestSequenceFilter(sequence.CurrentSequence), nil
+}
+
+func (m *LabelPolicy) Reduce(event *models.Event) (err error) {
+ switch event.AggregateType {
+ case model.IAMAggregate:
+ err = m.processLabelPolicy(event)
+ }
+ return err
+}
+
+func (m *LabelPolicy) processLabelPolicy(event *models.Event) (err error) {
+ policy := new(iam_model.LabelPolicyView)
+ switch event.Type {
+ case model.LabelPolicyAdded:
+ err = policy.AppendEvent(event)
+ case model.LabelPolicyChanged:
+ policy, err = m.view.LabelPolicyByAggregateID(event.AggregateID)
+ if err != nil {
+ return err
+ }
+ err = policy.AppendEvent(event)
+ default:
+ return m.view.ProcessedLabelPolicySequence(event.Sequence)
+ }
+ if err != nil {
+ return err
+ }
+ return m.view.PutLabelPolicy(policy, policy.Sequence)
+}
+
+func (m *LabelPolicy) OnError(event *models.Event, err error) error {
+ logging.LogWithFields("SPOOL-Wj8sf", "id", event.AggregateID).WithError(err).Warn("something went wrong in label policy handler")
+ return spooler.HandleError(event, err, m.view.GetLatestLabelPolicyFailedEvent, m.view.ProcessedLabelPolicyFailedEvent, m.view.ProcessedLabelPolicySequence, m.errorCountUntilSkip)
+}
diff --git a/internal/admin/repository/eventsourcing/view/label_policies.go b/internal/admin/repository/eventsourcing/view/label_policies.go
new file mode 100644
index 0000000000..113859894f
--- /dev/null
+++ b/internal/admin/repository/eventsourcing/view/label_policies.go
@@ -0,0 +1,39 @@
+package view
+
+import (
+ "github.com/caos/zitadel/internal/iam/repository/view"
+ "github.com/caos/zitadel/internal/iam/repository/view/model"
+ global_view "github.com/caos/zitadel/internal/view/repository"
+)
+
+const (
+ labelPolicyTable = "adminapi.label_policies"
+)
+
+func (v *View) LabelPolicyByAggregateID(aggregateID string) (*model.LabelPolicyView, error) {
+ return view.GetLabelPolicyByAggregateID(v.Db, labelPolicyTable, aggregateID)
+}
+
+func (v *View) PutLabelPolicy(policy *model.LabelPolicyView, sequence uint64) error {
+ err := view.PutLabelPolicy(v.Db, labelPolicyTable, policy)
+ if err != nil {
+ return err
+ }
+ return v.ProcessedLabelPolicySequence(sequence)
+}
+
+func (v *View) GetLatestLabelPolicySequence() (*global_view.CurrentSequence, error) {
+ return v.latestSequence(labelPolicyTable)
+}
+
+func (v *View) ProcessedLabelPolicySequence(eventSequence uint64) error {
+ return v.saveCurrentSequence(labelPolicyTable, eventSequence)
+}
+
+func (v *View) GetLatestLabelPolicyFailedEvent(sequence uint64) (*global_view.FailedEvent, error) {
+ return v.latestFailedEvent(labelPolicyTable, sequence)
+}
+
+func (v *View) ProcessedLabelPolicyFailedEvent(failedEvent *global_view.FailedEvent) error {
+ return v.saveFailedEvent(failedEvent)
+}
diff --git a/internal/admin/repository/iam.go b/internal/admin/repository/iam.go
index c75a683812..a91181f7fc 100644
--- a/internal/admin/repository/iam.go
+++ b/internal/admin/repository/iam.go
@@ -2,6 +2,7 @@ package repository
import (
"context"
+
iam_model "github.com/caos/zitadel/internal/iam/model"
)
@@ -28,6 +29,9 @@ type IAMRepository interface {
SearchDefaultIDPProviders(ctx context.Context, request *iam_model.IDPProviderSearchRequest) (*iam_model.IDPProviderSearchResponse, error)
AddIDPProviderToLoginPolicy(ctx context.Context, provider *iam_model.IDPProvider) (*iam_model.IDPProvider, error)
RemoveIDPProviderFromLoginPolicy(ctx context.Context, provider *iam_model.IDPProvider) error
+ GetDefaultLabelPolicy(ctx context.Context) (*iam_model.LabelPolicyView, error)
+ AddDefaultLabelPolicy(ctx context.Context, policy *iam_model.LabelPolicy) (*iam_model.LabelPolicy, error)
+ ChangeDefaultLabelPolicy(ctx context.Context, policy *iam_model.LabelPolicy) (*iam_model.LabelPolicy, error)
GetDefaultPasswordComplexityPolicy(ctx context.Context) (*iam_model.PasswordComplexityPolicyView, error)
AddDefaultPasswordComplexityPolicy(ctx context.Context, policy *iam_model.PasswordComplexityPolicy) (*iam_model.PasswordComplexityPolicy, error)
diff --git a/internal/api/grpc/admin/label_policy.go b/internal/api/grpc/admin/label_policy.go
new file mode 100644
index 0000000000..1d1befa260
--- /dev/null
+++ b/internal/api/grpc/admin/label_policy.go
@@ -0,0 +1,24 @@
+package admin
+
+import (
+ "context"
+
+ "github.com/caos/zitadel/pkg/grpc/admin"
+ "github.com/golang/protobuf/ptypes/empty"
+)
+
+func (s *Server) GetDefaultLabelPolicy(ctx context.Context, _ *empty.Empty) (*admin.DefaultLabelPolicyView, error) {
+ result, err := s.iam.GetDefaultLabelPolicy(ctx)
+ if err != nil {
+ return nil, err
+ }
+ return labelPolicyViewFromModel(result), nil
+}
+
+func (s *Server) UpdateDefaultLabelPolicy(ctx context.Context, policy *admin.DefaultLabelPolicyUpdate) (*admin.DefaultLabelPolicy, error) {
+ result, err := s.iam.ChangeDefaultLabelPolicy(ctx, labelPolicyToModel(policy))
+ if err != nil {
+ return nil, err
+ }
+ return labelPolicyFromModel(result), nil
+}
diff --git a/internal/api/grpc/admin/label_policy_converter.go b/internal/api/grpc/admin/label_policy_converter.go
new file mode 100644
index 0000000000..a5e0f09745
--- /dev/null
+++ b/internal/api/grpc/admin/label_policy_converter.go
@@ -0,0 +1,45 @@
+package admin
+
+import (
+ "github.com/caos/logging"
+ iam_model "github.com/caos/zitadel/internal/iam/model"
+ "github.com/caos/zitadel/pkg/grpc/admin"
+ "github.com/golang/protobuf/ptypes"
+)
+
+func labelPolicyToModel(policy *admin.DefaultLabelPolicyUpdate) *iam_model.LabelPolicy {
+ return &iam_model.LabelPolicy{
+ PrimaryColor: policy.PrimaryColor,
+ SecondaryColor: policy.SecondaryColor,
+ }
+}
+
+func labelPolicyFromModel(policy *iam_model.LabelPolicy) *admin.DefaultLabelPolicy {
+ creationDate, err := ptypes.TimestampProto(policy.CreationDate)
+ logging.Log("ADMIN-QwQG9").OnError(err).Debug("date parse failed")
+
+ changeDate, err := ptypes.TimestampProto(policy.ChangeDate)
+ logging.Log("ADMIN-mAgcI").OnError(err).Debug("date parse failed")
+
+ return &admin.DefaultLabelPolicy{
+ PrimaryColor: policy.PrimaryColor,
+ SecondaryColor: policy.SecondaryColor,
+ CreationDate: creationDate,
+ ChangeDate: changeDate,
+ }
+}
+
+func labelPolicyViewFromModel(policy *iam_model.LabelPolicyView) *admin.DefaultLabelPolicyView {
+ creationDate, err := ptypes.TimestampProto(policy.CreationDate)
+ logging.Log("ADMIN-zMnlF").OnError(err).Debug("date parse failed")
+
+ changeDate, err := ptypes.TimestampProto(policy.ChangeDate)
+ logging.Log("ADMIN-Vhvfp").OnError(err).Debug("date parse failed")
+
+ return &admin.DefaultLabelPolicyView{
+ PrimaryColor: policy.PrimaryColor,
+ SecondaryColor: policy.SecondaryColor,
+ CreationDate: creationDate,
+ ChangeDate: changeDate,
+ }
+}
diff --git a/internal/iam/model/iam.go b/internal/iam/model/iam.go
index 894f00f350..f10b6295c2 100644
--- a/internal/iam/model/iam.go
+++ b/internal/iam/model/iam.go
@@ -12,6 +12,7 @@ const (
Step3
Step4
Step5
+ Step6
//StepCount marks the the length of possible steps (StepCount-1 == last possible step)
StepCount
)
@@ -25,6 +26,7 @@ type IAM struct {
Members []*IAMMember
IDPs []*IDPConfig
DefaultLoginPolicy *LoginPolicy
+ DefaultLabelPolicy *LabelPolicy
DefaultOrgIAMPolicy *OrgIAMPolicy
DefaultPasswordComplexityPolicy *PasswordComplexityPolicy
DefaultPasswordAgePolicy *PasswordAgePolicy
diff --git a/internal/iam/model/label_policy.go b/internal/iam/model/label_policy.go
new file mode 100644
index 0000000000..ead99759a0
--- /dev/null
+++ b/internal/iam/model/label_policy.go
@@ -0,0 +1,18 @@
+package model
+
+import (
+ "github.com/caos/zitadel/internal/eventstore/models"
+)
+
+type LabelPolicy struct {
+ models.ObjectRoot
+
+ State PolicyState
+ Default bool
+ PrimaryColor string
+ SecondaryColor string
+}
+
+func (p *LabelPolicy) IsValid() bool {
+ return p.ObjectRoot.AggregateID != ""
+}
diff --git a/internal/iam/model/label_policy_view.go b/internal/iam/model/label_policy_view.go
new file mode 100644
index 0000000000..9202680909
--- /dev/null
+++ b/internal/iam/model/label_policy_view.go
@@ -0,0 +1,48 @@
+package model
+
+import (
+ "time"
+
+ "github.com/caos/zitadel/internal/model"
+)
+
+type LabelPolicyView struct {
+ AggregateID string
+ PrimaryColor string
+ SecondaryColor string
+ Default bool
+
+ CreationDate time.Time
+ ChangeDate time.Time
+ Sequence uint64
+}
+
+type LabelPolicySearchRequest struct {
+ Offset uint64
+ Limit uint64
+ SortingColumn LabelPolicySearchKey
+ Asc bool
+ Queries []*LabelPolicySearchQuery
+}
+
+type LabelPolicySearchKey int32
+
+const (
+ LabelPolicySearchKeyUnspecified LabelPolicySearchKey = iota
+ LabelPolicySearchKeyAggregateID
+)
+
+type LabelPolicySearchQuery struct {
+ Key LabelPolicySearchKey
+ Method model.SearchMethod
+ Value interface{}
+}
+
+type LabelPolicySearchResponse struct {
+ Offset uint64
+ Limit uint64
+ TotalResult uint64
+ Result []*LabelPolicyView
+ Sequence uint64
+ Timestamp time.Time
+}
diff --git a/internal/iam/repository/eventsourcing/eventstore.go b/internal/iam/repository/eventsourcing/eventstore.go
index c1c08f0258..cd1b3794a5 100644
--- a/internal/iam/repository/eventsourcing/eventstore.go
+++ b/internal/iam/repository/eventsourcing/eventstore.go
@@ -2,6 +2,7 @@ package eventsourcing
import (
"context"
+
"github.com/caos/zitadel/internal/cache/config"
sd "github.com/caos/zitadel/internal/config/systemdefaults"
"github.com/caos/zitadel/internal/crypto"
@@ -415,6 +416,68 @@ func (es *IAMEventstore) ChangeIDPOIDCConfig(ctx context.Context, config *iam_mo
return nil, caos_errs.ThrowInternal(nil, "EVENT-Sldk8", "Errors.Internal")
}
+func (es *IAMEventstore) PrepareAddLabelPolicy(ctx context.Context, policy *iam_model.LabelPolicy) (*model.IAM, *models.Aggregate, error) {
+ if policy == nil || policy.AggregateID == "" {
+ return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-VwlDv", "Errors.IAM.LabelPolicy.Empty")
+ }
+ iam, err := es.IAMByID(ctx, policy.AggregateID)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ repoIam := model.IAMFromModel(iam)
+ labelPolicy := model.LabelPolicyFromModel(policy)
+
+ addAggregate := LabelPolicyAddedAggregate(es.Eventstore.AggregateCreator(), repoIam, labelPolicy)
+ aggregate, err := addAggregate(ctx)
+ if err != nil {
+ return nil, nil, err
+ }
+ return repoIam, aggregate, nil
+}
+
+func (es *IAMEventstore) AddLabelPolicy(ctx context.Context, policy *iam_model.LabelPolicy) (*iam_model.LabelPolicy, error) {
+ if policy == nil || !policy.IsValid() {
+ return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-aAPWI", "Errors.IAM.LabelPolicyInvalid")
+ }
+ iam, err := es.IAMByID(ctx, policy.AggregateID)
+ if err != nil {
+ return nil, err
+ }
+
+ repoIam := model.IAMFromModel(iam)
+ repoLabelPolicy := model.LabelPolicyFromModel(policy)
+
+ addAggregate := LabelPolicyAddedAggregate(es.Eventstore.AggregateCreator(), repoIam, repoLabelPolicy)
+ err = es_sdk.Push(ctx, es.PushAggregates, repoIam.AppendEvents, addAggregate)
+ if err != nil {
+ return nil, err
+ }
+ es.iamCache.cacheIAM(repoIam)
+ return model.LabelPolicyToModel(repoIam.DefaultLabelPolicy), nil
+}
+
+func (es *IAMEventstore) ChangeLabelPolicy(ctx context.Context, policy *iam_model.LabelPolicy) (*iam_model.LabelPolicy, error) {
+ if policy == nil || !policy.IsValid() {
+ return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-vRqjg", "Errors.IAM.LabelPolicyInvalid")
+ }
+ iam, err := es.IAMByID(ctx, policy.AggregateID)
+ if err != nil {
+ return nil, err
+ }
+
+ repoIam := model.IAMFromModel(iam)
+ repoLabelPolicy := model.LabelPolicyFromModel(policy)
+
+ addAggregate := LabelPolicyChangedAggregate(es.Eventstore.AggregateCreator(), repoIam, repoLabelPolicy)
+ err = es_sdk.Push(ctx, es.PushAggregates, repoIam.AppendEvents, addAggregate)
+ if err != nil {
+ return nil, err
+ }
+ es.iamCache.cacheIAM(repoIam)
+ return model.LabelPolicyToModel(repoIam.DefaultLabelPolicy), nil
+}
+
func (es *IAMEventstore) PrepareAddLoginPolicy(ctx context.Context, policy *iam_model.LoginPolicy) (*model.IAM, *models.Aggregate, error) {
if policy == nil || !policy.IsValid() {
return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-Lso02", "Errors.IAM.LoginPolicyInvalid")
diff --git a/internal/iam/repository/eventsourcing/eventstore_mock_test.go b/internal/iam/repository/eventsourcing/eventstore_mock_test.go
index cb5a6b36c5..f022d5b65d 100644
--- a/internal/iam/repository/eventsourcing/eventstore_mock_test.go
+++ b/internal/iam/repository/eventsourcing/eventstore_mock_test.go
@@ -2,6 +2,7 @@ package eventsourcing
import (
"encoding/json"
+
"github.com/caos/zitadel/internal/crypto"
"github.com/caos/zitadel/internal/id"
@@ -182,3 +183,16 @@ func GetMockManipulateIAMNotExisting(ctrl *gomock.Controller) *IAMEventstore {
mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil)
return GetMockedEventstore(ctrl, mockEs)
}
+
+func GetMockManipulateIAMWithLabelPolicy(ctrl *gomock.Controller) *IAMEventstore {
+ policyData, _ := json.Marshal(model.LabelPolicy{PrimaryColor: "000001", SecondaryColor: "FFFFF1"})
+ events := []*es_models.Event{
+ &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.IAMSetupStarted},
+ &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.LabelPolicyAdded, Data: policyData},
+ }
+ mockEs := mock.NewMockEventstore(ctrl)
+ mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)
+ mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST"))
+ mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil)
+ return GetMockedEventstore(ctrl, mockEs)
+}
diff --git a/internal/iam/repository/eventsourcing/eventstore_test.go b/internal/iam/repository/eventsourcing/eventstore_test.go
index b81dc608cb..7ccb53127e 100644
--- a/internal/iam/repository/eventsourcing/eventstore_test.go
+++ b/internal/iam/repository/eventsourcing/eventstore_test.go
@@ -1657,6 +1657,170 @@ func TestRemoveIdpProviderFromLoginPolicy(t *testing.T) {
}
}
+func TestAddLabelPolicy(t *testing.T) {
+ ctrl := gomock.NewController(t)
+ type args struct {
+ es *IAMEventstore
+ ctx context.Context
+ policy *iam_model.LabelPolicy
+ }
+ type res struct {
+ result *iam_model.LabelPolicy
+ wantErr bool
+ errFunc func(err error) bool
+ }
+ tests := []struct {
+ name string
+ args args
+ res res
+ }{
+ {
+ name: "add label policy, ok",
+ args: args{
+ es: GetMockManipulateIAM(ctrl),
+ ctx: authz.NewMockContext("orgID", "userID"),
+ policy: &iam_model.LabelPolicy{
+ ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0},
+ PrimaryColor: "000000",
+ },
+ },
+ res: res{
+ result: &iam_model.LabelPolicy{
+ ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0},
+ PrimaryColor: "000000",
+ },
+ },
+ },
+ {
+ name: "invalid policy",
+ args: args{
+ es: GetMockManipulateIAM(ctrl),
+ ctx: authz.NewMockContext("orgID", "userID"),
+ policy: &iam_model.LabelPolicy{
+ ObjectRoot: es_models.ObjectRoot{Sequence: 0},
+ },
+ },
+ res: res{
+ wantErr: true,
+ errFunc: caos_errs.IsPreconditionFailed,
+ },
+ },
+ {
+ name: "existing iam not found",
+ args: args{
+ es: GetMockManipulateIAMNotExisting(ctrl),
+ ctx: authz.NewMockContext("orgID", "userID"),
+ policy: &iam_model.LabelPolicy{
+ ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0},
+ },
+ },
+ res: res{
+ wantErr: true,
+ errFunc: caos_errs.IsNotFound,
+ },
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ result, err := tt.args.es.AddLabelPolicy(tt.args.ctx, tt.args.policy)
+ if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) {
+ t.Errorf("got wrong err: %v ", err)
+ return
+ }
+ if tt.res.wantErr && tt.res.errFunc(err) {
+ return
+ }
+ if result.PrimaryColor != tt.res.result.PrimaryColor {
+ t.Errorf("got wrong result PrimaryColor: expected: %v, actual: %v ", tt.res.result.PrimaryColor, result.PrimaryColor)
+ }
+ })
+ }
+}
+
+func TestChangeLabelPolicy(t *testing.T) {
+ ctrl := gomock.NewController(t)
+ type args struct {
+ es *IAMEventstore
+ ctx context.Context
+ policy *iam_model.LabelPolicy
+ }
+ type res struct {
+ result *iam_model.LabelPolicy
+ wantErr bool
+ errFunc func(err error) bool
+ }
+ tests := []struct {
+ name string
+ args args
+ res res
+ }{
+ {
+ name: "change label policy, ok",
+ args: args{
+ es: GetMockManipulateIAMWithLabelPolicy(ctrl),
+ ctx: authz.NewMockContext("orgID", "userID"),
+ policy: &iam_model.LabelPolicy{
+ ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0},
+ PrimaryColor: "000000",
+ SecondaryColor: "FFFFFF",
+ },
+ },
+ res: res{
+ result: &iam_model.LabelPolicy{
+ ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0},
+ PrimaryColor: "000000",
+ SecondaryColor: "FFFFFF",
+ },
+ },
+ },
+ {
+ name: "invalid policy",
+ args: args{
+ es: GetMockManipulateIAM(ctrl),
+ ctx: authz.NewMockContext("orgID", "userID"),
+ policy: &iam_model.LabelPolicy{
+ ObjectRoot: es_models.ObjectRoot{Sequence: 0},
+ },
+ },
+ res: res{
+ wantErr: true,
+ errFunc: caos_errs.IsPreconditionFailed,
+ },
+ },
+ {
+ name: "existing iam not found",
+ args: args{
+ es: GetMockManipulateIAMNotExisting(ctrl),
+ ctx: authz.NewMockContext("orgID", "userID"),
+ policy: &iam_model.LabelPolicy{
+ ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0},
+ },
+ },
+ res: res{
+ wantErr: true,
+ errFunc: caos_errs.IsNotFound,
+ },
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ result, err := tt.args.es.ChangeLabelPolicy(tt.args.ctx, tt.args.policy)
+ if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) {
+ t.Errorf("got wrong err: %v ", err)
+ return
+ }
+ if tt.res.wantErr && tt.res.errFunc(err) {
+ return
+ }
+ if result.PrimaryColor != tt.res.result.PrimaryColor {
+ t.Errorf("got wrong result PrimaryColor: expected: %v, actual: %v ", tt.res.result.PrimaryColor, result.PrimaryColor)
+ }
+ if result.SecondaryColor != tt.res.result.SecondaryColor {
+ t.Errorf("got wrong result SecondaryColor: expected: %v, actual: %v ", tt.res.result.SecondaryColor, result.SecondaryColor)
+ }
+ })
+ }
+}
func TestAddPasswordComplexityPolicy(t *testing.T) {
ctrl := gomock.NewController(t)
type args struct {
diff --git a/internal/iam/repository/eventsourcing/iam.go b/internal/iam/repository/eventsourcing/iam.go
index 9199ccdcce..9e5a892028 100644
--- a/internal/iam/repository/eventsourcing/iam.go
+++ b/internal/iam/repository/eventsourcing/iam.go
@@ -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/iam/repository/eventsourcing/model"
@@ -231,6 +232,54 @@ func OIDCIDPConfigChangedAggregate(aggCreator *es_models.AggregateCreator, exist
return agg.AppendEvent(model.OIDCIDPConfigChanged, changes)
}
}
+func LabelPolicyAddedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, policy *model.LabelPolicy) func(ctx context.Context) (*es_models.Aggregate, error) {
+ return func(ctx context.Context) (*es_models.Aggregate, error) {
+ if policy == nil {
+ return nil, errors.ThrowPreconditionFailed(nil, "EVENT-e248Y", "Errors.Internal")
+ }
+ agg, err := IAMAggregate(ctx, aggCreator, existing)
+ if err != nil {
+ return nil, err
+ }
+ validationQuery := es_models.NewSearchQuery().
+ AggregateTypeFilter(model.IAMAggregate).
+ EventTypesFilter(model.LabelPolicyAdded).
+ AggregateIDFilter(existing.AggregateID)
+
+ validation := checkExistingLabelPolicyValidation()
+ agg.SetPrecondition(validationQuery, validation)
+ return agg.AppendEvent(model.LabelPolicyAdded, policy)
+ }
+}
+
+func checkExistingLabelPolicyValidation() func(...*es_models.Event) error {
+ return func(events ...*es_models.Event) error {
+ for _, event := range events {
+ switch event.Type {
+ case model.LabelPolicyAdded:
+ return errors.ThrowPreconditionFailed(nil, "EVENT-KyLIK", "Errors.IAM.LabelPolicy.AlreadyExists")
+ }
+ }
+ return nil
+ }
+}
+
+func LabelPolicyChangedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, policy *model.LabelPolicy) func(ctx context.Context) (*es_models.Aggregate, error) {
+ return func(ctx context.Context) (*es_models.Aggregate, error) {
+ if policy == nil {
+ return nil, errors.ThrowPreconditionFailed(nil, "EVENT-uP6HQ", "Errors.Internal")
+ }
+ agg, err := IAMAggregate(ctx, aggCreator, existing)
+ if err != nil {
+ return nil, err
+ }
+ changes := existing.DefaultLabelPolicy.Changes(policy)
+ if len(changes) == 0 {
+ return nil, errors.ThrowPreconditionFailed(nil, "EVENT-hZE24", "Errors.NoChangesFound")
+ }
+ return agg.AppendEvent(model.LabelPolicyChanged, changes)
+ }
+}
func LoginPolicyAddedAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, existing *model.IAM, policy *model.LoginPolicy) (*es_models.Aggregate, error) {
if policy == nil {
diff --git a/internal/iam/repository/eventsourcing/model/iam.go b/internal/iam/repository/eventsourcing/model/iam.go
index da626b4f57..e86889c69d 100644
--- a/internal/iam/repository/eventsourcing/model/iam.go
+++ b/internal/iam/repository/eventsourcing/model/iam.go
@@ -30,6 +30,7 @@ type IAM struct {
Members []*IAMMember `json:"-"`
IDPs []*IDPConfig `json:"-"`
DefaultLoginPolicy *LoginPolicy `json:"-"`
+ DefaultLabelPolicy *LabelPolicy `json:"-"`
DefaultOrgIAMPolicy *OrgIAMPolicy `json:"-"`
DefaultPasswordComplexityPolicy *PasswordComplexityPolicy `json:"-"`
DefaultPasswordAgePolicy *PasswordAgePolicy `json:"-"`
@@ -51,6 +52,9 @@ func IAMFromModel(iam *model.IAM) *IAM {
if iam.DefaultLoginPolicy != nil {
converted.DefaultLoginPolicy = LoginPolicyFromModel(iam.DefaultLoginPolicy)
}
+ if iam.DefaultLabelPolicy != nil {
+ converted.DefaultLabelPolicy = LabelPolicyFromModel(iam.DefaultLabelPolicy)
+ }
if iam.DefaultPasswordComplexityPolicy != nil {
converted.DefaultPasswordComplexityPolicy = PasswordComplexityPolicyFromModel(iam.DefaultPasswordComplexityPolicy)
}
@@ -81,6 +85,9 @@ func IAMToModel(iam *IAM) *model.IAM {
if iam.DefaultLoginPolicy != nil {
converted.DefaultLoginPolicy = LoginPolicyToModel(iam.DefaultLoginPolicy)
}
+ if iam.DefaultLabelPolicy != nil {
+ converted.DefaultLabelPolicy = LabelPolicyToModel(iam.DefaultLabelPolicy)
+ }
if iam.DefaultPasswordComplexityPolicy != nil {
converted.DefaultPasswordComplexityPolicy = PasswordComplexityPolicyToModel(iam.DefaultPasswordComplexityPolicy)
}
@@ -161,6 +168,10 @@ func (i *IAM) AppendEvent(event *es_models.Event) (err error) {
return i.appendAddIDPProviderToLoginPolicyEvent(event)
case LoginPolicyIDPProviderRemoved:
return i.appendRemoveIDPProviderFromLoginPolicyEvent(event)
+ case LabelPolicyAdded:
+ return i.appendAddLabelPolicyEvent(event)
+ case LabelPolicyChanged:
+ return i.appendChangeLabelPolicyEvent(event)
case PasswordComplexityPolicyAdded:
return i.appendAddPasswordComplexityPolicyEvent(event)
case PasswordComplexityPolicyChanged:
diff --git a/internal/iam/repository/eventsourcing/model/label_policy.go b/internal/iam/repository/eventsourcing/model/label_policy.go
new file mode 100644
index 0000000000..738b54fcb0
--- /dev/null
+++ b/internal/iam/repository/eventsourcing/model/label_policy.go
@@ -0,0 +1,78 @@
+package model
+
+import (
+ "encoding/json"
+
+ "github.com/caos/zitadel/internal/errors"
+ "github.com/caos/zitadel/internal/eventstore/models"
+ es_models "github.com/caos/zitadel/internal/eventstore/models"
+ iam_model "github.com/caos/zitadel/internal/iam/model"
+)
+
+type LabelPolicy struct {
+ models.ObjectRoot
+ State int32 `json:"-"`
+ PrimaryColor string `json:"primaryColor"`
+ SecondaryColor string `json:"secondaryColor"`
+}
+
+func LabelPolicyToModel(policy *LabelPolicy) *iam_model.LabelPolicy {
+ return &iam_model.LabelPolicy{
+ ObjectRoot: policy.ObjectRoot,
+ State: iam_model.PolicyState(policy.State),
+ PrimaryColor: policy.PrimaryColor,
+ SecondaryColor: policy.SecondaryColor,
+ }
+}
+
+func LabelPolicyFromModel(policy *iam_model.LabelPolicy) *LabelPolicy {
+ return &LabelPolicy{
+ ObjectRoot: policy.ObjectRoot,
+ State: int32(policy.State),
+ PrimaryColor: policy.PrimaryColor,
+ SecondaryColor: policy.SecondaryColor,
+ }
+}
+
+func (p *LabelPolicy) Changes(changed *LabelPolicy) map[string]interface{} {
+ changes := make(map[string]interface{}, 2)
+
+ if changed.PrimaryColor != p.PrimaryColor {
+ changes["primaryColor"] = changed.PrimaryColor
+ }
+ if changed.SecondaryColor != p.SecondaryColor {
+ changes["secondaryColor"] = changed.SecondaryColor
+ }
+
+ return changes
+}
+
+func (i *IAM) appendAddLabelPolicyEvent(event *es_models.Event) error {
+ i.DefaultLabelPolicy = new(LabelPolicy)
+ err := i.DefaultLabelPolicy.SetDataLabel(event)
+ if err != nil {
+ return err
+ }
+ i.DefaultLabelPolicy.ObjectRoot.CreationDate = event.CreationDate
+ return nil
+}
+
+func (i *IAM) appendChangeLabelPolicyEvent(event *es_models.Event) error {
+ return i.DefaultLabelPolicy.SetDataLabel(event)
+}
+
+func (p *LabelPolicy) SetDataLabel(event *es_models.Event) error {
+ err := json.Unmarshal(event.Data, p)
+ if err != nil {
+ return errors.ThrowInternal(err, "MODEL-ikjhf", "unable to unmarshal data")
+ }
+ return nil
+}
+
+func (p *IDPProvider) SetDataLabel(event *es_models.Event) error {
+ err := json.Unmarshal(event.Data, p)
+ if err != nil {
+ return errors.ThrowInternal(err, "MODEL-c41Hn", "unable to unmarshal data")
+ }
+ return nil
+}
diff --git a/internal/iam/repository/eventsourcing/model/label_policy_test.go b/internal/iam/repository/eventsourcing/model/label_policy_test.go
new file mode 100644
index 0000000000..094e51f28c
--- /dev/null
+++ b/internal/iam/repository/eventsourcing/model/label_policy_test.go
@@ -0,0 +1,132 @@
+package model
+
+import (
+ "encoding/json"
+ "testing"
+
+ es_models "github.com/caos/zitadel/internal/eventstore/models"
+)
+
+func TestLabelPolicyChanges(t *testing.T) {
+ type args struct {
+ existing *LabelPolicy
+ new *LabelPolicy
+ }
+ type res struct {
+ changesLen int
+ }
+ tests := []struct {
+ name string
+ args args
+ res res
+ }{
+ {
+ name: "labelpolicy all attributes change",
+ args: args{
+ existing: &LabelPolicy{PrimaryColor: "000001", SecondaryColor: "FFFFFA"},
+ new: &LabelPolicy{PrimaryColor: "000000", SecondaryColor: "FFFFFF"},
+ },
+ res: res{
+ changesLen: 2,
+ },
+ },
+ {
+ name: "no changes",
+ args: args{
+ existing: &LabelPolicy{PrimaryColor: "000000", SecondaryColor: "FFFFFF"},
+ new: &LabelPolicy{PrimaryColor: "000000", SecondaryColor: "FFFFFF"},
+ },
+ 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))
+ }
+ })
+ }
+}
+
+func TestAppendAddLabelPolicyEvent(t *testing.T) {
+ type args struct {
+ iam *IAM
+ policy *LabelPolicy
+ event *es_models.Event
+ }
+ tests := []struct {
+ name string
+ args args
+ result *IAM
+ }{
+ {
+ name: "append add label policy event",
+ args: args{
+ iam: new(IAM),
+ policy: &LabelPolicy{PrimaryColor: "000000", SecondaryColor: "FFFFFF"},
+ event: new(es_models.Event),
+ },
+ result: &IAM{DefaultLabelPolicy: &LabelPolicy{PrimaryColor: "000000", SecondaryColor: "FFFFFF"}},
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ if tt.args.policy != nil {
+ data, _ := json.Marshal(tt.args.policy)
+ tt.args.event.Data = data
+ }
+ tt.args.iam.appendAddLabelPolicyEvent(tt.args.event)
+ if tt.result.DefaultLabelPolicy.PrimaryColor != tt.args.iam.DefaultLabelPolicy.PrimaryColor {
+ t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultLabelPolicy.PrimaryColor, tt.args.iam.DefaultLabelPolicy.PrimaryColor)
+ }
+ if tt.result.DefaultLabelPolicy.SecondaryColor != tt.args.iam.DefaultLabelPolicy.SecondaryColor {
+ t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultLabelPolicy.SecondaryColor, tt.args.iam.DefaultLabelPolicy.SecondaryColor)
+ }
+ })
+ }
+}
+
+func TestAppendChangeLabelPolicyEvent(t *testing.T) {
+ type args struct {
+ iam *IAM
+ policy *LabelPolicy
+ event *es_models.Event
+ }
+ tests := []struct {
+ name string
+ args args
+ result *IAM
+ }{
+ {
+ name: "append change label policy event",
+ args: args{
+ iam: &IAM{DefaultLabelPolicy: &LabelPolicy{
+ PrimaryColor: "000001", SecondaryColor: "FFFFF0",
+ }},
+ policy: &LabelPolicy{PrimaryColor: "000000", SecondaryColor: "FFFFFF"},
+ event: &es_models.Event{},
+ },
+ result: &IAM{DefaultLabelPolicy: &LabelPolicy{
+ PrimaryColor: "000000", SecondaryColor: "FFFFFF",
+ }},
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ if tt.args.policy != nil {
+ data, _ := json.Marshal(tt.args.policy)
+ tt.args.event.Data = data
+ }
+ tt.args.iam.appendChangeLabelPolicyEvent(tt.args.event)
+ if tt.result.DefaultLabelPolicy.PrimaryColor != tt.args.iam.DefaultLabelPolicy.PrimaryColor {
+ t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultLabelPolicy.PrimaryColor, tt.args.iam.DefaultLabelPolicy.PrimaryColor)
+ }
+ if tt.result.DefaultLabelPolicy.SecondaryColor != tt.args.iam.DefaultLabelPolicy.SecondaryColor {
+ t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.DefaultLabelPolicy.SecondaryColor, tt.args.iam.DefaultLabelPolicy.SecondaryColor)
+ }
+ })
+ }
+}
diff --git a/internal/iam/repository/eventsourcing/model/types.go b/internal/iam/repository/eventsourcing/model/types.go
index 71b1fbe0b4..93b153f6a7 100644
--- a/internal/iam/repository/eventsourcing/model/types.go
+++ b/internal/iam/repository/eventsourcing/model/types.go
@@ -30,6 +30,8 @@ const (
LoginPolicyIDPProviderAdded models.EventType = "iam.policy.login.idpprovider.added"
LoginPolicyIDPProviderRemoved models.EventType = "iam.policy.login.idpprovider.removed"
LoginPolicyIDPProviderCascadeRemoved models.EventType = "iam.policy.login.idpprovider.cascade.removed"
+ LabelPolicyAdded models.EventType = "iam.policy.label.added"
+ LabelPolicyChanged models.EventType = "iam.policy.label.changed"
PasswordComplexityPolicyAdded models.EventType = "iam.policy.password.complexity.added"
PasswordComplexityPolicyChanged models.EventType = "iam.policy.password.complexity.changed"
diff --git a/internal/iam/repository/view/label_policy_view.go b/internal/iam/repository/view/label_policy_view.go
new file mode 100644
index 0000000000..e77f3b1dc9
--- /dev/null
+++ b/internal/iam/repository/view/label_policy_view.go
@@ -0,0 +1,32 @@
+package view
+
+import (
+ caos_errs "github.com/caos/zitadel/internal/errors"
+ iam_model "github.com/caos/zitadel/internal/iam/model"
+ "github.com/caos/zitadel/internal/iam/repository/view/model"
+ global_model "github.com/caos/zitadel/internal/model"
+ "github.com/caos/zitadel/internal/view/repository"
+ "github.com/jinzhu/gorm"
+)
+
+func GetLabelPolicyByAggregateID(db *gorm.DB, table, aggregateID string) (*model.LabelPolicyView, error) {
+ policy := new(model.LabelPolicyView)
+ userIDQuery := &model.LabelPolicySearchQuery{Key: iam_model.LabelPolicySearchKeyAggregateID, Value: aggregateID, Method: global_model.SearchMethodEquals}
+ query := repository.PrepareGetByQuery(table, userIDQuery)
+ err := query(db, policy)
+ if caos_errs.IsNotFound(err) {
+ return nil, caos_errs.ThrowNotFound(nil, "VIEW-68G11", "Errors.IAM.LabelPolicy.NotExisting")
+ }
+ return policy, err
+}
+
+func PutLabelPolicy(db *gorm.DB, table string, policy *model.LabelPolicyView) error {
+ save := repository.PrepareSave(table)
+ return save(db, policy)
+}
+
+func DeleteLabelPolicy(db *gorm.DB, table, aggregateID string) error {
+ delete := repository.PrepareDeleteByKey(table, model.LabelPolicySearchKey(iam_model.LabelPolicySearchKeyAggregateID), aggregateID)
+
+ return delete(db)
+}
diff --git a/internal/iam/repository/view/model/label_policy.go b/internal/iam/repository/view/model/label_policy.go
new file mode 100644
index 0000000000..0f9e4ad70f
--- /dev/null
+++ b/internal/iam/repository/view/model/label_policy.go
@@ -0,0 +1,82 @@
+package model
+
+import (
+ "encoding/json"
+ "time"
+
+ org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
+
+ es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
+
+ "github.com/caos/logging"
+ caos_errs "github.com/caos/zitadel/internal/errors"
+ "github.com/caos/zitadel/internal/eventstore/models"
+ "github.com/caos/zitadel/internal/iam/model"
+)
+
+const (
+ LabelPolicyKeyAggregateID = "aggregate_id"
+)
+
+type LabelPolicyView struct {
+ AggregateID string `json:"-" gorm:"column:aggregate_id;primary_key"`
+ CreationDate time.Time `json:"-" gorm:"column:creation_date"`
+ ChangeDate time.Time `json:"-" gorm:"column:change_date"`
+ State int32 `json:"-" gorm:"column:label_policy_state"`
+
+ PrimaryColor string `json:"primaryColor" gorm:"column:primary_color"`
+ SecondaryColor string `json:"secondaryColor" gorm:"column:secondary_color"`
+ Default bool `json:"-" gorm:"-"`
+
+ Sequence uint64 `json:"-" gorm:"column:sequence"`
+}
+
+func LabelPolicyViewFromModel(policy *model.LabelPolicyView) *LabelPolicyView {
+ return &LabelPolicyView{
+ AggregateID: policy.AggregateID,
+ Sequence: policy.Sequence,
+ CreationDate: policy.CreationDate,
+ ChangeDate: policy.ChangeDate,
+ PrimaryColor: policy.PrimaryColor,
+ SecondaryColor: policy.SecondaryColor,
+ Default: policy.Default,
+ }
+}
+
+func LabelPolicyViewToModel(policy *LabelPolicyView) *model.LabelPolicyView {
+ return &model.LabelPolicyView{
+ AggregateID: policy.AggregateID,
+ Sequence: policy.Sequence,
+ CreationDate: policy.CreationDate,
+ ChangeDate: policy.ChangeDate,
+ PrimaryColor: policy.PrimaryColor,
+ SecondaryColor: policy.SecondaryColor,
+ Default: policy.Default,
+ }
+}
+
+func (i *LabelPolicyView) AppendEvent(event *models.Event) (err error) {
+ i.Sequence = event.Sequence
+ i.ChangeDate = event.CreationDate
+ switch event.Type {
+ case es_model.LabelPolicyAdded, org_es_model.LabelPolicyAdded:
+ i.setRootData(event)
+ i.CreationDate = event.CreationDate
+ err = i.SetData(event)
+ case es_model.LabelPolicyChanged, org_es_model.LabelPolicyChanged:
+ err = i.SetData(event)
+ }
+ return err
+}
+
+func (r *LabelPolicyView) setRootData(event *models.Event) {
+ r.AggregateID = event.AggregateID
+}
+
+func (r *LabelPolicyView) SetData(event *models.Event) error {
+ if err := json.Unmarshal(event.Data, r); err != nil {
+ logging.Log("MODEL-Flp9C").WithError(err).Error("could not unmarshal event data")
+ return caos_errs.ThrowInternal(err, "MODEL-Hs8uf", "Could not unmarshal data")
+ }
+ return nil
+}
diff --git a/internal/iam/repository/view/model/label_policy_query.go b/internal/iam/repository/view/model/label_policy_query.go
new file mode 100644
index 0000000000..d12dcd2f78
--- /dev/null
+++ b/internal/iam/repository/view/model/label_policy_query.go
@@ -0,0 +1,59 @@
+package model
+
+import (
+ iam_model "github.com/caos/zitadel/internal/iam/model"
+ global_model "github.com/caos/zitadel/internal/model"
+ "github.com/caos/zitadel/internal/view/repository"
+)
+
+type LabelPolicySearchRequest iam_model.LabelPolicySearchRequest
+type LabelPolicySearchQuery iam_model.LabelPolicySearchQuery
+type LabelPolicySearchKey iam_model.LabelPolicySearchKey
+
+func (req LabelPolicySearchRequest) GetLimit() uint64 {
+ return req.Limit
+}
+
+func (req LabelPolicySearchRequest) GetOffset() uint64 {
+ return req.Offset
+}
+
+func (req LabelPolicySearchRequest) GetSortingColumn() repository.ColumnKey {
+ if req.SortingColumn == iam_model.LabelPolicySearchKeyUnspecified {
+ return nil
+ }
+ return LabelPolicySearchKey(req.SortingColumn)
+}
+
+func (req LabelPolicySearchRequest) GetAsc() bool {
+ return req.Asc
+}
+
+func (req LabelPolicySearchRequest) GetQueries() []repository.SearchQuery {
+ result := make([]repository.SearchQuery, len(req.Queries))
+ for i, q := range req.Queries {
+ result[i] = LabelPolicySearchQuery{Key: q.Key, Value: q.Value, Method: q.Method}
+ }
+ return result
+}
+
+func (req LabelPolicySearchQuery) GetKey() repository.ColumnKey {
+ return LabelPolicySearchKey(req.Key)
+}
+
+func (req LabelPolicySearchQuery) GetMethod() global_model.SearchMethod {
+ return req.Method
+}
+
+func (req LabelPolicySearchQuery) GetValue() interface{} {
+ return req.Value
+}
+
+func (key LabelPolicySearchKey) ToColumnName() string {
+ switch iam_model.LabelPolicySearchKey(key) {
+ case iam_model.LabelPolicySearchKeyAggregateID:
+ return LabelPolicyKeyAggregateID
+ default:
+ return ""
+ }
+}
diff --git a/internal/management/repository/eventsourcing/eventstore/org.go b/internal/management/repository/eventsourcing/eventstore/org.go
index f098ac780b..da580eed4d 100644
--- a/internal/management/repository/eventsourcing/eventstore/org.go
+++ b/internal/management/repository/eventsourcing/eventstore/org.go
@@ -2,25 +2,25 @@ package eventstore
import (
"context"
+ "strings"
+
"github.com/caos/logging"
+ "github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/internal/config/systemdefaults"
+ "github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/eventstore/models"
+ es_models "github.com/caos/zitadel/internal/eventstore/models"
+ "github.com/caos/zitadel/internal/eventstore/sdk"
iam_model "github.com/caos/zitadel/internal/iam/model"
iam_es_model "github.com/caos/zitadel/internal/iam/repository/view/model"
iam_view_model "github.com/caos/zitadel/internal/iam/repository/view/model"
- usr_model "github.com/caos/zitadel/internal/user/model"
- "strings"
-
- "github.com/caos/zitadel/internal/api/authz"
- "github.com/caos/zitadel/internal/errors"
- es_models "github.com/caos/zitadel/internal/eventstore/models"
- "github.com/caos/zitadel/internal/eventstore/sdk"
mgmt_view "github.com/caos/zitadel/internal/management/repository/eventsourcing/view"
global_model "github.com/caos/zitadel/internal/model"
org_model "github.com/caos/zitadel/internal/org/model"
org_es "github.com/caos/zitadel/internal/org/repository/eventsourcing"
org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
"github.com/caos/zitadel/internal/org/repository/view/model"
+ usr_model "github.com/caos/zitadel/internal/user/model"
usr_es "github.com/caos/zitadel/internal/user/repository/eventsourcing"
)
@@ -302,6 +302,31 @@ func (repo *OrgRepository) SearchIDPConfigs(ctx context.Context, request *iam_mo
return result, nil
}
+func (repo *OrgRepository) GetLabelPolicy(ctx context.Context) (*iam_model.LabelPolicyView, error) {
+ policy, err := repo.View.LabelPolicyByAggregateID(authz.GetCtxData(ctx).OrgID)
+ if errors.IsNotFound(err) {
+ policy, err = repo.View.LabelPolicyByAggregateID(repo.SystemDefaults.IamID)
+ if err != nil {
+ return nil, err
+ }
+ policy.Default = true
+ }
+ if err != nil {
+ return nil, err
+ }
+ return iam_es_model.LabelPolicyViewToModel(policy), err
+}
+
+func (repo *OrgRepository) AddLabelPolicy(ctx context.Context, policy *iam_model.LabelPolicy) (*iam_model.LabelPolicy, error) {
+ policy.AggregateID = authz.GetCtxData(ctx).OrgID
+ return repo.OrgEventstore.AddLabelPolicy(ctx, policy)
+}
+
+func (repo *OrgRepository) ChangeLabelPolicy(ctx context.Context, policy *iam_model.LabelPolicy) (*iam_model.LabelPolicy, error) {
+ policy.AggregateID = authz.GetCtxData(ctx).OrgID
+ return repo.OrgEventstore.ChangeLabelPolicy(ctx, policy)
+}
+
func (repo *OrgRepository) GetLoginPolicy(ctx context.Context) (*iam_model.LoginPolicyView, error) {
policy, err := repo.View.LoginPolicyByAggregateID(authz.GetCtxData(ctx).OrgID)
if errors.IsNotFound(err) {
diff --git a/internal/management/repository/eventsourcing/handler/handler.go b/internal/management/repository/eventsourcing/handler/handler.go
index fecff808b7..531a9db468 100644
--- a/internal/management/repository/eventsourcing/handler/handler.go
+++ b/internal/management/repository/eventsourcing/handler/handler.go
@@ -61,6 +61,7 @@ func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, ev
&MachineKeys{handler: handler{view, bulkLimit, configs.cycleDuration("MachineKeys"), errorCount}},
&IDPConfig{handler: handler{view, bulkLimit, configs.cycleDuration("IDPConfig"), errorCount}},
&LoginPolicy{handler: handler{view, bulkLimit, configs.cycleDuration("LoginPolicy"), errorCount}},
+ &LabelPolicy{handler: handler{view, bulkLimit, configs.cycleDuration("LabelPolicy"), errorCount}},
&IDPProvider{handler: handler{view, bulkLimit, configs.cycleDuration("IDPProvider"), errorCount},
systemDefaults: defaults, iamEvents: repos.IamEvents, orgEvents: repos.OrgEvents},
&ExternalIDP{handler: handler{view, bulkLimit, configs.cycleDuration("ExternalIDP"), errorCount},
diff --git a/internal/management/repository/eventsourcing/handler/label_policy.go b/internal/management/repository/eventsourcing/handler/label_policy.go
new file mode 100644
index 0000000000..8c3238159f
--- /dev/null
+++ b/internal/management/repository/eventsourcing/handler/label_policy.go
@@ -0,0 +1,67 @@
+package handler
+
+import (
+ "github.com/caos/logging"
+ iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
+
+ "github.com/caos/zitadel/internal/eventstore/models"
+ es_models "github.com/caos/zitadel/internal/eventstore/models"
+ "github.com/caos/zitadel/internal/eventstore/spooler"
+ iam_model "github.com/caos/zitadel/internal/iam/repository/view/model"
+ "github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
+)
+
+type LabelPolicy struct {
+ handler
+}
+
+const (
+ labelPolicyTable = "management.label_policies"
+)
+
+func (m *LabelPolicy) ViewModel() string {
+ return labelPolicyTable
+}
+
+func (m *LabelPolicy) EventQuery() (*models.SearchQuery, error) {
+ sequence, err := m.view.GetLatestLabelPolicySequence()
+ if err != nil {
+ return nil, err
+ }
+ return es_models.NewSearchQuery().
+ AggregateTypeFilter(model.OrgAggregate, iam_es_model.IAMAggregate).
+ LatestSequenceFilter(sequence.CurrentSequence), nil
+}
+
+func (m *LabelPolicy) Reduce(event *models.Event) (err error) {
+ switch event.AggregateType {
+ case model.OrgAggregate, iam_es_model.IAMAggregate:
+ err = m.processLabelPolicy(event)
+ }
+ return err
+}
+
+func (m *LabelPolicy) processLabelPolicy(event *models.Event) (err error) {
+ policy := new(iam_model.LabelPolicyView)
+ switch event.Type {
+ case iam_es_model.LabelPolicyAdded, model.LabelPolicyAdded:
+ err = policy.AppendEvent(event)
+ case iam_es_model.LabelPolicyChanged, model.LabelPolicyChanged:
+ policy, err = m.view.LabelPolicyByAggregateID(event.AggregateID)
+ if err != nil {
+ return err
+ }
+ err = policy.AppendEvent(event)
+ default:
+ return m.view.ProcessedLabelPolicySequence(event.Sequence)
+ }
+ if err != nil {
+ return err
+ }
+ return m.view.PutLabelPolicy(policy, policy.Sequence)
+}
+
+func (m *LabelPolicy) OnError(event *models.Event, err error) error {
+ logging.LogWithFields("SPOOL-4Djo9", "id", event.AggregateID).WithError(err).Warn("something went wrong in label policy handler")
+ return spooler.HandleError(event, err, m.view.GetLatestLabelPolicyFailedEvent, m.view.ProcessedLabelPolicyFailedEvent, m.view.ProcessedLabelPolicySequence, m.errorCountUntilSkip)
+}
diff --git a/internal/management/repository/eventsourcing/view/label_policies.go b/internal/management/repository/eventsourcing/view/label_policies.go
new file mode 100644
index 0000000000..182ca4f368
--- /dev/null
+++ b/internal/management/repository/eventsourcing/view/label_policies.go
@@ -0,0 +1,48 @@
+package view
+
+import (
+ "github.com/caos/zitadel/internal/errors"
+ "github.com/caos/zitadel/internal/iam/repository/view"
+ "github.com/caos/zitadel/internal/iam/repository/view/model"
+ global_view "github.com/caos/zitadel/internal/view/repository"
+)
+
+const (
+ labelPolicyTable = "management.label_policies"
+)
+
+func (v *View) LabelPolicyByAggregateID(aggregateID string) (*model.LabelPolicyView, error) {
+ return view.GetLabelPolicyByAggregateID(v.Db, labelPolicyTable, aggregateID)
+}
+
+func (v *View) PutLabelPolicy(policy *model.LabelPolicyView, sequence uint64) error {
+ err := view.PutLabelPolicy(v.Db, labelPolicyTable, policy)
+ if err != nil {
+ return err
+ }
+ return v.ProcessedLabelPolicySequence(sequence)
+}
+
+func (v *View) DeleteLabelPolicy(aggregateID string, eventSequence uint64) error {
+ err := view.DeleteLabelPolicy(v.Db, labelPolicyTable, aggregateID)
+ if err != nil && !errors.IsNotFound(err) {
+ return err
+ }
+ return v.ProcessedLabelPolicySequence(eventSequence)
+}
+
+func (v *View) GetLatestLabelPolicySequence() (*global_view.CurrentSequence, error) {
+ return v.latestSequence(labelPolicyTable)
+}
+
+func (v *View) ProcessedLabelPolicySequence(eventSequence uint64) error {
+ return v.saveCurrentSequence(labelPolicyTable, eventSequence)
+}
+
+func (v *View) GetLatestLabelPolicyFailedEvent(sequence uint64) (*global_view.FailedEvent, error) {
+ return v.latestFailedEvent(labelPolicyTable, sequence)
+}
+
+func (v *View) ProcessedLabelPolicyFailedEvent(failedEvent *global_view.FailedEvent) error {
+ return v.saveFailedEvent(failedEvent)
+}
diff --git a/internal/notification/repository/eventsourcing/handler/notification.go b/internal/notification/repository/eventsourcing/handler/notification.go
index 9991e72773..99e79effa4 100644
--- a/internal/notification/repository/eventsourcing/handler/notification.go
+++ b/internal/notification/repository/eventsourcing/handler/notification.go
@@ -10,11 +10,14 @@ import (
"github.com/caos/zitadel/internal/api/authz"
sd "github.com/caos/zitadel/internal/config/systemdefaults"
"github.com/caos/zitadel/internal/crypto"
+ "github.com/caos/zitadel/internal/errors"
caos_errs "github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/eventstore"
"github.com/caos/zitadel/internal/eventstore/models"
"github.com/caos/zitadel/internal/eventstore/spooler"
"github.com/caos/zitadel/internal/i18n"
+ iam_model "github.com/caos/zitadel/internal/iam/model"
+ iam_es_model "github.com/caos/zitadel/internal/iam/repository/view/model"
"github.com/caos/zitadel/internal/notification/types"
"github.com/caos/zitadel/internal/user/repository/eventsourcing"
usr_event "github.com/caos/zitadel/internal/user/repository/eventsourcing"
@@ -32,8 +35,10 @@ type Notification struct {
}
const (
- notificationTable = "notification.notifications"
- NotifyUserID = "NOTIFICATION"
+ notificationTable = "notification.notifications"
+ NotifyUserID = "NOTIFICATION"
+ labelPolicyTableOrg = "management.label_policies"
+ labelPolicyTableDef = "adminapi.label_policies"
)
func (n *Notification) ViewModel() string {
@@ -78,13 +83,19 @@ func (n *Notification) handleInitUserCode(event *models.Event) (err error) {
if err != nil || alreadyHandled {
return err
}
+
+ colors, err := n.getLabelPolicy(context.Background())
+ if err != nil {
+ return err
+ }
+
initCode := new(es_model.InitUserCode)
initCode.SetData(event)
user, err := n.view.NotifyUserByID(event.AggregateID)
if err != nil {
return err
}
- err = types.SendUserInitCode(n.statikDir, n.i18n, user, initCode, n.systemDefaults, n.AesCrypto)
+ err = types.SendUserInitCode(n.statikDir, n.i18n, user, initCode, n.systemDefaults, n.AesCrypto, colors)
if err != nil {
return err
}
@@ -96,13 +107,19 @@ func (n *Notification) handlePasswordCode(event *models.Event) (err error) {
if err != nil || alreadyHandled {
return err
}
+
+ colors, err := n.getLabelPolicy(context.Background())
+ if err != nil {
+ return err
+ }
+
pwCode := new(es_model.PasswordCode)
pwCode.SetData(event)
user, err := n.view.NotifyUserByID(event.AggregateID)
if err != nil {
return err
}
- err = types.SendPasswordCode(n.statikDir, n.i18n, user, pwCode, n.systemDefaults, n.AesCrypto)
+ err = types.SendPasswordCode(n.statikDir, n.i18n, user, pwCode, n.systemDefaults, n.AesCrypto, colors)
if err != nil {
return err
}
@@ -114,13 +131,19 @@ func (n *Notification) handleEmailVerificationCode(event *models.Event) (err err
if err != nil || alreadyHandled {
return nil
}
+
+ colors, err := n.getLabelPolicy(context.Background())
+ if err != nil {
+ return err
+ }
+
emailCode := new(es_model.EmailCode)
emailCode.SetData(event)
user, err := n.view.NotifyUserByID(event.AggregateID)
if err != nil {
return err
}
- err = types.SendEmailVerificationCode(n.statikDir, n.i18n, user, emailCode, n.systemDefaults, n.AesCrypto)
+ err = types.SendEmailVerificationCode(n.statikDir, n.i18n, user, emailCode, n.systemDefaults, n.AesCrypto, colors)
if err != nil {
return err
}
@@ -196,3 +219,21 @@ func (n *Notification) OnError(event *models.Event, err error) error {
func getSetNotifyContextData(orgID string) context.Context {
return authz.SetCtxData(context.Background(), authz.CtxData{UserID: NotifyUserID, OrgID: orgID})
}
+
+// Read organization specific colors
+func (n *Notification) getLabelPolicy(ctx context.Context) (*iam_model.LabelPolicyView, error) {
+ // read from Org
+ policy, err := n.view.LabelPolicyByAggregateID(authz.GetCtxData(ctx).OrgID, labelPolicyTableOrg)
+ if errors.IsNotFound(err) {
+ // read from default
+ policy, err = n.view.LabelPolicyByAggregateID(n.systemDefaults.IamID, labelPolicyTableDef)
+ if err != nil {
+ return nil, err
+ }
+ policy.Default = true
+ }
+ if err != nil {
+ return nil, err
+ }
+ return iam_es_model.LabelPolicyViewToModel(policy), err
+}
diff --git a/internal/notification/repository/eventsourcing/view/label_policies.go b/internal/notification/repository/eventsourcing/view/label_policies.go
new file mode 100644
index 0000000000..a330d4ac84
--- /dev/null
+++ b/internal/notification/repository/eventsourcing/view/label_policies.go
@@ -0,0 +1,10 @@
+package view
+
+import (
+ "github.com/caos/zitadel/internal/iam/repository/view"
+ "github.com/caos/zitadel/internal/iam/repository/view/model"
+)
+
+func (v *View) LabelPolicyByAggregateID(aggregateID string, labelPolicyTableVar string) (*model.LabelPolicyView, error) {
+ return view.GetLabelPolicyByAggregateID(v.Db, labelPolicyTableVar, aggregateID)
+}
diff --git a/internal/notification/static/i18n/de.yaml b/internal/notification/static/i18n/de.yaml
index 5435841b70..001c572dfb 100644
--- a/internal/notification/static/i18n/de.yaml
+++ b/internal/notification/static/i18n/de.yaml
@@ -3,28 +3,28 @@ InitCode:
PreHeader: User initialisieren
Subject: User initialisieren
Greeting: Hallo {{.FirstName}} {{.LastName}},
- Text: Dieser Benutzer wurde soeben im Zitadel erstellt. Mit dem Benutzernamen {{.PreferredLoginName}} kannst du dich anmelden. Nutze den untenstehenden Button, um die Initialisierung abzuschliesen. (Code {{.Code}}) Falls du dieses Mail nicht angefordert hast, kannst du es einfach ignorieren.
+ Text: Dieser Benutzer wurde soeben im Zitadel erstellt. Mit dem Benutzernamen <br><strong>{{.PreferredLoginName}}</strong><br> kannst du dich anmelden. Nutze den untenstehenden Button, um die Initialisierung abzuschliessen <br>(Code <strong>{{.Code}}</strong>).<br> Falls du dieses Mail nicht angefordert hast, kannst du es einfach ignorieren.
ButtonText: Initialisierung abschliessen
PasswordReset:
Title: Zitadel - Passwort zurücksetzen
PreHeader: Passwort zurücksetzen
Subject: Passwort zurücksetzen
Greeting: Hallo {{.FirstName}} {{.LastName}},
- Text: Wir haben eine Anfrage für das Zurücksetzen deines Passwortes bekommen. Du kannst den untenstehenden Button verwenden, um dein Passwort zurückzusetzen. (Code {{.Code}}) Falls du dieses Mail nicht angefordert hast, kannst du es ignorieren.
+ Text: Wir haben eine Anfrage für das Zurücksetzen deines Passwortes bekommen. Du kannst den untenstehenden Button verwenden, um dein Passwort zurückzusetzen <br>(Code <strong>{{.Code}}</strong>).<br> Falls du dieses Mail nicht angefordert hast, kannst du es ignorieren.
ButtonText: Passwort zurücksetzen
VerifyEmail:
Title: Zitadel - Email verifizieren
PreHeader: Email verifizieren
Subject: Email verifizieren
Greeting: Hallo {{.FirstName}} {{.LastName}},
- Text: Eine neue E-Mail Adresse wurde hinzugefügt. Bitte verwende den untenstehenden Button um diese zu verifizieren. (Code {{.Code}}) Falls du deine E-Mail Adresse nicht selber hinzugefügt hast, kannst du dieses E-Mail ignorieren.
+ Text: Eine neue E-Mail Adresse wurde hinzugefügt. Bitte verwende den untenstehenden Button um diese zu verifizieren <br>(Code <strong>{{.Code}}</strong>).<br> Falls du deine E-Mail Adresse nicht selber hinzugefügt hast, kannst du dieses E-Mail ignorieren.
ButtonText: Email verifizieren
VerifyPhone:
Title: Zitadel - Telefonnummer verifizieren
PreHeader: Telefonnummer verifizieren
Subject: Telefonnummer verifizieren
Greeting: Hallo {{.FirstName}} {{.LastName}},
- Text: Eine Telefonnummer wurde hinzugefügt. Bitte verifiziere diese in dem du folgenden Code eingibst {{.Code}}
+ Text: Eine Telefonnummer wurde hinzugefügt. Bitte verifiziere diese in dem du folgenden Code eingibst<br>(Code <strong>{{.Code}}</strong>).<br>
ButtonText: Telefon verifizieren
DomainClaimed:
Title: Zitadel - Domain wurde beansprucht
diff --git a/internal/notification/static/templates/template 01 Tabelle black.mjml b/internal/notification/static/templates/template 01 Tabelle black.mjml
new file mode 100644
index 0000000000..8d514752eb
--- /dev/null
+++ b/internal/notification/static/templates/template 01 Tabelle black.mjml
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
+