Skip to content

Commit

Permalink
Add SSO application manangement
Browse files Browse the repository at this point in the history
  • Loading branch information
itaihanski committed Apr 18, 2024
1 parent 99e38f8 commit ffc6ccf
Show file tree
Hide file tree
Showing 7 changed files with 525 additions and 1 deletion.
93 changes: 93 additions & 0 deletions Descope.Test/IntegrationTests/Management/SsoApplicationTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
using Xunit;

namespace Descope.Test.Integration
{
public class SsoApplicationTests
{
private readonly DescopeClient _descopeClient = IntegrationTestSetup.InitDescopeClient();

[Fact]
public async Task SsoApplication_Saml()
{
string? id = null;
try
{
var name = "name";
var url = "https://sometestidp.com";
// Create
var options = new SamlApplicationOptions(name, url);
id = await _descopeClient.Management.SsoApplication.CreateSAMLApplication(options);

// Load
var loadedApp = await _descopeClient.Management.SsoApplication.Load(id);
Assert.Equal(name, loadedApp.Name);
Assert.Equal(url, loadedApp.SamlSettings!.LoginPageUrl);

// Update
options = new SamlApplicationOptions(name, url) { Id = id };
await _descopeClient.Management.SsoApplication.UpdateSamlApplication(options);

// Load All
var apps = await _descopeClient.Management.SsoApplication.LoadAll();
loadedApp = apps.Find(a => a.Id == id);
Assert.Equal(name, loadedApp!.Name);
Assert.Equal(url, loadedApp.SamlSettings!.LoginPageUrl);

// Delete
await _descopeClient.Management.SsoApplication.Delete(id);
id = null;
}
finally
{
if (!string.IsNullOrEmpty(id))
{
try { await _descopeClient.Management.SsoApplication.Delete(id); }
catch { }
}
}
}

[Fact]
public async Task SsoApplication_Oidc()
{
string? id = null;
try
{
var name = "name";
var url = "https://sometestidp.com";
// Create
var options = new OidcApplicationOptions(name, url);
id = await _descopeClient.Management.SsoApplication.CreateOidcApplication(options);

// Load
var loadedApp = await _descopeClient.Management.SsoApplication.Load(id);
Assert.Equal(name, loadedApp.Name);
Assert.Equal(url, loadedApp.OidcSettings!.LoginPageUrl);

// Update
options = new OidcApplicationOptions(name, url) { Id = id };
await _descopeClient.Management.SsoApplication.UpdateOidcApplication(options);

// Load All
var apps = await _descopeClient.Management.SsoApplication.LoadAll();
loadedApp = apps.Find(a => a.Id == id);
Assert.Equal(name, loadedApp!.Name);
Assert.Equal(url, loadedApp.OidcSettings!.LoginPageUrl);

// Delete
await _descopeClient.Management.SsoApplication.Delete(id);
id = null;
}
finally
{
if (!string.IsNullOrEmpty(id))
{
try { await _descopeClient.Management.SsoApplication.Delete(id); }
catch { }
}
}
}

}

}
12 changes: 12 additions & 0 deletions Descope/Internal/Http/Routes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,18 @@ public static class Routes

#endregion SSO

#region SSO Application

public const string SsoApplicationOidcCreate = "/v1/mgmt/sso/idp/app/oidc/create";
public const string SsoApplicationSamlCreate = "/v1/mgmt/sso/idp/app/saml/create";
public const string SsoApplicationOidcUpdate = "/v1/mgmt/sso/idp/app/oidc/update";
public const string SsoApplicationSamlUpdate = "/v1/mgmt/sso/idp/app/saml/update";
public const string SsoApplicationDelete = "/v1/mgmt/sso/idp/app/delete";
public const string SsoApplicationLoad = "/v1/mgmt/sso/idp/app/load";
public const string SsoApplicationLoadAll = "/v1/mgmt/sso/idp/apps/load";

#endregion SSO Application

#region Permission

public const string PermissionCreate = "/v1/mgmt/permission/create";
Expand Down
3 changes: 3 additions & 0 deletions Descope/Internal/Management/Managment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ internal class Management : IManagement
public IUser User => _user;
public IAccessKey AccessKey => _accessKey;
public ISso Sso => _sso;
public ISsoApplication SsoApplication => _ssoApplication;
public IPasswordSettings Password => _password;
public IJwt Jwt => _jwt;
public IPermission Permission => _permission;
Expand All @@ -16,6 +17,7 @@ internal class Management : IManagement
private readonly User _user;
private readonly AccessKey _accessKey;
private readonly Sso _sso;
private readonly SsoApplication _ssoApplication;
private readonly Password _password;
private readonly Jwt _jwt;
private readonly Permission _permission;
Expand All @@ -28,6 +30,7 @@ public Management(IHttpClient client, string managementKey)
_user = new User(client, managementKey);
_accessKey = new AccessKey(client, managementKey);
_sso = new Sso(client, managementKey);
_ssoApplication = new SsoApplication(client, managementKey);
_password = new Password(client, managementKey);
_jwt = new Jwt(client, managementKey);
_permission = new Permission(client, managementKey);
Expand Down
80 changes: 80 additions & 0 deletions Descope/Internal/Management/SsoApplication.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@

