148 lines
4.1 KiB
Rust
148 lines
4.1 KiB
Rust
use jsonschema::JSONSchema;
|
|
use once_cell::sync::Lazy;
|
|
use schemars::JsonSchema;
|
|
use utoipa::ToSchema;
|
|
|
|
use super::Schema;
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, JsonSchema, ToSchema)]
|
|
#[serde(rename_all = "camelCase")]
|
|
pub struct App {
|
|
pub id: String,
|
|
pub name: String,
|
|
#[schemars(url)]
|
|
pub callback_url: Option<String>,
|
|
#[schema(inline)]
|
|
pub permission: Vec<AppPermission>,
|
|
pub secret: Option<String>,
|
|
pub is_authorized: Option<bool>,
|
|
}
|
|
|
|
/// This represents `permissions` in `packages/calckey-js/src/consts.ts`.
|
|
#[derive(Clone, Debug, PartialEq, Eq, JsonSchema, ToSchema)]
|
|
pub enum AppPermission {
|
|
#[serde(rename = "read:account")]
|
|
ReadAccount,
|
|
#[serde(rename = "write:account")]
|
|
WriteAccount,
|
|
#[serde(rename = "read:blocks")]
|
|
ReadBlocks,
|
|
#[serde(rename = "write:blocks")]
|
|
WriteBlocks,
|
|
#[serde(rename = "read:drive")]
|
|
ReadDrive,
|
|
#[serde(rename = "write:drive")]
|
|
WriteDrive,
|
|
#[serde(rename = "read:favorites")]
|
|
ReadFavorites,
|
|
#[serde(rename = "write:favorites")]
|
|
WriteFavorites,
|
|
#[serde(rename = "read:following")]
|
|
ReadFollowing,
|
|
#[serde(rename = "write:following")]
|
|
WriteFollowing,
|
|
#[serde(rename = "read:messaging")]
|
|
ReadMessaging,
|
|
#[serde(rename = "write:messaging")]
|
|
WriteMessaging,
|
|
#[serde(rename = "read:mutes")]
|
|
ReadMutes,
|
|
#[serde(rename = "write:mutes")]
|
|
WriteMutes,
|
|
#[serde(rename = "read:notes")]
|
|
ReadNotes,
|
|
#[serde(rename = "write:notes")]
|
|
WriteNotes,
|
|
#[serde(rename = "read:notifications")]
|
|
ReadNotifications,
|
|
#[serde(rename = "write:notifications")]
|
|
WriteNotifications,
|
|
#[serde(rename = "read:reactions")]
|
|
ReadReactions,
|
|
#[serde(rename = "write:reactions")]
|
|
WriteReactions,
|
|
#[serde(rename = "write:votes")]
|
|
WriteVotes,
|
|
#[serde(rename = "read:pages")]
|
|
ReadPages,
|
|
#[serde(rename = "write:pages")]
|
|
WritePages,
|
|
#[serde(rename = "read:page-likes")]
|
|
ReadPageLikes,
|
|
#[serde(rename = "write:page-likes")]
|
|
WritePageLikes,
|
|
#[serde(rename = "read:user-groups")]
|
|
ReadUserGroups,
|
|
#[serde(rename = "write:user-groups")]
|
|
WriteUserGroups,
|
|
#[serde(rename = "read:channels")]
|
|
ReadChannels,
|
|
#[serde(rename = "write:channels")]
|
|
WriteChannels,
|
|
#[serde(rename = "read:gallery")]
|
|
ReadGallery,
|
|
#[serde(rename = "write:gallery")]
|
|
WriteGallery,
|
|
#[serde(rename = "read:gallery-likes")]
|
|
ReadGalleryLikes,
|
|
#[serde(rename = "write:gallery-likes")]
|
|
WriteGalleryLikes,
|
|
}
|
|
|
|
impl Schema<Self> for App {}
|
|
|
|
pub static VALIDATOR: Lazy<JSONSchema> = Lazy::new(App::validator);
|
|
|
|
#[cfg(test)]
|
|
mod unit_test {
|
|
use pretty_assertions::assert_eq;
|
|
use serde_json::json;
|
|
|
|
use crate::util::id::{create_id, init_id};
|
|
use crate::util::random::gen_string;
|
|
|
|
use super::VALIDATOR;
|
|
|
|
#[test]
|
|
fn app_valid() {
|
|
init_id(12, "");
|
|
let instance = json!({
|
|
"id": create_id().unwrap(),
|
|
"name": "Test App",
|
|
"secret": gen_string(24),
|
|
"callbackUrl": "urn:ietf:wg:oauth:2.0:oob",
|
|
"permission": ["read:account", "write:account", "read:notes"],
|
|
});
|
|
|
|
assert!(VALIDATOR.is_valid(&instance));
|
|
}
|
|
|
|
#[test]
|
|
fn app_invalid() {
|
|
init_id(12, "");
|
|
let instance = json!({
|
|
"id": create_id().unwrap(),
|
|
// "name" is required
|
|
"name": null,
|
|
// "permission" must be one of the app permissions
|
|
"permission": ["write:invalid_perm", "write:notes"],
|
|
// "secret" is a nullable string
|
|
"secret": 123,
|
|
// "is_authorized" is a nullable boolean
|
|
"isAuthorized": "true-ish",
|
|
});
|
|
let result = VALIDATOR
|
|
.validate(&instance)
|
|
.expect_err("validation must fail");
|
|
let mut paths: Vec<String> = result
|
|
.map(|e| e.instance_path.to_string())
|
|
.filter(|e| !e.is_empty())
|
|
.collect();
|
|
paths.sort();
|
|
assert_eq!(
|
|
paths,
|
|
vec!["/isAuthorized", "/name", "/permission/0", "/secret"]
|
|
);
|
|
}
|
|
}
|