Skip to content
Draft
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
46 changes: 46 additions & 0 deletions src/OneLoginClient/Converters/AppConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using OneLogin.Types;
using System;
using System.Reflection;

namespace OneLogin.Converters
{
public class AppConverter<T> : JsonConverter where T : AppDetail, new()
{
public override bool CanConvert(Type objectType)
{
// ToDo: Build modern target framework without GetTypeInfo hack
return typeof(AppDetail).GetTypeInfo().IsAssignableFrom(objectType.GetTypeInfo());
}

public override bool CanWrite => false;

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{

JObject jObject = JObject.Load(reader);

AppConfiguration configTarget = null;
if (jObject.ContainsKey("auth_method"))
{
var authMethod = (int)jObject["auth_method"];
switch (authMethod)
{
case 2:
configTarget = new AppSamlConfiguration();
break;
}
}

var target = new T() { Configuration = configTarget };
serializer.Populate(jObject.CreateReader(), target);
return target;
}

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
}
5 changes: 5 additions & 0 deletions src/OneLoginClient/Endpoints.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ public static class Endpoints
public const string BaseApi = OneLoginApiBase + API + ApiVersion;
public const string BaseApi2 = OneLoginApiBase + API + ApiVersion2;

/// <summary>
/// https://api.{us_or_eu}.onelogin.com/api/2/apps
/// </summary>
public const string ONELOGIN_APPS = "apps";

/// <summary>
/// https://api.<us_or_eu>.onelogin.com/api/1/users
/// </summary>
Expand Down
89 changes: 89 additions & 0 deletions src/OneLoginClient/OneLogin.Client.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 38 additions & 0 deletions src/OneLoginClient/OneLoginClient.Apps.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using OneLogin.Requests;
using OneLogin.Responses;
using OneLogin.Types;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace OneLogin
{
public partial class OneLoginClient
{
public async Task<GetAppsResponse> GetApps(string name = null, int? connectorId = null, AppAuthMethod? authMethod = null)
{
var parameters = new Dictionary<string, string>
{
{"name", name},
{"connector_id", connectorId.HasValue ? connectorId.ToString() : string.Empty},
{"auth_method", authMethod.HasValue ? authMethod.ToString() : string.Empty}
};
return await GetResource<GetAppsResponse>($"/{Endpoints.API}{Endpoints.ApiVersion2}{Endpoints.ONELOGIN_APPS}", parameters);
}

public async Task<AppDetail> GetAppById(int appId)
{
return await GetResource<AppDetail>($"/{Endpoints.API}{Endpoints.ApiVersion2}{Endpoints.ONELOGIN_APPS}/{appId}");
}

public async Task<AppDetail> UpdateApp(UpdateAppRequest app)
{
return await PutResource<AppDetail>($"/{Endpoints.API}{Endpoints.ApiVersion2}{Endpoints.ONELOGIN_APPS}/{app.Id}", app);
}

public async Task<AppDetail> CreateApp(CreateAppRequest app)
{
return await PostResource<AppDetail>($"/{Endpoints.API}{Endpoints.ApiVersion2}{Endpoints.ONELOGIN_APPS}", app);
}
}
}
10 changes: 2 additions & 8 deletions src/OneLoginClient/OneLoginClient.Events.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using OneLogin.Requests;
using OneLogin.Responses;
Expand Down Expand Up @@ -46,14 +45,9 @@ public async Task<GetEventsResponse> GetEvents(string clientId = null, DateTime?
{"since", since.ToString()},
{"until", until.ToString()},
{"user_id", userId.ToString()},
}
.Where(kv => !string.IsNullOrWhiteSpace(kv.Value))
.Select(kv => $"{kv.Key}={kv.Value}")
.ToList();
};

var url = $"{Endpoints.ONELOGIN_EVENTS}{(parameters.Any() ? "?" : "")}" + string.Join("&", parameters);

return await GetResource<GetEventsResponse>(url);
return await GetResource<GetEventsResponse>(Endpoints.ONELOGIN_EVENTS, parameters);
}

/// <summary>
Expand Down
8 changes: 2 additions & 6 deletions src/OneLoginClient/OneLoginClient.Users.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,9 @@ public async Task<GetUsersResponse> GetUsers(string directoryId = null, string e
{"until", until.ToString()},
{"username", userName},
{"userprincipalname", userPrincipalName}
}
.Where(kv => !string.IsNullOrWhiteSpace(kv.Value))
.Select(kv => $"{kv.Key}={kv.Value}")
.ToList();
};

var url = $"{Endpoints.ONELOGIN_USERS}{(parameters.Any() ? "?" : "")}" + string.Join("&", parameters);
return await GetResource<GetUsersResponse>(url);
return await GetResource<GetUsersResponse>(Endpoints.ONELOGIN_USERS, parameters);
}

