Skip to content

Commit

Permalink
DXCDT-564: Ensure new ul experience is active when customizing ul (#869)
Browse files Browse the repository at this point in the history
Co-authored-by: Rita Zerrizuela <[email protected]>
  • Loading branch information
sergiught and Widcket committed Nov 1, 2023
1 parent 5dc4a9e commit fcce165
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 106 deletions.
44 changes: 28 additions & 16 deletions internal/cli/universal_login_customize.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,11 @@ const (

type (
universalLoginBrandingData struct {
AuthenticationProfile *management.Prompt `json:"auth_profile"`
Settings *management.Branding `json:"settings"`
Template *management.BrandingUniversalLogin `json:"template"`
Theme *management.BrandingTheme `json:"theme"`
Tenant *tenantData `json:"tenant"`
Prompt *promptData `json:"prompt"`
Settings *management.Branding `json:"settings"`
Template *management.BrandingUniversalLogin `json:"template"`
Theme *management.BrandingTheme `json:"theme"`
Tenant *tenantData `json:"tenant"`
Prompt *promptData `json:"prompt"`
}

tenantData struct {
Expand Down Expand Up @@ -80,6 +79,10 @@ func customizeUniversalLoginCmd(cli *cli) *cobra.Command {
return err
}

if err := ensureNewUniversalLoginExperienceIsActive(ctx, cli.api); err != nil {
return err
}

var universalLoginBrandingData *universalLoginBrandingData

if err := ansi.Spinner("Fetching Universal Login branding data", func() (err error) {
Expand All @@ -96,19 +99,29 @@ func customizeUniversalLoginCmd(cli *cli) *cobra.Command {
return cmd
}

func ensureNewUniversalLoginExperienceIsActive(ctx context.Context, api *auth0.API) error {
authenticationProfile, err := api.Prompt.Read(ctx)
if err != nil {
return err
}

if authenticationProfile.UniversalLoginExperience == "new" {
return nil
}

return fmt.Errorf(
"this feature requires the new Universal Login experience to be enabled for the tenant, " +
"use `auth0 api patch prompts --data '{\"universal_login_experience\":\"new\"}'` to enable it",
)
}

func fetchUniversalLoginBrandingData(
ctx context.Context,
api *auth0.API,
tenantDomain string,
) (*universalLoginBrandingData, error) {
group, ctx := errgroup.WithContext(ctx)

var authenticationProfile *management.Prompt
group.Go(func() (err error) {
authenticationProfile, err = api.Prompt.Read(ctx)
return err
})

var brandingSettings *management.Branding
group.Go(func() (err error) {
brandingSettings = fetchBrandingSettingsOrUseDefaults(ctx, api)
Expand Down Expand Up @@ -147,10 +160,9 @@ func fetchUniversalLoginBrandingData(
}

return &universalLoginBrandingData{
AuthenticationProfile: authenticationProfile,
Settings: brandingSettings,
Template: currentTemplate,
Theme: currentTheme,
Settings: brandingSettings,
Template: currentTemplate,
Theme: currentTheme,
Tenant: &tenantData{
FriendlyName: tenant.GetFriendlyName(),
EnabledLocales: tenant.GetEnabledLocales(),
Expand Down
172 changes: 82 additions & 90 deletions internal/cli/universal_login_customize_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,17 @@ import (
"github.com/auth0/auth0-cli/internal/auth0/mock"
)

func TestFetchUniversalLoginBrandingData(t *testing.T) {
const tenantDomain = "tenant-example.auth0.com"

func TestEnsureNewUniversalLoginExperienceIsActive(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

var testCases = []struct {
name string
mockedAPI func() *auth0.API
expectedData *universalLoginBrandingData
expectedError string
}{
{
name: "it can correctly fetch universal login branding data",
name: "it returns nil if new ul is active",
mockedAPI: func() *auth0.API {
mockPromptAPI := mock.NewMockPromptAPI(ctrl)
mockPromptAPI.
Expand All @@ -42,6 +39,79 @@ func TestFetchUniversalLoginBrandingData(t *testing.T) {
nil,
)

return &auth0.API{
Prompt: mockPromptAPI,
}
},
},
{
name: "it returns an error if there is an api error",
mockedAPI: func() *auth0.API {
mockPromptAPI := mock.NewMockPromptAPI(ctrl)
mockPromptAPI.
EXPECT().
Read(gomock.Any()).
Return(nil, fmt.Errorf("api error"))

return &auth0.API{
Prompt: mockPromptAPI,
}
},
expectedError: "api error",
},
{
name: "it returns an error if classic UL is enabled",
mockedAPI: func() *auth0.API {
mockPromptAPI := mock.NewMockPromptAPI(ctrl)
mockPromptAPI.
EXPECT().
Read(gomock.Any()).
Return(
&management.Prompt{
UniversalLoginExperience: "classic",
IdentifierFirst: auth0.Bool(true),
WebAuthnPlatformFirstFactor: auth0.Bool(true),
},
nil,
)

return &auth0.API{
Prompt: mockPromptAPI,
}
},
expectedError: "this feature requires the new Universal Login experience to be enabled for the tenant, use `auth0 api patch prompts --data '{\"universal_login_experience\":\"new\"}'` to enable it",
},
}

for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
err := ensureNewUniversalLoginExperienceIsActive(context.Background(), test.mockedAPI())

if test.expectedError != "" {
assert.EqualError(t, err, test.expectedError)
return
}

assert.NoError(t, err)
})
}
}

func TestFetchUniversalLoginBrandingData(t *testing.T) {
const tenantDomain = "tenant-example.auth0.com"

ctrl := gomock.NewController(t)
defer ctrl.Finish()

var testCases = []struct {
name string
mockedAPI func() *auth0.API
expectedData *universalLoginBrandingData
expectedError string
}{
{
name: "it can correctly fetch universal login branding data",
mockedAPI: func() *auth0.API {
mockBrandingAPI := mock.NewMockBrandingAPI(ctrl)
mockBrandingAPI.
EXPECT().
Expand Down Expand Up @@ -85,6 +155,7 @@ func TestFetchUniversalLoginBrandingData(t *testing.T) {
nil,
)

mockPromptAPI := mock.NewMockPromptAPI(ctrl)
mockPromptAPI.
EXPECT().
CustomText(gomock.Any(), "login", "en").
Expand All @@ -107,11 +178,6 @@ func TestFetchUniversalLoginBrandingData(t *testing.T) {
return mockAPI
},
expectedData: &universalLoginBrandingData{
AuthenticationProfile: &management.Prompt{
UniversalLoginExperience: "new",
IdentifierFirst: auth0.Bool(true),
WebAuthnPlatformFirstFactor: auth0.Bool(true),
},
Settings: &management.Branding{
Colors: &management.BrandingColors{
Primary: auth0.String("#334455"),
Expand Down Expand Up @@ -178,19 +244,6 @@ func TestFetchUniversalLoginBrandingData(t *testing.T) {
{
name: "it uses default branding settings if it fails to fetch them",
mockedAPI: func() *auth0.API {
mockPromptAPI := mock.NewMockPromptAPI(ctrl)
mockPromptAPI.
EXPECT().
Read(gomock.Any()).
Return(
&management.Prompt{
UniversalLoginExperience: "new",
IdentifierFirst: auth0.Bool(true),
WebAuthnPlatformFirstFactor: auth0.Bool(true),
},
nil,
)

mockBrandingAPI := mock.NewMockBrandingAPI(ctrl)
mockBrandingAPI.
EXPECT().
Expand Down Expand Up @@ -225,6 +278,7 @@ func TestFetchUniversalLoginBrandingData(t *testing.T) {
nil,
)

mockPromptAPI := mock.NewMockPromptAPI(ctrl)
mockPromptAPI.
EXPECT().
CustomText(gomock.Any(), "login", "en").
Expand All @@ -247,11 +301,6 @@ func TestFetchUniversalLoginBrandingData(t *testing.T) {
return mockAPI
},
expectedData: &universalLoginBrandingData{
AuthenticationProfile: &management.Prompt{
UniversalLoginExperience: "new",
IdentifierFirst: auth0.Bool(true),
WebAuthnPlatformFirstFactor: auth0.Bool(true),
},
Settings: &management.Branding{
Colors: &management.BrandingColors{
Primary: auth0.String(defaultPrimaryColor),
Expand Down Expand Up @@ -318,19 +367,6 @@ func TestFetchUniversalLoginBrandingData(t *testing.T) {
{
name: "it uses an empty branding template if it fails to fetch it",
mockedAPI: func() *auth0.API {
mockPromptAPI := mock.NewMockPromptAPI(ctrl)
mockPromptAPI.
EXPECT().
Read(gomock.Any()).
Return(
&management.Prompt{
UniversalLoginExperience: "new",
IdentifierFirst: auth0.Bool(true),
WebAuthnPlatformFirstFactor: auth0.Bool(true),
},
nil,
)

mockBrandingAPI := mock.NewMockBrandingAPI(ctrl)
mockBrandingAPI.
EXPECT().
Expand Down Expand Up @@ -369,6 +405,7 @@ func TestFetchUniversalLoginBrandingData(t *testing.T) {
nil,
)

mockPromptAPI := mock.NewMockPromptAPI(ctrl)
mockPromptAPI.
EXPECT().
CustomText(gomock.Any(), "login", "en").
Expand All @@ -391,11 +428,6 @@ func TestFetchUniversalLoginBrandingData(t *testing.T) {
return mockAPI
},
expectedData: &universalLoginBrandingData{
AuthenticationProfile: &management.Prompt{
UniversalLoginExperience: "new",
IdentifierFirst: auth0.Bool(true),
WebAuthnPlatformFirstFactor: auth0.Bool(true),
},
Settings: &management.Branding{
Colors: &management.BrandingColors{
Primary: auth0.String("#334455"),
Expand Down Expand Up @@ -460,19 +492,6 @@ func TestFetchUniversalLoginBrandingData(t *testing.T) {
{
name: "it uses a default branding theme if it fails to fetch it",
mockedAPI: func() *auth0.API {
mockPromptAPI := mock.NewMockPromptAPI(ctrl)
mockPromptAPI.
EXPECT().
Read(gomock.Any()).
Return(
&management.Prompt{
UniversalLoginExperience: "new",
IdentifierFirst: auth0.Bool(true),
WebAuthnPlatformFirstFactor: auth0.Bool(true),
},
nil,
)

mockBrandingAPI := mock.NewMockBrandingAPI(ctrl)
mockBrandingAPI.
EXPECT().
Expand Down Expand Up @@ -516,6 +535,7 @@ func TestFetchUniversalLoginBrandingData(t *testing.T) {
nil,
)

mockPromptAPI := mock.NewMockPromptAPI(ctrl)
mockPromptAPI.
EXPECT().
CustomText(gomock.Any(), "login", "en").
Expand All @@ -538,11 +558,6 @@ func TestFetchUniversalLoginBrandingData(t *testing.T) {
return mockAPI
},
expectedData: &universalLoginBrandingData{
AuthenticationProfile: &management.Prompt{
UniversalLoginExperience: "new",
IdentifierFirst: auth0.Bool(true),
WebAuthnPlatformFirstFactor: auth0.Bool(true),
},
Settings: &management.Branding{
Colors: &management.BrandingColors{
Primary: auth0.String("#334455"),
Expand Down Expand Up @@ -682,19 +697,6 @@ func TestFetchUniversalLoginBrandingData(t *testing.T) {
{
name: "it fails to fetch branding data if there's an error retrieving tenant data",
mockedAPI: func() *auth0.API {
mockPromptAPI := mock.NewMockPromptAPI(ctrl)
mockPromptAPI.
EXPECT().
Read(gomock.Any()).
Return(
&management.Prompt{
UniversalLoginExperience: "new",
IdentifierFirst: auth0.Bool(true),
WebAuthnPlatformFirstFactor: auth0.Bool(true),
},
nil,
)

mockBrandingAPI := mock.NewMockBrandingAPI(ctrl)
mockBrandingAPI.
EXPECT().
Expand Down Expand Up @@ -726,6 +728,8 @@ func TestFetchUniversalLoginBrandingData(t *testing.T) {
Default(gomock.Any()).
Return(&management.BrandingTheme{}, nil)

mockPromptAPI := mock.NewMockPromptAPI(ctrl)

mockTenantAPI := mock.NewMockTenantAPI(ctrl)
mockTenantAPI.
EXPECT().
Expand All @@ -746,19 +750,6 @@ func TestFetchUniversalLoginBrandingData(t *testing.T) {
{
name: "it fails to fetch branding data if there's an error retrieving prompt text data",
mockedAPI: func() *auth0.API {
mockPromptAPI := mock.NewMockPromptAPI(ctrl)
mockPromptAPI.
EXPECT().
Read(gomock.Any()).
Return(
&management.Prompt{
UniversalLoginExperience: "new",
IdentifierFirst: auth0.Bool(true),
WebAuthnPlatformFirstFactor: auth0.Bool(true),
},
nil,
)

mockBrandingAPI := mock.NewMockBrandingAPI(ctrl)
mockBrandingAPI.
EXPECT().
Expand Down Expand Up @@ -802,6 +793,7 @@ func TestFetchUniversalLoginBrandingData(t *testing.T) {
nil,
)

mockPromptAPI := mock.NewMockPromptAPI(ctrl)
mockPromptAPI.
EXPECT().
CustomText(gomock.Any(), "login", "en").
Expand Down

0 comments on commit fcce165

Please sign in to comment.