1use std::time::{Duration, SystemTime};
16
17use futures_util::{future, FutureExt};
18use uuid::Uuid;
19use xmltree::Element;
20
21use crate::davpath::DavPath;
22use crate::ls::*;
23
24#[derive(Debug, Clone)]
26pub struct FakeLs {}
27
28impl FakeLs {
29 pub fn new() -> Box<FakeLs> {
31 Box::new(FakeLs {})
32 }
33}
34
35fn tm_limit(d: Option<Duration>) -> Duration {
36 match d {
37 None => Duration::new(120, 0),
38 Some(d) => {
39 if d.as_secs() > 120 {
40 Duration::new(120, 0)
41 } else {
42 d
43 }
44 }
45 }
46}
47
48impl DavLockSystem for FakeLs {
49 fn lock(
50 &self,
51 path: &DavPath,
52 principal: Option<&str>,
53 owner: Option<&Element>,
54 timeout: Option<Duration>,
55 shared: bool,
56 deep: bool,
57 ) -> LsFuture<Result<DavLock, DavLock>> {
58 let timeout = tm_limit(timeout);
59 let timeout_at = SystemTime::now() + timeout;
60
61 let d = if deep { 'I' } else { '0' };
62 let s = if shared { 'S' } else { 'E' };
63 let token = format!("opaquetoken:{}/{}/{}", Uuid::new_v4().hyphenated(), d, s);
64
65 let lock = DavLock {
66 token,
67 path: path.clone(),
68 principal: principal.map(|s| s.to_string()),
69 owner: owner.cloned(),
70 timeout_at: Some(timeout_at),
71 timeout: Some(timeout),
72 shared,
73 deep,
74 };
75 debug!("lock {} created", &lock.token);
76 future::ready(Ok(lock)).boxed()
77 }
78
79 fn unlock(&self, _path: &DavPath, _token: &str) -> LsFuture<Result<(), ()>> {
80 future::ready(Ok(())).boxed()
81 }
82
83 fn refresh(
84 &self,
85 path: &DavPath,
86 token: &str,
87 timeout: Option<Duration>,
88 ) -> LsFuture<Result<DavLock, ()>> {
89 debug!("refresh lock {}", token);
90 let v: Vec<&str> = token.split('/').collect();
91 let deep = v.len() > 1 && v[1] == "I";
92 let shared = v.len() > 2 && v[2] == "S";
93
94 let timeout = tm_limit(timeout);
95 let timeout_at = SystemTime::now() + timeout;
96
97 let lock = DavLock {
98 token: token.to_string(),
99 path: path.clone(),
100 principal: None,
101 owner: None,
102 timeout_at: Some(timeout_at),
103 timeout: Some(timeout),
104 shared,
105 deep,
106 };
107 future::ready(Ok(lock)).boxed()
108 }
109
110 fn check(
111 &self,
112 _path: &DavPath,
113 _principal: Option<&str>,
114 _ignore_principal: bool,
115 _deep: bool,
116 _submitted_tokens: Vec<&str>,
117 ) -> LsFuture<Result<(), DavLock>> {
118 future::ready(Ok(())).boxed()
119 }
120
121 fn discover(&self, _path: &DavPath) -> LsFuture<Vec<DavLock>> {
122 future::ready(Vec::new()).boxed()
123 }
124
125 fn delete(&self, _path: &DavPath) -> LsFuture<Result<(), ()>> {
126 future::ready(Ok(())).boxed()
127 }
128}