1 use std
::collections
::HashSet
;
3 use anyhow
::{bail, format_err, Error}
;
5 use proxmox_backup
::api2
;
7 use proxmox
::api
::schema
::*;
9 // Simply test if api lookup tables inside Routers and Schemas are
12 fn verify_object_schema(schema
: &ObjectSchema
) -> Result
<(), Error
> {
14 let map
= schema
.properties
;
18 for i
in 1..map
.len() {
20 if map
[i
].0 <= map
[i
-1].0 {
21 for (name
, _
, _
) in map
.iter() {
22 eprintln
!("{}", name
);
24 bail
!("found unsorted property map ({} <= {})", map
[i
].0, map
[i
-1].0);
29 for (_name
, _
, sub_schema
) in map
.iter() {
30 verify_schema(sub_schema
)?
;
36 // verify entries in an AllOf schema are actually object schemas and that they don't contain
38 fn verify_all_of_schema(schema
: &AllOfSchema
) -> Result
<(), Error
> {
39 for entry
in schema
.list
{
41 Schema
::Object(obj
) => verify_object_schema(obj
)?
,
42 Schema
::AllOf(allof
) => verify_all_of_schema(allof
)?
,
43 _
=> bail
!("AllOf schema with a non-object schema entry!"),
47 let mut keys
= HashSet
::<&'
static str>::new();
48 let mut dupes
= String
::new();
49 for property
in schema
.properties() {
50 if !keys
.insert(property
.0) {
51 if !dupes
.is_empty() {
54 dupes
.push_str(property
.0);
57 if !dupes
.is_empty() {
58 bail
!("Duplicate keys found in AllOf schema: {}", dupes
);
64 fn verify_schema(schema
: &Schema
) -> Result
<(), Error
> {
66 Schema
::Object(obj_schema
) => {
67 verify_object_schema(obj_schema
)?
;
69 Schema
::AllOf(all_of_schema
) => {
70 verify_all_of_schema(all_of_schema
)?
;
72 Schema
::Array(arr_schema
) => {
73 verify_schema(arr_schema
.items
)?
;
80 fn verify_access_permissions(permission
: &Permission
) -> Result
<(), Error
> {
83 Permission
::Or(list
) => {
84 for perm
in list
.iter() { verify_access_permissions(perm)?; }
86 Permission
::And(list
) => {
87 for perm
in list
.iter() { verify_access_permissions(perm)?; }
89 Permission
::Privilege(path_comp
, ..)=> {
90 let path
= format
!("/{}", path_comp
.join("/"));
91 pbs_config
::acl
::check_acl_path(&path
)?
;
102 ) -> Result
<(), Error
>
104 match &info
.parameters
{
105 ParameterSchema
::Object(obj
) => {
106 verify_object_schema(obj
)
107 .map_err(|err
| format_err
!("{} {} parameters: {}", method
, path
, err
))?
;
109 ParameterSchema
::AllOf(all_of
) => {
110 verify_all_of_schema(all_of
)
111 .map_err(|err
| format_err
!("{} {} parameters: {}", method
, path
, err
))?
;
115 verify_schema(info
.returns
.schema
)
116 .map_err(|err
| format_err
!("{} {} returns: {}", method
, path
, err
))?
;
118 verify_access_permissions(info
.access
.permission
)
119 .map_err(|err
| format_err
!("{} {} access: {}", method
, path
, err
))?
;
127 ) -> Result
<(), Error
> {
129 if !dirmap
.is_empty() {
131 for i
in 1..dirmap
.len() {
133 if dirmap
[i
].0 <= dirmap
[i
-1].0 {
134 for (name
, _
) in dirmap
.iter() {
135 eprintln
!("{}/{}", path
, name
);
137 bail
!("found unsorted dirmap at {:?} ({} <= {})", path
, dirmap
[i
].0, dirmap
[i
-1].0);
143 for (name
, router
) in dirmap
.iter() {
144 let sub_path
= format
!("{}/{}", path
, name
);
145 verify_router(&sub_path
, router
)?
;
151 fn verify_router(path
: &str, router
: &Router
) -> Result
<(), Error
> {
153 println
!("Verify {}", path
);
155 if let Some(api_method
) = router
.get
{
156 verify_api_method("GET", path
, api_method
)?
;
158 if let Some(api_method
) = router
.put
{
159 verify_api_method("PUT", path
, api_method
)?
;
161 if let Some(api_method
) = router
.post
{
162 verify_api_method("POST", path
, api_method
)?
;
164 if let Some(api_method
) = router
.delete
{
165 verify_api_method("DELETE", path
, api_method
)?
;
168 match router
.subroute
{
169 Some(SubRoute
::Map(dirmap
)) => {
170 verify_dirmap(path
, dirmap
)?
;
172 Some(SubRoute
::MatchAll { router, param_name }
) => {
173 let path
= format
!("{}/{{{}}}", path
, param_name
);
174 verify_router(&path
, router
)?
;
183 fn verify_backup_api() -> Result
<(), Error
> {
185 let api
= &api2
::backup
::BACKUP_API_ROUTER
;
186 verify_router("backup-api", api
)?
;
192 fn verify_reader_api() -> Result
<(), Error
> {
194 let api
= &api2
::reader
::READER_API_ROUTER
;
195 verify_router("reader-api", api
)?
;
201 fn verify_root_api() -> Result
<(), Error
> {
203 let api
= &api2
::ROUTER
;
204 verify_router("root", api
)?
;