Skip to content

Commit

Permalink
Audit events
Browse files Browse the repository at this point in the history
  • Loading branch information
sk-keeper committed May 18, 2022
1 parent b7ad4dd commit 9e6ce84
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 12 deletions.
2 changes: 2 additions & 0 deletions Commander/ConnectedCommands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -702,6 +702,8 @@ private async Task GetCommand(string uid)
tab.AddRow(name, status);
}
}

_vault.AuditLogRecordOpen(record.Uid);
}
}
else if (_vault.TryGetSharedFolder(uid, out var sf))
Expand Down
22 changes: 22 additions & 0 deletions KeeperSdk/auth/AuthCommon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,9 @@ public interface IAuthentication : IAuthEndpoint
/// </summary>
/// <returns>Awaitable Task</returns>
Task Logout();

/// <exclude/>
Task AuditEventLogging(string eventType, AuditEventInput input = null);
}

/// <summary>
Expand Down Expand Up @@ -703,6 +706,25 @@ protected async Task PostLogin()
}
}

/// <exclude/>
public async Task AuditEventLogging(string eventType, AuditEventInput input = null)
{
if (AuthContext.EnterprisePublicEcKey != null)
{
var rq = new AuditEventLoggingCommand
{
ItemLogs = new[] {
new AuditEventItem
{
AuditEventType = eventType,
Inputs = input
}
}
};
_ = await AuthExtensions.ExecuteAuthCommand<AuditEventLoggingCommand, AuditEventLoggingResponse>(this, rq);
}
}

private async Task DoLogout()
{
try
Expand Down
42 changes: 42 additions & 0 deletions KeeperSdk/auth/Commands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -168,4 +168,46 @@ public class ExecuteResponse : KeeperApiResponse
[DataMember(Name = "results")]
public IList<KeeperApiResponse> Results { get; set; }
}

[DataContract]
public class AuditEventInput
{
[DataMember(Name = "record_uid", EmitDefaultValue = false)]
public string RecordUid { get; set; }

[DataMember(Name = "attachment_id", EmitDefaultValue = false)]
public string AttachmentId { get; set; }
}

[DataContract]
public class AuditEventItem
{
[DataMember(Name = "audit_event_type", EmitDefaultValue = false)]
public string AuditEventType { get; set; }

[DataMember(Name = "inputs", EmitDefaultValue = false)]
public AuditEventInput Inputs { get; set; }

[DataMember(Name = "event_time", EmitDefaultValue = false)]
public long? EventTime { get; set; }

}

[DataContract]
public class AuditEventLoggingCommand : AuthenticatedCommand
{
public AuditEventLoggingCommand() : base("audit_event_client_logging") { }

[DataMember(Name = "item_logs", EmitDefaultValue = false)]
public AuditEventItem[] ItemLogs { get; set; }
}

[DataContract]
public class AuditEventLoggingResponse : KeeperApiResponse
{
[DataMember(Name = "ignored", EmitDefaultValue = false)]
public AuditEventItem[] Ignored { get; set; }
}

}

