[FEAT] Adds support for enterprise audit logs

This commit is contained in:
gitasaurus
2023-05-09 11:28:58 -04:00
committed by GitHub
parent ecf5af499e
commit 3c82ff359c
31 changed files with 1090 additions and 35 deletions

View File

@@ -0,0 +1,111 @@
using Octokit.Models.Request.Enterprise;
using System;
using System.Diagnostics.CodeAnalysis;
namespace Octokit.Reactive
{
/// <summary>
/// A client for GitHub's Enterprise Audit Log API
/// </summary>
/// <remarks>
/// See the <a href="https://docs.github.com/en/enterprise-cloud@latest/rest/enterprise-admin/audit-log">Enterprise Audit Log API documentation</a> for more information.
///</remarks>
public interface IObservableEnterpriseAuditLogClient
{
/// <summary>
/// Gets GitHub Enterprise Audit Log Entries (must be Site Admin user).
/// </summary>
/// <remarks>
/// https://docs.github.com/en/enterprise-cloud@latest/rest/enterprise-admin/audit-log/#get-the-audit-log-for-an-enterprise
/// </remarks>
/// <param name="enterprise">Name of enterprise</param>
/// <returns>The <see cref="AuditLogEvent"/> list.</returns>
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
IObservable<AuditLogEvent> GetAll(string enterprise);
/// <summary>
/// Gets GitHub Enterprise Audit Log Entries (must be Site Admin user).
/// </summary>
/// <remarks>
/// https://docs.github.com/en/enterprise-cloud@latest/rest/enterprise-admin/audit-log/#get-the-audit-log-for-an-enterprise
/// </remarks>
/// <param name="enterprise">Name of enterprise</param>
/// <param name="request">Used to filter and sort the list of events returned</param>
/// <returns>The <see cref="AuditLogEvent"/> list.</returns>
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
IObservable<AuditLogEvent> GetAll(string enterprise, AuditLogRequest request);
/// <summary>
/// Gets GitHub Enterprise Audit Log Entries (must be Site Admin user).
/// </summary>
/// <remarks>
/// https://docs.github.com/en/enterprise-cloud@latest/rest/enterprise-admin/audit-log/#get-the-audit-log-for-an-enterprise
/// </remarks>
/// <param name="enterprise">Name of enterprise</param>
/// <param name="auditLogApiOptions">Options for changing the API response</param>
/// <returns>The <see cref="AuditLogEvent"/> list.</returns>
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
IObservable<AuditLogEvent> GetAll(string enterprise, AuditLogApiOptions auditLogApiOptions);
/// <summary>
/// Gets GitHub Enterprise Audit Log Entries (must be Site Admin user).
/// </summary>
/// <remarks>
/// https://docs.github.com/en/enterprise-cloud@latest/rest/enterprise-admin/audit-log/#get-the-audit-log-for-an-enterprise
/// </remarks>
/// <param name="enterprise">Name of enterprise</param>
/// <param name="request">Used to filter and sort the list of events returned</param>
/// <param name="auditLogApiOptions">Options for changing the API response</param>
/// <returns>The <see cref="AuditLogEvent"/> list.</returns>
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
IObservable<AuditLogEvent> GetAll(string enterprise, AuditLogRequest request, AuditLogApiOptions auditLogApiOptions);
/// <summary>
/// Gets GitHub Enterprise Audit Log Entries as raw Json (must be Site Admin user).
/// </summary>
/// <remarks>
/// https://docs.github.com/en/enterprise-cloud@latest/rest/enterprise-admin/audit-log/#get-the-audit-log-for-an-enterprise
/// </remarks>
/// <param name="enterprise">Name of enterprise</param>
/// <returns>The <see cref="AuditLogEvent"/> list.</returns>
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
IObservable<object> GetAllJson(string enterprise);
/// <summary>
/// Gets GitHub Enterprise Audit Log Entries as raw Json (must be Site Admin user).
/// </summary>
/// <remarks>
/// https://docs.github.com/en/enterprise-cloud@latest/rest/enterprise-admin/audit-log/#get-the-audit-log-for-an-enterprise
/// </remarks>
/// <param name="enterprise">Name of enterprise</param>
/// <param name="request">Used to filter and sort the list of events returned</param>
/// <returns>The <see cref="AuditLogEvent"/> list.</returns>
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
IObservable<object> GetAllJson(string enterprise, AuditLogRequest request);
/// <summary>
/// Gets GitHub Enterprise Audit Log Entries as raw Json (must be Site Admin user).
/// </summary>
/// <remarks>
/// https://docs.github.com/en/enterprise-cloud@latest/rest/enterprise-admin/audit-log/#get-the-audit-log-for-an-enterprise
/// </remarks>
/// <param name="enterprise">Name of enterprise</param>
/// <param name="auditLogApiOptions">Options for changing the API response</param>
/// <returns>The <see cref="AuditLogEvent"/> list.</returns>
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
IObservable<object> GetAllJson(string enterprise, AuditLogApiOptions auditLogApiOptions);
/// <summary>
/// Gets GitHub Enterprise Audit Log Entries as raw Json (must be Site Admin user).
/// </summary>
/// <remarks>
/// https://docs.github.com/en/enterprise-cloud@latest/rest/enterprise-admin/audit-log/#get-the-audit-log-for-an-enterprise
/// </remarks>
/// <param name="enterprise">Name of enterprise</param>
/// <param name="request">Used to filter and sort the list of issues returned</param>
/// <param name="auditLogApiOptions">Options for changing the API response</param>
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
[ManualRoute("GET", "/enterprise/audit-log")]
IObservable<object> GetAllJson(string enterprise, AuditLogRequest request, AuditLogApiOptions auditLogApiOptions);
}
}

