feat(oidc): id token for device authorization (#7088)

* cleanup todo

* pass id token details to oidc

* feat(oidc): id token for device authorization

This changes updates to the newest oidc version,
so the Device Authorization grant can return ID tokens when
the scope `openid` is set.
There is also some refactoring done, so that the eventstore can be
queried directly when polling for state.
The projection is cleaned up to a minimum with only data required for the login UI.

* try to be explicit wit hthe timezone to fix github

* pin oidc v3.8.0

* remove TBD entry
This commit is contained in:
Tim Möhlmann
2023-12-20 14:21:08 +02:00
committed by GitHub
parent e15f6229cd
commit e22689c125
25 changed files with 629 additions and 621 deletions

View File

@@ -1,8 +1,6 @@
package deviceauth
import (
"strings"
"github.com/zitadel/zitadel/internal/eventstore"
)
@@ -13,15 +11,11 @@ const (
DuplicateDeviceCode = "Errors.DeviceCode.AlreadyExists"
)
func deviceCodeUniqueField(clientID, deviceCode string) string {
return strings.Join([]string{clientID, deviceCode}, ":")
}
func NewAddUniqueConstraints(clientID, deviceCode, userCode string) []*eventstore.UniqueConstraint {
func NewAddUniqueConstraints(deviceCode, userCode string) []*eventstore.UniqueConstraint {
return []*eventstore.UniqueConstraint{
eventstore.NewAddEventUniqueConstraint(
UniqueDeviceCode,
deviceCodeUniqueField(clientID, deviceCode),
deviceCode,
DuplicateDeviceCode,
),
eventstore.NewAddEventUniqueConstraint(
@@ -32,11 +26,11 @@ func NewAddUniqueConstraints(clientID, deviceCode, userCode string) []*eventstor
}
}
func NewRemoveUniqueConstraints(clientID, deviceCode, userCode string) []*eventstore.UniqueConstraint {
func NewRemoveUniqueConstraints(deviceCode, userCode string) []*eventstore.UniqueConstraint {
return []*eventstore.UniqueConstraint{
eventstore.NewRemoveUniqueConstraint(
UniqueDeviceCode,
deviceCodeUniqueField(clientID, deviceCode),
deviceCode,
),
eventstore.NewRemoveUniqueConstraint(
UniqueUserCode,

View File

@@ -13,7 +13,6 @@ const (
AddedEventType = eventTypePrefix + "added"
ApprovedEventType = eventTypePrefix + "approved"
CanceledEventType = eventTypePrefix + "canceled"
RemovedEventType = eventTypePrefix + "removed"
)
type AddedEvent struct {
@@ -36,7 +35,7 @@ func (e *AddedEvent) Payload() any {
}
func (e *AddedEvent) UniqueConstraints() []*eventstore.UniqueConstraint {
return NewAddUniqueConstraints(e.ClientID, e.DeviceCode, e.UserCode)
return NewAddUniqueConstraints(e.DeviceCode, e.UserCode)
}
func NewAddedEvent(
@@ -58,7 +57,9 @@ func NewAddedEvent(
type ApprovedEvent struct {
*eventstore.BaseEvent `json:"-"`
Subject string
Subject string
UserAuthMethods []domain.UserAuthMethodType
AuthTime time.Time
}
func (e *ApprovedEvent) SetBaseEvent(b *eventstore.BaseEvent) {
@@ -77,12 +78,16 @@ func NewApprovedEvent(
ctx context.Context,
aggregate *eventstore.Aggregate,
subject string,
userAuthMethods []domain.UserAuthMethodType,
authTime time.Time,
) *ApprovedEvent {
return &ApprovedEvent{
eventstore.NewBaseEventForPush(
ctx, aggregate, ApprovedEventType,
),
subject,
userAuthMethods,
authTime,
}
}
@@ -107,36 +112,3 @@ func (e *CanceledEvent) UniqueConstraints() []*eventstore.UniqueConstraint {
func NewCanceledEvent(ctx context.Context, aggregate *eventstore.Aggregate, reason domain.DeviceAuthCanceled) *CanceledEvent {
return &CanceledEvent{eventstore.NewBaseEventForPush(ctx, aggregate, CanceledEventType), reason}
}
type RemovedEvent struct {
*eventstore.BaseEvent `json:"-"`
ClientID string
DeviceCode string
UserCode string
}
func (e *RemovedEvent) SetBaseEvent(b *eventstore.BaseEvent) {
e.BaseEvent = b
}
func (e *RemovedEvent) Payload() any {
return e
}
func (e *RemovedEvent) UniqueConstraints() []*eventstore.UniqueConstraint {
return NewRemoveUniqueConstraints(e.ClientID, e.DeviceCode, e.UserCode)
}
func NewRemovedEvent(
ctx context.Context,
aggregate *eventstore.Aggregate,
clientID, deviceCode, userCode string,
) *RemovedEvent {
return &RemovedEvent{
eventstore.NewBaseEventForPush(
ctx, aggregate, RemovedEventType,
),
clientID, deviceCode, userCode,
}
}

View File

@@ -0,0 +1,9 @@
package deviceauth
import "github.com/zitadel/zitadel/internal/eventstore"
func RegisterEventMappers(es *eventstore.Eventstore) {
es.RegisterFilterEventMapper(AggregateType, AddedEventType, eventstore.GenericEventMapper[AddedEvent]).
RegisterFilterEventMapper(AggregateType, ApprovedEventType, eventstore.GenericEventMapper[ApprovedEvent]).
RegisterFilterEventMapper(AggregateType, CanceledEventType, eventstore.GenericEventMapper[CanceledEvent])
}