160 crow::SimpleApp &app,
161 std::shared_ptr<rest_server_context> ctx) {
163 CROW_ROUTE(app,
"/api/v1/audit/logs")
164 .methods(crow::HTTPMethod::GET)([ctx](
const crow::request &req) {
166 res.add_header(
"Content-Type",
"application/json");
167 add_cors_headers(res, *ctx);
169 if (!ctx->database) {
177 auto [limit, offset] = parse_pagination(req);
182 query.offset = offset;
184 auto event_type = req.url_params.get(
"event_type");
186 query.event_type = event_type;
189 auto outcome = req.url_params.get(
"outcome");
191 query.outcome = outcome;
194 auto user_id = req.url_params.get(
"user_id");
196 query.user_id = user_id;
199 auto source_ae = req.url_params.get(
"source_ae");
201 query.source_ae = source_ae;
204 auto patient_id = req.url_params.get(
"patient_id");
206 query.patient_id = patient_id;
209 auto study_uid = req.url_params.get(
"study_uid");
211 query.study_uid = study_uid;
214 auto date_from = req.url_params.get(
"date_from");
216 query.date_from = date_from;
219 auto date_to = req.url_params.get(
"date_to");
221 query.date_to = date_to;
225 auto format_param = req.url_params.get(
"format");
226 bool export_csv = format_param && std::string(format_param) ==
"csv";
230 count_query.
limit = 0;
232 auto all_records_result = ctx->database->query_audit_log(count_query);
233 if (!all_records_result.is_ok()) {
236 all_records_result.error().message);
239 size_t total_count = all_records_result.value().size();
242 auto records_result = ctx->database->query_audit_log(query);
243 if (!records_result.is_ok()) {
246 records_result.error().message);
249 auto records = std::move(records_result.value());
252 res.add_header(
"Content-Type",
"text/csv");
253 res.add_header(
"Content-Disposition",
254 "attachment; filename=\"audit_logs.csv\"");
256 res.body = audit_records_to_csv(records);
259 res.body = audit_records_to_json(records, total_count);
265 CROW_ROUTE(app,
"/api/v1/audit/logs/<int>")
266 .methods(crow::HTTPMethod::GET)(
267 [ctx](
const crow::request & ,
int pk) {
269 res.add_header(
"Content-Type",
"application/json");
270 add_cors_headers(res, *ctx);
272 if (!ctx->database) {
275 "Database not configured");
279 auto record = ctx->database->find_audit_by_pk(pk);
287 res.body = audit_record_to_json(*record);
292 CROW_ROUTE(app,
"/api/v1/audit/export")
293 .methods(crow::HTTPMethod::GET)([ctx](
const crow::request &req) {
295 add_cors_headers(res, *ctx);
297 if (!ctx->database) {
298 res.add_header(
"Content-Type",
"application/json");
308 auto event_type = req.url_params.get(
"event_type");
310 query.event_type = event_type;
313 auto outcome = req.url_params.get(
"outcome");
315 query.outcome = outcome;
318 auto user_id = req.url_params.get(
"user_id");
320 query.user_id = user_id;
323 auto date_from = req.url_params.get(
"date_from");
325 query.date_from = date_from;
328 auto date_to = req.url_params.get(
"date_to");
330 query.date_to = date_to;
333 auto records_result = ctx->database->query_audit_log(query);
334 if (!records_result.is_ok()) {
335 res.add_header(
"Content-Type",
"application/json");
338 records_result.error().message);
341 auto records = std::move(records_result.value());
344 auto format_param = req.url_params.get(
"format");
345 std::string format = format_param ? format_param :
"json";
347 if (format ==
"csv") {
348 res.add_header(
"Content-Type",
"text/csv");
349 res.add_header(
"Content-Disposition",
350 "attachment; filename=\"audit_logs.csv\"");
352 res.body = audit_records_to_csv(records);
354 res.add_header(
"Content-Type",
"application/json");
355 res.add_header(
"Content-Disposition",
356 "attachment; filename=\"audit_logs.json\"");
358 res.body = audit_records_to_json(records, records.size());