View File

@@ -16,6 +16,14 @@
/// </remarks>
IObservableEnterpriseAdminStatsClient AdminStats { get; }
/// <summary>
/// A client for GitHub's Enterprise Audit Log API
/// </summary>
/// <remarks>
/// See the <a href="https://docs.github.com/en/enterprise-cloud@latest/rest/enterprise-admin/audit-log">Enterprise Audit Log API documentation</a> for more information.
/// </remarks>
IObservableEnterpriseAuditLogClient AuditLog { get; }
/// <summary>
/// A client for GitHub's Enterprise LDAP API
/// </summary>

View File

@@ -0,0 +1,195 @@
using Octokit.Models.Request.Enterprise;
using Octokit.Reactive.Internal;
using System;
using System.Collections.Generic;
using System.Reactive.Threading.Tasks;
using System.Threading.Tasks;
namespace Octokit.Reactive
{
/// <summary>
/// A client for GitHub's Enterprise Admin Stats API
/// </summary>
/// <remarks>
/// See the <a href="https://developer.github.com/v3/enterprise/admin_stats/">Enterprise Admin Stats API documentation</a> for more information.
///</remarks>
public class ObservableEnterpriseAuditLogClient : IObservableEnterpriseAuditLogClient
{
readonly IConnection _connection;
public ObservableEnterpriseAuditLogClient(IGitHubClient client)
{
Ensure.ArgumentNotNull(client, "client");
_connection = client.Connection;
}
/// <summary>
/// Gets GitHub Enterprise Audit Log Entries (must be Site Admin user). Note: Defaults to 100 entries per page (max count).
/// </summary>
/// <remarks>
/// https://docs.github.com/en/enterprise-cloud@latest/rest/enterprise-admin/audit-log/#get-the-audit-log-for-an-enterprise
/// </remarks>
/// <param name="enterprise">Name of enterprise</param>
/// <returns>The <see cref="AuditLogEvent"/> list.</returns>
public IObservable<AuditLogEvent> GetAll(string enterprise)
{
Ensure.ArgumentNotNull(enterprise, nameof(enterprise));
return GetAll(enterprise, new AuditLogRequest(), new AuditLogApiOptions());
}
/// <summary>
/// Gets GitHub Enterprise Audit Log Entries (must be Site Admin user). Note: Defaults to 100 entries per page (max count).
/// </summary>
/// <remarks>
/// https://docs.github.com/en/enterprise-cloud@latest/rest/enterprise-admin/audit-log/#get-the-audit-log-for-an-enterprise
/// </remarks>
/// <param name="enterprise">Name of enterprise</param>
/// <param name="request">Used to filter and sort the list of issues returned</param>
/// <returns>The <see cref="AuditLogEvent"/> list.</returns>
public IObservable<AuditLogEvent> GetAll(string enterprise, AuditLogRequest request)
{
Ensure.ArgumentNotNull(enterprise, nameof(enterprise));
Ensure.ArgumentNotNull(request, nameof(request));
return GetAll(enterprise, request, new AuditLogApiOptions());
}
/// <summary>
/// Gets GitHub Enterprise Audit Log Entries (must be Site Admin user).
/// </summary>
/// <remarks>
/// https://docs.github.com/en/enterprise-cloud@latest/rest/enterprise-admin/audit-log/#get-the-audit-log-for-an-enterprise
/// </remarks>
/// <param name="enterprise">Name of enterprise</param>
/// <param name="auditLogApiOptions">Options for changing the API response</param>
/// <returns>The <see cref="AuditLogEvent"/> list.</returns>
public IObservable<AuditLogEvent> GetAll(string enterprise, AuditLogApiOptions auditLogApiOptions)
{
Ensure.ArgumentNotNull(enterprise, nameof(enterprise));
Ensure.ArgumentNotNull(auditLogApiOptions, nameof(auditLogApiOptions));
return GetAll(enterprise, new AuditLogRequest(), auditLogApiOptions);
}
/// <summary>
/// Gets GitHub Enterprise Audit Log Entries (must be Site Admin user).
/// </summary>
/// <remarks>
/// https://docs.github.com/en/enterprise-cloud@latest/rest/enterprise-admin/audit-log/#get-the-audit-log-for-an-enterprise
/// </remarks>
/// <param name="enterprise">Name of enterprise</param>
/// <param name="request">Used to filter and sort the list of events returned</param>
/// <param name="auditLogApiOptions">Options for changing the API response</param>
/// <returns>The <see cref="AuditLogEvent"/> list.</returns>
public IObservable<AuditLogEvent> GetAll(string enterprise, AuditLogRequest request, AuditLogApiOptions auditLogApiOptions)
{
Ensure.ArgumentNotNull(enterprise, nameof(enterprise));
ApiOptionsExtended options = new ApiOptionsExtended()
{
PageSize = auditLogApiOptions.PageSize
};
return _connection.GetAndFlattenAllPages<AuditLogEvent>(ApiUrls.EnterpriseAuditLog(enterprise), request.ToParametersDictionary(), null, options, GeneratePreProcessFunction(auditLogApiOptions, options));
}
/// <summary>
/// Gets GitHub Enterprise Audit Log Entries as raw Json (must be Site Admin user). Note: Defaults to 100 entries per page (max count).
/// </summary>
/// <remarks>
/// https://docs.github.com/en/enterprise-cloud@latest/rest/enterprise-admin/audit-log/#get-the-audit-log-for-an-enterprise
/// </remarks>
/// <param name="enterprise">Name of enterprise</param>
/// <returns>The <see cref="AuditLogEvent"/> list.</returns>
public IObservable<object> GetAllJson(string enterprise)
{
Ensure.ArgumentNotNull(enterprise, nameof(enterprise));
return GetAllJson(enterprise, new AuditLogRequest(), new AuditLogApiOptions());
}
/// <summary>
/// Gets GitHub Enterprise Audit Log Entries as raw Json (must be Site Admin user). Note: Defaults to 100 entries per page (max count).
/// </summary>
/// <remarks>
/// https://docs.github.com/en/enterprise-cloud@latest/rest/enterprise-admin/audit-log/#get-the-audit-log-for-an-enterprise
/// </remarks>
/// <param name="enterprise">Name of enterprise</param>
/// <param name="request">Used to filter and sort the list of events returned</param>
/// <returns>The <see cref="AuditLogEvent"/> list.</returns>
public IObservable<object> GetAllJson(string enterprise, AuditLogRequest request)
{
Ensure.ArgumentNotNull(enterprise, nameof(enterprise));
return GetAllJson(enterprise, request, new AuditLogApiOptions());
}
/// <summary>
/// Gets GitHub Enterprise Audit Log Entries as raw Json (must be Site Admin user).
/// </summary>
/// <remarks>
/// https://docs.github.com/en/enterprise-cloud@latest/rest/enterprise-admin/audit-log/#get-the-audit-log-for-an-enterprise
/// </remarks>
/// <param name="enterprise">Name of enterprise</param>
/// <param name="auditLogApiOptions">Options for changing the API response</param>
/// <returns>The <see cref="AuditLogEvent"/> list.</returns>
public IObservable<object> GetAllJson(string enterprise, AuditLogApiOptions auditLogApiOptions)
{
Ensure.ArgumentNotNull(enterprise, nameof(enterprise));
return GetAllJson(enterprise, new AuditLogRequest(), auditLogApiOptions);
}
/// <summary>
/// Gets GitHub Enterprise Audit Log Entries as raw Json (must be Site Admin user).
/// </summary>
/// <remarks>
/// https://docs.github.com/en/enterprise-cloud@latest/rest/enterprise-admin/audit-log/#get-the-audit-log-for-an-enterprise
/// </remarks>
/// <param name="enterprise">Name of enterprise</param>
/// <param name="request">Used to filter and sort the list of events returned</param>
/// <param name="auditLogApiOptions">Options for changing the API response</param>
/// <returns>The <see cref="AuditLogEvent"/> list.</returns>
public IObservable<object> GetAllJson(string enterprise, AuditLogRequest request, AuditLogApiOptions auditLogApiOptions)
{
Ensure.ArgumentNotNull(enterprise, nameof(enterprise));
ApiOptionsExtended options = new ApiOptionsExtended()
{
PageSize = auditLogApiOptions.PageSize
};
return _connection.GetAndFlattenAllPages<AuditLogEvent>(ApiUrls.EnterpriseAuditLog(enterprise), request.ToParametersDictionary(), null, options, GeneratePreProcessFunction(auditLogApiOptions, options));
}
private static Func<object, object> GeneratePreProcessFunction(AuditLogApiOptions auditLogApiOptions, ApiOptionsExtended options)
{
Func<object, object> preProcessResponseBody = null;
if (string.IsNullOrEmpty(auditLogApiOptions?.StopWhenFound))
preProcessResponseBody = (r) =>
{
if (r is string body)
r = body.Replace("_document_id", "document_id").Replace("@timestamp", "timestamp");
return r;
};
else
preProcessResponseBody = (r) =>
{
if (r is string body)
{
if (body.Contains(auditLogApiOptions.StopWhenFound))
options.IsDone = true;
r = body.Replace("_document_id", "document_id").Replace("@timestamp", "timestamp");
}
return r;
};
return preProcessResponseBody;
}
}
}

