feat: Login, OP Support and Auth Queries (#177)

* fix: change oidc config

* fix: change oidc config secret

* begin models

* begin repo

* fix: implement grpc app funcs

* fix: add application requests

* fix: converter

* fix: converter

* fix: converter and generate clientid

* fix: tests

* feat: project grant aggregate

* feat: project grant

* fix: project grant check if role existing

* fix: project grant requests

* fix: project grant fixes

* fix: project grant member model

* fix: project grant member aggregate

* fix: project grant member eventstore

* fix: project grant member requests

* feat: user model

* begin repo

* repo models and more

* feat: user command side

* lots of functions

* user command side

* profile requests

* commit before rebase on user

* save

* local config with gopass and more

* begin new auth command (user centric)

* Update internal/user/model/user.go

Co-Authored-By: Livio Amstutz <livio.a@gmail.com>

* Update internal/user/repository/eventsourcing/model/address.go

Co-Authored-By: Livio Amstutz <livio.a@gmail.com>

* Update internal/user/repository/eventsourcing/model/address.go

Co-Authored-By: Livio Amstutz <livio.a@gmail.com>

* Update internal/user/repository/eventsourcing/model/email.go

Co-Authored-By: Livio Amstutz <livio.a@gmail.com>

* Update internal/user/repository/eventsourcing/model/email.go

Co-Authored-By: Livio Amstutz <livio.a@gmail.com>

* Update internal/user/repository/eventsourcing/model/email.go

Co-Authored-By: Livio Amstutz <livio.a@gmail.com>

* Update internal/user/repository/eventsourcing/model/mfa.go

Co-Authored-By: Livio Amstutz <livio.a@gmail.com>

* Update internal/user/repository/eventsourcing/model/mfa.go

Co-Authored-By: Livio Amstutz <livio.a@gmail.com>

* Update internal/user/repository/eventsourcing/model/password.go

Co-Authored-By: Livio Amstutz <livio.a@gmail.com>

* Update internal/user/repository/eventsourcing/model/password.go

Co-Authored-By: Livio Amstutz <livio.a@gmail.com>

* Update internal/user/repository/eventsourcing/model/password.go

Co-Authored-By: Livio Amstutz <livio.a@gmail.com>

* Update internal/user/repository/eventsourcing/model/phone.go

Co-Authored-By: Livio Amstutz <livio.a@gmail.com>

* Update internal/user/repository/eventsourcing/model/phone.go

Co-Authored-By: Livio Amstutz <livio.a@gmail.com>

* Update internal/user/repository/eventsourcing/model/phone.go

Co-Authored-By: Livio Amstutz <livio.a@gmail.com>

* Update internal/user/repository/eventsourcing/model/user.go

Co-Authored-By: Livio Amstutz <livio.a@gmail.com>

* Update internal/user/repository/eventsourcing/model/user.go

Co-Authored-By: Livio Amstutz <livio.a@gmail.com>

* Update internal/user/repository/eventsourcing/model/user.go

Co-Authored-By: Livio Amstutz <livio.a@gmail.com>

* Update internal/usergrant/repository/eventsourcing/model/user_grant.go

Co-Authored-By: Livio Amstutz <livio.a@gmail.com>

* Update internal/usergrant/repository/eventsourcing/model/user_grant.go

Co-Authored-By: Livio Amstutz <livio.a@gmail.com>

* Update internal/usergrant/repository/eventsourcing/user_grant.go

Co-Authored-By: Livio Amstutz <livio.a@gmail.com>

* Update internal/user/repository/eventsourcing/user_test.go

Co-Authored-By: Livio Amstutz <livio.a@gmail.com>

* Update internal/user/repository/eventsourcing/eventstore_mock_test.go

Co-Authored-By: Livio Amstutz <livio.a@gmail.com>

* changes from mr review

* save files into basedir

* changes from mr review

* changes from mr review

* move to auth request

* Update internal/usergrant/repository/eventsourcing/cache.go

Co-authored-by: Silvan <silvan.reusser@gmail.com>

* Update internal/usergrant/repository/eventsourcing/cache.go

Co-authored-by: Silvan <silvan.reusser@gmail.com>

* changes requested on mr

* fix generate codes

* fix return if no events

* password code

* email verification step

* more steps

* lot of mfa

* begin tests

* more next steps

* auth api

* auth api (user)

* auth api (user)

* auth api (user)

* differ requests

* merge

* tests

* fix compilation error

* mock for id generator

* Update internal/user/repository/eventsourcing/model/password.go

Co-authored-by: Silvan <silvan.reusser@gmail.com>

* Update internal/user/repository/eventsourcing/model/user.go

Co-authored-by: Silvan <silvan.reusser@gmail.com>

* requests of mr

* check email

* begin separation of command and query

* otp

* change packages

* some cleanup and fixes

* tests for auth request / next steps

* add VerificationLifetimes to config and make it run

* tests

* fix code challenge validation

* cleanup

* fix merge

* begin view

* repackaging tests and configs

* fix startup config for auth

* add migration

* add PromptSelectAccount

* fix copy / paste

* remove user_agent files

* fixes

* fix sequences in user_session

* token commands

* token queries and signout

* fix

* fix set password test

* add token handler and table

* handle session init

* add session state

* add user view test cases

* change VerifyMyMfaOTP

* some fixes

* fix user repo in auth api

* cleanup

* add user session view test

* fix merge

* begin oidc

* user agent and more

* config

* keys

* key command and query

* add login statics

* key handler

* start login

* login handlers

* lot of fixes

* merge oidc

* add missing exports

* add missing exports

* fix some bugs

* authrequestid in htmls

* getrequest

* update auth request

* fix userid check

* add username to authrequest

* fix user session and auth request handling

* fix UserSessionsByAgentID

* fix auth request tests

* fix user session on UserPasswordChanged and MfaOtpRemoved

* fix MfaTypesSetupPossible

* handle mfa

* fill username

* auth request query checks new events

* fix userSessionByIDs

* fix tokens

* fix userSessionByIDs test

* add user selection

* init code

* user code creation date

* add init user step

* add verification failed types

* add verification failures

* verify init code

* user init code handle

* user init code handle

* fix userSessionByIDs

* update logging

* user agent cookie

* browserinfo from request

* add DeleteAuthRequest

* add static login files to binary

* add login statik to build

* move generate to separate file and remove statik.go files

* remove static dirs from startup.yaml

* generate into separate namespaces

* merge master

* auth request code

* auth request type mapping

* fix keys

* improve tokens

* improve register and basic styling

* fix ailerons font

* improve password reset

* add audience to token

* all oidc apps as audience

* fix test nextStep

* fix email texts

* remove "not set"

* lot of style changes

* improve copy to clipboard

* fix footer

* add cookie handler

* remove placeholders

* fix compilation after merge

* fix auth config

* remove comments

* typo

* use new secrets store

* change default pws to match default policy

* fixes

* add todo

* enable login

* fix db name

* Auth queries (#179)

* my usersession

* org structure/ auth handlers

* working user grant spooler

* auth internal user grants

* search my project orgs

* remove permissions file

* my zitadel permissions

* my zitadel permissions

* remove unused code

* authz

* app searches in view

* token verification

* fix user grant load

* fix tests

* fix tests

* read configs

* remove unused const

* remove todos

* env variables

* app_name

* working authz

* search projects

* global resourceowner

* Update internal/api/auth/permissions.go

Co-authored-by: Livio Amstutz <livio.a@gmail.com>

* Update internal/api/auth/permissions.go

Co-authored-by: Livio Amstutz <livio.a@gmail.com>

* model2 rename

* at least it works

* check token expiry

* search my user grants

* remove token table from authz

Co-authored-by: Livio Amstutz <livio.a@gmail.com>

* fix test

* fix ports and enable console

Co-authored-by: Fabiennne <fabienne.gerschwiler@gmail.com>
Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com>
Co-authored-by: Silvan <silvan.reusser@gmail.com>
This commit is contained in:
Livio Amstutz
2020-06-05 07:50:04 +02:00
committed by GitHub
parent 46b60a6968
commit 8a5badddf6
293 changed files with 14189 additions and 3176 deletions

46
internal/key/model/key.go Normal file
View File

@@ -0,0 +1,46 @@
package model
import (
"time"
"github.com/caos/zitadel/internal/crypto"
es_models "github.com/caos/zitadel/internal/eventstore/models"
)
type KeyPair struct {
es_models.ObjectRoot
Usage KeyUsage
Algorithm string
PrivateKey *Key
PublicKey *Key
}
type KeyUsage int32
const (
KeyUsageSigning KeyUsage = iota
)
func (u KeyUsage) String() string {
switch u {
case KeyUsageSigning:
return "sig"
}
return ""
}
type Key struct {
Key *crypto.CryptoValue
Expiry time.Time
}
func (k *KeyPair) IsValid() bool {
return k.Algorithm != "" &&
k.PrivateKey != nil && k.PrivateKey.IsValid() &&
k.PublicKey != nil && k.PublicKey.IsValid()
}
func (k *Key) IsValid() bool {
return k.Key != nil
}

View File

@@ -0,0 +1,120 @@
package model
import (
"time"
"github.com/caos/zitadel/internal/crypto"
"github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/model"
)
type KeyView struct {
ID string
Private bool
Expiry time.Time
Algorithm string
Usage KeyUsage
Key *crypto.CryptoValue
Sequence uint64
}
type SigningKey struct {
ID string
Algorithm string
Key interface{}
}
type PublicKey struct {
ID string
Algorithm string
Usage KeyUsage
Key interface{}
}
type KeySearchRequest struct {
Offset uint64
Limit uint64
SortingColumn KeySearchKey
Asc bool
Queries []*KeySearchQuery
}
type KeySearchKey int32
const (
KEYSEARCHKEY_UNSPECIFIED KeySearchKey = iota
KEYSEARCHKEY_ID
KEYSEARCHKEY_PRIVATE
KEYSEARCHKEY_EXPIRY
KEYSEARCHKEY_USAGE
)
type KeySearchQuery struct {
Key KeySearchKey
Method model.SearchMethod
Value interface{}
}
type KeySearchResponse struct {
Offset uint64
Limit uint64
TotalResult uint64
Result []*KeyView
}
func (r *KeySearchRequest) EnsureLimit(limit uint64) {
if r.Limit == 0 || r.Limit > limit {
r.Limit = limit
}
}
func SigningKeyFromKeyView(key *KeyView, alg crypto.EncryptionAlgorithm) (*SigningKey, error) {
if key.Usage != KeyUsageSigning || !key.Private {
return nil, errors.ThrowInvalidArgument(nil, "MODEL-5HBdh", "key must be private signing key")
}
keyData, err := crypto.Decrypt(key.Key, alg)
if err != nil {
return nil, err
}
privateKey, err := crypto.BytesToPrivateKey(keyData)
if err != nil {
return nil, err
}
return &SigningKey{
ID: key.ID,
Algorithm: key.Algorithm,
Key: privateKey,
}, nil
}
func PublicKeysFromKeyView(keys []*KeyView, alg crypto.EncryptionAlgorithm) ([]*PublicKey, error) {
converted := make([]*PublicKey, len(keys))
var err error
for i, key := range keys {
converted[i], err = PublicKeyFromKeyView(key, alg)
if err != nil {
return nil, err
}
}
return converted, nil
}
func PublicKeyFromKeyView(key *KeyView, alg crypto.EncryptionAlgorithm) (*PublicKey, error) {
if key.Private {
return nil, errors.ThrowInvalidArgument(nil, "MODEL-dTZa2", "key must be public")
}
keyData, err := crypto.Decrypt(key.Key, alg)
if err != nil {
return nil, err
}
publicKey, err := crypto.BytesToPublicKey(keyData)
if err != nil {
return nil, err
}
return &PublicKey{
ID: key.ID,
Algorithm: key.Algorithm,
Usage: key.Usage,
Key: publicKey,
}, nil
}

View File

@@ -0,0 +1,84 @@
package eventsourcing
import (
"context"
"time"
"github.com/caos/zitadel/internal/config/types"
"github.com/caos/zitadel/internal/crypto"
caos_errs "github.com/caos/zitadel/internal/errors"
es_int "github.com/caos/zitadel/internal/eventstore"
"github.com/caos/zitadel/internal/eventstore/models"
es_sdk "github.com/caos/zitadel/internal/eventstore/sdk"
"github.com/caos/zitadel/internal/id"
key_model "github.com/caos/zitadel/internal/key/model"
"github.com/caos/zitadel/internal/key/repository/eventsourcing/model"
)
type KeyEventstore struct {
es_int.Eventstore
keySize int
keyAlgorithm crypto.EncryptionAlgorithm
privateKeyLifetime time.Duration
publicKeyLifetime time.Duration
idGenerator id.Generator
}
type KeyConfig struct {
Size int
PrivateKeyLifetime types.Duration
PublicKeyLifetime types.Duration
EncryptionConfig *crypto.KeyConfig
SigningKeyRotation types.Duration
}
func StartKey(eventstore es_int.Eventstore, config KeyConfig, keyAlgorithm crypto.EncryptionAlgorithm, generator id.Generator) (*KeyEventstore, error) {
return &KeyEventstore{
Eventstore: eventstore,
keySize: config.Size,
keyAlgorithm: keyAlgorithm,
privateKeyLifetime: config.PrivateKeyLifetime.Duration,
publicKeyLifetime: config.PublicKeyLifetime.Duration,
idGenerator: generator,
}, nil
}
func (es *KeyEventstore) GenerateKeyPair(ctx context.Context, usage key_model.KeyUsage, algorithm string) (*key_model.KeyPair, error) {
privateKey, publicKey, err := crypto.GenerateEncryptedKeyPair(es.keySize, es.keyAlgorithm)
if err != nil {
return nil, err
}
privateKeyExp := time.Now().UTC().Add(es.privateKeyLifetime)
publicKeyExp := time.Now().UTC().Add(es.publicKeyLifetime)
return es.CreateKeyPair(ctx, &key_model.KeyPair{
ObjectRoot: models.ObjectRoot{},
Usage: usage,
Algorithm: algorithm,
PrivateKey: &key_model.Key{
Key: privateKey,
Expiry: privateKeyExp,
},
PublicKey: &key_model.Key{
Key: publicKey,
Expiry: publicKeyExp,
},
})
}
func (es *KeyEventstore) CreateKeyPair(ctx context.Context, pair *key_model.KeyPair) (*key_model.KeyPair, error) {
if !pair.IsValid() {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-G34ga", "Name is required")
}
id, err := es.idGenerator.Next()
if err != nil {
return nil, err
}
pair.AggregateID = id
repoKey := model.KeyPairFromModel(pair)
createAggregate := KeyPairCreateAggregate(es.AggregateCreator(), repoKey)
err = es_sdk.Push(ctx, es.PushAggregates, repoKey.AppendEvents, createAggregate)
if err != nil {
return nil, err
}
return model.KeyPairToModel(repoKey), nil
}

View File

@@ -0,0 +1,33 @@
package eventsourcing
import (
"context"
"github.com/caos/zitadel/internal/errors"
es_models "github.com/caos/zitadel/internal/eventstore/models"
"github.com/caos/zitadel/internal/key/repository/eventsourcing/model"
)
func KeyPairQuery(latestSequence uint64) *es_models.SearchQuery {
return es_models.NewSearchQuery().
AggregateTypeFilter(model.KeyPairAggregate).
LatestSequenceFilter(latestSequence)
}
func KeyPairAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, pair *model.KeyPair) (*es_models.Aggregate, error) {
if pair == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-d5HNJA", "existing key pair must not be nil")
}
return aggCreator.NewAggregate(ctx, pair.AggregateID, model.KeyPairAggregate, model.KeyPairVersion, pair.Sequence)
}
func KeyPairCreateAggregate(aggCreator *es_models.AggregateCreator, pair *model.KeyPair) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
agg, err := KeyPairAggregate(ctx, aggCreator, pair)
if err != nil {
return nil, err
}
return agg.AppendEvent(model.KeyPairAdded, pair)
}
}

