mirror of
https://github.com/lennart-k/rustical.git
synced 2025-12-13 19:22:26 +00:00
Rename User struct to Principal
This commit is contained in:
@@ -9,7 +9,7 @@ use ical::generator::{Emitter, IcalCalendarBuilder};
|
||||
use ical::property::Property;
|
||||
use percent_encoding::{CONTROLS, utf8_percent_encode};
|
||||
use rustical_ical::{CalendarObjectComponent, EventObject, JournalObject, TodoObject};
|
||||
use rustical_store::{CalendarStore, SubscriptionStore, auth::User};
|
||||
use rustical_store::{CalendarStore, SubscriptionStore, auth::Principal};
|
||||
use std::collections::HashMap;
|
||||
use std::str::FromStr;
|
||||
use tracing::instrument;
|
||||
@@ -18,7 +18,7 @@ use tracing::instrument;
|
||||
pub async fn route_get<C: CalendarStore, S: SubscriptionStore>(
|
||||
Path((principal, calendar_id)): Path<(String, String)>,
|
||||
State(CalendarResourceService { cal_store, .. }): State<CalendarResourceService<C, S>>,
|
||||
user: User,
|
||||
user: Principal,
|
||||
) -> Result<Response, Error> {
|
||||
if !user.is_principal(&principal) {
|
||||
return Err(crate::Error::Unauthorized);
|
||||
|
||||
@@ -6,7 +6,7 @@ use axum::response::{IntoResponse, Response};
|
||||
use http::{Method, StatusCode};
|
||||
use rustical_dav::xml::HrefElement;
|
||||
use rustical_ical::CalendarObjectType;
|
||||
use rustical_store::auth::User;
|
||||
use rustical_store::auth::Principal;
|
||||
use rustical_store::{Calendar, CalendarStore, SubscriptionStore};
|
||||
use rustical_xml::{Unparsed, XmlDeserialize, XmlDocument, XmlRootTag};
|
||||
use tracing::instrument;
|
||||
@@ -63,7 +63,7 @@ struct MkcolRequest {
|
||||
#[instrument(skip(cal_store))]
|
||||
pub async fn route_mkcalendar<C: CalendarStore, S: SubscriptionStore>(
|
||||
Path((principal, cal_id)): Path<(String, String)>,
|
||||
user: User,
|
||||
user: Principal,
|
||||
State(CalendarResourceService { cal_store, .. }): State<CalendarResourceService<C, S>>,
|
||||
method: Method,
|
||||
body: String,
|
||||
|
||||
@@ -7,7 +7,7 @@ use http::{HeaderMap, HeaderValue, StatusCode, header};
|
||||
use rustical_dav::privileges::UserPrivilege;
|
||||
use rustical_dav::resource::Resource;
|
||||
use rustical_dav_push::register::PushRegister;
|
||||
use rustical_store::auth::User;
|
||||
use rustical_store::auth::Principal;
|
||||
use rustical_store::{CalendarStore, Subscription, SubscriptionStore};
|
||||
use rustical_xml::XmlDocument;
|
||||
use tracing::instrument;
|
||||
@@ -15,7 +15,7 @@ use tracing::instrument;
|
||||
#[instrument(skip(resource_service))]
|
||||
pub async fn route_post<C: CalendarStore, S: SubscriptionStore>(
|
||||
Path((principal, cal_id)): Path<(String, String)>,
|
||||
user: User,
|
||||
user: Principal,
|
||||
State(resource_service): State<CalendarResourceService<C, S>>,
|
||||
body: String,
|
||||
) -> Result<Response, Error> {
|
||||
|
||||
@@ -21,7 +21,7 @@ use rustical_dav::{
|
||||
},
|
||||
};
|
||||
use rustical_ical::CalendarObject;
|
||||
use rustical_store::{CalendarStore, SubscriptionStore, auth::User};
|
||||
use rustical_store::{CalendarStore, SubscriptionStore, auth::Principal};
|
||||
use rustical_xml::{XmlDeserialize, XmlDocument};
|
||||
use sync_collection::handle_sync_collection;
|
||||
use tracing::instrument;
|
||||
@@ -56,7 +56,7 @@ fn objects_response(
|
||||
path: &str,
|
||||
principal: &str,
|
||||
puri: &impl PrincipalUri,
|
||||
user: &User,
|
||||
user: &Principal,
|
||||
prop: &PropfindType<CalendarObjectPropWrapperName>,
|
||||
) -> Result<MultistatusElement<CalendarObjectPropWrapper, String>, Error> {
|
||||
let mut responses = Vec::new();
|
||||
@@ -90,7 +90,7 @@ fn objects_response(
|
||||
#[instrument(skip(cal_store))]
|
||||
pub async fn route_report_calendar<C: CalendarStore, S: SubscriptionStore>(
|
||||
Path((principal, cal_id)): Path<(String, String)>,
|
||||
user: User,
|
||||
user: Principal,
|
||||
Extension(puri): Extension<CalDavPrincipalUri>,
|
||||
State(CalendarResourceService { cal_store, .. }): State<CalendarResourceService<C, S>>,
|
||||
OriginalUri(uri): OriginalUri,
|
||||
|
||||
@@ -13,7 +13,7 @@ use rustical_dav::{
|
||||
};
|
||||
use rustical_store::{
|
||||
CalendarStore,
|
||||
auth::User,
|
||||
auth::Principal,
|
||||
synctoken::{format_synctoken, parse_synctoken},
|
||||
};
|
||||
|
||||
@@ -21,7 +21,7 @@ pub async fn handle_sync_collection<C: CalendarStore>(
|
||||
sync_collection: &SyncCollectionRequest<CalendarObjectPropWrapperName>,
|
||||
path: &str,
|
||||
puri: &impl PrincipalUri,
|
||||
user: &User,
|
||||
user: &Principal,
|
||||
principal: &str,
|
||||
cal_id: &str,
|
||||
cal_store: &C,
|
||||
|
||||
@@ -12,7 +12,7 @@ use rustical_dav::xml::{HrefElement, Resourcetype, ResourcetypeInner, SupportedR
|
||||
use rustical_dav_push::{DavPushExtension, DavPushExtensionProp};
|
||||
use rustical_ical::CalDateTime;
|
||||
use rustical_store::Calendar;
|
||||
use rustical_store::auth::User;
|
||||
use rustical_store::auth::Principal;
|
||||
use rustical_xml::{EnumVariants, PropName};
|
||||
use rustical_xml::{XmlDeserialize, XmlSerialize};
|
||||
use std::str::FromStr;
|
||||
@@ -95,7 +95,7 @@ impl DavPushExtension for CalendarResource {
|
||||
impl Resource for CalendarResource {
|
||||
type Prop = CalendarPropWrapper;
|
||||
type Error = Error;
|
||||
type Principal = User;
|
||||
type Principal = Principal;
|
||||
|
||||
fn is_collection(&self) -> bool {
|
||||
true
|
||||
@@ -121,7 +121,7 @@ impl Resource for CalendarResource {
|
||||
fn get_prop(
|
||||
&self,
|
||||
puri: &impl PrincipalUri,
|
||||
user: &User,
|
||||
user: &Principal,
|
||||
prop: &CalendarPropWrapperName,
|
||||
) -> Result<Self::Prop, Self::Error> {
|
||||
Ok(match prop {
|
||||
@@ -291,7 +291,7 @@ impl Resource for CalendarResource {
|
||||
Some(&self.cal.principal)
|
||||
}
|
||||
|
||||
fn get_user_privileges(&self, user: &User) -> Result<UserPrivilegeSet, Self::Error> {
|
||||
fn get_user_privileges(&self, user: &Principal) -> Result<UserPrivilegeSet, Self::Error> {
|
||||
if self.cal.subscription_url.is_some() || self.read_only {
|
||||
return Ok(UserPrivilegeSet::owner_read(
|
||||
user.is_principal(&self.cal.principal),
|
||||
|
||||
@@ -13,7 +13,7 @@ use axum::handler::Handler;
|
||||
use axum::response::Response;
|
||||
use futures_util::future::BoxFuture;
|
||||
use rustical_dav::resource::{AxumMethods, ResourceService};
|
||||
use rustical_store::auth::User;
|
||||
use rustical_store::auth::Principal;
|
||||
use rustical_store::{CalendarStore, SubscriptionStore};
|
||||
use std::convert::Infallible;
|
||||
use std::sync::Arc;
|
||||
@@ -48,7 +48,7 @@ impl<C: CalendarStore, S: SubscriptionStore> ResourceService for CalendarResourc
|
||||
type PathComponents = (String, String); // principal, calendar_id
|
||||
type Resource = CalendarResource;
|
||||
type Error = Error;
|
||||
type Principal = User;
|
||||
type Principal = Principal;
|
||||
type PrincipalUri = CalDavPrincipalUri;
|
||||
|
||||
const DAV_HEADER: &str = "1, 3, access-control, calendar-access, calendar-proxy, webdav-push";
|
||||
|
||||
@@ -9,7 +9,7 @@ use headers::{ContentType, ETag, HeaderMapExt, IfNoneMatch};
|
||||
use http::{HeaderMap, StatusCode};
|
||||
use rustical_ical::CalendarObject;
|
||||
use rustical_store::CalendarStore;
|
||||
use rustical_store::auth::User;
|
||||
use rustical_store::auth::Principal;
|
||||
use std::str::FromStr;
|
||||
use tracing::instrument;
|
||||
|
||||
@@ -21,7 +21,7 @@ pub async fn get_event<C: CalendarStore>(
|
||||
object_id,
|
||||
}): Path<CalendarObjectPathComponents>,
|
||||
State(CalendarObjectResourceService { cal_store }): State<CalendarObjectResourceService<C>>,
|
||||
user: User,
|
||||
user: Principal,
|
||||
) -> Result<Response, Error> {
|
||||
if !user.is_principal(&principal) {
|
||||
return Err(crate::Error::Unauthorized);
|
||||
@@ -51,7 +51,7 @@ pub async fn put_event<C: CalendarStore>(
|
||||
object_id,
|
||||
}): Path<CalendarObjectPathComponents>,
|
||||
State(CalendarObjectResourceService { cal_store }): State<CalendarObjectResourceService<C>>,
|
||||
user: User,
|
||||
user: Principal,
|
||||
mut if_none_match: Option<TypedHeader<IfNoneMatch>>,
|
||||
header_map: HeaderMap,
|
||||
body: String,
|
||||
|
||||
@@ -8,7 +8,7 @@ use rustical_dav::{
|
||||
xml::Resourcetype,
|
||||
};
|
||||
use rustical_ical::CalendarObject;
|
||||
use rustical_store::auth::User;
|
||||
use rustical_store::auth::Principal;
|
||||
|
||||
#[derive(Clone, From, Into)]
|
||||
pub struct CalendarObjectResource {
|
||||
@@ -25,7 +25,7 @@ impl ResourceName for CalendarObjectResource {
|
||||
impl Resource for CalendarObjectResource {
|
||||
type Prop = CalendarObjectPropWrapper;
|
||||
type Error = Error;
|
||||
type Principal = User;
|
||||
type Principal = Principal;
|
||||
|
||||
fn is_collection(&self) -> bool {
|
||||
false
|
||||
@@ -38,7 +38,7 @@ impl Resource for CalendarObjectResource {
|
||||
fn get_prop(
|
||||
&self,
|
||||
puri: &impl PrincipalUri,
|
||||
user: &User,
|
||||
user: &Principal,
|
||||
prop: &CalendarObjectPropWrapperName,
|
||||
) -> Result<Self::Prop, Self::Error> {
|
||||
Ok(match prop {
|
||||
@@ -81,7 +81,7 @@ impl Resource for CalendarObjectResource {
|
||||
Some(self.object.get_etag())
|
||||
}
|
||||
|
||||
fn get_user_privileges(&self, user: &User) -> Result<UserPrivilegeSet, Self::Error> {
|
||||
fn get_user_privileges(&self, user: &Principal) -> Result<UserPrivilegeSet, Self::Error> {
|
||||
Ok(UserPrivilegeSet::owner_only(
|
||||
user.is_principal(&self.principal),
|
||||
))
|
||||
|
||||
@@ -9,7 +9,7 @@ use async_trait::async_trait;
|
||||
use axum::{extract::Request, handler::Handler, response::Response};
|
||||
use futures_util::future::BoxFuture;
|
||||
use rustical_dav::resource::{AxumMethods, ResourceService};
|
||||
use rustical_store::{CalendarStore, auth::User};
|
||||
use rustical_store::{CalendarStore, auth::Principal};
|
||||
use serde::{Deserialize, Deserializer};
|
||||
use std::{convert::Infallible, sync::Arc};
|
||||
use tower::Service;
|
||||
@@ -46,7 +46,7 @@ impl<C: CalendarStore> ResourceService for CalendarObjectResourceService<C> {
|
||||
type Resource = CalendarObjectResource;
|
||||
type MemberType = CalendarObjectResource;
|
||||
type Error = Error;
|
||||
type Principal = User;
|
||||
type Principal = Principal;
|
||||
type PrincipalUri = CalDavPrincipalUri;
|
||||
|
||||
const DAV_HEADER: &str = "1, 3, access-control, calendar-access";
|
||||
|
||||
@@ -6,7 +6,7 @@ use principal::PrincipalResourceService;
|
||||
use rustical_dav::resource::{PrincipalUri, ResourceService};
|
||||
use rustical_dav::resources::RootResourceService;
|
||||
use rustical_store::auth::middleware::AuthenticationLayer;
|
||||
use rustical_store::auth::{AuthenticationProvider, User};
|
||||
use rustical_store::auth::{AuthenticationProvider, Principal};
|
||||
use rustical_store::{CalendarStore, SubscriptionStore};
|
||||
use std::sync::Arc;
|
||||
|
||||
@@ -44,7 +44,7 @@ pub fn caldav_router<AP: AuthenticationProvider, C: CalendarStore, S: Subscripti
|
||||
Router::new()
|
||||
.nest(
|
||||
prefix,
|
||||
RootResourceService::<_, User, CalDavPrincipalUri>::new(principal_service.clone())
|
||||
RootResourceService::<_, Principal, CalDavPrincipalUri>::new(principal_service.clone())
|
||||
.axum_router()
|
||||
.layer(AuthenticationLayer::new(auth_provider))
|
||||
.layer(Extension(CalDavPrincipalUri(prefix))),
|
||||
|
||||
@@ -5,7 +5,7 @@ use rustical_dav::resource::{PrincipalUri, Resource, ResourceName};
|
||||
use rustical_dav::xml::{
|
||||
GroupMemberSet, GroupMembership, Resourcetype, ResourcetypeInner, SupportedReportSet,
|
||||
};
|
||||
use rustical_store::auth::User;
|
||||
use rustical_store::auth::Principal;
|
||||
|
||||
mod service;
|
||||
pub use service::*;
|
||||
@@ -14,7 +14,7 @@ pub use prop::*;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct PrincipalResource {
|
||||
principal: User,
|
||||
principal: Principal,
|
||||
members: Vec<String>,
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ impl ResourceName for PrincipalResource {
|
||||
impl Resource for PrincipalResource {
|
||||
type Prop = PrincipalPropWrapper;
|
||||
type Error = Error;
|
||||
type Principal = User;
|
||||
type Principal = Principal;
|
||||
|
||||
fn is_collection(&self) -> bool {
|
||||
true
|
||||
@@ -48,7 +48,7 @@ impl Resource for PrincipalResource {
|
||||
fn get_prop(
|
||||
&self,
|
||||
puri: &impl PrincipalUri,
|
||||
user: &User,
|
||||
user: &Principal,
|
||||
prop: &PrincipalPropWrapperName,
|
||||
) -> Result<Self::Prop, Self::Error> {
|
||||
let principal_url = puri.principal_uri(&self.principal.id);
|
||||
@@ -113,7 +113,7 @@ impl Resource for PrincipalResource {
|
||||
Some(&self.principal.id)
|
||||
}
|
||||
|
||||
fn get_user_privileges(&self, user: &User) -> Result<UserPrivilegeSet, Self::Error> {
|
||||
fn get_user_privileges(&self, user: &Principal) -> Result<UserPrivilegeSet, Self::Error> {
|
||||
Ok(UserPrivilegeSet::owner_read(
|
||||
user.is_principal(&self.principal.id),
|
||||
))
|
||||
|
||||
@@ -2,7 +2,7 @@ use rustical_dav::{
|
||||
extensions::CommonPropertiesProp,
|
||||
xml::{GroupMemberSet, GroupMembership, HrefElement, SupportedReportSet},
|
||||
};
|
||||
use rustical_store::auth::user::PrincipalType;
|
||||
use rustical_store::auth::PrincipalType;
|
||||
use rustical_xml::{EnumVariants, PropName, XmlDeserialize, XmlSerialize};
|
||||
use strum_macros::VariantArray;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ use crate::{CalDavPrincipalUri, Error};
|
||||
use async_trait::async_trait;
|
||||
use axum::Router;
|
||||
use rustical_dav::resource::{AxumMethods, ResourceService};
|
||||
use rustical_store::auth::{AuthenticationProvider, User};
|
||||
use rustical_store::auth::{AuthenticationProvider, Principal};
|
||||
use rustical_store::{CalendarStore, SubscriptionStore};
|
||||
use std::sync::Arc;
|
||||
|
||||
@@ -40,7 +40,7 @@ impl<AP: AuthenticationProvider, S: SubscriptionStore, CS: CalendarStore> Resour
|
||||
type MemberType = CalendarResource;
|
||||
type Resource = PrincipalResource;
|
||||
type Error = Error;
|
||||
type Principal = User;
|
||||
type Principal = Principal;
|
||||
type PrincipalUri = CalDavPrincipalUri;
|
||||
|
||||
const DAV_HEADER: &str = "1, 3, access-control, calendar-access, calendar-proxy";
|
||||
|
||||
@@ -12,7 +12,7 @@ use rustical_dav::privileges::UserPrivilege;
|
||||
use rustical_dav::resource::Resource;
|
||||
use rustical_ical::AddressObject;
|
||||
use rustical_store::AddressbookStore;
|
||||
use rustical_store::auth::User;
|
||||
use rustical_store::auth::Principal;
|
||||
use std::str::FromStr;
|
||||
use tracing::instrument;
|
||||
|
||||
@@ -24,7 +24,7 @@ pub async fn get_object<AS: AddressbookStore>(
|
||||
object_id,
|
||||
}): Path<AddressObjectPathComponents>,
|
||||
State(AddressObjectResourceService { addr_store }): State<AddressObjectResourceService<AS>>,
|
||||
user: User,
|
||||
user: Principal,
|
||||
) -> Result<Response, Error> {
|
||||
if !user.is_principal(&principal) {
|
||||
return Err(Error::Unauthorized);
|
||||
@@ -60,7 +60,7 @@ pub async fn put_object<AS: AddressbookStore>(
|
||||
object_id,
|
||||
}): Path<AddressObjectPathComponents>,
|
||||
State(AddressObjectResourceService { addr_store }): State<AddressObjectResourceService<AS>>,
|
||||
user: User,
|
||||
user: Principal,
|
||||
mut if_none_match: Option<TypedHeader<IfNoneMatch>>,
|
||||
header_map: HeaderMap,
|
||||
body: String,
|
||||
|
||||
@@ -13,7 +13,7 @@ use rustical_dav::{
|
||||
xml::Resourcetype,
|
||||
};
|
||||
use rustical_ical::AddressObject;
|
||||
use rustical_store::auth::User;
|
||||
use rustical_store::auth::Principal;
|
||||
|
||||
#[derive(Clone, From, Into)]
|
||||
pub struct AddressObjectResource {
|
||||
@@ -30,7 +30,7 @@ impl ResourceName for AddressObjectResource {
|
||||
impl Resource for AddressObjectResource {
|
||||
type Prop = AddressObjectPropWrapper;
|
||||
type Error = Error;
|
||||
type Principal = User;
|
||||
type Principal = Principal;
|
||||
|
||||
fn is_collection(&self) -> bool {
|
||||
false
|
||||
@@ -43,7 +43,7 @@ impl Resource for AddressObjectResource {
|
||||
fn get_prop(
|
||||
&self,
|
||||
puri: &impl PrincipalUri,
|
||||
user: &User,
|
||||
user: &Principal,
|
||||
prop: &AddressObjectPropWrapperName,
|
||||
) -> Result<Self::Prop, Self::Error> {
|
||||
Ok(match prop {
|
||||
@@ -78,7 +78,7 @@ impl Resource for AddressObjectResource {
|
||||
Some(self.object.get_etag())
|
||||
}
|
||||
|
||||
fn get_user_privileges(&self, user: &User) -> Result<UserPrivilegeSet, Self::Error> {
|
||||
fn get_user_privileges(&self, user: &Principal) -> Result<UserPrivilegeSet, Self::Error> {
|
||||
Ok(UserPrivilegeSet::owner_only(
|
||||
user.is_principal(&self.principal),
|
||||
))
|
||||
|
||||
@@ -5,7 +5,7 @@ use axum::{extract::Request, handler::Handler, response::Response};
|
||||
use derive_more::derive::Constructor;
|
||||
use futures_util::future::BoxFuture;
|
||||
use rustical_dav::resource::{AxumMethods, ResourceService};
|
||||
use rustical_store::{AddressbookStore, auth::User};
|
||||
use rustical_store::{AddressbookStore, auth::Principal};
|
||||
use serde::{Deserialize, Deserializer};
|
||||
use std::{convert::Infallible, sync::Arc};
|
||||
use tower::Service;
|
||||
@@ -37,7 +37,7 @@ impl<AS: AddressbookStore> ResourceService for AddressObjectResourceService<AS>
|
||||
type Resource = AddressObjectResource;
|
||||
type MemberType = AddressObjectResource;
|
||||
type Error = Error;
|
||||
type Principal = User;
|
||||
type Principal = Principal;
|
||||
type PrincipalUri = CardDavPrincipalUri;
|
||||
|
||||
const DAV_HEADER: &str = "1, 3, access-control, addressbook";
|
||||
|
||||
@@ -10,7 +10,7 @@ use percent_encoding::{CONTROLS, utf8_percent_encode};
|
||||
use rustical_dav::privileges::UserPrivilege;
|
||||
use rustical_dav::resource::Resource;
|
||||
use rustical_ical::AddressObject;
|
||||
use rustical_store::auth::User;
|
||||
use rustical_store::auth::Principal;
|
||||
use rustical_store::{AddressbookStore, SubscriptionStore};
|
||||
use std::str::FromStr;
|
||||
use tracing::instrument;
|
||||
@@ -19,7 +19,7 @@ use tracing::instrument;
|
||||
pub async fn route_get<AS: AddressbookStore, S: SubscriptionStore>(
|
||||
Path((principal, addressbook_id)): Path<(String, String)>,
|
||||
State(AddressbookResourceService { addr_store, .. }): State<AddressbookResourceService<AS, S>>,
|
||||
user: User,
|
||||
user: Principal,
|
||||
) -> Result<Response, Error> {
|
||||
if !user.is_principal(&principal) {
|
||||
return Err(Error::Unauthorized);
|
||||
|
||||
@@ -4,7 +4,7 @@ use axum::{
|
||||
response::{IntoResponse, Response},
|
||||
};
|
||||
use http::StatusCode;
|
||||
use rustical_store::{Addressbook, AddressbookStore, SubscriptionStore, auth::User};
|
||||
use rustical_store::{Addressbook, AddressbookStore, SubscriptionStore, auth::Principal};
|
||||
use rustical_xml::{XmlDeserialize, XmlDocument, XmlRootTag};
|
||||
use tracing::instrument;
|
||||
|
||||
@@ -44,7 +44,7 @@ struct MkcolRequest {
|
||||
#[instrument(skip(addr_store))]
|
||||
pub async fn route_mkcol<AS: AddressbookStore, S: SubscriptionStore>(
|
||||
Path((principal, addressbook_id)): Path<(String, String)>,
|
||||
user: User,
|
||||
user: Principal,
|
||||
State(AddressbookResourceService { addr_store, .. }): State<AddressbookResourceService<AS, S>>,
|
||||
body: String,
|
||||
) -> Result<Response, Error> {
|
||||
|
||||
@@ -7,7 +7,7 @@ use http::{HeaderMap, HeaderValue, StatusCode, header};
|
||||
use rustical_dav::privileges::UserPrivilege;
|
||||
use rustical_dav::resource::Resource;
|
||||
use rustical_dav_push::register::PushRegister;
|
||||
use rustical_store::auth::User;
|
||||
use rustical_store::auth::Principal;
|
||||
use rustical_store::{AddressbookStore, Subscription, SubscriptionStore};
|
||||
use rustical_xml::XmlDocument;
|
||||
use tracing::instrument;
|
||||
@@ -15,7 +15,7 @@ use tracing::instrument;
|
||||
#[instrument(skip(resource_service))]
|
||||
pub async fn route_post<AS: AddressbookStore, S: SubscriptionStore>(
|
||||
Path((principal, addr_id)): Path<(String, String)>,
|
||||
user: User,
|
||||
user: Principal,
|
||||
State(resource_service): State<AddressbookResourceService<AS, S>>,
|
||||
body: String,
|
||||
) -> Result<Response, Error> {
|
||||
|
||||
@@ -9,14 +9,14 @@ use http::StatusCode;
|
||||
use ical::VcardParser;
|
||||
use rustical_ical::AddressObject;
|
||||
use rustical_store::Addressbook;
|
||||
use rustical_store::{AddressbookStore, SubscriptionStore, auth::User};
|
||||
use rustical_store::{AddressbookStore, SubscriptionStore, auth::Principal};
|
||||
use tracing::instrument;
|
||||
|
||||
#[instrument(skip(addr_store))]
|
||||
pub async fn route_put<AS: AddressbookStore, S: SubscriptionStore>(
|
||||
Path((principal, addressbook_id)): Path<(String, String)>,
|
||||
State(AddressbookResourceService { addr_store, .. }): State<AddressbookResourceService<AS, S>>,
|
||||
user: User,
|
||||
user: Principal,
|
||||
body: String,
|
||||
) -> Result<Response, Error> {
|
||||
if !user.is_principal(&principal) {
|
||||
|
||||
@@ -10,7 +10,7 @@ use rustical_dav::{
|
||||
xml::{MultistatusElement, PropfindType, multistatus::ResponseElement},
|
||||
};
|
||||
use rustical_ical::AddressObject;
|
||||
use rustical_store::{AddressbookStore, auth::User};
|
||||
use rustical_store::{AddressbookStore, auth::Principal};
|
||||
use rustical_xml::XmlDeserialize;
|
||||
|
||||
#[derive(XmlDeserialize, Clone, Debug, PartialEq)]
|
||||
@@ -63,7 +63,7 @@ pub async fn handle_addressbook_multiget<AS: AddressbookStore>(
|
||||
prop: &PropfindType<AddressObjectPropWrapperName>,
|
||||
path: &str,
|
||||
puri: &impl PrincipalUri,
|
||||
user: &User,
|
||||
user: &Principal,
|
||||
principal: &str,
|
||||
cal_id: &str,
|
||||
addr_store: &AS,
|
||||
|
||||
@@ -9,7 +9,7 @@ use axum::{
|
||||
response::IntoResponse,
|
||||
};
|
||||
use rustical_dav::xml::{PropfindType, sync_collection::SyncCollectionRequest};
|
||||
use rustical_store::{AddressbookStore, SubscriptionStore, auth::User};
|
||||
use rustical_store::{AddressbookStore, SubscriptionStore, auth::Principal};
|
||||
use rustical_xml::{XmlDeserialize, XmlDocument};
|
||||
use sync_collection::handle_sync_collection;
|
||||
use tracing::instrument;
|
||||
@@ -37,7 +37,7 @@ impl ReportRequest {
|
||||
#[instrument(skip(addr_store))]
|
||||
pub async fn route_report_addressbook<AS: AddressbookStore, S: SubscriptionStore>(
|
||||
Path((principal, addressbook_id)): Path<(String, String)>,
|
||||
user: User,
|
||||
user: Principal,
|
||||
OriginalUri(uri): OriginalUri,
|
||||
Extension(puri): Extension<CardDavPrincipalUri>,
|
||||
State(AddressbookResourceService { addr_store, .. }): State<AddressbookResourceService<AS, S>>,
|
||||
|
||||
@@ -13,7 +13,7 @@ use rustical_dav::{
|
||||
};
|
||||
use rustical_store::{
|
||||
AddressbookStore,
|
||||
auth::User,
|
||||
auth::Principal,
|
||||
synctoken::{format_synctoken, parse_synctoken},
|
||||
};
|
||||
|
||||
@@ -21,7 +21,7 @@ pub async fn handle_sync_collection<AS: AddressbookStore>(
|
||||
sync_collection: &SyncCollectionRequest<AddressObjectPropWrapperName>,
|
||||
path: &str,
|
||||
puri: &impl PrincipalUri,
|
||||
user: &User,
|
||||
user: &Principal,
|
||||
principal: &str,
|
||||
addressbook_id: &str,
|
||||
addr_store: &AS,
|
||||
|
||||
@@ -10,7 +10,7 @@ use rustical_dav::resource::{PrincipalUri, Resource, ResourceName};
|
||||
use rustical_dav::xml::{Resourcetype, ResourcetypeInner, SupportedReportSet};
|
||||
use rustical_dav_push::DavPushExtension;
|
||||
use rustical_store::Addressbook;
|
||||
use rustical_store::auth::User;
|
||||
use rustical_store::auth::Principal;
|
||||
|
||||
#[derive(Clone, Debug, From, Into)]
|
||||
pub struct AddressbookResource(pub(crate) Addressbook);
|
||||
@@ -36,7 +36,7 @@ impl DavPushExtension for AddressbookResource {
|
||||
impl Resource for AddressbookResource {
|
||||
type Prop = AddressbookPropWrapper;
|
||||
type Error = Error;
|
||||
type Principal = User;
|
||||
type Principal = Principal;
|
||||
|
||||
fn is_collection(&self) -> bool {
|
||||
true
|
||||
@@ -52,7 +52,7 @@ impl Resource for AddressbookResource {
|
||||
fn get_prop(
|
||||
&self,
|
||||
puri: &impl PrincipalUri,
|
||||
user: &User,
|
||||
user: &Principal,
|
||||
prop: &AddressbookPropWrapperName,
|
||||
) -> Result<Self::Prop, Self::Error> {
|
||||
Ok(match prop {
|
||||
@@ -138,7 +138,7 @@ impl Resource for AddressbookResource {
|
||||
Some(&self.0.principal)
|
||||
}
|
||||
|
||||
fn get_user_privileges(&self, user: &User) -> Result<UserPrivilegeSet, Self::Error> {
|
||||
fn get_user_privileges(&self, user: &Principal) -> Result<UserPrivilegeSet, Self::Error> {
|
||||
Ok(UserPrivilegeSet::owner_only(
|
||||
user.is_principal(&self.0.principal),
|
||||
))
|
||||
|
||||
@@ -14,7 +14,7 @@ use axum::handler::Handler;
|
||||
use axum::response::Response;
|
||||
use futures_util::future::BoxFuture;
|
||||
use rustical_dav::resource::{AxumMethods, ResourceService};
|
||||
use rustical_store::auth::User;
|
||||
use rustical_store::auth::Principal;
|
||||
use rustical_store::{AddressbookStore, SubscriptionStore};
|
||||
use std::convert::Infallible;
|
||||
use std::sync::Arc;
|
||||
@@ -51,7 +51,7 @@ impl<AS: AddressbookStore, S: SubscriptionStore> ResourceService
|
||||
type PathComponents = (String, String); // principal, addressbook_id
|
||||
type Resource = AddressbookResource;
|
||||
type Error = Error;
|
||||
type Principal = User;
|
||||
type Principal = Principal;
|
||||
type PrincipalUri = CardDavPrincipalUri;
|
||||
|
||||
const DAV_HEADER: &str = "1, 3, access-control, addressbook, webdav-push";
|
||||
|
||||
@@ -9,7 +9,7 @@ use rustical_dav::resources::RootResourceService;
|
||||
use rustical_store::auth::middleware::AuthenticationLayer;
|
||||
use rustical_store::{
|
||||
AddressbookStore, SubscriptionStore,
|
||||
auth::{AuthenticationProvider, User},
|
||||
auth::{AuthenticationProvider, Principal},
|
||||
};
|
||||
use std::sync::Arc;
|
||||
|
||||
@@ -44,7 +44,9 @@ pub fn carddav_router<AP: AuthenticationProvider, A: AddressbookStore, S: Subscr
|
||||
Router::new()
|
||||
.nest(
|
||||
prefix,
|
||||
RootResourceService::<_, User, CardDavPrincipalUri>::new(principal_service.clone())
|
||||
RootResourceService::<_, Principal, CardDavPrincipalUri>::new(
|
||||
principal_service.clone(),
|
||||
)
|
||||
.axum_router()
|
||||
.layer(AuthenticationLayer::new(auth_provider))
|
||||
.layer(Extension(CardDavPrincipalUri(prefix))),
|
||||
|
||||
@@ -5,7 +5,7 @@ use rustical_dav::resource::{PrincipalUri, Resource, ResourceName};
|
||||
use rustical_dav::xml::{
|
||||
GroupMemberSet, GroupMembership, HrefElement, Resourcetype, ResourcetypeInner,
|
||||
};
|
||||
use rustical_store::auth::User;
|
||||
use rustical_store::auth::Principal;
|
||||
|
||||
mod service;
|
||||
pub use service::*;
|
||||
@@ -14,7 +14,7 @@ pub use prop::*;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct PrincipalResource {
|
||||
principal: User,
|
||||
principal: Principal,
|
||||
members: Vec<String>,
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ impl ResourceName for PrincipalResource {
|
||||
impl Resource for PrincipalResource {
|
||||
type Prop = PrincipalPropWrapper;
|
||||
type Error = Error;
|
||||
type Principal = User;
|
||||
type Principal = Principal;
|
||||
|
||||
fn is_collection(&self) -> bool {
|
||||
true
|
||||
@@ -43,7 +43,7 @@ impl Resource for PrincipalResource {
|
||||
fn get_prop(
|
||||
&self,
|
||||
puri: &impl PrincipalUri,
|
||||
user: &User,
|
||||
user: &Principal,
|
||||
prop: &PrincipalPropWrapperName,
|
||||
) -> Result<Self::Prop, Self::Error> {
|
||||
let principal_href = HrefElement::new(puri.principal_uri(&self.principal.id));
|
||||
@@ -99,7 +99,7 @@ impl Resource for PrincipalResource {
|
||||
Some(&self.principal.id)
|
||||
}
|
||||
|
||||
fn get_user_privileges(&self, user: &User) -> Result<UserPrivilegeSet, Self::Error> {
|
||||
fn get_user_privileges(&self, user: &Principal) -> Result<UserPrivilegeSet, Self::Error> {
|
||||
Ok(UserPrivilegeSet::owner_only(
|
||||
user.is_principal(&self.principal.id),
|
||||
))
|
||||
|
||||
@@ -5,7 +5,7 @@ use crate::{CardDavPrincipalUri, Error};
|
||||
use async_trait::async_trait;
|
||||
use axum::Router;
|
||||
use rustical_dav::resource::{AxumMethods, ResourceService};
|
||||
use rustical_store::auth::{AuthenticationProvider, User};
|
||||
use rustical_store::auth::{AuthenticationProvider, Principal};
|
||||
use rustical_store::{AddressbookStore, SubscriptionStore};
|
||||
use std::sync::Arc;
|
||||
|
||||
@@ -51,7 +51,7 @@ impl<A: AddressbookStore, AP: AuthenticationProvider, S: SubscriptionStore> Reso
|
||||
type MemberType = AddressbookResource;
|
||||
type Resource = PrincipalResource;
|
||||
type Error = Error;
|
||||
type Principal = User;
|
||||
type Principal = Principal;
|
||||
type PrincipalUri = CardDavPrincipalUri;
|
||||
|
||||
const DAV_HEADER: &str = "1, 3, access-control, addressbook";
|
||||
|
||||
@@ -13,7 +13,7 @@ use axum_extra::{TypedHeader, extract::Host};
|
||||
use chrono::{Duration, Utc};
|
||||
use headers::UserAgent;
|
||||
use http::StatusCode;
|
||||
use rustical_store::auth::{AuthenticationProvider, User};
|
||||
use rustical_store::auth::{AuthenticationProvider, Principal};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::sync::Arc;
|
||||
use tracing::instrument;
|
||||
@@ -101,7 +101,7 @@ struct NextcloudLoginPage {
|
||||
pub(crate) async fn get_nextcloud_flow(
|
||||
Extension(state): Extension<Arc<NextcloudFlows>>,
|
||||
Path(flow_id): Path<String>,
|
||||
user: User,
|
||||
user: Principal,
|
||||
) -> Result<Response, rustical_store::Error> {
|
||||
if let Some(flow) = state.flows.read().await.get(&flow_id) {
|
||||
Ok(Html(
|
||||
@@ -131,7 +131,7 @@ struct NextcloudLoginSuccessPage {
|
||||
|
||||
#[instrument(skip(state))]
|
||||
pub(crate) async fn post_nextcloud_flow(
|
||||
user: User,
|
||||
user: Principal,
|
||||
Extension(state): Extension<Arc<NextcloudFlows>>,
|
||||
Path(flow_id): Path<String>,
|
||||
Host(host): Host,
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::sync::Arc;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use rustical_oidc::UserStore;
|
||||
use rustical_store::auth::{AuthenticationProvider, User};
|
||||
use rustical_store::auth::{AuthenticationProvider, Principal};
|
||||
|
||||
pub struct OidcUserStore<AP: AuthenticationProvider>(pub Arc<AP>);
|
||||
|
||||
@@ -23,7 +23,7 @@ impl<AP: AuthenticationProvider> UserStore for OidcUserStore<AP> {
|
||||
async fn insert_user(&self, id: &str) -> Result<(), Self::Error> {
|
||||
self.0
|
||||
.insert_principal(
|
||||
User {
|
||||
Principal {
|
||||
id: id.to_owned(),
|
||||
displayname: None,
|
||||
principal_type: Default::default(),
|
||||
|
||||
@@ -10,7 +10,7 @@ use axum::{
|
||||
use axum_extra::TypedHeader;
|
||||
use headers::Referer;
|
||||
use http::StatusCode;
|
||||
use rustical_store::{Addressbook, AddressbookStore, auth::User};
|
||||
use rustical_store::{Addressbook, AddressbookStore, auth::Principal};
|
||||
|
||||
#[derive(Template, WebTemplate)]
|
||||
#[template(path = "pages/addressbook.html")]
|
||||
@@ -21,7 +21,7 @@ struct AddressbookPage {
|
||||
pub async fn route_addressbook<AS: AddressbookStore>(
|
||||
Path((owner, addrbook_id)): Path<(String, String)>,
|
||||
Extension(store): Extension<Arc<AS>>,
|
||||
user: User,
|
||||
user: Principal,
|
||||
) -> Result<Response, rustical_store::Error> {
|
||||
if !user.is_principal(&owner) {
|
||||
return Ok(StatusCode::UNAUTHORIZED.into_response());
|
||||
@@ -35,7 +35,7 @@ pub async fn route_addressbook<AS: AddressbookStore>(
|
||||
pub async fn route_addressbook_restore<AS: AddressbookStore>(
|
||||
Path((owner, addressbook_id)): Path<(String, String)>,
|
||||
Extension(store): Extension<Arc<AS>>,
|
||||
user: User,
|
||||
user: Principal,
|
||||
referer: Option<TypedHeader<Referer>>,
|
||||
) -> Result<Response, rustical_store::Error> {
|
||||
if !user.is_principal(&owner) {
|
||||
@@ -51,7 +51,7 @@ pub async fn route_addressbook_restore<AS: AddressbookStore>(
|
||||
pub async fn route_delete_addressbook<AS: AddressbookStore>(
|
||||
Path((owner, addressbook_id)): Path<(String, String)>,
|
||||
Extension(store): Extension<Arc<AS>>,
|
||||
user: User,
|
||||
user: Principal,
|
||||
) -> Result<Response, rustical_store::Error> {
|
||||
if !user.is_principal(&owner) {
|
||||
return Ok(StatusCode::UNAUTHORIZED.into_response());
|
||||
|
||||
@@ -12,7 +12,7 @@ use headers::{ContentType, HeaderMapExt};
|
||||
use http::{HeaderValue, StatusCode, header};
|
||||
use percent_encoding::{CONTROLS, utf8_percent_encode};
|
||||
use rand::{Rng, distr::Alphanumeric};
|
||||
use rustical_store::auth::{AuthenticationProvider, User};
|
||||
use rustical_store::auth::{AuthenticationProvider, Principal};
|
||||
use serde::Deserialize;
|
||||
use uuid::Uuid;
|
||||
|
||||
@@ -47,7 +47,7 @@ pub(crate) struct PostAppTokenForm {
|
||||
}
|
||||
|
||||
pub async fn route_post_app_token<AP: AuthenticationProvider>(
|
||||
user: User,
|
||||
user: Principal,
|
||||
Extension(auth_provider): Extension<Arc<AP>>,
|
||||
Path(user_id): Path<String>,
|
||||
Host(hostname): Host,
|
||||
@@ -96,7 +96,7 @@ pub async fn route_post_app_token<AP: AuthenticationProvider>(
|
||||
}
|
||||
|
||||
pub async fn route_delete_app_token<AP: AuthenticationProvider>(
|
||||
user: User,
|
||||
user: Principal,
|
||||
Extension(auth_provider): Extension<Arc<AP>>,
|
||||
Path((user_id, token_id)): Path<(String, String)>,
|
||||
) -> Result<Redirect, rustical_store::Error> {
|
||||
|
||||
@@ -10,7 +10,7 @@ use axum::{
|
||||
use axum_extra::TypedHeader;
|
||||
use headers::Referer;
|
||||
use http::StatusCode;
|
||||
use rustical_store::{Calendar, CalendarStore, auth::User};
|
||||
use rustical_store::{Calendar, CalendarStore, auth::Principal};
|
||||
|
||||
#[derive(Template, WebTemplate)]
|
||||
#[template(path = "pages/calendar.html")]
|
||||
@@ -21,7 +21,7 @@ struct CalendarPage {
|
||||
pub async fn route_calendar<C: CalendarStore>(
|
||||
Path((owner, cal_id)): Path<(String, String)>,
|
||||
Extension(store): Extension<Arc<C>>,
|
||||
user: User,
|
||||
user: Principal,
|
||||
) -> Result<Response, rustical_store::Error> {
|
||||
if !user.is_principal(&owner) {
|
||||
return Ok(StatusCode::UNAUTHORIZED.into_response());
|
||||
@@ -35,7 +35,7 @@ pub async fn route_calendar<C: CalendarStore>(
|
||||
pub async fn route_calendar_restore<CS: CalendarStore>(
|
||||
Path((owner, cal_id)): Path<(String, String)>,
|
||||
Extension(store): Extension<Arc<CS>>,
|
||||
user: User,
|
||||
user: Principal,
|
||||
referer: Option<TypedHeader<Referer>>,
|
||||
) -> Result<Response, rustical_store::Error> {
|
||||
if !user.is_principal(&owner) {
|
||||
@@ -51,7 +51,7 @@ pub async fn route_calendar_restore<CS: CalendarStore>(
|
||||
pub async fn route_delete_calendar<C: CalendarStore>(
|
||||
Path((owner, cal_id)): Path<(String, String)>,
|
||||
Extension(store): Extension<Arc<C>>,
|
||||
user: User,
|
||||
user: Principal,
|
||||
) -> Result<Response, rustical_store::Error> {
|
||||
if !user.is_principal(&owner) {
|
||||
return Ok(StatusCode::UNAUTHORIZED.into_response());
|
||||
|
||||
@@ -12,13 +12,13 @@ use headers::UserAgent;
|
||||
use http::StatusCode;
|
||||
use rustical_store::{
|
||||
Addressbook, AddressbookStore, Calendar, CalendarStore,
|
||||
auth::{AuthenticationProvider, User, user::AppToken},
|
||||
auth::{AppToken, AuthenticationProvider, Principal},
|
||||
};
|
||||
|
||||
#[derive(Template, WebTemplate)]
|
||||
#[template(path = "pages/user.html")]
|
||||
pub struct UserPage {
|
||||
pub user: User,
|
||||
pub user: Principal,
|
||||
pub app_tokens: Vec<AppToken>,
|
||||
pub calendars: Vec<Calendar>,
|
||||
pub deleted_calendars: Vec<Calendar>,
|
||||
@@ -39,7 +39,7 @@ pub async fn route_user_named<
|
||||
Extension(auth_provider): Extension<Arc<AP>>,
|
||||
TypedHeader(user_agent): TypedHeader<UserAgent>,
|
||||
Host(host): Host,
|
||||
user: User,
|
||||
user: Principal,
|
||||
) -> impl IntoResponse {
|
||||
if user_id != user.id {
|
||||
return StatusCode::UNAUTHORIZED.into_response();
|
||||
@@ -81,11 +81,11 @@ pub async fn route_user_named<
|
||||
.into_response()
|
||||
}
|
||||
|
||||
pub async fn route_get_home(user: User) -> Redirect {
|
||||
pub async fn route_get_home(user: Principal) -> Redirect {
|
||||
Redirect::to(&format!("/frontend/user/{}", user.id))
|
||||
}
|
||||
|
||||
pub async fn route_root(user: Option<User>) -> Redirect {
|
||||
pub async fn route_root(user: Option<Principal>) -> Redirect {
|
||||
match user {
|
||||
Some(user) => route_get_home(user).await,
|
||||
None => Redirect::to("/frontend/login"),
|
||||
|
||||
@@ -1,17 +1,26 @@
|
||||
pub mod middleware;
|
||||
pub mod user;
|
||||
mod principal;
|
||||
use crate::error::Error;
|
||||
use async_trait::async_trait;
|
||||
|
||||
pub use principal::{AppToken, Principal, PrincipalType};
|
||||
|
||||
#[async_trait]
|
||||
pub trait AuthenticationProvider: Send + Sync + 'static {
|
||||
async fn get_principals(&self) -> Result<Vec<User>, crate::Error>;
|
||||
async fn get_principal(&self, id: &str) -> Result<Option<User>, crate::Error>;
|
||||
async fn get_principals(&self) -> Result<Vec<Principal>, crate::Error>;
|
||||
async fn get_principal(&self, id: &str) -> Result<Option<Principal>, crate::Error>;
|
||||
async fn remove_principal(&self, id: &str) -> Result<(), crate::Error>;
|
||||
async fn insert_principal(&self, user: User, overwrite: bool) -> Result<(), crate::Error>;
|
||||
async fn validate_password(&self, user_id: &str, password: &str)
|
||||
-> Result<Option<User>, Error>;
|
||||
async fn validate_app_token(&self, user_id: &str, token: &str) -> Result<Option<User>, Error>;
|
||||
async fn insert_principal(&self, user: Principal, overwrite: bool) -> Result<(), crate::Error>;
|
||||
async fn validate_password(
|
||||
&self,
|
||||
user_id: &str,
|
||||
password: &str,
|
||||
) -> Result<Option<Principal>, Error>;
|
||||
async fn validate_app_token(
|
||||
&self,
|
||||
user_id: &str,
|
||||
token: &str,
|
||||
) -> Result<Option<Principal>, Error>;
|
||||
/// Returns a token identifier
|
||||
async fn add_app_token(
|
||||
&self,
|
||||
@@ -28,5 +37,3 @@ pub trait AuthenticationProvider: Send + Sync + 'static {
|
||||
}
|
||||
|
||||
pub use middleware::AuthenticationMiddleware;
|
||||
use user::AppToken;
|
||||
pub use user::User;
|
||||
|
||||
@@ -78,8 +78,7 @@ pub struct AppToken {
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
// TODO: Rename this to Principal
|
||||
pub struct User {
|
||||
pub struct Principal {
|
||||
pub id: String,
|
||||
pub displayname: Option<String>,
|
||||
#[serde(default)]
|
||||
@@ -89,7 +88,7 @@ pub struct User {
|
||||
pub memberships: Vec<String>,
|
||||
}
|
||||
|
||||
impl User {
|
||||
impl Principal {
|
||||
/// Returns true if the user is either
|
||||
/// - the principal itself
|
||||
/// - has full access to the prinicpal (is member)
|
||||
@@ -114,7 +113,7 @@ impl User {
|
||||
}
|
||||
}
|
||||
|
||||
impl rustical_dav::Principal for User {
|
||||
impl rustical_dav::Principal for Principal {
|
||||
fn get_id(&self) -> &str {
|
||||
&self.id
|
||||
}
|
||||
@@ -134,7 +133,7 @@ impl IntoResponse for UnauthorizedError {
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Send + Sync + Clone> FromRequestParts<S> for User {
|
||||
impl<S: Send + Sync + Clone> FromRequestParts<S> for Principal {
|
||||
type Rejection = UnauthorizedError;
|
||||
|
||||
async fn from_request_parts(
|
||||
@@ -149,7 +148,7 @@ impl<S: Send + Sync + Clone> FromRequestParts<S> for User {
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Send + Sync + Clone> OptionalFromRequestParts<S> for User {
|
||||
impl<S: Send + Sync + Clone> OptionalFromRequestParts<S> for Principal {
|
||||
type Rejection = Infallible;
|
||||
|
||||
async fn from_request_parts(
|
||||
@@ -7,7 +7,7 @@ use pbkdf2::{
|
||||
};
|
||||
use rustical_store::{
|
||||
Error, Secret,
|
||||
auth::{AuthenticationProvider, User, user::AppToken},
|
||||
auth::{AppToken, AuthenticationProvider, Principal},
|
||||
};
|
||||
use sqlx::{SqlitePool, types::Json};
|
||||
use tracing::instrument;
|
||||
@@ -21,11 +21,11 @@ struct PrincipalRow {
|
||||
memberships: Option<Json<Vec<Option<String>>>>,
|
||||
}
|
||||
|
||||
impl TryFrom<PrincipalRow> for User {
|
||||
impl TryFrom<PrincipalRow> for Principal {
|
||||
type Error = Error;
|
||||
|
||||
fn try_from(value: PrincipalRow) -> Result<Self, Self::Error> {
|
||||
Ok(User {
|
||||
Ok(Principal {
|
||||
id: value.id,
|
||||
displayname: value.displayname,
|
||||
password: value.password_hash.map(Secret::from),
|
||||
@@ -49,8 +49,8 @@ pub struct SqlitePrincipalStore {
|
||||
#[async_trait]
|
||||
impl AuthenticationProvider for SqlitePrincipalStore {
|
||||
#[instrument]
|
||||
async fn get_principals(&self) -> Result<Vec<User>, Error> {
|
||||
let result: Result<Vec<User>, Error> = sqlx::query_as!(
|
||||
async fn get_principals(&self) -> Result<Vec<Principal>, Error> {
|
||||
let result: Result<Vec<Principal>, Error> = sqlx::query_as!(
|
||||
PrincipalRow,
|
||||
r#"
|
||||
SELECT id, displayname, principal_type, password_hash, json_group_array(member_of) AS "memberships: Json<Vec<Option<String>>>"
|
||||
@@ -63,13 +63,13 @@ impl AuthenticationProvider for SqlitePrincipalStore {
|
||||
.await
|
||||
.map_err(crate::Error::from)?
|
||||
.into_iter()
|
||||
.map(User::try_from)
|
||||
.map(Principal::try_from)
|
||||
.collect();
|
||||
Ok(result?)
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
async fn get_principal(&self, id: &str) -> Result<Option<User>, Error> {
|
||||
async fn get_principal(&self, id: &str) -> Result<Option<Principal>, Error> {
|
||||
let row= sqlx::query_as!(
|
||||
PrincipalRow,
|
||||
r#"
|
||||
@@ -83,7 +83,7 @@ impl AuthenticationProvider for SqlitePrincipalStore {
|
||||
.fetch_optional(&self.db)
|
||||
.await
|
||||
.map_err(crate::Error::from)?
|
||||
.map(User::try_from);
|
||||
.map(Principal::try_from);
|
||||
if let Some(row) = row {
|
||||
Ok(Some(row?))
|
||||
} else {
|
||||
@@ -103,7 +103,7 @@ impl AuthenticationProvider for SqlitePrincipalStore {
|
||||
#[instrument]
|
||||
async fn insert_principal(
|
||||
&self,
|
||||
user: User,
|
||||
user: Principal,
|
||||
overwrite: bool,
|
||||
) -> Result<(), rustical_store::Error> {
|
||||
// Would be cleaner to put this into a transaction but for now it will be fine
|
||||
@@ -142,7 +142,11 @@ impl AuthenticationProvider for SqlitePrincipalStore {
|
||||
}
|
||||
|
||||
#[instrument(skip(token))]
|
||||
async fn validate_app_token(&self, user_id: &str, token: &str) -> Result<Option<User>, Error> {
|
||||
async fn validate_app_token(
|
||||
&self,
|
||||
user_id: &str,
|
||||
token: &str,
|
||||
) -> Result<Option<Principal>, Error> {
|
||||
for app_token in &self.get_app_tokens(user_id).await? {
|
||||
if password_auth::verify_password(token, app_token.token.as_ref()).is_ok() {
|
||||
return self.get_principal(user_id).await;
|
||||
@@ -169,8 +173,8 @@ impl AuthenticationProvider for SqlitePrincipalStore {
|
||||
&self,
|
||||
user_id: &str,
|
||||
password_input: &str,
|
||||
) -> Result<Option<User>, Error> {
|
||||
let user: User = match self.get_principal(user_id).await? {
|
||||
) -> Result<Option<Principal>, Error> {
|
||||
let user: Principal = match self.get_principal(user_id).await? {
|
||||
Some(user) => user,
|
||||
None => return Ok(None),
|
||||
};
|
||||
|
||||
@@ -6,7 +6,7 @@ use figment::{
|
||||
providers::{Env, Format, Toml},
|
||||
};
|
||||
use password_hash::{PasswordHasher, SaltString, rand_core::OsRng};
|
||||
use rustical_store::auth::{AuthenticationProvider, User, user::PrincipalType};
|
||||
use rustical_store::auth::{AuthenticationProvider, Principal, PrincipalType};
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
pub struct PrincipalsArgs {
|
||||
@@ -99,7 +99,7 @@ pub async fn cmd_principals(args: PrincipalsArgs) -> anyhow::Result<()> {
|
||||
};
|
||||
principal_store
|
||||
.insert_principal(
|
||||
User {
|
||||
Principal {
|
||||
id,
|
||||
displayname: name,
|
||||
principal_type: principal_type.unwrap_or_default(),
|
||||
|
||||
Reference in New Issue
Block a user