mirror of
https://github.com/kanidm/kanidm.git
synced 2025-02-24 04:57:00 +01:00
* fix(scim_proto): fixing an issue with building due to dependencies * feat(cli): more error message detail when things go wrong with images on the CLI
271 lines
7.3 KiB
Rust
271 lines
7.3 KiB
Rust
//! Kanidm internal elements
|
|
//!
|
|
//! Items defined in this module *may* change between releases without notice.
|
|
|
|
use crate::constants::{
|
|
CONTENT_TYPE_GIF, CONTENT_TYPE_JPG, CONTENT_TYPE_PNG, CONTENT_TYPE_SVG, CONTENT_TYPE_WEBP,
|
|
};
|
|
use clap::ValueEnum;
|
|
use serde::{Deserialize, Serialize};
|
|
use std::fmt;
|
|
use std::str::FromStr;
|
|
use url::Url;
|
|
use utoipa::ToSchema;
|
|
use uuid::Uuid;
|
|
|
|
use num_enum::TryFromPrimitive;
|
|
|
|
mod credupdate;
|
|
mod error;
|
|
mod raw;
|
|
mod token;
|
|
|
|
pub use self::credupdate::*;
|
|
pub use self::error::*;
|
|
pub use self::raw::*;
|
|
pub use self::token::*;
|
|
|
|
pub const COOKIE_AUTH_SESSION_ID: &str = "auth-session-id";
|
|
pub const COOKIE_BEARER_TOKEN: &str = "bearer";
|
|
pub const COOKIE_CU_SESSION_TOKEN: &str = "cu-session-token";
|
|
pub const COOKIE_USERNAME: &str = "username";
|
|
pub const COOKIE_OAUTH2_REQ: &str = "o2-authreq";
|
|
|
|
#[derive(Debug, Serialize, Deserialize, Clone, ToSchema)]
|
|
/// This is a description of a linked or connected application for a user. This is
|
|
/// used in the UI to render applications on the dashboard for a user to access.
|
|
pub enum AppLink {
|
|
Oauth2 {
|
|
name: String,
|
|
display_name: String,
|
|
redirect_url: Url,
|
|
// Whether this oauth2 resource has an image.
|
|
has_image: bool,
|
|
},
|
|
}
|
|
|
|
#[derive(
|
|
Debug, Serialize, Deserialize, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, ToSchema,
|
|
)]
|
|
#[serde(rename_all = "lowercase")]
|
|
#[derive(TryFromPrimitive)]
|
|
#[repr(u16)]
|
|
pub enum UiHint {
|
|
ExperimentalFeatures = 0,
|
|
PosixAccount = 1,
|
|
CredentialUpdate = 2,
|
|
SynchronisedAccount = 3,
|
|
}
|
|
|
|
impl fmt::Display for UiHint {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
match self {
|
|
UiHint::PosixAccount => write!(f, "PosixAccount"),
|
|
UiHint::CredentialUpdate => write!(f, "CredentialUpdate"),
|
|
UiHint::ExperimentalFeatures => write!(f, "ExperimentalFeatures"),
|
|
UiHint::SynchronisedAccount => write!(f, "SynchronisedAccount"),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl FromStr for UiHint {
|
|
type Err = ();
|
|
|
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
match s {
|
|
"CredentialUpdate" => Ok(UiHint::CredentialUpdate),
|
|
"PosixAccount" => Ok(UiHint::PosixAccount),
|
|
"ExperimentalFeatures" => Ok(UiHint::ExperimentalFeatures),
|
|
"SynchronisedAccount" => Ok(UiHint::SynchronisedAccount),
|
|
_ => Err(()),
|
|
}
|
|
}
|
|
}
|
|
|
|
// State machine states and transitions for the identity verification system feature!
|
|
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, ToSchema)]
|
|
pub enum IdentifyUserRequest {
|
|
Start,
|
|
SubmitCode { other_totp: u32 },
|
|
DisplayCode,
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, ToSchema)]
|
|
pub enum IdentifyUserResponse {
|
|
IdentityVerificationUnavailable,
|
|
IdentityVerificationAvailable,
|
|
ProvideCode { step: u32, totp: u32 },
|
|
WaitForCode,
|
|
Success,
|
|
CodeFailure,
|
|
InvalidUserId,
|
|
}
|
|
|
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Hash, Ord, PartialOrd, ValueEnum)]
|
|
#[serde(rename_all = "lowercase")]
|
|
pub enum ImageType {
|
|
Png,
|
|
Jpg,
|
|
Gif,
|
|
Svg,
|
|
Webp,
|
|
}
|
|
|
|
impl TryFrom<&str> for ImageType {
|
|
type Error = &'static str;
|
|
/// ```
|
|
/// use kanidm_proto::internal::ImageType;
|
|
/// assert_eq!(ImageType::try_from("png").unwrap(), ImageType::Png);
|
|
/// assert!(ImageType::try_from("krabs").is_err());
|
|
/// ```
|
|
fn try_from(value: &str) -> Result<Self, &'static str> {
|
|
#[allow(clippy::panic)]
|
|
match value {
|
|
"png" => Ok(Self::Png),
|
|
"jpg" => Ok(Self::Jpg),
|
|
"jpeg" => Ok(Self::Jpg), // ugh I hate this
|
|
"gif" => Ok(Self::Gif),
|
|
"svg" => Ok(Self::Svg),
|
|
"webp" => Ok(Self::Webp),
|
|
_ => Err("Invalid image type!"),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl ImageType {
|
|
pub fn try_from_content_type(content_type: &str) -> Result<Self, String> {
|
|
let content_type = content_type.to_lowercase();
|
|
match content_type.as_str() {
|
|
CONTENT_TYPE_JPG => Ok(ImageType::Jpg),
|
|
CONTENT_TYPE_PNG => Ok(ImageType::Png),
|
|
CONTENT_TYPE_GIF => Ok(ImageType::Gif),
|
|
CONTENT_TYPE_WEBP => Ok(ImageType::Webp),
|
|
CONTENT_TYPE_SVG => Ok(ImageType::Svg),
|
|
_ => Err(format!("Invalid content type: {}", content_type)),
|
|
}
|
|
}
|
|
|
|
pub fn as_content_type_str(&self) -> &'static str {
|
|
match &self {
|
|
ImageType::Jpg => CONTENT_TYPE_JPG,
|
|
ImageType::Png => CONTENT_TYPE_PNG,
|
|
ImageType::Gif => CONTENT_TYPE_GIF,
|
|
ImageType::Webp => CONTENT_TYPE_WEBP,
|
|
ImageType::Svg => CONTENT_TYPE_SVG,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug, PartialOrd, Ord, Hash)]
|
|
pub struct ImageValue {
|
|
pub filename: String,
|
|
pub filetype: ImageType,
|
|
pub contents: Vec<u8>,
|
|
}
|
|
|
|
impl TryFrom<&str> for ImageValue {
|
|
type Error = String;
|
|
fn try_from(s: &str) -> Result<Self, String> {
|
|
serde_json::from_str(s)
|
|
.map_err(|e| format!("Failed to decode ImageValue from {} - {:?}", s, e))
|
|
}
|
|
}
|
|
|
|
impl ImageValue {
|
|
pub fn new(filename: String, filetype: ImageType, contents: Vec<u8>) -> Self {
|
|
Self {
|
|
filename,
|
|
filetype,
|
|
contents,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[repr(u32)]
|
|
#[derive(Debug, Copy, Clone, Deserialize, Default, Eq, PartialEq)]
|
|
#[serde(rename_all = "lowercase")]
|
|
/// Filesystem type object, used for tuning database parameters.
|
|
pub enum FsType {
|
|
Zfs = 65536,
|
|
#[default]
|
|
#[serde(other)]
|
|
/// The default setting, if not set to "zfs"
|
|
Generic = 4096,
|
|
}
|
|
|
|
impl FsType {
|
|
pub fn checkpoint_pages(&self) -> u32 {
|
|
match self {
|
|
FsType::Generic => 2048,
|
|
FsType::Zfs => 256,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl TryFrom<&str> for FsType {
|
|
type Error = ();
|
|
|
|
fn try_from(s: &str) -> Result<Self, Self::Error> {
|
|
match s {
|
|
"zfs" => Ok(FsType::Zfs),
|
|
"generic" => Ok(FsType::Generic),
|
|
_ => Err(()),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize, Clone, Copy, ToSchema)]
|
|
pub enum Oauth2ClaimMapJoin {
|
|
#[serde(rename = "csv")]
|
|
Csv,
|
|
#[serde(rename = "ssv")]
|
|
Ssv,
|
|
#[serde(rename = "array")]
|
|
Array,
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
|
pub struct DomainInfo {
|
|
pub name: String,
|
|
pub displayname: String,
|
|
pub uuid: Uuid,
|
|
pub level: u32,
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
|
pub struct DomainUpgradeCheckReport {
|
|
pub name: String,
|
|
pub uuid: Uuid,
|
|
pub current_level: u32,
|
|
pub upgrade_level: u32,
|
|
pub report_items: Vec<DomainUpgradeCheckItem>,
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
|
pub enum DomainUpgradeCheckStatus {
|
|
Pass6To7Gidnumber,
|
|
Fail6To7Gidnumber,
|
|
|
|
Pass7To8SecurityKeys,
|
|
Fail7To8SecurityKeys,
|
|
|
|
Pass7To8Oauth2StrictRedirectUri,
|
|
Fail7To8Oauth2StrictRedirectUri,
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
|
pub struct DomainUpgradeCheckItem {
|
|
pub from_level: u32,
|
|
pub to_level: u32,
|
|
pub status: DomainUpgradeCheckStatus,
|
|
pub affected_entries: Vec<String>,
|
|
}
|
|
|
|
#[test]
|
|
fn test_fstype_deser() {
|
|
assert_eq!(FsType::try_from("zfs"), Ok(FsType::Zfs));
|
|
assert_eq!(FsType::try_from("generic"), Ok(FsType::Generic));
|
|
assert_eq!(FsType::try_from(" "), Err(()));
|
|
assert_eq!(FsType::try_from("crab🦀"), Err(()));
|
|
}
|