mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-26 08:42:41 +01:00
Admin and disabled flags for users
Summary: Provide an "isAdmin" flag for users, to designate administrative users. Restore the account editing interface and allow it to set role flags and reset passwords. Provide an "isDisabled" flag for users and shut down all system access for them. Test Plan: Created "admin" and "disabled" users. Did administrative things with the admin user. Tried to do stuff with the disabled user and was rebuffed. Tried to access administrative interfaces with a normal non-admin user and was denied. Reviewed By: aran Reviewers: tuomaspelkonen, jungejason, aran CC: ccheever, aran Differential Revision: 278
This commit is contained in:
parent
03b56c1035
commit
f9f8ef0e6e
17 changed files with 468 additions and 84 deletions
|
@ -35,43 +35,6 @@ return array(
|
||||||
// be 50x50px.
|
// be 50x50px.
|
||||||
'user.default-profile-image-phid' => 'PHID-FILE-4d61229816cfe6f2b2a3',
|
'user.default-profile-image-phid' => 'PHID-FILE-4d61229816cfe6f2b2a3',
|
||||||
|
|
||||||
// -- Access Control -------------------------------------------------------- //
|
|
||||||
|
|
||||||
// Phabricator users have one of three access levels: "anyone", "verified",
|
|
||||||
// or "admin". "anyone" means every user, including users who do not have
|
|
||||||
// accounts or are not logged into the system. "verified" is users who have
|
|
||||||
// accounts, are logged in, and have satisfied whatever verification steps
|
|
||||||
// the configuration requires (e.g., email verification and/or manual
|
|
||||||
// approval). "admin" is verified users with the "administrator" flag set.
|
|
||||||
|
|
||||||
// These configuration options control which access level is required to read
|
|
||||||
// data from Phabricator (e.g., view revisions and comments in Differential)
|
|
||||||
// and write data to Phabricator (e.g., upload files and create diffs). By
|
|
||||||
// default they are both set to "verified", meaning only verified user
|
|
||||||
// accounts can interact with the system in any meaningful way.
|
|
||||||
|
|
||||||
// If you are configuring an install for an open source project, you may
|
|
||||||
// want to reduce the "phabricator.read-access" requirement to "anyone". This
|
|
||||||
// will allow anyone to browse Phabricator content, even without logging in.
|
|
||||||
|
|
||||||
// Alternatively, you could raise the "phabricator.write-access" requirement
|
|
||||||
// to "admin", effectively creating a read-only install.
|
|
||||||
|
|
||||||
|
|
||||||
// Controls the minimum access level required to read data from Phabricator
|
|
||||||
// (e.g., view revisions in Differential). Allowed values are "anyone",
|
|
||||||
// "verified", or "admin". Note that "anyone" includes users who are not
|
|
||||||
// logged in! You should leave this at 'verified' unless you want your data
|
|
||||||
// to be publicly readable (e.g., you are developing open source software).
|
|
||||||
'phabricator.read-access' => 'verified',
|
|
||||||
|
|
||||||
// Controls the minimum access level required to write data to Phabricator
|
|
||||||
// (e.g., create new revisions in Differential). Allowed values are
|
|
||||||
// "verified" or "admin". Setting this to "admin" will effectively create a
|
|
||||||
// read-only install.
|
|
||||||
'phabricator.write-access' => 'verified',
|
|
||||||
|
|
||||||
|
|
||||||
// -- DarkConsole ----------------------------------------------------------- //
|
// -- DarkConsole ----------------------------------------------------------- //
|
||||||
|
|
||||||
// DarkConsole is a administrative debugging/profiling tool built into
|
// DarkConsole is a administrative debugging/profiling tool built into
|
||||||
|
|
5
resources/sql/patches/038.admin.sql
Normal file
5
resources/sql/patches/038.admin.sql
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
ALTER TABLE phabricator_user.user
|
||||||
|
ADD isDisabled bool NOT NULL;
|
||||||
|
|
||||||
|
ALTER TABLE phabricator_user.user
|
||||||
|
ADD isAdmin bool NOT NULL;
|
|
@ -301,6 +301,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorDirectoryItemEditController' => 'applications/directory/controller/itemedit',
|
'PhabricatorDirectoryItemEditController' => 'applications/directory/controller/itemedit',
|
||||||
'PhabricatorDirectoryItemListController' => 'applications/directory/controller/itemlist',
|
'PhabricatorDirectoryItemListController' => 'applications/directory/controller/itemlist',
|
||||||
'PhabricatorDirectoryMainController' => 'applications/directory/controller/main',
|
'PhabricatorDirectoryMainController' => 'applications/directory/controller/main',
|
||||||
|
'PhabricatorDisabledUserController' => 'applications/auth/controller/disabled',
|
||||||
'PhabricatorDraft' => 'applications/draft/storage/draft',
|
'PhabricatorDraft' => 'applications/draft/storage/draft',
|
||||||
'PhabricatorDraftDAO' => 'applications/draft/storage/base',
|
'PhabricatorDraftDAO' => 'applications/draft/storage/base',
|
||||||
'PhabricatorEditPreferencesController' => 'applications/preferences/controller/edit',
|
'PhabricatorEditPreferencesController' => 'applications/preferences/controller/edit',
|
||||||
|
@ -727,6 +728,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorDirectoryItemEditController' => 'PhabricatorDirectoryController',
|
'PhabricatorDirectoryItemEditController' => 'PhabricatorDirectoryController',
|
||||||
'PhabricatorDirectoryItemListController' => 'PhabricatorDirectoryController',
|
'PhabricatorDirectoryItemListController' => 'PhabricatorDirectoryController',
|
||||||
'PhabricatorDirectoryMainController' => 'PhabricatorDirectoryController',
|
'PhabricatorDirectoryMainController' => 'PhabricatorDirectoryController',
|
||||||
|
'PhabricatorDisabledUserController' => 'PhabricatorAuthController',
|
||||||
'PhabricatorDraft' => 'PhabricatorDraftDAO',
|
'PhabricatorDraft' => 'PhabricatorDraftDAO',
|
||||||
'PhabricatorDraftDAO' => 'PhabricatorLiskDAO',
|
'PhabricatorDraftDAO' => 'PhabricatorLiskDAO',
|
||||||
'PhabricatorEditPreferencesController' => 'PhabricatorPreferencesController',
|
'PhabricatorEditPreferencesController' => 'PhabricatorPreferencesController',
|
||||||
|
|
|
@ -69,7 +69,8 @@ class AphrontDefaultApplicationConfiguration
|
||||||
),
|
),
|
||||||
'/people/' => array(
|
'/people/' => array(
|
||||||
'$' => 'PhabricatorPeopleListController',
|
'$' => 'PhabricatorPeopleListController',
|
||||||
'edit/(?:(?P<username>\w+)/)?$' => 'PhabricatorPeopleEditController',
|
'edit/(?:(?P<id>\d+)/(?:(?P<view>\w+)/)?)?$'
|
||||||
|
=> 'PhabricatorPeopleEditController',
|
||||||
),
|
),
|
||||||
'/p/(?P<username>\w+)/$' => 'PhabricatorPeopleProfileController',
|
'/p/(?P<username>\w+)/$' => 'PhabricatorPeopleProfileController',
|
||||||
'/profile/' => array(
|
'/profile/' => array(
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class PhabricatorDisabledUserController extends PhabricatorAuthController {
|
||||||
|
|
||||||
|
public function shouldRequireEnabledUser() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function processRequest() {
|
||||||
|
$request = $this->getRequest();
|
||||||
|
$user = $request->getUser();
|
||||||
|
if (!$user->getIsDisabled()) {
|
||||||
|
return new Aphront404Response();
|
||||||
|
}
|
||||||
|
|
||||||
|
$failure_view = new AphrontRequestFailureView();
|
||||||
|
$failure_view->setHeader('Account Disabled');
|
||||||
|
$failure_view->appendChild('<p>Your account has been disabled.</p>');
|
||||||
|
|
||||||
|
return $this->buildStandardPageResponse(
|
||||||
|
$failure_view,
|
||||||
|
array(
|
||||||
|
'title' => 'Account Disabled',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
14
src/applications/auth/controller/disabled/__init__.php
Normal file
14
src/applications/auth/controller/disabled/__init__.php
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'aphront/response/404');
|
||||||
|
phutil_require_module('phabricator', 'applications/auth/controller/base');
|
||||||
|
phutil_require_module('phabricator', 'view/page/failure');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorDisabledUserController.php');
|
|
@ -22,6 +22,11 @@ class PhabricatorLogoutController extends PhabricatorAuthController {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function shouldRequireEnabledUser() {
|
||||||
|
// Allow disabled users to logout.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public function processRequest() {
|
public function processRequest() {
|
||||||
$request = $this->getRequest();
|
$request = $this->getRequest();
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,14 @@ abstract class PhabricatorController extends AphrontController {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function shouldRequireAdmin() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function shouldRequireEnabledUser() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
final public function willBeginExecution() {
|
final public function willBeginExecution() {
|
||||||
|
|
||||||
$request = $this->getRequest();
|
$request = $this->getRequest();
|
||||||
|
@ -47,6 +55,13 @@ abstract class PhabricatorController extends AphrontController {
|
||||||
|
|
||||||
$request->setUser($user);
|
$request->setUser($user);
|
||||||
|
|
||||||
|
if ($user->getIsDisabled() && $this->shouldRequireEnabledUser()) {
|
||||||
|
$disabled_user_controller = newv(
|
||||||
|
'PhabricatorDisabledUserController',
|
||||||
|
array($request));
|
||||||
|
return $this->delegateToController($disabled_user_controller);
|
||||||
|
}
|
||||||
|
|
||||||
if (PhabricatorEnv::getEnvConfig('darkconsole.enabled')) {
|
if (PhabricatorEnv::getEnvConfig('darkconsole.enabled')) {
|
||||||
if ($user->getConsoleEnabled() ||
|
if ($user->getConsoleEnabled() ||
|
||||||
PhabricatorEnv::getEnvConfig('darkconsole.always-on')) {
|
PhabricatorEnv::getEnvConfig('darkconsole.always-on')) {
|
||||||
|
@ -59,11 +74,21 @@ abstract class PhabricatorController extends AphrontController {
|
||||||
$login_controller = newv('PhabricatorLoginController', array($request));
|
$login_controller = newv('PhabricatorLoginController', array($request));
|
||||||
return $this->delegateToController($login_controller);
|
return $this->delegateToController($login_controller);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->shouldRequireAdmin() && !$user->getIsAdmin()) {
|
||||||
|
return new Aphront404Response();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function buildStandardPageView() {
|
public function buildStandardPageView() {
|
||||||
$view = new PhabricatorStandardPageView();
|
$view = new PhabricatorStandardPageView();
|
||||||
$view->setRequest($this->getRequest());
|
$view->setRequest($this->getRequest());
|
||||||
|
|
||||||
|
if ($this->shouldRequireAdmin()) {
|
||||||
|
$view->setIsAdminInterface(true);
|
||||||
|
}
|
||||||
|
|
||||||
return $view;
|
return $view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
phutil_require_module('phabricator', 'aphront/console/core');
|
phutil_require_module('phabricator', 'aphront/console/core');
|
||||||
phutil_require_module('phabricator', 'aphront/controller');
|
phutil_require_module('phabricator', 'aphront/controller');
|
||||||
|
phutil_require_module('phabricator', 'aphront/response/404');
|
||||||
phutil_require_module('phabricator', 'aphront/response/webpage');
|
phutil_require_module('phabricator', 'aphront/response/webpage');
|
||||||
phutil_require_module('phabricator', 'applications/people/storage/user');
|
phutil_require_module('phabricator', 'applications/people/storage/user');
|
||||||
phutil_require_module('phabricator', 'infrastructure/env');
|
phutil_require_module('phabricator', 'infrastructure/env');
|
||||||
|
|
|
@ -58,6 +58,10 @@ class PhabricatorMetaMTAReceivedMail extends PhabricatorMetaMTADAO {
|
||||||
return $this->setMessage("Invalid user '{$user_id}'")->save();
|
return $this->setMessage("Invalid user '{$user_id}'")->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($user->getIsDisabled()) {
|
||||||
|
return $this->setMessage("User '{$user_id}' is disabled")->save();
|
||||||
|
}
|
||||||
|
|
||||||
$this->setAuthorPHID($user->getPHID());
|
$this->setAuthorPHID($user->getPHID());
|
||||||
|
|
||||||
$receiver = self::loadReceiverObject($receiver_name);
|
$receiver = self::loadReceiverObject($receiver_name);
|
||||||
|
|
|
@ -18,20 +18,25 @@
|
||||||
|
|
||||||
class PhabricatorPeopleEditController extends PhabricatorPeopleController {
|
class PhabricatorPeopleEditController extends PhabricatorPeopleController {
|
||||||
|
|
||||||
private $username;
|
public function shouldRequireAdmin() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private $id;
|
||||||
|
private $view;
|
||||||
|
|
||||||
public function willProcessRequest(array $data) {
|
public function willProcessRequest(array $data) {
|
||||||
$this->username = idx($data, 'username');
|
$this->id = idx($data, 'id');
|
||||||
|
$this->view = idx($data, 'view');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function processRequest() {
|
public function processRequest() {
|
||||||
|
|
||||||
return new Aphront404Response();
|
$request = $this->getRequest();
|
||||||
|
$admin = $request->getUser();
|
||||||
|
|
||||||
if ($this->username) {
|
if ($this->id) {
|
||||||
$user = id(new PhabricatorUser())->loadOneWhere(
|
$user = id(new PhabricatorUser())->load($this->id);
|
||||||
'userName = %s',
|
|
||||||
$this->username);
|
|
||||||
if (!$user) {
|
if (!$user) {
|
||||||
return new Aphront404Response();
|
return new Aphront404Response();
|
||||||
}
|
}
|
||||||
|
@ -39,6 +44,77 @@ class PhabricatorPeopleEditController extends PhabricatorPeopleController {
|
||||||
$user = new PhabricatorUser();
|
$user = new PhabricatorUser();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$views = array(
|
||||||
|
'basic' => 'Basic Information',
|
||||||
|
'password' => 'Reset Password',
|
||||||
|
'role' => 'Edit Role',
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!$user->getID()) {
|
||||||
|
$view = 'basic';
|
||||||
|
} else if (isset($views[$this->view])) {
|
||||||
|
$view = $this->view;
|
||||||
|
} else {
|
||||||
|
$view = 'basic';
|
||||||
|
}
|
||||||
|
|
||||||
|
$content = array();
|
||||||
|
|
||||||
|
if ($request->getStr('saved')) {
|
||||||
|
$notice = new AphrontErrorView();
|
||||||
|
$notice->setSeverity(AphrontErrorView::SEVERITY_NOTICE);
|
||||||
|
$notice->setTitle('Changed Saved');
|
||||||
|
$notice->appendChild('<p>Your changes were saved.</p>');
|
||||||
|
$content[] = $notice;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($view) {
|
||||||
|
case 'basic':
|
||||||
|
$response = $this->processBasicRequest($user);
|
||||||
|
break;
|
||||||
|
case 'password':
|
||||||
|
$response = $this->processPasswordRequest($user);
|
||||||
|
break;
|
||||||
|
case 'role':
|
||||||
|
$response = $this->processRoleRequest($user);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($response instanceof AphrontResponse) {
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
$content[] = $response;
|
||||||
|
|
||||||
|
if ($user->getID()) {
|
||||||
|
$side_nav = new AphrontSideNavView();
|
||||||
|
$side_nav->appendChild($content);
|
||||||
|
foreach ($views as $key => $name) {
|
||||||
|
$side_nav->addNavItem(
|
||||||
|
phutil_render_tag(
|
||||||
|
'a',
|
||||||
|
array(
|
||||||
|
'href' => '/people/edit/'.$user->getID().'/'.$key.'/',
|
||||||
|
'class' => ($key == $view)
|
||||||
|
? 'aphront-side-nav-selected'
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
phutil_escape_html($name)));
|
||||||
|
}
|
||||||
|
$content = $side_nav;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->buildStandardPageResponse(
|
||||||
|
$content,
|
||||||
|
array(
|
||||||
|
'title' => 'Edit User',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function processBasicRequest(PhabricatorUser $user) {
|
||||||
|
$request = $this->getRequest();
|
||||||
|
$admin = $request->getUser();
|
||||||
|
|
||||||
$e_username = true;
|
$e_username = true;
|
||||||
$e_realname = true;
|
$e_realname = true;
|
||||||
$e_email = true;
|
$e_email = true;
|
||||||
|
@ -58,23 +134,46 @@ class PhabricatorPeopleEditController extends PhabricatorPeopleController {
|
||||||
} else if (!preg_match('/^[a-z0-9]+$/', $user->getUsername())) {
|
} else if (!preg_match('/^[a-z0-9]+$/', $user->getUsername())) {
|
||||||
$errors[] = "Username must consist of only numbers and letters.";
|
$errors[] = "Username must consist of only numbers and letters.";
|
||||||
$e_username = 'Invalid';
|
$e_username = 'Invalid';
|
||||||
|
} else {
|
||||||
|
$e_username = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strlen($user->getRealName())) {
|
if (!strlen($user->getRealName())) {
|
||||||
$errors[] = 'Real name is required.';
|
$errors[] = 'Real name is required.';
|
||||||
$e_realname = 'Required';
|
$e_realname = 'Required';
|
||||||
|
} else {
|
||||||
|
$e_realname = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strlen($user->getEmail())) {
|
if (!strlen($user->getEmail())) {
|
||||||
$errors[] = 'Email is required.';
|
$errors[] = 'Email is required.';
|
||||||
$e_email = 'Required';
|
$e_email = 'Required';
|
||||||
|
} else {
|
||||||
|
$e_email = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$errors) {
|
if (!$errors) {
|
||||||
|
try {
|
||||||
$user->save();
|
$user->save();
|
||||||
$response = id(new AphrontRedirectResponse())
|
$response = id(new AphrontRedirectResponse())
|
||||||
->setURI('/p/'.$user->getUsername().'/');
|
->setURI('/people/edit/'.$user->getID().'/?saved=true');
|
||||||
return $response;
|
return $response;
|
||||||
|
} catch (AphrontQueryDuplicateKeyException $ex) {
|
||||||
|
$errors[] = 'Username and email must be unique.';
|
||||||
|
|
||||||
|
$same_username = id(new PhabricatorUser())
|
||||||
|
->loadOneWhere('username = %s', $user->getUsername());
|
||||||
|
$same_email = id(new PhabricatorUser())
|
||||||
|
->loadOneWhere('email = %s', $user->getEmail());
|
||||||
|
|
||||||
|
if ($same_username) {
|
||||||
|
$e_username = 'Duplicate';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($same_email) {
|
||||||
|
$e_email = 'Duplicate';
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,9 +185,9 @@ class PhabricatorPeopleEditController extends PhabricatorPeopleController {
|
||||||
}
|
}
|
||||||
|
|
||||||
$form = new AphrontFormView();
|
$form = new AphrontFormView();
|
||||||
$form->setUser($request->getUser());
|
$form->setUser($admin);
|
||||||
if ($user->getUsername()) {
|
if ($user->getID()) {
|
||||||
$form->setAction('/people/edit/'.$user->getUsername().'/');
|
$form->setAction('/people/edit/'.$user->getID().'/');
|
||||||
} else {
|
} else {
|
||||||
$form->setAction('/people/edit/');
|
$form->setAction('/people/edit/');
|
||||||
}
|
}
|
||||||
|
@ -135,11 +234,146 @@ class PhabricatorPeopleEditController extends PhabricatorPeopleController {
|
||||||
$panel->appendChild($form);
|
$panel->appendChild($form);
|
||||||
$panel->setWidth(AphrontPanelView::WIDTH_FORM);
|
$panel->setWidth(AphrontPanelView::WIDTH_FORM);
|
||||||
|
|
||||||
return $this->buildStandardPageResponse(
|
return array($error_view, $panel);
|
||||||
array($error_view, $panel),
|
}
|
||||||
array(
|
|
||||||
'title' => 'Edit User',
|
private function processPasswordRequest(PhabricatorUser $user) {
|
||||||
));
|
$request = $this->getRequest();
|
||||||
|
$admin = $request->getUser();
|
||||||
|
|
||||||
|
$e_password = true;
|
||||||
|
$errors = array();
|
||||||
|
|
||||||
|
if ($request->isFormPost()) {
|
||||||
|
if (strlen($request->getStr('password'))) {
|
||||||
|
$user->setPassword($request->getStr('password'));
|
||||||
|
$e_password = null;
|
||||||
|
} else {
|
||||||
|
$errors[] = 'Password is required.';
|
||||||
|
$e_password = 'Required';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$errors) {
|
||||||
|
$user->save();
|
||||||
|
return id(new AphrontRedirectResponse())
|
||||||
|
->setURI($request->getRequestURI()->alter('saved', 'true'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$error_view = null;
|
||||||
|
if ($errors) {
|
||||||
|
$error_view = id(new AphrontErrorView())
|
||||||
|
->setTitle('Form Errors')
|
||||||
|
->setErrors($errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$form = id(new AphrontFormView())
|
||||||
|
->setUser($admin)
|
||||||
|
->setAction($request->getRequestURI()->alter('saved', null))
|
||||||
|
->appendChild(
|
||||||
|
'<p class="aphront-form-instructions">Submitting this form will '.
|
||||||
|
'change this user\'s password. They will no longer be able to login '.
|
||||||
|
'with their old password.</p>')
|
||||||
|
->appendChild(
|
||||||
|
id(new AphrontFormTextControl())
|
||||||
|
->setLabel('New Password')
|
||||||
|
->setName('password')
|
||||||
|
->setError($e_password))
|
||||||
|
->appendChild(
|
||||||
|
id(new AphrontFormSubmitControl())
|
||||||
|
->setValue('Reset Password'));
|
||||||
|
|
||||||
|
|
||||||
|
$panel = new AphrontPanelView();
|
||||||
|
$panel->setHeader('Reset Password');
|
||||||
|
$panel->setWidth(AphrontPanelView::WIDTH_FORM);
|
||||||
|
$panel->appendChild($form);
|
||||||
|
|
||||||
|
return array($error_view, $panel);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function processRoleRequest(PhabricatorUser $user) {
|
||||||
|
$request = $this->getRequest();
|
||||||
|
$admin = $request->getUser();
|
||||||
|
|
||||||
|
$is_self = ($user->getID() == $admin->getID());
|
||||||
|
|
||||||
|
$errors = array();
|
||||||
|
|
||||||
|
if ($request->isFormPost()) {
|
||||||
|
if ($is_self) {
|
||||||
|
$errors[] = "You can not edit your own role.";
|
||||||
|
} else {
|
||||||
|
$user->setIsAdmin($request->getInt('is_admin'));
|
||||||
|
$user->setIsDisabled($request->getInt('is_disabled'));
|
||||||
|
$user->setIsSystemAgent($request->getInt('is_agent'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$errors) {
|
||||||
|
$user->save();
|
||||||
|
return id(new AphrontRedirectResponse())
|
||||||
|
->setURI($request->getRequestURI()->alter('saved', 'true'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$error_view = null;
|
||||||
|
if ($errors) {
|
||||||
|
$error_view = id(new AphrontErrorView())
|
||||||
|
->setTitle('Form Errors')
|
||||||
|
->setErrors($errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$form = id(new AphrontFormView())
|
||||||
|
->setUser($admin)
|
||||||
|
->setAction($request->getRequestURI()->alter('saved', null));
|
||||||
|
|
||||||
|
if ($is_self) {
|
||||||
|
$form->appendChild(
|
||||||
|
'<p class="aphront-form-instructions">NOTE: You can not edit your own '.
|
||||||
|
'role.</p>');
|
||||||
|
}
|
||||||
|
|
||||||
|
$form
|
||||||
|
->appendChild(
|
||||||
|
id(new AphrontFormCheckboxControl())
|
||||||
|
->addCheckbox(
|
||||||
|
'is_admin',
|
||||||
|
1,
|
||||||
|
'Admin: wields absolute power.',
|
||||||
|
$user->getIsAdmin())
|
||||||
|
->setDisabled($is_self))
|
||||||
|
->appendChild(
|
||||||
|
id(new AphrontFormCheckboxControl())
|
||||||
|
->addCheckbox(
|
||||||
|
'is_disabled',
|
||||||
|
1,
|
||||||
|
'Disabled: can not login.',
|
||||||
|
$user->getIsDisabled())
|
||||||
|
->setDisabled($is_self))
|
||||||
|
->appendChild(
|
||||||
|
id(new AphrontFormCheckboxControl())
|
||||||
|
->addCheckbox(
|
||||||
|
'is_agent',
|
||||||
|
1,
|
||||||
|
'Agent: system agent (robot).',
|
||||||
|
$user->getIsSystemAgent())
|
||||||
|
->setDisabled($is_self));
|
||||||
|
|
||||||
|
if (!$is_self) {
|
||||||
|
$form
|
||||||
|
->appendChild(
|
||||||
|
id(new AphrontFormSubmitControl())
|
||||||
|
->setValue('Edit Role'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$panel = new AphrontPanelView();
|
||||||
|
$panel->setHeader('Edit Role');
|
||||||
|
$panel->setWidth(AphrontPanelView::WIDTH_FORM);
|
||||||
|
$panel->appendChild($form);
|
||||||
|
|
||||||
|
return array($error_view, $panel);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,11 +11,14 @@ phutil_require_module('phabricator', 'aphront/response/redirect');
|
||||||
phutil_require_module('phabricator', 'applications/people/controller/base');
|
phutil_require_module('phabricator', 'applications/people/controller/base');
|
||||||
phutil_require_module('phabricator', 'applications/people/storage/user');
|
phutil_require_module('phabricator', 'applications/people/storage/user');
|
||||||
phutil_require_module('phabricator', 'view/form/base');
|
phutil_require_module('phabricator', 'view/form/base');
|
||||||
|
phutil_require_module('phabricator', 'view/form/control/checkbox');
|
||||||
phutil_require_module('phabricator', 'view/form/control/submit');
|
phutil_require_module('phabricator', 'view/form/control/submit');
|
||||||
phutil_require_module('phabricator', 'view/form/control/text');
|
phutil_require_module('phabricator', 'view/form/control/text');
|
||||||
phutil_require_module('phabricator', 'view/form/error');
|
phutil_require_module('phabricator', 'view/form/error');
|
||||||
phutil_require_module('phabricator', 'view/layout/panel');
|
phutil_require_module('phabricator', 'view/layout/panel');
|
||||||
|
phutil_require_module('phabricator', 'view/layout/sidenav');
|
||||||
|
|
||||||
|
phutil_require_module('phutil', 'markup');
|
||||||
phutil_require_module('phutil', 'utils');
|
phutil_require_module('phutil', 'utils');
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ class PhabricatorPeopleListController extends PhabricatorPeopleController {
|
||||||
|
|
||||||
public function processRequest() {
|
public function processRequest() {
|
||||||
$request = $this->getRequest();
|
$request = $this->getRequest();
|
||||||
|
$is_admin = $request->getUser()->getIsAdmin();
|
||||||
|
|
||||||
$user = new PhabricatorUser();
|
$user = new PhabricatorUser();
|
||||||
|
|
||||||
|
@ -41,41 +42,92 @@ class PhabricatorPeopleListController extends PhabricatorPeopleController {
|
||||||
|
|
||||||
$rows = array();
|
$rows = array();
|
||||||
foreach ($users as $user) {
|
foreach ($users as $user) {
|
||||||
$rows[] = array(
|
$cols = array();
|
||||||
$user->getPHID(),
|
$cols[] = date('M jS, Y', $user->getDateCreated());
|
||||||
$user->getUserName(),
|
$cols[] = date('g:i:s A', $user->getDateCreated());
|
||||||
$user->getRealName(),
|
$cols[] = phutil_render_tag(
|
||||||
phutil_render_tag(
|
'a',
|
||||||
|
array(
|
||||||
|
'href' => '/p/'.$user->getUsername().'/',
|
||||||
|
),
|
||||||
|
phutil_escape_html($user->getUserName()));
|
||||||
|
$cols[] = phutil_escape_html($user->getRealName());
|
||||||
|
|
||||||
|
if ($is_admin) {
|
||||||
|
$status = '';
|
||||||
|
if ($user->getIsDisabled()) {
|
||||||
|
$status = 'Disabled';
|
||||||
|
} else if ($user->getIsAdmin()) {
|
||||||
|
$status = 'Admin';
|
||||||
|
} else {
|
||||||
|
$status = '-';
|
||||||
|
}
|
||||||
|
$cols[] = $status;
|
||||||
|
$cols[] = phutil_render_tag(
|
||||||
'a',
|
'a',
|
||||||
array(
|
array(
|
||||||
'class' => 'button grey small',
|
'class' => 'button grey small',
|
||||||
'href' => '/p/'.$user->getUsername().'/',
|
'href' => '/people/edit/'.$user->getID().'/',
|
||||||
),
|
),
|
||||||
'View Profile'),
|
'Administrate User');
|
||||||
);
|
}
|
||||||
|
|
||||||
|
$rows[] = $cols;
|
||||||
}
|
}
|
||||||
|
|
||||||
$table = new AphrontTableView($rows);
|
$table = new AphrontTableView($rows);
|
||||||
|
if ($is_admin) {
|
||||||
$table->setHeaders(
|
$table->setHeaders(
|
||||||
array(
|
array(
|
||||||
'PHID',
|
'Join Date',
|
||||||
|
'Time',
|
||||||
'Username',
|
'Username',
|
||||||
'Real Name',
|
'Real Name',
|
||||||
|
'Status',
|
||||||
'',
|
'',
|
||||||
));
|
));
|
||||||
$table->setColumnClasses(
|
$table->setColumnClasses(
|
||||||
array(
|
array(
|
||||||
null,
|
null,
|
||||||
null,
|
'right',
|
||||||
|
'pri',
|
||||||
'wide',
|
'wide',
|
||||||
|
null,
|
||||||
'action',
|
'action',
|
||||||
));
|
));
|
||||||
|
} else {
|
||||||
|
$table->setHeaders(
|
||||||
|
array(
|
||||||
|
'Join Date',
|
||||||
|
'Time',
|
||||||
|
'Username',
|
||||||
|
'Real Name',
|
||||||
|
));
|
||||||
|
$table->setColumnClasses(
|
||||||
|
array(
|
||||||
|
null,
|
||||||
|
'right',
|
||||||
|
'pri',
|
||||||
|
'wide',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
$panel = new AphrontPanelView();
|
$panel = new AphrontPanelView();
|
||||||
$panel->setHeader('People');
|
$panel->setHeader('People ('.number_format($count).')');
|
||||||
$panel->appendChild($table);
|
$panel->appendChild($table);
|
||||||
$panel->appendChild($pager);
|
$panel->appendChild($pager);
|
||||||
|
|
||||||
|
if ($is_admin) {
|
||||||
|
$panel->addButton(
|
||||||
|
phutil_render_tag(
|
||||||
|
'a',
|
||||||
|
array(
|
||||||
|
'href' => '/people/edit/',
|
||||||
|
'class' => 'button green',
|
||||||
|
),
|
||||||
|
'Create New Account'));
|
||||||
|
}
|
||||||
|
|
||||||
return $this->buildStandardPageResponse($panel, array(
|
return $this->buildStandardPageResponse($panel, array(
|
||||||
'title' => 'People',
|
'title' => 'People',
|
||||||
'tab' => 'people',
|
'tab' => 'people',
|
||||||
|
|
|
@ -35,6 +35,8 @@ class PhabricatorUser extends PhabricatorUserDAO {
|
||||||
protected $conduitCertificate;
|
protected $conduitCertificate;
|
||||||
|
|
||||||
protected $isSystemAgent = 0;
|
protected $isSystemAgent = 0;
|
||||||
|
protected $isAdmin = 0;
|
||||||
|
protected $isDisabled = 0;
|
||||||
|
|
||||||
private $preferences = null;
|
private $preferences = null;
|
||||||
|
|
||||||
|
@ -56,9 +58,13 @@ class PhabricatorUser extends PhabricatorUserDAO {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setPassword($password) {
|
public function setPassword($password) {
|
||||||
|
if (!strlen($password)) {
|
||||||
|
$this->setPasswordHash('');
|
||||||
|
} else {
|
||||||
$this->setPasswordSalt(md5(mt_rand()));
|
$this->setPasswordSalt(md5(mt_rand()));
|
||||||
$hash = $this->hashPassword($password);
|
$hash = $this->hashPassword($password);
|
||||||
$this->setPasswordHash($hash);
|
$this->setPasswordHash($hash);
|
||||||
|
}
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,6 +83,12 @@ class PhabricatorUser extends PhabricatorUserDAO {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function comparePassword($password) {
|
public function comparePassword($password) {
|
||||||
|
if (!strlen($password)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!strlen($this->getPasswordHash())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$password = $this->hashPassword($password);
|
$password = $this->hashPassword($password);
|
||||||
return ($password === $this->getPasswordHash());
|
return ($password === $this->getPasswordHash());
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,7 @@ class AphrontFormCheckboxControl extends AphrontFormControl {
|
||||||
'name' => $box['name'],
|
'name' => $box['name'],
|
||||||
'value' => $box['value'],
|
'value' => $box['value'],
|
||||||
'checked' => $box['checked'] ? 'checked' : null,
|
'checked' => $box['checked'] ? 'checked' : null,
|
||||||
|
'disabled' => $this->getDisabled() ? 'disabled' : null,
|
||||||
));
|
));
|
||||||
$label = phutil_render_tag(
|
$label = phutil_render_tag(
|
||||||
'label',
|
'label',
|
||||||
|
|
|
@ -25,6 +25,16 @@ class PhabricatorStandardPageView extends AphrontPageView {
|
||||||
private $glyph;
|
private $glyph;
|
||||||
private $bodyContent;
|
private $bodyContent;
|
||||||
private $request;
|
private $request;
|
||||||
|
private $isAdminInterface;
|
||||||
|
|
||||||
|
public function setIsAdminInterface($is_admin_interface) {
|
||||||
|
$this->isAdminInterface = $is_admin_interface;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getIsAdminInterface() {
|
||||||
|
return $this->isAdminInterface;
|
||||||
|
}
|
||||||
|
|
||||||
public function setRequest($request) {
|
public function setRequest($request) {
|
||||||
$this->request = $request;
|
$this->request = $request;
|
||||||
|
@ -254,9 +264,14 @@ class PhabricatorStandardPageView extends AphrontPageView {
|
||||||
|
|
||||||
$foot_links = implode(' · ', $foot_links);
|
$foot_links = implode(' · ', $foot_links);
|
||||||
|
|
||||||
|
$admin_class = null;
|
||||||
|
if ($this->getIsAdminInterface()) {
|
||||||
|
$admin_class = 'phabricator-admin-page-view';
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
($console ? '<darkconsole />' : null).
|
($console ? '<darkconsole />' : null).
|
||||||
'<div class="phabricator-standard-page">'.
|
'<div class="phabricator-standard-page '.$admin_class.'">'.
|
||||||
'<div class="phabricator-standard-header">'.
|
'<div class="phabricator-standard-header">'.
|
||||||
'<div class="phabricator-login-details">'.
|
'<div class="phabricator-login-details">'.
|
||||||
$login_stuff.
|
$login_stuff.
|
||||||
|
|
|
@ -19,6 +19,10 @@
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.phabricator-admin-page-view .phabricator-standard-header {
|
||||||
|
background: #aa0000;
|
||||||
|
}
|
||||||
|
|
||||||
.phabricator-primary-navigation {
|
.phabricator-primary-navigation {
|
||||||
padding-top: 12px;
|
padding-top: 12px;
|
||||||
padding-bottom: 8px;
|
padding-bottom: 8px;
|
||||||
|
|
Loading…
Reference in a new issue