api: move config/user to access/users, implement change_password
To make it similar to the pve api
This commit is contained in:
parent
7d817b0358
commit
685e13347e
|
@ -1,4 +1,4 @@
|
||||||
mod access;
|
pub mod access;
|
||||||
pub mod admin;
|
pub mod admin;
|
||||||
pub mod backup;
|
pub mod backup;
|
||||||
pub mod config;
|
pub mod config;
|
||||||
|
|
|
@ -2,7 +2,7 @@ use failure::*;
|
||||||
|
|
||||||
use serde_json::{json, Value};
|
use serde_json::{json, Value};
|
||||||
|
|
||||||
use proxmox::api::api;
|
use proxmox::api::{api, RpcEnvironment};
|
||||||
use proxmox::api::router::{Router, SubdirMap};
|
use proxmox::api::router::{Router, SubdirMap};
|
||||||
use proxmox::sortable;
|
use proxmox::sortable;
|
||||||
use proxmox::{http_err, list_subdirs_api_method};
|
use proxmox::{http_err, list_subdirs_api_method};
|
||||||
|
@ -10,6 +10,9 @@ use proxmox::{http_err, list_subdirs_api_method};
|
||||||
use crate::tools;
|
use crate::tools;
|
||||||
use crate::tools::ticket::*;
|
use crate::tools::ticket::*;
|
||||||
use crate::auth_helpers::*;
|
use crate::auth_helpers::*;
|
||||||
|
use crate::api2::types::*;
|
||||||
|
|
||||||
|
pub mod user;
|
||||||
|
|
||||||
fn authenticate_user(username: &str, password: &str) -> Result<(), Error> {
|
fn authenticate_user(username: &str, password: &str) -> Result<(), Error> {
|
||||||
|
|
||||||
|
@ -32,13 +35,10 @@ fn authenticate_user(username: &str, password: &str) -> Result<(), Error> {
|
||||||
input: {
|
input: {
|
||||||
properties: {
|
properties: {
|
||||||
username: {
|
username: {
|
||||||
type: String,
|
schema: PROXMOX_USER_ID_SCHEMA,
|
||||||
description: "User name.",
|
|
||||||
max_length: 64,
|
|
||||||
},
|
},
|
||||||
password: {
|
password: {
|
||||||
type: String,
|
schema: PASSWORD_SCHEMA,
|
||||||
description: "The secret password. This can also be a valid ticket.",
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -87,12 +87,57 @@ fn create_ticket(username: String, password: String) -> Result<Value, Error> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[api(
|
||||||
|
input: {
|
||||||
|
properties: {
|
||||||
|
userid: {
|
||||||
|
schema: PROXMOX_USER_ID_SCHEMA,
|
||||||
|
},
|
||||||
|
password: {
|
||||||
|
schema: PASSWORD_SCHEMA,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)]
|
||||||
|
/// Change user password
|
||||||
|
///
|
||||||
|
/// Each user is allowed to change his own password. Superuser
|
||||||
|
/// can change all passwords.
|
||||||
|
fn change_password(
|
||||||
|
userid: String,
|
||||||
|
password: String,
|
||||||
|
rpcenv: &mut dyn RpcEnvironment,
|
||||||
|
) -> Result<Value, Error> {
|
||||||
|
|
||||||
|
let current_user = rpcenv.get_user()
|
||||||
|
.ok_or_else(|| format_err!("unknown user"))?;
|
||||||
|
|
||||||
|
let mut allowed = userid == current_user;
|
||||||
|
|
||||||
|
if userid == "root@pam" { allowed = true; }
|
||||||
|
|
||||||
|
if !allowed {
|
||||||
|
bail!("you are not authorized to change the password.");
|
||||||
|
}
|
||||||
|
|
||||||
|
let (username, realm) = crate::auth::parse_userid(&userid)?;
|
||||||
|
let authenticator = crate::auth::lookup_authenticator(&realm)?;
|
||||||
|
authenticator.store_password(&username, &password)?;
|
||||||
|
|
||||||
|
Ok(Value::Null)
|
||||||
|
}
|
||||||
|
|
||||||
#[sortable]
|
#[sortable]
|
||||||
const SUBDIRS: SubdirMap = &[
|
const SUBDIRS: SubdirMap = &[
|
||||||
|
(
|
||||||
|
"password", &Router::new()
|
||||||
|
.put(&API_METHOD_CHANGE_PASSWORD)
|
||||||
|
),
|
||||||
(
|
(
|
||||||
"ticket", &Router::new()
|
"ticket", &Router::new()
|
||||||
.post(&API_METHOD_CREATE_TICKET)
|
.post(&API_METHOD_CREATE_TICKET)
|
||||||
)
|
),
|
||||||
|
("users", &user::ROUTER),
|
||||||
];
|
];
|
||||||
|
|
||||||
pub const ROUTER: Router = Router::new()
|
pub const ROUTER: Router = Router::new()
|
||||||
|
|
|
@ -140,7 +140,7 @@ pub fn create_user(userid: String, password: Option<String>, param: Value) -> Re
|
||||||
userid: {
|
userid: {
|
||||||
schema: PROXMOX_USER_ID_SCHEMA,
|
schema: PROXMOX_USER_ID_SCHEMA,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
returns: {
|
returns: {
|
||||||
description: "The user configuration (with config digest).",
|
description: "The user configuration (with config digest).",
|
|
@ -3,12 +3,10 @@ use proxmox::list_subdirs_api_method;
|
||||||
|
|
||||||
pub mod datastore;
|
pub mod datastore;
|
||||||
pub mod remote;
|
pub mod remote;
|
||||||
pub mod user;
|
|
||||||
|
|
||||||
const SUBDIRS: SubdirMap = &[
|
const SUBDIRS: SubdirMap = &[
|
||||||
("datastore", &datastore::ROUTER),
|
("datastore", &datastore::ROUTER),
|
||||||
("remote", &remote::ROUTER),
|
("remote", &remote::ROUTER),
|
||||||
("user", &user::ROUTER),
|
|
||||||
];
|
];
|
||||||
|
|
||||||
pub const ROUTER: Router = Router::new()
|
pub const ROUTER: Router = Router::new()
|
||||||
|
|
|
@ -91,6 +91,17 @@ pub const PASSWORD_FORMAT: ApiStringFormat =
|
||||||
ApiStringFormat::Pattern(&PASSWORD_REGEX);
|
ApiStringFormat::Pattern(&PASSWORD_REGEX);
|
||||||
|
|
||||||
|
|
||||||
|
pub const PASSWORD_SCHEMA: Schema = StringSchema::new("Password.")
|
||||||
|
.format(&PASSWORD_FORMAT)
|
||||||
|
.min_length(1)
|
||||||
|
.max_length(64)
|
||||||
|
.schema();
|
||||||
|
|
||||||
|
pub const PBS_PASSWORD_SCHEMA: Schema = StringSchema::new("User Password.")
|
||||||
|
.format(&PASSWORD_FORMAT)
|
||||||
|
.min_length(5)
|
||||||
|
.max_length(64)
|
||||||
|
.schema();
|
||||||
|
|
||||||
pub const CERT_FINGERPRINT_SHA256_SCHEMA: Schema = StringSchema::new(
|
pub const CERT_FINGERPRINT_SHA256_SCHEMA: Schema = StringSchema::new(
|
||||||
"X509 certificate fingerprint (sha256)."
|
"X509 certificate fingerprint (sha256)."
|
||||||
|
|
|
@ -125,7 +125,7 @@ fn list_users(param: Value, rpcenv: &mut dyn RpcEnvironment) -> Result<Value, Er
|
||||||
|
|
||||||
let output_format = get_output_format(¶m);
|
let output_format = get_output_format(¶m);
|
||||||
|
|
||||||
let info = &api2::config::user::API_METHOD_LIST_USERS;
|
let info = &api2::access::user::API_METHOD_LIST_USERS;
|
||||||
let mut data = match info.handler {
|
let mut data = match info.handler {
|
||||||
ApiHandler::Sync(handler) => (handler)(param, info, rpcenv)?,
|
ApiHandler::Sync(handler) => (handler)(param, info, rpcenv)?,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
|
@ -152,18 +152,18 @@ fn user_commands() -> CommandLineInterface {
|
||||||
.insert(
|
.insert(
|
||||||
"create",
|
"create",
|
||||||
// fixme: howto handle password parameter?
|
// fixme: howto handle password parameter?
|
||||||
CliCommand::new(&api2::config::user::API_METHOD_CREATE_USER)
|
CliCommand::new(&api2::access::user::API_METHOD_CREATE_USER)
|
||||||
.arg_param(&["userid"])
|
.arg_param(&["userid"])
|
||||||
)
|
)
|
||||||
.insert(
|
.insert(
|
||||||
"update",
|
"update",
|
||||||
CliCommand::new(&api2::config::user::API_METHOD_UPDATE_USER)
|
CliCommand::new(&api2::access::user::API_METHOD_UPDATE_USER)
|
||||||
.arg_param(&["userid"])
|
.arg_param(&["userid"])
|
||||||
.completion_cb("userid", config::user::complete_user_name)
|
.completion_cb("userid", config::user::complete_user_name)
|
||||||
)
|
)
|
||||||
.insert(
|
.insert(
|
||||||
"remove",
|
"remove",
|
||||||
CliCommand::new(&api2::config::user::API_METHOD_DELETE_USER)
|
CliCommand::new(&api2::access::user::API_METHOD_DELETE_USER)
|
||||||
.arg_param(&["userid"])
|
.arg_param(&["userid"])
|
||||||
.completion_cb("userid", config::user::complete_user_name)
|
.completion_cb("userid", config::user::complete_user_name)
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue