fix(auth): always get token by id and user id (#4371)

Co-authored-by: Florian Forster <florian@zitadel.com>
This commit is contained in:
Silvan 2022-09-15 14:59:40 +02:00 committed by GitHub
parent 7191344817
commit 84b20bc4e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 19 additions and 16 deletions

2
.gitignore vendored
View File

@ -65,3 +65,5 @@ migrations/cockroach/migrate_cloud.go
!/.artifacts/zitadel !/.artifacts/zitadel
/zitadel /zitadel
go.work
go.work.sum

View File

@ -174,7 +174,7 @@ func (o *OPStorage) RevokeToken(ctx context.Context, token, userID, clientID str
} }
return oidc.ErrServerError().WithParent(err) return oidc.ErrServerError().WithParent(err)
} }
accessToken, err := o.repo.TokenByID(ctx, userID, token) accessToken, err := o.repo.TokenByIDs(ctx, userID, token)
if err != nil { if err != nil {
if errors.IsNotFound(err) { if errors.IsNotFound(err) {
return nil return nil

View File

@ -119,7 +119,7 @@ func (o *OPStorage) AuthorizeClientIDSecret(ctx context.Context, id string, secr
func (o *OPStorage) SetUserinfoFromToken(ctx context.Context, userInfo oidc.UserInfoSetter, tokenID, subject, origin string) (err error) { func (o *OPStorage) SetUserinfoFromToken(ctx context.Context, userInfo oidc.UserInfoSetter, tokenID, subject, origin string) (err error) {
ctx, span := tracing.NewSpan(ctx) ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }() defer func() { span.EndWithError(err) }()
token, err := o.repo.TokenByID(ctx, subject, tokenID) token, err := o.repo.TokenByIDs(ctx, subject, tokenID)
if err != nil { if err != nil {
return errors.ThrowPermissionDenied(nil, "OIDC-Dsfb2", "token is not valid or has expired") return errors.ThrowPermissionDenied(nil, "OIDC-Dsfb2", "token is not valid or has expired")
} }
@ -154,7 +154,7 @@ func (o *OPStorage) SetUserinfoFromScopes(ctx context.Context, userInfo oidc.Use
} }
func (o *OPStorage) SetIntrospectionFromToken(ctx context.Context, introspection oidc.IntrospectionResponse, tokenID, subject, clientID string) error { func (o *OPStorage) SetIntrospectionFromToken(ctx context.Context, introspection oidc.IntrospectionResponse, tokenID, subject, clientID string) error {
token, err := o.repo.TokenByID(ctx, subject, tokenID) token, err := o.repo.TokenByIDs(ctx, subject, tokenID)
if err != nil { if err != nil {
return errors.ThrowPermissionDenied(nil, "OIDC-Dsfb2", "token is not valid or has expired") return errors.ThrowPermissionDenied(nil, "OIDC-Dsfb2", "token is not valid or has expired")
} }

View File

@ -23,7 +23,7 @@ type TokenRepo struct {
} }
func (repo *TokenRepo) IsTokenValid(ctx context.Context, userID, tokenID string) (bool, error) { func (repo *TokenRepo) IsTokenValid(ctx context.Context, userID, tokenID string) (bool, error) {
token, err := repo.TokenByID(ctx, userID, tokenID) token, err := repo.TokenByIDs(ctx, userID, tokenID)
if err == nil { if err == nil {
return token.Expiration.After(time.Now().UTC()), nil return token.Expiration.After(time.Now().UTC()), nil
} }
@ -33,8 +33,8 @@ func (repo *TokenRepo) IsTokenValid(ctx context.Context, userID, tokenID string)
return false, err return false, err
} }
func (repo *TokenRepo) TokenByID(ctx context.Context, userID, tokenID string) (*usr_model.TokenView, error) { func (repo *TokenRepo) TokenByIDs(ctx context.Context, userID, tokenID string) (*usr_model.TokenView, error) {
token, viewErr := repo.View.TokenByID(tokenID, authz.GetInstance(ctx).InstanceID()) token, viewErr := repo.View.TokenByIDs(tokenID, userID, authz.GetInstance(ctx).InstanceID())
if viewErr != nil && !errors.IsNotFound(viewErr) { if viewErr != nil && !errors.IsNotFound(viewErr) {
return nil, viewErr return nil, viewErr
} }

View File

@ -12,8 +12,8 @@ const (
tokenTable = "auth.tokens" tokenTable = "auth.tokens"
) )
func (v *View) TokenByID(tokenID, instanceID string) (*model.TokenView, error) { func (v *View) TokenByIDs(tokenID, userID, instanceID string) (*model.TokenView, error) {
return usr_view.TokenByID(v.Db, tokenTable, tokenID, instanceID) return usr_view.TokenByIDs(v.Db, tokenTable, tokenID, userID, instanceID)
} }
func (v *View) TokensByUserID(userID, instanceID string) ([]*model.TokenView, error) { func (v *View) TokensByUserID(userID, instanceID string) ([]*model.TokenView, error) {

View File

@ -8,5 +8,5 @@ import (
type TokenRepository interface { type TokenRepository interface {
IsTokenValid(ctx context.Context, userID, tokenID string) (bool, error) IsTokenValid(ctx context.Context, userID, tokenID string) (bool, error)
TokenByID(ctx context.Context, userID, tokenID string) (*usr_model.TokenView, error) TokenByIDs(ctx context.Context, userID, tokenID string) (*usr_model.TokenView, error)
} }

View File

@ -49,7 +49,7 @@ func (repo *TokenVerifierRepo) tokenByID(ctx context.Context, tokenID, userID st
OnError(err). OnError(err).
Errorf("could not get current sequence for token check") Errorf("could not get current sequence for token check")
token, viewErr := repo.View.TokenByID(tokenID, instanceID) token, viewErr := repo.View.TokenByIDs(tokenID, userID, instanceID)
if viewErr != nil && !caos_errs.IsNotFound(viewErr) { if viewErr != nil && !caos_errs.IsNotFound(viewErr) {
return nil, viewErr return nil, viewErr
} }
@ -146,7 +146,7 @@ func (repo *TokenVerifierRepo) getUserEvents(ctx context.Context, userID, instan
return repo.Eventstore.FilterEvents(ctx, query) return repo.Eventstore.FilterEvents(ctx, query)
} }
//getTokenIDAndSubject returns the TokenID and Subject of both opaque tokens and JWTs // getTokenIDAndSubject returns the TokenID and Subject of both opaque tokens and JWTs
func (repo *TokenVerifierRepo) getTokenIDAndSubject(ctx context.Context, accessToken string) (tokenID string, subject string, valid bool) { func (repo *TokenVerifierRepo) getTokenIDAndSubject(ctx context.Context, accessToken string) (tokenID string, subject string, valid bool) {
// accessToken can be either opaque or JWT // accessToken can be either opaque or JWT
// let's try opaque first: // let's try opaque first:
@ -188,8 +188,8 @@ type openIDKeySet struct {
*query.Queries *query.Queries
} }
//VerifySignature implements the oidc.KeySet interface // VerifySignature implements the oidc.KeySet interface
//providing an implementation for the keys retrieved directly from Queries // providing an implementation for the keys retrieved directly from Queries
func (o *openIDKeySet) VerifySignature(ctx context.Context, jws *jose.JSONWebSignature) ([]byte, error) { func (o *openIDKeySet) VerifySignature(ctx context.Context, jws *jose.JSONWebSignature) ([]byte, error) {
keySet, err := o.Queries.ActivePublicKeys(ctx, time.Now()) keySet, err := o.Queries.ActivePublicKeys(ctx, time.Now())
if err != nil { if err != nil {

View File

@ -12,8 +12,8 @@ const (
tokenTable = "auth.tokens" tokenTable = "auth.tokens"
) )
func (v *View) TokenByID(tokenID, instanceID string) (*usr_view_model.TokenView, error) { func (v *View) TokenByIDs(tokenID, userID, instanceID string) (*usr_view_model.TokenView, error) {
return usr_view.TokenByID(v.Db, tokenTable, tokenID, instanceID) return usr_view.TokenByIDs(v.Db, tokenTable, tokenID, userID, instanceID)
} }
func (v *View) PutToken(token *usr_view_model.TokenView, event *models.Event) error { func (v *View) PutToken(token *usr_view_model.TokenView, event *models.Event) error {

View File

@ -10,10 +10,11 @@ import (
"github.com/zitadel/zitadel/internal/view/repository" "github.com/zitadel/zitadel/internal/view/repository"
) )
func TokenByID(db *gorm.DB, table, tokenID, instanceID string) (*usr_model.TokenView, error) { func TokenByIDs(db *gorm.DB, table, tokenID, userID, instanceID string) (*usr_model.TokenView, error) {
token := new(usr_model.TokenView) token := new(usr_model.TokenView)
query := repository.PrepareGetByQuery(table, query := repository.PrepareGetByQuery(table,
&usr_model.TokenSearchQuery{Key: model.TokenSearchKeyTokenID, Method: domain.SearchMethodEquals, Value: tokenID}, &usr_model.TokenSearchQuery{Key: model.TokenSearchKeyTokenID, Method: domain.SearchMethodEquals, Value: tokenID},
&usr_model.TokenSearchQuery{Key: model.TokenSearchKeyUserID, Method: domain.SearchMethodEquals, Value: userID},
&usr_model.TokenSearchQuery{Key: model.TokenSearchKeyInstanceID, Method: domain.SearchMethodEquals, Value: instanceID}, &usr_model.TokenSearchQuery{Key: model.TokenSearchKeyInstanceID, Method: domain.SearchMethodEquals, Value: instanceID},
) )
err := query(db, token) err := query(db, token)