/// <summary>
Expand Down
44 changes: 44 additions & 0 deletions src/OneLoginClient/OneLoginClient.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
Expand Down Expand Up @@ -132,7 +133,30 @@ public async Task<List<T>> GetPreviousPages<T>(T source, int? pages = null) wher
return results;
}

/// <summary>
/// Utility method to call OneLogin GET API endpoints and deserialize response
/// </summary>
/// <typeparam name="T">The type of the object to deserialize.</typeparam>
/// <param name="path">The path of the API endpoint</param>
/// <param name="queryParameters">A dictionary of query string parameters</param>
/// <returns></returns>
public async Task<T> GetResource<T>(string path, Dictionary<string, string> queryParameters)
{
var parameters = queryParameters
.Where(kv => !string.IsNullOrWhiteSpace(kv.Value))
.Select(kv => $"{kv.Key}={kv.Value}")
.ToList();

var url = $"{path}{(parameters.Any() ? "?" : "")}" + string.Join("&", parameters);
return await GetResource<T>(url);
}

/// <summary>
/// Utility method to call OneLogin GET API endpoints and deserialize response
/// </summary>
/// <typeparam name="T">The type of the object to deserialize.</typeparam>
/// <param name="url">The relative URL (path and optional query string) of the API endpoint</param>
/// <returns></returns>
public async Task<T> GetResource<T>(string url)
{
if (string.IsNullOrWhiteSpace(url)) { throw new ArgumentException(nameof(url)); }
Expand All @@ -142,6 +166,13 @@ public async Task<T> GetResource<T>(string url)
return response;
}

/// <summary>
/// Utility method to call OneLogin POST API endpoints and deserialize response
/// </summary>
/// <typeparam name="T">The type of the object to deserialize.</typeparam>
/// <param name="url">The relative URL (path and optional query string) of the API endpoint</param>
/// <param name="obj">The object to serialize</param>
/// <returns></returns>
public async Task<T> PostResource<T>(string url, object obj)
{
if (obj == null) throw new ArgumentNullException(nameof(obj));
Expand All @@ -152,6 +183,13 @@ public async Task<T> PostResource<T>(string url, object obj)
return response;
}

/// <summary>
/// Utility method to call OneLogin PUT API endpoints and deserialize response
/// </summary>
/// <typeparam name="T">The type of the object to deserialize.</typeparam>
/// <param name="url">The relative URL (path and optional query string) of the API endpoint</param>
/// <param name="obj">The object to serialize</param>
/// <returns></returns>
public async Task<T> PutResource<T>(string url, object obj)
{
if (obj == null) throw new ArgumentNullException(nameof(obj));
Expand All @@ -162,6 +200,12 @@ public async Task<T> PutResource<T>(string url, object obj)
return response;
}

/// <summary>
/// Utility method to call OneLogin DELETE API endpoints and deserialize response
/// </summary>
/// <typeparam name="T">The type of the object to deserialize.</typeparam>
/// <param name="url">The relative URL (path and optional query string) of the API endpoint</param>
/// <returns></returns>
public async Task<T> DeleteResource<T>(string url)
{
if (string.IsNullOrWhiteSpace(url)) { throw new ArgumentException(nameof(url)); }
Expand Down
19 changes: 19 additions & 0 deletions src/OneLoginClient/Requests/CreateAppRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using OneLogin.Types;
using System;

namespace OneLogin.Requests
{
public class CreateAppRequest : AppDetail
{
public CreateAppRequest(int connectorId, string name)
{
if (string.IsNullOrEmpty(name))
{
throw new ArgumentNullException(nameof(name), "Name is required");
}

ConnectorId = connectorId;
Name = name;
}
}
}
18 changes: 18 additions & 0 deletions src/OneLoginClient/Requests/UpdateAppRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using OneLogin.Types;
using System;

namespace OneLogin.Requests
{
public class UpdateAppRequest : AppDetail
{
public UpdateAppRequest(int appId)
{
if (appId <= 0)
{
throw new ArgumentOutOfRangeException(nameof(appId), "App Id is required in app parameter");
}

Id = appId;
}
}
}
11 changes: 11 additions & 0 deletions src/OneLoginClient/Responses/GetAppsResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using OneLogin.Types;
using System;
using System.Collections.Generic;

namespace OneLogin.Responses
{
public class GetAppsResponse : List<AppSummary>
{

}
}
2 changes: 1 addition & 1 deletion src/OneLoginClient/Serializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace OneLogin
/// </summary>
public class Serializer
{
private static readonly JsonSerializer _serializer = new JsonSerializer { NullValueHandling = NullValueHandling.Ignore };
private static readonly JsonSerializer _serializer = new JsonSerializer { NullValueHandling = NullValueHandling.Ignore, ContractResolver = new SnakeCaseContractResolver() };

/// <summary>
/// Serializes the specified object to a JSON string.
Expand Down
Loading