-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #292 from rGunti/262-feature-activity-log
Implemented API for Activity Log
- Loading branch information
Showing
44 changed files
with
1,514 additions
and
71 deletions.
There are no files selected for viewing
113 changes: 113 additions & 0 deletions
113
src/FloppyBot.Base.Auditing.Abstraction/AuditorExtenstions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
using System.Diagnostics; | ||
using FloppyBot.Base.Auditing.Abstraction.Entities; | ||
using FloppyBot.Chat.Entities.Identifiers; | ||
|
||
namespace FloppyBot.Base.Auditing.Abstraction; | ||
|
||
[StackTraceHidden] | ||
public static class AuditorExtensions | ||
{ | ||
/// <summary> | ||
/// Records a new event | ||
/// </summary> | ||
/// <seealso cref="IAuditor.Record"/> | ||
/// <param name="auditor">The auditor to use</param> | ||
/// <param name="userIdentifier">The identifier of the user taking the action</param> | ||
/// <param name="channelIdentifier">The channel that this action was taken on</param> | ||
/// <param name="objectType">The type of the object subjected to change</param> | ||
/// <param name="objectIdentifier">An identifier for the object</param> | ||
/// <param name="action">The action performed on the object</param> | ||
/// <param name="additionalData">Additional context data</param> | ||
/// <param name="timestamp">Optional timestamp</param> | ||
public static void Record( | ||
this IAuditor auditor, | ||
string userIdentifier, | ||
string channelIdentifier, | ||
string objectType, | ||
string objectIdentifier, | ||
string action, | ||
string? additionalData = null, | ||
DateTimeOffset? timestamp = null | ||
) | ||
{ | ||
auditor.Record( | ||
new AuditRecord( | ||
// The ID is set to null here, but it will be set by the storage layer | ||
Id: null!, | ||
Timestamp: timestamp ?? DateTimeOffset.MinValue, | ||
UserIdentifier: userIdentifier, | ||
ChannelIdentifier: channelIdentifier, | ||
ObjectType: objectType, | ||
ObjectIdentifier: objectIdentifier, | ||
Action: action, | ||
AdditionalData: additionalData | ||
) | ||
); | ||
} | ||
|
||
/// <summary> | ||
/// Records a new event | ||
/// </summary> | ||
/// <param name="auditor">The auditor to use</param> | ||
/// <param name="user">The identifier of the user taking the action</param> | ||
/// <param name="channel">The channel that this action was taken on</param> | ||
/// <param name="objectType">The type of the object subjected to change</param> | ||
/// <param name="objectIdentifier">An identifier for the object</param> | ||
/// <param name="action">The action performed on the object</param> | ||
/// <param name="additionalData">Additional context data</param> | ||
/// <param name="timestamp">Optional timestamp</param> | ||
public static void Record( | ||
this IAuditor auditor, | ||
ChannelIdentifier user, | ||
ChannelIdentifier channel, | ||
string objectType, | ||
string objectIdentifier, | ||
string action, | ||
string? additionalData = null, | ||
DateTimeOffset? timestamp = null | ||
) | ||
{ | ||
auditor.Record( | ||
user.ToString(), | ||
channel.ToString(), | ||
objectType, | ||
objectIdentifier, | ||
action, | ||
additionalData, | ||
timestamp | ||
); | ||
} | ||
|
||
/// <summary> | ||
/// Records a new event | ||
/// </summary> | ||
/// <param name="auditor">The auditor to use</param> | ||
/// <param name="user">The identifier of the user taking the action</param> | ||
/// <param name="channel">The channel that this action was taken on</param> | ||
/// <param name="object">The object affected</param> | ||
/// <param name="objectIdentifier">A function that returns the identifier of the object</param> | ||
/// <param name="action">The action performed on the object</param> | ||
/// <param name="additionalData">Additional context data</param> | ||
/// <param name="timestamp">Optional timestamp</param> | ||
public static void Record<T>( | ||
this IAuditor auditor, | ||
ChannelIdentifier user, | ||
ChannelIdentifier channel, | ||
T @object, | ||
Func<T, string> objectIdentifier, | ||
string action, | ||
string? additionalData = null, | ||
DateTimeOffset? timestamp = null | ||
) | ||
{ | ||
auditor.Record( | ||
user.ToString(), | ||
channel.ToString(), | ||
typeof(T).Name, | ||
objectIdentifier(@object), | ||
action, | ||
additionalData, | ||
timestamp | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
namespace FloppyBot.Base.Auditing.Abstraction; | ||
|
||
public static class CommonActions | ||
{ | ||
public const string Created = "Created"; | ||
public const string Updated = "Updated"; | ||
public const string Deleted = "Deleted"; | ||
public const string Disabled = "Disabled"; | ||
public const string Enabled = "Enabled"; | ||
} |
12 changes: 12 additions & 0 deletions
12
src/FloppyBot.Base.Auditing.Abstraction/Entities/AuditRecord.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
namespace FloppyBot.Base.Auditing.Abstraction.Entities; | ||
|
||
public record AuditRecord( | ||
string Id, | ||
DateTimeOffset Timestamp, | ||
string UserIdentifier, | ||
string ChannelIdentifier, | ||
string ObjectType, | ||
string ObjectIdentifier, | ||
string Action, | ||
string? AdditionalData | ||
); |
17 changes: 17 additions & 0 deletions
17
src/FloppyBot.Base.Auditing.Abstraction/FloppyBot.Base.Auditing.Abstraction.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\FloppyBot.Chat\FloppyBot.Chat.csproj" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.1" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
using FloppyBot.Base.Auditing.Abstraction.Entities; | ||
|
||
namespace FloppyBot.Base.Auditing.Abstraction; | ||
|
||
/// <summary> | ||
/// A service that records events for auditing purposes | ||
/// </summary> | ||
public interface IAuditor | ||
{ | ||
/// <summary> | ||
/// Records a new event | ||
/// </summary> | ||
/// <param name="auditRecord"></param> | ||
void Record(AuditRecord auditRecord); | ||
|
||
/// <summary> | ||
/// Get a list of audit records for the specified channels | ||
/// </summary> | ||
/// <param name="channels">Channels to query from</param> | ||
/// <returns></returns> | ||
IEnumerable<AuditRecord> GetAuditRecords(params string[] channels); | ||
} |
18 changes: 18 additions & 0 deletions
18
src/FloppyBot.Base.Auditing.Abstraction/Impl/NoopAuditor.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
using FloppyBot.Base.Auditing.Abstraction.Entities; | ||
|
||
namespace FloppyBot.Base.Auditing.Abstraction.Impl; | ||
|
||
/// <summary> | ||
/// A no-op auditor that does nothing, useful for testing | ||
/// </summary> | ||
public class NoopAuditor : IAuditor | ||
{ | ||
/// <inheritdoc /> | ||
public void Record(AuditRecord auditRecord) { } | ||
|
||
/// <inheritdoc /> | ||
public IEnumerable<AuditRecord> GetAuditRecords(params string[] channels) | ||
{ | ||
return []; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
using Microsoft.Extensions.DependencyInjection; | ||
|
||
namespace FloppyBot.Base.Auditing.Abstraction; | ||
|
||
public static class Registration | ||
{ | ||
public static IServiceCollection AddAuditor<T>(this IServiceCollection services) | ||
where T : class, IAuditor | ||
{ | ||
return services.AddScoped<IAuditor, T>(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
using System.Diagnostics; | ||
using FloppyBot.Base.Auditing.Abstraction; | ||
using FloppyBot.Base.Storage; | ||
using FloppyBot.Chat.Entities.Identifiers; | ||
|
||
namespace FloppyBot.Base.Auditing.Storage; | ||
|
||
public static class AuditorExtensions | ||
{ | ||
/// <summary> | ||
/// Records a new event | ||
/// </summary> | ||
/// <param name="auditor">The auditor to use</param> | ||
/// <param name="user">The identifier of the user taking the action</param> | ||
/// <param name="channel">The channel that this action was taken on</param> | ||
/// <param name="object">The object affected</param> | ||
/// <param name="action">The action performed on the object</param> | ||
/// <param name="additionalData">Additional context data</param> | ||
/// <param name="timestamp">Optional timestamp</param> | ||
[StackTraceHidden] | ||
public static void Record<T>( | ||
this IAuditor auditor, | ||
ChannelIdentifier user, | ||
ChannelIdentifier channel, | ||
T @object, | ||
string action, | ||
string? additionalData = null, | ||
DateTimeOffset? timestamp = null | ||
) | ||
where T : IEntity<T> | ||
{ | ||
auditor.Record( | ||
user, | ||
channel, | ||
@object, | ||
GetObjectIdentifier, | ||
action, | ||
additionalData ?? @object.ToString() | ||
); | ||
} | ||
|
||
private static string GetObjectIdentifier<T>(T @object) | ||
where T : IEntity<T> | ||
{ | ||
return @object.Id; | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
src/FloppyBot.Base.Auditing.Storage/FloppyBot.Base.Auditing.Storage.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\FloppyBot.Base.Auditing.Abstraction\FloppyBot.Base.Auditing.Abstraction.csproj" /> | ||
<ProjectReference Include="..\FloppyBot.Base.Clock\FloppyBot.Base.Clock.csproj" /> | ||
<ProjectReference Include="..\FloppyBot.Base.Storage\FloppyBot.Base.Storage.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
49 changes: 49 additions & 0 deletions
49
src/FloppyBot.Base.Auditing.Storage/InternalAuditRecord.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
using FloppyBot.Base.Auditing.Abstraction.Entities; | ||
using FloppyBot.Base.Storage; | ||
|
||
namespace FloppyBot.Base.Auditing.Storage; | ||
|
||
internal record InternalAuditRecord( | ||
string Id, | ||
DateTimeOffset Timestamp, | ||
string UserIdentifier, | ||
string ChannelIdentifier, | ||
string ObjectType, | ||
string ObjectIdentifier, | ||
string Action, | ||
string? AdditionalData | ||
) : IEntity<InternalAuditRecord> | ||
{ | ||
public InternalAuditRecord WithId(string newId) | ||
{ | ||
return this with { Id = newId }; | ||
} | ||
|
||
public AuditRecord ToAuditRecord() | ||
{ | ||
return new AuditRecord( | ||
Id, | ||
Timestamp, | ||
UserIdentifier, | ||
ChannelIdentifier, | ||
ObjectType, | ||
ObjectIdentifier, | ||
Action, | ||
AdditionalData | ||
); | ||
} | ||
|
||
public static InternalAuditRecord FromAuditRecord(AuditRecord auditRecord) | ||
{ | ||
return new InternalAuditRecord( | ||
auditRecord.Id, | ||
auditRecord.Timestamp, | ||
auditRecord.UserIdentifier, | ||
auditRecord.ChannelIdentifier, | ||
auditRecord.ObjectType, | ||
auditRecord.ObjectIdentifier, | ||
auditRecord.Action, | ||
auditRecord.AdditionalData | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
using FloppyBot.Base.Auditing.Abstraction; | ||
using FloppyBot.Base.Auditing.Abstraction.Entities; | ||
using FloppyBot.Base.Clock; | ||
using FloppyBot.Base.Storage; | ||
|
||
namespace FloppyBot.Base.Auditing.Storage; | ||
|
||
/// <summary> | ||
/// Implementation of <see cref="IAuditor"/> that stores audit records in a repository. | ||
/// </summary> | ||
public class StorageAuditor : IAuditor | ||
{ | ||
private readonly IRepository<InternalAuditRecord> _repository; | ||
private readonly ITimeProvider _timeProvider; | ||
|
||
public StorageAuditor(IRepositoryFactory repositoryFactory, ITimeProvider timeProvider) | ||
{ | ||
_timeProvider = timeProvider; | ||
_repository = repositoryFactory.GetRepository<InternalAuditRecord>("AuditRecord"); | ||
} | ||
|
||
/// <inheritdoc /> | ||
public void Record(AuditRecord auditRecord) | ||
{ | ||
_repository.Insert( | ||
InternalAuditRecord.FromAuditRecord(auditRecord) with | ||
{ | ||
Timestamp = _timeProvider.GetCurrentUtcTime(), | ||
} | ||
); | ||
} | ||
|
||
/// <inheritdoc /> | ||
public IEnumerable<AuditRecord> GetAuditRecords(params string[] channels) | ||
{ | ||
return _repository | ||
.GetAll() | ||
.Where(c => channels.Contains(c.ChannelIdentifier)) | ||
.ToList() | ||
.Select(i => i.ToAuditRecord()) | ||
.OrderByDescending(i => i.Timestamp); | ||
} | ||
} |
Oops, something went wrong.