View File

@@ -0,0 +1,90 @@
package model
import (
"encoding/json"
"time"
"github.com/caos/logging"
"github.com/caos/zitadel/internal/crypto"
es_models "github.com/caos/zitadel/internal/eventstore/models"
"github.com/caos/zitadel/internal/key/model"
)
const (
KeyPairVersion = "v1"
)
type KeyPair struct {
es_models.ObjectRoot
Usage int32 `json:"usage"`
Algorithm string `json:"algorithm"`
PrivateKey *Key `json:"privateKey"`
PublicKey *Key `json:"publicKey"`
}
type Key struct {
Key *crypto.CryptoValue `json:"key"`
Expiry time.Time `json:"expiry"`
}
func KeyPairFromModel(pair *model.KeyPair) *KeyPair {
return &KeyPair{
ObjectRoot: pair.ObjectRoot,
Usage: int32(pair.Usage),
Algorithm: pair.Algorithm,
PrivateKey: KeyFromModel(pair.PrivateKey),
PublicKey: KeyFromModel(pair.PublicKey),
}
}
func KeyPairToModel(pair *KeyPair) *model.KeyPair {
return &model.KeyPair{
ObjectRoot: pair.ObjectRoot,
Usage: model.KeyUsage(pair.Usage),
Algorithm: pair.Algorithm,
PrivateKey: KeyToModel(pair.PrivateKey),
PublicKey: KeyToModel(pair.PublicKey),
}
}
func KeyFromModel(key *model.Key) *Key {
return &Key{
Key: key.Key,
Expiry: key.Expiry,
}
}
func KeyToModel(key *Key) *model.Key {
return &model.Key{
Key: key.Key,
Expiry: key.Expiry,
}
}
func (k *KeyPair) AppendEvents(events ...*es_models.Event) error {
for _, event := range events {
if err := k.AppendEvent(event); err != nil {
return err
}
}
return nil
}
func (k *KeyPair) AppendEvent(event *es_models.Event) error {
k.ObjectRoot.AppendEvent(event)
switch event.Type {
case KeyPairAdded:
return k.AppendAddKeyPair(event)
}
return nil
}
func (k *KeyPair) AppendAddKeyPair(event *es_models.Event) error {
if err := json.Unmarshal(event.Data, k); err != nil {
logging.Log("EVEN-Je92s").WithError(err).Error("could not unmarshal event data")
return err
}
return nil
}

