2011-04-03 22:03:27 -07:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
/*
|
2012-01-10 11:21:49 -08:00
|
|
|
* Copyright 2012 Facebook, Inc.
|
2011-04-03 22:03:27 -07:00
|
|
|
*
|
|
|
|
|
* 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.
|
|
|
|
|
*/
|
|
|
|
|
|
2012-03-09 15:46:25 -08:00
|
|
|
final class PhabricatorOwnersEditController
|
|
|
|
|
extends PhabricatorOwnersController {
|
2011-04-03 22:03:27 -07:00
|
|
|
|
|
|
|
|
private $id;
|
|
|
|
|
|
|
|
|
|
public function willProcessRequest(array $data) {
|
|
|
|
|
$this->id = idx($data, 'id');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function processRequest() {
|
|
|
|
|
$request = $this->getRequest();
|
|
|
|
|
$user = $request->getUser();
|
|
|
|
|
|
|
|
|
|
if ($this->id) {
|
|
|
|
|
$package = id(new PhabricatorOwnersPackage())->load($this->id);
|
|
|
|
|
if (!$package) {
|
|
|
|
|
return new Aphront404Response();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
$package = new PhabricatorOwnersPackage();
|
|
|
|
|
$package->setPrimaryOwnerPHID($user->getPHID());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$e_name = true;
|
|
|
|
|
$e_primary = true;
|
|
|
|
|
|
|
|
|
|
$errors = array();
|
|
|
|
|
|
|
|
|
|
if ($request->isFormPost()) {
|
|
|
|
|
$package->setName($request->getStr('name'));
|
|
|
|
|
$package->setDescription($request->getStr('description'));
|
Detect package change and send out email
Summary:
For package creation and deletion, send email to all the owners For
package modification, detect important fields such as owners and paths, and then
send out emails to all owners (including deleted owners and current owners)
Also start using transaction for package creation/deletion/modification.
Test Plan:
- tested mail creation and deletion
- tested modification to auditing enabled, primary owners, owners, paths
Reviewers: epriestley, nh, vrana
Reviewed By: epriestley
CC: prithvi, aran, Koolvin
Differential Revision: https://secure.phabricator.com/D2470
2012-05-07 00:19:44 -07:00
|
|
|
$old_auditing_enabled = $package->getAuditingEnabled();
|
Add Basic Auditing Functionalities
Summary:
add basic auditing functionalities. For the related commits for a
package, we detect the following conditions which might be suspicious to the
owners of the package:
* no revision specified
* revision not found
* author not match
* reviewedby not match
* owners not involved
* commit author not recognized
The owners of the package can change the status of the audit entries by
accepting it or specify concern.
The owner can turn on/off the auditing for a package.
Test Plan:
* verified that non-owner cannot see the details of the audit and cannot modify
it
* verified that all the audit reasons can be detected
* tested dropdown filtering and package search
* verified really normal change not detected
* verified accept/concern a commit
* tested enable/disable a package for auditing
* verified one audit applies to all <commit, packages> to the packages the
auditor owns
* verified that re-parsing a commit won't have effect if there exists a
relationship for <commit, package> already
Reviewers: epriestley, nh
Reviewed By: epriestley
CC: aran, benmathews, btrahan, mpodobnik, prithvi, TomL, epriestley
Differential Revision: 1242
2011-12-17 15:52:54 -08:00
|
|
|
$package->setAuditingEnabled($request->getStr('auditing') === 'enabled');
|
2011-04-03 22:03:27 -07:00
|
|
|
|
|
|
|
|
$primary = $request->getArr('primary');
|
|
|
|
|
$primary = reset($primary);
|
Detect package change and send out email
Summary:
For package creation and deletion, send email to all the owners For
package modification, detect important fields such as owners and paths, and then
send out emails to all owners (including deleted owners and current owners)
Also start using transaction for package creation/deletion/modification.
Test Plan:
- tested mail creation and deletion
- tested modification to auditing enabled, primary owners, owners, paths
Reviewers: epriestley, nh, vrana
Reviewed By: epriestley
CC: prithvi, aran, Koolvin
Differential Revision: https://secure.phabricator.com/D2470
2012-05-07 00:19:44 -07:00
|
|
|
$old_primary = $package->getPrimaryOwnerPHID();
|
2011-04-03 22:03:27 -07:00
|
|
|
$package->setPrimaryOwnerPHID($primary);
|
|
|
|
|
|
|
|
|
|
$owners = $request->getArr('owners');
|
|
|
|
|
if ($primary) {
|
|
|
|
|
array_unshift($owners, $primary);
|
|
|
|
|
}
|
|
|
|
|
$owners = array_unique($owners);
|
|
|
|
|
|
|
|
|
|
$paths = $request->getArr('path');
|
|
|
|
|
$repos = $request->getArr('repo');
|
|
|
|
|
|
|
|
|
|
$path_refs = array();
|
|
|
|
|
for ($ii = 0; $ii < count($paths); $ii++) {
|
|
|
|
|
if (empty($paths[$ii]) || empty($repos[$ii])) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
$path_refs[] = array(
|
|
|
|
|
'repositoryPHID' => $repos[$ii],
|
|
|
|
|
'path' => $paths[$ii],
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!strlen($package->getName())) {
|
|
|
|
|
$e_name = 'Required';
|
|
|
|
|
$errors[] = 'Package name is required.';
|
|
|
|
|
} else {
|
|
|
|
|
$e_name = null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!$package->getPrimaryOwnerPHID()) {
|
|
|
|
|
$e_primary = 'Required';
|
|
|
|
|
$errors[] = 'Package must have a primary owner.';
|
|
|
|
|
} else {
|
|
|
|
|
$e_primary = null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!$path_refs) {
|
|
|
|
|
$errors[] = 'Package must include at least one path.';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!$errors) {
|
|
|
|
|
$package->attachUnsavedOwners($owners);
|
|
|
|
|
$package->attachUnsavedPaths($path_refs);
|
Detect package change and send out email
Summary:
For package creation and deletion, send email to all the owners For
package modification, detect important fields such as owners and paths, and then
send out emails to all owners (including deleted owners and current owners)
Also start using transaction for package creation/deletion/modification.
Test Plan:
- tested mail creation and deletion
- tested modification to auditing enabled, primary owners, owners, paths
Reviewers: epriestley, nh, vrana
Reviewed By: epriestley
CC: prithvi, aran, Koolvin
Differential Revision: https://secure.phabricator.com/D2470
2012-05-07 00:19:44 -07:00
|
|
|
$package->attachOldAuditingEnabled($old_auditing_enabled);
|
|
|
|
|
$package->attachOldPrimaryOwnerPHID($old_primary);
|
|
|
|
|
$package->attachActorPHID($user->getPHID());
|
2011-04-03 22:03:27 -07:00
|
|
|
try {
|
|
|
|
|
$package->save();
|
|
|
|
|
return id(new AphrontRedirectResponse())
|
|
|
|
|
->setURI('/owners/package/'.$package->getID().'/');
|
|
|
|
|
} catch (AphrontQueryDuplicateKeyException $ex) {
|
|
|
|
|
$e_name = 'Duplicate';
|
|
|
|
|
$errors[] = 'Package name must be unique.';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
$owners = $package->loadOwners();
|
|
|
|
|
$owners = mpull($owners, 'getUserPHID');
|
|
|
|
|
|
|
|
|
|
$paths = $package->loadPaths();
|
|
|
|
|
$path_refs = array();
|
|
|
|
|
foreach ($paths as $path) {
|
|
|
|
|
$path_refs[] = array(
|
|
|
|
|
'repositoryPHID' => $path->getRepositoryPHID(),
|
|
|
|
|
'path' => $path->getPath(),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$error_view = null;
|
|
|
|
|
if ($errors) {
|
|
|
|
|
$error_view = new AphrontErrorView();
|
|
|
|
|
$error_view->setTitle('Package Errors');
|
|
|
|
|
$error_view->setErrors($errors);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$handles = id(new PhabricatorObjectHandleData($owners))
|
|
|
|
|
->loadHandles();
|
|
|
|
|
|
|
|
|
|
$primary = $package->getPrimaryOwnerPHID();
|
|
|
|
|
if ($primary && isset($handles[$primary])) {
|
|
|
|
|
$token_primary_owner = array(
|
|
|
|
|
$primary => $handles[$primary]->getFullName(),
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
$token_primary_owner = array();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$token_all_owners = array_select_keys($handles, $owners);
|
|
|
|
|
$token_all_owners = mpull($token_all_owners, 'getFullName');
|
|
|
|
|
|
2012-01-10 11:21:49 -08:00
|
|
|
if ($package->getID()) {
|
|
|
|
|
$title = 'Edit Package';
|
|
|
|
|
$side_nav_filter = 'edit/'.$this->id;
|
|
|
|
|
} else {
|
|
|
|
|
$title = 'New Package';
|
|
|
|
|
$side_nav_filter = 'new';
|
|
|
|
|
}
|
|
|
|
|
$this->setSideNavFilter($side_nav_filter);
|
2011-04-03 22:03:27 -07:00
|
|
|
|
|
|
|
|
$repos = id(new PhabricatorRepository())->loadAll();
|
|
|
|
|
|
|
|
|
|
$default_paths = array();
|
|
|
|
|
foreach ($repos as $repo) {
|
|
|
|
|
$default_path = $repo->getDetail('default-owners-path');
|
|
|
|
|
if ($default_path) {
|
|
|
|
|
$default_paths[$repo->getPHID()] = $default_path;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$repos = mpull($repos, 'getCallsign', 'getPHID');
|
|
|
|
|
|
|
|
|
|
$template = new AphrontTypeaheadTemplateView();
|
|
|
|
|
$template = $template->render();
|
|
|
|
|
|
|
|
|
|
Javelin::initBehavior(
|
|
|
|
|
'owners-path-editor',
|
|
|
|
|
array(
|
|
|
|
|
'root' => 'path-editor',
|
|
|
|
|
'table' => 'paths',
|
|
|
|
|
'add_button' => 'addpath',
|
|
|
|
|
'repositories' => $repos,
|
|
|
|
|
'input_template' => $template,
|
|
|
|
|
'pathRefs' => $path_refs,
|
|
|
|
|
|
|
|
|
|
'completeURI' => '/diffusion/services/path/complete/',
|
|
|
|
|
'validateURI' => '/diffusion/services/path/validate/',
|
|
|
|
|
|
|
|
|
|
'repositoryDefaultPaths' => $default_paths,
|
|
|
|
|
));
|
|
|
|
|
|
|
|
|
|
require_celerity_resource('owners-path-editor-css');
|
|
|
|
|
|
|
|
|
|
$cancel_uri = $package->getID()
|
|
|
|
|
? '/owners/package/'.$package->getID().'/'
|
|
|
|
|
: '/owners/';
|
|
|
|
|
|
|
|
|
|
$form = id(new AphrontFormView())
|
|
|
|
|
->setUser($user)
|
|
|
|
|
->appendChild(
|
|
|
|
|
id(new AphrontFormTextControl())
|
|
|
|
|
->setLabel('Name')
|
|
|
|
|
->setName('name')
|
|
|
|
|
->setValue($package->getName())
|
|
|
|
|
->setError($e_name))
|
|
|
|
|
->appendChild(
|
|
|
|
|
id(new AphrontFormTokenizerControl())
|
2012-03-30 15:46:32 -07:00
|
|
|
->setDatasource('/typeahead/common/usersorprojects/')
|
2011-04-03 22:03:27 -07:00
|
|
|
->setLabel('Primary Owner')
|
|
|
|
|
->setName('primary')
|
|
|
|
|
->setLimit(1)
|
|
|
|
|
->setValue($token_primary_owner)
|
|
|
|
|
->setError($e_primary))
|
|
|
|
|
->appendChild(
|
|
|
|
|
id(new AphrontFormTokenizerControl())
|
2012-03-30 15:46:32 -07:00
|
|
|
->setDatasource('/typeahead/common/usersorprojects/')
|
2011-04-03 22:03:27 -07:00
|
|
|
->setLabel('Owners')
|
|
|
|
|
->setName('owners')
|
2012-04-10 17:14:53 -07:00
|
|
|
->setValue($token_all_owners))
|
Add Basic Auditing Functionalities
Summary:
add basic auditing functionalities. For the related commits for a
package, we detect the following conditions which might be suspicious to the
owners of the package:
* no revision specified
* revision not found
* author not match
* reviewedby not match
* owners not involved
* commit author not recognized
The owners of the package can change the status of the audit entries by
accepting it or specify concern.
The owner can turn on/off the auditing for a package.
Test Plan:
* verified that non-owner cannot see the details of the audit and cannot modify
it
* verified that all the audit reasons can be detected
* tested dropdown filtering and package search
* verified really normal change not detected
* verified accept/concern a commit
* tested enable/disable a package for auditing
* verified one audit applies to all <commit, packages> to the packages the
auditor owns
* verified that re-parsing a commit won't have effect if there exists a
relationship for <commit, package> already
Reviewers: epriestley, nh
Reviewed By: epriestley
CC: aran, benmathews, btrahan, mpodobnik, prithvi, TomL, epriestley
Differential Revision: 1242
2011-12-17 15:52:54 -08:00
|
|
|
->appendChild(
|
|
|
|
|
id(new AphrontFormSelectControl())
|
|
|
|
|
->setName('auditing')
|
|
|
|
|
->setLabel('Auditing')
|
2012-02-10 10:14:12 -08:00
|
|
|
->setCaption('With auditing enabled, all future commits that touch '.
|
|
|
|
|
'this package will be reviewed to make sure an owner '.
|
|
|
|
|
'of the package is involved and the commit message has '.
|
|
|
|
|
'a valid revision, reviewed by, and author.')
|
Add Basic Auditing Functionalities
Summary:
add basic auditing functionalities. For the related commits for a
package, we detect the following conditions which might be suspicious to the
owners of the package:
* no revision specified
* revision not found
* author not match
* reviewedby not match
* owners not involved
* commit author not recognized
The owners of the package can change the status of the audit entries by
accepting it or specify concern.
The owner can turn on/off the auditing for a package.
Test Plan:
* verified that non-owner cannot see the details of the audit and cannot modify
it
* verified that all the audit reasons can be detected
* tested dropdown filtering and package search
* verified really normal change not detected
* verified accept/concern a commit
* tested enable/disable a package for auditing
* verified one audit applies to all <commit, packages> to the packages the
auditor owns
* verified that re-parsing a commit won't have effect if there exists a
relationship for <commit, package> already
Reviewers: epriestley, nh
Reviewed By: epriestley
CC: aran, benmathews, btrahan, mpodobnik, prithvi, TomL, epriestley
Differential Revision: 1242
2011-12-17 15:52:54 -08:00
|
|
|
->setOptions(array(
|
|
|
|
|
'disabled' => 'Disabled',
|
|
|
|
|
'enabled' => 'Enabled',
|
|
|
|
|
))
|
|
|
|
|
->setValue(
|
|
|
|
|
$package->getAuditingEnabled()
|
|
|
|
|
? 'enabled'
|
|
|
|
|
: 'disabled'))
|
2011-04-03 22:03:27 -07:00
|
|
|
->appendChild(
|
2012-03-15 17:10:19 -07:00
|
|
|
id(new AphrontFormInsetView())
|
|
|
|
|
->setTitle('Paths')
|
|
|
|
|
->addDivAttributes(array('id' => 'path-editor'))
|
|
|
|
|
->setRightButton(javelin_render_tag(
|
2011-04-03 22:03:27 -07:00
|
|
|
'a',
|
|
|
|
|
array(
|
|
|
|
|
'href' => '#',
|
|
|
|
|
'class' => 'button green',
|
|
|
|
|
'sigil' => 'addpath',
|
|
|
|
|
'mustcapture' => true,
|
|
|
|
|
),
|
2012-03-15 17:10:19 -07:00
|
|
|
'Add New Path'))
|
|
|
|
|
->setDescription('Specify the files and directories which comprise '.
|
|
|
|
|
'this package.')
|
|
|
|
|
->setContent(javelin_render_tag(
|
|
|
|
|
'table',
|
|
|
|
|
array(
|
|
|
|
|
'class' => 'owners-path-editor-table',
|
|
|
|
|
'sigil' => 'paths',
|
|
|
|
|
),
|
|
|
|
|
'')))
|
2011-04-03 22:03:27 -07:00
|
|
|
->appendChild(
|
|
|
|
|
id(new AphrontFormTextAreaControl())
|
|
|
|
|
->setLabel('Description')
|
|
|
|
|
->setName('description')
|
|
|
|
|
->setValue($package->getDescription()))
|
|
|
|
|
->appendChild(
|
|
|
|
|
id(new AphrontFormSubmitControl())
|
|
|
|
|
->addCancelButton($cancel_uri)
|
|
|
|
|
->setValue('Save Package'));
|
|
|
|
|
|
|
|
|
|
$panel = new AphrontPanelView();
|
|
|
|
|
$panel->setHeader($title);
|
|
|
|
|
$panel->setWidth(AphrontPanelView::WIDTH_WIDE);
|
|
|
|
|
$panel->appendChild($error_view);
|
|
|
|
|
$panel->appendChild($form);
|
|
|
|
|
|
|
|
|
|
return $this->buildStandardPageResponse(
|
|
|
|
|
$panel,
|
|
|
|
|
array(
|
|
|
|
|
'title' => $title,
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
|
2012-01-10 11:21:49 -08:00
|
|
|
protected function getExtraPackageViews() {
|
|
|
|
|
if ($this->id) {
|
|
|
|
|
$extra = array(array('name' => 'Edit',
|
|
|
|
|
'key' => 'edit/'.$this->id));
|
|
|
|
|
} else {
|
|
|
|
|
$extra = array(array('name' => 'New',
|
|
|
|
|
'key' => 'new'));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $extra;
|
|
|
|
|
}
|
2011-04-03 22:03:27 -07:00
|
|
|
}
|