coven_storage/
provider_access.rs1use crate::{CloudProvider, StorageError, StorageFailure};
4use serde::{Deserialize, Serialize};
5
6#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
8pub enum DropboxAccess {
9 AppFolder,
11 FullDropbox,
13}
14
15#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
17pub enum OAuthAccess {
18 Dropbox(DropboxAccess),
20 OneDrive,
22}
23
24impl OAuthAccess {
25 pub fn provider(self) -> CloudProvider {
27 match self {
28 Self::Dropbox(_) => CloudProvider::Dropbox,
29 Self::OneDrive => CloudProvider::OneDrive,
30 }
31 }
32
33 pub(crate) fn scope(self) -> &'static str {
34 match self {
35 Self::Dropbox(DropboxAccess::AppFolder) => "files.content.read files.content.write files.metadata.read account_info.read",
36 Self::Dropbox(DropboxAccess::FullDropbox) => "files.content.read files.content.write files.metadata.read sharing.read sharing.write account_info.read",
37 Self::OneDrive => "Files.ReadWrite.All offline_access User.Read",
38 }
39 }
40
41 pub(crate) fn granted(
45 self,
46 scope: Option<&str>,
47 refreshable: bool,
48 ) -> Result<Self, StorageError> {
49 let refused = || Err(StorageFailure::AccessNotGranted { required: self }.into());
50 if self == Self::OneDrive && !refreshable {
55 return refused();
56 }
57 let Some(scope) = scope else { return Ok(self) };
59 let scopes: Vec<_> = scope
60 .split_ascii_whitespace()
61 .map(|granted| match self {
62 Self::OneDrive => {
64 granted.strip_prefix("https://graph.microsoft.com/").unwrap_or(granted)
65 }
66 Self::Dropbox(_) => granted,
67 })
68 .collect();
69 if self
70 .scope()
71 .split_ascii_whitespace()
72 .filter(|required| !(self == Self::OneDrive && *required == "offline_access"))
73 .all(|required| scopes.contains(&required))
74 {
75 Ok(self)
76 } else {
77 refused()
78 }
79 }
80}
81
82#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
84#[serde(deny_unknown_fields)]
85pub enum DropboxLocation {
86 AppFolder,
88 SharedFolder {
90 namespace_id: String,
92 },
93}
94
95impl DropboxLocation {
96 pub fn access(&self) -> DropboxAccess {
98 match self {
99 Self::AppFolder => DropboxAccess::AppFolder,
100 Self::SharedFolder { .. } => DropboxAccess::FullDropbox,
101 }
102 }
103}
104
105#[cfg(test)]
106#[path = "provider_access_tests.rs"]
107mod tests;