Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds support for /branding endpoints #475

Merged
merged 9 commits into from
Feb 15, 2021
77 changes: 77 additions & 0 deletions src/Auth0.ManagementApi/Clients/BrandingClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
using Auth0.ManagementApi.Models;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;

namespace Auth0.ManagementApi.Clients
{
/// <summary>
/// Contains methods to access the /branding endpoints.
/// </summary>
public class BrandingClient : BaseClient
{
/// <summary>
/// Initializes a new instance of <see cref="BrandingClient"/>.
/// </summary>
/// <param name="connection"><see cref="IManagementConnection"/> used to make all API calls.</param>
/// <param name="baseUri"><see cref="Uri"/> of the endpoint to use in making API calls.</param>
/// <param name="defaultHeaders">Dictionary containing default headers included with every request this client makes.</param>
public BrandingClient(IManagementConnection connection, Uri baseUri, IDictionary<string, string> defaultHeaders)
: base(connection, baseUri, defaultHeaders)
{
}

/// <summary>
/// Retrieves branding settings for a tenant.
/// </summary>
/// <returns>A <see cref="Branding"/> containing the branding for the tenant.</returns>
public Task<Branding> GetAsync()
{
return Connection.GetAsync<Branding>(BuildUri("branding"), DefaultHeaders);
}

/// <summary>s
/// Updates the branding for a tenant.
/// </summary>
/// <param name="request">A <see cref="BrandingUpdateRequest" /> containing the branding information to update.</param>
/// <returns>The newly updated <see cref="Branding"/>.</returns>
public Task<Branding> UpdateAsync(BrandingUpdateRequest request)
{
return Connection.SendAsync<Branding>(new HttpMethod("PATCH"), BuildUri("branding"), request, DefaultHeaders);
}

/// <summary>
/// Retrieves the template for the New Universal Login Experience.
/// </summary>
/// <returns>The <see cref="UniversalLoginTemplate"/> for the new universal login experience.</returns>
public Task<UniversalLoginTemplate> GetUniversalLoginTemplateAsync()
{
return Connection.GetAsync<UniversalLoginTemplate>(BuildUri("branding/templates/universal-login"), DefaultHeaders);
}

/// <summary>
/// Delete the template for the New Universal Login Experience
/// </summary>
/// <returns>A <see cref="Task"/> that represents the asynchronous delete operation.</returns>
public Task DeleteUniversalLoginTemplateAsync()
{
return Connection
.SendAsync<object>(
HttpMethod.Delete,
BuildUri("branding/templates/universal-login"),
null,
DefaultHeaders);
}

/// <summary>
/// Sets the template for the New Universal Login Experience.
/// </summary>
/// <param name="request">The <see cref="UniversalLoginTemplateUpdateRequest"/> containing details of the template to set.</param>
/// <returns>The newly updated <see cref="UniversalLoginTemplate"/>.</returns>
public Task<UniversalLoginTemplate> SetUniversalLoginTemplateAsync(UniversalLoginTemplateUpdateRequest request)
{
return Connection.SendAsync<UniversalLoginTemplate>(HttpMethod.Put, BuildUri("branding/templates/universal-login"), request, DefaultHeaders);
}
}
}
6 changes: 6 additions & 0 deletions src/Auth0.ManagementApi/ManagementApiClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ public class ManagementApiClient : IDisposable
/// </summary>
public BlacklistedTokensClient BlacklistedTokens { get; }

/// <summary>
/// Contains all the methods to call the /branding endpoints.
/// </summary>
public BrandingClient Branding { get; }

