Page MenuHomePhorge

No OneTemporary

diff --git a/src/applications/diffusion/protocol/DiffusionMercurialWireProtocol.php b/src/applications/diffusion/protocol/DiffusionMercurialWireProtocol.php
index 11e864e74e..32a73867e5 100644
--- a/src/applications/diffusion/protocol/DiffusionMercurialWireProtocol.php
+++ b/src/applications/diffusion/protocol/DiffusionMercurialWireProtocol.php
@@ -1,132 +1,132 @@
<?php
final class DiffusionMercurialWireProtocol extends Phobject {
public static function getCommandArgs($command) {
// We need to enumerate all of the Mercurial wire commands because the
// argument encoding varies based on the command. "Why?", you might ask,
// "Why would you do this?".
$commands = array(
'batch' => array('cmds', '*'),
'between' => array('pairs'),
'branchmap' => array(),
'branches' => array('nodes'),
'capabilities' => array(),
'changegroup' => array('roots'),
'changegroupsubset' => array('bases heads'),
'debugwireargs' => array('one two *'),
'getbundle' => array('*'),
'heads' => array(),
'hello' => array(),
'known' => array('nodes', '*'),
'listkeys' => array('namespace'),
'lookup' => array('key'),
'pushkey' => array('namespace', 'key', 'old', 'new'),
'stream_out' => array(''),
'unbundle' => array('heads'),
);
if (!isset($commands[$command])) {
throw new Exception(pht("Unknown Mercurial command '%s!", $command));
}
return $commands[$command];
}
public static function isReadOnlyCommand($command) {
$read_only = array(
'between' => true,
'branchmap' => true,
'branches' => true,
'capabilities' => true,
'changegroup' => true,
'changegroupsubset' => true,
'debugwireargs' => true,
'getbundle' => true,
'heads' => true,
'hello' => true,
'known' => true,
'listkeys' => true,
'lookup' => true,
'stream_out' => true,
);
// Notably, the write commands are "pushkey" and "unbundle". The
// "batch" command is theoretically read only, but we require explicit
// analysis of the actual commands.
return isset($read_only[$command]);
}
public static function isReadOnlyBatchCommand($cmds) {
if (!strlen($cmds)) {
// We expect a "batch" command to always have a "cmds" string, so err
// on the side of caution and throw if we don't get any data here. This
// either indicates a mangled command from the client or a programming
// error in our code.
throw new Exception(pht("Expected nonempty '%s' specification!", 'cmds'));
}
// For "batch" we get a "cmds" argument like:
//
// heads ;known nodes=
//
// We need to examine the commands (here, "heads" and "known") to make sure
// they're all read-only.
// NOTE: Mercurial has some code to escape semicolons, but it does not
// actually function for command separation. For example, these two batch
// commands will produce completely different results (the former will run
// the lookup; the latter will fail with a parser error):
//
// lookup key=a:xb;lookup key=z* 0
// lookup key=a:;b;lookup key=z* 0
// ^
// |
// +-- Note semicolon.
//
// So just split unconditionally.
$cmds = explode(';', $cmds);
foreach ($cmds as $sub_cmd) {
$name = head(explode(' ', $sub_cmd, 2));
if (!self::isReadOnlyCommand($name)) {
return false;
}
}
return true;
}
/** If the server version is running 3.4+ it will respond
* with 'bundle2' capability in the format of "bundle2=(url-encoding)".
* Until we maange to properly package up bundles to send back we
* disallow the client from knowing we speak bundle2 by removing it
* from the capabilities listing.
*
- * The format of the capabilties string is: "a space separated list
+ * The format of the capabilities string is: "a space separated list
* of strings representing what commands the server supports"
* @link https://www.mercurial-scm.org/wiki/CommandServer#Protocol
*
* @param string $capabilities - The string of capabilities to
* strip the bundle2 capability from. This is expected to be
* the space-separated list of strings resulting from the
- * querying the 'capabilties' command.
+ * querying the 'capabilities' command.
*
* @return string The resulting space-separated list of capabilities
* which no longer contains the 'bundle2' capability. This is meant
* to replace the original $body to send back to client.
*/
public static function filterBundle2Capability($capabilities) {
$parts = explode(' ', $capabilities);
foreach ($parts as $key => $part) {
if (preg_match('/^bundle2=/', $part)) {
unset($parts[$key]);
break;
}
}
return implode(' ', $parts);
}
}
diff --git a/src/applications/policy/controller/PhabricatorPolicyExplainController.php b/src/applications/policy/controller/PhabricatorPolicyExplainController.php
index da4103765b..fc508cfa3a 100644
--- a/src/applications/policy/controller/PhabricatorPolicyExplainController.php
+++ b/src/applications/policy/controller/PhabricatorPolicyExplainController.php
@@ -1,326 +1,326 @@
<?php
final class PhabricatorPolicyExplainController
extends PhabricatorPolicyController {
public function shouldAllowPublic() {
return true;
}
public function handleRequest(AphrontRequest $request) {
$viewer = $this->getViewer();
$phid = $request->getURIData('phid');
$capability = $request->getURIData('capability');
$object = id(new PhabricatorObjectQuery())
->setViewer($viewer)
->withPHIDs(array($phid))
->executeOne();
if (!$object) {
return new Aphront404Response();
}
$policies = PhabricatorPolicyQuery::loadPolicies(
$viewer,
$object);
$policy = idx($policies, $capability);
if (!$policy) {
return new Aphront404Response();
}
$handle = id(new PhabricatorHandleQuery())
->setViewer($viewer)
->withPHIDs(array($phid))
->executeOne();
$object_name = $handle->getName();
$object_uri = nonempty($handle->getURI(), '/');
$dialog = id(new AphrontDialogView())
->setUser($viewer)
->setClass('aphront-access-dialog aphront-policy-explain-dialog')
->setTitle(pht('Policy Details: %s', $object_name))
->addCancelButton($object_uri, pht('Done'));
$space_section = $this->buildSpaceSection(
$object,
$policy,
$capability);
$extended_section = $this->buildExtendedSection(
$object,
$capability);
$exceptions_section = $this->buildExceptionsSection(
$object,
$capability);
$object_section = $this->buildObjectSection(
$object,
$policy,
$capability,
$handle);
$dialog->appendChild(
array(
$space_section,
$extended_section,
$exceptions_section,
$object_section,
));
return $dialog;
}
private function buildSpaceSection(
PhabricatorPolicyInterface $object,
PhabricatorPolicy $policy,
$capability) {
$viewer = $this->getViewer();
if (!($object instanceof PhabricatorSpacesInterface)) {
return null;
}
if (!PhabricatorSpacesNamespaceQuery::getSpacesExist()) {
return null;
}
$space_phid = PhabricatorSpacesNamespaceQuery::getObjectSpacePHID(
$object);
$spaces = PhabricatorSpacesNamespaceQuery::getViewerSpaces($viewer);
$space = idx($spaces, $space_phid);
if (!$space) {
return null;
}
$space_policies = PhabricatorPolicyQuery::loadPolicies($viewer, $space);
$space_policy = idx($space_policies, PhabricatorPolicyCapability::CAN_VIEW);
if (!$space_policy) {
return null;
}
$doc_href = PhabricatorEnv::getDoclink('Spaces User Guide');
$capability_name = $this->getCapabilityName($capability);
$space_section = id(new PHUIPolicySectionView())
->setViewer($viewer)
->setIcon('fa-th-large bluegrey')
->setHeader(pht('Space'))
->setDocumentationLink(pht('Spaces Documentation'), $doc_href)
->appendList(
array(
array(
phutil_tag('strong', array(), pht('Space:')),
' ',
$viewer->renderHandle($space_phid)->setAsTag(true),
),
array(
phutil_tag('strong', array(), pht('%s:', $capability_name)),
' ',
$space_policy->getShortName(),
),
))
->appendParagraph(
pht(
'This object is in %s and can only be seen or edited by users '.
'with access to view objects in the space.',
$viewer->renderHandle($space_phid)));
$space_explanation = PhabricatorPolicy::getPolicyExplanation(
$viewer,
$space_policy->getPHID());
$items = array();
$items[] = $space_explanation;
$space_section
->appendParagraph(pht('Users who can see objects in this space:'))
->appendList($items);
$view_capability = PhabricatorPolicyCapability::CAN_VIEW;
if ($capability == $view_capability) {
$stronger = $space_policy->isStrongerThan($policy);
if ($stronger) {
$space_section->appendHint(
pht(
'The space this object is in has a more restrictive view '.
'policy ("%s") than the object does ("%s"), so the space\'s '.
'view policy is shown as a hint instead of the object policy.',
$space_policy->getShortName(),
$policy->getShortName()));
}
}
$space_section->appendHint(
pht(
'After a user passes space policy checks, they must still pass '.
'object policy checks.'));
return $space_section;
}
private function getStrengthInformation(
PhabricatorPolicyInterface $object,
PhabricatorPolicy $policy,
$capability) {
$viewer = $this->getViewer();
$default_policy = PhabricatorPolicyQuery::getDefaultPolicyForObject(
$viewer,
$object,
$capability);
if (!$default_policy) {
return;
}
if ($default_policy->getPHID() == $policy->getPHID()) {
return;
}
if ($default_policy->isStrongerThan($policy)) {
$info = pht(
'This object has a less restrictive policy ("%s") than the default '.
'policy for similar objects (which is "%s").',
$policy->getShortName(),
$default_policy->getShortName());
} else if ($policy->isStrongerThan($default_policy)) {
$info = pht(
'This object has a more restrictive policy ("%s") than the default '.
'policy for similar objects (which is "%s").',
$policy->getShortName(),
$default_policy->getShortName());
} else {
$info = pht(
'This object has a different policy ("%s") than the default policy '.
'for similar objects (which is "%s").',
$policy->getShortName(),
$default_policy->getShortName());
}
return $info;
}
private function getCapabilityName($capability) {
$capability_name = $capability;
$capobj = PhabricatorPolicyCapability::getCapabilityByKey($capability);
if ($capobj) {
$capability_name = $capobj->getCapabilityName();
}
return $capability_name;
}
private function buildExtendedSection(
PhabricatorPolicyInterface $object,
$capability) {
$viewer = $this->getViewer();
if (!($object instanceof PhabricatorExtendedPolicyInterface)) {
return null;
}
$extended_rules = $object->getExtendedPolicy($capability, $viewer);
if (!$extended_rules) {
return null;
}
$items = array();
foreach ($extended_rules as $extended_rule) {
$extended_target = $extended_rule[0];
$extended_capabilities = (array)$extended_rule[1];
if (is_object($extended_target)) {
$extended_target = $extended_target->getPHID();
}
foreach ($extended_capabilities as $extended_capability) {
$ex_name = $this->getCapabilityName($extended_capability);
$items[] = array(
phutil_tag('strong', array(), pht('%s:', $ex_name)),
' ',
$viewer->renderHandle($extended_target)->setAsTag(true),
);
}
}
return id(new PHUIPolicySectionView())
->setViewer($viewer)
->setIcon('fa-link')
->setHeader(pht('Required Capabilities on Other Objects'))
->appendParagraph(
pht(
'To access this object, users must have first have access '.
- 'capabilties on these other objects:'))
+ 'capabilities on these other objects:'))
->appendList($items);
}
private function buildExceptionsSection(
PhabricatorPolicyInterface $object,
$capability) {
$viewer = $this->getViewer();
$exceptions = PhabricatorPolicy::getSpecialRules(
$object,
$viewer,
$capability,
false);
if (!$exceptions) {
return null;
}
return id(new PHUIPolicySectionView())
->setViewer($viewer)
->setIcon('fa-unlock-alt red')
->setHeader(pht('Special Rules'))
->appendParagraph(
pht(
'This object has special rules which override normal object '.
'policy rules:'))
->appendList($exceptions);
}
private function buildObjectSection(
PhabricatorPolicyInterface $object,
PhabricatorPolicy $policy,
$capability,
PhabricatorObjectHandle $handle) {
$viewer = $this->getViewer();
$capability_name = $this->getCapabilityName($capability);
$object_section = id(new PHUIPolicySectionView())
->setViewer($viewer)
->setIcon($handle->getIcon().' bluegrey')
->setHeader(pht('Object Policy'))
->appendList(
array(
array(
phutil_tag('strong', array(), pht('%s:', $capability_name)),
' ',
$policy->getShortName(),
),
))
->appendParagraph(
pht(
'In detail, this means that these users can take this action, '.
'provided they pass all of the checks described above first:'))
->appendList(
array(
PhabricatorPolicy::getPolicyExplanation(
$viewer,
$policy->getPHID()),
));
$strength = $this->getStrengthInformation($object, $policy, $capability);
if ($strength) {
$object_section->appendHint($strength);
}
return $object_section;
}
}

File Metadata

Mime Type
text/x-diff
Expires
Jan 19 2025, 23:16 (6 w, 3 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1129791
Default Alt Text
(14 KB)

Event Timeline