mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-22 23:02:42 +01:00
Merge branch 'master' into redesign-2015
This commit is contained in:
commit
fe4bcde59e
13 changed files with 126 additions and 81 deletions
|
@ -2661,6 +2661,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorSpacesNamespaceSearchEngine' => 'applications/spaces/query/PhabricatorSpacesNamespaceSearchEngine.php',
|
||||
'PhabricatorSpacesNamespaceTransaction' => 'applications/spaces/storage/PhabricatorSpacesNamespaceTransaction.php',
|
||||
'PhabricatorSpacesNamespaceTransactionQuery' => 'applications/spaces/query/PhabricatorSpacesNamespaceTransactionQuery.php',
|
||||
'PhabricatorSpacesNoAccessController' => 'applications/spaces/controller/PhabricatorSpacesNoAccessController.php',
|
||||
'PhabricatorSpacesRemarkupRule' => 'applications/spaces/remarkup/PhabricatorSpacesRemarkupRule.php',
|
||||
'PhabricatorSpacesSchemaSpec' => 'applications/spaces/storage/PhabricatorSpacesSchemaSpec.php',
|
||||
'PhabricatorSpacesTestCase' => 'applications/spaces/__tests__/PhabricatorSpacesTestCase.php',
|
||||
|
@ -4670,6 +4671,7 @@ phutil_register_library_map(array(
|
|||
'NuanceItem' => array(
|
||||
'NuanceDAO',
|
||||
'PhabricatorPolicyInterface',
|
||||
'PhabricatorApplicationTransactionInterface',
|
||||
),
|
||||
'NuanceItemEditController' => 'NuanceController',
|
||||
'NuanceItemEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||
|
@ -6455,6 +6457,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorSpacesNamespaceSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||
'PhabricatorSpacesNamespaceTransaction' => 'PhabricatorApplicationTransaction',
|
||||
'PhabricatorSpacesNamespaceTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||
'PhabricatorSpacesNoAccessController' => 'PhabricatorSpacesController',
|
||||
'PhabricatorSpacesRemarkupRule' => 'PhabricatorObjectRemarkupRule',
|
||||
'PhabricatorSpacesSchemaSpec' => 'PhabricatorConfigSchemaSpec',
|
||||
'PhabricatorSpacesTestCase' => 'PhabricatorTestCase',
|
||||
|
|
|
@ -157,19 +157,6 @@ abstract class PhabricatorController extends AphrontController {
|
|||
}
|
||||
}
|
||||
|
||||
$event = new PhabricatorEvent(
|
||||
PhabricatorEventType::TYPE_CONTROLLER_CHECKREQUEST,
|
||||
array(
|
||||
'request' => $request,
|
||||
'controller' => $this,
|
||||
));
|
||||
$event->setUser($user);
|
||||
PhutilEventEngine::dispatchEvent($event);
|
||||
$checker_controller = $event->getValue('controller');
|
||||
if ($checker_controller != $this) {
|
||||
return $this->delegateToController($checker_controller);
|
||||
}
|
||||
|
||||
$auth_class = 'PhabricatorAuthApplication';
|
||||
$auth_application = PhabricatorApplication::getByClass($auth_class);
|
||||
|
||||
|
@ -200,7 +187,8 @@ abstract class PhabricatorController extends AphrontController {
|
|||
if ($this->shouldRequireLogin()) {
|
||||
// This actually means we need either:
|
||||
// - a valid user, or a public controller; and
|
||||
// - permission to see the application.
|
||||
// - permission to see the application; and
|
||||
// - permission to see at least one Space if spaces are configured.
|
||||
|
||||
$allow_public = $this->shouldAllowPublic() &&
|
||||
PhabricatorEnv::getEnvConfig('policy.allow-public');
|
||||
|
@ -223,10 +211,22 @@ abstract class PhabricatorController extends AphrontController {
|
|||
}
|
||||
}
|
||||
|
||||
// If Spaces are configured, require that the user have access to at
|
||||
// least one. If we don't do this, they'll get confusing error messages
|
||||
// later on.
|
||||
$spaces = PhabricatorSpacesNamespaceQuery::getSpacesExist();
|
||||
if ($spaces) {
|
||||
$viewer_spaces = PhabricatorSpacesNamespaceQuery::getViewerSpacesExist(
|
||||
$user);
|
||||
if (!$viewer_spaces) {
|
||||
$controller = new PhabricatorSpacesNoAccessController();
|
||||
return $this->delegateToController($controller);
|
||||
}
|
||||
}
|
||||
|
||||
// If the user doesn't have access to the application, don't let them use
|
||||
// any of its controllers. We query the application in order to generate
|
||||
// a policy exception if the viewer doesn't have permission.
|
||||
|
||||
$application = $this->getCurrentApplication();
|
||||
if ($application) {
|
||||
id(new PhabricatorApplicationQuery())
|
||||
|
|
|
@ -30,7 +30,7 @@ final class HarbormasterBuildUnitMessage
|
|||
'namespace' => 'optional string',
|
||||
'name' => 'string',
|
||||
'result' => 'string',
|
||||
'duration' => 'optional float',
|
||||
'duration' => 'optional float|int',
|
||||
'path' => 'optional string',
|
||||
'coverage' => 'optional map<string, wild>',
|
||||
);
|
||||
|
@ -44,7 +44,7 @@ final class HarbormasterBuildUnitMessage
|
|||
$obj->setNamespace(idx($dict, 'namespace', ''));
|
||||
$obj->setName($dict['name']);
|
||||
$obj->setResult($dict['result']);
|
||||
$obj->setDuration(idx($dict, 'duration'));
|
||||
$obj->setDuration((float)idx($dict, 'duration'));
|
||||
|
||||
$path = idx($dict, 'path');
|
||||
if (strlen($path)) {
|
||||
|
|
|
@ -49,6 +49,8 @@ final class ManiphestTaskEditBulkJobType
|
|||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->withPHIDs(array($task->getObjectPHID()))
|
||||
->needProjectPHIDs(true)
|
||||
->needSubscriberPHIDs(true)
|
||||
->executeOne();
|
||||
if (!$object) {
|
||||
return;
|
||||
|
|
|
@ -16,41 +16,32 @@ final class NuanceRequestorQuery
|
|||
return $this;
|
||||
}
|
||||
|
||||
protected function loadPage() {
|
||||
$table = new NuanceRequestor();
|
||||
$conn_r = $table->establishConnection('r');
|
||||
|
||||
$data = queryfx_all(
|
||||
$conn_r,
|
||||
'SELECT FROM %T %Q %Q %Q',
|
||||
$table->getTableName(),
|
||||
$this->buildWhereClause($conn_r),
|
||||
$this->buildOrderClause($conn_r),
|
||||
$this->buildLimitClause($conn_r));
|
||||
|
||||
return $table->loadAllFromArray($data);
|
||||
public function newObject() {
|
||||
return new NuanceRequestor();
|
||||
}
|
||||
|
||||
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
|
||||
$where = array();
|
||||
protected function loadPage() {
|
||||
return $this->loadStandardPage($this->newObject());
|
||||
}
|
||||
|
||||
$where[] = $this->buildPagingClause($conn_r);
|
||||
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
|
||||
$where = parent::buildWhereClauseParts($conn);
|
||||
|
||||
if ($this->ids) {
|
||||
if ($this->ids !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn_r,
|
||||
$conn,
|
||||
'id IN (%Ld)',
|
||||
$this->ids);
|
||||
}
|
||||
|
||||
if ($this->phids) {
|
||||
if ($this->phids !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn_r,
|
||||
$conn,
|
||||
'phid IN (%Ls)',
|
||||
$this->phids);
|
||||
}
|
||||
|
||||
return $this->formatWhereClause($where);
|
||||
return $where;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
|
||||
final class NuanceItem
|
||||
extends NuanceDAO
|
||||
implements PhabricatorPolicyInterface {
|
||||
implements
|
||||
PhabricatorPolicyInterface,
|
||||
PhabricatorApplicationTransactionInterface {
|
||||
|
||||
const STATUS_OPEN = 0;
|
||||
const STATUS_ASSIGNED = 10;
|
||||
|
@ -143,4 +145,27 @@ final class NuanceItem
|
|||
'dateNuanced' => $this->getDateNuanced(),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorApplicationTransactionInterface )------------------------- */
|
||||
|
||||
|
||||
public function getApplicationTransactionEditor() {
|
||||
return new NuanceItemEditor();
|
||||
}
|
||||
|
||||
public function getApplicationTransactionObject() {
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getApplicationTransactionTemplate() {
|
||||
return new NuanceItemTransaction();
|
||||
}
|
||||
|
||||
public function willRenderTimeline(
|
||||
PhabricatorApplicationTransactionView $timeline,
|
||||
AphrontRequest $request) {
|
||||
return $timeline;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,11 +31,7 @@ final class PhabricatorSpacesApplication extends PhabricatorApplication {
|
|||
}
|
||||
|
||||
public function canUninstall() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function isPrototype() {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getHelpDocumentationArticles(PhabricatorUser $viewer) {
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorSpacesNoAccessController
|
||||
extends PhabricatorSpacesController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('No Access to Spaces'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'This install uses spaces to organize objects, but your account '.
|
||||
'does not have access to any spaces.'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'Ask someone to add you to a Space so you can view and create '.
|
||||
'objects.'))
|
||||
->addCancelButton('/', pht('Drift Aimlessly'));
|
||||
}
|
||||
|
||||
}
|
|
@ -130,22 +130,6 @@ fields to, e.g., edit revision titles. Data available on this event:
|
|||
- `specification` Parameters that will be used to invoke the
|
||||
`differential.createrevision` Conduit call.
|
||||
|
||||
== Controller: Check Request ==
|
||||
|
||||
The constant for this event is
|
||||
`PhabricatorEventType::TYPE_CONTROLLER_CHECKREQUEST`.
|
||||
|
||||
This event is dispatched when controller is about to begin execution. It is
|
||||
meant for checking if the user is allowed to use the application at the moment.
|
||||
It can check if the user has performed too many operations recently, if his IP
|
||||
address is allowed or if the servers are overloaded to process the request.
|
||||
Data available on this event:
|
||||
|
||||
- `request` Object of class @{class:AphrontRequest}.
|
||||
- `controller` Class name of the current controller.
|
||||
|
||||
You can delegate the execution to another controller by modifying `controller`.
|
||||
|
||||
== Maniphest: Will Edit Task ==
|
||||
|
||||
The constant for this event is
|
||||
|
|
|
@ -92,6 +92,9 @@ You can optionally omit the trailing `=` signs -- that is, these are the same:
|
|||
This produces headers like the ones in this document. Make sure you have an
|
||||
empty line before and after the header.
|
||||
|
||||
Lists
|
||||
=====
|
||||
|
||||
Make **lists** by beginning each item with a `-` or a `*`:
|
||||
|
||||
lang=text
|
||||
|
@ -117,6 +120,21 @@ You can make numbered lists with a `#` instead of `-` or `*`:
|
|||
# Zapdos
|
||||
# Moltres
|
||||
|
||||
Numbered lists can also be started with `1.` or `1)`. If you use a number other
|
||||
than `1`, the list will start at that number instead. For example, this:
|
||||
|
||||
```
|
||||
200) OK
|
||||
201) Created
|
||||
202) Accepted
|
||||
```
|
||||
|
||||
...produces this:
|
||||
|
||||
200) OK
|
||||
201) Created
|
||||
202) Accepted
|
||||
|
||||
You can also nest lists:
|
||||
|
||||
```- Body
|
||||
|
|
|
@ -6,20 +6,18 @@ Guide to the Spaces application.
|
|||
Overview
|
||||
========
|
||||
|
||||
IMPORTANT: Spaces is a prototype application.
|
||||
|
||||
The Spaces application makes it easier to manage large groups of objects which
|
||||
share the same access policy. For example:
|
||||
|
||||
- An organization might make a Space for a project in order to satisfy a
|
||||
- An organization might make a space for a project in order to satisfy a
|
||||
contractual obligation to limit access, even internally.
|
||||
- An open source organization might make a Space for work related to
|
||||
- An open source organization might make a space for work related to
|
||||
internal governance, to separate private and public discussions.
|
||||
- A contracting company might make Spaces for clients, to separate them from
|
||||
- A contracting company might make spaces for clients, to separate them from
|
||||
one another.
|
||||
- A company might create a Space for consultants, to give them limited
|
||||
- A company might create a spaces for consultants, to give them limited
|
||||
access to only the resources they need to do their work.
|
||||
- An ambitious manager might create a Space to hide her team's work from her
|
||||
- An ambitious manager might create a space to hide her team's work from her
|
||||
enemies at the company, that she might use the element of surprise to later
|
||||
expand her domain.
|
||||
|
||||
|
@ -39,16 +37,16 @@ them if you don't plan to use them. You can always set them up later.
|
|||
|
||||
To activate Spaces, you need to create at least two spaces. Create spaces from
|
||||
the web UI, by navigating to {nav Spaces > Create Space}. By default, only
|
||||
administrators can create new Spaces, but you can configure this in the
|
||||
administrators can create new spaces, but you can configure this in the
|
||||
{nav Applications} application.
|
||||
|
||||
The first Space you create will be a special "default" Space, and all existing
|
||||
The first space you create will be a special "default" space, and all existing
|
||||
objects will be shifted into this space as soon as you create it. Spaces you
|
||||
create later will be normal spaces, and begin with no objects inside them.
|
||||
|
||||
Create the first space (you may want to name it something like "Default" or
|
||||
"Global" or "Public", depending on the nature of your organization), then
|
||||
create a second Space. Usually, the second space will be something like
|
||||
create a second space. Usually, the second space will be something like
|
||||
"Secret Plans" and have a more restrictive "Visible To" policy.
|
||||
|
||||
|
||||
|
@ -57,7 +55,7 @@ Using Spaces
|
|||
|
||||
Once you've created at least two spaces, you can begin using them.
|
||||
|
||||
Application UIs will change for users who can see at least two Spaces, opening
|
||||
Application UIs will change for users who can see at least two spaces, opening
|
||||
up new controls which let them work with spaces. They will now be able to
|
||||
choose which space to create new objects into, be able to move objects between
|
||||
spaces, and be able to search for objects in a specific space or set of spaces.
|
||||
|
@ -72,14 +70,14 @@ spaces exist. This simplifies the UI for users with limited access.
|
|||
Space Policies
|
||||
==============
|
||||
|
||||
Briefly, Spaces affect policies like this:
|
||||
Briefly, spacess affect policies like this:
|
||||
|
||||
- Spaces apply their view policy to all objects inside the space.
|
||||
- Space policies are absolute, and stronger than all other policies. A
|
||||
user who can not see a Space can **never** see objects inside the space.
|
||||
user who can not see a space can **never** see objects inside the space.
|
||||
- Normal policies are still checked: spaces can only reduce access.
|
||||
|
||||
When you create a Space, you choose a view policy for that space by using the
|
||||
When you create a space, you choose a view policy for that space by using the
|
||||
**Visible To** control. This policy controls both who can see the space, and
|
||||
who can see objects inside the space.
|
||||
|
||||
|
@ -90,21 +88,21 @@ and stronger than all other policy rules, including policy exceptions.
|
|||
For example, a user can never see a task in a space they can't see, even if
|
||||
they are an admin and the author and owner of the task, and subscribed to the
|
||||
task and the view and edit policies are set to "All Users", and they created
|
||||
the Space originally and the moon is full and they are pure of heart and
|
||||
the space originally and the moon is full and they are pure of heart and
|
||||
possessed of the noblest purpose. Spaces are impenetrable.
|
||||
|
||||
Even if a user satisfies the view policy for a space, they must still pass the
|
||||
view policy on the object: the space check is a new check in addition to any
|
||||
check on the object, and can only limit access.
|
||||
|
||||
The edit policy for a space only affects the Space itself, and is not applied
|
||||
The edit policy for a space only affects the space itself, and is not applied
|
||||
to objects inside the space.
|
||||
|
||||
|
||||
Archiving Spaces
|
||||
================
|
||||
|
||||
If you no longer need a Space, you can archive it by choosing
|
||||
If you no longer need a space, you can archive it by choosing
|
||||
{nav Archive Space} from the detail view. This hides the space and all the
|
||||
objects in it without deleting any data.
|
||||
|
||||
|
@ -123,14 +121,14 @@ You can reactivate a space later by choosing {nav Activate Space}.
|
|||
Application Email
|
||||
=================
|
||||
|
||||
After activating Spaces, you can choose a Space when configuring inbound email
|
||||
After activating spaces, you can choose a space when configuring inbound email
|
||||
addresses in {nav Applications}.
|
||||
|
||||
Spaces affect policies for application email just like they do for other
|
||||
objects: to see or use the address, you must be able to see the space which
|
||||
contains it.
|
||||
|
||||
Objects created from inbound email will be created in the Space the email is
|
||||
Objects created from inbound email will be created in the space the email is
|
||||
associated with.
|
||||
|
||||
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
*/
|
||||
final class PhabricatorEventType extends PhutilEventType {
|
||||
|
||||
const TYPE_CONTROLLER_CHECKREQUEST = 'controller.checkRequest';
|
||||
|
||||
const TYPE_MANIPHEST_WILLEDITTASK = 'maniphest.willEditTask';
|
||||
const TYPE_MANIPHEST_DIDEDITTASK = 'maniphest.didEditTask';
|
||||
|
||||
|
|
|
@ -1763,6 +1763,16 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery
|
|||
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
// If we have an omnipotent viewer and no formal space constraints, don't
|
||||
// emit a clause. This primarily enables older migrations to run cleanly,
|
||||
// without fataling because they try to match a `spacePHID` column which
|
||||
// does not exist yet. See T8743, T8746.
|
||||
if ($viewer->isOmnipotent()) {
|
||||
if ($this->spaceIsArchived === null && $this->spacePHIDs === null) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
$space_phids = array();
|
||||
$include_null = false;
|
||||
|
||||
|
|
Loading…
Reference in a new issue