/// <summary>
/// Contains all the methods to call the /client-grants endpoints
/// </summary>
Expand Down Expand Up @@ -139,6 +144,7 @@ public ManagementApiClient(string token, Uri baseUri, IManagementConnection mana
var defaultHeaders = CreateDefaultHeaders(token);

BlacklistedTokens = new BlacklistedTokensClient(managementConnection, baseUri, defaultHeaders);
Branding = new BrandingClient(managementConnection, baseUri, defaultHeaders);
ClientGrants = new ClientGrantsClient(managementConnection, baseUri, defaultHeaders);
Clients = new ClientsClient(managementConnection, baseUri, defaultHeaders);
Connections = new ConnectionsClient(managementConnection, baseUri, defaultHeaders);
Expand Down
9 changes: 9 additions & 0 deletions src/Auth0.ManagementApi/Models/Branding.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Auth0.ManagementApi.Models
{
/// <summary>
/// Represents the Auth0 Tenant's branding settings
/// </summary>
public class Branding : BrandingBase
{
}
}
31 changes: 31 additions & 0 deletions src/Auth0.ManagementApi/Models/BrandingBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using Newtonsoft.Json;

namespace Auth0.ManagementApi.Models
{
public class BrandingBase
{
/// <summary>
/// Custom color settings.
/// </summary>
[JsonProperty("colors")]
public BrandingColors Colors { get; set; }

/// <summary>
/// URL for the favicon. Must use HTTPS.
/// </summary>
[JsonProperty("favicon_url")]
public string FaviconUrl { get; set; }

/// <summary>
/// URL for the logo. Must use HTTPS.
/// </summary>
[JsonProperty("logo_url")]
public string LogoUrl { get; set; }

/// <summary>
/// Custom font settings.
/// </summary>
[JsonProperty("font")]
public BrandingFont Font{ get; set; }
}
}
19 changes: 19 additions & 0 deletions src/Auth0.ManagementApi/Models/BrandingColors.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using Newtonsoft.Json;

namespace Auth0.ManagementApi.Models
{
public class BrandingColors
{
/// <summary>
/// Accent color.
/// </summary>
[JsonProperty("primary")]
public string Primary { get; set; }

/// <summary>
/// Page Background Color or Gradient.
/// </summary>
[JsonProperty("page_background")]
public string PageBackground { get; set; }
}
}
13 changes: 13 additions & 0 deletions src/Auth0.ManagementApi/Models/BrandingFont.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Newtonsoft.Json;

namespace Auth0.ManagementApi.Models
{
public class BrandingFont
{
/// <summary>
/// URL for the custom font. The URL must point to a font file and not a stylesheet. Must use HTTPS.
/// </summary>
[JsonProperty("url")]
public string Url { get; set; }
}
}
7 changes: 7 additions & 0 deletions src/Auth0.ManagementApi/Models/BrandingUpdateRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Auth0.ManagementApi.Models
{
public class BrandingUpdateRequest : BrandingBase
{

}
}
13 changes: 13 additions & 0 deletions src/Auth0.ManagementApi/Models/UniversalLoginTemplate.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Newtonsoft.Json;

namespace Auth0.ManagementApi.Models
{
public class UniversalLoginTemplate
{
/// <summary>
/// The custom page template for the new universal login experience.
/// </summary>
[JsonProperty("body")]
public string Body { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Newtonsoft.Json;

namespace Auth0.ManagementApi.Models
{
/// <summary>
/// Request for updating the template for the New Universal Login Experience.
/// </summary>
public class UniversalLoginTemplateUpdateRequest
{
/// <summary>
/// Gets or sets the custom page template for the New Universal Login Experience
/// </summary>
[JsonProperty("template")]
public string Template { get; set; }
}
}
105 changes: 105 additions & 0 deletions tests/Auth0.ManagementApi.IntegrationTests/BrandingClientTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
using System;
using System.Threading.Tasks;
using Auth0.Core.Exceptions;
using Auth0.Tests.Shared;
using Xunit;

namespace Auth0.ManagementApi.IntegrationTests
{
public class BrandingClientTests : TestBase, IAsyncLifetime
{
private ManagementApiClient _apiClient;

public async Task InitializeAsync()
{
string token = await GenerateManagementApiToken();

_apiClient = new ManagementApiClient(token, GetVariable("AUTH0_MANAGEMENT_API_URL"));
}

public Task DisposeAsync()
{
return Task.CompletedTask;
}

[Fact]
public async Task Test_Branding_Reand_And_Update()
{
try
{
// Update branding
await _apiClient.Branding.UpdateAsync(new Models.BrandingUpdateRequest
{
LogoUrl = "https://cdn.auth0.com/website/press/resources/auth0-logo-monotone-white.svg",
FaviconUrl = "https://cdn.auth0.com/website/press/resources/auth0-logo-monotone-black.svg",
Colors = new Models.BrandingColors
{
PageBackground = "#ffffff",
Primary = "#ff0000"
},
Font = new Models.BrandingFont
{
Url = "https://fonts.googleapis.com/css2?family=Open+Sans&display=swap"
}
});

var updatedBranding = await _apiClient.Branding.GetAsync();

Assert.Equal("https://cdn.auth0.com/website/press/resources/auth0-logo-monotone-white.svg", updatedBranding.LogoUrl);
Assert.Equal("https://cdn.auth0.com/website/press/resources/auth0-logo-monotone-black.svg", updatedBranding.FaviconUrl);
Assert.Equal("https://fonts.googleapis.com/css2?family=Open+Sans&display=swap", updatedBranding.Font.Url);
Assert.Equal("#ff0000", updatedBranding.Colors.Primary);
Assert.Equal("#ffffff", updatedBranding.Colors.PageBackground);

}
finally
{
// Rollback
await _apiClient.Branding.UpdateAsync(new Models.BrandingUpdateRequest
{
Colors = new Models.BrandingColors {
Primary = "#0059d6",
PageBackground = "#000000"
},
LogoUrl = "https://cdn.auth0.com/website/press/resources/auth0-logo-monotone-black.svg",
FaviconUrl = "https://cdn2.auth0.com/styleguide/latest/lib/logos/img/favicon.png",
Font = new Models.BrandingFont
{
Url = "https://fonts.googleapis.com/css2?family=Roboto&display=swap"
},
});
}
}

[Fact(Skip = "Enable when migrated to new Tenant because missing permissions on current")]
public async Task Test_Branding_ULPTemplate_Reand_Update_Delete()
{
// var temp = await _apiClient.Branding.GetUniversalLoginTemplateAsync();
try
{
var newTemplateBody = @"<!DOCTYPE html><html>
<head>
{%- auth0:head -%}
</head>
<body>
{%- auth0:widget -%}
</body></html> ";

await _apiClient.Branding.SetUniversalLoginTemplateAsync(new Models.UniversalLoginTemplateUpdateRequest
{
Template = newTemplateBody
});

var updatedTemplate = await _apiClient.Branding.GetUniversalLoginTemplateAsync();

Assert.Equal(newTemplateBody, updatedTemplate.Body);
}
finally
{
await _apiClient.Branding.DeleteUniversalLoginTemplateAsync();

await Assert.ThrowsAsync<ErrorApiException>(() => _apiClient.Branding.GetUniversalLoginTemplateAsync());
}
}
}
}