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
3 changes: 3 additions & 0 deletions docs/auth0_apps_create.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ auth0 apps create [flags]
auth0 apps create -n myapp -d <description> -t [native|spa|regular|m2m|resource_server] -r --json --metadata "foo=bar,bazz=buzz"
auth0 apps create --name "My API Client" --type resource_server --resource-server-identifier "https://api.example.com"
auth0 apps create --name myapp --type resource_server --allow-any-profile-of-type custom_authentication,on_behalf_of_token_exchange
auth0 apps create --name "My 3P App" --type regular --third-party-security-mode strict --redirection-policy open_redirect_protection
```


Expand All @@ -48,9 +49,11 @@ auth0 apps create [flags]
--metadata stringToString Arbitrary keys-value pairs (max 255 characters each), that can be assigned to each application. More about application metadata: https://auth0.com/docs/get-started/applications/configure-application-metadata (default [])
-n, --name string Name of the application.
-o, --origins strings Comma-separated list of URLs allowed to make requests from JavaScript to Auth0 API (typically used with CORS). By default, all your callback URLs will be allowed. This field allows you to enter other origins if necessary. You can also use wildcards at the subdomain level (e.g., https://*.contoso.com). Query strings and hash information are not taken into account when validating these URLs.
-y, --redirection-policy string Controls whether Auth0 redirects users to the application's callback URL on authentication errors or in email verification flows: 'allow_always' or 'open_redirect_protection'.
-z, --refresh-token string Refresh Token Config for the application, formatted as JSON.
--resource-server-identifier string The identifier of the resource server that this client is associated with. This property can only be sent when app_type=resource_server and cannot be changed once the client is created.
-r, --reveal-secrets Display the application secrets ('signing_keys', 'client_secret') as part of the command output.
-s, --third-party-security-mode string Security mode for third-party clients: 'strict' or 'permissive'.
-t, --type string Type of application:
- native: mobile, desktop, CLI and smart device apps running natively.
- spa (single page application): a JavaScript front-end app that uses an API.
Expand Down
4 changes: 4 additions & 0 deletions docs/auth0_apps_update.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ auth0 apps update [flags]
auth0 apps update <app-id> -n myapp -d <description> -t [native|spa|regular|m2m] -r --json --metadata "foo=bar" --metadata "bazz=buzz"
auth0 apps update <app-id> -n myapp -d <description> -t [native|spa|regular|m2m] -r --json --metadata "foo=bar,bazz=buzz"
auth0 apps update <app-id> --allow-any-profile-of-type custom_authentication,on_behalf_of_token_exchange
auth0 apps update <app-id> --redirection-policy allow_always
auth0 apps update <app-id> --third-party-security-mode strict --redirection-policy open_redirect_protection
```


Expand All @@ -47,8 +49,10 @@ auth0 apps update [flags]
--metadata stringToString Arbitrary keys-value pairs (max 255 characters each), that can be assigned to each application. More about application metadata: https://auth0.com/docs/get-started/applications/configure-application-metadata (default [])
-n, --name string Name of the application.
-o, --origins strings Comma-separated list of URLs allowed to make requests from JavaScript to Auth0 API (typically used with CORS). By default, all your callback URLs will be allowed. This field allows you to enter other origins if necessary. You can also use wildcards at the subdomain level (e.g., https://*.contoso.com). Query strings and hash information are not taken into account when validating these URLs.
-y, --redirection-policy string Controls whether Auth0 redirects users to the application's callback URL on authentication errors or in email verification flows: 'allow_always' or 'open_redirect_protection'.
-z, --refresh-token string Refresh Token Config for the application, formatted as JSON.
-r, --reveal-secrets Display the application secrets ('signing_keys', 'client_secret') as part of the command output.
-s, --third-party-security-mode string Security mode for third-party clients: 'strict' or 'permissive'.
-t, --type string Type of application:
- native: mobile, desktop, CLI and smart device apps running natively.
- spa (single page application): a JavaScript front-end app that uses an API.
Expand Down
84 changes: 63 additions & 21 deletions internal/cli/apps.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,18 @@ var (
ShortForm: "p",
Help: "Comma-separated list of enabled token exchange types for this client. Possible values: custom_authentication, on_behalf_of_token_exchange.",
}
appThirdPartySecurityMode = Flag{
Name: "Third Party Security Mode",
LongForm: "third-party-security-mode",
ShortForm: "s",
Help: "Security mode for third-party clients: 'strict' or 'permissive'.",
}
appRedirectionPolicy = Flag{
Name: "Redirection Policy",
LongForm: "redirection-policy",
ShortForm: "y",
Help: "Controls whether Auth0 redirects users to the application's callback URL on authentication errors or in email verification flows: 'allow_always' or 'open_redirect_protection'.",
}
)