View File

@@ -0,0 +1,9 @@
package model
import "github.com/caos/zitadel/internal/eventstore/models"
const (
KeyPairAggregate models.AggregateType = "key_pair"
KeyPairAdded models.EventType = "key_pair.added"
)

View File

@@ -0,0 +1,70 @@
package view
import (
"time"
"github.com/jinzhu/gorm"
key_model "github.com/caos/zitadel/internal/key/model"
"github.com/caos/zitadel/internal/key/repository/view/model"
global_model "github.com/caos/zitadel/internal/model"
"github.com/caos/zitadel/internal/view"
)
func KeyByIDAndType(db *gorm.DB, table, keyID string, private bool) (*model.KeyView, error) {
key := new(model.KeyView)
query := view.PrepareGetByQuery(table,
model.KeySearchQuery{Key: key_model.KEYSEARCHKEY_ID, Method: global_model.SEARCHMETHOD_EQUALS, Value: keyID},
model.KeySearchQuery{Key: key_model.KEYSEARCHKEY_PRIVATE, Method: global_model.SEARCHMETHOD_EQUALS, Value: private},
)
err := query(db, key)
return key, err
}
func GetSigningKey(db *gorm.DB, table string) (*model.KeyView, error) {
key := new(model.KeyView)
query := view.PrepareGetByQuery(table,
model.KeySearchQuery{Key: key_model.KEYSEARCHKEY_PRIVATE, Method: global_model.SEARCHMETHOD_EQUALS, Value: true},
model.KeySearchQuery{Key: key_model.KEYSEARCHKEY_USAGE, Method: global_model.SEARCHMETHOD_EQUALS, Value: key_model.KeyUsageSigning},
model.KeySearchQuery{Key: key_model.KEYSEARCHKEY_EXPIRY, Method: global_model.SEARCHMETHOD_GREATER_THAN, Value: time.Now().UTC()},
)
err := query(db, key)
return key, err
}
func GetActivePublicKeys(db *gorm.DB, table string) ([]*model.KeyView, error) {
keys := make([]*model.KeyView, 0)
query := view.PrepareSearchQuery(table,
model.KeySearchRequest{
Queries: []*key_model.KeySearchQuery{
{Key: key_model.KEYSEARCHKEY_PRIVATE, Method: global_model.SEARCHMETHOD_EQUALS, Value: false},
{Key: key_model.KEYSEARCHKEY_USAGE, Method: global_model.SEARCHMETHOD_EQUALS, Value: key_model.KeyUsageSigning},
{Key: key_model.KEYSEARCHKEY_EXPIRY, Method: global_model.SEARCHMETHOD_GREATER_THAN, Value: time.Now().UTC()},
},
},
)
_, err := query(db, &keys)
return keys, err
}
func PutKeys(db *gorm.DB, table string, privateKey, publicKey *model.KeyView) error {
save := view.PrepareSave(table)
err := save(db, privateKey)
if err != nil {
return err
}
return save(db, publicKey)
}
func DeleteKey(db *gorm.DB, table, keyID string, private bool) error {
delete := view.PrepareDeleteByKeys(table,
view.Key{Key: model.KeySearchKey(key_model.KEYSEARCHKEY_ID), Value: keyID},
view.Key{Key: model.KeySearchKey(key_model.KEYSEARCHKEY_PRIVATE), Value: private},
)
return delete(db)
}
func DeleteKeyPair(db *gorm.DB, table, keyID string) error {
delete := view.PrepareDeleteByKey(table, model.KeySearchKey(key_model.KEYSEARCHKEY_ID), keyID)
return delete(db)
}

