1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-27 01:02:42 +01:00

Merge branch 'master' into redesign-2015

This commit is contained in:
epriestley 2015-07-03 13:05:16 -07:00
commit fe4bcde59e
13 changed files with 126 additions and 81 deletions

View file

@ -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',

View file

@ -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())

View file

@ -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)) {

View file

@ -49,6 +49,8 @@ final class ManiphestTaskEditBulkJobType
PhabricatorPolicyCapability::CAN_EDIT,
))
->withPHIDs(array($task->getObjectPHID()))
->needProjectPHIDs(true)
->needSubscriberPHIDs(true)
->executeOne();
if (!$object) {
return;

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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) {

View file

@ -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'));
}
}

View file

@ -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

View file

@ -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

View file

@ -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.

View file

@ -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';

View file

@ -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;