mirror of
https://github.com/lennart-k/rustical.git
synced 2025-12-22 23:39:34 +00:00
Refactoring: Lots of fixes still necessary to get it into a working state
This commit is contained in:
@@ -2,11 +2,9 @@ use actix_web::{web::Data, HttpRequest};
|
||||
use anyhow::{anyhow, Result};
|
||||
use async_trait::async_trait;
|
||||
use rustical_auth::AuthInfo;
|
||||
use rustical_dav::dav_resource::{Resource, ResourceService};
|
||||
use rustical_dav::error::Error;
|
||||
use rustical_dav::{
|
||||
resource::Resource,
|
||||
xml_snippets::{HrefElement, TextNode},
|
||||
};
|
||||
use rustical_dav::xml_snippets::{HrefElement, TextNode};
|
||||
use rustical_store::calendar::{Calendar, CalendarStore};
|
||||
use serde::Serialize;
|
||||
use std::sync::Arc;
|
||||
@@ -15,10 +13,10 @@ use tokio::sync::RwLock;
|
||||
|
||||
pub struct CalendarResource<C: CalendarStore + ?Sized> {
|
||||
pub cal_store: Arc<RwLock<C>>,
|
||||
pub calendar: Calendar,
|
||||
pub path: String,
|
||||
pub prefix: String,
|
||||
pub principal: String,
|
||||
pub calendar_id: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
@@ -159,51 +157,17 @@ pub enum CalendarPropResponse {
|
||||
CurrentUserPrivilegeSet(UserPrivilegeSet),
|
||||
}
|
||||
|
||||
#[async_trait(?Send)]
|
||||
impl<C: CalendarStore + ?Sized> Resource for CalendarResource<C> {
|
||||
type MemberType = Self;
|
||||
type UriComponents = (String, String); // principal, calendar_id
|
||||
pub struct CalendarFile {
|
||||
pub calendar: Calendar,
|
||||
pub principal: String,
|
||||
pub prefix: String,
|
||||
pub path: String,
|
||||
}
|
||||
|
||||
impl Resource for CalendarFile {
|
||||
type PropType = CalendarProp;
|
||||
type PropResponse = CalendarPropResponse;
|
||||
|
||||
async fn acquire_from_request(
|
||||
req: HttpRequest,
|
||||
_auth_info: AuthInfo,
|
||||
uri_components: Self::UriComponents,
|
||||
prefix: String,
|
||||
) -> Result<Self, Error> {
|
||||
let cal_store = req
|
||||
.app_data::<Data<RwLock<C>>>()
|
||||
.ok_or(anyhow!("no calendar store in app_data!"))?
|
||||
.clone()
|
||||
.into_inner();
|
||||
|
||||
let (principal, cid) = uri_components;
|
||||
// TODO: fix errors
|
||||
let calendar = cal_store
|
||||
.read()
|
||||
.await
|
||||
.get_calendar(&cid)
|
||||
.await
|
||||
.map_err(|_e| Error::NotFound)?;
|
||||
Ok(Self {
|
||||
cal_store,
|
||||
calendar,
|
||||
path: req.path().to_string(),
|
||||
prefix,
|
||||
principal,
|
||||
})
|
||||
}
|
||||
|
||||
fn get_path(&self) -> &str {
|
||||
&self.path
|
||||
}
|
||||
|
||||
async fn get_members(&self) -> Result<Vec<Self::MemberType>> {
|
||||
// As of now the calendar resource has no members
|
||||
Ok(vec![])
|
||||
}
|
||||
|
||||
fn get_prop(&self, prop: Self::PropType) -> Result<Self::PropResponse> {
|
||||
match prop {
|
||||
CalendarProp::Resourcetype => {
|
||||
@@ -246,4 +210,61 @@ impl<C: CalendarStore + ?Sized> Resource for CalendarResource<C> {
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_path(&self) -> &str {
|
||||
&self.path
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait(?Send)]
|
||||
impl<C: CalendarStore + ?Sized> ResourceService for CalendarResource<C> {
|
||||
type MemberType = CalendarFile;
|
||||
type PathComponents = (String, String); // principal, calendar_id
|
||||
type File = CalendarFile;
|
||||
|
||||
async fn get_file(&self) -> Result<Self::File> {
|
||||
let calendar = self
|
||||
.cal_store
|
||||
.read()
|
||||
.await
|
||||
.get_calendar(&self.calendar_id)
|
||||
.await
|
||||
.map_err(|_e| Error::NotFound)?;
|
||||
Ok(CalendarFile {
|
||||
calendar,
|
||||
prefix: self.prefix.to_owned(),
|
||||
principal: self.principal.to_owned(),
|
||||
path: self.path.to_owned(),
|
||||
})
|
||||
}
|
||||
|
||||
async fn get_members(
|
||||
&self,
|
||||
_auth_info: AuthInfo,
|
||||
_path_components: Self::PathComponents,
|
||||
) -> Result<Vec<Self::MemberType>> {
|
||||
// As of now the calendar resource has no members
|
||||
Ok(vec![])
|
||||
}
|
||||
|
||||
async fn new(
|
||||
req: HttpRequest,
|
||||
auth_info: AuthInfo,
|
||||
path_components: Self::PathComponents,
|
||||
prefix: String,
|
||||
) -> Result<Self, rustical_dav::error::Error> {
|
||||
let cal_store = req
|
||||
.app_data::<Data<RwLock<C>>>()
|
||||
.ok_or(anyhow!("no calendar store in app_data!"))?
|
||||
.clone()
|
||||
.into_inner();
|
||||
|
||||
Ok(Self {
|
||||
prefix,
|
||||
path: req.path().to_owned(),
|
||||
principal: auth_info.user_id,
|
||||
calendar_id: path_components.1,
|
||||
cal_store,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,9 @@ use actix_web::{web::Data, HttpRequest};
|
||||
use anyhow::{anyhow, Result};
|
||||
use async_trait::async_trait;
|
||||
use rustical_auth::AuthInfo;
|
||||
use rustical_dav::error::Error;
|
||||
use rustical_dav::{resource::Resource, xml_snippets::TextNode};
|
||||
use rustical_dav::dav_resource::Resource;
|
||||
use rustical_dav::xml_snippets::TextNode;
|
||||
use rustical_dav::{dav_resource::ResourceService, error::Error};
|
||||
use rustical_store::calendar::CalendarStore;
|
||||
use rustical_store::event::Event;
|
||||
use serde::Serialize;
|
||||
@@ -14,7 +15,8 @@ use tokio::sync::RwLock;
|
||||
pub struct EventResource<C: CalendarStore + ?Sized> {
|
||||
pub cal_store: Arc<RwLock<C>>,
|
||||
pub path: String,
|
||||
pub event: Event,
|
||||
pub cid: String,
|
||||
pub uid: String,
|
||||
}
|
||||
|
||||
#[derive(EnumString, Debug, VariantNames, IntoStaticStr, Clone)]
|
||||
@@ -33,42 +35,16 @@ pub enum PrincipalPropResponse {
|
||||
Getcontenttype(TextNode),
|
||||
}
|
||||
|
||||
#[async_trait(?Send)]
|
||||
impl<C: CalendarStore + ?Sized> Resource for EventResource<C> {
|
||||
type UriComponents = (String, String, String); // principal, calendar, event
|
||||
type MemberType = Self;
|
||||
pub struct EventFile {
|
||||
pub event: Event,
|
||||
}
|
||||
|
||||
impl Resource for EventFile {
|
||||
type PropType = EventProp;
|
||||
type PropResponse = PrincipalPropResponse;
|
||||
|
||||
fn get_path(&self) -> &str {
|
||||
&self.path
|
||||
}
|
||||
|
||||
async fn get_members(&self) -> Result<Vec<Self::MemberType>> {
|
||||
Ok(vec![])
|
||||
}
|
||||
|
||||
async fn acquire_from_request(
|
||||
req: HttpRequest,
|
||||
_auth_info: AuthInfo,
|
||||
uri_components: Self::UriComponents,
|
||||
_prefix: String,
|
||||
) -> Result<Self, Error> {
|
||||
let (_principal, cid, uid) = uri_components;
|
||||
|
||||
let cal_store = req
|
||||
.app_data::<Data<RwLock<C>>>()
|
||||
.ok_or(anyhow!("no calendar store in app_data!"))?
|
||||
.clone()
|
||||
.into_inner();
|
||||
|
||||
let event = cal_store.read().await.get_event(&cid, &uid).await?;
|
||||
|
||||
Ok(Self {
|
||||
cal_store,
|
||||
event,
|
||||
path: req.path().to_string(),
|
||||
})
|
||||
"asd"
|
||||
}
|
||||
|
||||
fn get_prop(&self, prop: Self::PropType) -> Result<Self::PropResponse> {
|
||||
@@ -77,7 +53,7 @@ impl<C: CalendarStore + ?Sized> Resource for EventResource<C> {
|
||||
self.event.get_etag(),
|
||||
)))),
|
||||
EventProp::CalendarData => Ok(PrincipalPropResponse::CalendarData(TextNode(Some(
|
||||
self.event.get_ics(),
|
||||
self.event.get_ics().to_owned(),
|
||||
)))),
|
||||
EventProp::Getcontenttype => Ok(PrincipalPropResponse::Getcontenttype(TextNode(Some(
|
||||
"text/calendar;charset=utf-8".to_owned(),
|
||||
@@ -85,3 +61,52 @@ impl<C: CalendarStore + ?Sized> Resource for EventResource<C> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait(?Send)]
|
||||
impl<C: CalendarStore + ?Sized> ResourceService for EventResource<C> {
|
||||
type PathComponents = (String, String, String); // principal, calendar, event
|
||||
type File = EventFile;
|
||||
type MemberType = EventFile;
|
||||
|
||||
async fn get_members(
|
||||
&self,
|
||||
_auth_info: AuthInfo,
|
||||
_path_components: Self::PathComponents,
|
||||
) -> Result<Vec<Self::MemberType>> {
|
||||
Ok(vec![])
|
||||
}
|
||||
|
||||
async fn new(
|
||||
req: HttpRequest,
|
||||
_auth_info: AuthInfo,
|
||||
path_components: Self::PathComponents,
|
||||
_prefix: String,
|
||||
) -> Result<Self, Error> {
|
||||
let (_principal, cid, uid) = path_components;
|
||||
|
||||
let cal_store = req
|
||||
.app_data::<Data<RwLock<C>>>()
|
||||
.ok_or(anyhow!("no calendar store in app_data!"))?
|
||||
.clone()
|
||||
.into_inner();
|
||||
|
||||
// let event = cal_store.read().await.get_event(&cid, &uid).await?;
|
||||
|
||||
Ok(Self {
|
||||
cal_store,
|
||||
cid,
|
||||
uid,
|
||||
path: req.path().to_string(),
|
||||
})
|
||||
}
|
||||
|
||||
async fn get_file(&self) -> Result<Self::File> {
|
||||
let event = self
|
||||
.cal_store
|
||||
.read()
|
||||
.await
|
||||
.get_event(&self.cid, &self.uid)
|
||||
.await?;
|
||||
Ok(EventFile { event })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +1,32 @@
|
||||
use actix_web::{web::Data, HttpRequest};
|
||||
use std::sync::Arc;
|
||||
|
||||
use actix_web::web::Data;
|
||||
use actix_web::HttpRequest;
|
||||
use anyhow::{anyhow, Result};
|
||||
use async_trait::async_trait;
|
||||
use rustical_auth::AuthInfo;
|
||||
use rustical_dav::error::Error;
|
||||
use rustical_dav::{resource::Resource, xml_snippets::HrefElement};
|
||||
use rustical_dav::dav_resource::{Resource, ResourceService};
|
||||
use rustical_dav::xml_snippets::HrefElement;
|
||||
use rustical_store::calendar::CalendarStore;
|
||||
use serde::Serialize;
|
||||
use std::sync::Arc;
|
||||
use strum::{EnumString, IntoStaticStr, VariantNames};
|
||||
use tokio::sync::RwLock;
|
||||
|
||||
use super::calendar::CalendarResource;
|
||||
use super::calendar::CalendarFile;
|
||||
|
||||
pub struct PrincipalCalendarsResource<C: CalendarStore + ?Sized> {
|
||||
pub struct PrincipalResource<C: CalendarStore + ?Sized> {
|
||||
prefix: String,
|
||||
principal: String,
|
||||
path: String,
|
||||
cal_store: Arc<RwLock<C>>,
|
||||
}
|
||||
|
||||
pub struct PrincipalFile {
|
||||
prefix: String,
|
||||
principal: String,
|
||||
path: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Default)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub struct Resourcetype {
|
||||
@@ -51,55 +59,10 @@ pub enum PrincipalProp {
|
||||
}
|
||||
|
||||
#[async_trait(?Send)]
|
||||
impl<C: CalendarStore + ?Sized> Resource for PrincipalCalendarsResource<C> {
|
||||
type UriComponents = ();
|
||||
type MemberType = CalendarResource<C>;
|
||||
impl Resource for PrincipalFile {
|
||||
type PropType = PrincipalProp;
|
||||
type PropResponse = PrincipalPropResponse;
|
||||
|
||||
fn get_path(&self) -> &str {
|
||||
&self.path
|
||||
}
|
||||
|
||||
async fn get_members(&self) -> Result<Vec<Self::MemberType>> {
|
||||
let calendars = self
|
||||
.cal_store
|
||||
.read()
|
||||
.await
|
||||
.get_calendars(&self.principal)
|
||||
.await?;
|
||||
let mut out = Vec::new();
|
||||
for calendar in calendars {
|
||||
let path = format!("{}/{}", &self.path, &calendar.id);
|
||||
out.push(CalendarResource {
|
||||
cal_store: self.cal_store.clone(),
|
||||
calendar,
|
||||
path,
|
||||
prefix: self.prefix.clone(),
|
||||
principal: self.principal.clone(),
|
||||
})
|
||||
}
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
async fn acquire_from_request(
|
||||
req: HttpRequest,
|
||||
auth_info: AuthInfo,
|
||||
_uri_components: Self::UriComponents,
|
||||
prefix: String,
|
||||
) -> Result<Self, Error> {
|
||||
let cal_store = req
|
||||
.app_data::<Data<RwLock<C>>>()
|
||||
.ok_or(anyhow!("no calendar store in app_data!"))?
|
||||
.clone()
|
||||
.into_inner();
|
||||
Ok(Self {
|
||||
cal_store,
|
||||
prefix,
|
||||
principal: auth_info.user_id,
|
||||
path: req.path().to_string(),
|
||||
})
|
||||
}
|
||||
fn get_prop(&self, prop: Self::PropType) -> Result<Self::PropResponse> {
|
||||
match prop {
|
||||
PrincipalProp::Resourcetype => {
|
||||
@@ -121,4 +84,65 @@ impl<C: CalendarStore + ?Sized> Resource for PrincipalCalendarsResource<C> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_path(&self) -> &str {
|
||||
&self.path
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait(?Send)]
|
||||
impl<C: CalendarStore + ?Sized> ResourceService for PrincipalResource<C> {
|
||||
type PathComponents = (String,);
|
||||
type MemberType = CalendarFile;
|
||||
type File = PrincipalFile;
|
||||
|
||||
async fn new(
|
||||
req: HttpRequest,
|
||||
auth_info: AuthInfo,
|
||||
_path_components: Self::PathComponents,
|
||||
prefix: String,
|
||||
) -> Result<Self, rustical_dav::error::Error> {
|
||||
let cal_store = req
|
||||
.app_data::<Data<RwLock<C>>>()
|
||||
.ok_or(anyhow!("no calendar store in app_data!"))?
|
||||
.clone()
|
||||
.into_inner();
|
||||
|
||||
Ok(Self {
|
||||
cal_store,
|
||||
path: req.path().to_owned(),
|
||||
principal: auth_info.user_id,
|
||||
prefix,
|
||||
})
|
||||
}
|
||||
|
||||
async fn get_file(&self) -> Result<Self::File> {
|
||||
Ok(PrincipalFile {
|
||||
principal: self.principal.to_owned(),
|
||||
prefix: self.prefix.to_owned(),
|
||||
path: self.path.to_owned(),
|
||||
})
|
||||
}
|
||||
|
||||
async fn get_members(
|
||||
&self,
|
||||
_auth_info: AuthInfo,
|
||||
_path_components: Self::PathComponents,
|
||||
) -> Result<Vec<Self::MemberType>> {
|
||||
let calendars = self
|
||||
.cal_store
|
||||
.read()
|
||||
.await
|
||||
.get_calendars(&self.principal)
|
||||
.await?;
|
||||
Ok(calendars
|
||||
.into_iter()
|
||||
.map(|cal| CalendarFile {
|
||||
calendar: cal,
|
||||
principal: self.principal.to_owned(),
|
||||
prefix: self.prefix.to_owned(),
|
||||
path: self.path.to_owned(),
|
||||
})
|
||||
.collect())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,9 @@ use actix_web::HttpRequest;
|
||||
use anyhow::Result;
|
||||
use async_trait::async_trait;
|
||||
use rustical_auth::AuthInfo;
|
||||
use rustical_dav::dav_resource::{Resource, ResourceService};
|
||||
use rustical_dav::error::Error;
|
||||
use rustical_dav::{resource::Resource, xml_snippets::HrefElement};
|
||||
use rustical_dav::xml_snippets::HrefElement;
|
||||
use serde::Serialize;
|
||||
use strum::{EnumString, IntoStaticStr, VariantNames};
|
||||
|
||||
@@ -33,34 +34,16 @@ pub enum RootPropResponse {
|
||||
CurrentUserPrincipal(HrefElement),
|
||||
}
|
||||
|
||||
#[async_trait(?Send)]
|
||||
impl Resource for RootResource {
|
||||
type UriComponents = ();
|
||||
type MemberType = Self;
|
||||
pub struct RootFile {
|
||||
pub prefix: String,
|
||||
pub principal: String,
|
||||
pub path: String,
|
||||
}
|
||||
|
||||
impl Resource for RootFile {
|
||||
type PropType = RootProp;
|
||||
type PropResponse = RootPropResponse;
|
||||
|
||||
fn get_path(&self) -> &str {
|
||||
&self.path
|
||||
}
|
||||
|
||||
async fn get_members(&self) -> Result<Vec<Self::MemberType>> {
|
||||
Ok(vec![])
|
||||
}
|
||||
|
||||
async fn acquire_from_request(
|
||||
req: HttpRequest,
|
||||
auth_info: AuthInfo,
|
||||
_uri_components: Self::UriComponents,
|
||||
prefix: String,
|
||||
) -> Result<Self, Error> {
|
||||
Ok(Self {
|
||||
prefix,
|
||||
principal: auth_info.user_id,
|
||||
path: req.path().to_string(),
|
||||
})
|
||||
}
|
||||
|
||||
fn get_prop(&self, prop: Self::PropType) -> Result<Self::PropResponse> {
|
||||
match prop {
|
||||
RootProp::Resourcetype => Ok(RootPropResponse::Resourcetype(Resourcetype::default())),
|
||||
@@ -69,4 +52,44 @@ impl Resource for RootResource {
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_path(&self) -> &str {
|
||||
&self.path
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait(?Send)]
|
||||
impl ResourceService for RootResource {
|
||||
type PathComponents = ();
|
||||
type MemberType = RootFile;
|
||||
type File = RootFile;
|
||||
|
||||
async fn get_members(
|
||||
&self,
|
||||
_auth_info: AuthInfo,
|
||||
_path_components: Self::PathComponents,
|
||||
) -> Result<Vec<Self::MemberType>> {
|
||||
Ok(vec![])
|
||||
}
|
||||
|
||||
async fn new(
|
||||
req: HttpRequest,
|
||||
auth_info: AuthInfo,
|
||||
_path_components: Self::PathComponents,
|
||||
prefix: String,
|
||||
) -> Result<Self, Error> {
|
||||
Ok(Self {
|
||||
prefix,
|
||||
principal: auth_info.user_id,
|
||||
path: req.path().to_string(),
|
||||
})
|
||||
}
|
||||
|
||||
async fn get_file(&self) -> Result<Self::File> {
|
||||
Ok(RootFile {
|
||||
path: self.path.to_owned(),
|
||||
principal: self.principal.to_owned(),
|
||||
prefix: self.prefix.to_owned(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user