scim_server/schema/
embedded.rs

1//! Embedded core SCIM schemas for schema discovery functionality.
2//!
3//! This module provides the core SCIM schemas (User, Group, ServiceProviderConfig)
4//! embedded as static strings, eliminating the need for external schema files
5//! for basic schema discovery functionality.
6
7/// Returns the core User schema as a JSON string.
8///
9/// This is the standard SCIM 2.0 User schema as defined in RFC 7643.
10pub fn core_user_schema() -> &'static str {
11    r#"{
12  "id": "urn:ietf:params:scim:schemas:core:2.0:User",
13  "name": "User",
14  "description": "User Account",
15  "attributes": [
16    {
17      "name": "id",
18      "type": "string",
19      "multiValued": false,
20      "required": false,
21      "caseExact": true,
22      "mutability": "readOnly",
23      "returned": "always",
24      "uniqueness": "server"
25    },
26    {
27      "name": "userName",
28      "type": "string",
29      "multiValued": false,
30      "required": true,
31      "caseExact": false,
32      "mutability": "readWrite",
33      "returned": "default",
34      "uniqueness": "server"
35    },
36    {
37      "name": "externalId",
38      "type": "string",
39      "multiValued": false,
40      "required": false,
41      "caseExact": true,
42      "mutability": "readWrite",
43      "returned": "default",
44      "uniqueness": "none"
45    },
46    {
47      "name": "displayName",
48      "type": "string",
49      "multiValued": false,
50      "required": false,
51      "caseExact": false,
52      "mutability": "readWrite",
53      "returned": "default",
54      "uniqueness": "none"
55    },
56    {
57      "name": "nickName",
58      "type": "string",
59      "multiValued": false,
60      "required": false,
61      "caseExact": false,
62      "mutability": "readWrite",
63      "returned": "default",
64      "uniqueness": "none"
65    },
66    {
67      "name": "profileUrl",
68      "type": "reference",
69      "multiValued": false,
70      "required": false,
71      "caseExact": false,
72      "mutability": "readWrite",
73      "returned": "default",
74      "uniqueness": "none"
75    },
76    {
77      "name": "title",
78      "type": "string",
79      "multiValued": false,
80      "required": false,
81      "caseExact": false,
82      "mutability": "readWrite",
83      "returned": "default",
84      "uniqueness": "none"
85    },
86    {
87      "name": "userType",
88      "type": "string",
89      "multiValued": false,
90      "required": false,
91      "caseExact": false,
92      "mutability": "readWrite",
93      "returned": "default",
94      "uniqueness": "none"
95    },
96    {
97      "name": "preferredLanguage",
98      "type": "string",
99      "multiValued": false,
100      "required": false,
101      "caseExact": false,
102      "mutability": "readWrite",
103      "returned": "default",
104      "uniqueness": "none"
105    },
106    {
107      "name": "locale",
108      "type": "string",
109      "multiValued": false,
110      "required": false,
111      "caseExact": false,
112      "mutability": "readWrite",
113      "returned": "default",
114      "uniqueness": "none"
115    },
116    {
117      "name": "timezone",
118      "type": "string",
119      "multiValued": false,
120      "required": false,
121      "caseExact": false,
122      "mutability": "readWrite",
123      "returned": "default",
124      "uniqueness": "none"
125    },
126    {
127      "name": "name",
128      "type": "complex",
129      "multiValued": false,
130      "required": false,
131      "caseExact": false,
132      "mutability": "readWrite",
133      "returned": "default",
134      "uniqueness": "none",
135      "subAttributes": [
136        {
137          "name": "formatted",
138          "type": "string",
139          "multiValued": false,
140          "required": false,
141          "caseExact": false,
142          "mutability": "readWrite",
143          "returned": "default",
144          "uniqueness": "none"
145        },
146        {
147          "name": "familyName",
148          "type": "string",
149          "multiValued": false,
150          "required": false,
151          "caseExact": false,
152          "mutability": "readWrite",
153          "returned": "default",
154          "uniqueness": "none"
155        },
156        {
157          "name": "givenName",
158          "type": "string",
159          "multiValued": false,
160          "required": false,
161          "caseExact": false,
162          "mutability": "readWrite",
163          "returned": "default",
164          "uniqueness": "none"
165        },
166        {
167          "name": "middleName",
168          "type": "string",
169          "multiValued": false,
170          "required": false,
171          "caseExact": false,
172          "mutability": "readWrite",
173          "returned": "default",
174          "uniqueness": "none"
175        },
176        {
177          "name": "honorificPrefix",
178          "type": "string",
179          "multiValued": false,
180          "required": false,
181          "caseExact": false,
182          "mutability": "readWrite",
183          "returned": "default",
184          "uniqueness": "none"
185        },
186        {
187          "name": "honorificSuffix",
188          "type": "string",
189          "multiValued": false,
190          "required": false,
191          "caseExact": false,
192          "mutability": "readWrite",
193          "returned": "default",
194          "uniqueness": "none"
195        }
196      ]
197    },
198    {
199      "name": "emails",
200      "type": "complex",
201      "multiValued": true,
202      "required": false,
203      "caseExact": false,
204      "mutability": "readWrite",
205      "returned": "default",
206      "uniqueness": "none",
207      "subAttributes": [
208        {
209          "name": "value",
210          "type": "string",
211          "multiValued": false,
212          "required": true,
213          "caseExact": false,
214          "mutability": "readWrite",
215          "returned": "default",
216          "uniqueness": "none"
217        },
218        {
219          "name": "type",
220          "type": "string",
221          "multiValued": false,
222          "required": false,
223          "caseExact": false,
224          "mutability": "readWrite",
225          "returned": "default",
226          "uniqueness": "none",
227          "canonicalValues": ["work", "home", "other"]
228        },
229        {
230          "name": "primary",
231          "type": "boolean",
232          "multiValued": false,
233          "required": false,
234          "caseExact": false,
235          "mutability": "readWrite",
236          "returned": "default",
237          "uniqueness": "none"
238        },
239        {
240          "name": "display",
241          "type": "string",
242          "multiValued": false,
243          "required": false,
244          "caseExact": false,
245          "mutability": "readWrite",
246          "returned": "default",
247          "uniqueness": "none"
248        }
249      ]
250    },
251    {
252      "name": "phoneNumbers",
253      "type": "complex",
254      "multiValued": true,
255      "required": false,
256      "caseExact": false,
257      "mutability": "readWrite",
258      "returned": "default",
259      "uniqueness": "none",
260      "subAttributes": [
261        {
262          "name": "value",
263          "type": "string",
264          "multiValued": false,
265          "required": true,
266          "caseExact": false,
267          "mutability": "readWrite",
268          "returned": "default",
269          "uniqueness": "none"
270        },
271        {
272          "name": "type",
273          "type": "string",
274          "multiValued": false,
275          "required": false,
276          "caseExact": false,
277          "mutability": "readWrite",
278          "returned": "default",
279          "uniqueness": "none",
280          "canonicalValues": ["work", "home", "mobile", "fax", "pager", "other"]
281        },
282        {
283          "name": "primary",
284          "type": "boolean",
285          "multiValued": false,
286          "required": false,
287          "caseExact": false,
288          "mutability": "readWrite",
289          "returned": "default",
290          "uniqueness": "none"
291        },
292        {
293          "name": "display",
294          "type": "string",
295          "multiValued": false,
296          "required": false,
297          "caseExact": false,
298          "mutability": "readWrite",
299          "returned": "default",
300          "uniqueness": "none"
301        }
302      ]
303    },
304    {
305      "name": "addresses",
306      "type": "complex",
307      "multiValued": true,
308      "required": false,
309      "caseExact": false,
310      "mutability": "readWrite",
311      "returned": "default",
312      "uniqueness": "none",
313      "subAttributes": [
314        {
315          "name": "formatted",
316          "type": "string",
317          "multiValued": false,
318          "required": false,
319          "caseExact": false,
320          "mutability": "readWrite",
321          "returned": "default",
322          "uniqueness": "none"
323        },
324        {
325          "name": "streetAddress",
326          "type": "string",
327          "multiValued": false,
328          "required": false,
329          "caseExact": false,
330          "mutability": "readWrite",
331          "returned": "default",
332          "uniqueness": "none"
333        },
334        {
335          "name": "locality",
336          "type": "string",
337          "multiValued": false,
338          "required": false,
339          "caseExact": false,
340          "mutability": "readWrite",
341          "returned": "default",
342          "uniqueness": "none"
343        },
344        {
345          "name": "region",
346          "type": "string",
347          "multiValued": false,
348          "required": false,
349          "caseExact": false,
350          "mutability": "readWrite",
351          "returned": "default",
352          "uniqueness": "none"
353        },
354        {
355          "name": "postalCode",
356          "type": "string",
357          "multiValued": false,
358          "required": false,
359          "caseExact": false,
360          "mutability": "readWrite",
361          "returned": "default",
362          "uniqueness": "none"
363        },
364        {
365          "name": "country",
366          "type": "string",
367          "multiValued": false,
368          "required": false,
369          "caseExact": false,
370          "mutability": "readWrite",
371          "returned": "default",
372          "uniqueness": "none"
373        },
374        {
375          "name": "type",
376          "type": "string",
377          "multiValued": false,
378          "required": false,
379          "caseExact": false,
380          "mutability": "readWrite",
381          "returned": "default",
382          "uniqueness": "none",
383          "canonicalValues": ["work", "home", "other"]
384        },
385        {
386          "name": "primary",
387          "type": "boolean",
388          "multiValued": false,
389          "required": false,
390          "caseExact": false,
391          "mutability": "readWrite",
392          "returned": "default",
393          "uniqueness": "none"
394        }
395      ]
396    },
397    {
398      "name": "active",
399      "type": "boolean",
400      "multiValued": false,
401      "required": false,
402      "caseExact": false,
403      "mutability": "readWrite",
404      "returned": "default",
405      "uniqueness": "none"
406    },
407    {
408      "name": "meta",
409      "type": "complex",
410      "multiValued": false,
411      "required": false,
412      "caseExact": false,
413      "mutability": "readOnly",
414      "returned": "default",
415      "uniqueness": "none",
416      "subAttributes": [
417        {
418          "name": "resourceType",
419          "type": "string",
420          "multiValued": false,
421          "required": false,
422          "caseExact": true,
423          "mutability": "readOnly",
424          "returned": "default",
425          "uniqueness": "none"
426        },
427        {
428          "name": "created",
429          "type": "dateTime",
430          "multiValued": false,
431          "required": false,
432          "caseExact": false,
433          "mutability": "readOnly",
434          "returned": "default",
435          "uniqueness": "none"
436        },
437        {
438          "name": "lastModified",
439          "type": "dateTime",
440          "multiValued": false,
441          "required": false,
442          "caseExact": false,
443          "mutability": "readOnly",
444          "returned": "default",
445          "uniqueness": "none"
446        },
447        {
448          "name": "location",
449          "type": "reference",
450          "multiValued": false,
451          "required": false,
452          "caseExact": false,
453          "mutability": "readOnly",
454          "returned": "default",
455          "uniqueness": "none"
456        },
457        {
458          "name": "version",
459          "type": "string",
460          "multiValued": false,
461          "required": false,
462          "caseExact": true,
463          "mutability": "readOnly",
464          "returned": "default",
465          "uniqueness": "none"
466        }
467      ]
468    }
469  ]
470}"#
471}
472
473/// Returns the core Group schema as a JSON string.
474///
475/// This is the standard SCIM 2.0 Group schema as defined in RFC 7643.
476pub fn core_group_schema() -> &'static str {
477    r#"{
478  "id": "urn:ietf:params:scim:schemas:core:2.0:Group",
479  "name": "Group",
480  "description": "Group",
481  "attributes": [
482    {
483      "name": "id",
484      "type": "string",
485      "multiValued": false,
486      "description": "Unique identifier for the SCIM resource as defined by the Service Provider.",
487      "required": false,
488      "caseExact": true,
489      "mutability": "readOnly",
490      "returned": "always",
491      "uniqueness": "server"
492    },
493    {
494      "name": "externalId",
495      "type": "string",
496      "multiValued": false,
497      "description": "A String that is an identifier for the resource as defined by the provisioning client.",
498      "required": false,
499      "caseExact": false,
500      "mutability": "readWrite",
501      "returned": "default",
502      "uniqueness": "none"
503    },
504    {
505      "name": "meta",
506      "type": "complex",
507      "multiValued": false,
508      "description": "A complex attribute that contains resource metadata.",
509      "required": false,
510      "caseExact": false,
511      "mutability": "readOnly",
512      "returned": "default",
513      "uniqueness": "none",
514      "subAttributes": [
515        {
516          "name": "resourceType",
517          "type": "string",
518          "multiValued": false,
519          "description": "The name of the resource type of the resource.",
520          "required": false,
521          "caseExact": false,
522          "mutability": "readOnly",
523          "returned": "default",
524          "uniqueness": "none"
525        },
526        {
527          "name": "created",
528          "type": "dateTime",
529          "multiValued": false,
530          "description": "The DateTime the Resource was added to the Service Provider.",
531          "required": false,
532          "caseExact": false,
533          "mutability": "readOnly",
534          "returned": "default",
535          "uniqueness": "none"
536        },
537        {
538          "name": "lastModified",
539          "type": "dateTime",
540          "multiValued": false,
541          "description": "The most recent DateTime that the details of this resource were updated at the Service Provider.",
542          "required": false,
543          "caseExact": false,
544          "mutability": "readOnly",
545          "returned": "default",
546          "uniqueness": "none"
547        },
548        {
549          "name": "location",
550          "type": "string",
551          "multiValued": false,
552          "description": "The URI of the resource being returned.",
553          "required": false,
554          "caseExact": false,
555          "mutability": "readOnly",
556          "returned": "default",
557          "uniqueness": "none"
558        },
559        {
560          "name": "version",
561          "type": "string",
562          "multiValued": false,
563          "description": "The version of the resource being returned.",
564          "required": false,
565          "caseExact": false,
566          "mutability": "readOnly",
567          "returned": "default",
568          "uniqueness": "none"
569        }
570      ]
571    },
572    {
573      "name": "displayName",
574      "type": "string",
575      "multiValued": false,
576      "description": "A human-readable name for the Group. REQUIRED.",
577      "required": false,
578      "caseExact": false,
579      "mutability": "readWrite",
580      "returned": "default",
581      "uniqueness": "none"
582    },
583    {
584      "name": "members",
585      "type": "complex",
586      "multiValued": true,
587      "description": "A list of members of the Group.",
588      "required": false,
589      "caseExact": false,
590      "uniqueness": "none",
591      "subAttributes": [
592        {
593          "name": "value",
594          "type": "string",
595          "multiValued": false,
596          "description": "Identifier of the member of this Group.",
597          "required": false,
598          "caseExact": false,
599          "mutability": "immutable",
600          "returned": "default",
601          "uniqueness": "none"
602        },
603        {
604          "name": "$ref",
605          "type": "reference",
606          "referenceTypes": ["User", "Group"],
607          "multiValued": false,
608          "description": "The URI corresponding to a SCIM resource that is a member of this Group.",
609          "required": false,
610          "caseExact": false,
611          "mutability": "immutable",
612          "returned": "default",
613          "uniqueness": "none"
614        },
615        {
616          "name": "type",
617          "type": "string",
618          "multiValued": false,
619          "description": "A label indicating the type of resource, e.g., 'User' or 'Group'.",
620          "required": false,
621          "caseExact": false,
622          "canonicalValues": ["User", "Group"],
623          "mutability": "immutable",
624          "returned": "default",
625          "uniqueness": "none"
626        },
627        {
628          "name": "display",
629          "type": "string",
630          "multiValued": false,
631          "description": "A human-readable name, primarily used for display purposes. READ-ONLY.",
632          "required": false,
633          "caseExact": false,
634          "mutability": "readOnly",
635          "returned": "default",
636          "uniqueness": "none"
637        }
638      ],
639      "mutability": "readWrite",
640      "returned": "default"
641    }
642  ]
643}"#
644}
645
646/// Returns the ServiceProviderConfig schema as a JSON string.
647///
648/// This is the standard SCIM 2.0 ServiceProviderConfig schema as defined in RFC 7643.
649pub fn service_provider_config_schema() -> &'static str {
650    r#"{
651  "id": "urn:ietf:params:scim:schemas:core:2.0:ServiceProviderConfig",
652  "name": "ServiceProviderConfig",
653  "description": "Schema for representing the service provider's configuration",
654  "attributes": [
655    {
656      "name": "documentationUri",
657      "type": "reference",
658      "multiValued": false,
659      "required": false,
660      "caseExact": false,
661      "mutability": "readOnly",
662      "returned": "default",
663      "uniqueness": "none"
664    },
665    {
666      "name": "patch",
667      "type": "complex",
668      "multiValued": false,
669      "required": true,
670      "caseExact": false,
671      "mutability": "readOnly",
672      "returned": "default",
673      "uniqueness": "none",
674      "subAttributes": [
675        {
676          "name": "supported",
677          "type": "boolean",
678          "multiValued": false,
679          "required": true,
680          "caseExact": false,
681          "mutability": "readOnly",
682          "returned": "default",
683          "uniqueness": "none"
684        }
685      ]
686    },
687    {
688      "name": "bulk",
689      "type": "complex",
690      "multiValued": false,
691      "required": true,
692      "caseExact": false,
693      "mutability": "readOnly",
694      "returned": "default",
695      "uniqueness": "none",
696      "subAttributes": [
697        {
698          "name": "supported",
699          "type": "boolean",
700          "multiValued": false,
701          "required": true,
702          "caseExact": false,
703          "mutability": "readOnly",
704          "returned": "default",
705          "uniqueness": "none"
706        },
707        {
708          "name": "maxOperations",
709          "type": "integer",
710          "multiValued": false,
711          "required": true,
712          "caseExact": false,
713          "mutability": "readOnly",
714          "returned": "default",
715          "uniqueness": "none"
716        },
717        {
718          "name": "maxPayloadSize",
719          "type": "integer",
720          "multiValued": false,
721          "required": true,
722          "caseExact": false,
723          "mutability": "readOnly",
724          "returned": "default",
725          "uniqueness": "none"
726        }
727      ]
728    },
729    {
730      "name": "filter",
731      "type": "complex",
732      "multiValued": false,
733      "required": true,
734      "caseExact": false,
735      "mutability": "readOnly",
736      "returned": "default",
737      "uniqueness": "none",
738      "subAttributes": [
739        {
740          "name": "supported",
741          "type": "boolean",
742          "multiValued": false,
743          "required": true,
744          "caseExact": false,
745          "mutability": "readOnly",
746          "returned": "default",
747          "uniqueness": "none"
748        },
749        {
750          "name": "maxResults",
751          "type": "integer",
752          "multiValued": false,
753          "required": true,
754          "caseExact": false,
755          "mutability": "readOnly",
756          "returned": "default",
757          "uniqueness": "none"
758        }
759      ]
760    },
761    {
762      "name": "changePassword",
763      "type": "complex",
764      "multiValued": false,
765      "required": true,
766      "caseExact": false,
767      "mutability": "readOnly",
768      "returned": "default",
769      "uniqueness": "none",
770      "subAttributes": [
771        {
772          "name": "supported",
773          "type": "boolean",
774          "multiValued": false,
775          "required": true,
776          "caseExact": false,
777          "mutability": "readOnly",
778          "returned": "default",
779          "uniqueness": "none"
780        }
781      ]
782    },
783    {
784      "name": "sort",
785      "type": "complex",
786      "multiValued": false,
787      "required": true,
788      "caseExact": false,
789      "mutability": "readOnly",
790      "returned": "default",
791      "uniqueness": "none",
792      "subAttributes": [
793        {
794          "name": "supported",
795          "type": "boolean",
796          "multiValued": false,
797          "required": true,
798          "caseExact": false,
799          "mutability": "readOnly",
800          "returned": "default",
801          "uniqueness": "none"
802        }
803      ]
804    },
805    {
806      "name": "etag",
807      "type": "complex",
808      "multiValued": false,
809      "required": true,
810      "caseExact": false,
811      "mutability": "readOnly",
812      "returned": "default",
813      "uniqueness": "none",
814      "subAttributes": [
815        {
816          "name": "supported",
817          "type": "boolean",
818          "multiValued": false,
819          "required": true,
820          "caseExact": false,
821          "mutability": "readOnly",
822          "returned": "default",
823          "uniqueness": "none"
824        }
825      ]
826    },
827    {
828      "name": "authenticationSchemes",
829      "type": "complex",
830      "multiValued": true,
831      "required": true,
832      "caseExact": false,
833      "mutability": "readOnly",
834      "returned": "default",
835      "uniqueness": "none",
836      "subAttributes": [
837        {
838          "name": "name",
839          "type": "string",
840          "multiValued": false,
841          "required": true,
842          "caseExact": false,
843          "mutability": "readOnly",
844          "returned": "default",
845          "uniqueness": "none"
846        },
847        {
848          "name": "description",
849          "type": "string",
850          "multiValued": false,
851          "required": true,
852          "caseExact": false,
853          "mutability": "readOnly",
854          "returned": "default",
855          "uniqueness": "none"
856        },
857        {
858          "name": "specUri",
859          "type": "reference",
860          "multiValued": false,
861          "required": false,
862          "caseExact": false,
863          "mutability": "readOnly",
864          "returned": "default",
865          "uniqueness": "none"
866        },
867        {
868          "name": "documentationUri",
869          "type": "reference",
870          "multiValued": false,
871          "required": false,
872          "caseExact": false,
873          "mutability": "readOnly",
874          "returned": "default",
875          "uniqueness": "none"
876        },
877        {
878          "name": "type",
879          "type": "string",
880          "multiValued": false,
881          "required": true,
882          "caseExact": false,
883          "mutability": "readOnly",
884          "returned": "default",
885          "uniqueness": "none",
886          "canonicalValues": ["oauth", "oauth2", "oauthbearertoken", "httpbasic", "httpdigest"]
887        },
888        {
889          "name": "primary",
890          "type": "boolean",
891          "multiValued": false,
892          "required": false,
893          "caseExact": false,
894          "mutability": "readOnly",
895          "returned": "default",
896          "uniqueness": "none"
897        }
898      ]
899    }
900  ]
901}"#
902}
903
904#[cfg(test)]
905mod tests {
906    use super::*;
907    use serde_json::Value;
908
909    #[test]
910    fn test_core_user_schema_parses() {
911        let schema_json = core_user_schema();
912        let parsed: Result<Value, _> = serde_json::from_str(schema_json);
913        assert!(parsed.is_ok(), "User schema should parse as valid JSON");
914
915        let schema = parsed.unwrap();
916        assert_eq!(schema["id"], "urn:ietf:params:scim:schemas:core:2.0:User");
917        assert_eq!(schema["name"], "User");
918    }
919
920    #[test]
921    fn test_core_group_schema_parses() {
922        let schema_json = core_group_schema();
923        let parsed: Result<Value, _> = serde_json::from_str(schema_json);
924        assert!(parsed.is_ok(), "Group schema should parse as valid JSON");
925
926        let schema = parsed.unwrap();
927        assert_eq!(schema["id"], "urn:ietf:params:scim:schemas:core:2.0:Group");
928        assert_eq!(schema["name"], "Group");
929    }
930
931    #[test]
932    fn test_service_provider_config_schema_parses() {
933        let schema_json = service_provider_config_schema();
934        let parsed: Result<Value, _> = serde_json::from_str(schema_json);
935        assert!(parsed.is_ok(), "ServiceProviderConfig schema should parse as valid JSON");
936
937        let schema = parsed.unwrap();
938        assert_eq!(schema["id"], "urn:ietf:params:scim:schemas:core:2.0:ServiceProviderConfig");
939        assert_eq!(schema["name"], "ServiceProviderConfig");
940    }
941}