mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-12 04:07:31 +00:00
feat(oidc): token exchange impersonation (#7516)
* add token exchange feature flag * allow setting reason and actor to access tokens * impersonation * set token types and scopes in response * upgrade oidc to working draft state * fix tests * audience and scope validation * id toke and jwt as input * return id tokens * add grant type token exchange to app config * add integration tests * check and deny actors in api calls * fix instance setting tests by triggering projection on write and cleanup * insert sleep statements again * solve linting issues * add translations * pin oidc v3.15.0 * resolve comments, add event translation * fix refreshtoken test * use ValidateAuthReqScopes from oidc * apparently the linter can't make up its mind * persist actor thru refresh tokens and check in tests * remove unneeded triggers
This commit is contained in:
@@ -39,6 +39,7 @@ type RefreshTokenView struct {
|
||||
Expiration time.Time `json:"-" gorm:"column:expiration"`
|
||||
Sequence uint64 `json:"-" gorm:"column:sequence"`
|
||||
InstanceID string `json:"instanceID" gorm:"column:instance_id;primary_key"`
|
||||
Actor TokenActor `json:"actor" gorm:"column:actor"`
|
||||
}
|
||||
|
||||
func RefreshTokenViewsToModel(tokens []*RefreshTokenView) []*usr_model.RefreshTokenView {
|
||||
@@ -66,6 +67,7 @@ func RefreshTokenViewToModel(token *RefreshTokenView) *usr_model.RefreshTokenVie
|
||||
IdleExpiration: token.IdleExpiration,
|
||||
Expiration: token.Expiration,
|
||||
Sequence: token.Sequence,
|
||||
Actor: token.Actor.TokenActor,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,6 +137,7 @@ func (t *RefreshTokenView) appendAddedEvent(event eventstore.Event) error {
|
||||
t.Scopes = e.Scopes
|
||||
t.Token = e.TokenID
|
||||
t.UserAgentID = e.UserAgentID
|
||||
t.Actor = TokenActor{e.Actor}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@@ -1,11 +1,14 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"github.com/zitadel/logging"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/database"
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
user_repo "github.com/zitadel/zitadel/internal/repository/user"
|
||||
usr_model "github.com/zitadel/zitadel/internal/user/model"
|
||||
@@ -40,6 +43,40 @@ type TokenView struct {
|
||||
IsPAT bool `json:"-" gorm:"is_pat"`
|
||||
Deactivated bool `json:"-" gorm:"-"`
|
||||
InstanceID string `json:"instanceID" gorm:"column:instance_id;primary_key"`
|
||||
Actor TokenActor `json:"actor" gorm:"column:actor"`
|
||||
}
|
||||
|
||||
type TokenActor struct {
|
||||
*domain.TokenActor
|
||||
}
|
||||
|
||||
func (a *TokenActor) Scan(value any) error {
|
||||
var data []byte
|
||||
switch v := value.(type) {
|
||||
case nil:
|
||||
a.TokenActor = nil
|
||||
case string:
|
||||
data = []byte(v)
|
||||
case []byte:
|
||||
data = v
|
||||
default:
|
||||
return zerrors.ThrowInternalf(nil, "MODEL-yo8Ae", "cannot scan type %T into %T", v, a)
|
||||
}
|
||||
if err := json.Unmarshal(data, &a.TokenActor); err != nil {
|
||||
return zerrors.ThrowInternal(nil, "MODEL-yo8Ae", "cannot unmarshal token actor")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a TokenActor) Value() (driver.Value, error) {
|
||||
if a.TokenActor == nil {
|
||||
return nil, nil
|
||||
}
|
||||
data, err := json.Marshal(a.TokenActor)
|
||||
if err != nil {
|
||||
return nil, zerrors.ThrowInternal(nil, "MODEL-oD2mi", "cannot marshal token actor")
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func TokenViewToModel(token *TokenView) *usr_model.TokenView {
|
||||
@@ -58,6 +95,7 @@ func TokenViewToModel(token *TokenView) *usr_model.TokenView {
|
||||
PreferredLanguage: token.PreferredLanguage,
|
||||
RefreshTokenID: token.RefreshTokenID,
|
||||
IsPAT: token.IsPAT,
|
||||
Actor: token.Actor.TokenActor,
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user