apiplant_core/
defaults.rs1use crate::schema::Resource;
13
14pub const ORGANIZATION_TOML: &str = r#"
17[resource]
18name = "organization"
19scope = "global"
20timestamps = true
21
22[permissions]
23list = "member" # organisations you belong to
24read = "member"
25create = "authenticated" # anyone may start one (and becomes its admin)
26update = "role:admin" # an admin *of that organisation*
27delete = "role:admin"
28
29[fields.name]
30type = "string"
31required = true
32
33[fields.slug]
34type = "string"
35unique = true
36"#;
37
38pub const MEMBERSHIP_TOML: &str = r#"
41[resource]
42name = "membership"
43scope = "organization"
44timestamps = true
45
46[permissions]
47list = "member" # members can see who else is in the org
48read = "member"
49create = "role:admin" # admins add members
50update = "role:admin"
51delete = "role:admin"
52
53# Built-in function: lets `create` name the person by `email` instead of by
54# `user_id`, and refuses a duplicate membership. The lookup has to happen here
55# because `user` is only readable by people you already share an org with.
56[hooks]
57before_create = "apiplant_organization_join"
58
59[fields.user_id]
60type = "reference"
61references = "user"
62required = true
63
64[fields.organization_id]
65type = "reference"
66references = "organization"
67required = true
68
69[fields.role]
70type = "string" # the member's *primary* role here, e.g. "admin".
71 # Further roles are `membership_role` rows; a
72 # `role:` permission is checked against all of them.
73"#;
74
75pub const MEMBERSHIP_ROLE_TOML: &str = r#"
87[resource]
88name = "membership_role"
89scope = "organization"
90timestamps = true
91
92[permissions]
93list = "member" # members can see who holds what
94read = "member"
95create = "role:admin" # admins grant roles
96update = "role:admin"
97delete = "role:admin"
98
99[fields.membership_id]
100type = "reference"
101references = "membership"
102required = true
103on_delete = "cascade" # a removed member takes their roles with them
104
105[fields.organization_id]
106type = "reference"
107references = "organization"
108required = true
109
110[fields.role]
111type = "string"
112required = true
113"#;
114
115pub const USER_TOML: &str = r#"
118[resource]
119name = "user"
120scope = "global"
121timestamps = true
122
123[permissions]
124list = "member" # people you share an organisation with
125read = "member"
126create = "public" # registration
127update = "owner"
128delete = "private"
129
130[auth]
131identity_field = "email"
132password_field = "password_hash"
133oauth_providers = []
134
135[fields.email]
136type = "string"
137required = true
138unique = true
139max_length = 320
140
141[fields.password_hash]
142type = "string"
143hidden = true
144
145[fields.display_name]
146type = "string"
147"#;
148
149pub const API_KEY_TOML: &str = r#"
151[resource]
152name = "api_key"
153scope = "global"
154timestamps = true
155
156# "Api key" is what titleising the name produces, and it is not how anybody
157# writes it.
158[admin]
159label = "API key"
160plural = "API keys"
161
162[permissions]
163list = "owner"
164read = "owner"
165create = "authenticated"
166update = "private"
167delete = "owner"
168
169[fields.name]
170type = "string"
171
172[fields.token_hash]
173type = "string"
174required = true
175unique = true
176hidden = true
177
178[fields.owner_id]
179type = "reference"
180references = "user"
181required = true
182"#;
183
184pub const OAUTH_TOML: &str = r#"
186[resource]
187name = "oauth_connection"
188scope = "global"
189timestamps = true
190
191[permissions]
192list = "owner"
193read = "owner"
194create = "private"
195update = "private"
196delete = "owner"
197
198[fields.provider]
199type = "string"
200required = true
201
202[fields.provider_user_id]
203type = "string"
204required = true
205
206[fields.owner_id]
207type = "reference"
208references = "user"
209required = true
210"#;
211
212pub fn builtins() -> Vec<(&'static str, &'static str)> {
215 vec![
216 ("organization", ORGANIZATION_TOML),
217 ("user", USER_TOML),
218 ("membership", MEMBERSHIP_TOML),
219 ("membership_role", MEMBERSHIP_ROLE_TOML),
220 ("api_key", API_KEY_TOML),
221 ("oauth_connection", OAUTH_TOML),
222 ]
223}
224
225pub fn parse_builtin(toml_src: &str) -> Resource {
228 let r: Resource = toml::from_str(toml_src).expect("built-in resource TOML is valid");
229 r.validate().expect("built-in resource is valid");
230 r
231}
232
233#[cfg(test)]
234mod tests {
235 use super::*;
236
237 #[test]
238 fn all_builtins_parse() {
239 for (name, src) in builtins() {
240 let r = parse_builtin(src);
241 assert_eq!(r.meta.name, name);
242 }
243 }
244}