View File

@@ -13,6 +13,7 @@
Ensure.ArgumentNotNull(client, nameof(client));
AdminStats = new ObservableEnterpriseAdminStatsClient(client);
AuditLog = new ObservableEnterpriseAuditLogClient(client);
Ldap = new ObservableEnterpriseLdapClient(client);
License = new ObservableEnterpriseLicenseClient(client);
ManagementConsole = new ObservableEnterpriseManagementConsoleClient(client);
@@ -30,6 +31,14 @@
/// </remarks>
public IObservableEnterpriseAdminStatsClient AdminStats { get; private set; }
/// <summary>
/// A client for GitHub's Enterprise Audit Log API
/// </summary>
/// <remarks>
/// See the <a href="https://docs.github.com/en/enterprise-cloud@latest/rest/enterprise-admin/audit-log">Enterprise Audit Log API documentation</a> for more information.
/// </remarks>
public IObservableEnterpriseAuditLogClient AuditLog { get; }
/// <summary>
/// A client for GitHub's Enterprise LDAP API
/// </summary>

View File

@@ -46,6 +46,15 @@ namespace Octokit.Reactive.Internal
});
}
public static IObservable<T> GetAndFlattenAllPages<T>(this IConnection connection, Uri url, IDictionary<string, string> parameters, string accepts, ApiOptions options, Func<object, object> preprocessResponseBody)
{
return GetPagesWithOptionsAndCallback(url, parameters, options, preprocessResponseBody, (pageUrl, pageParams, o, preprocess) =>
{
var passingParameters = Pagination.Setup(parameters, options);
return connection.Get<List<T>>(pageUrl, passingParameters, accepts).ToObservable();
});
}
static IObservable<T> GetPages<T>(Uri uri, IDictionary<string, string> parameters,
Func<Uri, IDictionary<string, string>, IObservable<IApiResponse<List<T>>>> getPageFunc)
{
@@ -75,5 +84,21 @@ namespace Octokit.Reactive.Internal
.Where(resp => resp != null)
.SelectMany(resp => resp.Body);
}
static IObservable<T> GetPagesWithOptionsAndCallback<T>(Uri uri, IDictionary<string, string> parameters, ApiOptions options, Func<object, object> preprocessResponseBody, Func<Uri, IDictionary<string, string>, ApiOptions, Func<object, object>, IObservable<IApiResponse<List<T>>>> getPageFunc)
{
return getPageFunc(uri, parameters, options, preprocessResponseBody).Expand(resp =>
{
var nextPageUrl = resp.HttpResponse.ApiInfo.GetNextPageUrl();
var shouldContinue = Pagination.ShouldContinue(nextPageUrl, options);
return shouldContinue
? Observable.Defer(() => getPageFunc(nextPageUrl, null, null, preprocessResponseBody))
: Observable.Empty<IApiResponse<List<T>>>();
})
.Where(resp => resp != null)
.SelectMany(resp => resp.Body);
}
}
}

View File

@@ -35,7 +35,7 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="..\Octokit\Helpers\Ensure.cs;..\Octokit\Helpers\Pagination.cs" />
<Compile Include="..\Octokit\Helpers\Ensure.cs;..\Octokit\Helpers\Pagination.cs;..\Octokit\Models\Request\Enterprise\ApiOptionsExtended.cs" />
<None Include="app.config" />
</ItemGroup>