- Add PostgreSQL persistence for dashboards module (was returning empty vec![])
- Tables: dashboards, dashboard_widgets, dashboard_data_sources, dashboard_filters,
dashboard_widget_data_sources, conversational_queries
- Full CRUD operations with spawn_blocking pattern
- Add PostgreSQL persistence for legal module (was using in-memory HashMap)
- Tables: legal_documents, legal_document_versions, cookie_consents, consent_history,
legal_acceptances, data_deletion_requests, data_export_requests
- GDPR-compliant consent tracking and document management
- Add PostgreSQL persistence for compliance module (was returning empty results)
- Tables: compliance_checks, compliance_issues, compliance_audit_log, compliance_evidence,
compliance_risk_assessments, compliance_risks, compliance_training_records,
compliance_access_reviews
- Support for GDPR, SOC2, ISO27001, HIPAA, PCI-DSS frameworks
- Add migration files for all new tables
- Update schema.rs with new table definitions and joinables
- Register new routes in main.rs
- Add recursion_limit = 512 for macro expansion
173 lines
5.2 KiB
Rust
173 lines
5.2 KiB
Rust
use axum::{
|
|
http::StatusCode,
|
|
response::{IntoResponse, Response},
|
|
routing::get,
|
|
Router,
|
|
};
|
|
use std::sync::Arc;
|
|
|
|
use crate::basic::keywords::book::CalendarEngine;
|
|
use crate::shared::state::AppState;
|
|
|
|
pub fn create_caldav_router(_engine: Arc<CalendarEngine>) -> Router<Arc<AppState>> {
|
|
Router::new()
|
|
.route("/caldav", get(caldav_root))
|
|
.route("/caldav/principals", get(caldav_principals))
|
|
.route("/caldav/calendars", get(caldav_calendars))
|
|
.route("/caldav/calendars/:calendar_id", get(caldav_calendar))
|
|
.route(
|
|
"/caldav/calendars/:calendar_id/:event_id.ics",
|
|
get(caldav_event).put(caldav_put_event),
|
|
)
|
|
}
|
|
|
|
async fn caldav_root() -> impl IntoResponse {
|
|
Response::builder()
|
|
.status(StatusCode::OK)
|
|
.header("DAV", "1, 2, calendar-access")
|
|
.header("Content-Type", "application/xml; charset=utf-8")
|
|
.body(
|
|
r#"<?xml version="1.0" encoding="utf-8"?>
|
|
<D:multistatus xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
|
|
<D:response>
|
|
<D:href>/caldav/</D:href>
|
|
<D:propstat>
|
|
<D:prop>
|
|
<D:resourcetype>
|
|
<D:collection/>
|
|
</D:resourcetype>
|
|
<D:displayname>GeneralBots CalDAV Server</D:displayname>
|
|
</D:prop>
|
|
<D:status>HTTP/1.1 200 OK</D:status>
|
|
</D:propstat>
|
|
</D:response>
|
|
</D:multistatus>"#
|
|
.to_string(),
|
|
)
|
|
.unwrap_or_default()
|
|
}
|
|
|
|
async fn caldav_principals() -> impl IntoResponse {
|
|
Response::builder()
|
|
.status(StatusCode::OK)
|
|
.header("Content-Type", "application/xml; charset=utf-8")
|
|
.body(
|
|
r#"<?xml version="1.0" encoding="utf-8"?>
|
|
<D:multistatus xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
|
|
<D:response>
|
|
<D:href>/caldav/principals/</D:href>
|
|
<D:propstat>
|
|
<D:prop>
|
|
<D:resourcetype>
|
|
<D:collection/>
|
|
<D:principal/>
|
|
</D:resourcetype>
|
|
<C:calendar-home-set>
|
|
<D:href>/caldav/calendars/</D:href>
|
|
</C:calendar-home-set>
|
|
</D:prop>
|
|
<D:status>HTTP/1.1 200 OK</D:status>
|
|
</D:propstat>
|
|
</D:response>
|
|
</D:multistatus>"#
|
|
.to_string(),
|
|
)
|
|
.unwrap_or_default()
|
|
}
|
|
|
|
async fn caldav_calendars() -> impl IntoResponse {
|
|
Response::builder()
|
|
.status(StatusCode::OK)
|
|
.header("Content-Type", "application/xml; charset=utf-8")
|
|
.body(
|
|
r#"<?xml version="1.0" encoding="utf-8"?>
|
|
<D:multistatus xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
|
|
<D:response>
|
|
<D:href>/caldav/calendars/</D:href>
|
|
<D:propstat>
|
|
<D:prop>
|
|
<D:resourcetype>
|
|
<D:collection/>
|
|
</D:resourcetype>
|
|
<D:displayname>Calendars</D:displayname>
|
|
</D:prop>
|
|
<D:status>HTTP/1.1 200 OK</D:status>
|
|
</D:propstat>
|
|
</D:response>
|
|
<D:response>
|
|
<D:href>/caldav/calendars/default/</D:href>
|
|
<D:propstat>
|
|
<D:prop>
|
|
<D:resourcetype>
|
|
<D:collection/>
|
|
<C:calendar/>
|
|
</D:resourcetype>
|
|
<D:displayname>Default Calendar</D:displayname>
|
|
<C:supported-calendar-component-set>
|
|
<C:comp name="VEVENT"/>
|
|
<C:comp name="VTODO"/>
|
|
</C:supported-calendar-component-set>
|
|
</D:prop>
|
|
<D:status>HTTP/1.1 200 OK</D:status>
|
|
</D:propstat>
|
|
</D:response>
|
|
</D:multistatus>"#
|
|
.to_string(),
|
|
)
|
|
.unwrap_or_default()
|
|
}
|
|
|
|
async fn caldav_calendar() -> impl IntoResponse {
|
|
Response::builder()
|
|
.status(StatusCode::OK)
|
|
.header("Content-Type", "application/xml; charset=utf-8")
|
|
.body(
|
|
r#"<?xml version="1.0" encoding="utf-8"?>
|
|
<D:multistatus xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
|
|
<D:response>
|
|
<D:href>/caldav/calendars/default/</D:href>
|
|
<D:propstat>
|
|
<D:prop>
|
|
<D:resourcetype>
|
|
<D:collection/>
|
|
<C:calendar/>
|
|
</D:resourcetype>
|
|
<D:displayname>Default Calendar</D:displayname>
|
|
</D:prop>
|
|
<D:status>HTTP/1.1 200 OK</D:status>
|
|
</D:propstat>
|
|
</D:response>
|
|
</D:multistatus>"#
|
|
.to_string(),
|
|
)
|
|
.unwrap_or_default()
|
|
}
|
|
|
|
async fn caldav_event() -> impl IntoResponse {
|
|
Response::builder()
|
|
.status(StatusCode::OK)
|
|
.header("Content-Type", "text/calendar; charset=utf-8")
|
|
.body(
|
|
r"BEGIN:VCALENDAR
|
|
VERSION:2.0
|
|
PRODID:-
|
|
BEGIN:VEVENT
|
|
UID:placeholder@generalbots.com
|
|
DTSTAMP:20240101T000000Z
|
|
DTSTART:20240101T090000Z
|
|
DTEND:20240101T100000Z
|
|
SUMMARY:Placeholder Event
|
|
END:VEVENT
|
|
END:VCALENDAR"
|
|
.to_string(),
|
|
)
|
|
.unwrap_or_default()
|
|
}
|
|
|
|
async fn caldav_put_event() -> impl IntoResponse {
|
|
Response::builder()
|
|
.status(StatusCode::CREATED)
|
|
.header("ETag", "\"placeholder-etag\"")
|
|
.body(String::new())
|
|
.unwrap_or_default()
|
|
}
|