2021-07-19 08:50:18 +00:00
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
|
2022-04-10 15:53:42 +00:00
|
|
|
use proxmox_schema::{api, BooleanSchema, IntegerSchema, Schema, StringSchema, Updater};
|
2021-07-19 08:50:18 +00:00
|
|
|
|
|
|
|
use super::userid::{Authid, Userid, PROXMOX_TOKEN_ID_SCHEMA};
|
2022-04-10 15:53:42 +00:00
|
|
|
use super::{SINGLE_LINE_COMMENT_FORMAT, SINGLE_LINE_COMMENT_SCHEMA};
|
2021-07-19 08:50:18 +00:00
|
|
|
|
|
|
|
pub const ENABLE_USER_SCHEMA: Schema = BooleanSchema::new(
|
2022-04-10 15:53:42 +00:00
|
|
|
"Enable the account (default). You can set this to '0' to disable the account.",
|
|
|
|
)
|
|
|
|
.default(true)
|
|
|
|
.schema();
|
2021-07-19 08:50:18 +00:00
|
|
|
|
|
|
|
pub const EXPIRE_USER_SCHEMA: Schema = IntegerSchema::new(
|
2022-04-10 15:53:42 +00:00
|
|
|
"Account expiration date (seconds since epoch). '0' means no expiration date.",
|
|
|
|
)
|
|
|
|
.default(0)
|
|
|
|
.minimum(0)
|
|
|
|
.schema();
|
2021-07-19 08:50:18 +00:00
|
|
|
|
|
|
|
pub const FIRST_NAME_SCHEMA: Schema = StringSchema::new("First name.")
|
|
|
|
.format(&SINGLE_LINE_COMMENT_FORMAT)
|
|
|
|
.min_length(2)
|
|
|
|
.max_length(64)
|
|
|
|
.schema();
|
|
|
|
|
|
|
|
pub const LAST_NAME_SCHEMA: Schema = StringSchema::new("Last name.")
|
|
|
|
.format(&SINGLE_LINE_COMMENT_FORMAT)
|
|
|
|
.min_length(2)
|
|
|
|
.max_length(64)
|
|
|
|
.schema();
|
|
|
|
|
|
|
|
pub const EMAIL_SCHEMA: Schema = StringSchema::new("E-Mail Address.")
|
|
|
|
.format(&SINGLE_LINE_COMMENT_FORMAT)
|
|
|
|
.min_length(2)
|
|
|
|
.max_length(64)
|
|
|
|
.schema();
|
|
|
|
|
|
|
|
#[api(
|
|
|
|
properties: {
|
|
|
|
userid: {
|
|
|
|
type: Userid,
|
|
|
|
},
|
|
|
|
comment: {
|
|
|
|
optional: true,
|
|
|
|
schema: SINGLE_LINE_COMMENT_SCHEMA,
|
|
|
|
},
|
|
|
|
enable: {
|
|
|
|
optional: true,
|
|
|
|
schema: ENABLE_USER_SCHEMA,
|
|
|
|
},
|
|
|
|
expire: {
|
|
|
|
optional: true,
|
|
|
|
schema: EXPIRE_USER_SCHEMA,
|
|
|
|
},
|
|
|
|
firstname: {
|
|
|
|
optional: true,
|
|
|
|
schema: FIRST_NAME_SCHEMA,
|
|
|
|
},
|
|
|
|
lastname: {
|
|
|
|
schema: LAST_NAME_SCHEMA,
|
|
|
|
optional: true,
|
|
|
|
},
|
|
|
|
email: {
|
|
|
|
schema: EMAIL_SCHEMA,
|
|
|
|
optional: true,
|
|
|
|
},
|
|
|
|
tokens: {
|
|
|
|
type: Array,
|
|
|
|
optional: true,
|
|
|
|
description: "List of user's API tokens.",
|
|
|
|
items: {
|
|
|
|
type: ApiToken
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
)]
|
2022-04-10 15:53:42 +00:00
|
|
|
#[derive(Serialize, Deserialize)]
|
2021-07-19 08:50:18 +00:00
|
|
|
/// User properties with added list of ApiTokens
|
|
|
|
pub struct UserWithTokens {
|
|
|
|
pub userid: Userid,
|
2022-04-10 15:53:42 +00:00
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
2021-07-19 08:50:18 +00:00
|
|
|
pub comment: Option<String>,
|
2022-04-10 15:53:42 +00:00
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
2021-07-19 08:50:18 +00:00
|
|
|
pub enable: Option<bool>,
|
2022-04-10 15:53:42 +00:00
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
2021-07-19 08:50:18 +00:00
|
|
|
pub expire: Option<i64>,
|
2022-04-10 15:53:42 +00:00
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
2021-07-19 08:50:18 +00:00
|
|
|
pub firstname: Option<String>,
|
2022-04-10 15:53:42 +00:00
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
2021-07-19 08:50:18 +00:00
|
|
|
pub lastname: Option<String>,
|
2022-04-10 15:53:42 +00:00
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
2021-07-19 08:50:18 +00:00
|
|
|
pub email: Option<String>,
|
2022-04-10 15:53:42 +00:00
|
|
|
#[serde(skip_serializing_if = "Vec::is_empty", default)]
|
2021-07-19 08:50:18 +00:00
|
|
|
pub tokens: Vec<ApiToken>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[api(
|
|
|
|
properties: {
|
|
|
|
tokenid: {
|
|
|
|
schema: PROXMOX_TOKEN_ID_SCHEMA,
|
|
|
|
},
|
|
|
|
comment: {
|
|
|
|
optional: true,
|
|
|
|
schema: SINGLE_LINE_COMMENT_SCHEMA,
|
|
|
|
},
|
|
|
|
enable: {
|
|
|
|
optional: true,
|
|
|
|
schema: ENABLE_USER_SCHEMA,
|
|
|
|
},
|
|
|
|
expire: {
|
|
|
|
optional: true,
|
|
|
|
schema: EXPIRE_USER_SCHEMA,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
)]
|
2022-04-10 15:53:42 +00:00
|
|
|
#[derive(Serialize, Deserialize)]
|
2021-07-19 08:50:18 +00:00
|
|
|
/// ApiToken properties.
|
|
|
|
pub struct ApiToken {
|
|
|
|
pub tokenid: Authid,
|
2022-04-10 15:53:42 +00:00
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
2021-07-19 08:50:18 +00:00
|
|
|
pub comment: Option<String>,
|
2022-04-10 15:53:42 +00:00
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
2021-07-19 08:50:18 +00:00
|
|
|
pub enable: Option<bool>,
|
2022-04-10 15:53:42 +00:00
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
2021-07-19 08:50:18 +00:00
|
|
|
pub expire: Option<i64>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ApiToken {
|
|
|
|
pub fn is_active(&self) -> bool {
|
|
|
|
if !self.enable.unwrap_or(true) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if let Some(expire) = self.expire {
|
2022-04-10 15:53:42 +00:00
|
|
|
let now = proxmox_time::epoch_i64();
|
2021-07-19 08:50:18 +00:00
|
|
|
if expire > 0 && expire <= now {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[api(
|
|
|
|
properties: {
|
|
|
|
userid: {
|
|
|
|
type: Userid,
|
|
|
|
},
|
|
|
|
comment: {
|
|
|
|
optional: true,
|
|
|
|
schema: SINGLE_LINE_COMMENT_SCHEMA,
|
|
|
|
},
|
|
|
|
enable: {
|
|
|
|
optional: true,
|
|
|
|
schema: ENABLE_USER_SCHEMA,
|
|
|
|
},
|
|
|
|
expire: {
|
|
|
|
optional: true,
|
|
|
|
schema: EXPIRE_USER_SCHEMA,
|
|
|
|
},
|
|
|
|
firstname: {
|
|
|
|
optional: true,
|
|
|
|
schema: FIRST_NAME_SCHEMA,
|
|
|
|
},
|
|
|
|
lastname: {
|
|
|
|
schema: LAST_NAME_SCHEMA,
|
|
|
|
optional: true,
|
|
|
|
},
|
|
|
|
email: {
|
|
|
|
schema: EMAIL_SCHEMA,
|
|
|
|
optional: true,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
)]
|
2022-04-10 15:53:42 +00:00
|
|
|
#[derive(Serialize, Deserialize, Updater)]
|
2021-07-19 08:50:18 +00:00
|
|
|
/// User properties.
|
|
|
|
pub struct User {
|
2021-09-09 11:14:28 +00:00
|
|
|
#[updater(skip)]
|
2021-07-19 08:50:18 +00:00
|
|
|
pub userid: Userid,
|
2022-04-10 15:53:42 +00:00
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
2021-07-19 08:50:18 +00:00
|
|
|
pub comment: Option<String>,
|
2022-04-10 15:53:42 +00:00
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
2021-07-19 08:50:18 +00:00
|
|
|
pub enable: Option<bool>,
|
2022-04-10 15:53:42 +00:00
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
2021-07-19 08:50:18 +00:00
|
|
|
pub expire: Option<i64>,
|
2022-04-10 15:53:42 +00:00
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
2021-07-19 08:50:18 +00:00
|
|
|
pub firstname: Option<String>,
|
2022-04-10 15:53:42 +00:00
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
2021-07-19 08:50:18 +00:00
|
|
|
pub lastname: Option<String>,
|
2022-04-10 15:53:42 +00:00
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
2021-07-19 08:50:18 +00:00
|
|
|
pub email: Option<String>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl User {
|
|
|
|
pub fn is_active(&self) -> bool {
|
|
|
|
if !self.enable.unwrap_or(true) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if let Some(expire) = self.expire {
|
2022-04-10 15:53:42 +00:00
|
|
|
let now = proxmox_time::epoch_i64();
|
2021-07-19 08:50:18 +00:00
|
|
|
if expire > 0 && expire <= now {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
true
|
|
|
|
}
|
|
|
|
}
|