1use indexmap::IndexMap;
4
5use super::{DbField, DbFieldType, DbTable, ForeignKey, OnDelete};
6use crate::plugin::PluginSchemaContribution;
7
8pub const OAUTH_CLIENT_MODEL: &str = "oauth_client";
9pub const OAUTH_REFRESH_TOKEN_MODEL: &str = "oauth_refresh_token";
10pub const OAUTH_ACCESS_TOKEN_MODEL: &str = "oauth_access_token";
11pub const OAUTH_CONSENT_MODEL: &str = "oauth_consent";
12
13pub fn oauth_provider_schema() -> Vec<PluginSchemaContribution> {
15 vec![
16 PluginSchemaContribution::table(
17 OAUTH_CLIENT_MODEL,
18 table(
19 "oauth_clients",
20 Some(20),
21 [
22 ("id", field("id", DbFieldType::String)),
23 (
24 "client_id",
25 field("client_id", DbFieldType::String).unique(),
26 ),
27 (
28 "client_secret",
29 field("client_secret", DbFieldType::String)
30 .optional()
31 .hidden(),
32 ),
33 (
34 "client_secret_expires_at",
35 field("client_secret_expires_at", DbFieldType::Timestamp)
36 .optional()
37 .hidden(),
38 ),
39 (
40 "disabled",
41 field("disabled", DbFieldType::Boolean).optional(),
42 ),
43 (
44 "skip_consent",
45 field("skip_consent", DbFieldType::Boolean).optional(),
46 ),
47 (
48 "enable_end_session",
49 field("enable_end_session", DbFieldType::Boolean).optional(),
50 ),
51 (
52 "subject_type",
53 field("subject_type", DbFieldType::String).optional(),
54 ),
55 (
56 "scopes",
57 field("scopes", DbFieldType::StringArray).optional(),
58 ),
59 (
60 "user_id",
61 field("user_id", DbFieldType::String)
62 .optional()
63 .indexed()
64 .references(ForeignKey::new("users", "id", OnDelete::SetNull)),
65 ),
66 (
67 "created_at",
68 field("created_at", DbFieldType::Timestamp).generated(),
69 ),
70 (
71 "updated_at",
72 field("updated_at", DbFieldType::Timestamp).generated(),
73 ),
74 ("name", field("name", DbFieldType::String).optional()),
75 ("uri", field("uri", DbFieldType::String).optional()),
76 ("icon", field("icon", DbFieldType::String).optional()),
77 (
78 "contacts",
79 field("contacts", DbFieldType::StringArray).optional(),
80 ),
81 ("tos", field("tos", DbFieldType::String).optional()),
82 ("policy", field("policy", DbFieldType::String).optional()),
83 (
84 "software_id",
85 field("software_id", DbFieldType::String).optional(),
86 ),
87 (
88 "software_version",
89 field("software_version", DbFieldType::String).optional(),
90 ),
91 (
92 "software_statement",
93 field("software_statement", DbFieldType::String).optional(),
94 ),
95 (
96 "redirect_uris",
97 field("redirect_uris", DbFieldType::StringArray),
98 ),
99 (
100 "post_logout_redirect_uris",
101 field("post_logout_redirect_uris", DbFieldType::StringArray).optional(),
102 ),
103 (
104 "token_endpoint_auth_method",
105 field("token_endpoint_auth_method", DbFieldType::String).optional(),
106 ),
107 (
108 "grant_types",
109 field("grant_types", DbFieldType::StringArray).optional(),
110 ),
111 (
112 "response_types",
113 field("response_types", DbFieldType::StringArray).optional(),
114 ),
115 ("public", field("public", DbFieldType::Boolean).optional()),
116 ("type", field("type", DbFieldType::String).optional()),
117 (
118 "require_pkce",
119 field("require_pkce", DbFieldType::Boolean).optional(),
120 ),
121 (
122 "reference_id",
123 field("reference_id", DbFieldType::String)
124 .optional()
125 .indexed(),
126 ),
127 ("metadata", field("metadata", DbFieldType::Json).optional()),
128 ],
129 ),
130 ),
131 PluginSchemaContribution::table(
132 OAUTH_REFRESH_TOKEN_MODEL,
133 table(
134 "oauth_refresh_tokens",
135 Some(21),
136 [
137 ("id", field("id", DbFieldType::String)),
138 (
139 "token",
140 field("token", DbFieldType::String).indexed().hidden(),
141 ),
142 (
143 "client_id",
144 field("client_id", DbFieldType::String)
145 .indexed()
146 .references(ForeignKey::new(
147 "oauth_clients",
148 "client_id",
149 OnDelete::Cascade,
150 )),
151 ),
152 (
153 "session_id",
154 field("session_id", DbFieldType::String)
155 .optional()
156 .references(ForeignKey::new("sessions", "id", OnDelete::SetNull)),
157 ),
158 (
159 "user_id",
160 field("user_id", DbFieldType::String)
161 .indexed()
162 .references(ForeignKey::new("users", "id", OnDelete::Cascade)),
163 ),
164 (
165 "reference_id",
166 field("reference_id", DbFieldType::String).optional(),
167 ),
168 ("expires_at", field("expires_at", DbFieldType::Timestamp)),
169 (
170 "created_at",
171 field("created_at", DbFieldType::Timestamp).generated(),
172 ),
173 (
174 "revoked",
175 field("revoked", DbFieldType::Timestamp).optional(),
176 ),
177 (
178 "auth_time",
179 field("auth_time", DbFieldType::Timestamp).optional(),
180 ),
181 ("scopes", field("scopes", DbFieldType::StringArray)),
182 ],
183 ),
184 ),
185 PluginSchemaContribution::table(
186 OAUTH_ACCESS_TOKEN_MODEL,
187 table(
188 "oauth_access_tokens",
189 Some(22),
190 [
191 ("id", field("id", DbFieldType::String)),
192 (
193 "token",
194 field("token", DbFieldType::String).unique().hidden(),
195 ),
196 (
197 "client_id",
198 field("client_id", DbFieldType::String)
199 .indexed()
200 .references(ForeignKey::new(
201 "oauth_clients",
202 "client_id",
203 OnDelete::Cascade,
204 )),
205 ),
206 (
207 "session_id",
208 field("session_id", DbFieldType::String)
209 .optional()
210 .references(ForeignKey::new("sessions", "id", OnDelete::SetNull)),
211 ),
212 (
213 "user_id",
214 field("user_id", DbFieldType::String)
215 .optional()
216 .indexed()
217 .references(ForeignKey::new("users", "id", OnDelete::SetNull)),
218 ),
219 (
220 "reference_id",
221 field("reference_id", DbFieldType::String).optional(),
222 ),
223 (
224 "refresh_id",
225 field("refresh_id", DbFieldType::String)
226 .optional()
227 .references(ForeignKey::new(
228 "oauth_refresh_tokens",
229 "id",
230 OnDelete::Cascade,
231 )),
232 ),
233 ("expires_at", field("expires_at", DbFieldType::Timestamp)),
234 (
235 "created_at",
236 field("created_at", DbFieldType::Timestamp).generated(),
237 ),
238 ("scopes", field("scopes", DbFieldType::StringArray)),
239 ],
240 ),
241 ),
242 PluginSchemaContribution::table(
243 OAUTH_CONSENT_MODEL,
244 table(
245 "oauth_consents",
246 Some(23),
247 [
248 ("id", field("id", DbFieldType::String)),
249 (
250 "client_id",
251 field("client_id", DbFieldType::String)
252 .indexed()
253 .references(ForeignKey::new(
254 "oauth_clients",
255 "client_id",
256 OnDelete::Cascade,
257 )),
258 ),
259 (
260 "user_id",
261 field("user_id", DbFieldType::String)
262 .optional()
263 .indexed()
264 .references(ForeignKey::new("users", "id", OnDelete::Cascade)),
265 ),
266 (
267 "reference_id",
268 field("reference_id", DbFieldType::String).optional(),
269 ),
270 ("scopes", field("scopes", DbFieldType::StringArray)),
271 (
272 "created_at",
273 field("created_at", DbFieldType::Timestamp).generated(),
274 ),
275 (
276 "updated_at",
277 field("updated_at", DbFieldType::Timestamp).generated(),
278 ),
279 ],
280 ),
281 ),
282 ]
283}
284
285fn table<const N: usize>(name: &str, order: Option<u16>, fields: [(&str, DbField); N]) -> DbTable {
286 DbTable {
287 name: name.to_owned(),
288 fields: fields
289 .into_iter()
290 .map(|(logical_name, field)| (logical_name.to_owned(), field))
291 .collect::<IndexMap<_, _>>(),
292 order,
293 }
294}
295
296fn field(name: &str, field_type: DbFieldType) -> DbField {
297 DbField::new(name, field_type)
298}