/// <summary> /// Returns the next number in the sequence for the given stream. /// </summary> /// <param name="connection">Database connection.</param> /// <param name="auditStream">Audit stream to get the next sequence number for.</param> /// <returns>Sequence number.</returns> public static long GetNext(SqlConnection connection, AuditStream auditStream) { connection.EnsureOpen(); using (var command = new SqlCommand()) { command.Connection = connection; command.CommandText = $"SELECT NEXT VALUE FOR dbo.{auditStream}"; return((long)command.ExecuteScalar()); } }
/// <summary> /// Logs the given data parameters to the given audit stream. /// </summary> /// <param name="auditStream">Stream for the audit event.</param> /// <param name="action">Summary of the action taken.</param> /// <param name="userDetails">Details to identify the user taking the action.</param> /// <param name="dataPayload">Details about the action taken.</param> public void Log(AuditStream auditStream, string action, object userDetails, object dataPayload) { using (var connection = new SqlConnection(_configuration.ConnectionString)) { connection.Open(); var auditEntry = new AuditEntry() { Sequence = Sequence.GetNext(connection, auditStream), CreatedAt = GetDate, Stream = auditStream.ToString(), Action = action, UserDetails = JsonConvert.SerializeObject(userDetails, Formatting.Indented), DataPayload = JsonConvert.SerializeObject(dataPayload, Formatting.Indented) }; var signingProvider = _certificateManager.GetSigningProvider(); auditEntry.SignAuditMesssage(signingProvider, _configuration.HashAlgorithm); using (var command = new SqlCommand()) { command.Connection = connection; command.CommandText = @" INSERT INTO [AuditLogMessages] ([AuditStream],[Sequence],[CreatedAt],[Action],[UserDetails],[DataPayload],[Signature]) VALUES (@AuditStream,@Sequence,@CreatedAt,@Action,@UserDetails,@DataPayload,@Signature)"; command.Parameters.Add(new SqlParameter("@AuditStream", auditEntry.Stream)); command.Parameters.Add(new SqlParameter("@Sequence", auditEntry.Sequence)); command.Parameters.Add(new SqlParameter("@CreatedAt", auditEntry.CreatedAt)); command.Parameters.Add(new SqlParameter("@Action", auditEntry.Action)); command.Parameters.Add(new SqlParameter("@UserDetails", auditEntry.UserDetails)); command.Parameters.Add(new SqlParameter("@DataPayload", auditEntry.DataPayload)); command.Parameters.Add(new SqlParameter("@Signature", auditEntry.Signature)); try { command.ExecuteNonQuery(); } catch (SqlException sqlex) { throw new AuditEventWriteException("Failed to write audit log entry", auditEntry, sqlex); } } } }
/// <summary> /// Logging method that does nothing. /// </summary> /// <param name="auditStream">Ignored audit stream.</param> /// <param name="action">Ignored user action.</param> /// <param name="userDetails">Ignored user details.</param> /// <param name="dataPayload">Ignored data payload.</param> public void Log(AuditStream auditStream, string action, object userDetails, object dataPayload) { // This is intentionally empty }