From: Marcin Haba Date: Fri, 12 Nov 2021 19:23:21 +0000 (+0100) Subject: baculum: Add API endpoints for API basic user management X-Git-Tag: Release-11.0.6~37 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a6fd01ed2170a5c1bfcba41672b0dc29da7d2d3c;p=thirdparty%2Fbacula.git baculum: Add API endpoints for API basic user management --- diff --git a/gui/baculum/protected/API/Class/BasicConfig.php b/gui/baculum/protected/API/Class/BasicConfig.php index b41ecc902..84e4fd584 100644 --- a/gui/baculum/protected/API/Class/BasicConfig.php +++ b/gui/baculum/protected/API/Class/BasicConfig.php @@ -131,6 +131,31 @@ class BasicConfig extends ConfigFileModule { return $is_valid; } + /** + * Get users. + * NOTE: User list bases on basic password file. + * @see BasicAPIUserConfig + * + * @return array basic user list + */ + public function getUsers() { + $basic_users = []; + $basic_apiuser = $this->getModule('basic_apiuser')->getUsers(); + $basic_config = $this->getConfig(); + foreach($basic_apiuser as $user => $pwd) { + $bconsole_cfg_path = ''; + if (key_exists($user, $basic_config) && key_exists('bconsole_cfg_path', $basic_config[$user])) { + $bconsole_cfg_path = $basic_config[$user]['bconsole_cfg_path']; + } + $basic_users[] = [ + 'username' => $user, + 'bconsole_cfg_path' => $bconsole_cfg_path + ]; + } + return $basic_users; + + } + /** * Add single basic user to config. * NOTE: Basic password hashes are stored in separate file. @@ -198,15 +223,18 @@ class BasicConfig extends ConfigFileModule { * @return boolean true on success, otherwise false */ public function removeUser($username) { - $success = false; $config = $this->getConfig(); if (key_exists($username, $config)) { unset($config[$username]); - $success = $this->setConfig($config); - } - if ($success) { - $success = $this->getModule('basic_apiuser')->removeUser($username); + $this->setConfig($config); } + /** + * There is returned only state of removing user from password file because + * because user can be defined in password file but it does not have + * to be defined in basic.conf file. It is for backward compatibility + * with config files. + */ + $success = $this->getModule('basic_apiuser')->removeUser($username); return $success; } } diff --git a/gui/baculum/protected/API/Lang/en/messages.mo b/gui/baculum/protected/API/Lang/en/messages.mo index d00e4cca8..17872bad2 100644 Binary files a/gui/baculum/protected/API/Lang/en/messages.mo and b/gui/baculum/protected/API/Lang/en/messages.mo differ diff --git a/gui/baculum/protected/API/Lang/en/messages.po b/gui/baculum/protected/API/Lang/en/messages.po index a001c3226..dfe00ea0e 100644 --- a/gui/baculum/protected/API/Lang/en/messages.po +++ b/gui/baculum/protected/API/Lang/en/messages.po @@ -685,3 +685,6 @@ msgstr "Binaries:" msgid "Configs:" msgstr "Configs:" + +msgid "Dedicated Bconsole config" +msgstr "Dedicated Bconsole config" diff --git a/gui/baculum/protected/API/Lang/pl/messages.mo b/gui/baculum/protected/API/Lang/pl/messages.mo index b1faff572..afd1d1e20 100644 Binary files a/gui/baculum/protected/API/Lang/pl/messages.mo and b/gui/baculum/protected/API/Lang/pl/messages.mo differ diff --git a/gui/baculum/protected/API/Lang/pl/messages.po b/gui/baculum/protected/API/Lang/pl/messages.po index cc7c55fc0..208a35044 100644 --- a/gui/baculum/protected/API/Lang/pl/messages.po +++ b/gui/baculum/protected/API/Lang/pl/messages.po @@ -691,3 +691,6 @@ msgstr "Pliki bin.:" msgid "Configs:" msgstr "Pliki konfig.:" + +msgid "Dedicated Bconsole config" +msgstr "Dedykowana konfiguracja Bconsole" diff --git a/gui/baculum/protected/API/Lang/pt/messages.mo b/gui/baculum/protected/API/Lang/pt/messages.mo index a7351ef70..7d8008aa7 100644 Binary files a/gui/baculum/protected/API/Lang/pt/messages.mo and b/gui/baculum/protected/API/Lang/pt/messages.mo differ diff --git a/gui/baculum/protected/API/Lang/pt/messages.po b/gui/baculum/protected/API/Lang/pt/messages.po index 1c3ce986b..0c5d798ff 100644 --- a/gui/baculum/protected/API/Lang/pt/messages.po +++ b/gui/baculum/protected/API/Lang/pt/messages.po @@ -692,3 +692,6 @@ msgstr "Binários:" msgid "Configs:" msgstr "Configurações:" + +msgid "Dedicated Bconsole config" +msgstr "Dedicated Bconsole config" diff --git a/gui/baculum/protected/API/Lang/ru/messages.mo b/gui/baculum/protected/API/Lang/ru/messages.mo index ecd7ee8b0..5d14856f5 100644 Binary files a/gui/baculum/protected/API/Lang/ru/messages.mo and b/gui/baculum/protected/API/Lang/ru/messages.mo differ diff --git a/gui/baculum/protected/API/Lang/ru/messages.po b/gui/baculum/protected/API/Lang/ru/messages.po index 6cae288e3..64c13649f 100644 --- a/gui/baculum/protected/API/Lang/ru/messages.po +++ b/gui/baculum/protected/API/Lang/ru/messages.po @@ -692,3 +692,6 @@ msgstr "Двоичные файлы:" msgid "Configs:" msgstr "Настройка:" + +msgid "Dedicated Bconsole config" +msgstr "Dedicated Bconsole config" diff --git a/gui/baculum/protected/API/Pages/API/BasicUser.php b/gui/baculum/protected/API/Pages/API/BasicUser.php new file mode 100644 index 000000000..a9e87cd32 --- /dev/null +++ b/gui/baculum/protected/API/Pages/API/BasicUser.php @@ -0,0 +1,273 @@ + + * @category API + * @package Baculum API + */ +class BasicUser extends BaculumAPIServer { + + public function get() { + $user = $this->Request->contains('id') ? $this->Request['id'] : 0; + $username = $this->getModule('basic_apiuser')->validateUsername($user) ? $user : null; + if (is_string($username)) { + $basic_config = $this->getModule('basic_config')->getConfig($username); + if (count($basic_config) > 0) { + $this->output = array_merge($basic_config, ['username' => $username]); + $this->error = BasicUserError::ERROR_NO_ERRORS; + } else { + $this->output = BasicUserError::MSG_ERROR_BASIC_USER_DOES_NOT_EXIST; + $this->error = BasicUserError::ERROR_BASIC_USER_DOES_NOT_EXIST; + } + } else { + $this->output = BasicUserError::MSG_ERROR_BASIC_USER_INVALID_USERNAME; + $this->error = BasicUserError::ERROR_BASIC_USER_INVALID_USERNAME; + } + } + + public function create($params) { + $basic_apiuser = $this->getModule('basic_apiuser'); + $basic_config = $this->getModule('basic_config'); + $misc = $this->getModule('misc'); + $basic_cfg = $basic_apiuser->getUsers(); + $username = ''; + $password = ''; + $props = []; + + if (property_exists($params, 'username') && key_exists($params->username, $basic_cfg)) { + $this->output = BasicUserError::MSG_ERROR_BASIC_USER_ALREADY_EXISTS; + $this->error = BasicUserError::ERROR_BASIC_USER_ALREADY_EXISTS; + return; + } + + if (property_exists($params, 'username') && $basic_apiuser->validateUsername($params->username)) { + $username = $params->username; + } else { + $this->output = BasicUserError::MSG_ERROR_BASIC_USER_INVALID_USERNAME; + $this->error = BasicUserError::ERROR_BASIC_USER_INVALID_USERNAME; + return; + } + + if (property_exists($params, 'password')) { + $password = $params->password; + } else { + $this->output = BasicUserError::MSG_ERROR_BASIC_USER_INVALID_PASSWORD; + $this->error = BasicUserError::ERROR_BASIC_USER_INVALID_PASSWORD; + return; + } + + if (property_exists($params, 'bconsole_cfg_path')) { + if ($misc->isValidPath($params->bconsole_cfg_path)) { + $props['bconsole_cfg_path'] = $params->bconsole_cfg_path; + } else { + $this->output = BasicUserError::MSG_ERROR_BASIC_USER_INVALID_BCONSOLE_CFG_PATH; + $this->error = BasicUserError::ERROR_BASIC_USER_INVALID_BCONSOLE_CFG_PATH; + return; + } + } else { + $props['bconsole_cfg_path'] = ''; + } + + if (property_exists($params, 'console') && property_exists($params, 'director')) { + if (!$misc->isValidName($params->console)) { + $this->output = BasicUserError::MSG_ERROR_BASIC_USER_INVALID_CONSOLE; + $this->error = BasicUserError::ERROR_BASIC_USER_INVALID_CONSOLE; + return; + } + if (!$misc->isValidName($params->director)) { + $this->output = BasicUserError::MSG_ERROR_BASIC_USER_INVALID_DIRECTOR; + $this->error = BasicUserError::ERROR_BASIC_USER_INVALID_DIRECTOR; + return; + } + $bs = $this->getModule('bacula_setting'); + + $dir_cfg = $bs->getConfig('bcons', 'Director', $params->director); + if ($dir_cfg['exitcode'] != 0) { + $this->output = $dir_cfg['output']; + $this->error = BasicUserError::ERROR_INTERNAL_ERROR; + return; + } + + $console_cfg = $bs->getConfig('dir', 'Console', $params->console); + if ($console_cfg['exitcode'] != 0) { + $this->output = $console_cfg['output']; + $this->error = BasicUserError::ERROR_INTERNAL_ERROR; + return; + } + + $cfg = [ + [ + 'Director' => [ + 'Name' => '"' . $dir_cfg['output']['Name'] . '"', + 'DirPort' => $dir_cfg['output']['DirPort'], + 'Address' => $dir_cfg['output']['Address'], + 'Password' => 'XXXX' + ], + 'Console' => [ + 'Name' => '"' . $console_cfg['output']['Name'] . '"', + 'Password' => '"' . $console_cfg['output']['Password'] . '"' + ] + ] + ]; + $json_tools = $this->getModule('api_config')->getConfig('jsontools'); + $dir = $json_tools['bconfig_dir']; + $file = sprintf('%s/bconsole-%s.cfg', $dir, $console_cfg['output']['Name']); + $this->getModule('bacula_config')->setConfig('bcons', $cfg, $file); + $props['bconsole_cfg_path'] = $file; + } + + // save config + $result = $basic_config->addUser($username, $password, $props); + + if ($result) { + $this->output = $props; + $this->error = BasicUserError::ERROR_NO_ERRORS; + } else { + $this->output = BasicUserError::MSG_ERROR_INTERNAL_ERROR; + $this->error = BasicUserError::ERROR_INTERNAL_ERROR; + } + } + + public function set($id, $params) { + $basic_apiuser = $this->getModule('basic_apiuser'); + $basic_config = $this->getModule('basic_config'); + $misc = $this->getModule('misc'); + $basic_cfg = $basic_apiuser->getUsers(); + $username = ''; + $password = ''; + $props = []; + + if (property_exists($params, 'username') && !key_exists($params->username, $basic_cfg)) { + $this->output = BasicUserError::MSG_ERROR_BASIC_USER_DOES_NOT_EXIST; + $this->error = BasicUserError::ERROR_BASIC_USER_DOES_NOT_EXIST; + return; + } + + if (property_exists($params, 'username') && $basic_apiuser->validateUsername($params->username)) { + $username = $params->username; + } else { + $this->output = BasicUserError::MSG_ERROR_BASIC_USER_INVALID_USERNAME; + $this->error = BasicUserError::ERROR_BASIC_USER_INVALID_USERNAME; + return; + } + + if (property_exists($params, 'password')) { + $password = $params->password; + } else { + $this->output = BasicUserError::MSG_ERROR_BASIC_USER_INVALID_PASSWORD; + $this->error = BasicUserError::ERROR_BASIC_USER_INVALID_PASSWORD; + return; + } + + if (property_exists($params, 'bconsole_cfg_path')) { + if ($misc->isValidPath($params->bconsole_cfg_path)) { + $props['bconsole_cfg_path'] = $params->bconsole_cfg_path; + } else { + $this->output = BasicUserError::MSG_ERROR_BASIC_USER_INVALID_BCONSOLE_CFG_PATH; + $this->error = BasicUserError::ERROR_BASIC_USER_INVALID_BCONSOLE_CFG_PATH; + return; + } + } else { + $props['bconsole_cfg_path'] = ''; + } + + if (property_exists($params, 'console') && property_exists($params, 'director')) { + if (!$misc->isValidName($params->console)) { + $this->output = BasicUserError::MSG_ERROR_BASIC_USER_INVALID_CONSOLE; + $this->error = BasicUserError::ERROR_BASIC_USER_INVALID_CONSOLE; + return; + } + if (!$misc->isValidName($params->director)) { + $this->output = BasicUserError::MSG_ERROR_BASIC_USER_INVALID_DIRECTOR; + $this->error = BasicUserError::ERROR_BASIC_USER_INVALID_DIRECTOR; + return; + } + $bs = $this->getModule('bacula_setting'); + + $dir_cfg = $bs->getConfig('bcons', 'Director', $params->director); + if ($dir_cfg['exitcode'] != 0) { + $this->output = $dir_cfg['output']; + $this->error = BasicUserError::ERROR_INTERNAL_ERROR; + return; + } + + $console_cfg = $bs->getConfig('dir', 'Console', $params->console); + if ($console_cfg['exitcode'] != 0) { + $this->output = $console_cfg['output']; + $this->error = BasicUserError::ERROR_INTERNAL_ERROR; + return; + } + + $cfg = [ + [ + 'Director' => [ + 'Name' => '"' . $dir_cfg['output']['Name'] . '"', + 'DirPort' => $dir_cfg['output']['DirPort'], + 'Address' => $dir_cfg['output']['Address'], + 'Password' => 'XXXX' + ], + 'Console' => [ + 'Name' => '"' . $console_cfg['output']['Name'] . '"', + 'Password' => '"' . $console_cfg['output']['Password'] . '"' + ] + ] + ]; + $json_tools = $this->getModule('api_config')->getConfig('jsontools'); + $dir = $json_tools['bconfig_dir']; + $file = sprintf('%s/bconsole-%s.cfg', $dir, $console_cfg['output']['Name']); + $this->getModule('bacula_config')->setConfig('bcons', $cfg, $file); + $props['bconsole_cfg_path'] = $file; + } + + // save config + $result = $basic_config->editUser($username, $password, $props); + + if ($result) { + $this->output = $props; + $this->error = BasicUserError::ERROR_NO_ERRORS; + } else { + $this->output = BasicUserError::MSG_ERROR_INTERNAL_ERROR; + $this->error = BasicUserError::ERROR_INTERNAL_ERROR; + } + } + + public function remove($id) { + $user_cfg = $this->getModule('basic_apiuser')->getUserCfg($id); + if (count($user_cfg) > 0) { + $result = $this->getModule('basic_config')->removeUser($id); + if ($result) { + $this->output = []; + $this->error = BasicUserError::ERROR_NO_ERRORS; + } else { + $this->output = BasicUserError::MSG_ERROR_INTERNAL_ERROR; + $this->error = BasicUserError::ERROR_INTERNAL_ERROR; + } + } else { + $this->output = BasicUserError::MSG_ERROR_BASIC_USER_DOES_NOT_EXIST; + $this->error = BasicUserError::ERROR_BASIC_USER_DOES_NOT_EXIST; + } + } +} +?> diff --git a/gui/baculum/protected/API/Pages/API/BasicUsers.php b/gui/baculum/protected/API/Pages/API/BasicUsers.php new file mode 100644 index 000000000..7c676f234 --- /dev/null +++ b/gui/baculum/protected/API/Pages/API/BasicUsers.php @@ -0,0 +1,37 @@ + + * @category API + * @package Baculum API + */ +class BasicUsers extends BaculumAPIServer { + + public function get() { + $this->output = $this->getModule('basic_config')->getUsers();; + $this->error = ClientError::ERROR_NO_ERRORS; + } +} +?> diff --git a/gui/baculum/protected/API/Pages/API/OAuth2Client.php b/gui/baculum/protected/API/Pages/API/OAuth2Client.php index 52fbbf4dc..ab291bba4 100644 --- a/gui/baculum/protected/API/Pages/API/OAuth2Client.php +++ b/gui/baculum/protected/API/Pages/API/OAuth2Client.php @@ -3,7 +3,7 @@ * Bacula(R) - The Network Backup Solution * Baculum - Bacula web interface * - * Copyright (C) 2013-2020 Kern Sibbald + * Copyright (C) 2013-2021 Kern Sibbald * * The main author of Baculum is Marcin Haba. * The original author of Bacula is Kern Sibbald, with contributions @@ -130,14 +130,14 @@ class OAuth2Client extends BaculumAPIServer { $dir_cfg = $bs->getConfig('bcons', 'Director', $params->director); if ($dir_cfg['exitcode'] != 0) { - $this->output = $dir_cfg->output; + $this->output = $dir_cfg['output']; $this->error = OAuth2Error::ERROR_INTERNAL_ERROR; return; } $console_cfg = $bs->getConfig('dir', 'Console', $params->console); if ($console_cfg['exitcode'] != 0) { - $this->output = $console_cfg->output; + $this->output = $console_cfg['output']; $this->error = OAuth2Error::ERROR_INTERNAL_ERROR; return; } @@ -257,14 +257,14 @@ class OAuth2Client extends BaculumAPIServer { $dir_cfg = $bs->getConfig('bcons', 'Director', $params->director); if ($dir_cfg['exitcode'] != 0) { - $this->output = $dir_cfg->output; + $this->output = $dir_cfg['output']; $this->error = OAuth2Error::ERROR_INTERNAL_ERROR; return; } $console_cfg = $bs->getConfig('dir', 'Console', $params->console); if ($console_cfg['exitcode'] != 0) { - $this->output = $console_cfg->output; + $this->output = $console_cfg['output']; $this->error = OAuth2Error::ERROR_INTERNAL_ERROR; return; } diff --git a/gui/baculum/protected/API/Pages/API/config.xml b/gui/baculum/protected/API/Pages/API/config.xml index a44502c1a..c5cc3731f 100644 --- a/gui/baculum/protected/API/Pages/API/config.xml +++ b/gui/baculum/protected/API/Pages/API/config.xml @@ -11,6 +11,7 @@ + diff --git a/gui/baculum/protected/API/Pages/API/endpoints.xml b/gui/baculum/protected/API/Pages/API/endpoints.xml index 6e54bf056..4f507d65d 100644 --- a/gui/baculum/protected/API/Pages/API/endpoints.xml +++ b/gui/baculum/protected/API/Pages/API/endpoints.xml @@ -109,6 +109,9 @@ + + + diff --git a/gui/baculum/protected/API/Pages/Panel/APIBasicUsers.php b/gui/baculum/protected/API/Pages/Panel/APIBasicUsers.php index d9c6f278a..ea93bc0fe 100644 --- a/gui/baculum/protected/API/Pages/Panel/APIBasicUsers.php +++ b/gui/baculum/protected/API/Pages/Panel/APIBasicUsers.php @@ -46,7 +46,7 @@ class APIBasicUsers extends BaculumAPIPage { } public function loadBasicUsers($sender, $param) { - $users = $this->getBasicUsers(); + $users = $this->getModule('basic_config')->getUsers(); $this->getCallbackClient()->callClientFunction( 'oAPIBasicUsers.load_basic_users_cb', [$users] @@ -74,23 +74,6 @@ class APIBasicUsers extends BaculumAPIPage { } } - private function getBasicUsers() { - $basic_users = array(); - $basic_apiuser = $this->getModule('basic_apiuser')->getUsers(); - $basic_config = $this->getModule('basic_config')->getConfig(); - foreach($basic_apiuser as $user => $pwd) { - $bconsole_cfg_path = ''; - if (key_exists($user, $basic_config) && key_exists('bconsole_cfg_path', $basic_config[$user])) { - $bconsole_cfg_path = $basic_config[$user]['bconsole_cfg_path']; - } - $basic_users[] = [ - 'username' => $user, - 'bconsole_cfg_path' => $bconsole_cfg_path - ]; - } - return $basic_users; - } - public function deleteBasicUser($sender, $param) { $username = $param->getCallbackParameter(); $this->getModule('basic_config')->removeUser($username); diff --git a/gui/baculum/protected/API/openapi_baculum.json b/gui/baculum/protected/API/openapi_baculum.json index 472c55d48..4df9b3e05 100644 --- a/gui/baculum/protected/API/openapi_baculum.json +++ b/gui/baculum/protected/API/openapi_baculum.json @@ -108,6 +108,15 @@ "OAuth2Client": { "$ref": "#/definitions/OAuth2Client" }, + "BasicUsers": { + "type": "array", + "items": { + "$ref": "#/definitions/BasicUser" + } + }, + "BasicUser": { + "$ref": "#/definitions/BasicUser" + }, "AutochangerDriveVolume": { "$ref": "#/definitions/AutochangerDriveVolume" }, @@ -5540,6 +5549,24 @@ "type": "string" } }, + { + "name": "console", + "in": "body", + "required": false, + "description": "Director Console name to create dedicated bconsole.conf that is assigned to account. Parameter must be used together with 'director' parameter.", + "schema": { + "type": "string" + } + }, + { + "name": "director", + "in": "body", + "required": false, + "description": "Director Name to create dedicated bconsole.conf that is assigned to account. Parameter must be used together with 'console' parameter.", + "schema": { + "type": "string" + } + }, { "name": "name", "in": "body", @@ -5625,6 +5652,24 @@ "type": "string" } }, + { + "name": "console", + "in": "body", + "required": false, + "description": "Director Console name to create dedicated bconsole.conf that is assigned to account. Parameter must be used together with 'director' parameter.", + "schema": { + "type": "string" + } + }, + { + "name": "director", + "in": "body", + "required": false, + "description": "Director Name to create dedicated bconsole.conf that is assigned to account. Parameter must be used together with 'console' parameter.", + "schema": { + "type": "string" + } + }, { "name": "name", "in": "body", @@ -5676,6 +5721,267 @@ } ] } + }, + "/api/v2/basic/users": { + "get": { + "tags": ["basic"], + "summary": "Basic user list", + "description": "Get Basic user list.", + "responses": { + "200": { + "description": "List of Basic users properties", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "output": { + "$ref": "#/components/schemas/BasicUsers" + }, + "error": { + "type": "integer", + "description": "Error code", + "enum": [0, 1000] + } + } + } + } + } + } + } + } + }, + "/api/v2/basic/users/{username}": { + "get": { + "tags": ["basic"], + "summary": "Specific Basic user config", + "description": "Get specific Basic user config", + "responses": { + "200": { + "description": "Specific Basic user config", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "output": { + "$ref": "#/components/schemas/BasicUser" + }, + "error": { + "type": "integer", + "description": "Error code", + "enum": [0, 140, 142, 1000] + } + } + } + } + } + } + }, + "parameters": [ + { + "name": "username", + "in": "path", + "required": true, + "description": "Basic user name", + "schema": { + "type": "string" + } + } + ] + }, + "put": { + "tags": ["basic"], + "summary": "Set Basic user settings", + "description": "Set specific Basic user settings", + "consumes": [ "application/json" ], + "responses": { + "200": { + "description": "Set Basic user settings", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "output": { + "type": "object", + "description": "Updated Basic user settings" + }, + "error": { + "type": "integer", + "description": "Error code", + "enum": [0, 140, 142, 143, 144, 145, 146, 1000] + } + } + } + } + } + } + }, + "parameters": [ + { + "name": "username", + "in": "path", + "required": true, + "description": "Basic user name", + "schema": { + "type": "string" + } + }, + { + "name": "password", + "in": "body", + "required": false, + "description": "Basic user password", + "schema": { + "type": "string" + } + }, + { + "name": "bconsole_cfg_path", + "in": "body", + "required": false, + "description": "Dedicated Bconsole configuration file path", + "schema": { + "type": "string" + } + }, + { + "name": "console", + "in": "body", + "required": false, + "description": "Director Console name to create dedicated bconsole.conf that is assigned to account. Parameter must be used together with 'director' parameter.", + "schema": { + "type": "string" + } + }, + { + "name": "director", + "in": "body", + "required": false, + "description": "Director Name to create dedicated bconsole.conf that is assigned to account. Parameter must be used together with 'console' parameter.", + "schema": { + "type": "string" + } + } + ] + }, + "post": { + "tags": ["basic"], + "summary": "Create Basic user account", + "description": "Create specific Basic user account", + "consumes": [ "application/json" ], + "responses": { + "200": { + "description": "Create Basic user account", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "output": { + "type": "object", + "description": "New Basic user settings" + }, + "error": { + "type": "integer", + "description": "Error code", + "enum": [0, 141, 142, 143, 144, 145, 146, 1000] + } + } + } + } + } + } + }, + "parameters": [ + { + "name": "username", + "in": "path", + "required": true, + "description": "Basic user name", + "schema": { + "type": "string" + } + }, + { + "name": "password", + "in": "body", + "required": true, + "description": "Basic user password", + "schema": { + "type": "string" + } + }, + { + "name": "bconsole_cfg_path", + "in": "body", + "required": false, + "description": "Dedicated Bconsole configuration file path", + "schema": { + "type": "string" + } + }, + { + "name": "console", + "in": "body", + "required": false, + "description": "Director Console name to create dedicated bconsole.conf that is assigned to account. Parameter must be used together with 'director' parameter.", + "schema": { + "type": "string" + } + }, + { + "name": "director", + "in": "body", + "required": false, + "description": "Director Name to create dedicated bconsole.conf that is assigned to account. Parameter must be used together with 'console' parameter.", + "schema": { + "type": "string" + } + } + ] + }, + "delete": { + "tags": ["basic"], + "summary": "Delete Basic user account", + "description": "Delete Basic user account.", + "responses": { + "200": { + "description": "Delete Basic user account", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "output": { + "type": "array", + "items": { + } + }, + "error": { + "type": "integer", + "description": "Error code", + "enum": [0, 140, 1000] + } + } + } + } + } + } + }, + "parameters": [ + { + "name": "username", + "in": "path", + "required": true, + "description": "Basic user name", + "schema": { + "type": "string" + } + } + ] + } } }, "definitions": { @@ -6340,6 +6646,19 @@ } } }, + "BasicUser": { + "type": "object", + "properties": { + "bconsole_cfg_path": { + "description": "Dedicated Bconsole configuration file", + "type": "string" + }, + "username": { + "description": "User login name", + "type": "string" + } + } + }, "AutochangerDriveVolume": { "type": "object", "properties": { diff --git a/gui/baculum/protected/Common/Class/BasicUserConfig.php b/gui/baculum/protected/Common/Class/BasicUserConfig.php index 68c340e09..0b5d891a6 100644 --- a/gui/baculum/protected/Common/Class/BasicUserConfig.php +++ b/gui/baculum/protected/Common/Class/BasicUserConfig.php @@ -3,7 +3,7 @@ * Bacula(R) - The Network Backup Solution * Baculum - Bacula web interface * - * Copyright (C) 2013-2020 Kern Sibbald + * Copyright (C) 2013-2021 Kern Sibbald * * The main author of Baculum is Marcin Haba. * The original author of Bacula is Kern Sibbald, with contributions @@ -41,6 +41,11 @@ class BasicUserConfig extends CommonModule { */ const USER_PATTERN = '[a-zA-Z0-9]+'; + /** + * Password allowed characters pattern. + */ + const PASSWORD_PATTERN = '[\S\s]{5,60}'; + /** * Get config file path to store users' parameters. * @return string config path @@ -195,7 +200,6 @@ class BasicUserConfig extends CommonModule { * @return boolean true if users removed successfully, otherwise false */ public function removeUsers(array $usernames) { - $result = false; $all_users = $this->getUsers(); for ($i = 0; $i < count($usernames); $i++) { if (key_exists($usernames[$i], $all_users)) { @@ -225,4 +229,8 @@ class BasicUserConfig extends CommonModule { $result = file_put_contents($this->getConfigPath(), '', LOCK_EX) !== false; return $result; } + + public function validateUsername($username) { + return (preg_match('/^' . self::USER_PATTERN . '$/', $username) === 1); + } } diff --git a/gui/baculum/protected/Common/Class/Errors.php b/gui/baculum/protected/Common/Class/Errors.php index b5537b34c..3ed0823ca 100644 --- a/gui/baculum/protected/Common/Class/Errors.php +++ b/gui/baculum/protected/Common/Class/Errors.php @@ -3,7 +3,7 @@ * Bacula(R) - The Network Backup Solution * Baculum - Bacula web interface * - * Copyright (C) 2013-2020 Kern Sibbald + * Copyright (C) 2013-2021 Kern Sibbald * * The main author of Baculum is Marcin Haba. * The original author of Bacula is Kern Sibbald, with contributions @@ -247,4 +247,22 @@ class DeviceError extends GenericError { const MSG_ERROR_DEVICE_DRIVE_DOES_NOT_BELONG_TO_AUTOCHANGER = 'Drive does not belong to selected autochanger.'; } +class BasicUserError extends GenericError { + + const ERROR_BASIC_USER_DOES_NOT_EXIST = 140; + const ERROR_BASIC_USER_ALREADY_EXISTS = 141; + const ERROR_BASIC_USER_INVALID_USERNAME = 142; + const ERROR_BASIC_USER_INVALID_BCONSOLE_CFG_PATH = 143; + const ERROR_BASIC_USER_INVALID_CONSOLE = 144; + const ERROR_BASIC_USER_INVALID_DIRECTOR = 145; + const ERROR_BASIC_USER_INVALID_PASSWORD= 146; + + const MSG_ERROR_BASIC_USER_DOES_NOT_EXIST = 'Basic user does not exist.'; + const MSG_ERROR_BASIC_USER_ALREADY_EXISTS = 'Basic user already exists.'; + const MSG_ERROR_BASIC_USER_INVALID_USERNAME = 'Invalid basic user username'; + const MSG_ERROR_BASIC_USER_INVALID_BCONSOLE_CFG_PATH = 'Invalid bconsole config path.'; + const MSG_ERROR_BASIC_USER_INVALID_CONSOLE = 'Invalid Console name.'; + const MSG_ERROR_BASIC_USER_INVALID_DIRECTOR = 'Invalid Director name.'; + const MSG_ERROR_BASIC_USER_INVALID_PASSWORD = 'Invalid password.'; +} ?> diff --git a/gui/baculum/protected/Common/Portlets/NewAuthClient.tpl b/gui/baculum/protected/Common/Portlets/NewAuthClient.tpl index 13fbe95b3..40b34ff14 100644 --- a/gui/baculum/protected/Common/Portlets/NewAuthClient.tpl +++ b/gui/baculum/protected/Common/Portlets/NewAuthClient.tpl @@ -62,7 +62,7 @@ Display="Dynamic" ControlCssClass="invalidate" ControlToValidate="APIBasicPassword" - RegularExpression="[\S\s]{5,60}" + RegularExpression="<%=BasicUserConfig::PASSWORD_PATTERN%>" ValidationGroup="<%=$this->ClientID%>Basic" Text="<%[ Password must be longer than 4 chars. ]%>" /> @@ -96,7 +96,7 @@ Display="Dynamic" ControlCssClass="invalidate" ControlToValidate="RetypeAPIBasicPassword" - RegularExpression="[\S\s]{5,60}" + RegularExpression="<%=BasicUserConfig::PASSWORD_PATTERN%>" ValidationGroup="<%=$this->ClientID%>Basic" Text="<%[ Password must be longer than 4 chars. ]%>" />