1use std::fmt;
2use std::fmt::{Display, Formatter};
3
4use crate::sql::{Base, Cond, Ident, RecordIdLit};
5use crate::val::{Datetime, Duration, Strand, Uuid};
6
7#[derive(Clone, Debug, PartialEq, Eq)]
8#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
9pub enum AccessStatement {
10 Grant(AccessStatementGrant), Show(AccessStatementShow), Revoke(AccessStatementRevoke), Purge(AccessStatementPurge), }
15
16impl From<AccessStatement> for crate::expr::statements::access::AccessStatement {
17 fn from(v: AccessStatement) -> Self {
18 match v {
19 AccessStatement::Grant(v) => Self::Grant(v.into()),
20 AccessStatement::Show(v) => Self::Show(v.into()),
21 AccessStatement::Revoke(v) => Self::Revoke(v.into()),
22 AccessStatement::Purge(v) => Self::Purge(v.into()),
23 }
24 }
25}
26
27impl From<crate::expr::statements::access::AccessStatement> for AccessStatement {
28 fn from(v: crate::expr::statements::access::AccessStatement) -> Self {
29 match v {
30 crate::expr::statements::access::AccessStatement::Grant(v) => Self::Grant(v.into()),
31 crate::expr::statements::access::AccessStatement::Show(v) => Self::Show(v.into()),
32 crate::expr::statements::access::AccessStatement::Revoke(v) => Self::Revoke(v.into()),
33 crate::expr::statements::access::AccessStatement::Purge(v) => Self::Purge(v.into()),
34 }
35 }
36}
37
38#[derive(Clone, Debug, PartialEq, Eq)]
39#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
40pub struct AccessStatementGrant {
41 pub ac: Ident,
42 pub base: Option<Base>,
43 pub subject: Subject,
44}
45
46impl From<AccessStatementGrant> for crate::expr::statements::access::AccessStatementGrant {
47 fn from(v: AccessStatementGrant) -> Self {
48 Self {
49 ac: v.ac.into(),
50 base: v.base.map(Into::into),
51 subject: v.subject.into(),
52 }
53 }
54}
55
56impl From<crate::expr::statements::access::AccessStatementGrant> for AccessStatementGrant {
57 fn from(v: crate::expr::statements::access::AccessStatementGrant) -> Self {
58 Self {
59 ac: v.ac.into(),
60 base: v.base.map(Into::into),
61 subject: v.subject.into(),
62 }
63 }
64}
65
66#[derive(Clone, Debug, Default, PartialEq, Eq)]
67#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
68pub struct AccessStatementShow {
69 pub ac: Ident,
70 pub base: Option<Base>,
71 pub gr: Option<Ident>,
72 pub cond: Option<Cond>,
73}
74
75impl From<AccessStatementShow> for crate::expr::statements::access::AccessStatementShow {
76 fn from(v: AccessStatementShow) -> Self {
77 Self {
78 ac: v.ac.into(),
79 base: v.base.map(Into::into),
80 gr: v.gr.map(Into::into),
81 cond: v.cond.map(Into::into),
82 }
83 }
84}
85
86impl From<crate::expr::statements::access::AccessStatementShow> for AccessStatementShow {
87 fn from(v: crate::expr::statements::access::AccessStatementShow) -> Self {
88 Self {
89 ac: v.ac.into(),
90 base: v.base.map(Into::into),
91 gr: v.gr.map(Into::into),
92 cond: v.cond.map(Into::into),
93 }
94 }
95}
96
97#[derive(Clone, Debug, Default, PartialEq, Eq)]
98#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
99pub struct AccessStatementRevoke {
100 pub ac: Ident,
101 pub base: Option<Base>,
102 pub gr: Option<Ident>,
103 pub cond: Option<Cond>,
104}
105
106impl From<AccessStatementRevoke> for crate::expr::statements::access::AccessStatementRevoke {
107 fn from(v: AccessStatementRevoke) -> Self {
108 Self {
109 ac: v.ac.into(),
110 base: v.base.map(Into::into),
111 gr: v.gr.map(Into::into),
112 cond: v.cond.map(Into::into),
113 }
114 }
115}
116
117impl From<crate::expr::statements::access::AccessStatementRevoke> for AccessStatementRevoke {
118 fn from(v: crate::expr::statements::access::AccessStatementRevoke) -> Self {
119 Self {
120 ac: v.ac.into(),
121 base: v.base.map(Into::into),
122 gr: v.gr.map(Into::into),
123 cond: v.cond.map(Into::into),
124 }
125 }
126}
127
128#[derive(Clone, Debug, Default, PartialEq, Eq)]
129#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
130pub struct AccessStatementPurge {
131 pub ac: Ident,
132 pub base: Option<Base>,
133 pub expired: bool,
135 pub revoked: bool,
136 pub grace: Duration,
137}
138
139impl From<AccessStatementPurge> for crate::expr::statements::access::AccessStatementPurge {
140 fn from(v: AccessStatementPurge) -> Self {
141 Self {
142 ac: v.ac.into(),
143 base: v.base.map(Into::into),
144 expired: v.expired,
145 revoked: v.revoked,
146 grace: v.grace,
147 }
148 }
149}
150
151impl From<crate::expr::statements::access::AccessStatementPurge> for AccessStatementPurge {
152 fn from(v: crate::expr::statements::access::AccessStatementPurge) -> Self {
153 Self {
154 ac: v.ac.into(),
155 base: v.base.map(Into::into),
156 expired: v.expired,
157 revoked: v.revoked,
158 grace: v.grace,
159 }
160 }
161}
162
163#[derive(Clone, Debug, PartialEq, Eq)]
164#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
165pub struct AccessGrant {
166 pub id: Ident, pub ac: Ident, pub creation: Datetime, pub expiration: Option<Datetime>, pub revocation: Option<Datetime>, pub subject: Subject, pub grant: Grant, }
174
175#[derive(Clone, Debug, PartialEq, Eq)]
176#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
177pub enum Subject {
178 Record(RecordIdLit),
179 User(Ident),
180}
181
182impl From<Subject> for crate::expr::statements::access::Subject {
183 fn from(v: Subject) -> Self {
184 match v {
185 Subject::Record(id) => Self::Record(id.into()),
186 Subject::User(name) => Self::User(name.into()),
187 }
188 }
189}
190
191impl From<crate::expr::statements::access::Subject> for Subject {
192 fn from(v: crate::expr::statements::access::Subject) -> Self {
193 match v {
194 crate::expr::statements::access::Subject::Record(id) => Self::Record(id.into()),
195 crate::expr::statements::access::Subject::User(name) => Self::User(name.into()),
196 }
197 }
198}
199
200#[derive(Clone, Debug, PartialEq, Eq)]
201#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
202pub enum Grant {
203 Jwt(GrantJwt),
204 Record(GrantRecord),
205 Bearer(GrantBearer),
206}
207
208impl Grant {
209 pub fn variant(&self) -> &str {
211 match self {
212 Grant::Jwt(_) => "jwt",
213 Grant::Record(_) => "record",
214 Grant::Bearer(_) => "bearer",
215 }
216 }
217}
218
219#[derive(Clone, Debug, PartialEq, Eq)]
220#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
221pub struct GrantJwt {
222 pub jti: Uuid, pub token: Option<Strand>, }
225
226#[derive(Clone, Debug, PartialEq, Eq)]
227#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
228pub struct GrantRecord {
229 pub rid: Uuid, pub jti: Uuid, pub token: Option<Strand>, }
233
234#[derive(Clone, Debug, PartialEq, Eq)]
235#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
236pub struct GrantBearer {
237 pub id: Ident, pub key: Strand,
242}
243
244impl Display for AccessStatement {
245 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
246 match self {
247 Self::Grant(stmt) => {
248 write!(f, "ACCESS {}", stmt.ac)?;
249 if let Some(ref v) = stmt.base {
250 write!(f, " ON {v}")?;
251 }
252 write!(f, " GRANT")?;
253 match &stmt.subject {
254 Subject::User(x) => write!(f, " FOR USER {}", x)?,
255 Subject::Record(x) => write!(f, " FOR RECORD {}", x)?,
256 }
257 Ok(())
258 }
259 Self::Show(stmt) => {
260 write!(f, "ACCESS {}", stmt.ac)?;
261 if let Some(ref v) = stmt.base {
262 write!(f, " ON {v}")?;
263 }
264 write!(f, " SHOW")?;
265 match &stmt.gr {
266 Some(v) => write!(f, " GRANT {v}")?,
267 None => match &stmt.cond {
268 Some(v) => write!(f, " {v}")?,
269 None => write!(f, " ALL")?,
270 },
271 };
272 Ok(())
273 }
274 Self::Revoke(stmt) => {
275 write!(f, "ACCESS {}", stmt.ac)?;
276 if let Some(ref v) = stmt.base {
277 write!(f, " ON {v}")?;
278 }
279 write!(f, " REVOKE")?;
280 match &stmt.gr {
281 Some(v) => write!(f, " GRANT {v}")?,
282 None => match &stmt.cond {
283 Some(v) => write!(f, " {v}")?,
284 None => write!(f, " ALL")?,
285 },
286 };
287 Ok(())
288 }
289 Self::Purge(stmt) => {
290 write!(f, "ACCESS {}", stmt.ac)?;
291 if let Some(ref v) = stmt.base {
292 write!(f, " ON {v}")?;
293 }
294 write!(f, " PURGE")?;
295 match (stmt.expired, stmt.revoked) {
296 (true, false) => write!(f, " EXPIRED")?,
297 (false, true) => write!(f, " REVOKED")?,
298 (true, true) => write!(f, " EXPIRED, REVOKED")?,
299 (false, false) => write!(f, " NONE")?,
301 };
302 if !stmt.grace.is_zero() {
303 write!(f, " FOR {}", stmt.grace)?;
304 }
305 Ok(())
306 }
307 }
308 }
309}