feat: token introspection, api clients and auth method private_key_jwt (#1276)

* introspect

* testingapplication key

* date

* client keys

* fix client keys

* fix client keys

* access tokens only for users

* AuthMethodPrivateKeyJWT

* client keys

* set introspection info correctly

* managae apis

* update oidc pkg

* cleanup

* merge msater

* set current sequence in migration

* set current sequence in migration

* set current sequence in migration

* Apply suggestions from code review

Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com>

* DeleteAuthNKeysByObjectID

* ensure authn keys uptodate

* update oidc version

* merge master

* merge master

Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com>
This commit is contained in:
Livio Amstutz
2021-02-17 15:31:47 +01:00
committed by GitHub
parent 39eb172804
commit 744185449e
64 changed files with 2275 additions and 836 deletions

View File

@@ -20,6 +20,7 @@ import (
es_sdk "github.com/caos/zitadel/internal/eventstore/sdk"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/internal/id"
key_model "github.com/caos/zitadel/internal/key/model"
global_model "github.com/caos/zitadel/internal/model"
"github.com/caos/zitadel/internal/telemetry/tracing"
usr_model "github.com/caos/zitadel/internal/user/model"
@@ -27,11 +28,6 @@ import (
webauthn_helper "github.com/caos/zitadel/internal/webauthn"
)
const (
yearLayout = "2006-01-02"
defaultExpirationDate = "9999-01-01"
)
type UserEventstore struct {
es_int.Eventstore
userCache *UserCache
@@ -1630,7 +1626,7 @@ func (es *UserEventstore) AddMachineKey(ctx context.Context, key *usr_model.Mach
}
if key.ExpirationDate.IsZero() {
key.ExpirationDate, err = time.Parse(yearLayout, defaultExpirationDate)
key.ExpirationDate, err = key_model.DefaultExpiration()
if err != nil {
logging.Log("EVENT-vzibi").WithError(err).Warn("unable to set default date")
return nil, errors.ThrowInternal(err, "EVENT-j68fg", "Errors.Internal")

View File

@@ -9,6 +9,7 @@ import (
"github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/eventstore/models"
es_models "github.com/caos/zitadel/internal/eventstore/models"
key_model "github.com/caos/zitadel/internal/key/model"
"github.com/caos/zitadel/internal/user/model"
)
@@ -115,7 +116,7 @@ func MachineKeyToModel(machine *MachineKey) *model.MachineKey {
ExpirationDate: machine.ExpirationDate,
KeyID: machine.KeyID,
PrivateKey: machine.privateKey,
Type: model.MachineKeyType(machine.Type),
Type: key_model.AuthNKeyType(machine.Type),
}
}

View File

@@ -1,77 +0,0 @@
package view
import (
caos_errs "github.com/caos/zitadel/internal/errors"
global_model "github.com/caos/zitadel/internal/model"
usr_model "github.com/caos/zitadel/internal/user/model"
"github.com/caos/zitadel/internal/user/repository/view/model"
"github.com/caos/zitadel/internal/view/repository"
"github.com/jinzhu/gorm"
)
func MachineKeyByIDs(db *gorm.DB, table, userID, keyID string) (*model.MachineKeyView, error) {
key := new(model.MachineKeyView)
query := repository.PrepareGetByQuery(table,
model.MachineKeySearchQuery{Key: usr_model.MachineKeyKeyUserID, Method: global_model.SearchMethodEquals, Value: userID},
model.MachineKeySearchQuery{Key: usr_model.MachineKeyKeyID, Method: global_model.SearchMethodEquals, Value: keyID},
)
err := query(db, key)
if caos_errs.IsNotFound(err) {
return nil, caos_errs.ThrowNotFound(nil, "VIEW-3Dk9s", "Errors.User.KeyNotFound")
}
return key, err
}
func SearchMachineKeys(db *gorm.DB, table string, req *usr_model.MachineKeySearchRequest) ([]*model.MachineKeyView, uint64, error) {
members := make([]*model.MachineKeyView, 0)
query := repository.PrepareSearchQuery(table, model.MachineKeySearchRequest{Limit: req.Limit, Offset: req.Offset, Queries: req.Queries})
count, err := query(db, &members)
if err != nil {
return nil, 0, err
}
return members, count, nil
}
func MachineKeysByUserID(db *gorm.DB, table string, userID string) ([]*model.MachineKeyView, error) {
keys := make([]*model.MachineKeyView, 0)
queries := []*usr_model.MachineKeySearchQuery{
{
Key: usr_model.MachineKeyKeyUserID,
Value: userID,
Method: global_model.SearchMethodEquals,
},
}
query := repository.PrepareSearchQuery(table, model.MachineKeySearchRequest{Queries: queries})
_, err := query(db, &keys)
if err != nil {
return nil, err
}
return keys, nil
}
func MachineKeyByID(db *gorm.DB, table string, keyID string) (*model.MachineKeyView, error) {
key := new(model.MachineKeyView)
query := repository.PrepareGetByQuery(table,
model.MachineKeySearchQuery{Key: usr_model.MachineKeyKeyID, Method: global_model.SearchMethodEquals, Value: keyID},
)
err := query(db, key)
if caos_errs.IsNotFound(err) {
return nil, caos_errs.ThrowNotFound(nil, "VIEW-BjN6x", "Errors.User.KeyNotFound")
}
return key, err
}
func PutMachineKey(db *gorm.DB, table string, role *model.MachineKeyView) error {
save := repository.PrepareSave(table)
return save(db, role)
}
func DeleteMachineKey(db *gorm.DB, table, keyID string) error {
delete := repository.PrepareDeleteByKey(table, model.MachineKeySearchKey(usr_model.MachineKeyKeyID), keyID)
return delete(db)
}
func DeleteMachineKeysByUserID(db *gorm.DB, table, userID string) error {
delete := repository.PrepareDeleteByKey(table, model.MachineKeySearchKey(usr_model.MachineKeyKeyUserID), userID)
return delete(db)
}

View File

@@ -1,84 +0,0 @@
package model
import (
"encoding/json"
"time"
"github.com/caos/logging"
caos_errs "github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/eventstore/models"
"github.com/caos/zitadel/internal/user/model"
es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
)
const (
MachineKeyKeyID = "id"
MachineKeyKeyUserID = "user_id"
)
type MachineKeyView struct {
ID string `json:"keyId" gorm:"column:id;primary_key"`
UserID string `json:"-" gorm:"column:user_id;primary_key"`
Type int32 `json:"type" gorm:"column:machine_type"`
ExpirationDate time.Time `json:"expirationDate" gorm:"column:expiration_date"`
Sequence uint64 `json:"-" gorm:"column:sequence"`
CreationDate time.Time `json:"-" gorm:"column:creation_date"`
PublicKey []byte `json:"publicKey" gorm:"column:public_key"`
}
func MachineKeyViewFromModel(key *model.MachineKeyView) *MachineKeyView {
return &MachineKeyView{
ID: key.ID,
UserID: key.UserID,
Type: int32(key.Type),
ExpirationDate: key.ExpirationDate,
Sequence: key.Sequence,
CreationDate: key.CreationDate,
}
}
func MachineKeyToModel(key *MachineKeyView) *model.MachineKeyView {
return &model.MachineKeyView{
ID: key.ID,
UserID: key.UserID,
Type: model.MachineKeyType(key.Type),
ExpirationDate: key.ExpirationDate,
Sequence: key.Sequence,
CreationDate: key.CreationDate,
PublicKey: key.PublicKey,
}
}
func MachineKeysToModel(keys []*MachineKeyView) []*model.MachineKeyView {
result := make([]*model.MachineKeyView, len(keys))
for i, key := range keys {
result[i] = MachineKeyToModel(key)
}
return result
}
func (k *MachineKeyView) AppendEvent(event *models.Event) (err error) {
k.Sequence = event.Sequence
switch event.Type {
case es_model.MachineKeyAdded:
k.setRootData(event)
k.CreationDate = event.CreationDate
err = k.SetData(event)
}
return err
}
func (k *MachineKeyView) setRootData(event *models.Event) {
k.UserID = event.AggregateID
}
func (r *MachineKeyView) SetData(event *models.Event) error {
if err := json.Unmarshal(event.Data, r); err != nil {
logging.Log("EVEN-Sj90d").WithError(err).Error("could not unmarshal event data")
return caos_errs.ThrowInternal(err, "MODEL-lub6s", "Could not unmarshal data")
}
return nil
}

View File

@@ -1,61 +0,0 @@
package model
import (
global_model "github.com/caos/zitadel/internal/model"
usr_model "github.com/caos/zitadel/internal/user/model"
"github.com/caos/zitadel/internal/view/repository"
)
type MachineKeySearchRequest usr_model.MachineKeySearchRequest
type MachineKeySearchQuery usr_model.MachineKeySearchQuery
type MachineKeySearchKey usr_model.MachineKeySearchKey
func (req MachineKeySearchRequest) GetLimit() uint64 {
return req.Limit
}
func (req MachineKeySearchRequest) GetOffset() uint64 {
return req.Offset
}
func (req MachineKeySearchRequest) GetSortingColumn() repository.ColumnKey {
if req.SortingColumn == usr_model.MachineKeyKeyUnspecified {
return nil
}
return MachineKeySearchKey(req.SortingColumn)
}
func (req MachineKeySearchRequest) GetAsc() bool {
return req.Asc
}
func (req MachineKeySearchRequest) GetQueries() []repository.SearchQuery {
result := make([]repository.SearchQuery, len(req.Queries))
for i, q := range req.Queries {
result[i] = MachineKeySearchQuery{Key: q.Key, Value: q.Value, Method: q.Method}
}
return result
}
func (req MachineKeySearchQuery) GetKey() repository.ColumnKey {
return MachineKeySearchKey(req.Key)
}
func (req MachineKeySearchQuery) GetMethod() global_model.SearchMethod {
return req.Method
}
func (req MachineKeySearchQuery) GetValue() interface{} {
return req.Value
}
func (key MachineKeySearchKey) ToColumnName() string {
switch usr_model.MachineKeySearchKey(key) {
case usr_model.MachineKeyKeyID:
return MachineKeyKeyID
case usr_model.MachineKeyKeyUserID:
return MachineKeyKeyUserID
default:
return ""
}
}

View File

@@ -5,6 +5,7 @@ import (
"time"
"github.com/caos/logging"
caos_errs "github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/eventstore/models"
es_models "github.com/caos/zitadel/internal/eventstore/models"