using System.Text.Json.Serialization;

namespace Descope.Internal.Management
{
internal class SsoApplication : ISsoApplication
{
private readonly IHttpClient _httpClient;
private readonly string _managementKey;

internal SsoApplication(IHttpClient httpClient, string managementKey)
{
_httpClient = httpClient;
_managementKey = managementKey;
}

public async Task<string> CreateOidcApplication(OidcApplicationOptions options)
{
var resp = await _httpClient.Post<SsoApplicationCreateResponse>(Routes.SsoApplicationOidcCreate, _managementKey, body: options);
return resp.Id;
}

public async Task<string> CreateSAMLApplication(SamlApplicationOptions options)
{
var resp = await _httpClient.Post<SsoApplicationCreateResponse>(Routes.SsoApplicationSamlCreate, _managementKey, body: options);
return resp.Id;
}

public async Task UpdateOidcApplication(OidcApplicationOptions options)
{
await _httpClient.Post<object>(Routes.SsoApplicationOidcUpdate, _managementKey, body: options);
}

public async Task UpdateSamlApplication(SamlApplicationOptions options)
{
await _httpClient.Post<object>(Routes.SsoApplicationSamlUpdate, _managementKey, body: options);
}

public async Task Delete(string id)
{
var body = new { id };
await _httpClient.Post<object>(Routes.SsoApplicationDelete, _managementKey, body: body);
}

public async Task<SsoApplicationResponse> Load(string id)
{
return await _httpClient.Get<SsoApplicationResponse>(Routes.SsoApplicationLoad, _managementKey, queryParams: new Dictionary<string, string?> { { "id", id } });
}

public async Task<List<SsoApplicationResponse>> LoadAll()
{
var resp = await _httpClient.Get<SsoLoadAllResponse>(Routes.SsoApplicationLoadAll, _managementKey);
return resp.Apps;
}

}

internal class SsoApplicationCreateResponse
{
[JsonPropertyName("id")]
public string Id { get; set; }

public SsoApplicationCreateResponse(string id)
{
Id = id;
}
}

internal class SsoLoadAllResponse
{
[JsonPropertyName("apps")]
public List<SsoApplicationResponse> Apps { get; set; }

public SsoLoadAllResponse(List<SsoApplicationResponse> apps)
{
Apps = apps;
}
}

}
65 changes: 65 additions & 0 deletions Descope/Sdk/Managment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,66 @@ public interface ISso
Task DeleteSettings(string tenantId);
}

/// <summary>
/// Provides functions for managing SSO applications in a project.
/// </summary>
public interface ISsoApplication
{
/// <summary>
/// Create a new OIDC SSO application according to the given options.
/// </summary>
/// <param name="options">Options to define an OIDC application</param>
/// <returns>The created application ID</returns>
public Task<string> CreateOidcApplication(OidcApplicationOptions options);

/// <summary>
/// Create a new SAML SSO application according to the given options.
/// </summary>
/// <param name="options"></param>
/// <returns>The created application ID</returns>
public Task<string> CreateSAMLApplication(SamlApplicationOptions options);

/// <summary>
/// Update an existing OIDC SSO application.
/// <para>
/// <b>IMPORTANT:</b> All options are taken as-is and will override whatever value is currently set. Use carefully.
/// </para>
/// </summary>
/// <param name="options">The options to set for an existing SSO application</param>
public Task UpdateOidcApplication(OidcApplicationOptions options);

/// <summary>
/// Update an existing SAML SSO application.
/// <para>
/// <b>IMPORTANT:</b> All options are taken as-is and will override whatever value is currently set. Use carefully.
/// </para>
/// </summary>
/// <param name="options">The options to set for an existing SSO application</param>
public Task UpdateSamlApplication(SamlApplicationOptions options);

/// <summary>
/// Delete an existing SSO application.
/// <para>
/// <b>IMPORTANT:</b> This action is irreversible. Use carefully.
/// </para>
/// </summary>
/// <param name="id">The ID of application to delete</param>
public Task Delete(string id);

/// <summary>
/// Load an SSO application
/// </summary>
/// <param name="id">The ID of the application to load</param>
/// <returns>The loaded SSO application</returns>
public Task<SsoApplicationResponse> Load(string id);

/// <summary>
/// Load all project SSO applications.
/// </summary>
/// <returns>A list of all SSO applications.</returns>
public Task<List<SsoApplicationResponse>> LoadAll();
}

/// <summary>
/// Provides functions for managing permissions in a project.
/// </summary>
Expand Down Expand Up @@ -788,6 +848,11 @@ public interface IManagement
/// </summary>
public ISso Sso { get; }

/// <summary>
/// Provides functions for configuring SSO Applications in a project.
/// </summary>
public ISsoApplication SsoApplication { get; }

/// <summary>
/// Provides functions for managing password policy for a project or a tenant.
/// </summary>
Expand Down
Loading

0 comments on commit ffc6ccf

Please sign in to comment.