Database System 0.1.0
Advanced C++20 Database System with Multi-Backend Support
Loading...
Searching...
No Matches
database::security::audit_logger Class Reference

Security audit logging system. More...

#include <secure_connection.h>

Collaboration diagram for database::security::audit_logger:
Collaboration graph

Public Member Functions

 audit_logger ()=default
 Default constructor - used by database_context.
 
 audit_logger (const std::string &log_file_path)
 Constructor with persistent log file path.
 
void log_database_access (const std::string &user_id, const std::string &session_id, const std::string &operation, const std::string &table, const std::string &query_hash, bool success, const std::string &error_message="")
 
void log_authentication_event (const std::string &user_id, const std::string &client_ip, bool success, const std::string &method)
 
void log_authorization_failure (const std::string &user_id, const std::string &operation, const std::string &table, const std::string &reason)
 
std::vector< audit_log_entryget_audit_logs (std::chrono::hours window) const
 
std::vector< audit_log_entryget_user_audit_logs (const std::string &user_id, std::chrono::hours window) const
 
std::string generate_security_report (std::chrono::hours window) const
 
std::vector< std::string > detect_suspicious_activity (std::chrono::hours window) const
 
void set_log_retention_period (std::chrono::hours retention)
 
void cleanup_old_logs ()
 
bool export_logs_to_file (const std::string &filename) const
 

Private Member Functions

void persist_entry (const audit_log_entry &entry)
 

Private Attributes

std::mutex audit_mutex_
 
std::vector< audit_log_entryaudit_logs_
 
std::chrono::hours retention_period_ {24 * 30}
 
std::string log_file_path_
 

Detailed Description

Security audit logging system.

Note
This class uses dependency injection pattern. Access via database_context::get_audit_logger() (Sprint 3, Task 3.3).

Example:

auto context = std::make_shared<database_context>();
auto audit_log = context->get_audit_logger();

Definition at line 268 of file secure_connection.h.

Constructor & Destructor Documentation

◆ audit_logger() [1/2]

database::security::audit_logger::audit_logger ( )
default

Default constructor - used by database_context.

◆ audit_logger() [2/2]

database::security::audit_logger::audit_logger ( const std::string & log_file_path)
explicit

Constructor with persistent log file path.

Parameters
log_file_pathPath to the audit log file for durable storage.

When a log file path is provided, all audit events are appended to the file immediately (with flush) in addition to the in-memory vector.

Definition at line 707 of file secure_connection.cpp.

708 : log_file_path_(log_file_path)
709 {
710 }

Member Function Documentation

◆ cleanup_old_logs()

void database::security::audit_logger::cleanup_old_logs ( )

Definition at line 904 of file secure_connection.cpp.

905 {
906 std::lock_guard<std::mutex> lock(audit_mutex_);
907
908 auto cutoff = std::chrono::system_clock::now() - retention_period_;
909 audit_logs_.erase(
910 std::remove_if(audit_logs_.begin(), audit_logs_.end(),
911 [&cutoff](const audit_log_entry& entry) {
912 return entry.timestamp < cutoff;
913 }),
914 audit_logs_.end());
915 }
std::vector< audit_log_entry > audit_logs_

References audit_logs_, audit_mutex_, and retention_period_.

◆ detect_suspicious_activity()

std::vector< std::string > database::security::audit_logger::detect_suspicious_activity ( std::chrono::hours window) const

Definition at line 868 of file secure_connection.cpp.

870 {
871 auto logs = get_audit_logs(window);
872 std::vector<std::string> alerts;
873
874 // Detect users with high failure rates
875 std::unordered_map<std::string, size_t> user_failures;
876 for (const auto& entry : logs)
877 {
878 if (!entry.success)
879 {
880 ++user_failures[entry.user_id];
881 }
882 }
883
884 for (const auto& [user_id, count] : user_failures)
885 {
886 if (count >= 5)
887 {
888 alerts.push_back("User '" + user_id + "' has " +
889 std::to_string(count) +
890 " failed operations in the last " +
891 std::to_string(window.count()) + " hours");
892 }
893 }
894
895 return alerts;
896 }
std::vector< audit_log_entry > get_audit_logs(std::chrono::hours window) const

References get_audit_logs().

Here is the call graph for this function:

◆ export_logs_to_file()

bool database::security::audit_logger::export_logs_to_file ( const std::string & filename) const

Definition at line 917 of file secure_connection.cpp.