View File

@@ -0,0 +1,88 @@
package model
import (
"database/sql"
"encoding/json"
"time"
"github.com/caos/logging"
"github.com/caos/zitadel/internal/crypto"
caos_errs "github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/eventstore/models"
"github.com/caos/zitadel/internal/key/model"
es_model "github.com/caos/zitadel/internal/key/repository/eventsourcing/model"
)
const (
KeyKeyID = "id"
KeyPrivate = "private"
KeyUsage = "usage"
KeyAlgorithm = "algorithm"
KeyExpiry = "expiry"
)
type KeyView struct {
ID string `json:"-" gorm:"column:id;primary_key"`
Private sql.NullBool `json:"-" gorm:"column:private;primary_key"`
Expiry time.Time `json:"-" gorm:"column:expiry"`
Algorithm string `json:"-" gorm:"column:algorithm"`
Usage int32 `json:"-" gorm:"column:usage"`
Key *crypto.CryptoValue `json:"-" gorm:"column:key"`
Sequence uint64 `json:"-" gorm:"column:sequence"`
}
func KeysFromPairEvent(event *models.Event) (*KeyView, *KeyView, error) {
pair := new(es_model.KeyPair)
if err := json.Unmarshal(event.Data, pair); err != nil {
logging.Log("MODEL-s3Ga1").WithError(err).Error("could not unmarshal event data")
return nil, nil, caos_errs.ThrowInternal(nil, "MODEL-G3haa", "could not unmarshal data")
}
privateKey := &KeyView{
ID: event.AggregateID,
Private: sql.NullBool{Bool: true, Valid: true},
Expiry: pair.PrivateKey.Expiry,
Algorithm: pair.Algorithm,
Usage: pair.Usage,
Key: pair.PrivateKey.Key,
Sequence: pair.Sequence,
}
publicKey := &KeyView{
ID: event.AggregateID,
Private: sql.NullBool{Bool: false, Valid: true},
Expiry: pair.PublicKey.Expiry,
Algorithm: pair.Algorithm,
Usage: pair.Usage,
Key: pair.PublicKey.Key,
Sequence: pair.Sequence,
}
return privateKey, publicKey, nil
}
func KeyViewsToModel(keys []*KeyView) []*model.KeyView {
converted := make([]*model.KeyView, len(keys))
for i, key := range keys {
converted[i] = KeyViewToModel(key)
}
return converted
}
func KeyViewToModel(key *KeyView) *model.KeyView {
return &model.KeyView{
ID: key.ID,
Private: key.Private.Bool,
Expiry: key.Expiry,
Algorithm: key.Algorithm,
Usage: model.KeyUsage(key.Usage),
Key: key.Key,
Sequence: key.Sequence,
}
}
func (k *KeyView) setData(event *models.Event) error {
if err := json.Unmarshal(event.Data, k); err != nil {
logging.Log("MODEL-4ag41").WithError(err).Error("could not unmarshal event data")
return caos_errs.ThrowInternal(nil, "MODEL-GFQ31", "could not unmarshal data")
}
return nil
}

