From 9fb205bc2b5dfe4ff1036f46ccac8f35300decef Mon Sep 17 00:00:00 2001 From: Dmitriy Simushev Date: Thu, 22 May 2014 10:12:11 +0000 Subject: [PATCH] Replace "operator/operator.php" with a controller --- .../Mibew/Controller/OperatorController.php | 224 ++++++++++++++++++ src/mibew/libs/operator.php | 2 +- src/mibew/libs/operator_settings.php | 3 +- src/mibew/libs/routing.yml | 32 +++ src/mibew/operator/index.php | 2 +- src/mibew/operator/login.php | 2 +- src/mibew/operator/operator.php | 175 -------------- .../server_side/_menu.handlebars | 2 +- .../server_side/group_members.handlebars | 2 +- .../server_side/index.handlebars | 2 +- ...or.handlebars => operator_edit.handlebars} | 2 +- .../server_side/operators.handlebars | 4 +- 12 files changed, 267 insertions(+), 185 deletions(-) delete mode 100644 src/mibew/operator/operator.php rename src/mibew/styles/pages/default/templates_src/server_side/{operator.handlebars => operator_edit.handlebars} (98%) diff --git a/src/mibew/libs/classes/Mibew/Controller/OperatorController.php b/src/mibew/libs/classes/Mibew/Controller/OperatorController.php index 724f03b2..59322f72 100644 --- a/src/mibew/libs/classes/Mibew/Controller/OperatorController.php +++ b/src/mibew/libs/classes/Mibew/Controller/OperatorController.php @@ -18,6 +18,7 @@ namespace Mibew\Controller; use Mibew\Database; +use Mibew\Http\Exception\AccessDeniedException; use Mibew\Http\Exception\NotFoundException; use Symfony\Component\HttpFoundation\Request; @@ -206,4 +207,227 @@ class OperatorController extends AbstractController // Redirect the current operator to the page with operators list return $this->redirect($this->generateUrl('operators')); } + + /** + * Builds a page with form for add/edit operator. + * + * @param Request $request + * @return string Rendered page content + */ + public function showEditFormAction(Request $request) + { + set_csrf_token(); + + $operator = $request->attributes->get('_operator'); + $page = array( + 'opid' => false, + // Use errors list stored in the request. We need to do so to have + // an ability to pass the request from the "submitEditForm" action. + 'errors' => $request->attributes->get('errors', array()), + ); + + $op_id = false; + + if ($request->attributes->has('operator_id')) { + // Load and validate an operator to edit + $op_id = $request->attributes->getInt('operator_id'); + $op = operator_by_id($op_id); + if (!$op) { + throw new NotFoundException('The operator is not found.'); + } + + // Show an error if the admin password hasn't been set yet. + $no_password = check_password_hash($operator['vclogin'], '', $operator['vcpassword']) + && !$request->query->has('stored'); + if ($no_password) { + $page['errors'][] = getlocal('my_settings.error.no_password'); + } + + $page['formlogin'] = $op['vclogin']; + $page['formname'] = $op['vclocalename']; + $page['formemail'] = $op['vcemail']; + $page['formcommonname'] = $op['vccommonname']; + $page['formcode'] = $op['code']; + $page['opid'] = $op['operatorid']; + } + + // Override group's fields from the request if it's needed. This + // case will take place when a save handler fails and passes the request + // to this action. + if ($request->isMethod('POST')) { + // The login field can be disabled in the form. In that case it will + // not has a value. Thus we should override login field only when it + // is set. + if ($request->request->has('login')) { + $page['formlogin'] = $request->request->get('login'); + } + + $page['formname'] = $request->request->get('name'); + $page['formemail'] = $request->request->get('email'); + $page['formcommonname'] = $request->request->get('commonname'); + $page['formcode'] = $request->request->get('code'); + } + + // Operator without CAN_ADMINISTRATE permission can neither create new + // operators nor view/edit other operator's profile. + $access_restricted = !is_capable(CAN_ADMINISTRATE, $operator) + && (!$op_id || ($operator['operatorid'] != $op_id)); + if ($access_restricted) { + throw new AccessDeniedException(); + } + + $can_modify = ($op_id == $operator['operatorid'] && is_capable(CAN_MODIFYPROFILE, $operator)) + || is_capable(CAN_ADMINISTRATE, $operator); + + $page['stored'] = $request->query->has('stored'); + $page['canmodify'] = $can_modify ? '1' : ''; + $page['canchangelogin'] = is_capable(CAN_ADMINISTRATE, $operator); + $page['needChangePassword'] = check_password_hash($operator['vclogin'], '', $operator['vcpassword']); + $page['title'] = getlocal('page_agent.title'); + $page['menuid'] = ($op_id == $operator['operatorid']) ? 'profile' : 'operators'; + $page['requirePassword'] = (!$op_id || $page['needChangePassword']); + $page['formaction'] = $request->getBaseUrl() . $request->getPathInfo(); + $page = array_merge($page, prepare_menu($operator)); + $page['tabs'] = setup_operator_settings_tabs($op_id, 0); + + return $this->render('operator_edit', $page); + } + + /** + * Processes submitting of the form which is generated in + * {@link \Mibew\Controller\OperatorController::showEditFormAction()} method. + * + * @param Request $request + * @return string Rendered page content + */ + public function submitEditFormAction(Request $request) + { + csrf_check_token($request); + + $errors = array(); + $operator = $request->attributes->get('_operator'); + // Use value from the form and not from the path to make sure it is + // correct. If not, treat the param as empty one. + $op_id = $request->request->getInt('opid', false); + + if (is_capable(CAN_ADMINISTRATE, $operator)) { + $login = $request->request->get('login'); + } else { + $login = $operator['vclogin']; + } + + $email = $request->request->get('email'); + $password = $request->request->get('password'); + $password_confirm = $request->request->get('passwordConfirm'); + $local_name = $request->request->get('name'); + $common_name = $request->request->get('commonname'); + $code = $request->request->get('code'); + + $can_modify = ($op_id == $operator['operatorid'] && is_capable(CAN_MODIFYPROFILE, $operator)) + || is_capable(CAN_ADMINISTRATE, $operator); + if (!$can_modify) { + throw new AccessDeniedException('Cannot modify profile.'); + } + + if (!$local_name) { + $errors[] = no_field('form.field.agent_name'); + } + + if (!$common_name) { + $errors[] = no_field('form.field.agent_commonname'); + } + + if (!$login) { + $errors[] = no_field('form.field.login'); + } elseif (!preg_match("/^[\w_\.]+$/", $login)) { + $errors[] = getlocal('page_agent.error.wrong_login'); + } + + if (!$email || !is_valid_email($email)) { + $errors[] = wrong_field('form.field.mail'); + } + + if ($code && (!preg_match("/^[A-Za-z0-9_]+$/", $code))) { + $errors[] = getlocal('page_agent.error.wrong_agent_code'); + } + + if (!$op_id && !$password) { + $errors[] = no_field('form.field.password'); + } + + if ($password != $password_confirm) { + $errors[] = getlocal('my_settings.error.password_match'); + } + + $existing_operator = operator_by_login($login); + $duplicate_login = (!$op_id && $existing_operator) + || ($op_id + && $existing_operator + && $op_id != $existing_operator['operatorid']); + if ($duplicate_login) { + $errors[] = getlocal('page_agent.error.duplicate_login'); + } + + // Check if operator with specified email already exists in the database. + $existing_operator = operator_by_email($email); + $duplicate_email = + // Create operator with email already in database. + (!$op_id && $existing_operator) + // Update operator email to existing one. + || ($op_id + && $existing_operator + && $op_id != $existing_operator['operatorid']); + if ($duplicate_email) { + $errors[] = getlocal('page_agent.error.duplicate_email'); + } + + if (count($errors) != 0) { + $request->attributes->set('errors', $errors); + + // The form should be rebuild. Invoke appropriate action. + return $this->showEditFormAction($request); + } + + if (!$op_id) { + // Create new operator and redirect the current operator to avatar + // page. + $new_operator = create_operator($login, $email, $password, $local_name, $common_name, '', $code); + $redirect_to = $request->getBasePath() . '/operator/avatar.php?op=' + . intval($new_operator['operatorid']); + + return $this->redirect($redirect_to); + } + + // Update existing operator + update_operator($op_id, $login, $email, $password, $local_name, $common_name, $code); + + // Operator data are cached in the session, thus we need to manually + // update them. + if (!empty($password) && $op_id == $operator['operatorid']) { + // Check if the admin has set his password for the first time. + $to_dashboard = check_password_hash($login, '', $operator['vcpassword']) && $password != ''; + + // Update operator's password. + $operator['vcpassword'] = calculate_password_hash($login, $password); + $_SESSION[SESSION_PREFIX . 'operator'] = $operator; + $request->attributes->set('_operator', $operator); + + // Redirect the admin to the home page if needed. + if ($to_dashboard) { + return $this->redirect($request->getBasePath() . '/operator/index.php'); + } + } + + // Redirect the operator to edit page again to use GET method instead of + // POST. + $redirect_to = $this->generateUrl( + 'operator_edit', + array( + 'operator_id' => $op_id, + 'stored' => true, + ) + ); + + return $this->redirect($redirect_to); + } } diff --git a/src/mibew/libs/operator.php b/src/mibew/libs/operator.php index c7b5ecbd..e90ab7c3 100644 --- a/src/mibew/libs/operator.php +++ b/src/mibew/libs/operator.php @@ -589,7 +589,7 @@ function check_login($redirect = true) function force_password($operator) { if (check_password_hash($operator['vclogin'], $operator['vcpassword'], '')) { - header("Location: " . MIBEW_WEB_ROOT . "/operator/operator.php?op=1"); + header("Location: " . MIBEW_WEB_ROOT . "/operator/operator/1/edit"); exit; } } diff --git a/src/mibew/libs/operator_settings.php b/src/mibew/libs/operator_settings.php index 7a746176..afbca99d 100644 --- a/src/mibew/libs/operator_settings.php +++ b/src/mibew/libs/operator_settings.php @@ -22,6 +22,7 @@ * @param int $operator_id ID of the operator whose settings page is displayed. * @param int $active Number of the active tab. The count starts from 0. * @return array Tabs list + * @deprecated */ function setup_operator_settings_tabs($operator_id, $active) { @@ -30,7 +31,7 @@ function setup_operator_settings_tabs($operator_id, $active) if ($operator_id) { $tabs = array( getlocal("page_agent.tab.main") => ($active != 0 - ? (MIBEW_WEB_ROOT . "/operator/operator.php?op=" . $operator_id) + ? (MIBEW_WEB_ROOT . "/operator/operator/" . $operator_id . "/edit") : ""), getlocal("page_agent.tab.avatar") => ($active != 1 ? (MIBEW_WEB_ROOT . "/operator/avatar.php?op=" . $operator_id) diff --git a/src/mibew/libs/routing.yml b/src/mibew/libs/routing.yml index 9d1f34aa..c69befe1 100644 --- a/src/mibew/libs/routing.yml +++ b/src/mibew/libs/routing.yml @@ -170,6 +170,38 @@ invite: _access_check: Mibew\AccessControl\Check\LoggedInCheck ## Operators +operator_add: + path: /operator/operator/add + defaults: + _controller: Mibew\Controller\OperatorController::showEditFormAction + _access_check: Mibew\AccessControl\Check\LoggedInCheck + methods: [GET] + +operator_add_save: + path: /operator/operator/add + defaults: + _controller: Mibew\Controller\OperatorController::submitEditFormAction + _access_check: Mibew\AccessControl\Check\LoggedInCheck + methods: [POST] + +operator_edit: + path: /operator/operator/{operator_id}/edit + defaults: + _controller: Mibew\Controller\OperatorController::showEditFormAction + _access_check: Mibew\AccessControl\Check\LoggedInCheck + requirements: + operator_id: \d{1,10} + methods: [GET] + +operator_edit_save: + path: /operator/operator/{operator_id}/edit + defaults: + _controller: Mibew\Controller\OperatorController::submitEditFormAction + _access_check: Mibew\AccessControl\Check\LoggedInCheck + requirements: + operator_id: \d{1,10} + methods: [POST] + operator_enable: path: /operator/operator/{operator_id}/enable defaults: diff --git a/src/mibew/operator/index.php b/src/mibew/operator/index.php index 5dc28050..b26a0649 100644 --- a/src/mibew/operator/index.php +++ b/src/mibew/operator/index.php @@ -32,7 +32,7 @@ $page = array( 'localeLinks' => get_locale_links(), 'needUpdate' => Settings::get('dbversion') != DB_VERSION, 'needChangePassword' => check_password_hash($operator['vclogin'], '', $operator['vcpassword']), - 'profilePage' => MIBEW_WEB_ROOT . "/operator/operator.php?op=" . $operator['operatorid'], + 'profilePage' => MIBEW_WEB_ROOT . "/operator/operator/" . $operator['operatorid'] . '/edit', 'updateWizard' => MIBEW_WEB_ROOT . "/install/", 'newFeatures' => Settings::get('featuresversion') != FEATURES_VERSION, 'featuresPage' => MIBEW_WEB_ROOT . "/operator/features.php", diff --git a/src/mibew/operator/login.php b/src/mibew/operator/login.php index 31beb1ed..09ba1944 100644 --- a/src/mibew/operator/login.php +++ b/src/mibew/operator/login.php @@ -40,7 +40,7 @@ if (isset($_POST['login']) && isset($_POST['password'])) { if ($operator_can_login) { $target = $password == '' - ? MIBEW_WEB_ROOT . "/operator/operator.php?op=" . intval($operator['operatorid']) + ? MIBEW_WEB_ROOT . "/operator/operator/" . intval($operator['operatorid']) . '/edit' : (isset($_SESSION['backpath']) ? $_SESSION['backpath'] : MIBEW_WEB_ROOT . "/operator/index.php"); login_operator($operator, $remember, is_secure_request()); diff --git a/src/mibew/operator/operator.php b/src/mibew/operator/operator.php deleted file mode 100644 index 395584ef..00000000 --- a/src/mibew/operator/operator.php +++ /dev/null @@ -1,175 +0,0 @@ - '', - 'errors' => array(), -); - -$op_id = ''; - -if ((isset($_POST['login']) || !is_capable(CAN_ADMINISTRATE, $operator)) && isset($_POST['password'])) { - $op_id = verify_param("opid", "/^(\d{1,9})?$/", ""); - if (is_capable(CAN_ADMINISTRATE, $operator)) { - $login = get_param('login'); - } else { - $login = $operator['vclogin']; - } - $email = get_param('email'); - $password = get_param('password'); - $password_confirm = get_param('passwordConfirm'); - $local_name = get_param('name'); - $common_name = get_param('commonname'); - $code = get_param('code'); - - if (!$local_name) { - $page['errors'][] = no_field("form.field.agent_name"); - } - - if (!$common_name) { - $page['errors'][] = no_field("form.field.agent_commonname"); - } - - if (!$login) { - $page['errors'][] = no_field("form.field.login"); - } elseif (!preg_match("/^[\w_\.]+$/", $login)) { - $page['errors'][] = getlocal("page_agent.error.wrong_login"); - } - - if ($email == '' || !is_valid_email($email)) { - $page['errors'][] = wrong_field("form.field.mail"); - } - - if ($code != '' && (!preg_match("/^[A-z0-9_]+$/", $code))) { - $page['errors'][] = getlocal("page_agent.error.wrong_agent_code"); - } - - if (!$op_id && !$password) { - $page['errors'][] = no_field("form.field.password"); - } - - if ($password != $password_confirm) { - $page['errors'][] = getlocal("my_settings.error.password_match"); - } - - $existing_operator = operator_by_login($login); - $duplicate_login = (!$op_id && $existing_operator) - || ($op_id - && $existing_operator - && $op_id != $existing_operator['operatorid']); - if ($duplicate_login) { - $page['errors'][] = getlocal("page_agent.error.duplicate_login"); - } - - // Check if operator with specified email already exists in the database - $existing_operator = operator_by_email($email); - $duplicate_email = - // Create operator with email already in database - (!$op_id && $existing_operator) - // Update operator email to existing one - || ($op_id - && $existing_operator - && $op_id != $existing_operator['operatorid']); - if ($duplicate_email) { - $page['errors'][] = getlocal("page_agent.error.duplicate_email"); - } - - $can_modify = ($op_id == $operator['operatorid'] && is_capable(CAN_MODIFYPROFILE, $operator)) - || is_capable(CAN_ADMINISTRATE, $operator); - if (!$can_modify) { - $page['errors'][] = getlocal('page_agent.cannot_modify'); - } - - if (count($page['errors']) == 0) { - if (!$op_id) { - $new_operator = create_operator($login, $email, $password, $local_name, $common_name, "", $code); - header("Location: " . MIBEW_WEB_ROOT . "/operator/avatar.php?op=" . intval($new_operator['operatorid'])); - exit; - } else { - update_operator($op_id, $login, $email, $password, $local_name, $common_name, $code); - // update the session password - if (!empty($password) && $op_id == $operator['operatorid']) { - $to_dashboard = check_password_hash($login, '', $operator['vcpassword']) && $password != ''; - $_SESSION[SESSION_PREFIX . "operator"]['vcpassword'] = calculate_password_hash($login, $password); - if ($to_dashboard) { - header("Location: " . MIBEW_WEB_ROOT . "/operator/index.php"); - exit; - } - } - header("Location: " . MIBEW_WEB_ROOT . "/operator/operator.php?op=" . intval($op_id) . "&stored"); - exit; - } - } else { - $page['formlogin'] = $login; - $page['formname'] = $local_name; - $page['formemail'] = $email; - $page['formcommonname'] = $common_name; - $page['formcode'] = $code; - $page['opid'] = $op_id; - } -} elseif (isset($_GET['op'])) { - $op_id = verify_param('op', "/^\d{1,9}$/"); - $op = operator_by_id($op_id); - - if (!$op) { - $page['errors'][] = getlocal("no_such_operator"); - $page['opid'] = $op_id; - } else { - //show an error if the admin password hasn't been set yet. - if (check_password_hash($operator['vclogin'], '', $operator['vcpassword']) && !isset($_GET['stored'])) { - $page['errors'][] = getlocal("my_settings.error.no_password"); - } - - $page['formlogin'] = $op['vclogin']; - $page['formname'] = $op['vclocalename']; - $page['formemail'] = $op['vcemail']; - $page['formcommonname'] = $op['vccommonname']; - $page['formcode'] = $op['code']; - $page['opid'] = $op['operatorid']; - } -} - -if (!$op_id && !is_capable(CAN_ADMINISTRATE, $operator)) { - $page['errors'][] = getlocal("page_agent.error.forbidden_create"); -} - -$can_modify = ($op_id == $operator['operatorid'] && is_capable(CAN_MODIFYPROFILE, $operator)) - || is_capable(CAN_ADMINISTRATE, $operator); - -$page['stored'] = isset($_GET['stored']); -$page['canmodify'] = $can_modify ? "1" : ""; -$page['canchangelogin'] = is_capable(CAN_ADMINISTRATE, $operator); -$page['needChangePassword'] = check_password_hash($operator['vclogin'], '', $operator['vcpassword']); -$page['title'] = getlocal("page_agent.title"); -$page['menuid'] = ($op_id == $operator['operatorid']) ? "profile" : "operators"; -$page['requirePassword'] = (!$op_id || $page['needChangePassword']); - -$page = array_merge($page, prepare_menu($operator)); - -$page['tabs'] = setup_operator_settings_tabs($op_id, 0); - -$page_style = new PageStyle(PageStyle::getCurrentStyle()); -$page_style->render('operator', $page); diff --git a/src/mibew/styles/pages/default/templates_src/server_side/_menu.handlebars b/src/mibew/styles/pages/default/templates_src/server_side/_menu.handlebars index 65a170fa..c1842199 100644 --- a/src/mibew/styles/pages/default/templates_src/server_side/_menu.handlebars +++ b/src/mibew/styles/pages/default/templates_src/server_side/_menu.handlebars @@ -36,7 +36,7 @@ {{l10n "menu.updates"}} {{/if}} {{#if currentopid}} - {{l10n "menu.profile"}} + {{l10n "menu.profile"}} {{/if}} diff --git a/src/mibew/styles/pages/default/templates_src/server_side/group_members.handlebars b/src/mibew/styles/pages/default/templates_src/server_side/group_members.handlebars index d4f770a9..7ba188be 100644 --- a/src/mibew/styles/pages/default/templates_src/server_side/group_members.handlebars +++ b/src/mibew/styles/pages/default/templates_src/server_side/group_members.handlebars @@ -32,7 +32,7 @@
- +
{{/each}} diff --git a/src/mibew/styles/pages/default/templates_src/server_side/index.handlebars b/src/mibew/styles/pages/default/templates_src/server_side/index.handlebars index b0562e71..eb8ae75b 100644 --- a/src/mibew/styles/pages/default/templates_src/server_side/index.handlebars +++ b/src/mibew/styles/pages/default/templates_src/server_side/index.handlebars @@ -126,7 +126,7 @@
- + {{l10n "menu.profile"}} {{l10n "menu.profile.content"}} diff --git a/src/mibew/styles/pages/default/templates_src/server_side/operator.handlebars b/src/mibew/styles/pages/default/templates_src/server_side/operator_edit.handlebars similarity index 98% rename from src/mibew/styles/pages/default/templates_src/server_side/operator.handlebars rename to src/mibew/styles/pages/default/templates_src/server_side/operator_edit.handlebars index 45e00d11..3d057e4f 100644 --- a/src/mibew/styles/pages/default/templates_src/server_side/operator.handlebars +++ b/src/mibew/styles/pages/default/templates_src/server_side/operator_edit.handlebars @@ -23,7 +23,7 @@ {{/if}} {{#ifAny opid canmodify}} -
+ {{csrfTokenInput}} diff --git a/src/mibew/styles/pages/default/templates_src/server_side/operators.handlebars b/src/mibew/styles/pages/default/templates_src/server_side/operators.handlebars index 1f10e4e0..d20fcb33 100644 --- a/src/mibew/styles/pages/default/templates_src/server_side/operators.handlebars +++ b/src/mibew/styles/pages/default/templates_src/server_side/operators.handlebars @@ -63,7 +63,7 @@ {{#if canmodify}} @@ -87,7 +87,7 @@ {{#each allowedAgents}} - + {{vclogin}}