918 {
919 std::lock_guard<std::mutex> lock(audit_mutex_);
920
921 std::ofstream file(filename);
922 if (!file.is_open())
923 {
924 return false;
925 }
926
927 // Write CSV header
928 file << "timestamp,user_id,session_id,operation,table_name,"
929 "query_hash,success,error_message,client_ip,user_agent\n";
930
931 for (const auto& entry : audit_logs_)
932 {
933 auto time_t = std::chrono::system_clock::to_time_t(entry.timestamp);
934 file << time_t << ","
935 << entry.user_id << ","
936 << entry.session_id << ","
937 << entry.operation << ","
938 << entry.table_name << ","
939 << entry.query_hash << ","
940 << (entry.success ? "true" : "false") << ","
941 << entry.error_message << ","
942 << entry.client_ip << ","
943 << entry.user_agent << "\n";
944 }
945
946 return true;
947 }

References audit_logs_, and audit_mutex_.

◆ generate_security_report()

std::string database::security::audit_logger::generate_security_report ( std::chrono::hours window) const

Definition at line 836 of file secure_connection.cpp.

838 {
839 auto logs = get_audit_logs(window);
840
841 size_t total = logs.size();
842 size_t failures = 0;
843 size_t auth_events = 0;
844
845 for (const auto& entry : logs)
846 {
847 if (!entry.success)
848 {
849 ++failures;
850 }
851 if (entry.operation == "authentication")
852 {
853 ++auth_events;
854 }
855 }
856
857 std::ostringstream oss;
858 oss << "Security Report (last " << window.count() << " hours)\n"
859 << " Total events: " << total << "\n"
860 << " Failures: " << failures << "\n"
861 << " Auth events: " << auth_events << "\n"
862 << " Failure rate: "
863 << (total > 0 ? (100.0 * failures / total) : 0.0) << "%\n";
864
865 return oss.str();
866 }

References get_audit_logs().

Here is the call graph for this function:

◆ get_audit_logs()

std::vector< audit_log_entry > database::security::audit_logger::get_audit_logs ( std::chrono::hours window) const

Definition at line 798 of file secure_connection.cpp.

800 {
801 std::lock_guard<std::mutex> lock(audit_mutex_);
802
803 auto cutoff = std::chrono::system_clock::now() - window;
804 std::vector<audit_log_entry> result;
805
806 for (const auto& entry : audit_logs_)
807 {
808 if (entry.timestamp >= cutoff)
809 {
810 result.push_back(entry);
811 }
812 }
813
814 return result;
815 }

References audit_logs_, and audit_mutex_.

Referenced by detect_suspicious_activity(), and generate_security_report().

Here is the caller graph for this function:

◆ get_user_audit_logs()

std::vector< audit_log_entry > database::security::audit_logger::get_user_audit_logs ( const std::string & user_id,
std::chrono::hours window ) const

Definition at line 817 of file secure_connection.cpp.

819 {
820 std::lock_guard<std::mutex> lock(audit_mutex_);
821
822 auto cutoff = std::chrono::system_clock::now() - window;
823 std::vector<audit_log_entry> result;
824
825 for (const auto& entry : audit_logs_)
826 {
827 if (entry.timestamp >= cutoff && entry.user_id == user_id)
828 {
829 result.push_back(entry);
830 }
831 }
832
833 return result;
834 }

References audit_logs_, and audit_mutex_.

◆ log_authentication_event()

void database::security::audit_logger::log_authentication_event ( const std::string & user_id,
const std::string & client_ip,
bool success,
const std::string & method )

Definition at line 762 of file secure_connection.cpp.

766 {
767 audit_log_entry entry;
768 entry.timestamp = std::chrono::system_clock::now();
769 entry.user_id = user_id;
770 entry.client_ip = client_ip;
771 entry.operation = "authentication";
772 entry.success = success;
773 entry.error_message = success ? "" : "Authentication failed via " + method;
774
775 std::lock_guard<std::mutex> lock(audit_mutex_);
776 audit_logs_.push_back(entry);
777 persist_entry(entry);
778 }
void persist_entry(const audit_log_entry &entry)

References audit_logs_, audit_mutex_, database::security::audit_log_entry::client_ip, database::security::audit_log_entry::error_message, database::security::audit_log_entry::operation, persist_entry(), database::success, database::security::audit_log_entry::success, database::security::audit_log_entry::timestamp, and database::security::audit_log_entry::user_id.

Here is the call graph for this function:

◆ log_authorization_failure()

void database::security::audit_logger::log_authorization_failure ( const std::string & user_id,
const std::string & operation,
const std::string & table,
const std::string & reason )

