Import upstream v0.16.22, stripped
Upstream commit: 474dd0229cb20cf513036619781ed97bd8073c3f Enterprise-only files removed or emptied: 63 Enterprise-only snippets removed: 117 in 50 files Dangling module declarations removed: 5 Cargo edits turning enterprise off: 14 Verification: clean Enterprise feature gates left for rebuilt features: 19 in 18 files Produced by tools/fork/strip.py. The full report is in docs/fork/strip-reports/ on main.
This commit is contained in:
@@ -0,0 +1,426 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Stalwart Labs LLC <[email protected]>
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
use crate::{
|
||||
responses::XmlEscape,
|
||||
schema::{
|
||||
Namespace, Namespaces,
|
||||
property::{DavProperty, Privilege},
|
||||
response::{
|
||||
Ace, AclRestrictions, GrantDeny, Href, List, Principal, PrincipalSearchProperty,
|
||||
PrincipalSearchPropertySet, RequiredPrincipal, Resource, SupportedPrivilege,
|
||||
},
|
||||
},
|
||||
};
|
||||
use std::fmt::Display;
|
||||
|
||||
impl Display for SupportedPrivilege {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "<D:supported-privilege>{}", self.privilege)?;
|
||||
if self.abstract_ {
|
||||
write!(f, "<D:abstract/>")?;
|
||||
}
|
||||
write!(f, "<D:description>")?;
|
||||
self.description.write_escaped_to(f)?;
|
||||
write!(
|
||||
f,
|
||||
"</D:description>{}</D:supported-privilege>",
|
||||
self.supported_privilege
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl SupportedPrivilege {
|
||||
pub fn new(privilege: Privilege, description: impl Into<String>) -> Self {
|
||||
SupportedPrivilege {
|
||||
privilege,
|
||||
abstract_: false,
|
||||
description: description.into(),
|
||||
supported_privilege: List(vec![]),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_abstract(mut self) -> Self {
|
||||
self.abstract_ = true;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_supported_privilege(mut self, supported_privilege: SupportedPrivilege) -> Self {
|
||||
self.supported_privilege.0.push(supported_privilege);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_opt_supported_privilege(
|
||||
mut self,
|
||||
supported_privilege: Option<SupportedPrivilege>,
|
||||
) -> Self {
|
||||
if let Some(supported_privilege) = supported_privilege {
|
||||
self.supported_privilege.0.push(supported_privilege);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
pub fn all_privileges(is_calendar: bool) -> SupportedPrivilege {
|
||||
SupportedPrivilege::new(Privilege::All, "Any operation")
|
||||
.with_abstract()
|
||||
.with_supported_privilege(
|
||||
SupportedPrivilege::new(Privilege::Read, "Read objects").with_supported_privilege(
|
||||
SupportedPrivilege::new(
|
||||
Privilege::ReadCurrentUserPrivilegeSet,
|
||||
"Read current user privileges",
|
||||
),
|
||||
),
|
||||
)
|
||||
.with_supported_privilege(
|
||||
SupportedPrivilege::new(Privilege::Write, "Write objects")
|
||||
.with_supported_privilege(SupportedPrivilege::new(
|
||||
Privilege::WriteProperties,
|
||||
"Write properties",
|
||||
))
|
||||
.with_supported_privilege(SupportedPrivilege::new(
|
||||
Privilege::WriteContent,
|
||||
"Write object contents",
|
||||
))
|
||||
.with_supported_privilege(SupportedPrivilege::new(
|
||||
Privilege::Bind,
|
||||
"Add resources to a collection",
|
||||
))
|
||||
.with_supported_privilege(SupportedPrivilege::new(
|
||||
Privilege::Unbind,
|
||||
"Remove resources from a collection",
|
||||
))
|
||||
.with_supported_privilege(SupportedPrivilege::new(
|
||||
Privilege::Unlock,
|
||||
"Unlock resources",
|
||||
)),
|
||||
)
|
||||
.with_supported_privilege(SupportedPrivilege::new(Privilege::ReadAcl, "Read ACL"))
|
||||
.with_supported_privilege(SupportedPrivilege::new(Privilege::WriteAcl, "Write ACL"))
|
||||
.with_opt_supported_privilege((is_calendar).then(|| {
|
||||
SupportedPrivilege::new(Privilege::ReadFreeBusy, "Read free/busy information")
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn all_scheduling_privileges(is_inbox: bool) -> SupportedPrivilege {
|
||||
let privilege = SupportedPrivilege::new(Privilege::All, "Any operation")
|
||||
.with_abstract()
|
||||
.with_supported_privilege(
|
||||
SupportedPrivilege::new(Privilege::Read, "Read objects").with_supported_privilege(
|
||||
SupportedPrivilege::new(
|
||||
Privilege::ReadCurrentUserPrivilegeSet,
|
||||
"Read current user privileges",
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
if is_inbox {
|
||||
privilege.with_supported_privilege(
|
||||
SupportedPrivilege::new(
|
||||
Privilege::ScheduleDeliver,
|
||||
"Deliver calendar scheduling messages",
|
||||
)
|
||||
.with_supported_privilege(SupportedPrivilege::new(
|
||||
Privilege::ScheduleDeliverInvite,
|
||||
"Deliver calendar scheduling invites",
|
||||
))
|
||||
.with_supported_privilege(SupportedPrivilege::new(
|
||||
Privilege::ScheduleDeliverReply,
|
||||
"Deliver calendar scheduling replies",
|
||||
))
|
||||
.with_supported_privilege(SupportedPrivilege::new(
|
||||
Privilege::ScheduleQueryFreeBusy,
|
||||
"Query free/busy information",
|
||||
)),
|
||||
)
|
||||
} else {
|
||||
privilege.with_supported_privilege(
|
||||
SupportedPrivilege::new(
|
||||
Privilege::ScheduleSend,
|
||||
"Send calendar scheduling messages",
|
||||
)
|
||||
.with_supported_privilege(SupportedPrivilege::new(
|
||||
Privilege::ScheduleSendInvite,
|
||||
"Send calendar scheduling invites",
|
||||
))
|
||||
.with_supported_privilege(SupportedPrivilege::new(
|
||||
Privilege::ScheduleSendReply,
|
||||
"Send calendar scheduling replies",
|
||||
))
|
||||
.with_supported_privilege(SupportedPrivilege::new(
|
||||
Privilege::ScheduleSendFreeBusy,
|
||||
"Send free/busy information",
|
||||
)),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Ace {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "<D:ace>")?;
|
||||
if self.invert {
|
||||
write!(f, "<D:invert>")?;
|
||||
}
|
||||
self.principal.fmt(f)?;
|
||||
if self.invert {
|
||||
write!(f, "</D:invert>")?;
|
||||
}
|
||||
self.grant_deny.fmt(f)?;
|
||||
if self.protected {
|
||||
write!(f, "<D:protected/>")?;
|
||||
}
|
||||
if let Some(inherited) = &self.inherited {
|
||||
write!(f, "<D:inherited>")?;
|
||||
inherited.fmt(f)?;
|
||||
write!(f, "</D:inherited>")?;
|
||||
}
|
||||
write!(f, "</D:ace>")
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Principal {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "<D:principal>")?;
|
||||
match self {
|
||||
Principal::Href(href) => href.fmt(f),
|
||||
Principal::Response(response) => response.fmt(f),
|
||||
Principal::All => "<D:all/>".fmt(f),
|
||||
Principal::Authenticated => "<D:authenticated/>".fmt(f),
|
||||
Principal::Unauthenticated => "<D:unauthenticated/>".fmt(f),
|
||||
Principal::Property(property) => {
|
||||
write!(f, "<D:property>{}</D:property>", property)
|
||||
}
|
||||
Principal::Self_ => "<D:self/>".fmt(f),
|
||||
}?;
|
||||
write!(f, "</D:principal>")
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for GrantDeny {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
GrantDeny::Grant(privileges) => {
|
||||
write!(f, "<D:grant>")?;
|
||||
privileges.fmt(f)?;
|
||||
write!(f, "</D:grant>")
|
||||
}
|
||||
GrantDeny::Deny(privileges) => {
|
||||
write!(f, "<D:deny>")?;
|
||||
privileges.fmt(f)?;
|
||||
write!(f, "</D:deny>")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for AclRestrictions {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
if self.grant_only {
|
||||
write!(f, "<D:grant-only/>")?;
|
||||
}
|
||||
if self.no_invert {
|
||||
write!(f, "<D:no-invert/>")?;
|
||||
}
|
||||
if self.deny_before_grant {
|
||||
write!(f, "<D:deny-before-grant/>")?;
|
||||
}
|
||||
if let Some(required_principal) = &self.required_principal {
|
||||
required_principal.fmt(f)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for RequiredPrincipal {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "<D:required-principal>")?;
|
||||
match self {
|
||||
RequiredPrincipal::All => "<D:all/>".fmt(f)?,
|
||||
RequiredPrincipal::Authenticated => "<D:authenticated/>".fmt(f)?,
|
||||
RequiredPrincipal::Unauthenticated => "<D:unauthenticated/>".fmt(f)?,
|
||||
RequiredPrincipal::Self_ => "<D:self/>".fmt(f)?,
|
||||
RequiredPrincipal::Href(hrefs) => hrefs.fmt(f)?,
|
||||
RequiredPrincipal::Property(properties) => {
|
||||
for property in properties {
|
||||
write!(f, "<D:property>{}</D:property>", property)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
write!(f, "</D:required-principal>")
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Privilege {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Privilege::Read => "<D:privilege><D:read/></D:privilege>".fmt(f),
|
||||
Privilege::Write => "<D:privilege><D:write/></D:privilege>".fmt(f),
|
||||
Privilege::WriteProperties => "<D:privilege><D:write-properties/></D:privilege>".fmt(f),
|
||||
Privilege::WriteContent => "<D:privilege><D:write-content/></D:privilege>".fmt(f),
|
||||
Privilege::Unlock => "<D:privilege><D:unlock/></D:privilege>".fmt(f),
|
||||
Privilege::ReadAcl => "<D:privilege><D:read-acl/></D:privilege>".fmt(f),
|
||||
Privilege::ReadCurrentUserPrivilegeSet => {
|
||||
"<D:privilege><D:read-current-user-privilege-set/></D:privilege>".fmt(f)
|
||||
}
|
||||
Privilege::WriteAcl => "<D:privilege><D:write-acl/></D:privilege>".fmt(f),
|
||||
Privilege::Bind => "<D:privilege><D:bind/></D:privilege>".fmt(f),
|
||||
Privilege::Unbind => "<D:privilege><D:unbind/></D:privilege>".fmt(f),
|
||||
Privilege::All => "<D:privilege><D:all/></D:privilege>".fmt(f),
|
||||
Privilege::ReadFreeBusy => "<D:privilege><A:read-free-busy/></D:privilege>".fmt(f),
|
||||
Privilege::ScheduleDeliver => "<D:privilege><A:schedule-deliver/></D:privilege>".fmt(f),
|
||||
Privilege::ScheduleDeliverInvite => {
|
||||
"<D:privilege><A:schedule-deliver-invite/></D:privilege>".fmt(f)
|
||||
}
|
||||
Privilege::ScheduleDeliverReply => {
|
||||
"<D:privilege><A:schedule-deliver-reply/></D:privilege>".fmt(f)
|
||||
}
|
||||
Privilege::ScheduleQueryFreeBusy => {
|
||||
"<D:privilege><A:schedule-query-freebusy/></D:privilege>".fmt(f)
|
||||
}
|
||||
Privilege::ScheduleSend => "<D:privilege><A:schedule-send/></D:privilege>".fmt(f),
|
||||
Privilege::ScheduleSendInvite => {
|
||||
"<D:privilege><A:schedule-send-invite/></D:privilege>".fmt(f)
|
||||
}
|
||||
Privilege::ScheduleSendReply => {
|
||||
"<D:privilege><A:schedule-send-reply/></D:privilege>".fmt(f)
|
||||
}
|
||||
Privilege::ScheduleSendFreeBusy => {
|
||||
"<D:privilege><A:schedule-send-freebusy/></D:privilege>".fmt(f)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Resource {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"<D:resource>{}{}</D:resource>",
|
||||
self.href, self.privilege
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for PrincipalSearchPropertySet {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>")?;
|
||||
write!(
|
||||
f,
|
||||
"<D:principal-search-property-set {}>{}</D:principal-search-property-set>",
|
||||
self.namespaces, self.properties
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for PrincipalSearchProperty {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"<D:principal-search-property><D:prop>{}</D:prop>",
|
||||
self.name
|
||||
)?;
|
||||
write!(
|
||||
f,
|
||||
"<D:description>{}</D:description></D:principal-search-property>",
|
||||
self.description
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Resource {
|
||||
pub fn new(href: impl Into<String>, privilege: Privilege) -> Self {
|
||||
Resource {
|
||||
href: Href(href.into()),
|
||||
privilege,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PrincipalSearchPropertySet {
|
||||
pub fn new(properties: Vec<PrincipalSearchProperty>) -> Self {
|
||||
PrincipalSearchPropertySet {
|
||||
namespaces: Namespaces::default(),
|
||||
properties: List(properties),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_namespace(mut self, namespace: Namespace) -> Self {
|
||||
self.namespaces.set(namespace);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl PrincipalSearchProperty {
|
||||
pub fn new(name: impl Into<DavProperty>, description: impl Into<String>) -> Self {
|
||||
PrincipalSearchProperty {
|
||||
name: name.into(),
|
||||
description: description.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Ace {
|
||||
pub fn new(principal: Principal, grant_deny: GrantDeny) -> Self {
|
||||
Ace {
|
||||
principal,
|
||||
invert: false,
|
||||
grant_deny,
|
||||
protected: false,
|
||||
inherited: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_invert(mut self) -> Self {
|
||||
self.invert = true;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_protected(mut self) -> Self {
|
||||
self.protected = true;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_inherited(mut self, inherited: impl Into<String>) -> Self {
|
||||
self.inherited = Some(Href(inherited.into()));
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl GrantDeny {
|
||||
pub fn grant(privileges: Vec<Privilege>) -> Self {
|
||||
GrantDeny::Grant(List(privileges))
|
||||
}
|
||||
|
||||
pub fn deny(privileges: Vec<Privilege>) -> Self {
|
||||
GrantDeny::Deny(List(privileges))
|
||||
}
|
||||
}
|
||||
|
||||
impl AclRestrictions {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
pub fn with_grant_only(mut self) -> Self {
|
||||
self.grant_only = true;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_no_invert(mut self) -> Self {
|
||||
self.no_invert = true;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_deny_before_grant(mut self) -> Self {
|
||||
self.deny_before_grant = true;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_required_principal(mut self, required_principal: RequiredPrincipal) -> Self {
|
||||
self.required_principal = Some(required_principal);
|
||||
self
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user