9 changes: 8 additions & 1 deletion KeeperSdk/vault/RecordTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,19 @@ public interface IRecordTypeField
/// </summary>
public class RecordTypeField : IRecordTypeField
{
/// <summary>
/// Initializes a new instance of the RecordTypeField class
/// </summary>
/// <param name="fieldName">Field Name</param>
public RecordTypeField(string fieldName): this(fieldName, null)
{
}
/// <summary>
/// Initializes a new instance of the RecordTypeField class
/// </summary>
/// <param name="fieldName">Field Name</param>
/// <param name="label">Field Label</param>
public RecordTypeField(string fieldName, string label = null)
public RecordTypeField(string fieldName, string label)
{
if (RecordTypesConstants.TryGetRecordField(fieldName, out var rf))
{
Expand Down
13 changes: 11 additions & 2 deletions KeeperSdk/vault/VaultOnline.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
Expand Down Expand Up @@ -151,6 +150,16 @@ protected override void Dispose(bool disposing)
base.Dispose(disposing);
}

/// <inheritdoc/>
public void AuditLogRecordOpen(string recordUid)
{
_ = Task.Run(async () =>
{
await Auth.AuditEventLogging("open_record", new AuditEventInput { RecordUid = recordUid });
});
}


/// <inheritdoc/>
public Task<KeeperRecord> CreateRecord(KeeperRecord record, string folderUid = null)
{
Expand All @@ -160,7 +169,7 @@ public Task<KeeperRecord> CreateRecord(KeeperRecord record, string folderUid = n
/// <inheritdoc/>
public Task<KeeperRecord> UpdateRecord(KeeperRecord record, bool skipExtra = true)
{
return this.PutRecord(record, false, skipExtra);
return this.PutRecord(record, skipExtra);
}

/// <inheritdoc/>
Expand Down
53 changes: 44 additions & 9 deletions KeeperSdk/vault/VaultOnlineFunctions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -350,8 +350,7 @@ void TraverseFolderForRecords(FolderNode folder)
await vault.Auth.ExecuteAuthCommand(request);
}

public static async Task<KeeperRecord> PutRecord(this VaultOnline vault, KeeperRecord record,
bool skipData = false, bool skipExtra = true)
public static async Task<KeeperRecord> PutRecord(this VaultOnline vault, KeeperRecord record, bool skipExtra = true)
{
IStorageRecord existingRecord = null;
if (!string.IsNullOrEmpty(record.Uid))
Expand All @@ -364,7 +363,6 @@ public static async Task<KeeperRecord> PutRecord(this VaultOnline vault, KeeperR
return await vault.AddRecordToFolder(record);
}


if (record is PasswordRecord passwordRecord)
{
var updateRecord = new RecordUpdateRecord
Expand All @@ -384,12 +382,9 @@ public static async Task<KeeperRecord> PutRecord(this VaultOnline vault, KeeperR
}
}

if (!skipData)
{
var data = passwordRecord.ExtractRecordData();
var unencryptedData = JsonUtils.DumpJson(data);
updateRecord.Data = CryptoUtils.EncryptAesV1(unencryptedData, record.RecordKey).Base64UrlEncode();
}
var data = passwordRecord.ExtractRecordData();
var unencryptedData = JsonUtils.DumpJson(data);
updateRecord.Data = CryptoUtils.EncryptAesV1(unencryptedData, record.RecordKey).Base64UrlEncode();

if (!skipExtra)
{
Expand Down Expand Up @@ -521,6 +516,46 @@ public static async Task<KeeperRecord> PutRecord(this VaultOnline vault, KeeperR
throw new Exception($"Unsupported record type: {record.GetType().Name}");
}

if (vault.Auth.AuthContext.EnterprisePublicEcKey != null)
{
_ = Task.Run(async () =>
{
bool logPasswordChanged = false;
switch (existingRecord.Version)
{
case 2:
{
if (record is PasswordRecord pr)
{
var er = existingRecord.LoadV2(record.RecordKey);
logPasswordChanged = (er.Password ?? "") != (pr.Password ?? "");
}
}
break;
case 3:
{
if (record is TypedRecord tr)
{
var er = existingRecord.LoadV3(record.RecordKey);
if (tr.FindTypedField(new RecordTypeField("password"), out var f1) &&
er.FindTypedField(new RecordTypeField("password"), out var f2))
{
var password1 = (f1.Value ?? "").ToString();
var password2 = (f2.Value ?? "").ToString();

logPasswordChanged = password1 != password2;
}
}
}
break;
}
if (logPasswordChanged)
{
await vault.Auth.AuditEventLogging("record_password_change", new AuditEventInput { RecordUid = record.Uid });
}
});
}

await vault.ScheduleSyncDown(TimeSpan.FromSeconds(0));

return vault.TryGetKeeperRecord(record.Uid, out var r) ? r : record;
Expand Down
6 changes: 6 additions & 0 deletions KeeperSdk/vault/VaultTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,12 @@ public interface IVault : IVaultData
/// </summary>
bool AutoSync { get; set; }

/// <summary>
/// Records "open_record" audit event for enterprise accounts
/// </summary>
/// <param name="recordUid"></param>
void AuditLogRecordOpen(string recordUid);

/// <summary>
/// Creates a password record.
/// </summary>
Expand Down

0 comments on commit 9e6ce84

Please sign in to comment.