zitadel/internal/command/device_auth.go
Tim Möhlmann 5819924275
feat: device authorization RFC 8628 (#5646)
* device auth: implement the write events

* add grant type device code

* fix(init): check if default value implements stringer

---------

Co-authored-by: adlerhurst <silvan.reusser@gmail.com>
2023-04-19 08:46:02 +00:00

114 lines
3.2 KiB
Go

package command
import (
"context"
"time"
"github.com/zitadel/zitadel/internal/api/authz"
"github.com/zitadel/zitadel/internal/domain"
caos_errs "github.com/zitadel/zitadel/internal/errors"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/repository/deviceauth"
)
func (c *Commands) AddDeviceAuth(ctx context.Context, clientID, deviceCode, userCode string, expires time.Time, scopes []string) (string, *domain.ObjectDetails, error) {
aggrID, err := c.idGenerator.Next()
if err != nil {
return "", nil, err
}
aggr := deviceauth.NewAggregate(aggrID, authz.GetInstance(ctx).InstanceID())
model := NewDeviceAuthWriteModel(aggrID, aggr.ResourceOwner)
pushedEvents, err := c.eventstore.Push(ctx, deviceauth.NewAddedEvent(
ctx,
aggr,
clientID,
deviceCode,
userCode,
expires,
scopes,
))
if err != nil {
return "", nil, err
}
err = AppendAndReduce(model, pushedEvents...)
if err != nil {
return "", nil, err
}
return model.AggregateID, writeModelToObjectDetails(&model.WriteModel), nil
}
func (c *Commands) ApproveDeviceAuth(ctx context.Context, id, subject string) (*domain.ObjectDetails, error) {
model, err := c.getDeviceAuthWriteModelByID(ctx, id)
if err != nil {
return nil, err
}
if !model.State.Exists() {
return nil, caos_errs.ThrowNotFound(nil, "COMMAND-Hief9", "Errors.DeviceAuth.NotFound")
}
aggr := deviceauth.NewAggregate(model.AggregateID, model.InstanceID)
pushedEvents, err := c.eventstore.Push(ctx, deviceauth.NewApprovedEvent(ctx, aggr, subject))
if err != nil {
return nil, err
}
err = AppendAndReduce(model, pushedEvents...)
if err != nil {
return nil, err
}
return writeModelToObjectDetails(&model.WriteModel), nil
}
func (c *Commands) CancelDeviceAuth(ctx context.Context, id string, reason domain.DeviceAuthCanceled) (*domain.ObjectDetails, error) {
model, err := c.getDeviceAuthWriteModelByID(ctx, id)
if err != nil {
return nil, err
}
if !model.State.Exists() {
return nil, caos_errs.ThrowNotFound(nil, "COMMAND-gee5A", "Errors.DeviceAuth.NotFound")
}
aggr := deviceauth.NewAggregate(model.AggregateID, model.InstanceID)
pushedEvents, err := c.eventstore.Push(ctx, deviceauth.NewCanceledEvent(ctx, aggr, reason))
if err != nil {
return nil, err
}
err = AppendAndReduce(model, pushedEvents...)
if err != nil {
return nil, err
}
return writeModelToObjectDetails(&model.WriteModel), nil
}
func (c *Commands) RemoveDeviceAuth(ctx context.Context, id string) (*domain.ObjectDetails, error) {
model, err := c.getDeviceAuthWriteModelByID(ctx, id)
if err != nil {
return nil, err
}
aggr := deviceauth.NewAggregate(model.AggregateID, model.InstanceID)
pushedEvents, err := c.eventstore.Push(ctx, deviceauth.NewRemovedEvent(ctx, aggr, model.ClientID, model.DeviceCode, model.UserCode))
if err != nil {
return nil, err
}
err = AppendAndReduce(model, pushedEvents...)
if err != nil {
return nil, err
}
return writeModelToObjectDetails(&model.WriteModel), nil
}
func (c *Commands) getDeviceAuthWriteModelByID(ctx context.Context, id string) (*DeviceAuthWriteModel, error) {
model := &DeviceAuthWriteModel{WriteModel: eventstore.WriteModel{AggregateID: id}}
err := c.eventstore.FilterToQueryReducer(ctx, model)
if err != nil {
return nil, err
}
return model, nil
}