View File

@@ -0,0 +1,65 @@
package model
import (
key_model "github.com/caos/zitadel/internal/key/model"
global_model "github.com/caos/zitadel/internal/model"
"github.com/caos/zitadel/internal/view"
)
type KeySearchRequest key_model.KeySearchRequest
type KeySearchQuery key_model.KeySearchQuery
type KeySearchKey key_model.KeySearchKey
func (req KeySearchRequest) GetLimit() uint64 {
return req.Limit
}
func (req KeySearchRequest) GetOffset() uint64 {
return req.Offset
}
func (req KeySearchRequest) GetSortingColumn() view.ColumnKey {
if req.SortingColumn == key_model.KEYSEARCHKEY_UNSPECIFIED {
return nil
}
return KeySearchKey(req.SortingColumn)
}
func (req KeySearchRequest) GetAsc() bool {
return req.Asc
}
func (req KeySearchRequest) GetQueries() []view.SearchQuery {
result := make([]view.SearchQuery, len(req.Queries))
for i, q := range req.Queries {
result[i] = KeySearchQuery{Key: q.Key, Value: q.Value, Method: q.Method}
}
return result
}
func (req KeySearchQuery) GetKey() view.ColumnKey {
return KeySearchKey(req.Key)
}
func (req KeySearchQuery) GetMethod() global_model.SearchMethod {
return req.Method
}
func (req KeySearchQuery) GetValue() interface{} {
return req.Value
}
func (key KeySearchKey) ToColumnName() string {
switch key_model.KeySearchKey(key) {
case key_model.KEYSEARCHKEY_ID:
return KeyKeyID
case key_model.KEYSEARCHKEY_PRIVATE:
return KeyPrivate
case key_model.KEYSEARCHKEY_USAGE:
return KeyUsage
case key_model.KEYSEARCHKEY_EXPIRY:
return KeyExpiry
default:
return ""
}
}