Definition at line 780 of file secure_connection.cpp.

784 {
785 audit_log_entry entry;
786 entry.timestamp = std::chrono::system_clock::now();
787 entry.user_id = user_id;
788 entry.operation = "authorization_failure:" + operation;
789 entry.table_name = table;
790 entry.success = false;
791 entry.error_message = reason;
792
793 std::lock_guard<std::mutex> lock(audit_mutex_);
794 audit_logs_.push_back(entry);
795 persist_entry(entry);
796 }

References audit_logs_, audit_mutex_, database::security::audit_log_entry::error_message, database::security::audit_log_entry::operation, persist_entry(), database::security::audit_log_entry::success, database::security::audit_log_entry::table_name, database::security::audit_log_entry::timestamp, and database::security::audit_log_entry::user_id.

Here is the call graph for this function:

◆ log_database_access()

void database::security::audit_logger::log_database_access ( const std::string & user_id,
const std::string & session_id,
const std::string & operation,
const std::string & table,
const std::string & query_hash,
bool success,
const std::string & error_message = "" )

Definition at line 739 of file secure_connection.cpp.

746 {
747 audit_log_entry entry;
748 entry.timestamp = std::chrono::system_clock::now();
749 entry.user_id = user_id;
750 entry.session_id = session_id;
751 entry.operation = operation;
752 entry.table_name = table;
753 entry.query_hash = query_hash;
754 entry.success = success;
755 entry.error_message = error_message;
756
757 std::lock_guard<std::mutex> lock(audit_mutex_);
758 audit_logs_.push_back(entry);
759 persist_entry(entry);
760 }

References audit_logs_, audit_mutex_, database::security::audit_log_entry::error_message, database::security::audit_log_entry::operation, persist_entry(), database::security::audit_log_entry::query_hash, database::security::audit_log_entry::session_id, database::success, database::security::audit_log_entry::success, database::security::audit_log_entry::table_name, database::security::audit_log_entry::timestamp, and database::security::audit_log_entry::user_id.

Here is the call graph for this function:

◆ persist_entry()

void database::security::audit_logger::persist_entry ( const audit_log_entry & entry)
private

Definition at line 712 of file secure_connection.cpp.

713 {
714 if (log_file_path_.empty())
715 {
716 return;
717 }
718
719 std::ofstream file(log_file_path_, std::ios::app);
720 if (!file.is_open())
721 {
722 return;
723 }
724
725 auto time_t = std::chrono::system_clock::to_time_t(entry.timestamp);
726 file << time_t << ","
727 << entry.user_id << ","
728 << entry.session_id << ","
729 << entry.operation << ","
730 << entry.table_name << ","
731 << entry.query_hash << ","
732 << (entry.success ? "true" : "false") << ","
733 << entry.error_message << ","
734 << entry.client_ip << ","
735 << entry.user_agent << "\n";
736 file.flush();
737 }

References database::security::audit_log_entry::client_ip, database::security::audit_log_entry::error_message, log_file_path_, database::security::audit_log_entry::operation, database::security::audit_log_entry::query_hash, database::security::audit_log_entry::session_id, database::security::audit_log_entry::success, database::security::audit_log_entry::table_name, database::security::audit_log_entry::timestamp, database::security::audit_log_entry::user_agent, and database::security::audit_log_entry::user_id.

Referenced by log_authentication_event(), log_authorization_failure(), and log_database_access().

Here is the caller graph for this function:

◆ set_log_retention_period()

void database::security::audit_logger::set_log_retention_period ( std::chrono::hours retention)

Definition at line 898 of file secure_connection.cpp.

899 {
900 std::lock_guard<std::mutex> lock(audit_mutex_);
901 retention_period_ = retention;
902 }

References audit_mutex_, and retention_period_.

Member Data Documentation

◆ audit_logs_

std::vector<audit_log_entry> database::security::audit_logger::audit_logs_
private

◆ audit_mutex_

std::mutex database::security::audit_logger::audit_mutex_
mutableprivate

◆ log_file_path_

std::string database::security::audit_logger::log_file_path_
private

Definition at line 317 of file secure_connection.h.

Referenced by persist_entry().

◆ retention_period_

std::chrono::hours database::security::audit_logger::retention_period_ {24 * 30}
private

Definition at line 316 of file secure_connection.h.

316{24 * 30}; // 30 days

Referenced by cleanup_old_logs(), and set_log_retention_period().


The documentation for this class was generated from the following files: