mirror of
https://github.com/lennart-k/rustical.git
synced 2025-12-13 21:42:34 +00:00
dav: Make reusable for other projects
This commit is contained in:
25
Cargo.lock
generated
25
Cargo.lock
generated
@@ -3035,6 +3035,7 @@ dependencies = [
|
|||||||
"rustical_caldav",
|
"rustical_caldav",
|
||||||
"rustical_carddav",
|
"rustical_carddav",
|
||||||
"rustical_dav",
|
"rustical_dav",
|
||||||
|
"rustical_dav_push",
|
||||||
"rustical_frontend",
|
"rustical_frontend",
|
||||||
"rustical_store",
|
"rustical_store",
|
||||||
"rustical_store_sqlite",
|
"rustical_store_sqlite",
|
||||||
@@ -3063,6 +3064,7 @@ dependencies = [
|
|||||||
"futures-util",
|
"futures-util",
|
||||||
"quick-xml",
|
"quick-xml",
|
||||||
"rustical_dav",
|
"rustical_dav",
|
||||||
|
"rustical_dav_push",
|
||||||
"rustical_store",
|
"rustical_store",
|
||||||
"rustical_xml",
|
"rustical_xml",
|
||||||
"serde",
|
"serde",
|
||||||
@@ -3088,6 +3090,7 @@ dependencies = [
|
|||||||
"futures-util",
|
"futures-util",
|
||||||
"quick-xml",
|
"quick-xml",
|
||||||
"rustical_dav",
|
"rustical_dav",
|
||||||
|
"rustical_dav_push",
|
||||||
"rustical_store",
|
"rustical_store",
|
||||||
"rustical_xml",
|
"rustical_xml",
|
||||||
"serde",
|
"serde",
|
||||||
@@ -3111,6 +3114,27 @@ dependencies = [
|
|||||||
"log",
|
"log",
|
||||||
"quick-xml",
|
"quick-xml",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
|
"rustical_xml",
|
||||||
|
"serde",
|
||||||
|
"thiserror 2.0.12",
|
||||||
|
"tokio",
|
||||||
|
"tracing",
|
||||||
|
"tracing-actix-web",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustical_dav_push"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"actix-web",
|
||||||
|
"async-trait",
|
||||||
|
"derive_more 2.0.1",
|
||||||
|
"futures-util",
|
||||||
|
"itertools 0.14.0",
|
||||||
|
"log",
|
||||||
|
"quick-xml",
|
||||||
|
"reqwest",
|
||||||
|
"rustical_dav",
|
||||||
"rustical_store",
|
"rustical_store",
|
||||||
"rustical_xml",
|
"rustical_xml",
|
||||||
"serde",
|
"serde",
|
||||||
@@ -3167,6 +3191,7 @@ dependencies = [
|
|||||||
"regex",
|
"regex",
|
||||||
"rstest",
|
"rstest",
|
||||||
"rstest_reuse",
|
"rstest_reuse",
|
||||||
|
"rustical_dav",
|
||||||
"rustical_store_sqlite",
|
"rustical_store_sqlite",
|
||||||
"rustical_xml",
|
"rustical_xml",
|
||||||
"serde",
|
"serde",
|
||||||
|
|||||||
@@ -88,6 +88,7 @@ sqlx-sqlite = { version = "0.8", features = ["bundled"] }
|
|||||||
ical = { version = "0.11", features = ["generator", "serde"] }
|
ical = { version = "0.11", features = ["generator", "serde"] }
|
||||||
toml = "0.8"
|
toml = "0.8"
|
||||||
rustical_dav = { path = "./crates/dav/" }
|
rustical_dav = { path = "./crates/dav/" }
|
||||||
|
rustical_dav_push = { path = "./crates/dav_push/" }
|
||||||
rustical_store = { path = "./crates/store/" }
|
rustical_store = { path = "./crates/store/" }
|
||||||
rustical_store_sqlite = { path = "./crates/store_sqlite/" }
|
rustical_store_sqlite = { path = "./crates/store_sqlite/" }
|
||||||
rustical_caldav = { path = "./crates/caldav/" }
|
rustical_caldav = { path = "./crates/caldav/" }
|
||||||
@@ -155,4 +156,5 @@ pbkdf2.workspace = true
|
|||||||
password-hash.workspace = true
|
password-hash.workspace = true
|
||||||
reqwest.workspace = true
|
reqwest.workspace = true
|
||||||
rustical_dav.workspace = true
|
rustical_dav.workspace = true
|
||||||
|
rustical_dav_push.workspace = true
|
||||||
quick-xml.workspace = true
|
quick-xml.workspace = true
|
||||||
|
|||||||
@@ -27,3 +27,4 @@ chrono-tz = { workspace = true }
|
|||||||
sha2 = { workspace = true }
|
sha2 = { workspace = true }
|
||||||
rustical_xml.workspace = true
|
rustical_xml.workspace = true
|
||||||
uuid.workspace = true
|
uuid.workspace = true
|
||||||
|
rustical_dav_push.workspace = true
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
use crate::calendar::resource::CalendarResource;
|
|
||||||
use crate::Error;
|
use crate::Error;
|
||||||
|
use crate::calendar::resource::CalendarResource;
|
||||||
use actix_web::http::header;
|
use actix_web::http::header;
|
||||||
use actix_web::web::{Data, Path};
|
use actix_web::web::{Data, Path};
|
||||||
use actix_web::{HttpRequest, HttpResponse};
|
use actix_web::{HttpRequest, HttpResponse};
|
||||||
use rustical_dav::privileges::UserPrivilege;
|
use rustical_dav::privileges::UserPrivilege;
|
||||||
use rustical_dav::push::PushRegister;
|
|
||||||
use rustical_dav::resource::Resource;
|
use rustical_dav::resource::Resource;
|
||||||
|
use rustical_dav_push::register::PushRegister;
|
||||||
use rustical_store::auth::User;
|
use rustical_store::auth::User;
|
||||||
use rustical_store::{CalendarStore, Subscription, SubscriptionStore};
|
use rustical_store::{CalendarStore, Subscription, SubscriptionStore};
|
||||||
use rustical_xml::XmlDocument;
|
use rustical_xml::XmlDocument;
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ use super::methods::mkcalendar::route_mkcalendar;
|
|||||||
use super::methods::post::route_post;
|
use super::methods::post::route_post;
|
||||||
use super::methods::report::route_report_calendar;
|
use super::methods::report::route_report_calendar;
|
||||||
use super::prop::{SupportedCalendarComponentSet, SupportedCalendarData, SupportedReportSet};
|
use super::prop::{SupportedCalendarComponentSet, SupportedCalendarData, SupportedReportSet};
|
||||||
|
use crate::Error;
|
||||||
use crate::calendar_object::resource::CalendarObjectResource;
|
use crate::calendar_object::resource::CalendarObjectResource;
|
||||||
use crate::principal::PrincipalResource;
|
use crate::principal::PrincipalResource;
|
||||||
use crate::Error;
|
|
||||||
use actix_web::dev::ResourceMap;
|
use actix_web::dev::ResourceMap;
|
||||||
use actix_web::http::Method;
|
use actix_web::http::Method;
|
||||||
use actix_web::web;
|
use actix_web::web;
|
||||||
@@ -12,12 +12,12 @@ use async_trait::async_trait;
|
|||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use derive_more::derive::{From, Into};
|
use derive_more::derive::{From, Into};
|
||||||
use rustical_dav::extensions::{
|
use rustical_dav::extensions::{
|
||||||
CommonPropertiesExtension, CommonPropertiesProp, DavPushExtension, DavPushExtensionProp,
|
CommonPropertiesExtension, CommonPropertiesProp, SyncTokenExtension, SyncTokenExtensionProp,
|
||||||
SyncTokenExtension, SyncTokenExtensionProp,
|
|
||||||
};
|
};
|
||||||
use rustical_dav::privileges::UserPrivilegeSet;
|
use rustical_dav::privileges::UserPrivilegeSet;
|
||||||
use rustical_dav::resource::{Resource, ResourceService};
|
use rustical_dav::resource::{Resource, ResourceService};
|
||||||
use rustical_dav::xml::{HrefElement, Resourcetype, ResourcetypeInner};
|
use rustical_dav::xml::{HrefElement, Resourcetype, ResourcetypeInner};
|
||||||
|
use rustical_dav_push::{DavPushExtension, DavPushExtensionProp};
|
||||||
use rustical_store::auth::User;
|
use rustical_store::auth::User;
|
||||||
use rustical_store::calendar::CalDateTime;
|
use rustical_store::calendar::CalDateTime;
|
||||||
use rustical_store::{Calendar, CalendarStore, SubscriptionStore};
|
use rustical_store::{Calendar, CalendarStore, SubscriptionStore};
|
||||||
@@ -104,6 +104,7 @@ impl Resource for CalendarResource {
|
|||||||
type Prop = CalendarPropWrapper;
|
type Prop = CalendarPropWrapper;
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type PrincipalResource = PrincipalResource;
|
type PrincipalResource = PrincipalResource;
|
||||||
|
type Principal = User;
|
||||||
|
|
||||||
fn get_resourcetype(&self) -> Resourcetype {
|
fn get_resourcetype(&self) -> Resourcetype {
|
||||||
if self.cal.subscription_url.is_none() {
|
if self.cal.subscription_url.is_none() {
|
||||||
@@ -331,6 +332,7 @@ impl<C: CalendarStore, S: SubscriptionStore> ResourceService for CalendarResourc
|
|||||||
type PathComponents = (String, String); // principal, calendar_id
|
type PathComponents = (String, String); // principal, calendar_id
|
||||||
type Resource = CalendarResource;
|
type Resource = CalendarResource;
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
type Principal = User;
|
||||||
|
|
||||||
async fn get_resource(
|
async fn get_resource(
|
||||||
&self,
|
&self,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use super::methods::{get_event, put_event};
|
use super::methods::{get_event, put_event};
|
||||||
use crate::{principal::PrincipalResource, Error};
|
use crate::{Error, principal::PrincipalResource};
|
||||||
use actix_web::dev::ResourceMap;
|
use actix_web::dev::ResourceMap;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use derive_more::derive::{From, Into};
|
use derive_more::derive::{From, Into};
|
||||||
@@ -9,7 +9,7 @@ use rustical_dav::{
|
|||||||
resource::{Resource, ResourceService},
|
resource::{Resource, ResourceService},
|
||||||
xml::Resourcetype,
|
xml::Resourcetype,
|
||||||
};
|
};
|
||||||
use rustical_store::{auth::User, CalendarObject, CalendarStore};
|
use rustical_store::{CalendarObject, CalendarStore, auth::User};
|
||||||
use rustical_xml::{EnumUnitVariants, EnumVariants, XmlDeserialize, XmlSerialize};
|
use rustical_xml::{EnumUnitVariants, EnumVariants, XmlDeserialize, XmlSerialize};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@@ -55,6 +55,7 @@ impl Resource for CalendarObjectResource {
|
|||||||
type Prop = CalendarObjectPropWrapper;
|
type Prop = CalendarObjectPropWrapper;
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type PrincipalResource = PrincipalResource;
|
type PrincipalResource = PrincipalResource;
|
||||||
|
type Principal = User;
|
||||||
|
|
||||||
fn get_resourcetype(&self) -> Resourcetype {
|
fn get_resourcetype(&self) -> Resourcetype {
|
||||||
Resourcetype(&[])
|
Resourcetype(&[])
|
||||||
@@ -132,6 +133,7 @@ impl<C: CalendarStore> ResourceService for CalendarObjectResourceService<C> {
|
|||||||
type Resource = CalendarObjectResource;
|
type Resource = CalendarObjectResource;
|
||||||
type MemberType = CalendarObjectResource;
|
type MemberType = CalendarObjectResource;
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
type Principal = User;
|
||||||
|
|
||||||
async fn get_resource(
|
async fn get_resource(
|
||||||
&self,
|
&self,
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
|
use crate::Error;
|
||||||
use crate::calendar::resource::CalendarResource;
|
use crate::calendar::resource::CalendarResource;
|
||||||
use crate::principal::PrincipalResource;
|
use crate::principal::PrincipalResource;
|
||||||
use crate::Error;
|
|
||||||
use actix_web::dev::ResourceMap;
|
use actix_web::dev::ResourceMap;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use rustical_dav::extensions::{CommonPropertiesExtension, CommonPropertiesProp};
|
use rustical_dav::extensions::{CommonPropertiesExtension, CommonPropertiesProp};
|
||||||
use rustical_dav::privileges::UserPrivilegeSet;
|
use rustical_dav::privileges::UserPrivilegeSet;
|
||||||
use rustical_dav::resource::{Resource, ResourceService};
|
use rustical_dav::resource::{Resource, ResourceService};
|
||||||
use rustical_dav::xml::{Resourcetype, ResourcetypeInner};
|
use rustical_dav::xml::{Resourcetype, ResourcetypeInner};
|
||||||
use rustical_store::auth::User;
|
|
||||||
use rustical_store::CalendarStore;
|
use rustical_store::CalendarStore;
|
||||||
|
use rustical_store::auth::User;
|
||||||
use rustical_xml::{EnumUnitVariants, EnumVariants, XmlDeserialize, XmlSerialize};
|
use rustical_xml::{EnumUnitVariants, EnumVariants, XmlDeserialize, XmlSerialize};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
@@ -28,6 +28,7 @@ impl Resource for CalendarSetResource {
|
|||||||
type Prop = PrincipalPropWrapper;
|
type Prop = PrincipalPropWrapper;
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type PrincipalResource = PrincipalResource;
|
type PrincipalResource = PrincipalResource;
|
||||||
|
type Principal = User;
|
||||||
|
|
||||||
fn get_resourcetype(&self) -> Resourcetype {
|
fn get_resourcetype(&self) -> Resourcetype {
|
||||||
Resourcetype(&[ResourcetypeInner(
|
Resourcetype(&[ResourcetypeInner(
|
||||||
@@ -78,6 +79,7 @@ impl<C: CalendarStore> ResourceService for CalendarSetResourceService<C> {
|
|||||||
type MemberType = CalendarResource;
|
type MemberType = CalendarResource;
|
||||||
type Resource = CalendarSetResource;
|
type Resource = CalendarSetResource;
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
type Principal = User;
|
||||||
|
|
||||||
async fn get_resource(
|
async fn get_resource(
|
||||||
&self,
|
&self,
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
|
use actix_web::HttpResponse;
|
||||||
use actix_web::dev::{HttpServiceFactory, ServiceResponse};
|
use actix_web::dev::{HttpServiceFactory, ServiceResponse};
|
||||||
use actix_web::http::header::{HeaderName, HeaderValue};
|
use actix_web::http::header::{HeaderName, HeaderValue};
|
||||||
use actix_web::http::{Method, StatusCode};
|
use actix_web::http::{Method, StatusCode};
|
||||||
use actix_web::middleware::{ErrorHandlerResponse, ErrorHandlers};
|
use actix_web::middleware::{ErrorHandlerResponse, ErrorHandlers};
|
||||||
use actix_web::web::{self, Data};
|
use actix_web::web::{self, Data};
|
||||||
use actix_web::HttpResponse;
|
|
||||||
use calendar::resource::CalendarResourceService;
|
use calendar::resource::CalendarResourceService;
|
||||||
use calendar_object::resource::CalendarObjectResourceService;
|
use calendar_object::resource::CalendarObjectResourceService;
|
||||||
use calendar_set::CalendarSetResourceService;
|
use calendar_set::CalendarSetResourceService;
|
||||||
use principal::{PrincipalResource, PrincipalResourceService};
|
use principal::{PrincipalResource, PrincipalResourceService};
|
||||||
use rustical_dav::resource::{NamedRoute, ResourceService, ResourceServiceRoute};
|
use rustical_dav::resource::{NamedRoute, ResourceService, ResourceServiceRoute};
|
||||||
use rustical_dav::resources::RootResourceService;
|
use rustical_dav::resources::RootResourceService;
|
||||||
use rustical_store::auth::{AuthenticationMiddleware, AuthenticationProvider};
|
use rustical_store::auth::{AuthenticationMiddleware, AuthenticationProvider, User};
|
||||||
use rustical_store::{AddressbookStore, CalendarStore, ContactBirthdayStore, SubscriptionStore};
|
use rustical_store::{AddressbookStore, CalendarStore, ContactBirthdayStore, SubscriptionStore};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use subscription::subscription_resource;
|
use subscription::subscription_resource;
|
||||||
@@ -62,7 +62,7 @@ pub fn caldav_service<
|
|||||||
.app_data(Data::from(store.clone()))
|
.app_data(Data::from(store.clone()))
|
||||||
.app_data(Data::from(birthday_store.clone()))
|
.app_data(Data::from(birthday_store.clone()))
|
||||||
.app_data(Data::from(subscription_store))
|
.app_data(Data::from(subscription_store))
|
||||||
.service(RootResourceService::<PrincipalResource>::default().actix_resource())
|
.service(RootResourceService::<PrincipalResource, User>::default().actix_resource())
|
||||||
.service(
|
.service(
|
||||||
web::scope("/principal").service(
|
web::scope("/principal").service(
|
||||||
web::scope("/{principal}")
|
web::scope("/{principal}")
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::calendar_set::CalendarSetResource;
|
|
||||||
use crate::Error;
|
use crate::Error;
|
||||||
|
use crate::calendar_set::CalendarSetResource;
|
||||||
use actix_web::dev::ResourceMap;
|
use actix_web::dev::ResourceMap;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use rustical_dav::extensions::{CommonPropertiesExtension, CommonPropertiesProp};
|
use rustical_dav::extensions::{CommonPropertiesExtension, CommonPropertiesProp};
|
||||||
@@ -65,6 +65,7 @@ impl Resource for PrincipalResource {
|
|||||||
type Prop = PrincipalPropWrapper;
|
type Prop = PrincipalPropWrapper;
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type PrincipalResource = PrincipalResource;
|
type PrincipalResource = PrincipalResource;
|
||||||
|
type Principal = User;
|
||||||
|
|
||||||
fn get_resourcetype(&self) -> Resourcetype {
|
fn get_resourcetype(&self) -> Resourcetype {
|
||||||
Resourcetype(&[
|
Resourcetype(&[
|
||||||
@@ -142,6 +143,7 @@ impl<AP: AuthenticationProvider> ResourceService for PrincipalResourceService<AP
|
|||||||
type MemberType = CalendarSetResource;
|
type MemberType = CalendarSetResource;
|
||||||
type Resource = PrincipalResource;
|
type Resource = PrincipalResource;
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
type Principal = User;
|
||||||
|
|
||||||
async fn get_resource(
|
async fn get_resource(
|
||||||
&self,
|
&self,
|
||||||
|
|||||||
@@ -25,3 +25,4 @@ rustical_store = { workspace = true }
|
|||||||
chrono = { workspace = true }
|
chrono = { workspace = true }
|
||||||
rustical_xml.workspace = true
|
rustical_xml.workspace = true
|
||||||
uuid.workspace = true
|
uuid.workspace = true
|
||||||
|
rustical_dav_push.workspace = true
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use crate::{principal::PrincipalResource, Error};
|
use crate::{Error, principal::PrincipalResource};
|
||||||
use actix_web::dev::ResourceMap;
|
use actix_web::dev::ResourceMap;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use derive_more::derive::{Constructor, From, Into};
|
use derive_more::derive::{Constructor, From, Into};
|
||||||
@@ -8,7 +8,7 @@ use rustical_dav::{
|
|||||||
resource::{Resource, ResourceService},
|
resource::{Resource, ResourceService},
|
||||||
xml::Resourcetype,
|
xml::Resourcetype,
|
||||||
};
|
};
|
||||||
use rustical_store::{auth::User, AddressObject, AddressbookStore};
|
use rustical_store::{AddressObject, AddressbookStore, auth::User};
|
||||||
use rustical_xml::{EnumUnitVariants, EnumVariants, XmlDeserialize, XmlSerialize};
|
use rustical_xml::{EnumUnitVariants, EnumVariants, XmlDeserialize, XmlSerialize};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@@ -51,6 +51,7 @@ impl Resource for AddressObjectResource {
|
|||||||
type Prop = AddressObjectPropWrapper;
|
type Prop = AddressObjectPropWrapper;
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type PrincipalResource = PrincipalResource;
|
type PrincipalResource = PrincipalResource;
|
||||||
|
type Principal = User;
|
||||||
|
|
||||||
fn get_resourcetype(&self) -> Resourcetype {
|
fn get_resourcetype(&self) -> Resourcetype {
|
||||||
Resourcetype(&[])
|
Resourcetype(&[])
|
||||||
@@ -128,6 +129,7 @@ impl<AS: AddressbookStore> ResourceService for AddressObjectResourceService<AS>
|
|||||||
type Resource = AddressObjectResource;
|
type Resource = AddressObjectResource;
|
||||||
type MemberType = AddressObjectResource;
|
type MemberType = AddressObjectResource;
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
type Principal = User;
|
||||||
|
|
||||||
async fn get_resource(
|
async fn get_resource(
|
||||||
&self,
|
&self,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use crate::Error;
|
|||||||
use actix_web::http::header;
|
use actix_web::http::header;
|
||||||
use actix_web::web::{Data, Path};
|
use actix_web::web::{Data, Path};
|
||||||
use actix_web::{HttpRequest, HttpResponse};
|
use actix_web::{HttpRequest, HttpResponse};
|
||||||
use rustical_dav::push::PushRegister;
|
use rustical_dav_push::register::PushRegister;
|
||||||
use rustical_store::auth::User;
|
use rustical_store::auth::User;
|
||||||
use rustical_store::{AddressbookStore, Subscription, SubscriptionStore};
|
use rustical_store::{AddressbookStore, Subscription, SubscriptionStore};
|
||||||
use rustical_xml::XmlDocument;
|
use rustical_xml::XmlDocument;
|
||||||
|
|||||||
@@ -2,21 +2,21 @@ use super::methods::mkcol::route_mkcol;
|
|||||||
use super::methods::post::route_post;
|
use super::methods::post::route_post;
|
||||||
use super::methods::report::route_report_addressbook;
|
use super::methods::report::route_report_addressbook;
|
||||||
use super::prop::{SupportedAddressData, SupportedReportSet};
|
use super::prop::{SupportedAddressData, SupportedReportSet};
|
||||||
|
use crate::Error;
|
||||||
use crate::address_object::resource::AddressObjectResource;
|
use crate::address_object::resource::AddressObjectResource;
|
||||||
use crate::principal::PrincipalResource;
|
use crate::principal::PrincipalResource;
|
||||||
use crate::Error;
|
|
||||||
use actix_web::dev::ResourceMap;
|
use actix_web::dev::ResourceMap;
|
||||||
use actix_web::http::Method;
|
use actix_web::http::Method;
|
||||||
use actix_web::web;
|
use actix_web::web;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use derive_more::derive::{From, Into};
|
use derive_more::derive::{From, Into};
|
||||||
use rustical_dav::extensions::{
|
use rustical_dav::extensions::{
|
||||||
CommonPropertiesExtension, CommonPropertiesProp, DavPushExtension, DavPushExtensionProp,
|
CommonPropertiesExtension, CommonPropertiesProp, SyncTokenExtension, SyncTokenExtensionProp,
|
||||||
SyncTokenExtension, SyncTokenExtensionProp,
|
|
||||||
};
|
};
|
||||||
use rustical_dav::privileges::UserPrivilegeSet;
|
use rustical_dav::privileges::UserPrivilegeSet;
|
||||||
use rustical_dav::resource::{Resource, ResourceService};
|
use rustical_dav::resource::{Resource, ResourceService};
|
||||||
use rustical_dav::xml::{Resourcetype, ResourcetypeInner};
|
use rustical_dav::xml::{Resourcetype, ResourcetypeInner};
|
||||||
|
use rustical_dav_push::{DavPushExtension, DavPushExtensionProp};
|
||||||
use rustical_store::auth::User;
|
use rustical_store::auth::User;
|
||||||
use rustical_store::{Addressbook, AddressbookStore, SubscriptionStore};
|
use rustical_store::{Addressbook, AddressbookStore, SubscriptionStore};
|
||||||
use rustical_xml::{EnumUnitVariants, EnumVariants, XmlDeserialize, XmlSerialize};
|
use rustical_xml::{EnumUnitVariants, EnumVariants, XmlDeserialize, XmlSerialize};
|
||||||
@@ -84,6 +84,7 @@ impl Resource for AddressbookResource {
|
|||||||
type Prop = AddressbookPropWrapper;
|
type Prop = AddressbookPropWrapper;
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type PrincipalResource = PrincipalResource;
|
type PrincipalResource = PrincipalResource;
|
||||||
|
type Principal = User;
|
||||||
|
|
||||||
fn get_resourcetype(&self) -> Resourcetype {
|
fn get_resourcetype(&self) -> Resourcetype {
|
||||||
Resourcetype(&[
|
Resourcetype(&[
|
||||||
@@ -199,6 +200,7 @@ impl<AS: AddressbookStore, S: SubscriptionStore> ResourceService
|
|||||||
type PathComponents = (String, String); // principal, addressbook_id
|
type PathComponents = (String, String); // principal, addressbook_id
|
||||||
type Resource = AddressbookResource;
|
type Resource = AddressbookResource;
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
type Principal = User;
|
||||||
|
|
||||||
async fn get_resource(
|
async fn get_resource(
|
||||||
&self,
|
&self,
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
use actix_web::{
|
use actix_web::{
|
||||||
|
HttpResponse,
|
||||||
dev::{HttpServiceFactory, ServiceResponse},
|
dev::{HttpServiceFactory, ServiceResponse},
|
||||||
http::{
|
http::{
|
||||||
header::{HeaderName, HeaderValue},
|
|
||||||
Method, StatusCode,
|
Method, StatusCode,
|
||||||
|
header::{HeaderName, HeaderValue},
|
||||||
},
|
},
|
||||||
middleware::{ErrorHandlerResponse, ErrorHandlers},
|
middleware::{ErrorHandlerResponse, ErrorHandlers},
|
||||||
web::{self, Data},
|
web::{self, Data},
|
||||||
HttpResponse,
|
|
||||||
};
|
};
|
||||||
use address_object::resource::AddressObjectResourceService;
|
use address_object::resource::AddressObjectResourceService;
|
||||||
use addressbook::resource::AddressbookResourceService;
|
use addressbook::resource::AddressbookResourceService;
|
||||||
@@ -15,8 +15,8 @@ use principal::{PrincipalResource, PrincipalResourceService};
|
|||||||
use rustical_dav::resource::{NamedRoute, ResourceService};
|
use rustical_dav::resource::{NamedRoute, ResourceService};
|
||||||
use rustical_dav::resources::RootResourceService;
|
use rustical_dav::resources::RootResourceService;
|
||||||
use rustical_store::{
|
use rustical_store::{
|
||||||
auth::{AuthenticationMiddleware, AuthenticationProvider},
|
|
||||||
AddressbookStore, SubscriptionStore,
|
AddressbookStore, SubscriptionStore,
|
||||||
|
auth::{AuthenticationMiddleware, AuthenticationProvider, User},
|
||||||
};
|
};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ pub fn carddav_service<AP: AuthenticationProvider, A: AddressbookStore, S: Subsc
|
|||||||
)
|
)
|
||||||
.app_data(Data::from(store.clone()))
|
.app_data(Data::from(store.clone()))
|
||||||
.app_data(Data::from(subscription_store))
|
.app_data(Data::from(subscription_store))
|
||||||
.service(RootResourceService::<PrincipalResource>::default().actix_resource())
|
.service(RootResourceService::<PrincipalResource, User>::default().actix_resource())
|
||||||
.service(
|
.service(
|
||||||
web::scope("/principal").service(
|
web::scope("/principal").service(
|
||||||
web::scope("/{principal}")
|
web::scope("/{principal}")
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
use crate::addressbook::resource::AddressbookResource;
|
|
||||||
use crate::Error;
|
use crate::Error;
|
||||||
|
use crate::addressbook::resource::AddressbookResource;
|
||||||
use actix_web::dev::ResourceMap;
|
use actix_web::dev::ResourceMap;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use rustical_dav::extensions::{CommonPropertiesExtension, CommonPropertiesProp};
|
use rustical_dav::extensions::{CommonPropertiesExtension, CommonPropertiesProp};
|
||||||
use rustical_dav::privileges::UserPrivilegeSet;
|
use rustical_dav::privileges::UserPrivilegeSet;
|
||||||
use rustical_dav::resource::{NamedRoute, Resource, ResourceService};
|
use rustical_dav::resource::{NamedRoute, Resource, ResourceService};
|
||||||
use rustical_dav::xml::{HrefElement, Resourcetype, ResourcetypeInner};
|
use rustical_dav::xml::{HrefElement, Resourcetype, ResourcetypeInner};
|
||||||
use rustical_store::auth::{AuthenticationProvider, User};
|
|
||||||
use rustical_store::AddressbookStore;
|
use rustical_store::AddressbookStore;
|
||||||
|
use rustical_store::auth::{AuthenticationProvider, User};
|
||||||
use rustical_xml::{EnumUnitVariants, EnumVariants, XmlDeserialize, XmlSerialize};
|
use rustical_xml::{EnumUnitVariants, EnumVariants, XmlDeserialize, XmlSerialize};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
@@ -74,6 +74,7 @@ impl Resource for PrincipalResource {
|
|||||||
type Prop = PrincipalPropWrapper;
|
type Prop = PrincipalPropWrapper;
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type PrincipalResource = PrincipalResource;
|
type PrincipalResource = PrincipalResource;
|
||||||
|
type Principal = User;
|
||||||
|
|
||||||
fn get_resourcetype(&self) -> Resourcetype {
|
fn get_resourcetype(&self) -> Resourcetype {
|
||||||
Resourcetype(&[
|
Resourcetype(&[
|
||||||
@@ -140,6 +141,7 @@ impl<A: AddressbookStore, AP: AuthenticationProvider> ResourceService
|
|||||||
type MemberType = AddressbookResource;
|
type MemberType = AddressbookResource;
|
||||||
type Resource = PrincipalResource;
|
type Resource = PrincipalResource;
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
type Principal = User;
|
||||||
|
|
||||||
async fn get_resource(
|
async fn get_resource(
|
||||||
&self,
|
&self,
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ actix-web = { workspace = true }
|
|||||||
async-trait = { workspace = true }
|
async-trait = { workspace = true }
|
||||||
futures-util = { workspace = true }
|
futures-util = { workspace = true }
|
||||||
quick-xml = { workspace = true }
|
quick-xml = { workspace = true }
|
||||||
rustical_store = { workspace = true }
|
|
||||||
serde = { workspace = true }
|
serde = { workspace = true }
|
||||||
thiserror = { workspace = true }
|
thiserror = { workspace = true }
|
||||||
itertools = { workspace = true }
|
itertools = { workspace = true }
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
|
Principal,
|
||||||
privileges::UserPrivilegeSet,
|
privileges::UserPrivilegeSet,
|
||||||
resource::{NamedRoute, Resource},
|
resource::{NamedRoute, Resource},
|
||||||
xml::{HrefElement, Resourcetype},
|
xml::{HrefElement, Resourcetype},
|
||||||
};
|
};
|
||||||
use actix_web::dev::ResourceMap;
|
use actix_web::dev::ResourceMap;
|
||||||
use rustical_store::auth::User;
|
|
||||||
use rustical_xml::{EnumUnitVariants, EnumVariants, XmlDeserialize, XmlSerialize};
|
use rustical_xml::{EnumUnitVariants, EnumVariants, XmlDeserialize, XmlSerialize};
|
||||||
|
|
||||||
#[derive(XmlDeserialize, XmlSerialize, PartialEq, Clone, EnumUnitVariants, EnumVariants)]
|
#[derive(XmlDeserialize, XmlSerialize, PartialEq, Clone, EnumUnitVariants, EnumVariants)]
|
||||||
@@ -31,7 +31,7 @@ pub trait CommonPropertiesExtension: Resource {
|
|||||||
fn get_prop(
|
fn get_prop(
|
||||||
&self,
|
&self,
|
||||||
rmap: &ResourceMap,
|
rmap: &ResourceMap,
|
||||||
user: &User,
|
principal: &Self::Principal,
|
||||||
prop: &CommonPropertiesPropName,
|
prop: &CommonPropertiesPropName,
|
||||||
) -> Result<CommonPropertiesProp, <Self as Resource>::Error> {
|
) -> Result<CommonPropertiesProp, <Self as Resource>::Error> {
|
||||||
Ok(match prop {
|
Ok(match prop {
|
||||||
@@ -40,13 +40,13 @@ pub trait CommonPropertiesExtension: Resource {
|
|||||||
}
|
}
|
||||||
CommonPropertiesPropName::CurrentUserPrincipal => {
|
CommonPropertiesPropName::CurrentUserPrincipal => {
|
||||||
CommonPropertiesProp::CurrentUserPrincipal(
|
CommonPropertiesProp::CurrentUserPrincipal(
|
||||||
Self::PrincipalResource::get_url(rmap, [&user.id])
|
Self::PrincipalResource::get_url(rmap, [&principal.get_id()])
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into(),
|
.into(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
CommonPropertiesPropName::CurrentUserPrivilegeSet => {
|
CommonPropertiesPropName::CurrentUserPrivilegeSet => {
|
||||||
CommonPropertiesProp::CurrentUserPrivilegeSet(self.get_user_privileges(user)?)
|
CommonPropertiesProp::CurrentUserPrivilegeSet(self.get_user_privileges(principal)?)
|
||||||
}
|
}
|
||||||
CommonPropertiesPropName::Owner => {
|
CommonPropertiesPropName::Owner => {
|
||||||
CommonPropertiesProp::Owner(self.get_owner().map(|owner| {
|
CommonPropertiesProp::Owner(self.get_owner().map(|owner| {
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
mod common;
|
mod common;
|
||||||
mod davpush;
|
|
||||||
mod synctoken;
|
mod synctoken;
|
||||||
|
|
||||||
pub use common::*;
|
pub use common::*;
|
||||||
pub use davpush::*;
|
|
||||||
pub use synctoken::*;
|
pub use synctoken::*;
|
||||||
|
|||||||
@@ -3,9 +3,13 @@ pub mod error;
|
|||||||
pub mod extensions;
|
pub mod extensions;
|
||||||
pub mod namespace;
|
pub mod namespace;
|
||||||
pub mod privileges;
|
pub mod privileges;
|
||||||
pub mod push;
|
|
||||||
pub mod resource;
|
pub mod resource;
|
||||||
pub mod resources;
|
pub mod resources;
|
||||||
pub mod xml;
|
pub mod xml;
|
||||||
|
|
||||||
|
use actix_web::FromRequest;
|
||||||
pub use error::Error;
|
pub use error::Error;
|
||||||
|
|
||||||
|
pub trait Principal: std::fmt::Debug + Clone + FromRequest + 'static {
|
||||||
|
fn get_id(&self) -> &str;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
mod prop;
|
|
||||||
mod push_notifier;
|
|
||||||
mod push_register;
|
|
||||||
|
|
||||||
pub use prop::*;
|
|
||||||
pub use push_notifier::push_notifier;
|
|
||||||
pub use push_register::*;
|
|
||||||
@@ -1,16 +1,15 @@
|
|||||||
|
use crate::Error;
|
||||||
use crate::privileges::UserPrivilege;
|
use crate::privileges::UserPrivilege;
|
||||||
use crate::resource::Resource;
|
use crate::resource::Resource;
|
||||||
use crate::resource::ResourceService;
|
use crate::resource::ResourceService;
|
||||||
use crate::Error;
|
use actix_web::HttpRequest;
|
||||||
|
use actix_web::HttpResponse;
|
||||||
|
use actix_web::Responder;
|
||||||
use actix_web::http::header::IfMatch;
|
use actix_web::http::header::IfMatch;
|
||||||
use actix_web::http::header::IfNoneMatch;
|
use actix_web::http::header::IfNoneMatch;
|
||||||
use actix_web::web;
|
use actix_web::web;
|
||||||
use actix_web::web::Data;
|
use actix_web::web::Data;
|
||||||
use actix_web::web::Path;
|
use actix_web::web::Path;
|
||||||
use actix_web::HttpRequest;
|
|
||||||
use actix_web::HttpResponse;
|
|
||||||
use actix_web::Responder;
|
|
||||||
use rustical_store::auth::User;
|
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
use tracing_actix_web::RootSpan;
|
use tracing_actix_web::RootSpan;
|
||||||
|
|
||||||
@@ -18,7 +17,7 @@ use tracing_actix_web::RootSpan;
|
|||||||
pub async fn route_delete<R: ResourceService>(
|
pub async fn route_delete<R: ResourceService>(
|
||||||
path: Path<R::PathComponents>,
|
path: Path<R::PathComponents>,
|
||||||
req: HttpRequest,
|
req: HttpRequest,
|
||||||
user: User,
|
principal: R::Principal,
|
||||||
resource_service: Data<R>,
|
resource_service: Data<R>,
|
||||||
root_span: RootSpan,
|
root_span: RootSpan,
|
||||||
if_match: web::Header<IfMatch>,
|
if_match: web::Header<IfMatch>,
|
||||||
@@ -32,7 +31,7 @@ pub async fn route_delete<R: ResourceService>(
|
|||||||
|
|
||||||
let resource = resource_service.get_resource(&path).await?;
|
let resource = resource_service.get_resource(&path).await?;
|
||||||
|
|
||||||
let privileges = resource.get_user_privileges(&user)?;
|
let privileges = resource.get_user_privileges(&principal)?;
|
||||||
if !privileges.has(&UserPrivilege::Write) {
|
if !privileges.has(&UserPrivilege::Write) {
|
||||||
return Err(Error::Unauthorized.into());
|
return Err(Error::Unauthorized.into());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use crate::Error;
|
||||||
use crate::depth_header::Depth;
|
use crate::depth_header::Depth;
|
||||||
use crate::privileges::UserPrivilege;
|
use crate::privileges::UserPrivilege;
|
||||||
use crate::resource::Resource;
|
use crate::resource::Resource;
|
||||||
@@ -6,11 +7,9 @@ use crate::xml::MultistatusElement;
|
|||||||
use crate::xml::PropElement;
|
use crate::xml::PropElement;
|
||||||
use crate::xml::PropfindElement;
|
use crate::xml::PropfindElement;
|
||||||
use crate::xml::PropfindType;
|
use crate::xml::PropfindType;
|
||||||
use crate::Error;
|
use actix_web::HttpRequest;
|
||||||
use actix_web::web::Data;
|
use actix_web::web::Data;
|
||||||
use actix_web::web::Path;
|
use actix_web::web::Path;
|
||||||
use actix_web::HttpRequest;
|
|
||||||
use rustical_store::auth::User;
|
|
||||||
use rustical_xml::XmlDocument;
|
use rustical_xml::XmlDocument;
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
use tracing_actix_web::RootSpan;
|
use tracing_actix_web::RootSpan;
|
||||||
@@ -21,7 +20,7 @@ pub(crate) async fn route_propfind<R: ResourceService>(
|
|||||||
path: Path<R::PathComponents>,
|
path: Path<R::PathComponents>,
|
||||||
body: String,
|
body: String,
|
||||||
req: HttpRequest,
|
req: HttpRequest,
|
||||||
user: User,
|
user: R::Principal,
|
||||||
depth: Depth,
|
depth: Depth,
|
||||||
root_span: RootSpan,
|
root_span: RootSpan,
|
||||||
resource_service: Data<R>,
|
resource_service: Data<R>,
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
|
use crate::Error;
|
||||||
use crate::privileges::UserPrivilege;
|
use crate::privileges::UserPrivilege;
|
||||||
use crate::resource::Resource;
|
use crate::resource::Resource;
|
||||||
use crate::resource::ResourceService;
|
use crate::resource::ResourceService;
|
||||||
use crate::xml::multistatus::{PropstatElement, PropstatWrapper, ResponseElement};
|
|
||||||
use crate::xml::MultistatusElement;
|
use crate::xml::MultistatusElement;
|
||||||
use crate::xml::TagList;
|
use crate::xml::TagList;
|
||||||
use crate::Error;
|
use crate::xml::multistatus::{PropstatElement, PropstatWrapper, ResponseElement};
|
||||||
use actix_web::http::StatusCode;
|
use actix_web::http::StatusCode;
|
||||||
use actix_web::web::Data;
|
use actix_web::web::Data;
|
||||||
use actix_web::{web::Path, HttpRequest};
|
use actix_web::{HttpRequest, web::Path};
|
||||||
use quick_xml::name::Namespace;
|
use quick_xml::name::Namespace;
|
||||||
use rustical_store::auth::User;
|
|
||||||
use rustical_xml::EnumUnitVariants;
|
use rustical_xml::EnumUnitVariants;
|
||||||
use rustical_xml::Unparsed;
|
use rustical_xml::Unparsed;
|
||||||
use rustical_xml::XmlDeserialize;
|
use rustical_xml::XmlDeserialize;
|
||||||
@@ -69,7 +68,7 @@ pub(crate) async fn route_proppatch<R: ResourceService>(
|
|||||||
path: Path<R::PathComponents>,
|
path: Path<R::PathComponents>,
|
||||||
body: String,
|
body: String,
|
||||||
req: HttpRequest,
|
req: HttpRequest,
|
||||||
user: User,
|
principal: R::Principal,
|
||||||
root_span: RootSpan,
|
root_span: RootSpan,
|
||||||
resource_service: Data<R>,
|
resource_service: Data<R>,
|
||||||
) -> Result<MultistatusElement<String, String>, R::Error> {
|
) -> Result<MultistatusElement<String, String>, R::Error> {
|
||||||
@@ -81,7 +80,7 @@ pub(crate) async fn route_proppatch<R: ResourceService>(
|
|||||||
) = XmlDocument::parse_str(&body).map_err(Error::XmlError)?;
|
) = XmlDocument::parse_str(&body).map_err(Error::XmlError)?;
|
||||||
|
|
||||||
let mut resource = resource_service.get_resource(&path).await?;
|
let mut resource = resource_service.get_resource(&path).await?;
|
||||||
let privileges = resource.get_user_privileges(&user)?;
|
let privileges = resource.get_user_privileges(&principal)?;
|
||||||
if !privileges.has(&UserPrivilege::Write) {
|
if !privileges.has(&UserPrivilege::Write) {
|
||||||
return Err(Error::Unauthorized.into());
|
return Err(Error::Unauthorized.into());
|
||||||
}
|
}
|
||||||
@@ -131,7 +130,7 @@ pub(crate) async fn route_proppatch<R: ResourceService>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Operation::Remove(remove_el) => {
|
Operation::Remove(remove_el) => {
|
||||||
let propname = remove_el.prop.0 .0;
|
let propname = remove_el.prop.0.0;
|
||||||
match <<R::Resource as Resource>::Prop as EnumUnitVariants>::UnitVariants::from_str(
|
match <<R::Resource as Resource>::Prop as EnumUnitVariants>::UnitVariants::from_str(
|
||||||
&propname,
|
&propname,
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
use crate::privileges::UserPrivilegeSet;
|
use crate::privileges::UserPrivilegeSet;
|
||||||
use crate::xml::multistatus::{PropTagWrapper, PropstatElement, PropstatWrapper};
|
|
||||||
use crate::xml::Resourcetype;
|
use crate::xml::Resourcetype;
|
||||||
use crate::xml::{multistatus::ResponseElement, TagList};
|
use crate::xml::multistatus::{PropTagWrapper, PropstatElement, PropstatWrapper};
|
||||||
use crate::Error;
|
use crate::xml::{TagList, multistatus::ResponseElement};
|
||||||
|
use crate::{Error, Principal};
|
||||||
use actix_web::dev::ResourceMap;
|
use actix_web::dev::ResourceMap;
|
||||||
use actix_web::http::header::{EntityTag, IfMatch, IfNoneMatch};
|
use actix_web::http::header::{EntityTag, IfMatch, IfNoneMatch};
|
||||||
use actix_web::{http::StatusCode, ResponseError};
|
use actix_web::{ResponseError, http::StatusCode};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use quick_xml::name::Namespace;
|
use quick_xml::name::Namespace;
|
||||||
pub use resource_service::ResourceService;
|
pub use resource_service::ResourceService;
|
||||||
use rustical_store::auth::User;
|
|
||||||
use rustical_xml::{EnumUnitVariants, EnumVariants, XmlDeserialize, XmlSerialize};
|
use rustical_xml::{EnumUnitVariants, EnumVariants, XmlDeserialize, XmlSerialize};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
@@ -28,6 +27,7 @@ pub trait Resource: Clone + 'static {
|
|||||||
type Prop: ResourceProp + PartialEq + Clone + EnumVariants + EnumUnitVariants;
|
type Prop: ResourceProp + PartialEq + Clone + EnumVariants + EnumUnitVariants;
|
||||||
type Error: ResponseError + From<crate::Error>;
|
type Error: ResponseError + From<crate::Error>;
|
||||||
type PrincipalResource: Resource + NamedRoute;
|
type PrincipalResource: Resource + NamedRoute;
|
||||||
|
type Principal: Principal;
|
||||||
|
|
||||||
fn get_resourcetype(&self) -> Resourcetype;
|
fn get_resourcetype(&self) -> Resourcetype;
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ pub trait Resource: Clone + 'static {
|
|||||||
fn get_prop(
|
fn get_prop(
|
||||||
&self,
|
&self,
|
||||||
rmap: &ResourceMap,
|
rmap: &ResourceMap,
|
||||||
user: &User,
|
principal: &Self::Principal,
|
||||||
prop: &<Self::Prop as EnumUnitVariants>::UnitVariants,
|
prop: &<Self::Prop as EnumUnitVariants>::UnitVariants,
|
||||||
) -> Result<Self::Prop, Self::Error>;
|
) -> Result<Self::Prop, Self::Error>;
|
||||||
|
|
||||||
@@ -93,13 +93,16 @@ pub trait Resource: Clone + 'static {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_user_privileges(&self, user: &User) -> Result<UserPrivilegeSet, Self::Error>;
|
fn get_user_privileges(
|
||||||
|
&self,
|
||||||
|
principal: &Self::Principal,
|
||||||
|
) -> Result<UserPrivilegeSet, Self::Error>;
|
||||||
|
|
||||||
fn propfind(
|
fn propfind(
|
||||||
&self,
|
&self,
|
||||||
path: &str,
|
path: &str,
|
||||||
props: &[&str],
|
props: &[&str],
|
||||||
user: &User,
|
principal: &Self::Principal,
|
||||||
rmap: &ResourceMap,
|
rmap: &ResourceMap,
|
||||||
) -> Result<ResponseElement<Self::Prop>, Self::Error> {
|
) -> Result<ResponseElement<Self::Prop>, Self::Error> {
|
||||||
let mut props = props.to_vec();
|
let mut props = props.to_vec();
|
||||||
@@ -152,7 +155,7 @@ pub trait Resource: Clone + 'static {
|
|||||||
|
|
||||||
let prop_responses = valid_props
|
let prop_responses = valid_props
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|prop| self.get_prop(rmap, user, &prop))
|
.map(|prop| self.get_prop(rmap, principal, &prop))
|
||||||
.collect::<Result<Vec<_>, Self::Error>>()?;
|
.collect::<Result<Vec<_>, Self::Error>>()?;
|
||||||
|
|
||||||
let mut propstats = vec![PropstatWrapper::Normal(PropstatElement {
|
let mut propstats = vec![PropstatWrapper::Normal(PropstatElement {
|
||||||
|
|||||||
@@ -2,20 +2,23 @@ use actix_web::dev::{AppService, HttpServiceFactory};
|
|||||||
use actix_web::error::UrlGenerationError;
|
use actix_web::error::UrlGenerationError;
|
||||||
use actix_web::test::TestRequest;
|
use actix_web::test::TestRequest;
|
||||||
use actix_web::web::Data;
|
use actix_web::web::Data;
|
||||||
use actix_web::{dev::ResourceMap, http::Method, web, ResponseError};
|
use actix_web::{ResponseError, dev::ResourceMap, http::Method, web};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use super::methods::{route_delete, route_propfind, route_proppatch};
|
use crate::Principal;
|
||||||
|
|
||||||
use super::Resource;
|
use super::Resource;
|
||||||
|
use super::methods::{route_delete, route_propfind, route_proppatch};
|
||||||
|
|
||||||
#[async_trait(?Send)]
|
#[async_trait(?Send)]
|
||||||
pub trait ResourceService: Sized + 'static {
|
pub trait ResourceService: Sized + 'static {
|
||||||
type MemberType: Resource<Error = Self::Error>;
|
type MemberType: Resource<Error = Self::Error, Principal = Self::Principal>;
|
||||||
type PathComponents: for<'de> Deserialize<'de> + Sized + Clone + 'static; // defines how the resource URI maps to parameters, i.e. /{principal}/{calendar} -> (String, String)
|
type PathComponents: for<'de> Deserialize<'de> + Sized + Clone + 'static; // defines how the resource URI maps to parameters, i.e. /{principal}/{calendar} -> (String, String)
|
||||||
type Resource: Resource<Error = Self::Error>;
|
type Resource: Resource<Error = Self::Error, Principal = Self::Principal>;
|
||||||
type Error: ResponseError + From<crate::Error>;
|
type Error: ResponseError + From<crate::Error>;
|
||||||
|
type Principal: Principal;
|
||||||
|
|
||||||
async fn get_members(
|
async fn get_members(
|
||||||
&self,
|
&self,
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use crate::Principal;
|
||||||
use crate::extensions::{
|
use crate::extensions::{
|
||||||
CommonPropertiesExtension, CommonPropertiesProp, CommonPropertiesPropName,
|
CommonPropertiesExtension, CommonPropertiesProp, CommonPropertiesPropName,
|
||||||
};
|
};
|
||||||
@@ -6,22 +7,22 @@ use crate::resource::{NamedRoute, Resource, ResourceService};
|
|||||||
use crate::xml::{Resourcetype, ResourcetypeInner};
|
use crate::xml::{Resourcetype, ResourcetypeInner};
|
||||||
use actix_web::dev::ResourceMap;
|
use actix_web::dev::ResourceMap;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use rustical_store::auth::User;
|
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct RootResource<PR: Resource>(PhantomData<PR>);
|
pub struct RootResource<PR: Resource, P: Principal>(PhantomData<PR>, PhantomData<P>);
|
||||||
|
|
||||||
impl<PR: Resource> Default for RootResource<PR> {
|
impl<PR: Resource, P: Principal> Default for RootResource<PR, P> {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self(Default::default())
|
Self(PhantomData, PhantomData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<PR: Resource + NamedRoute> Resource for RootResource<PR> {
|
impl<PR: Resource + NamedRoute, P: Principal> Resource for RootResource<PR, P> {
|
||||||
type Prop = CommonPropertiesProp;
|
type Prop = CommonPropertiesProp;
|
||||||
type Error = PR::Error;
|
type Error = PR::Error;
|
||||||
type PrincipalResource = PR;
|
type PrincipalResource = PR;
|
||||||
|
type Principal = P;
|
||||||
|
|
||||||
fn get_resourcetype(&self) -> Resourcetype {
|
fn get_resourcetype(&self) -> Resourcetype {
|
||||||
Resourcetype(&[ResourcetypeInner(
|
Resourcetype(&[ResourcetypeInner(
|
||||||
@@ -33,34 +34,37 @@ impl<PR: Resource + NamedRoute> Resource for RootResource<PR> {
|
|||||||
fn get_prop(
|
fn get_prop(
|
||||||
&self,
|
&self,
|
||||||
rmap: &ResourceMap,
|
rmap: &ResourceMap,
|
||||||
user: &User,
|
user: &P,
|
||||||
prop: &CommonPropertiesPropName,
|
prop: &CommonPropertiesPropName,
|
||||||
) -> Result<Self::Prop, Self::Error> {
|
) -> Result<Self::Prop, Self::Error> {
|
||||||
CommonPropertiesExtension::get_prop(self, rmap, user, prop)
|
CommonPropertiesExtension::get_prop(self, rmap, user, prop)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_user_privileges(&self, _user: &User) -> Result<UserPrivilegeSet, Self::Error> {
|
fn get_user_privileges(&self, _user: &P) -> Result<UserPrivilegeSet, Self::Error> {
|
||||||
Ok(UserPrivilegeSet::all())
|
Ok(UserPrivilegeSet::all())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct RootResourceService<PR: Resource>(PhantomData<PR>);
|
pub struct RootResourceService<PR: Resource, P: Principal>(PhantomData<PR>, PhantomData<P>);
|
||||||
|
|
||||||
impl<PR: Resource> Default for RootResourceService<PR> {
|
impl<PR: Resource, P: Principal> Default for RootResourceService<PR, P> {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self(PhantomData)
|
Self(PhantomData, PhantomData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait(?Send)]
|
#[async_trait(?Send)]
|
||||||
impl<PR: Resource + NamedRoute> ResourceService for RootResourceService<PR> {
|
impl<PR: Resource<Principal = P> + NamedRoute, P: Principal> ResourceService
|
||||||
|
for RootResourceService<PR, P>
|
||||||
|
{
|
||||||
type PathComponents = ();
|
type PathComponents = ();
|
||||||
type MemberType = PR;
|
type MemberType = PR;
|
||||||
type Resource = RootResource<PR>;
|
type Resource = RootResource<PR, P>;
|
||||||
type Error = PR::Error;
|
type Error = PR::Error;
|
||||||
|
type Principal = P;
|
||||||
|
|
||||||
async fn get_resource(&self, _: &()) -> Result<Self::Resource, Self::Error> {
|
async fn get_resource(&self, _: &()) -> Result<Self::Resource, Self::Error> {
|
||||||
Ok(RootResource::<PR>::default())
|
Ok(RootResource::<PR, P>::default())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
25
crates/dav_push/Cargo.toml
Normal file
25
crates/dav_push/Cargo.toml
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
[package]
|
||||||
|
name = "rustical_dav_push"
|
||||||
|
version.workspace = true
|
||||||
|
edition.workspace = true
|
||||||
|
description.workspace = true
|
||||||
|
repository.workspace = true
|
||||||
|
publish = false
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
rustical_xml.workspace = true
|
||||||
|
actix-web = { workspace = true }
|
||||||
|
async-trait = { workspace = true }
|
||||||
|
futures-util = { workspace = true }
|
||||||
|
quick-xml = { workspace = true }
|
||||||
|
serde = { workspace = true }
|
||||||
|
thiserror = { workspace = true }
|
||||||
|
itertools = { workspace = true }
|
||||||
|
log = { workspace = true }
|
||||||
|
derive_more = { workspace = true }
|
||||||
|
tracing = { workspace = true }
|
||||||
|
tracing-actix-web = { workspace = true }
|
||||||
|
reqwest.workspace = true
|
||||||
|
tokio.workspace = true
|
||||||
|
rustical_dav.workspace = true
|
||||||
|
rustical_store.workspace = true
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
use crate::push::Transports;
|
use crate::Transports;
|
||||||
use rustical_xml::{EnumUnitVariants, EnumVariants, XmlDeserialize, XmlSerialize};
|
use rustical_xml::{EnumUnitVariants, EnumVariants, XmlDeserialize, XmlSerialize};
|
||||||
|
|
||||||
#[derive(XmlDeserialize, XmlSerialize, PartialEq, Clone, EnumUnitVariants, EnumVariants)]
|
#[derive(XmlDeserialize, XmlSerialize, PartialEq, Clone, EnumUnitVariants, EnumVariants)]
|
||||||
@@ -6,9 +6,9 @@ use rustical_xml::{EnumUnitVariants, EnumVariants, XmlDeserialize, XmlSerialize}
|
|||||||
pub enum DavPushExtensionProp {
|
pub enum DavPushExtensionProp {
|
||||||
// WebDav Push
|
// WebDav Push
|
||||||
#[xml(skip_deserializing)]
|
#[xml(skip_deserializing)]
|
||||||
#[xml(ns = "crate::namespace::NS_DAVPUSH")]
|
#[xml(ns = "rustical_dav::namespace::NS_DAVPUSH")]
|
||||||
Transports(Transports),
|
Transports(Transports),
|
||||||
#[xml(ns = "crate::namespace::NS_DAVPUSH")]
|
#[xml(ns = "rustical_dav::namespace::NS_DAVPUSH")]
|
||||||
Topic(String),
|
Topic(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ pub trait DavPushExtension {
|
|||||||
fn get_prop(
|
fn get_prop(
|
||||||
&self,
|
&self,
|
||||||
prop: &DavPushExtensionPropName,
|
prop: &DavPushExtensionPropName,
|
||||||
) -> Result<DavPushExtensionProp, crate::Error> {
|
) -> Result<DavPushExtensionProp, rustical_dav::Error> {
|
||||||
Ok(match &prop {
|
Ok(match &prop {
|
||||||
DavPushExtensionPropName::Transports => {
|
DavPushExtensionPropName::Transports => {
|
||||||
DavPushExtensionProp::Transports(Default::default())
|
DavPushExtensionProp::Transports(Default::default())
|
||||||
@@ -27,11 +27,11 @@ pub trait DavPushExtension {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_prop(&self, _prop: DavPushExtensionProp) -> Result<(), crate::Error> {
|
fn set_prop(&self, _prop: DavPushExtensionProp) -> Result<(), rustical_dav::Error> {
|
||||||
Err(crate::Error::PropReadOnly)
|
Err(rustical_dav::Error::PropReadOnly)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_prop(&self, _prop: &DavPushExtensionPropName) -> Result<(), crate::Error> {
|
fn remove_prop(&self, _prop: &DavPushExtensionPropName) -> Result<(), rustical_dav::Error> {
|
||||||
Err(crate::Error::PropReadOnly)
|
Err(rustical_dav::Error::PropReadOnly)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
7
crates/dav_push/src/lib.rs
Normal file
7
crates/dav_push/src/lib.rs
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
mod extension;
|
||||||
|
pub mod notifier;
|
||||||
|
mod prop;
|
||||||
|
pub mod register;
|
||||||
|
|
||||||
|
pub use extension::*;
|
||||||
|
pub use prop::*;
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
use crate::xml::multistatus::PropstatElement;
|
|
||||||
use actix_web::http::StatusCode;
|
use actix_web::http::StatusCode;
|
||||||
|
use rustical_dav::xml::multistatus::PropstatElement;
|
||||||
use rustical_store::{CollectionOperation, CollectionOperationType, SubscriptionStore};
|
use rustical_store::{CollectionOperation, CollectionOperationType, SubscriptionStore};
|
||||||
use rustical_xml::{XmlRootTag, XmlSerialize, XmlSerializeRoot};
|
use rustical_xml::{XmlRootTag, XmlSerialize, XmlSerializeRoot};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@@ -8,17 +8,20 @@ use tracing::{error, info, warn};
|
|||||||
|
|
||||||
#[derive(XmlSerialize, Debug)]
|
#[derive(XmlSerialize, Debug)]
|
||||||
struct PushMessageProp {
|
struct PushMessageProp {
|
||||||
#[xml(ns = "crate::namespace::NS_DAV")]
|
#[xml(ns = "rustical_dav::namespace::NS_DAV")]
|
||||||
topic: String,
|
topic: String,
|
||||||
#[xml(ns = "crate::namespace::NS_DAV")]
|
#[xml(ns = "rustical_dav::namespace::NS_DAV")]
|
||||||
sync_token: Option<String>,
|
sync_token: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(XmlSerialize, XmlRootTag, Debug)]
|
#[derive(XmlSerialize, XmlRootTag, Debug)]
|
||||||
#[xml(root = b"push-message", ns = "crate::namespace::NS_DAVPUSH")]
|
#[xml(root = b"push-message", ns = "rustical_dav::namespace::NS_DAVPUSH")]
|
||||||
#[xml(ns_prefix(crate::namespace::NS_DAVPUSH = b"", crate::namespace::NS_DAV = b"D",))]
|
#[xml(ns_prefix(
|
||||||
|
rustical_dav::namespace::NS_DAVPUSH = b"",
|
||||||
|
rustical_dav::namespace::NS_DAV = b"D",
|
||||||
|
))]
|
||||||
struct PushMessage {
|
struct PushMessage {
|
||||||
#[xml(ns = "crate::namespace::NS_DAV")]
|
#[xml(ns = "rustical_dav::namespace::NS_DAV")]
|
||||||
propstat: PropstatElement<PushMessageProp>,
|
propstat: PropstatElement<PushMessageProp>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,7 +90,10 @@ pub async fn push_notifier(
|
|||||||
error!("{err}");
|
error!("{err}");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
warn!("Not sending a push notification to {} since it's not allowed in dav_push::allowed_push_servers", push_resource);
|
warn!(
|
||||||
|
"Not sending a push notification to {} since it's not allowed in dav_push::allowed_push_servers",
|
||||||
|
push_resource
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,7 @@ use rustical_xml::XmlSerialize;
|
|||||||
|
|
||||||
#[derive(Debug, Clone, XmlSerialize, PartialEq)]
|
#[derive(Debug, Clone, XmlSerialize, PartialEq)]
|
||||||
pub enum Transport {
|
pub enum Transport {
|
||||||
#[xml(ns = "crate::namespace::NS_DAVPUSH")]
|
#[xml(ns = "rustical_dav::namespace::NS_DAVPUSH")]
|
||||||
WebPush,
|
WebPush,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3,23 +3,23 @@ use rustical_xml::{XmlDeserialize, XmlRootTag};
|
|||||||
#[derive(XmlDeserialize, Clone, Debug, PartialEq)]
|
#[derive(XmlDeserialize, Clone, Debug, PartialEq)]
|
||||||
#[xml(ns = "crate::namespace::NS_DAVPUSH")]
|
#[xml(ns = "crate::namespace::NS_DAVPUSH")]
|
||||||
pub struct WebPushSubscription {
|
pub struct WebPushSubscription {
|
||||||
#[xml(ns = "crate::namespace::NS_DAVPUSH")]
|
#[xml(ns = "rustical_dav::namespace::NS_DAVPUSH")]
|
||||||
pub push_resource: String,
|
pub push_resource: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(XmlDeserialize, Clone, Debug, PartialEq)]
|
#[derive(XmlDeserialize, Clone, Debug, PartialEq)]
|
||||||
pub struct SubscriptionElement {
|
pub struct SubscriptionElement {
|
||||||
#[xml(ns = "crate::namespace::NS_DAVPUSH")]
|
#[xml(ns = "rustical_dav::namespace::NS_DAVPUSH")]
|
||||||
pub web_push_subscription: WebPushSubscription,
|
pub web_push_subscription: WebPushSubscription,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(XmlDeserialize, XmlRootTag, Clone, Debug, PartialEq)]
|
#[derive(XmlDeserialize, XmlRootTag, Clone, Debug, PartialEq)]
|
||||||
#[xml(root = b"push-register")]
|
#[xml(root = b"push-register")]
|
||||||
#[xml(ns = "crate::namespace::NS_DAVPUSH")]
|
#[xml(ns = "rustical_dav::namespace::NS_DAVPUSH")]
|
||||||
pub struct PushRegister {
|
pub struct PushRegister {
|
||||||
#[xml(ns = "crate::namespace::NS_DAVPUSH")]
|
#[xml(ns = "rustical_dav::namespace::NS_DAVPUSH")]
|
||||||
pub subscription: SubscriptionElement,
|
pub subscription: SubscriptionElement,
|
||||||
#[xml(ns = "crate::namespace::NS_DAVPUSH")]
|
#[xml(ns = "rustical_dav::namespace::NS_DAVPUSH")]
|
||||||
pub expires: Option<String>,
|
pub expires: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -10,9 +10,9 @@ use actix_web::{
|
|||||||
};
|
};
|
||||||
use error::OidcError;
|
use error::OidcError;
|
||||||
use openidconnect::{
|
use openidconnect::{
|
||||||
AuthenticationFlow, AuthorizationCode, CsrfToken, EmptyAdditionalClaims, EndpointMaybeSet,
|
AuthenticationFlow, AuthorizationCode, CsrfToken, EndpointMaybeSet, EndpointNotSet,
|
||||||
EndpointNotSet, EndpointSet, IssuerUrl, Nonce, OAuth2TokenResponse, PkceCodeChallenge,
|
EndpointSet, IssuerUrl, Nonce, OAuth2TokenResponse, PkceCodeChallenge, PkceCodeVerifier,
|
||||||
PkceCodeVerifier, RedirectUrl, TokenResponse, UserInfoClaims,
|
RedirectUrl, TokenResponse, UserInfoClaims,
|
||||||
core::{CoreClient, CoreGenderClaim, CoreProviderMetadata, CoreResponseType},
|
core::{CoreClient, CoreGenderClaim, CoreProviderMetadata, CoreResponseType},
|
||||||
};
|
};
|
||||||
use rustical_store::auth::{AuthenticationProvider, User, user::PrincipalType::Individual};
|
use rustical_store::auth::{AuthenticationProvider, User, user::PrincipalType::Individual};
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ tokio.workspace = true
|
|||||||
rand.workspace = true
|
rand.workspace = true
|
||||||
uuid.workspace = true
|
uuid.workspace = true
|
||||||
clap.workspace = true
|
clap.workspace = true
|
||||||
|
rustical_dav.workspace = true
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
rstest = { workspace = true }
|
rstest = { workspace = true }
|
||||||
|
|||||||
@@ -81,6 +81,12 @@ impl User {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl rustical_dav::Principal for User {
|
||||||
|
fn get_id(&self) -> &str {
|
||||||
|
&self.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Display)]
|
#[derive(Clone, Debug, Display)]
|
||||||
pub struct UnauthorizedError;
|
pub struct UnauthorizedError;
|
||||||
|
|
||||||
|
|||||||
26
src/main.rs
26
src/main.rs
@@ -9,7 +9,7 @@ use commands::{cmd_gen_config, cmd_pwhash};
|
|||||||
use config::{DataStoreConfig, SqliteDataStoreConfig};
|
use config::{DataStoreConfig, SqliteDataStoreConfig};
|
||||||
use figment::Figment;
|
use figment::Figment;
|
||||||
use figment::providers::{Env, Format, Toml};
|
use figment::providers::{Env, Format, Toml};
|
||||||
use rustical_dav::push::push_notifier;
|
use rustical_dav_push::notifier::push_notifier;
|
||||||
use rustical_frontend::nextcloud_login::NextcloudFlows;
|
use rustical_frontend::nextcloud_login::NextcloudFlows;
|
||||||
use rustical_store::auth::TomlPrincipalStore;
|
use rustical_store::auth::TomlPrincipalStore;
|
||||||
use rustical_store::{AddressbookStore, CalendarStore, CollectionOperation, SubscriptionStore};
|
use rustical_store::{AddressbookStore, CalendarStore, CollectionOperation, SubscriptionStore};
|
||||||
@@ -150,51 +150,51 @@ mod tests {
|
|||||||
}
|
}
|
||||||
async fn get_principal(
|
async fn get_principal(
|
||||||
&self,
|
&self,
|
||||||
id: &str,
|
_id: &str,
|
||||||
) -> Result<Option<rustical_store::auth::User>, rustical_store::Error> {
|
) -> Result<Option<rustical_store::auth::User>, rustical_store::Error> {
|
||||||
Err(rustical_store::Error::Other(anyhow!("Not implemented")))
|
Err(rustical_store::Error::Other(anyhow!("Not implemented")))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn remove_principal(&self, id: &str) -> Result<(), rustical_store::Error> {
|
async fn remove_principal(&self, _id: &str) -> Result<(), rustical_store::Error> {
|
||||||
Err(rustical_store::Error::Other(anyhow!("Not implemented")))
|
Err(rustical_store::Error::Other(anyhow!("Not implemented")))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn validate_password(
|
async fn validate_password(
|
||||||
&self,
|
&self,
|
||||||
user_id: &str,
|
_user_id: &str,
|
||||||
password: &str,
|
_password: &str,
|
||||||
) -> Result<Option<rustical_store::auth::User>, rustical_store::Error> {
|
) -> Result<Option<rustical_store::auth::User>, rustical_store::Error> {
|
||||||
Err(rustical_store::Error::Other(anyhow!("Not implemented")))
|
Err(rustical_store::Error::Other(anyhow!("Not implemented")))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn validate_app_token(
|
async fn validate_app_token(
|
||||||
&self,
|
&self,
|
||||||
user_id: &str,
|
_user_id: &str,
|
||||||
token: &str,
|
_token: &str,
|
||||||
) -> Result<Option<rustical_store::auth::User>, rustical_store::Error> {
|
) -> Result<Option<rustical_store::auth::User>, rustical_store::Error> {
|
||||||
Err(rustical_store::Error::Other(anyhow!("Not implemented")))
|
Err(rustical_store::Error::Other(anyhow!("Not implemented")))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn add_app_token(
|
async fn add_app_token(
|
||||||
&self,
|
&self,
|
||||||
user_id: &str,
|
_user_id: &str,
|
||||||
name: String,
|
_name: String,
|
||||||
token: String,
|
_token: String,
|
||||||
) -> Result<String, rustical_store::Error> {
|
) -> Result<String, rustical_store::Error> {
|
||||||
Err(rustical_store::Error::Other(anyhow!("Not implemented")))
|
Err(rustical_store::Error::Other(anyhow!("Not implemented")))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn remove_app_token(
|
async fn remove_app_token(
|
||||||
&self,
|
&self,
|
||||||
user_id: &str,
|
_user_id: &str,
|
||||||
token_id: &str,
|
_token_id: &str,
|
||||||
) -> Result<(), rustical_store::Error> {
|
) -> Result<(), rustical_store::Error> {
|
||||||
Err(rustical_store::Error::Other(anyhow!("Not implemented")))
|
Err(rustical_store::Error::Other(anyhow!("Not implemented")))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn insert_principal(
|
async fn insert_principal(
|
||||||
&self,
|
&self,
|
||||||
user: rustical_store::auth::User,
|
_user: rustical_store::auth::User,
|
||||||
) -> Result<(), rustical_store::Error> {
|
) -> Result<(), rustical_store::Error> {
|
||||||
Err(rustical_store::Error::Other(anyhow!("Not implemented")))
|
Err(rustical_store::Error::Other(anyhow!("Not implemented")))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user