2011-01-24 03:09:16 +01:00
|
|
|
<?php
|
|
|
|
|
2012-03-10 00:46:25 +01:00
|
|
|
final class PhabricatorPeopleEditController
|
|
|
|
extends PhabricatorPeopleController {
|
2011-01-24 03:09:16 +01:00
|
|
|
|
2011-05-12 19:06:54 +02:00
|
|
|
private $id;
|
|
|
|
private $view;
|
2011-01-24 03:09:16 +01:00
|
|
|
|
|
|
|
public function willProcessRequest(array $data) {
|
2011-05-12 19:06:54 +02:00
|
|
|
$this->id = idx($data, 'id');
|
|
|
|
$this->view = idx($data, 'view');
|
2011-01-24 03:09:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function processRequest() {
|
|
|
|
|
2011-05-12 19:06:54 +02:00
|
|
|
$request = $this->getRequest();
|
|
|
|
$admin = $request->getUser();
|
2011-02-20 01:46:14 +01:00
|
|
|
|
2013-02-21 23:10:22 +01:00
|
|
|
$crumbs = $this->buildApplicationCrumbs($this->buildSideNavView());
|
2011-05-12 19:06:54 +02:00
|
|
|
if ($this->id) {
|
|
|
|
$user = id(new PhabricatorUser())->load($this->id);
|
2011-01-24 03:09:16 +01:00
|
|
|
if (!$user) {
|
|
|
|
return new Aphront404Response();
|
|
|
|
}
|
2012-06-06 16:09:56 +02:00
|
|
|
$base_uri = '/people/edit/'.$user->getID().'/';
|
2013-02-21 23:10:22 +01:00
|
|
|
$crumbs->addCrumb(
|
|
|
|
id(new PhabricatorCrumbView())
|
|
|
|
->setName(pht('Edit User'))
|
|
|
|
->setHref('/people/edit/'));
|
|
|
|
$crumbs->addCrumb(
|
|
|
|
id(new PhabricatorCrumbView())
|
|
|
|
->setName($user->getFullName())
|
|
|
|
->setHref($base_uri));
|
2011-01-24 03:09:16 +01:00
|
|
|
} else {
|
|
|
|
$user = new PhabricatorUser();
|
2012-06-06 16:09:56 +02:00
|
|
|
$base_uri = '/people/edit/';
|
2013-02-21 23:10:22 +01:00
|
|
|
$crumbs->addCrumb(
|
|
|
|
id(new PhabricatorCrumbView())
|
|
|
|
->setName(pht('Create New User'))
|
|
|
|
->setHref($base_uri));
|
2011-01-24 03:09:16 +01:00
|
|
|
}
|
|
|
|
|
2012-06-06 16:09:56 +02:00
|
|
|
$nav = new AphrontSideNavFilterView();
|
|
|
|
$nav->setBaseURI(new PhutilURI($base_uri));
|
2013-02-21 23:10:22 +01:00
|
|
|
$nav->addLabel(pht('User Information'));
|
|
|
|
$nav->addFilter('basic', pht('Basic Information'));
|
|
|
|
$nav->addFilter('role', pht('Edit Roles'));
|
|
|
|
$nav->addFilter('cert', pht('Conduit Certificate'));
|
|
|
|
$nav->addFilter('profile',
|
|
|
|
pht('View Profile'), '/p/'.$user->getUsername().'/');
|
|
|
|
$nav->addLabel(pht('Special'));
|
|
|
|
$nav->addFilter('rename', pht('Change Username'));
|
2013-03-16 16:44:01 +01:00
|
|
|
if ($user->getIsSystemAgent()) {
|
|
|
|
$nav->addFilter('picture', pht('Set Account Picture'));
|
|
|
|
}
|
2013-02-21 23:10:22 +01:00
|
|
|
$nav->addFilter('delete', pht('Delete User'));
|
2011-05-12 19:06:54 +02:00
|
|
|
|
|
|
|
if (!$user->getID()) {
|
2012-06-06 16:09:56 +02:00
|
|
|
$this->view = 'basic';
|
2011-05-12 19:06:54 +02:00
|
|
|
}
|
2012-08-14 00:27:21 +02:00
|
|
|
|
2012-06-06 16:09:56 +02:00
|
|
|
$view = $nav->selectFilter($this->view, 'basic');
|
2011-05-12 19:06:54 +02:00
|
|
|
|
|
|
|
$content = array();
|
|
|
|
|
|
|
|
if ($request->getStr('saved')) {
|
|
|
|
$notice = new AphrontErrorView();
|
|
|
|
$notice->setSeverity(AphrontErrorView::SEVERITY_NOTICE);
|
2013-02-21 23:10:22 +01:00
|
|
|
$notice->setTitle(pht('Changes Saved'));
|
2013-02-07 01:53:49 +01:00
|
|
|
$notice->appendChild(
|
2013-02-21 23:10:22 +01:00
|
|
|
phutil_tag('p', array(), pht('Your changes were saved.')));
|
2011-05-12 19:06:54 +02:00
|
|
|
$content[] = $notice;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch ($view) {
|
|
|
|
case 'basic':
|
|
|
|
$response = $this->processBasicRequest($user);
|
|
|
|
break;
|
|
|
|
case 'role':
|
|
|
|
$response = $this->processRoleRequest($user);
|
|
|
|
break;
|
2011-05-17 22:15:19 +02:00
|
|
|
case 'cert':
|
|
|
|
$response = $this->processCertificateRequest($user);
|
|
|
|
break;
|
2012-06-06 16:09:56 +02:00
|
|
|
case 'rename':
|
|
|
|
$response = $this->processRenameRequest($user);
|
|
|
|
break;
|
2013-03-08 17:31:25 +01:00
|
|
|
case 'picture':
|
|
|
|
$response = $this->processSetAccountPicture($user);
|
|
|
|
break;
|
2012-06-16 02:02:20 +02:00
|
|
|
case 'delete':
|
|
|
|
$response = $this->processDeleteRequest($user);
|
|
|
|
break;
|
2012-06-06 16:09:56 +02:00
|
|
|
default:
|
|
|
|
return new Aphront404Response();
|
2011-05-12 19:06:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if ($response instanceof AphrontResponse) {
|
|
|
|
return $response;
|
|
|
|
}
|
|
|
|
|
|
|
|
$content[] = $response;
|
|
|
|
|
|
|
|
if ($user->getID()) {
|
2012-06-06 16:09:56 +02:00
|
|
|
$nav->appendChild($content);
|
2012-08-14 00:27:21 +02:00
|
|
|
} else {
|
|
|
|
$nav = $this->buildSideNavView();
|
|
|
|
$nav->selectFilter('edit');
|
|
|
|
$nav->appendChild($content);
|
2011-05-12 19:06:54 +02:00
|
|
|
}
|
|
|
|
|
2013-02-21 23:10:22 +01:00
|
|
|
$nav->setCrumbs($crumbs);
|
2012-08-14 00:27:21 +02:00
|
|
|
return $this->buildApplicationPage(
|
|
|
|
$nav,
|
2011-05-12 19:06:54 +02:00
|
|
|
array(
|
2013-02-21 23:10:22 +01:00
|
|
|
'title' => pht('Edit User'),
|
|
|
|
'device' => true,
|
2011-05-12 19:06:54 +02:00
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
private function processBasicRequest(PhabricatorUser $user) {
|
|
|
|
$request = $this->getRequest();
|
|
|
|
$admin = $request->getUser();
|
|
|
|
|
2011-01-24 03:09:16 +01:00
|
|
|
$e_username = true;
|
|
|
|
$e_realname = true;
|
|
|
|
$e_email = true;
|
|
|
|
$errors = array();
|
|
|
|
|
Revise administrative workflow for user creation
Summary:
- When an administrator creates a user, provide an option to send a welcome
email. Right now this workflow kind of dead-ends.
- Prevent administrators from changing the "System Agent" flag. If they can
change it, they can grab another user's certificate and then act as them. This
is a vaguely weaker security policy than is exhibited elsewhere in the
application. Instead, make user accounts immutably normal users or system agents
at creation time.
- Prevent administrators from changing email addresses after account creation.
Same deal as conduit certs. The 'bin/accountadmin' script can still do this if a
user has a real problem.
- Prevent administrators from resetting passwords. There's no need for this
anymore with welcome emails plus email login and it raises the same issues.
Test Plan:
- Created a new account, selected "send welcome email", got a welcome email,
logged in with the link inside it.
- Created a new system agent.
- Reset an account's password.
Reviewed By: aran
Reviewers: tuomaspelkonen, jungejason, aran
CC: anjali, aran, epriestley
Differential Revision: 379
2011-05-30 23:59:17 +02:00
|
|
|
$welcome_checked = true;
|
|
|
|
|
2012-05-07 19:29:33 +02:00
|
|
|
$new_email = null;
|
|
|
|
|
2011-01-24 03:09:16 +01:00
|
|
|
$request = $this->getRequest();
|
|
|
|
if ($request->isFormPost()) {
|
Revise administrative workflow for user creation
Summary:
- When an administrator creates a user, provide an option to send a welcome
email. Right now this workflow kind of dead-ends.
- Prevent administrators from changing the "System Agent" flag. If they can
change it, they can grab another user's certificate and then act as them. This
is a vaguely weaker security policy than is exhibited elsewhere in the
application. Instead, make user accounts immutably normal users or system agents
at creation time.
- Prevent administrators from changing email addresses after account creation.
Same deal as conduit certs. The 'bin/accountadmin' script can still do this if a
user has a real problem.
- Prevent administrators from resetting passwords. There's no need for this
anymore with welcome emails plus email login and it raises the same issues.
Test Plan:
- Created a new account, selected "send welcome email", got a welcome email,
logged in with the link inside it.
- Created a new system agent.
- Reset an account's password.
Reviewed By: aran
Reviewers: tuomaspelkonen, jungejason, aran
CC: anjali, aran, epriestley
Differential Revision: 379
2011-05-30 23:59:17 +02:00
|
|
|
$welcome_checked = $request->getInt('welcome');
|
2012-08-29 20:07:29 +02:00
|
|
|
$is_new = !$user->getID();
|
Revise administrative workflow for user creation
Summary:
- When an administrator creates a user, provide an option to send a welcome
email. Right now this workflow kind of dead-ends.
- Prevent administrators from changing the "System Agent" flag. If they can
change it, they can grab another user's certificate and then act as them. This
is a vaguely weaker security policy than is exhibited elsewhere in the
application. Instead, make user accounts immutably normal users or system agents
at creation time.
- Prevent administrators from changing email addresses after account creation.
Same deal as conduit certs. The 'bin/accountadmin' script can still do this if a
user has a real problem.
- Prevent administrators from resetting passwords. There's no need for this
anymore with welcome emails plus email login and it raises the same issues.
Test Plan:
- Created a new account, selected "send welcome email", got a welcome email,
logged in with the link inside it.
- Created a new system agent.
- Reset an account's password.
Reviewed By: aran
Reviewers: tuomaspelkonen, jungejason, aran
CC: anjali, aran, epriestley
Differential Revision: 379
2011-05-30 23:59:17 +02:00
|
|
|
|
2012-08-29 20:07:29 +02:00
|
|
|
if ($is_new) {
|
2011-01-24 03:09:16 +01:00
|
|
|
$user->setUsername($request->getStr('username'));
|
2012-05-07 19:29:33 +02:00
|
|
|
|
|
|
|
$new_email = $request->getStr('email');
|
|
|
|
if (!strlen($new_email)) {
|
2013-02-21 23:10:22 +01:00
|
|
|
$errors[] = pht('Email is required.');
|
|
|
|
$e_email = pht('Required');
|
Allow restriction of permitted email domains
Summary:
Allow allowed email addresses to be restricted to certain domains. This implies email must be verified.
This probably isn't QUITE ready for prime-time without a few other tweaks (better administrative tools, notably) but we're nearly there.
Test Plan:
- With no restrictions:
- Registered with OAuth
- Created an account with accountadmin
- Added an email
- With restrictions:
- Tried to OAuth register with a restricted address, was prompted to provide a valid one.
- Tried to OAuth register with a valid address, worked fine.
- Tried to accountadmin a restricted address, got blocked.
- Tried to accountadmin a valid address, worked fine.
- Tried to add a restricted address, blocked.
- Tried to add a valid address, worked fine.
- Created a user with People with an invalid address, got blocked.
- Created a user with People with a valid address, worked fine.
Reviewers: btrahan, csilvers
Reviewed By: csilvers
CC: aran, joe, csilvers
Maniphest Tasks: T1184
Differential Revision: https://secure.phabricator.com/D2581
2012-05-26 15:04:35 +02:00
|
|
|
} else if (!PhabricatorUserEmail::isAllowedAddress($new_email)) {
|
2013-02-21 23:10:22 +01:00
|
|
|
$e_email = pht('Invalid');
|
Allow restriction of permitted email domains
Summary:
Allow allowed email addresses to be restricted to certain domains. This implies email must be verified.
This probably isn't QUITE ready for prime-time without a few other tweaks (better administrative tools, notably) but we're nearly there.
Test Plan:
- With no restrictions:
- Registered with OAuth
- Created an account with accountadmin
- Added an email
- With restrictions:
- Tried to OAuth register with a restricted address, was prompted to provide a valid one.
- Tried to OAuth register with a valid address, worked fine.
- Tried to accountadmin a restricted address, got blocked.
- Tried to accountadmin a valid address, worked fine.
- Tried to add a restricted address, blocked.
- Tried to add a valid address, worked fine.
- Created a user with People with an invalid address, got blocked.
- Created a user with People with a valid address, worked fine.
Reviewers: btrahan, csilvers
Reviewed By: csilvers
CC: aran, joe, csilvers
Maniphest Tasks: T1184
Differential Revision: https://secure.phabricator.com/D2581
2012-05-26 15:04:35 +02:00
|
|
|
$errors[] = PhabricatorUserEmail::describeAllowedAddresses();
|
Fix transaction handling in PhabricatorUserEditor->createNewUser()
Summary:
See https://github.com/facebook/phabricator/issues/117
- The $user save can hit a duplicate key exception like the email, but we don't handle it correctly.
- When the $user saves but the $email does not, the $user is left with a (rolled-back, invalid) ID. This makes the UI glitch out a bit. Wipe the ID if we abort the transaction.
- We show the "Required" star marker even if the email is filled in.
The ID issue is sort of a general problem, but I think it's fairly rare: you must be doing inserts on related objects and the caller must catch the transaction failure and attempt to handle it in some way.
I can think of three approaches:
- Manually "roll back" the objects inside the transaction, as here. Seems OK if this really is a rare problem.
- Automatically roll back the 'id' and 'phid' columns (if they exist). Seems reasonable but maybe more complicated than necessary. Won't get every case right. For instance, if we inserted a third object here and that failed, $email would still have the userPHID set.
- Automatically roll back the entire object. We can do this by cloning all the writable fields. Seems like it might be way too magical, but maybe the right solution? Might have weird bugs with nonwritable fields and other random stuff.
We can trigger the rollback by storing objects we updated on the transaction, and either throwing them away or rolling them back on saveTransaction() / killTransaction().
These fancier approaches all seem to have some tradeoffs though, and I don't think we need to pick one yet, since this has only caused problems in one case.
Test Plan: Tried to create a new user (via People -> Create New User) with a duplicate username. Got a proper UI message with no exception and no UI glitchiness.
Reviewers: btrahan, vrana, hgrimberg, hgrimberg01
Reviewed By: hgrimberg01
CC: aran
Differential Revision: https://secure.phabricator.com/D2650
2012-06-05 15:46:01 +02:00
|
|
|
} else {
|
|
|
|
$e_email = null;
|
2012-05-07 19:29:33 +02:00
|
|
|
}
|
Revise administrative workflow for user creation
Summary:
- When an administrator creates a user, provide an option to send a welcome
email. Right now this workflow kind of dead-ends.
- Prevent administrators from changing the "System Agent" flag. If they can
change it, they can grab another user's certificate and then act as them. This
is a vaguely weaker security policy than is exhibited elsewhere in the
application. Instead, make user accounts immutably normal users or system agents
at creation time.
- Prevent administrators from changing email addresses after account creation.
Same deal as conduit certs. The 'bin/accountadmin' script can still do this if a
user has a real problem.
- Prevent administrators from resetting passwords. There's no need for this
anymore with welcome emails plus email login and it raises the same issues.
Test Plan:
- Created a new account, selected "send welcome email", got a welcome email,
logged in with the link inside it.
- Created a new system agent.
- Reset an account's password.
Reviewed By: aran
Reviewers: tuomaspelkonen, jungejason, aran
CC: anjali, aran, epriestley
Differential Revision: 379
2011-05-30 23:59:17 +02:00
|
|
|
|
2011-01-24 03:09:16 +01:00
|
|
|
}
|
|
|
|
$user->setRealName($request->getStr('realname'));
|
|
|
|
|
|
|
|
if (!strlen($user->getUsername())) {
|
2013-02-21 23:10:22 +01:00
|
|
|
$errors[] = pht("Username is required.");
|
|
|
|
$e_username = pht('Required');
|
2012-01-16 16:30:28 +01:00
|
|
|
} else if (!PhabricatorUser::validateUsername($user->getUsername())) {
|
2012-06-06 16:09:05 +02:00
|
|
|
$errors[] = PhabricatorUser::describeValidUsername();
|
2013-02-21 23:10:22 +01:00
|
|
|
$e_username = pht('Invalid');
|
2011-05-12 19:06:54 +02:00
|
|
|
} else {
|
|
|
|
$e_username = null;
|
2011-01-24 03:09:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!strlen($user->getRealName())) {
|
2013-02-21 23:10:22 +01:00
|
|
|
$errors[] = pht('Real name is required.');
|
|
|
|
$e_realname = pht('Required');
|
2011-05-12 19:06:54 +02:00
|
|
|
} else {
|
|
|
|
$e_realname = null;
|
2011-01-24 03:09:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!$errors) {
|
2011-05-12 19:06:54 +02:00
|
|
|
try {
|
Revise administrative workflow for user creation
Summary:
- When an administrator creates a user, provide an option to send a welcome
email. Right now this workflow kind of dead-ends.
- Prevent administrators from changing the "System Agent" flag. If they can
change it, they can grab another user's certificate and then act as them. This
is a vaguely weaker security policy than is exhibited elsewhere in the
application. Instead, make user accounts immutably normal users or system agents
at creation time.
- Prevent administrators from changing email addresses after account creation.
Same deal as conduit certs. The 'bin/accountadmin' script can still do this if a
user has a real problem.
- Prevent administrators from resetting passwords. There's no need for this
anymore with welcome emails plus email login and it raises the same issues.
Test Plan:
- Created a new account, selected "send welcome email", got a welcome email,
logged in with the link inside it.
- Created a new system agent.
- Reset an account's password.
Reviewed By: aran
Reviewers: tuomaspelkonen, jungejason, aran
CC: anjali, aran, epriestley
Differential Revision: 379
2011-05-30 23:59:17 +02:00
|
|
|
|
2012-05-25 16:30:44 +02:00
|
|
|
if (!$is_new) {
|
|
|
|
id(new PhabricatorUserEditor())
|
|
|
|
->setActor($admin)
|
|
|
|
->updateUser($user);
|
|
|
|
} else {
|
2012-05-07 19:29:33 +02:00
|
|
|
$email = id(new PhabricatorUserEmail())
|
|
|
|
->setAddress($new_email)
|
2012-05-25 16:30:44 +02:00
|
|
|
->setIsVerified(0);
|
2012-05-07 19:29:33 +02:00
|
|
|
|
2012-05-25 16:30:44 +02:00
|
|
|
id(new PhabricatorUserEditor())
|
|
|
|
->setActor($admin)
|
|
|
|
->createNewUser($user, $email);
|
2012-08-29 20:07:29 +02:00
|
|
|
|
|
|
|
if ($request->getStr('role') == 'agent') {
|
|
|
|
id(new PhabricatorUserEditor())
|
|
|
|
->setActor($admin)
|
|
|
|
->makeSystemAgentUser($user, true);
|
|
|
|
}
|
|
|
|
|
2012-07-26 23:41:14 +02:00
|
|
|
}
|
Revise administrative workflow for user creation
Summary:
- When an administrator creates a user, provide an option to send a welcome
email. Right now this workflow kind of dead-ends.
- Prevent administrators from changing the "System Agent" flag. If they can
change it, they can grab another user's certificate and then act as them. This
is a vaguely weaker security policy than is exhibited elsewhere in the
application. Instead, make user accounts immutably normal users or system agents
at creation time.
- Prevent administrators from changing email addresses after account creation.
Same deal as conduit certs. The 'bin/accountadmin' script can still do this if a
user has a real problem.
- Prevent administrators from resetting passwords. There's no need for this
anymore with welcome emails plus email login and it raises the same issues.
Test Plan:
- Created a new account, selected "send welcome email", got a welcome email,
logged in with the link inside it.
- Created a new system agent.
- Reset an account's password.
Reviewed By: aran
Reviewers: tuomaspelkonen, jungejason, aran
CC: anjali, aran, epriestley
Differential Revision: 379
2011-05-30 23:59:17 +02:00
|
|
|
|
2012-07-26 23:41:14 +02:00
|
|
|
if ($welcome_checked) {
|
|
|
|
$user->sendWelcomeEmail($admin);
|
Revise administrative workflow for user creation
Summary:
- When an administrator creates a user, provide an option to send a welcome
email. Right now this workflow kind of dead-ends.
- Prevent administrators from changing the "System Agent" flag. If they can
change it, they can grab another user's certificate and then act as them. This
is a vaguely weaker security policy than is exhibited elsewhere in the
application. Instead, make user accounts immutably normal users or system agents
at creation time.
- Prevent administrators from changing email addresses after account creation.
Same deal as conduit certs. The 'bin/accountadmin' script can still do this if a
user has a real problem.
- Prevent administrators from resetting passwords. There's no need for this
anymore with welcome emails plus email login and it raises the same issues.
Test Plan:
- Created a new account, selected "send welcome email", got a welcome email,
logged in with the link inside it.
- Created a new system agent.
- Reset an account's password.
Reviewed By: aran
Reviewers: tuomaspelkonen, jungejason, aran
CC: anjali, aran, epriestley
Differential Revision: 379
2011-05-30 23:59:17 +02:00
|
|
|
}
|
Provide an activity log for login and administrative actions
Summary: This isn't complete, but I figured I'd ship it for review while it's still smallish.
Provide an activity log for high-level system actions (logins, admin actions). This basically allows two things to happen:
- The log itself is useful if there are shenanigans.
- Password login can check it and start CAPTCHA'ing users after a few failed attempts.
I'm going to change how the admin stuff works a little bit too, since right now you can make someone an agent, grab their certificate, revert them back to a normal user, and then act on their behalf over Conduit. This is a little silly, I'm going to move "agent" to the create workflow instead. I'll also add a confirm/email step to the administrative password reset flow.
Test Plan: Took various administrative and non-administrative actions, they appeared in the logs. Filtered the logs in a bunch of different ways.
Reviewers: jungejason, tuomaspelkonen, aran
CC:
Differential Revision: 302
2011-05-18 03:42:21 +02:00
|
|
|
|
2011-05-12 19:06:54 +02:00
|
|
|
$response = id(new AphrontRedirectResponse())
|
|
|
|
->setURI('/people/edit/'.$user->getID().'/?saved=true');
|
|
|
|
return $response;
|
|
|
|
} catch (AphrontQueryDuplicateKeyException $ex) {
|
2013-02-21 23:10:22 +01:00
|
|
|
$errors[] = pht('Username and email must be unique.');
|
2011-05-12 19:06:54 +02:00
|
|
|
|
|
|
|
$same_username = id(new PhabricatorUser())
|
|
|
|
->loadOneWhere('username = %s', $user->getUsername());
|
2012-05-07 19:29:33 +02:00
|
|
|
$same_email = id(new PhabricatorUserEmail())
|
|
|
|
->loadOneWhere('address = %s', $new_email);
|
2011-05-12 19:06:54 +02:00
|
|
|
|
|
|
|
if ($same_username) {
|
2013-02-21 23:10:22 +01:00
|
|
|
$e_username = pht('Duplicate');
|
2011-05-12 19:06:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if ($same_email) {
|
2013-02-21 23:10:22 +01:00
|
|
|
$e_email = pht('Duplicate');
|
2011-05-12 19:06:54 +02:00
|
|
|
}
|
|
|
|
}
|
2011-01-24 03:09:16 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$error_view = null;
|
|
|
|
if ($errors) {
|
|
|
|
$error_view = id(new AphrontErrorView())
|
2013-02-21 23:10:22 +01:00
|
|
|
->setTitle(pht('Form Errors'))
|
2011-01-24 03:09:16 +01:00
|
|
|
->setErrors($errors);
|
|
|
|
}
|
|
|
|
|
|
|
|
$form = new AphrontFormView();
|
2011-05-12 19:06:54 +02:00
|
|
|
$form->setUser($admin);
|
|
|
|
if ($user->getID()) {
|
|
|
|
$form->setAction('/people/edit/'.$user->getID().'/');
|
2011-01-24 03:09:16 +01:00
|
|
|
} else {
|
|
|
|
$form->setAction('/people/edit/');
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($user->getID()) {
|
|
|
|
$is_immutable = true;
|
|
|
|
} else {
|
|
|
|
$is_immutable = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
$form
|
|
|
|
->appendChild(
|
|
|
|
id(new AphrontFormTextControl())
|
2013-02-21 23:10:22 +01:00
|
|
|
->setLabel(pht('Username'))
|
2011-01-24 03:09:16 +01:00
|
|
|
->setName('username')
|
|
|
|
->setValue($user->getUsername())
|
|
|
|
->setError($e_username)
|
2012-06-16 02:02:20 +02:00
|
|
|
->setDisabled($is_immutable))
|
2011-01-24 03:09:16 +01:00
|
|
|
->appendChild(
|
|
|
|
id(new AphrontFormTextControl())
|
2013-02-21 23:10:22 +01:00
|
|
|
->setLabel(pht('Real Name'))
|
2011-01-24 03:09:16 +01:00
|
|
|
->setName('realname')
|
|
|
|
->setValue($user->getRealName())
|
2012-05-07 19:29:33 +02:00
|
|
|
->setError($e_realname));
|
|
|
|
|
|
|
|
if (!$user->getID()) {
|
|
|
|
$form->appendChild(
|
2011-01-24 03:09:16 +01:00
|
|
|
id(new AphrontFormTextControl())
|
2013-02-21 23:10:22 +01:00
|
|
|
->setLabel(pht('Email'))
|
2011-01-24 03:09:16 +01:00
|
|
|
->setName('email')
|
Revise administrative workflow for user creation
Summary:
- When an administrator creates a user, provide an option to send a welcome
email. Right now this workflow kind of dead-ends.
- Prevent administrators from changing the "System Agent" flag. If they can
change it, they can grab another user's certificate and then act as them. This
is a vaguely weaker security policy than is exhibited elsewhere in the
application. Instead, make user accounts immutably normal users or system agents
at creation time.
- Prevent administrators from changing email addresses after account creation.
Same deal as conduit certs. The 'bin/accountadmin' script can still do this if a
user has a real problem.
- Prevent administrators from resetting passwords. There's no need for this
anymore with welcome emails plus email login and it raises the same issues.
Test Plan:
- Created a new account, selected "send welcome email", got a welcome email,
logged in with the link inside it.
- Created a new system agent.
- Reset an account's password.
Reviewed By: aran
Reviewers: tuomaspelkonen, jungejason, aran
CC: anjali, aran, epriestley
Differential Revision: 379
2011-05-30 23:59:17 +02:00
|
|
|
->setDisabled($is_immutable)
|
2012-05-07 19:29:33 +02:00
|
|
|
->setValue($new_email)
|
Allow restriction of permitted email domains
Summary:
Allow allowed email addresses to be restricted to certain domains. This implies email must be verified.
This probably isn't QUITE ready for prime-time without a few other tweaks (better administrative tools, notably) but we're nearly there.
Test Plan:
- With no restrictions:
- Registered with OAuth
- Created an account with accountadmin
- Added an email
- With restrictions:
- Tried to OAuth register with a restricted address, was prompted to provide a valid one.
- Tried to OAuth register with a valid address, worked fine.
- Tried to accountadmin a restricted address, got blocked.
- Tried to accountadmin a valid address, worked fine.
- Tried to add a restricted address, blocked.
- Tried to add a valid address, worked fine.
- Created a user with People with an invalid address, got blocked.
- Created a user with People with a valid address, worked fine.
Reviewers: btrahan, csilvers
Reviewed By: csilvers
CC: aran, joe, csilvers
Maniphest Tasks: T1184
Differential Revision: https://secure.phabricator.com/D2581
2012-05-26 15:04:35 +02:00
|
|
|
->setCaption(PhabricatorUserEmail::describeAllowedAddresses())
|
2012-05-07 19:29:33 +02:00
|
|
|
->setError($e_email));
|
Allow installs to require email verification
Summary:
Allow installs to require users to verify email addresses before they can use Phabricator. If a user logs in without a verified email address, they're given instructions to verify their address.
This isn't too useful on its own since we don't actually have arbitrary email registration, but the next step is to allow installs to restrict email to only some domains (e.g., @mycompany.com).
Test Plan:
- Verification
- Set verification requirement to `true`.
- Tried to use Phabricator with an unverified account, was told to verify.
- Tried to use Conduit, was given a verification error.
- Verified account, used Phabricator.
- Unverified account, reset password, verified implicit verification, used Phabricator.
- People Admin Interface
- Viewed as admin. Clicked "Administrate User".
- Viewed as non-admin
- Sanity Checks
- Used Conduit normally from web/CLI with a verified account.
- Logged in/out.
- Sent password reset email.
- Created a new user.
- Logged in with an unverified user but with the configuration set to off.
Reviewers: btrahan, vrana, jungejason
Reviewed By: btrahan
CC: aran, csilvers
Maniphest Tasks: T1184
Differential Revision: https://secure.phabricator.com/D2520
2012-05-21 21:47:38 +02:00
|
|
|
} else {
|
2012-05-25 16:30:44 +02:00
|
|
|
$email = $user->loadPrimaryEmail();
|
|
|
|
if ($email) {
|
2013-02-21 23:10:22 +01:00
|
|
|
$status = $email->getIsVerified() ?
|
|
|
|
pht('Verified') : pht('Unverified');
|
2012-05-25 16:30:44 +02:00
|
|
|
} else {
|
2013-02-21 23:10:22 +01:00
|
|
|
$status = pht('No Email Address');
|
2012-05-25 16:30:44 +02:00
|
|
|
}
|
|
|
|
|
Allow installs to require email verification
Summary:
Allow installs to require users to verify email addresses before they can use Phabricator. If a user logs in without a verified email address, they're given instructions to verify their address.
This isn't too useful on its own since we don't actually have arbitrary email registration, but the next step is to allow installs to restrict email to only some domains (e.g., @mycompany.com).
Test Plan:
- Verification
- Set verification requirement to `true`.
- Tried to use Phabricator with an unverified account, was told to verify.
- Tried to use Conduit, was given a verification error.
- Verified account, used Phabricator.
- Unverified account, reset password, verified implicit verification, used Phabricator.
- People Admin Interface
- Viewed as admin. Clicked "Administrate User".
- Viewed as non-admin
- Sanity Checks
- Used Conduit normally from web/CLI with a verified account.
- Logged in/out.
- Sent password reset email.
- Created a new user.
- Logged in with an unverified user but with the configuration set to off.
Reviewers: btrahan, vrana, jungejason
Reviewed By: btrahan
CC: aran, csilvers
Maniphest Tasks: T1184
Differential Revision: https://secure.phabricator.com/D2520
2012-05-21 21:47:38 +02:00
|
|
|
$form->appendChild(
|
|
|
|
id(new AphrontFormStaticControl())
|
2013-02-21 23:10:22 +01:00
|
|
|
->setLabel(pht('Email'))
|
2012-05-25 16:30:44 +02:00
|
|
|
->setValue($status));
|
2012-07-26 23:41:14 +02:00
|
|
|
|
|
|
|
$form->appendChild(
|
|
|
|
id(new AphrontFormCheckboxControl())
|
|
|
|
->addCheckbox(
|
|
|
|
'welcome',
|
|
|
|
1,
|
2013-02-21 23:10:22 +01:00
|
|
|
pht('Re-send "Welcome to Phabricator" email.'),
|
2012-07-26 23:41:14 +02:00
|
|
|
false));
|
|
|
|
|
2012-05-07 19:29:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
$form->appendChild($this->getRoleInstructions());
|
Revise administrative workflow for user creation
Summary:
- When an administrator creates a user, provide an option to send a welcome
email. Right now this workflow kind of dead-ends.
- Prevent administrators from changing the "System Agent" flag. If they can
change it, they can grab another user's certificate and then act as them. This
is a vaguely weaker security policy than is exhibited elsewhere in the
application. Instead, make user accounts immutably normal users or system agents
at creation time.
- Prevent administrators from changing email addresses after account creation.
Same deal as conduit certs. The 'bin/accountadmin' script can still do this if a
user has a real problem.
- Prevent administrators from resetting passwords. There's no need for this
anymore with welcome emails plus email login and it raises the same issues.
Test Plan:
- Created a new account, selected "send welcome email", got a welcome email,
logged in with the link inside it.
- Created a new system agent.
- Reset an account's password.
Reviewed By: aran
Reviewers: tuomaspelkonen, jungejason, aran
CC: anjali, aran, epriestley
Differential Revision: 379
2011-05-30 23:59:17 +02:00
|
|
|
|
|
|
|
if (!$user->getID()) {
|
|
|
|
$form
|
|
|
|
->appendChild(
|
|
|
|
id(new AphrontFormSelectControl())
|
2013-02-21 23:10:22 +01:00
|
|
|
->setLabel(pht('Role'))
|
Revise administrative workflow for user creation
Summary:
- When an administrator creates a user, provide an option to send a welcome
email. Right now this workflow kind of dead-ends.
- Prevent administrators from changing the "System Agent" flag. If they can
change it, they can grab another user's certificate and then act as them. This
is a vaguely weaker security policy than is exhibited elsewhere in the
application. Instead, make user accounts immutably normal users or system agents
at creation time.
- Prevent administrators from changing email addresses after account creation.
Same deal as conduit certs. The 'bin/accountadmin' script can still do this if a
user has a real problem.
- Prevent administrators from resetting passwords. There's no need for this
anymore with welcome emails plus email login and it raises the same issues.
Test Plan:
- Created a new account, selected "send welcome email", got a welcome email,
logged in with the link inside it.
- Created a new system agent.
- Reset an account's password.
Reviewed By: aran
Reviewers: tuomaspelkonen, jungejason, aran
CC: anjali, aran, epriestley
Differential Revision: 379
2011-05-30 23:59:17 +02:00
|
|
|
->setName('role')
|
|
|
|
->setValue('user')
|
|
|
|
->setOptions(
|
|
|
|
array(
|
2013-02-21 23:10:22 +01:00
|
|
|
'user' => pht('Normal User'),
|
|
|
|
'agent' => pht('System Agent'),
|
Revise administrative workflow for user creation
Summary:
- When an administrator creates a user, provide an option to send a welcome
email. Right now this workflow kind of dead-ends.
- Prevent administrators from changing the "System Agent" flag. If they can
change it, they can grab another user's certificate and then act as them. This
is a vaguely weaker security policy than is exhibited elsewhere in the
application. Instead, make user accounts immutably normal users or system agents
at creation time.
- Prevent administrators from changing email addresses after account creation.
Same deal as conduit certs. The 'bin/accountadmin' script can still do this if a
user has a real problem.
- Prevent administrators from resetting passwords. There's no need for this
anymore with welcome emails plus email login and it raises the same issues.
Test Plan:
- Created a new account, selected "send welcome email", got a welcome email,
logged in with the link inside it.
- Created a new system agent.
- Reset an account's password.
Reviewed By: aran
Reviewers: tuomaspelkonen, jungejason, aran
CC: anjali, aran, epriestley
Differential Revision: 379
2011-05-30 23:59:17 +02:00
|
|
|
))
|
|
|
|
->setCaption(
|
2013-02-21 23:10:22 +01:00
|
|
|
pht('You can create a "system agent" account for bots, '.
|
|
|
|
'scripts, etc.')))
|
Revise administrative workflow for user creation
Summary:
- When an administrator creates a user, provide an option to send a welcome
email. Right now this workflow kind of dead-ends.
- Prevent administrators from changing the "System Agent" flag. If they can
change it, they can grab another user's certificate and then act as them. This
is a vaguely weaker security policy than is exhibited elsewhere in the
application. Instead, make user accounts immutably normal users or system agents
at creation time.
- Prevent administrators from changing email addresses after account creation.
Same deal as conduit certs. The 'bin/accountadmin' script can still do this if a
user has a real problem.
- Prevent administrators from resetting passwords. There's no need for this
anymore with welcome emails plus email login and it raises the same issues.
Test Plan:
- Created a new account, selected "send welcome email", got a welcome email,
logged in with the link inside it.
- Created a new system agent.
- Reset an account's password.
Reviewed By: aran
Reviewers: tuomaspelkonen, jungejason, aran
CC: anjali, aran, epriestley
Differential Revision: 379
2011-05-30 23:59:17 +02:00
|
|
|
->appendChild(
|
|
|
|
id(new AphrontFormCheckboxControl())
|
|
|
|
->addCheckbox(
|
|
|
|
'welcome',
|
|
|
|
1,
|
2013-02-21 23:10:22 +01:00
|
|
|
pht('Send "Welcome to Phabricator" email.'),
|
Revise administrative workflow for user creation
Summary:
- When an administrator creates a user, provide an option to send a welcome
email. Right now this workflow kind of dead-ends.
- Prevent administrators from changing the "System Agent" flag. If they can
change it, they can grab another user's certificate and then act as them. This
is a vaguely weaker security policy than is exhibited elsewhere in the
application. Instead, make user accounts immutably normal users or system agents
at creation time.
- Prevent administrators from changing email addresses after account creation.
Same deal as conduit certs. The 'bin/accountadmin' script can still do this if a
user has a real problem.
- Prevent administrators from resetting passwords. There's no need for this
anymore with welcome emails plus email login and it raises the same issues.
Test Plan:
- Created a new account, selected "send welcome email", got a welcome email,
logged in with the link inside it.
- Created a new system agent.
- Reset an account's password.
Reviewed By: aran
Reviewers: tuomaspelkonen, jungejason, aran
CC: anjali, aran, epriestley
Differential Revision: 379
2011-05-30 23:59:17 +02:00
|
|
|
$welcome_checked));
|
|
|
|
} else {
|
2012-05-07 19:25:36 +02:00
|
|
|
$roles = array();
|
|
|
|
|
|
|
|
if ($user->getIsSystemAgent()) {
|
2013-02-21 23:10:22 +01:00
|
|
|
$roles[] = pht('System Agent');
|
2012-05-07 19:25:36 +02:00
|
|
|
}
|
|
|
|
if ($user->getIsAdmin()) {
|
2013-02-21 23:10:22 +01:00
|
|
|
$roles[] = pht('Admin');
|
2012-05-07 19:25:36 +02:00
|
|
|
}
|
|
|
|
if ($user->getIsDisabled()) {
|
2013-02-21 23:10:22 +01:00
|
|
|
$roles[] = pht('Disabled');
|
2012-05-07 19:25:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!$roles) {
|
2013-02-21 23:10:22 +01:00
|
|
|
$roles[] = pht('Normal User');
|
2012-05-07 19:25:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
$roles = implode(', ', $roles);
|
|
|
|
|
Revise administrative workflow for user creation
Summary:
- When an administrator creates a user, provide an option to send a welcome
email. Right now this workflow kind of dead-ends.
- Prevent administrators from changing the "System Agent" flag. If they can
change it, they can grab another user's certificate and then act as them. This
is a vaguely weaker security policy than is exhibited elsewhere in the
application. Instead, make user accounts immutably normal users or system agents
at creation time.
- Prevent administrators from changing email addresses after account creation.
Same deal as conduit certs. The 'bin/accountadmin' script can still do this if a
user has a real problem.
- Prevent administrators from resetting passwords. There's no need for this
anymore with welcome emails plus email login and it raises the same issues.
Test Plan:
- Created a new account, selected "send welcome email", got a welcome email,
logged in with the link inside it.
- Created a new system agent.
- Reset an account's password.
Reviewed By: aran
Reviewers: tuomaspelkonen, jungejason, aran
CC: anjali, aran, epriestley
Differential Revision: 379
2011-05-30 23:59:17 +02:00
|
|
|
$form->appendChild(
|
|
|
|
id(new AphrontFormStaticControl())
|
2012-05-07 19:25:36 +02:00
|
|
|
->setLabel('Roles')
|
|
|
|
->setValue($roles));
|
Revise administrative workflow for user creation
Summary:
- When an administrator creates a user, provide an option to send a welcome
email. Right now this workflow kind of dead-ends.
- Prevent administrators from changing the "System Agent" flag. If they can
change it, they can grab another user's certificate and then act as them. This
is a vaguely weaker security policy than is exhibited elsewhere in the
application. Instead, make user accounts immutably normal users or system agents
at creation time.
- Prevent administrators from changing email addresses after account creation.
Same deal as conduit certs. The 'bin/accountadmin' script can still do this if a
user has a real problem.
- Prevent administrators from resetting passwords. There's no need for this
anymore with welcome emails plus email login and it raises the same issues.
Test Plan:
- Created a new account, selected "send welcome email", got a welcome email,
logged in with the link inside it.
- Created a new system agent.
- Reset an account's password.
Reviewed By: aran
Reviewers: tuomaspelkonen, jungejason, aran
CC: anjali, aran, epriestley
Differential Revision: 379
2011-05-30 23:59:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
$form
|
2011-01-24 03:09:16 +01:00
|
|
|
->appendChild(
|
|
|
|
id(new AphrontFormSubmitControl())
|
2013-02-21 23:10:22 +01:00
|
|
|
->setValue(pht('Save')));
|
2011-01-24 03:09:16 +01:00
|
|
|
|
|
|
|
$panel = new AphrontPanelView();
|
|
|
|
if ($user->getID()) {
|
2013-02-21 23:10:22 +01:00
|
|
|
$panel->setHeader(pht('Edit User'));
|
2011-01-24 03:09:16 +01:00
|
|
|
} else {
|
2013-02-21 23:10:22 +01:00
|
|
|
$panel->setHeader(pht('Create New User'));
|
2011-01-24 03:09:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
$panel->appendChild($form);
|
2013-02-21 23:10:22 +01:00
|
|
|
$panel->setNoBackground();
|
2011-01-24 03:09:16 +01:00
|
|
|
$panel->setWidth(AphrontPanelView::WIDTH_FORM);
|
|
|
|
|
2011-05-12 19:06:54 +02:00
|
|
|
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()) {
|
Provide an activity log for login and administrative actions
Summary: This isn't complete, but I figured I'd ship it for review while it's still smallish.
Provide an activity log for high-level system actions (logins, admin actions). This basically allows two things to happen:
- The log itself is useful if there are shenanigans.
- Password login can check it and start CAPTCHA'ing users after a few failed attempts.
I'm going to change how the admin stuff works a little bit too, since right now you can make someone an agent, grab their certificate, revert them back to a normal user, and then act on their behalf over Conduit. This is a little silly, I'm going to move "agent" to the create workflow instead. I'll also add a confirm/email step to the administrative password reset flow.
Test Plan: Took various administrative and non-administrative actions, they appeared in the logs. Filtered the logs in a bunch of different ways.
Reviewers: jungejason, tuomaspelkonen, aran
CC:
Differential Revision: 302
2011-05-18 03:42:21 +02:00
|
|
|
|
|
|
|
$log_template = PhabricatorUserLog::newLog(
|
|
|
|
$admin,
|
|
|
|
$user,
|
|
|
|
null);
|
|
|
|
|
|
|
|
$logs = array();
|
|
|
|
|
2011-05-12 19:06:54 +02:00
|
|
|
if ($is_self) {
|
2013-02-21 23:10:22 +01:00
|
|
|
$errors[] = pht("You can not edit your own role.");
|
2011-05-12 19:06:54 +02:00
|
|
|
} else {
|
Provide an activity log for login and administrative actions
Summary: This isn't complete, but I figured I'd ship it for review while it's still smallish.
Provide an activity log for high-level system actions (logins, admin actions). This basically allows two things to happen:
- The log itself is useful if there are shenanigans.
- Password login can check it and start CAPTCHA'ing users after a few failed attempts.
I'm going to change how the admin stuff works a little bit too, since right now you can make someone an agent, grab their certificate, revert them back to a normal user, and then act on their behalf over Conduit. This is a little silly, I'm going to move "agent" to the create workflow instead. I'll also add a confirm/email step to the administrative password reset flow.
Test Plan: Took various administrative and non-administrative actions, they appeared in the logs. Filtered the logs in a bunch of different ways.
Reviewers: jungejason, tuomaspelkonen, aran
CC:
Differential Revision: 302
2011-05-18 03:42:21 +02:00
|
|
|
$new_admin = (bool)$request->getBool('is_admin');
|
|
|
|
$old_admin = (bool)$user->getIsAdmin();
|
|
|
|
if ($new_admin != $old_admin) {
|
2012-05-25 16:30:44 +02:00
|
|
|
id(new PhabricatorUserEditor())
|
|
|
|
->setActor($admin)
|
|
|
|
->makeAdminUser($user, $new_admin);
|
Provide an activity log for login and administrative actions
Summary: This isn't complete, but I figured I'd ship it for review while it's still smallish.
Provide an activity log for high-level system actions (logins, admin actions). This basically allows two things to happen:
- The log itself is useful if there are shenanigans.
- Password login can check it and start CAPTCHA'ing users after a few failed attempts.
I'm going to change how the admin stuff works a little bit too, since right now you can make someone an agent, grab their certificate, revert them back to a normal user, and then act on their behalf over Conduit. This is a little silly, I'm going to move "agent" to the create workflow instead. I'll also add a confirm/email step to the administrative password reset flow.
Test Plan: Took various administrative and non-administrative actions, they appeared in the logs. Filtered the logs in a bunch of different ways.
Reviewers: jungejason, tuomaspelkonen, aran
CC:
Differential Revision: 302
2011-05-18 03:42:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
$new_disabled = (bool)$request->getBool('is_disabled');
|
|
|
|
$old_disabled = (bool)$user->getIsDisabled();
|
|
|
|
if ($new_disabled != $old_disabled) {
|
2012-05-25 16:30:44 +02:00
|
|
|
id(new PhabricatorUserEditor())
|
|
|
|
->setActor($admin)
|
|
|
|
->disableUser($user, $new_disabled);
|
Provide an activity log for login and administrative actions
Summary: This isn't complete, but I figured I'd ship it for review while it's still smallish.
Provide an activity log for high-level system actions (logins, admin actions). This basically allows two things to happen:
- The log itself is useful if there are shenanigans.
- Password login can check it and start CAPTCHA'ing users after a few failed attempts.
I'm going to change how the admin stuff works a little bit too, since right now you can make someone an agent, grab their certificate, revert them back to a normal user, and then act on their behalf over Conduit. This is a little silly, I'm going to move "agent" to the create workflow instead. I'll also add a confirm/email step to the administrative password reset flow.
Test Plan: Took various administrative and non-administrative actions, they appeared in the logs. Filtered the logs in a bunch of different ways.
Reviewers: jungejason, tuomaspelkonen, aran
CC:
Differential Revision: 302
2011-05-18 03:42:21 +02:00
|
|
|
}
|
2011-05-12 19:06:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!$errors) {
|
|
|
|
return id(new AphrontRedirectResponse())
|
|
|
|
->setURI($request->getRequestURI()->alter('saved', 'true'));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$error_view = null;
|
|
|
|
if ($errors) {
|
|
|
|
$error_view = id(new AphrontErrorView())
|
2013-02-21 23:10:22 +01:00
|
|
|
->setTitle(pht('Form Errors'))
|
2011-05-12 19:06:54 +02:00
|
|
|
->setErrors($errors);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$form = id(new AphrontFormView())
|
|
|
|
->setUser($admin)
|
|
|
|
->setAction($request->getRequestURI()->alter('saved', null));
|
|
|
|
|
|
|
|
if ($is_self) {
|
2013-02-21 23:10:22 +01:00
|
|
|
$inst = pht('NOTE: You can not edit your own role.');
|
2013-02-07 23:39:04 +01:00
|
|
|
$form->appendChild(hsprintf(
|
2013-02-21 23:10:22 +01:00
|
|
|
'<p class="aphront-form-instructions">%s</p>', $inst));
|
2011-05-12 19:06:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
$form
|
2012-04-09 00:10:00 +02:00
|
|
|
->appendChild($this->getRoleInstructions())
|
2011-05-12 19:06:54 +02:00
|
|
|
->appendChild(
|
|
|
|
id(new AphrontFormCheckboxControl())
|
|
|
|
->addCheckbox(
|
|
|
|
'is_admin',
|
|
|
|
1,
|
2013-02-21 23:10:22 +01:00
|
|
|
pht('Administrator'),
|
2011-05-12 19:06:54 +02:00
|
|
|
$user->getIsAdmin())
|
|
|
|
->setDisabled($is_self))
|
|
|
|
->appendChild(
|
|
|
|
id(new AphrontFormCheckboxControl())
|
|
|
|
->addCheckbox(
|
|
|
|
'is_disabled',
|
|
|
|
1,
|
2013-02-21 23:10:22 +01:00
|
|
|
pht('Disabled'),
|
2011-05-12 19:06:54 +02:00
|
|
|
$user->getIsDisabled())
|
2012-05-07 19:25:36 +02:00
|
|
|
->setDisabled($is_self))
|
|
|
|
->appendChild(
|
|
|
|
id(new AphrontFormCheckboxControl())
|
|
|
|
->addCheckbox(
|
|
|
|
'is_agent',
|
|
|
|
1,
|
2013-02-21 23:10:22 +01:00
|
|
|
pht('System Agent (Bot/Script User)'),
|
2012-05-07 19:25:36 +02:00
|
|
|
$user->getIsSystemAgent())
|
|
|
|
->setDisabled(true));
|
2011-05-12 19:06:54 +02:00
|
|
|
|
|
|
|
if (!$is_self) {
|
|
|
|
$form
|
|
|
|
->appendChild(
|
|
|
|
id(new AphrontFormSubmitControl())
|
2013-02-21 23:10:22 +01:00
|
|
|
->setValue(pht('Edit Role')));
|
2011-05-12 19:06:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
$panel = new AphrontPanelView();
|
2013-02-21 23:10:22 +01:00
|
|
|
$panel->setHeader(pht('Edit Role'));
|
2011-05-12 19:06:54 +02:00
|
|
|
$panel->setWidth(AphrontPanelView::WIDTH_FORM);
|
2013-02-21 23:10:22 +01:00
|
|
|
$panel->setNoBackground();
|
2011-05-12 19:06:54 +02:00
|
|
|
$panel->appendChild($form);
|
|
|
|
|
|
|
|
return array($error_view, $panel);
|
2011-01-24 03:09:16 +01:00
|
|
|
}
|
|
|
|
|
2011-05-17 22:15:19 +02:00
|
|
|
private function processCertificateRequest($user) {
|
|
|
|
$request = $this->getRequest();
|
|
|
|
$admin = $request->getUser();
|
|
|
|
|
2013-02-21 23:10:22 +01:00
|
|
|
$inst = pht('You can use this certificate '.
|
|
|
|
'to write scripts or bots which interface with Phabricator over '.
|
|
|
|
'Conduit.');
|
2011-05-17 22:15:19 +02:00
|
|
|
$form = new AphrontFormView();
|
|
|
|
$form
|
|
|
|
->setUser($admin)
|
|
|
|
->setAction($request->getRequestURI())
|
2013-02-07 23:39:04 +01:00
|
|
|
->appendChild(hsprintf(
|
2013-02-21 23:10:22 +01:00
|
|
|
'<p class="aphront-form-instructions">%s</p>', $inst));
|
2011-05-17 22:15:19 +02:00
|
|
|
|
|
|
|
if ($user->getIsSystemAgent()) {
|
|
|
|
$form
|
|
|
|
->appendChild(
|
|
|
|
id(new AphrontFormTextControl())
|
2013-02-21 23:10:22 +01:00
|
|
|
->setLabel(pht('Username'))
|
2011-05-17 22:15:19 +02:00
|
|
|
->setValue($user->getUsername()))
|
|
|
|
->appendChild(
|
|
|
|
id(new AphrontFormTextAreaControl())
|
2013-02-21 23:10:22 +01:00
|
|
|
->setLabel(pht('Certificate'))
|
2011-05-17 22:15:19 +02:00
|
|
|
->setValue($user->getConduitCertificate()));
|
|
|
|
} else {
|
|
|
|
$form->appendChild(
|
|
|
|
id(new AphrontFormStaticControl())
|
2013-02-21 23:10:22 +01:00
|
|
|
->setLabel(pht('Certificate'))
|
2011-05-17 22:15:19 +02:00
|
|
|
->setValue(
|
2013-02-21 23:10:22 +01:00
|
|
|
pht('You may only view the certificates of System Agents.')));
|
2011-05-17 22:15:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
$panel = new AphrontPanelView();
|
2013-02-21 23:10:22 +01:00
|
|
|
$panel->setHeader(pht('Conduit Certificate'));
|
2011-05-17 22:15:19 +02:00
|
|
|
$panel->setWidth(AphrontPanelView::WIDTH_FORM);
|
2013-02-21 23:10:22 +01:00
|
|
|
$panel->setNoBackground();
|
2011-05-17 22:15:19 +02:00
|
|
|
$panel->appendChild($form);
|
|
|
|
|
|
|
|
return array($panel);
|
|
|
|
}
|
|
|
|
|
2012-06-06 16:09:56 +02:00
|
|
|
private function processRenameRequest(PhabricatorUser $user) {
|
|
|
|
$request = $this->getRequest();
|
|
|
|
$admin = $request->getUser();
|
|
|
|
|
|
|
|
$e_username = true;
|
|
|
|
$username = $user->getUsername();
|
|
|
|
|
|
|
|
$errors = array();
|
|
|
|
if ($request->isFormPost()) {
|
|
|
|
|
|
|
|
$username = $request->getStr('username');
|
|
|
|
if (!strlen($username)) {
|
2013-02-21 23:10:22 +01:00
|
|
|
$e_username = pht('Required');
|
|
|
|
$errors[] = pht('New username is required.');
|
2012-06-06 16:09:56 +02:00
|
|
|
} else if ($username == $user->getUsername()) {
|
2013-02-21 23:10:22 +01:00
|
|
|
$e_username = pht('Invalid');
|
|
|
|
$errors[] = pht('New username must be different from old username.');
|
2012-06-06 16:09:56 +02:00
|
|
|
} else if (!PhabricatorUser::validateUsername($username)) {
|
2013-02-21 23:10:22 +01:00
|
|
|
$e_username = pht('Invalid');
|
2012-06-06 16:09:56 +02:00
|
|
|
$errors[] = PhabricatorUser::describeValidUsername();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!$errors) {
|
|
|
|
try {
|
|
|
|
|
|
|
|
id(new PhabricatorUserEditor())
|
|
|
|
->setActor($admin)
|
|
|
|
->changeUsername($user, $username);
|
|
|
|
|
|
|
|
return id(new AphrontRedirectResponse())
|
|
|
|
->setURI($request->getRequestURI()->alter('saved', true));
|
|
|
|
} catch (AphrontQueryDuplicateKeyException $ex) {
|
2013-02-21 23:10:22 +01:00
|
|
|
$e_username = pht('Not Unique');
|
|
|
|
$errors[] = pht('Another user already has that username.');
|
2012-06-06 16:09:56 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($errors) {
|
|
|
|
$errors = id(new AphrontErrorView())
|
2013-02-21 23:10:22 +01:00
|
|
|
->setTitle(pht('Form Errors'))
|
2012-06-06 16:09:56 +02:00
|
|
|
->setErrors($errors);
|
|
|
|
} else {
|
|
|
|
$errors = null;
|
|
|
|
}
|
|
|
|
|
2013-02-21 23:10:22 +01:00
|
|
|
$inst1 = pht('Be careful when renaming users!');
|
|
|
|
$inst2 = pht('The old username will no longer be tied to the user, so '.
|
|
|
|
'anything which uses it (like old commit messages) will no longer '.
|
|
|
|
'associate correctly. And if you give a user a username which some '.
|
|
|
|
'other user used to have, username lookups will begin returning '.
|
|
|
|
'the wrong user.');
|
|
|
|
$inst3 = pht('It is generally safe to rename newly created users (and '.
|
|
|
|
'test users and so on), but less safe to rename established users '.
|
|
|
|
'and unsafe to reissue a username.');
|
|
|
|
$inst4 = pht('Users who rely on password auth will need to reset their '.
|
|
|
|
'passwordafter their username is changed (their username is part '.
|
|
|
|
'of the salt in the password hash). They will receive an email '.
|
|
|
|
'with instructions on how to do this.');
|
|
|
|
|
2012-06-06 16:09:56 +02:00
|
|
|
$form = new AphrontFormView();
|
|
|
|
$form
|
|
|
|
->setUser($admin)
|
|
|
|
->setAction($request->getRequestURI())
|
2013-02-07 23:39:04 +01:00
|
|
|
->appendChild(hsprintf(
|
2012-06-06 16:09:56 +02:00
|
|
|
'<p class="aphront-form-instructions">'.
|
2013-02-21 23:10:22 +01:00
|
|
|
'<strong>%s</strong> '.
|
|
|
|
'%s'.
|
2012-06-06 16:09:56 +02:00
|
|
|
'</p>'.
|
|
|
|
'<p class="aphront-form-instructions">'.
|
2013-02-21 23:10:22 +01:00
|
|
|
'%s'.
|
2012-06-06 16:09:56 +02:00
|
|
|
'</p>'.
|
|
|
|
'<p class="aphront-form-instructions">'.
|
2013-02-21 23:10:22 +01:00
|
|
|
'%s'.
|
|
|
|
'</p>', $inst1, $inst2, $inst3, $inst4))
|
2012-06-06 16:09:56 +02:00
|
|
|
->appendChild(
|
|
|
|
id(new AphrontFormStaticControl())
|
2013-02-21 23:10:22 +01:00
|
|
|
->setLabel(pht('Old Username'))
|
2012-06-06 16:09:56 +02:00
|
|
|
->setValue($user->getUsername()))
|
|
|
|
->appendChild(
|
|
|
|
id(new AphrontFormTextControl())
|
2013-02-21 23:10:22 +01:00
|
|
|
->setLabel(pht('New Username'))
|
2012-06-06 16:09:56 +02:00
|
|
|
->setValue($username)
|
|
|
|
->setName('username')
|
|
|
|
->setError($e_username))
|
|
|
|
->appendChild(
|
|
|
|
id(new AphrontFormSubmitControl())
|
2013-02-21 23:10:22 +01:00
|
|
|
->setValue(pht('Change Username')));
|
2012-06-06 16:09:56 +02:00
|
|
|
|
|
|
|
$panel = new AphrontPanelView();
|
2013-02-21 23:10:22 +01:00
|
|
|
$panel->setHeader(pht('Change Username'));
|
2012-06-06 16:09:56 +02:00
|
|
|
$panel->setWidth(AphrontPanelView::WIDTH_FORM);
|
2013-02-21 23:10:22 +01:00
|
|
|
$panel->setNoBackground();
|
2012-06-06 16:09:56 +02:00
|
|
|
$panel->appendChild($form);
|
|
|
|
|
|
|
|
return array($errors, $panel);
|
|
|
|
}
|
|
|
|
|
2012-06-16 02:02:20 +02:00
|
|
|
private function processDeleteRequest(PhabricatorUser $user) {
|
|
|
|
$request = $this->getRequest();
|
|
|
|
$admin = $request->getUser();
|
|
|
|
|
2013-02-21 23:10:22 +01:00
|
|
|
$far1 = pht('As you stare into the gaping maw of the abyss, something '.
|
|
|
|
'hold you back.');
|
|
|
|
$far2 = pht('You can not delete your own account.');
|
|
|
|
|
2012-06-16 02:02:20 +02:00
|
|
|
if ($user->getPHID() == $admin->getPHID()) {
|
|
|
|
$error = new AphrontErrorView();
|
2013-02-21 23:10:22 +01:00
|
|
|
$error->setTitle(pht('You Shall Journey No Farther'));
|
2013-02-07 01:53:49 +01:00
|
|
|
$error->appendChild(hsprintf(
|
2013-02-21 23:10:22 +01:00
|
|
|
'<p>%s</p><p>%s</p>', $far1, $far2));
|
2012-06-16 02:02:20 +02:00
|
|
|
return $error;
|
|
|
|
}
|
|
|
|
|
|
|
|
$e_username = true;
|
|
|
|
$username = null;
|
2012-06-06 16:09:56 +02:00
|
|
|
|
2012-06-16 02:02:20 +02:00
|
|
|
$errors = array();
|
|
|
|
if ($request->isFormPost()) {
|
|
|
|
|
|
|
|
$username = $request->getStr('username');
|
|
|
|
if (!strlen($username)) {
|
2013-02-21 23:10:22 +01:00
|
|
|
$e_username = pht('Required');
|
|
|
|
$errors[] = pht('You must type the username to confirm deletion.');
|
2012-06-16 02:02:20 +02:00
|
|
|
} else if ($username != $user->getUsername()) {
|
2013-02-21 23:10:22 +01:00
|
|
|
$e_username = pht('Invalid');
|
|
|
|
$errors[] = pht('You must type the username correctly.');
|
2012-06-16 02:02:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!$errors) {
|
|
|
|
id(new PhabricatorUserEditor())
|
|
|
|
->setActor($admin)
|
|
|
|
->deleteUser($user);
|
|
|
|
|
|
|
|
return id(new AphrontRedirectResponse())->setURI('/people/');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($errors) {
|
|
|
|
$errors = id(new AphrontErrorView())
|
2013-02-21 23:10:22 +01:00
|
|
|
->setTitle(pht('Form Errors'))
|
2012-06-16 02:02:20 +02:00
|
|
|
->setErrors($errors);
|
|
|
|
} else {
|
|
|
|
$errors = null;
|
|
|
|
}
|
|
|
|
|
2013-02-21 23:10:22 +01:00
|
|
|
$str1 = pht('Be careful when deleting users!');
|
|
|
|
$str2 = pht('If this user interacted with anything, it is generally '.
|
|
|
|
'better to disable them, not delete them. If you delete them, it will '.
|
|
|
|
'no longer be possible to search for their objects, for example, '.
|
|
|
|
'and you will lose other information about their history. Disabling '.
|
|
|
|
'them instead will prevent them from logging in but not destroy '.
|
|
|
|
'any of their data.');
|
|
|
|
$str3 = pht('It is generally safe to delete newly created users (and '.
|
|
|
|
'test users and so on), but less safe to delete established users. '.
|
|
|
|
'If possible, disable them instead.');
|
|
|
|
|
2012-06-16 02:02:20 +02:00
|
|
|
$form = new AphrontFormView();
|
|
|
|
$form
|
|
|
|
->setUser($admin)
|
|
|
|
->setAction($request->getRequestURI())
|
2013-02-07 23:39:04 +01:00
|
|
|
->appendChild(hsprintf(
|
2012-06-16 02:02:20 +02:00
|
|
|
'<p class="aphront-form-instructions">'.
|
2013-02-21 23:10:22 +01:00
|
|
|
'<strong>%s</strong> %s'.
|
2012-06-16 02:02:20 +02:00
|
|
|
'</p>'.
|
|
|
|
'<p class="aphront-form-instructions">'.
|
2013-02-21 23:10:22 +01:00
|
|
|
'%s'.
|
|
|
|
'</p>', $str1, $str2, $str3))
|
2012-06-16 02:02:20 +02:00
|
|
|
->appendChild(
|
|
|
|
id(new AphrontFormStaticControl())
|
2013-02-21 23:10:22 +01:00
|
|
|
->setLabel(pht('Username'))
|
2012-06-16 02:02:20 +02:00
|
|
|
->setValue($user->getUsername()))
|
|
|
|
->appendChild(
|
|
|
|
id(new AphrontFormTextControl())
|
2013-02-21 23:10:22 +01:00
|
|
|
->setLabel(pht('Confirm'))
|
2012-06-16 02:02:20 +02:00
|
|
|
->setValue($username)
|
|
|
|
->setName('username')
|
2013-02-21 23:10:22 +01:00
|
|
|
->setCaption(pht("Type the username again to confirm deletion."))
|
2012-06-16 02:02:20 +02:00
|
|
|
->setError($e_username))
|
|
|
|
->appendChild(
|
|
|
|
id(new AphrontFormSubmitControl())
|
2013-02-21 23:10:22 +01:00
|
|
|
->setValue(pht('Delete User')));
|
2012-06-16 02:02:20 +02:00
|
|
|
|
|
|
|
$panel = new AphrontPanelView();
|
2013-02-21 23:10:22 +01:00
|
|
|
$panel->setHeader(pht('Delete User'));
|
2012-06-16 02:02:20 +02:00
|
|
|
$panel->setWidth(AphrontPanelView::WIDTH_FORM);
|
2013-02-21 23:10:22 +01:00
|
|
|
$panel->setNoBackground();
|
2012-06-16 02:02:20 +02:00
|
|
|
$panel->appendChild($form);
|
|
|
|
|
|
|
|
return array($errors, $panel);
|
|
|
|
}
|
2012-06-06 16:09:56 +02:00
|
|
|
|
2012-04-09 00:10:00 +02:00
|
|
|
private function getRoleInstructions() {
|
2013-01-18 03:57:09 +01:00
|
|
|
$roles_link = phutil_tag(
|
2012-04-09 00:10:00 +02:00
|
|
|
'a',
|
|
|
|
array(
|
|
|
|
'href' => PhabricatorEnv::getDoclink(
|
2012-04-10 19:15:40 +02:00
|
|
|
'article/User_Guide_Account_Roles.html'),
|
2012-04-09 00:10:00 +02:00
|
|
|
'target' => '_blank',
|
|
|
|
),
|
2013-02-21 23:10:22 +01:00
|
|
|
pht('User Guide: Account Roles'));
|
2012-04-09 00:10:00 +02:00
|
|
|
|
2013-02-21 23:10:22 +01:00
|
|
|
$inst = pht('For a detailed explanation of account roles, see %s.',
|
2013-02-07 23:39:04 +01:00
|
|
|
$roles_link);
|
2013-02-21 23:10:22 +01:00
|
|
|
return hsprintf(
|
|
|
|
'<p class="aphront-form-instructions">%s</p>',
|
|
|
|
$inst);
|
2012-04-09 00:10:00 +02:00
|
|
|
}
|
|
|
|
|
2013-03-08 17:31:25 +01:00
|
|
|
private function processSetAccountPicture(PhabricatorUser $user) {
|
|
|
|
$request = $this->getRequest();
|
|
|
|
$admin = $request->getUser();
|
|
|
|
|
|
|
|
$profile = id(new PhabricatorUserProfile())->loadOneWhere(
|
|
|
|
'userPHID = %s',
|
|
|
|
$user->getPHID());
|
|
|
|
if (!$profile) {
|
|
|
|
$profile = new PhabricatorUserProfile();
|
|
|
|
$profile->setUserPHID($user->getPHID());
|
|
|
|
$profile->setTitle('');
|
|
|
|
$profile->setBlurb('');
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$supported_formats = PhabricatorFile::getTransformableImageFormats();
|
|
|
|
|
|
|
|
$e_image = null;
|
|
|
|
$errors = array();
|
|
|
|
|
|
|
|
if ($request->isFormPost()) {
|
|
|
|
$default_image = $request->getExists('default_image');
|
|
|
|
|
|
|
|
if ($default_image) {
|
|
|
|
$profile->setProfileImagePHID(null);
|
|
|
|
$user->setProfileImagePHID(null);
|
|
|
|
} else if ($request->getFileExists('image')) {
|
|
|
|
$file = null;
|
|
|
|
$file = PhabricatorFile::newFromPHPUpload(
|
|
|
|
$_FILES['image'],
|
|
|
|
array(
|
|
|
|
'authorPHID' => $admin->getPHID(),
|
|
|
|
));
|
|
|
|
|
|
|
|
$okay = $file->isTransformableImage();
|
|
|
|
|
|
|
|
if ($okay) {
|
|
|
|
$xformer = new PhabricatorImageTransformer();
|
|
|
|
|
|
|
|
// Generate the large picture for the profile page.
|
|
|
|
$large_xformed = $xformer->executeProfileTransform(
|
|
|
|
$file,
|
|
|
|
$width = 280,
|
|
|
|
$min_height = 140,
|
|
|
|
$max_height = 420);
|
|
|
|
$profile->setProfileImagePHID($large_xformed->getPHID());
|
|
|
|
|
|
|
|
// Generate the small picture for comments, etc.
|
|
|
|
$small_xformed = $xformer->executeProfileTransform(
|
|
|
|
$file,
|
|
|
|
$width = 50,
|
|
|
|
$min_height = 50,
|
|
|
|
$max_height = 50);
|
|
|
|
$user->setProfileImagePHID($small_xformed->getPHID());
|
|
|
|
} else {
|
|
|
|
$e_image = pht('Not Supported');
|
|
|
|
$errors[] =
|
|
|
|
pht('This server only supports these image formats:').
|
|
|
|
' ' .implode(', ', $supported_formats);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!$errors) {
|
|
|
|
$user->save();
|
|
|
|
$profile->save();
|
|
|
|
$response = id(new AphrontRedirectResponse())
|
|
|
|
->setURI('/people/edit/'.$user->getID().'/picture/');
|
|
|
|
return $response;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$error_view = null;
|
|
|
|
if ($errors) {
|
|
|
|
$error_view = new AphrontErrorView();
|
|
|
|
$error_view->setTitle(pht('Form Errors'));
|
|
|
|
$error_view->setErrors($errors);
|
|
|
|
} else {
|
|
|
|
if ($request->getStr('saved')) {
|
|
|
|
$error_view = new AphrontErrorView();
|
|
|
|
$error_view->setSeverity(AphrontErrorView::SEVERITY_NOTICE);
|
|
|
|
$error_view->setTitle(pht('Changes Saved'));
|
|
|
|
$error_view->appendChild(
|
|
|
|
phutil_tag('p', array(), pht('Your changes have been saved.')));
|
|
|
|
$error_view = $error_view->render();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$img_src = $user->loadProfileImageURI();
|
|
|
|
|
|
|
|
$form = new AphrontFormView();
|
|
|
|
$form
|
|
|
|
->setUser($admin)
|
|
|
|
->setAction($request->getRequestURI())
|
|
|
|
->setEncType('multipart/form-data')
|
|
|
|
->appendChild(
|
|
|
|
id(new AphrontFormMarkupControl())
|
|
|
|
->setLabel(pht('Profile Image'))
|
|
|
|
->setValue(
|
|
|
|
phutil_tag(
|
|
|
|
'img',
|
|
|
|
array(
|
|
|
|
'src' => $img_src,
|
|
|
|
))))
|
|
|
|
->appendChild(
|
|
|
|
id(new AphrontFormImageControl())
|
|
|
|
->setLabel(pht('Change Image'))
|
|
|
|
->setName('image')
|
|
|
|
->setError($e_image)
|
|
|
|
->setCaption(
|
|
|
|
pht('Supported formats: %s', implode(', ', $supported_formats))));
|
|
|
|
|
|
|
|
$form->appendChild(
|
|
|
|
id(new AphrontFormSubmitControl())
|
|
|
|
->setValue(pht('Save'))
|
|
|
|
->addCancelButton('/people/edit/'.$user->getID().'/'));
|
|
|
|
|
|
|
|
$panel = new AphrontPanelView();
|
|
|
|
$panel->setHeader(pht('Set Profile Picture'));
|
|
|
|
$panel->setWidth(AphrontPanelView::WIDTH_FORM);
|
|
|
|
$panel->setNoBackground();
|
|
|
|
$panel->appendChild($form);
|
|
|
|
|
|
|
|
return array($error_view, $panel);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2011-01-24 03:09:16 +01:00
|
|
|
}
|