Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14355988
D8668.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
17 KB
Referenced Files
None
Subscribers
None
D8668.diff
View Options
diff --git a/src/applications/diffusion/panel/DiffusionSetPasswordPanel.php b/src/applications/diffusion/panel/DiffusionSetPasswordPanel.php
--- a/src/applications/diffusion/panel/DiffusionSetPasswordPanel.php
+++ b/src/applications/diffusion/panel/DiffusionSetPasswordPanel.php
@@ -2,6 +2,10 @@
final class DiffusionSetPasswordPanel extends PhabricatorSettingsPanel {
+ public function isEditableByAdministrators() {
+ return true;
+ }
+
public function getPanelKey() {
return 'vcspassword';
}
@@ -19,7 +23,8 @@
}
public function processRequest(AphrontRequest $request) {
- $user = $request->getUser();
+ $viewer = $request->getUser();
+ $user = $this->getUser();
$vcspassword = id(new PhabricatorRepositoryVCSPassword())
->loadOneWhere(
@@ -68,7 +73,12 @@
$e_password = pht('Does Not Match');
$e_confirm = pht('Does Not Match');
$errors[] = pht('Password and confirmation do not match.');
- } else if ($user->comparePassword($envelope)) {
+ } else if ($viewer->comparePassword($envelope)) {
+ // NOTE: The above test is against $viewer (not $user), so that the
+ // error message below makes sense in the case that the two are
+ // different, and because an admin reusing their own password is bad,
+ // while system agents generally do not have passwords anyway.
+
$e_password = pht('Not Unique');
$e_confirm = pht('Not Unique');
$errors[] = pht(
@@ -97,7 +107,7 @@
$title = pht('Set VCS Password');
$form = id(new AphrontFormView())
- ->setUser($user)
+ ->setUser($viewer)
->appendRemarkupInstructions(
pht(
'To access repositories hosted by Phabricator over HTTP, you must '.
@@ -193,7 +203,7 @@
->setFormErrors($errors);
$remove_form = id(new AphrontFormView())
- ->setUser($user);
+ ->setUser($viewer);
if ($vcspassword->getID()) {
$remove_form
diff --git a/src/applications/people/controller/PhabricatorPeopleEditController.php b/src/applications/people/controller/PhabricatorPeopleEditController.php
--- a/src/applications/people/controller/PhabricatorPeopleEditController.php
+++ b/src/applications/people/controller/PhabricatorPeopleEditController.php
@@ -35,7 +35,6 @@
$nav->setBaseURI(new PhutilURI($base_uri));
$nav->addLabel(pht('User Information'));
$nav->addFilter('basic', pht('Basic Information'));
- $nav->addFilter('cert', pht('Conduit Certificate'));
$nav->addFilter('profile',
pht('View Profile'), '/p/'.$user->getUsername().'/');
@@ -60,9 +59,6 @@
case 'basic':
$response = $this->processBasicRequest($user);
break;
- case 'cert':
- $response = $this->processCertificateRequest($user);
- break;
default:
return new Aphront404Response();
}
@@ -327,47 +323,6 @@
return array($form_box);
}
- private function processCertificateRequest($user) {
- $request = $this->getRequest();
- $admin = $request->getUser();
-
- $inst = pht('You can use this certificate '.
- 'to write scripts or bots which interface with Phabricator over '.
- 'Conduit.');
- $form = new AphrontFormView();
- $form
- ->setUser($admin)
- ->setAction($request->getRequestURI())
- ->appendChild(
- phutil_tag('p', array('class' => 'aphront-form-instructions'), $inst));
-
- if ($user->getIsSystemAgent()) {
- $form
- ->appendChild(
- id(new AphrontFormTextControl())
- ->setLabel(pht('Username'))
- ->setValue($user->getUsername()))
- ->appendChild(
- id(new AphrontFormTextAreaControl())
- ->setLabel(pht('Certificate'))
- ->setValue($user->getConduitCertificate()));
- } else {
- $form->appendChild(
- id(new AphrontFormStaticControl())
- ->setLabel(pht('Certificate'))
- ->setValue(
- pht('You may only view the certificates of System Agents.')));
- }
-
- $title = pht('Conduit Certificate');
-
- $form_box = id(new PHUIObjectBoxView())
- ->setHeaderText($title)
- ->setForm($form);
-
- return array($form_box);
- }
-
private function getRoleInstructions() {
$roles_link = phutil_tag(
'a',
diff --git a/src/applications/people/controller/PhabricatorPeopleProfileController.php b/src/applications/people/controller/PhabricatorPeopleProfileController.php
--- a/src/applications/people/controller/PhabricatorPeopleProfileController.php
+++ b/src/applications/people/controller/PhabricatorPeopleProfileController.php
@@ -64,6 +64,14 @@
->setWorkflow(!$can_edit));
if ($viewer->getIsAdmin()) {
+ $actions->addAction(
+ id(new PhabricatorActionView())
+ ->setIcon('wrench')
+ ->setName(pht('Edit Settings'))
+ ->setDisabled(!$can_edit)
+ ->setWorkflow(!$can_edit)
+ ->setHref('/settings/'.$user->getID().'/'));
+
if ($user->getIsAdmin()) {
$empower_icon = 'lower-priority';
$empower_name = pht('Remove Administrator');
diff --git a/src/applications/settings/application/PhabricatorApplicationSettings.php b/src/applications/settings/application/PhabricatorApplicationSettings.php
--- a/src/applications/settings/application/PhabricatorApplicationSettings.php
+++ b/src/applications/settings/application/PhabricatorApplicationSettings.php
@@ -21,7 +21,8 @@
public function getRoutes() {
return array(
'/settings/' => array(
- '(?:panel/(?P<key>[^/]+)/)?' => 'PhabricatorSettingsMainController',
+ '(?:(?P<id>\d+)/)?(?:panel/(?P<key>[^/]+)/)?'
+ => 'PhabricatorSettingsMainController',
'adjust/' => 'PhabricatorSettingsAdjustController',
),
);
diff --git a/src/applications/settings/controller/PhabricatorSettingsMainController.php b/src/applications/settings/controller/PhabricatorSettingsMainController.php
--- a/src/applications/settings/controller/PhabricatorSettingsMainController.php
+++ b/src/applications/settings/controller/PhabricatorSettingsMainController.php
@@ -3,14 +3,48 @@
final class PhabricatorSettingsMainController
extends PhabricatorController {
+ private $id;
private $key;
+ private $user;
+
+ private function getUser() {
+ return $this->user;
+ }
+
+ private function isSelf() {
+ $viewer_phid = $this->getRequest()->getUser()->getPHID();
+ $user_phid = $this->getUser()->getPHID();
+ return ($viewer_phid == $user_phid);
+ }
public function willProcessRequest(array $data) {
+ $this->id = idx($data, 'id');
$this->key = idx($data, 'key');
}
public function processRequest() {
$request = $this->getRequest();
+ $viewer = $request->getUser();
+
+ if ($this->id) {
+ $user = id(new PhabricatorPeopleQuery())
+ ->setViewer($viewer)
+ ->withIDs(array($this->id))
+ ->requireCapabilities(
+ array(
+ PhabricatorPolicyCapability::CAN_VIEW,
+ PhabricatorPolicyCapability::CAN_EDIT,
+ ))
+ ->executeOne();
+
+ if (!$user) {
+ return new Aphront404Response();
+ }
+
+ $this->user = $user;
+ } else {
+ $this->user = $viewer;
+ }
$panels = $this->buildPanels();
$nav = $this->renderSideNav($panels);
@@ -19,13 +53,27 @@
$panel = $panels[$key];
+ $panel->setUser($this->getUser());
+ $panel->setViewer($viewer);
$response = $panel->processRequest($request);
if ($response instanceof AphrontResponse) {
return $response;
}
- $nav->appendChild($response);
+ $crumbs = $this->buildApplicationCrumbs();
+ if (!$this->isSelf()) {
+ $crumbs->addTextCrumb(
+ $this->getUser()->getUsername(),
+ '/p/'.$this->getUser()->getUsername().'/');
+ }
+ $crumbs->addTextCrumb($panel->getPanelName());
+ $nav->appendChild(
+ array(
+ $crumbs,
+ $response,
+ ));
+
return $this->buildApplicationPage(
$nav,
array(
@@ -54,6 +102,13 @@
if (!$panel->isEnabled()) {
continue;
}
+
+ if (!$this->isSelf()) {
+ if (!$panel->isEditableByAdministrators()) {
+ continue;
+ }
+ }
+
if (!empty($result[$key])) {
throw new Exception(pht(
"Two settings panels share the same panel key ('%s'): %s, %s.",
@@ -61,17 +116,29 @@
get_class($panel),
get_class($result[$key])));
}
+
$result[$key] = $panel;
}
$result = msort($result, 'getPanelSortKey');
+ if (!$result) {
+ throw new Exception(pht('No settings panels are available.'));
+ }
+
return $result;
}
private function renderSideNav(array $panels) {
$nav = new AphrontSideNavFilterView();
- $nav->setBaseURI(new PhutilURI($this->getApplicationURI('/panel/')));
+
+ if ($this->isSelf()) {
+ $base_uri = 'panel/';
+ } else {
+ $base_uri = $this->getUser()->getID().'/panel/';
+ }
+
+ $nav->setBaseURI(new PhutilURI($this->getApplicationURI($base_uri)));
$group = null;
foreach ($panels as $panel) {
diff --git a/src/applications/settings/panel/PhabricatorSettingsPanel.php b/src/applications/settings/panel/PhabricatorSettingsPanel.php
--- a/src/applications/settings/panel/PhabricatorSettingsPanel.php
+++ b/src/applications/settings/panel/PhabricatorSettingsPanel.php
@@ -17,6 +17,27 @@
*/
abstract class PhabricatorSettingsPanel {
+ private $user;
+ private $viewer;
+
+ public function setUser(PhabricatorUser $user) {
+ $this->user = $user;
+ return $this;
+ }
+
+ public function getUser() {
+ return $this->user;
+ }
+
+ public function setViewer(PhabricatorUser $viewer) {
+ $this->viewer = $viewer;
+ return $this;
+ }
+
+ public function getViewer() {
+ return $this->viewer;
+ }
+
/* -( Panel Configuration )------------------------------------------------ */
@@ -86,6 +107,18 @@
}
+ /**
+ * Return true if this panel is available to administrators while editing
+ * system agent accounts.
+ *
+ * @return bool True to enable edit by administrators.
+ * @task config
+ */
+ public function isEditableByAdministrators() {
+ return false;
+ }
+
+
/* -( Panel Implementation )----------------------------------------------- */
@@ -117,7 +150,15 @@
final public function getPanelURI($path = '') {
$key = $this->getPanelKey();
$key = phutil_escape_uri($key);
- return '/settings/panel/'.$key.'/'.ltrim($path, '/');
+
+ $path = ltrim($path, '/');
+
+ if ($this->getUser()->getPHID() != $this->getViewer()->getPHID()) {
+ $user_id = $this->getUser()->getID();
+ return "/settings/{$user_id}/panel/{$key}/{$path}";
+ } else {
+ return "/settings/panel/{$key}/{$path}";
+ }
}
diff --git a/src/applications/settings/panel/PhabricatorSettingsPanelConduit.php b/src/applications/settings/panel/PhabricatorSettingsPanelConduit.php
--- a/src/applications/settings/panel/PhabricatorSettingsPanelConduit.php
+++ b/src/applications/settings/panel/PhabricatorSettingsPanelConduit.php
@@ -3,12 +3,16 @@
final class PhabricatorSettingsPanelConduit
extends PhabricatorSettingsPanel {
+ public function isEditableByAdministrators() {
+ return true;
+ }
+
public function getPanelKey() {
return 'conduit';
}
public function getPanelName() {
- return pht('Conduit');
+ return pht('Conduit Certificate');
}
public function getPanelGroup() {
@@ -16,12 +20,13 @@
}
public function processRequest(AphrontRequest $request) {
- $user = $request->getUser();
+ $user = $this->getUser();
+ $viewer = $request->getUser();
if ($request->isFormPost()) {
if (!$request->isDialogFormPost()) {
$dialog = new AphrontDialogView();
- $dialog->setUser($user);
+ $dialog->setUser($viewer);
$dialog->setTitle(pht('Really regenerate session?'));
$dialog->setSubmitURI($this->getPanelURI());
$dialog->addSubmitButton(pht('Regenerate'));
@@ -69,7 +74,7 @@
$cert_form = new AphrontFormView();
$cert_form
- ->setUser($user)
+ ->setUser($viewer)
->appendChild(phutil_tag(
'p',
array('class' => 'aphront-form-instructions'),
@@ -93,7 +98,7 @@
$regen_form = new AphrontFormView();
$regen_form
- ->setUser($user)
+ ->setUser($viewer)
->setAction($this->getPanelURI())
->setWorkflow(true)
->appendChild(phutil_tag(
diff --git a/src/applications/settings/panel/PhabricatorSettingsPanelSSHKeys.php b/src/applications/settings/panel/PhabricatorSettingsPanelSSHKeys.php
--- a/src/applications/settings/panel/PhabricatorSettingsPanelSSHKeys.php
+++ b/src/applications/settings/panel/PhabricatorSettingsPanelSSHKeys.php
@@ -3,6 +3,10 @@
final class PhabricatorSettingsPanelSSHKeys
extends PhabricatorSettingsPanel {
+ public function isEditableByAdministrators() {
+ return true;
+ }
+
public function getPanelKey() {
return 'ssh';
}
@@ -20,8 +24,8 @@
}
public function processRequest(AphrontRequest $request) {
-
- $user = $request->getUser();
+ $viewer = $request->getUser();
+ $user = $this->getUser();
$generate = $request->getStr('generate');
if ($generate) {
@@ -37,7 +41,7 @@
$id = nonempty($edit, $delete);
if ($id && is_numeric($id)) {
- // NOTE: Prevent editing/deleting of keys you don't own.
+ // NOTE: This prevents editing/deleting of keys not owned by the user.
$key = id(new PhabricatorUserSSHKey())->loadOneWhere(
'userPHID = %s AND id = %d',
$user->getPHID(),
@@ -142,7 +146,7 @@
}
$form = id(new AphrontFormView())
- ->setUser($user)
+ ->setUser($viewer)
->addHiddenInput('edit', $is_new ? 'true' : $key->getID())
->appendChild(
id(new AphrontFormTextControl())
@@ -170,8 +174,8 @@
}
private function renderKeyListView(AphrontRequest $request) {
-
- $user = $request->getUser();
+ $user = $this->getUser();
+ $viewer = $request->getUser();
$keys = id(new PhabricatorUserSSHKey())->loadAllWhere(
'userPHID = %s',
@@ -188,8 +192,8 @@
$key->getName()),
$key->getKeyComment(),
$key->getKeyType(),
- phabricator_date($key->getDateCreated(), $user),
- phabricator_time($key->getDateCreated(), $user),
+ phabricator_date($key->getDateCreated(), $viewer),
+ phabricator_time($key->getDateCreated(), $viewer),
javelin_tag(
'a',
array(
@@ -266,7 +270,8 @@
AphrontRequest $request,
PhabricatorUserSSHKey $key) {
- $user = $request->getUser();
+ $viewer = $request->getUser();
+ $user = $this->getUser();
$name = phutil_tag('strong', array(), $key->getName());
@@ -277,7 +282,7 @@
}
$dialog = id(new AphrontDialogView())
- ->setUser($user)
+ ->setUser($viewer)
->addHiddenInput('delete', $key->getID())
->setTitle(pht('Really delete SSH Public Key?'))
->appendChild(phutil_tag('p', array(), pht(
@@ -291,10 +296,12 @@
->setDialog($dialog);
}
- private function processGenerate(
- AphrontRequest $request) {
+ private function processGenerate(AphrontRequest $request) {
+ $user = $this->getUser();
$viewer = $request->getUser();
+ $is_self = ($user->getPHID() == $viewer->getPHID());
+
if ($request->isFormPost()) {
$keys = PhabricatorSSHKeyGenerator::generateKeypair();
list($public_key, $private_key) = $keys;
@@ -308,7 +315,7 @@
));
$key = id(new PhabricatorUserSSHKey())
- ->setUserPHID($viewer->getPHID())
+ ->setUserPHID($user->getPHID())
->setName('id_rsa_phabricator')
->setKeyType('rsa')
->setKeyBody($public_key)
@@ -320,6 +327,17 @@
// disabling workflow on cancel so the page reloads, showing the new
// key.
+ if ($is_self) {
+ $what_happened = pht(
+ 'The public key has been associated with your Phabricator '.
+ 'account. Use the button below to download the private key.');
+ } else {
+ $what_happened = pht(
+ 'The public key has been associated with the %s account. '.
+ 'Use the button below to download the private key.',
+ phutil_tag('strong', array(), $user->getUsername()));
+ }
+
$dialog = id(new AphrontDialogView())
->setTitle(pht('Download Private Key'))
->setUser($viewer)
@@ -329,10 +347,7 @@
->appendParagraph(
pht(
'Successfully generated a new keypair.'))
- ->appendParagraph(
- pht(
- 'The public key has been associated with your Phabricator '.
- 'account. Use the button below to download the private key.'))
+ ->appendParagraph($what_happened)
->appendParagraph(
pht(
'After you download the private key, it will be destroyed. '.
@@ -350,13 +365,22 @@
try {
PhabricatorSSHKeyGenerator::assertCanGenerateKeypair();
+
+ if ($is_self) {
+ $explain = pht(
+ 'This will generate an SSH keypair, associate the public key '.
+ 'with your account, and let you download the private key.');
+ } else {
+ $explain = pht(
+ 'This will generate an SSH keypair, associate the public key with '.
+ 'the %s account, and let you download the private key.',
+ phutil_tag('strong', array(), $user->getUsername()));
+ }
+
$dialog
->addHiddenInput('generate', true)
->setTitle(pht('Generate New Keypair'))
- ->appendParagraph(
- pht(
- "This will generate an SSH keypair, associate the public key ".
- "with your account, and let you download the private key."))
+ ->appendParagraph($explain)
->appendParagraph(
pht(
"Phabricator will not retain a copy of the private key."))
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Dec 20, 7:07 PM (17 h, 41 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6911718
Default Alt Text
D8668.diff (17 KB)
Attached To
Mode
D8668: Give administrators selective access to System Agent settings panels
Attached
Detach File
Event Timeline
Log In to Comment