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 _
=> bail
!("AllOf schema with a non-object schema entry!"),
46 let mut keys
= HashSet
::<&'
static str>::new();
47 let mut dupes
= String
::new();
48 for property
in schema
.properties() {
49 if !keys
.insert(property
.0) {
50 if !dupes
.is_empty() {
53 dupes
.push_str(property
.0);
56 if !dupes
.is_empty() {
57 bail
!("Duplicate keys found in AllOf schema: {}", dupes
);
63 fn verify_schema(schema
: &Schema
) -> Result
<(), Error
> {
65 Schema
::Object(obj_schema
) => {
66 verify_object_schema(obj_schema
)?
;
68 Schema
::AllOf(all_of_schema
) => {
69 verify_all_of_schema(all_of_schema
)?
;
71 Schema
::Array(arr_schema
) => {
72 verify_schema(arr_schema
.items
)?
;
79 fn verify_access_permissions(permission
: &Permission
) -> Result
<(), Error
> {
82 Permission
::Or(list
) => {
83 for perm
in list
.iter() { verify_access_permissions(perm)?; }
85 Permission
::And(list
) => {
86 for perm
in list
.iter() { verify_access_permissions(perm)?; }
88 Permission
::Privilege(path_comp
, ..)=> {
89 let path
= format
!("/{}", path_comp
.join("/"));
90 proxmox_backup
::config
::acl
::check_acl_path(&path
)?
;
101 ) -> Result
<(), Error
>
103 match &info
.parameters
{
104 ParameterSchema
::Object(obj
) => {
105 verify_object_schema(obj
)
106 .map_err(|err
| format_err
!("{} {} parameters: {}", method
, path
, err
))?
;
108 ParameterSchema
::AllOf(all_of
) => {
109 verify_all_of_schema(all_of
)
110 .map_err(|err
| format_err
!("{} {} parameters: {}", method
, path
, err
))?
;
114 verify_schema(info
.returns
.schema
)
115 .map_err(|err
| format_err
!("{} {} returns: {}", method
, path
, err
))?
;
117 verify_access_permissions(info
.access
.permission
)
118 .map_err(|err
| format_err
!("{} {} access: {}", method
, path
, err
))?
;
126 ) -> Result
<(), Error
> {
128 if !dirmap
.is_empty() {
130 for i
in 1..dirmap
.len() {
132 if dirmap
[i
].0 <= dirmap
[i
-1].0 {
133 for (name
, _
) in dirmap
.iter() {
134 eprintln
!("{}/{}", path
, name
);
136 bail
!("found unsorted dirmap at {:?} ({} <= {})", path
, dirmap
[i
].0, dirmap
[i
-1].0);
142 for (name
, router
) in dirmap
.iter() {
143 let sub_path
= format
!("{}/{}", path
, name
);
144 verify_router(&sub_path
, router
)?
;
150 fn verify_router(path
: &str, router
: &Router
) -> Result
<(), Error
> {
152 println
!("Verify {}", path
);
154 if let Some(api_method
) = router
.get
{
155 verify_api_method("GET", path
, api_method
)?
;
157 if let Some(api_method
) = router
.put
{
158 verify_api_method("PUT", path
, api_method
)?
;
160 if let Some(api_method
) = router
.post
{
161 verify_api_method("POST", path
, api_method
)?
;
163 if let Some(api_method
) = router
.delete
{
164 verify_api_method("DELETE", path
, api_method
)?
;
167 match router
.subroute
{
168 Some(SubRoute
::Map(dirmap
)) => {
169 verify_dirmap(path
, dirmap
)?
;
171 Some(SubRoute
::MatchAll { router, param_name }
) => {
172 let path
= format
!("{}/{{{}}}", path
, param_name
);
173 verify_router(&path
, router
)?
;
182 fn verify_backup_api() -> Result
<(), Error
> {
184 let api
= &api2
::backup
::BACKUP_API_ROUTER
;
185 verify_router("backup-api", api
)?
;
191 fn verify_reader_api() -> Result
<(), Error
> {
193 let api
= &api2
::reader
::READER_API_ROUTER
;
194 verify_router("reader-api", api
)?
;
200 fn verify_root_api() -> Result
<(), Error
> {
202 let api
= &api2
::ROUTER
;
203 verify_router("root", api
)?
;