feat: refresh token (#1728)

* begin refresh tokens

* refresh tokens

* list and revoke refresh tokens

* handle remove

* tests for refresh tokens

* uniqueness and default expiration

* rename oidc token methods

* cleanup

* migration version

* Update internal/static/i18n/en.yaml

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

* fixes

* feat: update oidc pkg for refresh tokens

Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com>
This commit is contained in:
Livio Amstutz
2021-05-20 13:33:35 +02:00
committed by GitHub
parent bc21eeb114
commit ec5020bebc
36 changed files with 2732 additions and 55 deletions

View File

@@ -0,0 +1,89 @@
package command
import (
"time"
"github.com/caos/zitadel/internal/eventstore"
"github.com/caos/zitadel/internal/domain"
"github.com/caos/zitadel/internal/repository/user"
)
type HumanRefreshTokenWriteModel struct {
eventstore.WriteModel
TokenID string
RefreshToken string
UserState domain.UserState
IdleExpiration time.Time
Expiration time.Time
}
func NewHumanRefreshTokenWriteModel(userID, resourceOwner, tokenID string) *HumanRefreshTokenWriteModel {
return &HumanRefreshTokenWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: userID,
ResourceOwner: resourceOwner,
},
TokenID: tokenID,
}
}
func (wm *HumanRefreshTokenWriteModel) AppendEvents(events ...eventstore.EventReader) {
for _, event := range events {
switch e := event.(type) {
case *user.HumanRefreshTokenAddedEvent:
if wm.TokenID != e.TokenID {
continue
}
wm.WriteModel.AppendEvents(e)
case *user.HumanRefreshTokenRenewedEvent:
if wm.TokenID != e.TokenID {
continue
}
wm.WriteModel.AppendEvents(e)
case *user.HumanRefreshTokenRemovedEvent:
if wm.TokenID != e.TokenID {
continue
}
wm.WriteModel.AppendEvents(e)
}
}
}
func (wm *HumanRefreshTokenWriteModel) Reduce() error {
for _, event := range wm.Events {
switch e := event.(type) {
case *user.HumanRefreshTokenAddedEvent:
wm.TokenID = e.TokenID
wm.RefreshToken = e.TokenID
wm.IdleExpiration = e.CreationDate().Add(e.IdleExpiration)
wm.Expiration = e.CreationDate().Add(e.Expiration)
wm.UserState = domain.UserStateActive
case *user.HumanRefreshTokenRenewedEvent:
if wm.UserState == domain.UserStateActive {
wm.RefreshToken = e.RefreshToken
}
wm.RefreshToken = e.RefreshToken
wm.IdleExpiration = e.CreationDate().Add(e.IdleExpiration)
case *user.HumanRefreshTokenRemovedEvent:
wm.UserState = domain.UserStateDeleted
}
}
return wm.WriteModel.Reduce()
}
func (wm *HumanRefreshTokenWriteModel) Query() *eventstore.SearchQueryBuilder {
query := eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, user.AggregateType).
AggregateIDs(wm.AggregateID).
EventTypes(
user.HumanRefreshTokenAddedType,
user.HumanRefreshTokenRenewedType,
user.HumanRefreshTokenRemovedType,
user.UserRemovedType)
if wm.ResourceOwner != "" {
query.ResourceOwner(wm.ResourceOwner)
}
return query
}