func appsCmd(cli *cli) *cobra.Command {
Expand Down Expand Up @@ -434,6 +446,8 @@ func createAppCmd(cli *cli) *cobra.Command {
RefreshToken string
ResourceServerIdentifier string
AllowAnyProfileOfType []string
ThirdPartySecurityMode string
RedirectionPolicy string
}
var oidcConformant = true
var algorithm = "RS256"
Expand All @@ -456,7 +470,8 @@ func createAppCmd(cli *cli) *cobra.Command {
auth0 apps create -n myapp -d <description> -t [native|spa|regular|m2m|resource_server] -r --json --metadata "foo=bar" --metadata "bazz=buzz"
auth0 apps create -n myapp -d <description> -t [native|spa|regular|m2m|resource_server] -r --json --metadata "foo=bar,bazz=buzz"
auth0 apps create --name "My API Client" --type resource_server --resource-server-identifier "https://api.example.com"
auth0 apps create --name myapp --type resource_server --allow-any-profile-of-type custom_authentication,on_behalf_of_token_exchange`,
auth0 apps create --name myapp --type resource_server --allow-any-profile-of-type custom_authentication,on_behalf_of_token_exchange
auth0 apps create --name "My 3P App" --type regular --third-party-security-mode strict --redirection-policy open_redirect_protection`,
RunE: func(cmd *cobra.Command, args []string) error {
if err := appName.Ask(cmd, &inputs.Name, nil); err != nil {
return err
Expand All @@ -474,6 +489,7 @@ func createAppCmd(cli *cli) *cobra.Command {
appIsNative := apiTypeFor(inputs.Type) == appTypeNative
appIsSPA := apiTypeFor(inputs.Type) == appTypeSPA
appIsResourceServer := apiTypeFor(inputs.Type) == appTypeResourceServer
isThirdPartyApp := inputs.ThirdPartySecurityMode != "" || inputs.RedirectionPolicy != ""

// Prompt for callback URLs if app is not m2m and not resource_server.
if !appIsM2M && !appIsResourceServer {
Expand All @@ -488,8 +504,8 @@ func createAppCmd(cli *cli) *cobra.Command {
}
}

// Prompt for logout URLs if app is not m2m and not resource_server.
if !appIsM2M && !appIsResourceServer {
// Prompt for logout URLs if app is not m2m and not resource_server and not a third-party app.
if !appIsM2M && !appIsResourceServer && !isThirdPartyApp {
var defaultValue string

if !appIsNative {
Expand Down Expand Up @@ -593,11 +609,21 @@ func createAppCmd(cli *cli) *cobra.Command {
a.TokenEndpointAuthMethod = apiAuthMethodFor(inputs.AuthMethod)
}

if inputs.ThirdPartySecurityMode != "" {
a.ThirdPartySecurityMode = &inputs.ThirdPartySecurityMode
}
if inputs.RedirectionPolicy != "" {
a.RedirectionPolicy = &inputs.RedirectionPolicy
}
if isThirdPartyApp {
a.IsFirstParty = auth0.Bool(false)
}

// Set grants.
if len(inputs.Grants) == 0 {
a.GrantTypes = apiDefaultGrantsFor(inputs.Type)
} else {
if len(inputs.Grants) > 0 {
a.GrantTypes = apiGrantsFor(inputs.Grants)
} else if !isThirdPartyApp {
a.GrantTypes = apiDefaultGrantsFor(inputs.Type)
}

// Create app.
Expand Down Expand Up @@ -633,26 +659,30 @@ func createAppCmd(cli *cli) *cobra.Command {
appTEAllowAnyProfileOfType.RegisterStringSlice(cmd, &inputs.AllowAnyProfileOfType, nil)
revealSecrets.RegisterBool(cmd, &inputs.RevealSecrets, false)
refreshToken.RegisterString(cmd, &inputs.RefreshToken, "")
appThirdPartySecurityMode.RegisterString(cmd, &inputs.ThirdPartySecurityMode, "")
appRedirectionPolicy.RegisterString(cmd, &inputs.RedirectionPolicy, "")

return cmd
}

func updateAppCmd(cli *cli) *cobra.Command {
var inputs struct {
ID string
Name string
Type string
Description string
Callbacks []string
AllowedOrigins []string
AllowedWebOrigins []string
AllowedLogoutURLs []string
AuthMethod string
Grants []string
RevealSecrets bool
Metadata map[string]string
RefreshToken string
AllowAnyProfileOfType []string
ID string
Name string
Type string
Description string
Callbacks []string
AllowedOrigins []string
AllowedWebOrigins []string
AllowedLogoutURLs []string
AuthMethod string
Grants []string
RevealSecrets bool
Metadata map[string]string
RefreshToken string
AllowAnyProfileOfType []string
ThirdPartySecurityMode string
RedirectionPolicy string
}

cmd := &cobra.Command{
Expand All @@ -673,7 +703,9 @@ func updateAppCmd(cli *cli) *cobra.Command {
auth0 apps update <app-id> -n myapp -d <description> -t [native|spa|regular|m2m] -r --json --metadata "foo=bar"
auth0 apps update <app-id> -n myapp -d <description> -t [native|spa|regular|m2m] -r --json --metadata "foo=bar" --metadata "bazz=buzz"
auth0 apps update <app-id> -n myapp -d <description> -t [native|spa|regular|m2m] -r --json --metadata "foo=bar,bazz=buzz"
auth0 apps update <app-id> --allow-any-profile-of-type custom_authentication,on_behalf_of_token_exchange`,
auth0 apps update <app-id> --allow-any-profile-of-type custom_authentication,on_behalf_of_token_exchange
auth0 apps update <app-id> --redirection-policy allow_always
auth0 apps update <app-id> --third-party-security-mode strict --redirection-policy open_redirect_protection`,
RunE: func(cmd *cobra.Command, args []string) error {
var current *management.Client

Expand Down Expand Up @@ -847,6 +879,14 @@ func updateAppCmd(cli *cli) *cobra.Command {
}
}

if appThirdPartySecurityMode.IsSet(cmd) {
a.ThirdPartySecurityMode = &inputs.ThirdPartySecurityMode
}

if appRedirectionPolicy.IsSet(cmd) {
a.RedirectionPolicy = &inputs.RedirectionPolicy
}

if err := ansi.Waiting(func() error {
return cli.api.Client.Update(cmd.Context(), inputs.ID, a)
}); err != nil {
Expand Down Expand Up @@ -874,6 +914,8 @@ func updateAppCmd(cli *cli) *cobra.Command {
appTEAllowAnyProfileOfType.RegisterStringSliceU(cmd, &inputs.AllowAnyProfileOfType, nil)
revealSecrets.RegisterBool(cmd, &inputs.RevealSecrets, false)
refreshToken.RegisterString(cmd, &inputs.RefreshToken, "")
appThirdPartySecurityMode.RegisterStringU(cmd, &inputs.ThirdPartySecurityMode, "")
appRedirectionPolicy.RegisterStringU(cmd, &inputs.RedirectionPolicy, "")

return cmd
}
Expand Down
8 changes: 7 additions & 1 deletion internal/cli/terraform_fetcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -274,8 +274,14 @@ func (f *clientGrantResourceFetcher) FetchData(ctx context.Context) (importDataL
}

for _, grant := range grants.ClientGrants {
var resourceName string
if grant.GetDefaultFor() != "" {
resourceName = "auth0_client_grant." + sanitizeResourceName("default_for_"+grant.GetDefaultFor()+"_"+grant.GetAudience())
} else {
resourceName = "auth0_client_grant." + sanitizeResourceName(grant.GetClientID()+"_"+grant.GetAudience())
}
data = append(data, importDataItem{
ResourceName: "auth0_client_grant." + sanitizeResourceName(grant.GetClientID()+"_"+grant.GetAudience()),
ResourceName: resourceName,
ImportID: grant.GetID(),
})
}
Expand Down
61 changes: 61 additions & 0 deletions internal/cli/terraform_fetcher_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -723,6 +723,67 @@ func TestClientGrantResourceFetcher_FetchData(t *testing.T) {
_, err := fetcher.FetchData(context.Background())
assert.EqualError(t, err, "failed to list clients")
})

t.Run("it handles default_for grants correctly", func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

clientGrantAPI := mock.NewMockClientGrantAPI(ctrl)
clientGrantAPI.EXPECT().
List(gomock.Any(), gomock.Any()).
Return(
&management.ClientGrantList{
List: management.List{
Start: 0,
Limit: 3,
Total: 3,
},
ClientGrants: []*management.ClientGrant{
{
ID: auth0.String("cgr_1"),
ClientID: auth0.String("client-id-1"),
Audience: auth0.String("https://travel0.com/api"),
},
{
ID: auth0.String("cgr_2"),
DefaultFor: auth0.String("third_party_clients"),
Audience: auth0.String("https://travel0.com/api"),
},
{
ID: auth0.String("cgr_3"),
DefaultFor: auth0.String("third_party_clients"),
Audience: auth0.String("https://partner-api.example.com"),
},
},
},
nil,
)

fetcher := clientGrantResourceFetcher{
api: &auth0.API{
ClientGrant: clientGrantAPI,
},
}

expectedData := importDataList{
{
ResourceName: "auth0_client_grant.client_id_1_https_travel0_com_api",
ImportID: "cgr_1",
},
{
ResourceName: "auth0_client_grant.default_for_third_party_clients_https_travel0_com_api",
ImportID: "cgr_2",
},
{
ResourceName: "auth0_client_grant.default_for_third_party_clients_https_partner_api_example_com",
ImportID: "cgr_3",
},
}

data, err := fetcher.FetchData(context.Background())
assert.NoError(t, err)
assert.Equal(t, expectedData, data)
})
}

func TestConnectionResourceFetcher_FetchData(t *testing.T) {
Expand Down
12 changes: 12 additions & 0 deletions internal/display/apps.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ type applicationView struct {
RefreshToken string
ResourceServerIdentifier string
AllowAnyProfileOfType []string
ThirdPartySecurityMode string
RedirectionPolicy string
revealSecret bool

raw interface{}
Expand Down Expand Up @@ -128,6 +130,14 @@ func (v *applicationView) KeyValues() [][]string {
keyValues = append(keyValues, []string{"TOKEN EXCHANGE TYPES", strings.Join(v.AllowAnyProfileOfType, ", ")})
}

if v.ThirdPartySecurityMode != "" {
keyValues = append(keyValues, []string{"THIRD PARTY SECURITY MODE", v.ThirdPartySecurityMode})
}

if v.RedirectionPolicy != "" {
keyValues = append(keyValues, []string{"REDIRECTION POLICY", v.RedirectionPolicy})
}

return keyValues
}

Expand Down Expand Up @@ -213,6 +223,8 @@ func makeApplicationView(client *management.Client, revealSecrets bool) *applica
Metadata: mapPointerToArray(client.ClientMetadata),
ResourceServerIdentifier: client.GetResourceServerIdentifier(),
AllowAnyProfileOfType: client.GetTokenExchange().GetAllowAnyProfileOfType(),
ThirdPartySecurityMode: client.GetThirdPartySecurityMode(),
RedirectionPolicy: client.GetRedirectionPolicy(),
raw: client,
RefreshToken: string(jsonRefreshToken),
}
Expand Down
10 changes: 10 additions & 0 deletions test/integration/apps-test-cases.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -376,3 +376,13 @@ tests:
050 - given a resource server app, it successfully deletes the app:
command: auth0 apps delete $(./test/integration/scripts/get-resource-server-app-id.sh) --force
exit-code: 0

051 - it successfully creates a regular app with third-party-security-mode and redirection-policy and outputs in json:
command: auth0 apps create --name integration-test-app-3p-strict --type regular --description 3PApp1 --third-party-security-mode strict --redirection-policy open_redirect_protection --json
exit-code: 0
stdout:
json:
name: integration-test-app-3p-strict
app_type: regular_web
third_party_security_mode: strict
redirection_policy: open_redirect_protection
Loading