Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions docs/auth0_apps_session-transfer_update.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,21 @@ auth0 apps session-transfer update [flags]
auth0 apps session-transfer update
auth0 apps session-transfer update <app-id>
auth0 apps session-transfer update <app-id> --can-create-token --json
auth0 apps session-transfer update <app-id> --delegation-allow-delegated-access=true --delegation-enforce-device-binding=asn
auth0 apps session-transfer update <app-id> --can-create-token=true --allowed-auth-methods=cookie,query --enforce-device-binding=ip
```


## Flags

```
-m, --allowed-auth-methods strings Comma-separated list of authentication methods (e.g., cookie, query).
-t, --can-create-token Allow creation of session transfer tokens.
-e, --enforce-device-binding string Device binding enforcement: 'none', 'ip', or 'asn'.
--json Output in json format.
--json-compact Output in compact json format.
-m, --allowed-auth-methods strings Comma-separated list of authentication methods (e.g., cookie, query).
-t, --can-create-token Allow creation of session transfer tokens.
-d, --delegation-allow-delegated-access (Early Access) Allow the application to accept Session Transfer Tokens containing an Actor, enabling delegated (impersonation) access. Defaults to false.
-b, --delegation-enforce-device-binding string (Early Access) Device binding enforcement for delegated (impersonation) access: 'ip' or 'asn'. Defaults to 'ip'.
-e, --enforce-device-binding string Device binding enforcement: 'none', 'ip', or 'asn'.
--json Output in json format.
--json-compact Output in compact json format.
```


Expand Down
43 changes: 39 additions & 4 deletions internal/cli/apps.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,20 @@ var (
Help: "Device binding enforcement: 'none', 'ip', or 'asn'.",
AlwaysPrompt: true,
}
appSTDelegationAllowAccess = Flag{
Name: "Allow Delegated Access",
LongForm: "delegation-allow-delegated-access",
ShortForm: "d",
Help: "(Early Access) Allow the application to accept Session Transfer Tokens containing an Actor, " +
"enabling delegated (impersonation) access. Defaults to false.",
}
appSTDelegationDeviceBinding = Flag{
Name: "Delegation Enforce Device Binding",
LongForm: "delegation-enforce-device-binding",
ShortForm: "b",
Help: "(Early Access) Device binding enforcement for delegated (impersonation) access: 'ip' or 'asn'. " +
"Defaults to 'ip'.",
}
refreshToken = Flag{
Name: "Refresh Token",
LongForm: "refresh-token",
Expand Down Expand Up @@ -1211,10 +1225,12 @@ func appsSessionTransferShowCmd(cli *cli) *cobra.Command {

func appsSessionTransferUpdateCmd(cli *cli) *cobra.Command {
var inputs struct {
ID string
CanCreateToken bool
AllowedAuthMethods []string
EnforceDeviceBinding string
ID string
CanCreateToken bool
AllowedAuthMethods []string
EnforceDeviceBinding string
DelegationAllowAccess bool
DelegationDeviceBinding string
}

cmd := &cobra.Command{
Expand All @@ -1224,6 +1240,7 @@ func appsSessionTransferUpdateCmd(cli *cli) *cobra.Command {
Example: ` auth0 apps session-transfer update
auth0 apps session-transfer update <app-id>
auth0 apps session-transfer update <app-id> --can-create-token --json
auth0 apps session-transfer update <app-id> --delegation-allow-delegated-access=true --delegation-enforce-device-binding=asn
auth0 apps session-transfer update <app-id> --can-create-token=true --allowed-auth-methods=cookie,query --enforce-device-binding=ip`,
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) == 0 {
Expand Down Expand Up @@ -1283,6 +1300,22 @@ func appsSessionTransferUpdateCmd(cli *cli) *cobra.Command {
st.EnforceDeviceBinding = current.SessionTransfer.EnforceDeviceBinding
}

// Delegation (EA) is sent only when a flag is set, leaving it untouched for
// others. The API merges sub-fields, so sending just the changed one is enough.
if appSTDelegationAllowAccess.IsSet(cmd) || appSTDelegationDeviceBinding.IsSet(cmd) {
Comment thread
bkiran6398 marked this conversation as resolved.
delegation := &management.SessionTransferDelegation{}

if appSTDelegationAllowAccess.IsSet(cmd) {
delegation.AllowDelegatedAccess = &inputs.DelegationAllowAccess
}

if appSTDelegationDeviceBinding.IsSet(cmd) {
delegation.EnforceDeviceBinding = &inputs.DelegationDeviceBinding
}

st.Delegation = delegation
}

// Send update request.
clientST := &management.Client{SessionTransfer: &st}
if err := ansi.Waiting(func() error {
Expand All @@ -1302,6 +1335,8 @@ func appsSessionTransferUpdateCmd(cli *cli) *cobra.Command {
appSTCanCreateToken.RegisterBoolU(cmd, &inputs.CanCreateToken, false)
appSTAllowedAuthMethods.RegisterStringSliceU(cmd, &inputs.AllowedAuthMethods, nil)
appSTEnforceDeviceBinding.RegisterStringU(cmd, &inputs.EnforceDeviceBinding, "")
appSTDelegationAllowAccess.RegisterBoolU(cmd, &inputs.DelegationAllowAccess, false)
appSTDelegationDeviceBinding.RegisterStringU(cmd, &inputs.DelegationDeviceBinding, "")

return cmd
}
26 changes: 24 additions & 2 deletions internal/display/apps_session_transfer.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ type SessionTransferView struct {
AllowedMethods string
DeviceBinding string

// Delegation (EA) fields, shown only when hasDelegation is true.
hasDelegation bool
DelegationAllowAccess string
DelegationDeviceBinding string

raw interface{}
}

Expand All @@ -29,12 +34,21 @@ func (v *SessionTransferView) AsTableRow() []string {
}

func (v *SessionTransferView) KeyValues() [][]string {
return [][]string{
keyValues := [][]string{
{"CLIENT ID", v.ID},
{"CAN CREATE TOKEN", v.CanCreateTOKEN},
{"ALLOWED METHODS", v.AllowedMethods},
{"DEVICE BINDING", v.DeviceBinding},
}

if v.hasDelegation {
keyValues = append(keyValues,
[]string{"ALLOW DELEGATED ACCESS", v.DelegationAllowAccess},
[]string{"DELEGATION DEVICE BINDING", v.DelegationDeviceBinding},
)
}

return keyValues
}

func (v *SessionTransferView) Object() interface{} {
Expand All @@ -54,11 +68,19 @@ func (r *Renderer) SessionTransferUpdate(client *management.Client, id string) {
}

func MakeSessionTransferView(client *management.Client) *SessionTransferView {
return &SessionTransferView{
view := &SessionTransferView{
ID: client.GetClientID(),
CanCreateTOKEN: boolean(client.SessionTransfer.GetCanCreateSessionTransferToken()),
AllowedMethods: stringSliceToCommaSeparatedString(client.SessionTransfer.GetAllowedAuthenticationMethods()),
DeviceBinding: client.SessionTransfer.GetEnforceDeviceBinding(),
raw: client.SessionTransfer,
}

if delegation := client.GetSessionTransfer().GetDelegation(); delegation != nil {
view.hasDelegation = true
view.DelegationAllowAccess = boolean(delegation.GetAllowDelegatedAccess())
view.DelegationDeviceBinding = delegation.GetEnforceDeviceBinding()
}

return view
}
67 changes: 67 additions & 0 deletions internal/display/apps_session_transfer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package display

import (
"testing"

"github.com/auth0/go-auth0"
"github.com/auth0/go-auth0/management"
"github.com/stretchr/testify/assert"
)

func TestMakeSessionTransferView_WithoutDelegation(t *testing.T) {
client := &management.Client{
ClientID: auth0.String("client-id"),
SessionTransfer: &management.SessionTransfer{
CanCreateSessionTransferToken: auth0.Bool(true),
AllowedAuthenticationMethods: &[]string{"cookie", "query"},
EnforceDeviceBinding: auth0.String("ip"),
},
}

view := MakeSessionTransferView(client)

assert.False(t, view.hasDelegation)
assert.Equal(t, "", view.DelegationAllowAccess)
assert.Equal(t, "", view.DelegationDeviceBinding)

// Delegation rows must be omitted when no delegation is configured.
keyValues := view.KeyValues()
assert.Equal(t, [][]string{
{"CLIENT ID", "client-id"},
{"CAN CREATE TOKEN", boolean(true)},
{"ALLOWED METHODS", "cookie, query"},
{"DEVICE BINDING", "ip"},
}, keyValues)
}

func TestMakeSessionTransferView_WithDelegation(t *testing.T) {
client := &management.Client{
ClientID: auth0.String("client-id"),
SessionTransfer: &management.SessionTransfer{
CanCreateSessionTransferToken: auth0.Bool(true),
AllowedAuthenticationMethods: &[]string{"cookie"},
EnforceDeviceBinding: auth0.String("ip"),
Delegation: &management.SessionTransferDelegation{
AllowDelegatedAccess: auth0.Bool(true),
EnforceDeviceBinding: auth0.String("asn"),
},
},
}

view := MakeSessionTransferView(client)

assert.True(t, view.hasDelegation)
assert.Equal(t, boolean(true), view.DelegationAllowAccess)
assert.Equal(t, "asn", view.DelegationDeviceBinding)

// Delegation rows must be appended after the base session-transfer rows.
keyValues := view.KeyValues()
assert.Equal(t, [][]string{
{"CLIENT ID", "client-id"},
{"CAN CREATE TOKEN", boolean(true)},
{"ALLOWED METHODS", "cookie"},
{"DEVICE BINDING", "ip"},
{"ALLOW DELEGATED ACCESS", boolean(true)},
{"DELEGATION DEVICE BINDING", "asn"},
}, keyValues)
}
Loading