diff --git a/src/Auth0.ManagementApi/Clients/ISelfServiceProfilesClient.cs b/src/Auth0.ManagementApi/Clients/ISelfServiceProfilesClient.cs
new file mode 100644
index 00000000..d2b23678
--- /dev/null
+++ b/src/Auth0.ManagementApi/Clients/ISelfServiceProfilesClient.cs
@@ -0,0 +1,98 @@
+using System.Threading;
+using System.Threading.Tasks;
+using Auth0.ManagementApi.Models.SelfServiceProfiles;
+using Auth0.ManagementApi.Paging;
+
+namespace Auth0.ManagementApi.Clients
+{
+ public interface ISelfServiceProfilesClient
+ {
+ ///
+ /// Retrieve self-service-profile information.
+ ///
+ ///
+ ///
+ /// of
+ Task> GetAllAsync(PaginationInfo pagination = null, CancellationToken cancellationToken = default);
+
+ ///
+ /// Create self-service-profile.
+ ///
+ ///
+ ///
+ ///
+ Task CreateAsync(SelfServiceProfileCreateRequest request, CancellationToken cancellationToken = default);
+
+ ///
+ /// Retrieve self-service-profile by id.
+ ///
+ /// Self-Service-Profile ID
+ ///
+ ///
+ Task GetAsync(string id, CancellationToken cancellationToken = default);
+
+ ///
+ /// Delete a self-service-profile by id.
+ ///
+ /// Self-Service-Profile ID
+ ///
+ Task DeleteAsync(string id, CancellationToken cancellationToken = default);
+
+ ///
+ /// Retrieve self-service-profile by id.
+ ///
+ /// Self-Service-Profile ID
+ ///
+ ///
+ ///
+ Task UpdateAsync(string id, SelfServiceProfileUpdateRequest request, CancellationToken cancellationToken = default);
+
+ ///
+ /// Creates an sso-access ticket to initiate the Self Service SSO Flow using a self-service profile
+ ///
+ /// The id of the sso-profile to retrieve
+ ///
+ ///
+ ///
+ Task CreateSsoTicketAsync(string id, SelfServiceSsoTicketCreateRequest request, CancellationToken cancellationToken = default);
+
+ ///
+ /// Revokes an SSO access ticket and invalidates associated sessions.
+ /// The ticket will no longer be accepted to initiate a Self-Service SSO session.
+ /// If any users have already started a session through this ticket, their session will be terminated.
+ /// Clients should expect a 202 Accepted response upon successful processing, indicating that the request
+ /// has been acknowledged and that the revocation is underway but may not be fully completed at the time of response.
+ /// If the specified ticket does not exist, a 202 Accepted response is also returned,
+ /// signaling that no further action is required.
+ /// Clients should treat these 202 responses as an acknowledgment that the request has been accepted and
+ /// is in progress, even if the ticket was not found.
+ ///
+ /// The id of the ticket to revoke
+ /// The id of the self-service profile
+ ///
+ ///
+ Task RevokeSsoTicketAsync(string profileId, string ticketId, CancellationToken cancellationToken = default);
+
+ ///
+ /// Retrieves text customizations for a given self-service profile, language and Self Service SSO Flow page
+ ///
+ /// The id of the self-service profile.
+ /// The language of the custom text.
+ /// The page where the custom text is shown.
+ ///
+ /// The list of custom text keys and values.
+ Task GetCustomTextForSelfServiceProfileAsync(string id, string language, string page, CancellationToken cancellationToken = default);
+
+ ///
+ /// Updates text customizations for a given self-service profile, language and Self Service SSO Flow page.
+ ///
+ /// The id of the self-service profile.
+ /// The language of the custom text.
+ /// The page where the custom text is shown.
+ /// The list of text keys and values to customize the self-service SSO page.
+ /// Values can be plain text or rich HTML content limited to basic styling tags and hyperlinks.
+ ///
+ /// The resulting list of custom text keys and values.
+ Task SetCustomTextForSelfServiceProfileAsync(string id, string language, string page, object body, CancellationToken cancellationToken = default);
+ }
+}
\ No newline at end of file
diff --git a/src/Auth0.ManagementApi/Clients/SelfServiceProfilesClient.cs b/src/Auth0.ManagementApi/Clients/SelfServiceProfilesClient.cs
new file mode 100644
index 00000000..9b4a373c
--- /dev/null
+++ b/src/Auth0.ManagementApi/Clients/SelfServiceProfilesClient.cs
@@ -0,0 +1,172 @@
+using System;
+using System.Collections.Generic;
+using System.Net.Http;
+using System.Threading;
+using System.Threading.Tasks;
+using Auth0.ManagementApi.Models.SelfServiceProfiles;
+using Auth0.ManagementApi.Paging;
+using Newtonsoft.Json;
+
+namespace Auth0.ManagementApi.Clients
+{
+ ///
+ /// Client to manage Self Service Profiles.
+ ///
+ public class SelfServiceProfilesClient : BaseClient, ISelfServiceProfilesClient
+ {
+ readonly JsonConverter[] converters = { new PagedListConverter("self_service_profiles") };
+ public SelfServiceProfilesClient(
+ IManagementConnection connection,
+ Uri baseUri,
+ IDictionary defaultHeaders) : base(connection, baseUri, defaultHeaders)
+ {
+ }
+
+ ///
+ public Task> GetAllAsync(PaginationInfo pagination = null, CancellationToken cancellationToken = default)
+ {
+ var queryStrings = new Dictionary();
+
+ if (pagination != null)
+ {
+ queryStrings["page"] = pagination.PageNo.ToString();
+ queryStrings["per_page"] = pagination.PerPage.ToString();
+ queryStrings["include_totals"] = pagination.IncludeTotals.ToString().ToLower();
+ }
+
+ return Connection.GetAsync>(
+ BuildUri("self-service-profiles", queryStrings),
+ DefaultHeaders,
+ converters,
+ cancellationToken);
+ }
+
+ ///
+ public Task CreateAsync(SelfServiceProfileCreateRequest request, CancellationToken cancellationToken = default)
+ {
+ if (request == null)
+ throw new ArgumentNullException(nameof(request));
+
+ return Connection.SendAsync(
+ HttpMethod.Post,
+ BuildUri("self-service-profiles"),
+ request,
+ DefaultHeaders,
+ cancellationToken: cancellationToken);
+ }
+
+ ///
+ public Task GetAsync(string id, CancellationToken cancellationToken = default)
+ {
+ if (string.IsNullOrEmpty(id))
+ throw new ArgumentNullException(nameof(id));
+
+ return Connection.GetAsync(
+ BuildUri($"self-service-profiles/{EncodePath(id)}"),
+ DefaultHeaders,
+ null,
+ cancellationToken);
+ }
+
+ ///
+ public Task DeleteAsync(string id, CancellationToken cancellationToken = default)
+ {
+ return Connection.SendAsync(
+ HttpMethod.Delete,
+ BuildUri($"self-service-profiles/{EncodePath(id)}"),
+ body: null,
+ headers: DefaultHeaders,
+ cancellationToken: cancellationToken);
+ }
+
+ ///
+ public Task UpdateAsync(string id, SelfServiceProfileUpdateRequest request, CancellationToken cancellationToken = default)
+ {
+ if (string.IsNullOrEmpty(id))
+ throw new ArgumentNullException(nameof(id));
+
+ return Connection.SendAsync(
+ new HttpMethod("PATCH"),
+ BuildUri($"self-service-profiles/{EncodePath(id)}"),
+ request,
+ DefaultHeaders,
+ cancellationToken: cancellationToken);
+ }
+
+ ///
+ public Task CreateSsoTicketAsync(string id, SelfServiceSsoTicketCreateRequest request, CancellationToken cancellationToken = default)
+ {
+ if (request == null)
+ throw new ArgumentNullException(nameof(request));
+
+ if (string.IsNullOrEmpty(id))
+ throw new ArgumentNullException(nameof(id));
+
+ return Connection.SendAsync(
+ HttpMethod.Post,
+ BuildUri($"self-service-profiles/{EncodePath(id)}/sso-ticket"),
+ request,
+ DefaultHeaders,
+ cancellationToken: cancellationToken);
+ }
+
+ ///
+ public Task RevokeSsoTicketAsync(string profileId, string ticketId, CancellationToken cancellationToken = default)
+ {
+ if (string.IsNullOrEmpty(profileId))
+ throw new ArgumentNullException(nameof(profileId));
+
+ if (string.IsNullOrEmpty(ticketId))
+ throw new ArgumentNullException(nameof(ticketId));
+
+ return Connection.SendAsync(
+ HttpMethod.Post,
+ BuildUri($"self-service-profiles/{EncodePath(profileId)}/sso-ticket/{EncodePath(ticketId)}/revoke"),
+ null,
+ DefaultHeaders,
+ cancellationToken: cancellationToken);
+ }
+
+ ///
+ public Task GetCustomTextForSelfServiceProfileAsync(string id, string language, string page,
+ CancellationToken cancellationToken = default)
+ {
+ if (string.IsNullOrEmpty(id))
+ throw new ArgumentNullException(nameof(id));
+
+ if (string.IsNullOrEmpty(language))
+ throw new ArgumentNullException(nameof(language));
+
+ if (string.IsNullOrEmpty(page))
+ throw new ArgumentNullException(nameof(page));
+
+ return Connection.GetAsync(
+ BuildUri($"self-service-profiles/{EncodePath(id)}/custom-text/{EncodePath(language)}/{EncodePath(page)}"),
+ DefaultHeaders,
+ null,
+ cancellationToken);
+ }
+
+ ///
+ public Task SetCustomTextForSelfServiceProfileAsync(string id, string language, string page, object body,
+ CancellationToken cancellationToken = default)
+ {
+ if (string.IsNullOrEmpty(id))
+ throw new ArgumentNullException(nameof(id));
+
+ if (string.IsNullOrEmpty(language))
+ throw new ArgumentNullException(nameof(language));
+
+ if (string.IsNullOrEmpty(page))
+ throw new ArgumentNullException(nameof(page));
+
+ return Connection
+ .SendAsync(
+ HttpMethod.Put,
+ BuildUri($"self-service-profiles/{EncodePath(id)}/custom-text/{EncodePath(language)}/{EncodePath(page)}"),
+ body,
+ DefaultHeaders,
+ cancellationToken: cancellationToken);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Auth0.ManagementApi/IManagementApiClient.cs b/src/Auth0.ManagementApi/IManagementApiClient.cs
index 064220da..4ceaf0e8 100644
--- a/src/Auth0.ManagementApi/IManagementApiClient.cs
+++ b/src/Auth0.ManagementApi/IManagementApiClient.cs
@@ -160,6 +160,11 @@ public interface IManagementApiClient : IDisposable
/// Contains all the methods to call the /sessions endpoints.
///
ISessionsClient Sessions { get; }
+
+ ///
+ /// Contains all the methods to call the /self-service-profile endpoints.
+ ///
+ ISelfServiceProfilesClient SelfServiceProfilesClient { get; }
///
/// Update the Access Token used with every request.
diff --git a/src/Auth0.ManagementApi/ManagementApiClient.cs b/src/Auth0.ManagementApi/ManagementApiClient.cs
index fb49b109..c985313b 100644
--- a/src/Auth0.ManagementApi/ManagementApiClient.cs
+++ b/src/Auth0.ManagementApi/ManagementApiClient.cs
@@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Text;
+using Auth0.ManagementApi.Models.SelfServiceProfiles;
namespace Auth0.ManagementApi
{
@@ -168,6 +169,9 @@ public class ManagementApiClient : IManagementApiClient
///
public ISessionsClient Sessions { get; }
+
+ ///
+ public ISelfServiceProfilesClient SelfServiceProfilesClient { get; }
private Dictionary DefaultHeaders { get; set; }
@@ -221,6 +225,7 @@ public ManagementApiClient(string token, Uri baseUri, IManagementConnection mana
Users = new UsersClient(managementConnection, baseUri, DefaultHeaders);
RefreshTokens = new RefreshTokenClient(managementConnection, baseUri, DefaultHeaders);
Sessions = new SessionsClient(managementConnection, baseUri, DefaultHeaders);
+ SelfServiceProfilesClient = new SelfServiceProfilesClient(managementConnection, baseUri, DefaultHeaders);
}
///
diff --git a/src/Auth0.ManagementApi/Models/SelfServiceProfiles/Branding.cs b/src/Auth0.ManagementApi/Models/SelfServiceProfiles/Branding.cs
new file mode 100644
index 00000000..22dbfd19
--- /dev/null
+++ b/src/Auth0.ManagementApi/Models/SelfServiceProfiles/Branding.cs
@@ -0,0 +1,25 @@
+using Newtonsoft.Json;
+
+namespace Auth0.ManagementApi.Models.SelfServiceProfiles
+{
+ public class Branding
+ {
+ ///
+ /// Logo Url
+ ///
+ [JsonProperty("logo_url")]
+ public string LogoUrl { get; set; }
+
+ ///
+ /// Branding Colors
+ ///
+ [JsonProperty("colors")]
+ public Color Color { get; set; }
+ }
+
+ public class Color
+ {
+ [JsonProperty("primary")]
+ public string Primary { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Auth0.ManagementApi/Models/SelfServiceProfiles/EnabledOrganization.cs b/src/Auth0.ManagementApi/Models/SelfServiceProfiles/EnabledOrganization.cs
new file mode 100644
index 00000000..5ee34df0
--- /dev/null
+++ b/src/Auth0.ManagementApi/Models/SelfServiceProfiles/EnabledOrganization.cs
@@ -0,0 +1,16 @@
+using Newtonsoft.Json;
+
+namespace Auth0.ManagementApi.Models.SelfServiceProfiles
+{
+ ///
+ /// List of organizations that the connection will be enabled for.
+ ///
+ public class EnabledOrganization
+ {
+ ///
+ /// Organization identifier
+ ///
+ [JsonProperty("organization_id")]
+ public string OrganizationId { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Auth0.ManagementApi/Models/SelfServiceProfiles/SelfServiceProfile.cs b/src/Auth0.ManagementApi/Models/SelfServiceProfiles/SelfServiceProfile.cs
new file mode 100644
index 00000000..2699e217
--- /dev/null
+++ b/src/Auth0.ManagementApi/Models/SelfServiceProfiles/SelfServiceProfile.cs
@@ -0,0 +1,26 @@
+using System;
+using Newtonsoft.Json;
+
+namespace Auth0.ManagementApi.Models.SelfServiceProfiles
+{
+ public class SelfServiceProfile : SelfServiceProfileBase
+ {
+ ///
+ /// The unique ID of the self-service profile.
+ ///
+ [JsonProperty("id")]
+ public string Id { get; set; }
+
+ ///
+ /// The time when this self-service Profile was created.
+ ///
+ [JsonProperty("created_at")]
+ public DateTime CreatedAt { get; set; }
+
+ ///
+ /// The time when this self-service Profile was updated.
+ ///
+ [JsonProperty("updated_at")]
+ public DateTime UpdatedAt { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Auth0.ManagementApi/Models/SelfServiceProfiles/SelfServiceProfileBase.cs b/src/Auth0.ManagementApi/Models/SelfServiceProfiles/SelfServiceProfileBase.cs
new file mode 100644
index 00000000..490d352f
--- /dev/null
+++ b/src/Auth0.ManagementApi/Models/SelfServiceProfiles/SelfServiceProfileBase.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using Newtonsoft.Json;
+
+namespace Auth0.ManagementApi.Models.SelfServiceProfiles
+{
+ ///
+ /// Represents the Self Service Profile.
+ ///
+ public class SelfServiceProfileBase
+ {
+ ///
+ /// Name of the self-service profile.
+ ///
+ [JsonProperty("name")]
+ public string Name { get; set; }
+
+ ///
+ /// Description of the self-service profile.
+ ///
+ [JsonProperty("description")]
+ public string Description { get; set; }
+
+ ///
+ [JsonProperty("user_attributes")]
+ public IList UserAttributes { get; set; }
+
+ [JsonProperty("branding")]
+ public Branding Branding { get; set; }
+
+ ///
+ /// List of IdP strategies that will be shown to users during the Self-Service SSO flow.
+ /// Possible values: [oidc, samlp, waad, google-apps, adfs, okta, keycloak-samlp, pingfederate]
+ ///
+ [JsonProperty("allowed_strategies")]
+ public string[] AllowedStrategies { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Auth0.ManagementApi/Models/SelfServiceProfiles/SelfServiceProfileCreateRequest.cs b/src/Auth0.ManagementApi/Models/SelfServiceProfiles/SelfServiceProfileCreateRequest.cs
new file mode 100644
index 00000000..0e066995
--- /dev/null
+++ b/src/Auth0.ManagementApi/Models/SelfServiceProfiles/SelfServiceProfileCreateRequest.cs
@@ -0,0 +1,10 @@
+namespace Auth0.ManagementApi.Models.SelfServiceProfiles
+{
+ ///
+ /// Represents information required for creating a Self Service Profile
+ ///
+ public class SelfServiceProfileCreateRequest : SelfServiceProfileBase
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/src/Auth0.ManagementApi/Models/SelfServiceProfiles/SelfServiceProfileUpdateRequest.cs b/src/Auth0.ManagementApi/Models/SelfServiceProfiles/SelfServiceProfileUpdateRequest.cs
new file mode 100644
index 00000000..8321cf66
--- /dev/null
+++ b/src/Auth0.ManagementApi/Models/SelfServiceProfiles/SelfServiceProfileUpdateRequest.cs
@@ -0,0 +1,10 @@
+namespace Auth0.ManagementApi.Models.SelfServiceProfiles
+{
+ ///
+ /// Contains information required for updating Self-Service-Profile
+ ///
+ public class SelfServiceProfileUpdateRequest : SelfServiceProfileBase
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/src/Auth0.ManagementApi/Models/SelfServiceProfiles/SelfServiceSsoConnectionConfig.cs b/src/Auth0.ManagementApi/Models/SelfServiceProfiles/SelfServiceSsoConnectionConfig.cs
new file mode 100644
index 00000000..3b170de0
--- /dev/null
+++ b/src/Auth0.ManagementApi/Models/SelfServiceProfiles/SelfServiceSsoConnectionConfig.cs
@@ -0,0 +1,16 @@
+using Newtonsoft.Json;
+
+namespace Auth0.ManagementApi.Models.SelfServiceProfiles
+{
+ ///
+ /// If provided, this will create a new connection for the SSO flow with the given configuration.
+ ///
+ public class SelfServiceSsoConnectionConfig
+ {
+ ///
+ /// Name of the connection that will be created as part of the SSO flow.
+ ///
+ [JsonProperty("name")]
+ public string Name { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Auth0.ManagementApi/Models/SelfServiceProfiles/SelfServiceSsoTicket.cs b/src/Auth0.ManagementApi/Models/SelfServiceProfiles/SelfServiceSsoTicket.cs
new file mode 100644
index 00000000..b379e9f2
--- /dev/null
+++ b/src/Auth0.ManagementApi/Models/SelfServiceProfiles/SelfServiceSsoTicket.cs
@@ -0,0 +1,16 @@
+using Newtonsoft.Json;
+
+namespace Auth0.ManagementApi.Models.SelfServiceProfiles
+{
+ ///
+ /// SSO-access ticket
+ ///
+ public class SelfServiceSsoTicket
+ {
+ ///
+ /// The URL for the created ticket.
+ ///
+ [JsonProperty("ticket")]
+ public string Ticket { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Auth0.ManagementApi/Models/SelfServiceProfiles/SelfServiceSsoTicketCreateRequest.cs b/src/Auth0.ManagementApi/Models/SelfServiceProfiles/SelfServiceSsoTicketCreateRequest.cs
new file mode 100644
index 00000000..255e8299
--- /dev/null
+++ b/src/Auth0.ManagementApi/Models/SelfServiceProfiles/SelfServiceSsoTicketCreateRequest.cs
@@ -0,0 +1,35 @@
+using System.Collections.Generic;
+using Newtonsoft.Json;
+
+namespace Auth0.ManagementApi.Models.SelfServiceProfiles
+{
+ public class SelfServiceSsoTicketCreateRequest
+ {
+ ///
+ /// If provided, this will allow editing of the provided connection during the SSO Flow
+ ///
+ [JsonProperty("connection_id")]
+ public string ConnectionId { get; set; }
+
+ ///
+ [JsonProperty("connection_config")]
+ public SelfServiceSsoConnectionConfig ConnectionConfig { get; set; }
+
+ ///
+ /// List of client_ids that the connection will be enabled for.
+ ///
+ [JsonProperty("enabled_clients")]
+ public string[] EnabledClients { get; set; }
+
+ ///
+ [JsonProperty("enabled_organizations")]
+ public IList EnabledOrganizations { get; set; }
+
+ ///
+ /// Number of seconds for which the ticket is valid before expiration.
+ /// If unspecified or set to 0, this value defaults to 432000 seconds (5 days).
+ ///
+ [JsonProperty("ttl_sec")]
+ public int? TtlSec { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Auth0.ManagementApi/Models/SelfServiceProfiles/UserAttribute.cs b/src/Auth0.ManagementApi/Models/SelfServiceProfiles/UserAttribute.cs
new file mode 100644
index 00000000..2386b2d1
--- /dev/null
+++ b/src/Auth0.ManagementApi/Models/SelfServiceProfiles/UserAttribute.cs
@@ -0,0 +1,28 @@
+using Newtonsoft.Json;
+
+namespace Auth0.ManagementApi.Models.SelfServiceProfiles
+{
+ ///
+ /// Attribute to be mapped that will be shown to the user during the SS-SSO workflow.
+ ///
+ public class UserAttribute
+ {
+ ///
+ /// Identifier of this attribute.
+ ///
+ [JsonProperty("name")]
+ public string Name { get; set; }
+
+ ///
+ /// Description of this attribute
+ ///
+ [JsonProperty("description")]
+ public string Description { get; set; }
+
+ ///
+ /// Determines if the attribute is required.
+ ///
+ [JsonProperty("is_optional")]
+ public bool? IsOptional { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/tests/Auth0.AuthenticationApi.IntegrationTests/Testing/ManagementTestBaseUtils.cs b/tests/Auth0.AuthenticationApi.IntegrationTests/Testing/ManagementTestBaseUtils.cs
index 452f3679..a72166a8 100644
--- a/tests/Auth0.AuthenticationApi.IntegrationTests/Testing/ManagementTestBaseUtils.cs
+++ b/tests/Auth0.AuthenticationApi.IntegrationTests/Testing/ManagementTestBaseUtils.cs
@@ -3,6 +3,7 @@
using System.Threading.Tasks;
using Auth0.IntegrationTests.Shared.CleanUp;
using Auth0.ManagementApi;
+using Auth0.ManagementApi.Clients;
namespace Auth0.AuthenticationApi.IntegrationTests.Testing
{
@@ -23,7 +24,8 @@ public static async Task CleanupAsync(ManagementApiClient client, CleanUpType ty
new RulesCleanUpStrategy(client),
new LogStreamsCleanUpStrategy(client),
new RolesCleanUpStrategy(client),
- new EncryptionKeysCleanupStrategy(client)
+ new EncryptionKeysCleanupStrategy(client),
+ new SelfServiceProviderCleanUpStrategy(client)
};
var cleanUpStrategy = strategies.Single(s => s.Type == type);
diff --git a/tests/Auth0.IntegrationTests.Shared/CleanUp/CleanUpType.cs b/tests/Auth0.IntegrationTests.Shared/CleanUp/CleanUpType.cs
index a2b0ec83..413a81be 100644
--- a/tests/Auth0.IntegrationTests.Shared/CleanUp/CleanUpType.cs
+++ b/tests/Auth0.IntegrationTests.Shared/CleanUp/CleanUpType.cs
@@ -13,6 +13,7 @@ public enum CleanUpType
Roles,
Rules,
LogStreams,
- EncryptionKeys
+ EncryptionKeys,
+ SelfServiceProvider
}
}
\ No newline at end of file
diff --git a/tests/Auth0.IntegrationTests.Shared/CleanUp/SelfServiceProviderCleanUpStrategy.cs b/tests/Auth0.IntegrationTests.Shared/CleanUp/SelfServiceProviderCleanUpStrategy.cs
new file mode 100644
index 00000000..7bcceeb6
--- /dev/null
+++ b/tests/Auth0.IntegrationTests.Shared/CleanUp/SelfServiceProviderCleanUpStrategy.cs
@@ -0,0 +1,19 @@
+using System.Threading.Tasks;
+using Auth0.ManagementApi;
+
+namespace Auth0.IntegrationTests.Shared.CleanUp
+{
+ public class SelfServiceProviderCleanUpStrategy : CleanUpStrategy
+ {
+ public SelfServiceProviderCleanUpStrategy(ManagementApiClient apiClient) : base(CleanUpType.SelfServiceProvider, apiClient)
+ {
+
+ }
+
+ public override async Task Run(string id)
+ {
+ System.Diagnostics.Debug.WriteLine("Running SelfServiceProviderCleanup");
+ await ApiClient.SelfServiceProfilesClient.DeleteAsync(id);
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/Auth0.ManagementApi.IntegrationTests/SelfServiceProfileTest.cs b/tests/Auth0.ManagementApi.IntegrationTests/SelfServiceProfileTest.cs
new file mode 100644
index 00000000..e986d171
--- /dev/null
+++ b/tests/Auth0.ManagementApi.IntegrationTests/SelfServiceProfileTest.cs
@@ -0,0 +1,189 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Auth0.IntegrationTests.Shared.CleanUp;
+using Auth0.ManagementApi.IntegrationTests.Testing;
+using Auth0.ManagementApi.Models.SelfServiceProfiles;
+using FluentAssertions;
+using Newtonsoft.Json;
+using Xunit;
+
+namespace Auth0.ManagementApi.IntegrationTests;
+
+public class SelfServiceProfileTestFixture : TestBaseFixture
+{
+ public override async Task DisposeAsync()
+ {
+ foreach (KeyValuePair> entry in identifiers)
+ {
+ await ManagementTestBaseUtils.CleanupAsync(ApiClient, entry.Key, entry.Value);
+ }
+
+ ApiClient.Dispose();
+ }
+}
+
+public class SelfServiceProfileTest : IClassFixture
+{
+ private SelfServiceProfileTestFixture _fixture;
+
+ public SelfServiceProfileTest(SelfServiceProfileTestFixture fixture)
+ {
+ _fixture = fixture;
+ }
+
+ [Fact]
+ public async void Test_self_service_profile_crud_operation()
+ {
+ // Create a self-service provider
+ var createRequest = GetASelfServiceProfileCreateRequest();
+ var ssp = await _fixture.ApiClient.SelfServiceProfilesClient.CreateAsync(createRequest);
+ _fixture.TrackIdentifier(CleanUpType.SelfServiceProvider, ssp.Id);
+ ssp.Should().BeEquivalentTo(createRequest);
+
+ // Get the created self-service provider
+ var sspAfterCreation = await _fixture.ApiClient.SelfServiceProfilesClient.GetAsync(ssp.Id);
+ sspAfterCreation.Should().BeEquivalentTo(createRequest);
+
+ // update the self-service provider
+ var sspUpdateRequest = GetASelfServiceProfileUpdateRequest();
+ var sspUpdated = await _fixture.ApiClient.SelfServiceProfilesClient.UpdateAsync(ssp.Id, sspUpdateRequest);
+ sspUpdated.Should().BeEquivalentTo(sspUpdateRequest);
+
+ // Get All self-service providers
+ var allSsps = await _fixture.ApiClient.SelfServiceProfilesClient.GetAllAsync();
+ allSsps.Count.Should().BeGreaterOrEqualTo(1);
+
+ // Delete the self-service provider
+ await _fixture.ApiClient.SelfServiceProfilesClient.DeleteAsync(ssp.Id);
+ }
+
+ [Fact]
+ public async void Test_self_service_sso_ticket_generation_revocation()
+ {
+ var createRequest = GetASelfServiceProfileCreateRequest();
+ var ssp = await CreateASelfServiceProfile(createRequest);
+
+ var existingOrganizationId = "org_V6ojENVd1ERs5YY1";
+ var ssoTicket = await _fixture.ApiClient.SelfServiceProfilesClient.CreateSsoTicketAsync(
+ ssp.Id, new SelfServiceSsoTicketCreateRequest()
+ {
+ ConnectionConfig = new SelfServiceSsoConnectionConfig()
+ {
+ Name = "Test-Connection-For-SSO"
+ },
+ EnabledOrganizations = new List()
+ {
+ new EnabledOrganization()
+ {
+ OrganizationId = existingOrganizationId
+ }
+ }
+ });
+
+ ssoTicket.Should().NotBeNull();
+
+ // Revoke the SSO ticket
+ await _fixture.ApiClient.SelfServiceProfilesClient.RevokeSsoTicketAsync(ssp.Id, ssoTicket.Ticket.Split('=').Last());
+
+ // Delete the self-service profile
+ await _fixture.ApiClient.SelfServiceProfilesClient.DeleteAsync(ssp.Id);
+ }
+
+ [Fact]
+ public async void Test_self_service_custom_text_get_set()
+ {
+ var ssp = await CreateASelfServiceProfile();
+
+ var customTextBody = new Dictionary()
+ {
+ { "introduction", "Hello this is welcome page" }
+ };
+
+ var customText =
+ await _fixture.ApiClient.SelfServiceProfilesClient.SetCustomTextForSelfServiceProfileAsync(
+ ssp.Id, "en", "get-started", customTextBody);
+
+ customText.Should().NotBeNull();
+ customTextBody.Should()
+ .BeEquivalentTo(JsonConvert.DeserializeObject>(customText.ToString()));
+
+ // Fetch the custom text and validate
+ var getCustomText =
+ await _fixture.ApiClient.SelfServiceProfilesClient.GetCustomTextForSelfServiceProfileAsync(
+ ssp.Id, "en", "get-started");
+ getCustomText.Should().BeEquivalentTo(customText);
+
+ // Delete the self-service profile
+ await _fixture.ApiClient.SelfServiceProfilesClient.DeleteAsync(ssp.Id);
+ }
+
+
+ private SelfServiceProfileCreateRequest GetASelfServiceProfileCreateRequest()
+ {
+ var createRequest = new SelfServiceProfileCreateRequest()
+ {
+ Name = "Test Self Service Profile",
+ Description = "Test Self Service Profile Description",
+ UserAttributes = new List()
+ {
+ new UserAttribute()
+ {
+ Name = "email",
+ Description = "Email",
+ IsOptional = false
+ }
+ },
+ Branding = new Branding()
+ {
+ LogoUrl = "https://example.com/logo.png",
+ Color = new Color()
+ {
+ Primary = "#FF0000"
+ }
+ },
+ AllowedStrategies = new string[] { "oidc" }
+ };
+ return createRequest;
+ }
+
+ private SelfServiceProfileUpdateRequest GetASelfServiceProfileUpdateRequest()
+ {
+ var sspUpdateRequest = new SelfServiceProfileUpdateRequest()
+ {
+ Name = "Test Self Service Profile Updated",
+ Description = "Test Self Service Profile Description Updated",
+ UserAttributes = new List()
+ {
+ new UserAttribute()
+ {
+ Name = "email",
+ Description = "Email",
+ IsOptional = true
+ }
+ },
+ Branding = new Branding()
+ {
+ LogoUrl = "https://example.com/logo-updated.png",
+ Color = new Color()
+ {
+ Primary = "#00FF00"
+ }
+ },
+ AllowedStrategies = new string[] { "samlp" }
+ };
+ return sspUpdateRequest;
+ }
+
+ private async Task CreateASelfServiceProfile(
+ SelfServiceProfileCreateRequest createRequest = null)
+ {
+ createRequest ??= GetASelfServiceProfileCreateRequest();
+
+ // Given a self-service profile
+ var ssp = await _fixture.ApiClient.SelfServiceProfilesClient.CreateAsync(createRequest);
+ _fixture.TrackIdentifier(CleanUpType.SelfServiceProvider, ssp.Id);
+ ssp.Should().BeEquivalentTo(createRequest);
+ return ssp;
+ }
+}
\ No newline at end of file
diff --git a/tests/Auth0.ManagementApi.IntegrationTests/Testing/ManagementTestBaseUtils.cs b/tests/Auth0.ManagementApi.IntegrationTests/Testing/ManagementTestBaseUtils.cs
index 4e18d514..e6f1df45 100644
--- a/tests/Auth0.ManagementApi.IntegrationTests/Testing/ManagementTestBaseUtils.cs
+++ b/tests/Auth0.ManagementApi.IntegrationTests/Testing/ManagementTestBaseUtils.cs
@@ -22,7 +22,8 @@ public static async Task CleanupAsync(ManagementApiClient client, CleanUpType ty
new RulesCleanUpStrategy(client),
new LogStreamsCleanUpStrategy(client),
new RolesCleanUpStrategy(client),
- new EncryptionKeysCleanupStrategy(client)
+ new EncryptionKeysCleanupStrategy(client),
+ new SelfServiceProviderCleanUpStrategy(client)
};
var cleanUpStrategy = strategies.Single(s => s.Type == type);