fix: add register org and key pairs (#1275)

This commit is contained in:
Fabi
2021-02-12 16:51:12 +01:00
committed by GitHub
parent fbc75d89b2
commit 3bc3ef1f2c
20 changed files with 307 additions and 224 deletions

View File

@@ -2,6 +2,7 @@ package command
import (
"context"
"time"
"github.com/caos/zitadel/internal/api/http"
sd "github.com/caos/zitadel/internal/config/systemdefaults"
@@ -11,6 +12,7 @@ import (
global_model "github.com/caos/zitadel/internal/model"
"github.com/caos/zitadel/internal/telemetry/tracing"
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
keypair "github.com/caos/zitadel/internal/v2/repository/keypair"
"github.com/caos/zitadel/internal/v2/repository/org"
proj_repo "github.com/caos/zitadel/internal/v2/repository/project"
usr_repo "github.com/caos/zitadel/internal/v2/repository/user"
@@ -39,6 +41,11 @@ type CommandSide struct {
//TODO: remove global model, or move to domain
multifactors global_model.Multifactors
webauthn *webauthn_helper.WebAuthN
keySize int
keyAlgorithm crypto.EncryptionAlgorithm
privateKeyLifetime time.Duration
publicKeyLifetime time.Duration
}
type Config struct {
@@ -48,15 +55,19 @@ type Config struct {
func StartCommandSide(config *Config) (repo *CommandSide, err error) {
repo = &CommandSide{
eventstore: config.Eventstore,
idGenerator: id.SonyFlakeGenerator,
iamDomain: config.SystemDefaults.Domain,
eventstore: config.Eventstore,
idGenerator: id.SonyFlakeGenerator,
iamDomain: config.SystemDefaults.Domain,
keySize: config.SystemDefaults.KeyConfig.Size,
privateKeyLifetime: config.SystemDefaults.KeyConfig.PrivateKeyLifetime.Duration,
publicKeyLifetime: config.SystemDefaults.KeyConfig.PublicKeyLifetime.Duration,
}
iam_repo.RegisterEventMappers(repo.eventstore)
org.RegisterEventMappers(repo.eventstore)
usr_repo.RegisterEventMappers(repo.eventstore)
usr_grant_repo.RegisterEventMappers(repo.eventstore)
proj_repo.RegisterEventMappers(repo.eventstore)
keypair.RegisterEventMappers(repo.eventstore)
//TODO: simplify!!!!
repo.idpConfigSecretCrypto, err = crypto.NewAESCrypto(config.SystemDefaults.IDPConfigVerificationKey)
@@ -99,6 +110,12 @@ func StartCommandSide(config *Config) (repo *CommandSide, err error) {
return nil, err
}
repo.webauthn = web
keyAlgorithm, err := crypto.NewAESCrypto(config.SystemDefaults.KeyConfig.EncryptionConfig)
if err != nil {
return nil, err
}
repo.keyAlgorithm = keyAlgorithm
return repo, nil
}

View File

@@ -0,0 +1,45 @@
package command
import (
"context"
"github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/internal/crypto"
"github.com/caos/zitadel/internal/v2/domain"
keypair "github.com/caos/zitadel/internal/v2/repository/keypair"
"time"
)
const (
oidcUser = "OIDC"
)
func (r *CommandSide) GenerateSigningKeyPair(ctx context.Context, algorithm string) error {
ctx = setOIDCCtx(ctx)
privateCrypto, publicCrypto, err := crypto.GenerateEncryptedKeyPair(r.keySize, r.keyAlgorithm)
if err != nil {
return err
}
keyID, err := r.idGenerator.Next()
if err != nil {
return err
}
privateKeyExp := time.Now().UTC().Add(r.privateKeyLifetime)
publicKeyExp := time.Now().UTC().Add(r.publicKeyLifetime)
keyPairWriteModel := NewKeyPairWriteModel(keyID, domain.IAMID)
keyAgg := KeyPairAggregateFromWriteModel(&keyPairWriteModel.WriteModel)
keyAgg.PushEvents(
keypair.NewAddedEvent(
ctx,
domain.KeyUsageSigning,
algorithm,
privateCrypto, publicCrypto,
privateKeyExp, publicKeyExp),
)
return r.eventstore.PushAggregate(ctx, keyPairWriteModel, keyAgg)
}
func setOIDCCtx(ctx context.Context) context.Context {
return authz.SetCtxData(ctx, authz.CtxData{UserID: oidcUser, OrgID: domain.IAMID})
}

View File

@@ -0,0 +1,61 @@
package command
import (
"github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/v2/domain"
keypair "github.com/caos/zitadel/internal/v2/repository/keypair"
"github.com/caos/zitadel/internal/v2/repository/project"
)
type KeyPairWriteModel struct {
eventstore.WriteModel
Usage domain.KeyUsage
Algorithm string
PrivateKey *domain.Key
PublicKey *domain.Key
}
func NewKeyPairWriteModel(aggregateID, resourceOwner string) *KeyPairWriteModel {
return &KeyPairWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: aggregateID,
ResourceOwner: resourceOwner,
},
}
}
func (wm *KeyPairWriteModel) AppendEvents(events ...eventstore.EventReader) {
wm.WriteModel.AppendEvents(events...)
}
func (wm *KeyPairWriteModel) Reduce() error {
for _, event := range wm.Events {
switch e := event.(type) {
case *keypair.AddedEvent:
wm.Usage = e.Usage
wm.Algorithm = e.Algorithm
wm.PrivateKey = &domain.Key{
Key: e.PrivateKey.Key,
Expiry: e.PrivateKey.Expiry,
}
wm.PublicKey = &domain.Key{
Key: e.PublicKey.Key,
Expiry: e.PublicKey.Expiry,
}
}
}
return wm.WriteModel.Reduce()
}
func (wm *KeyPairWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, project.AggregateType).
AggregateIDs(wm.AggregateID).
ResourceOwner(wm.ResourceOwner)
}
func KeyPairAggregateFromWriteModel(wm *eventstore.WriteModel) *keypair.Aggregate {
return &keypair.Aggregate{
Aggregate: *eventstore.AggregateFromWriteModel(wm, keypair.AggregateType, keypair.AggregateVersion),
}
}

View File

@@ -0,0 +1,45 @@
package domain
import (
"github.com/caos/zitadel/internal/crypto"
es_models "github.com/caos/zitadel/internal/eventstore/models"
"time"
)
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,14 @@
package usergrant
import (
"github.com/caos/zitadel/internal/eventstore/v2"
)
const (
AggregateType = "key_pair"
AggregateVersion = "v1"
)
type Aggregate struct {
eventstore.Aggregate
}

View File

@@ -0,0 +1,9 @@
package usergrant
import (
"github.com/caos/zitadel/internal/eventstore/v2"
)
func RegisterEventMappers(es *eventstore.Eventstore) {
es.RegisterFilterEventMapper(AddedEventType, AddedEventMapper)
}

View File

@@ -0,0 +1,78 @@
package usergrant
import (
"context"
"encoding/json"
"github.com/caos/zitadel/internal/crypto"
"github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/eventstore/v2/repository"
"github.com/caos/zitadel/internal/v2/domain"
"time"
)
const (
eventTypePrefix = eventstore.EventType("key_pair.")
AddedEventType = eventTypePrefix + "added"
)
type AddedEvent struct {
eventstore.BaseEvent `json:"-"`
Usage domain.KeyUsage `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 (e *AddedEvent) Data() interface{} {
return e
}
func (e *AddedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return nil
}
func NewAddedEvent(
ctx context.Context,
usage domain.KeyUsage,
algorithm string,
privateCrypto,
publicCrypto *crypto.CryptoValue,
privateKeyExpiration,
publicKeyExpiration time.Time) *AddedEvent {
return &AddedEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
ctx,
AddedEventType,
),
Usage: usage,
Algorithm: algorithm,
PrivateKey: &Key{
Key: privateCrypto,
Expiry: privateKeyExpiration,
},
PublicKey: &Key{
Key: publicCrypto,
Expiry: publicKeyExpiration,
},
}
}
func AddedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e := &AddedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event),
}
err := json.Unmarshal(event.Data, e)
if err != nil {
return nil, errors.ThrowInternal(err, "KEY-4n8vs", "unable to unmarshal key pair added")
}
return e, nil
}