Page MenuHomePhorge

No OneTemporary

diff --git a/src/applications/repository/storage/PhabricatorRepositoryURI.php b/src/applications/repository/storage/PhabricatorRepositoryURI.php
index 26db694a66..774df1fd95 100644
--- a/src/applications/repository/storage/PhabricatorRepositoryURI.php
+++ b/src/applications/repository/storage/PhabricatorRepositoryURI.php
@@ -1,762 +1,762 @@
<?php
final class PhabricatorRepositoryURI
extends PhabricatorRepositoryDAO
implements
PhabricatorApplicationTransactionInterface,
PhabricatorPolicyInterface,
PhabricatorExtendedPolicyInterface,
PhabricatorConduitResultInterface {
protected $repositoryPHID;
protected $uri;
protected $builtinProtocol;
protected $builtinIdentifier;
protected $credentialPHID;
protected $ioType;
protected $displayType;
protected $isDisabled;
private $repository = self::ATTACHABLE;
const BUILTIN_PROTOCOL_SSH = 'ssh';
const BUILTIN_PROTOCOL_HTTP = 'http';
const BUILTIN_PROTOCOL_HTTPS = 'https';
const BUILTIN_IDENTIFIER_ID = 'id';
const BUILTIN_IDENTIFIER_SHORTNAME = 'shortname';
const BUILTIN_IDENTIFIER_CALLSIGN = 'callsign';
const DISPLAY_DEFAULT = 'default';
const DISPLAY_NEVER = 'never';
const DISPLAY_ALWAYS = 'always';
const IO_DEFAULT = 'default';
const IO_OBSERVE = 'observe';
const IO_MIRROR = 'mirror';
const IO_NONE = 'none';
const IO_READ = 'read';
const IO_READWRITE = 'readwrite';
protected function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
self::CONFIG_COLUMN_SCHEMA => array(
'uri' => 'text255',
'builtinProtocol' => 'text32?',
'builtinIdentifier' => 'text32?',
'credentialPHID' => 'phid?',
'ioType' => 'text32',
'displayType' => 'text32',
'isDisabled' => 'bool',
),
self::CONFIG_KEY_SCHEMA => array(
'key_builtin' => array(
'columns' => array(
'repositoryPHID',
'builtinProtocol',
'builtinIdentifier',
),
'unique' => true,
),
),
) + parent::getConfiguration();
}
public static function initializeNewURI() {
return id(new self())
->setIoType(self::IO_DEFAULT)
->setDisplayType(self::DISPLAY_DEFAULT)
->setIsDisabled(0);
}
public function generatePHID() {
return PhabricatorPHID::generateNewPHID(
PhabricatorRepositoryURIPHIDType::TYPECONST);
}
public function attachRepository(PhabricatorRepository $repository) {
$this->repository = $repository;
return $this;
}
public function getRepository() {
return $this->assertAttached($this->repository);
}
public function getRepositoryURIBuiltinKey() {
if (!$this->getBuiltinProtocol()) {
return null;
}
$parts = array(
$this->getBuiltinProtocol(),
$this->getBuiltinIdentifier(),
);
return implode('.', $parts);
}
public function isBuiltin() {
return (bool)$this->getBuiltinProtocol();
}
public function getEffectiveDisplayType() {
$display = $this->getDisplayType();
if ($display != self::DISPLAY_DEFAULT) {
return $display;
}
return $this->getDefaultDisplayType();
}
public function getDefaultDisplayType() {
switch ($this->getEffectiveIOType()) {
case self::IO_MIRROR:
case self::IO_OBSERVE:
case self::IO_NONE:
return self::DISPLAY_NEVER;
case self::IO_READ:
case self::IO_READWRITE:
// By default, only show the "best" version of the builtin URI, not the
// other redundant versions.
$repository = $this->getRepository();
$other_uris = $repository->getURIs();
$identifier_value = array(
self::BUILTIN_IDENTIFIER_SHORTNAME => 3,
self::BUILTIN_IDENTIFIER_CALLSIGN => 2,
self::BUILTIN_IDENTIFIER_ID => 1,
);
$have_identifiers = array();
foreach ($other_uris as $other_uri) {
if ($other_uri->getIsDisabled()) {
continue;
}
$identifier = $other_uri->getBuiltinIdentifier();
if (!$identifier) {
continue;
}
$have_identifiers[$identifier] = $identifier_value[$identifier];
}
$best_identifier = max($have_identifiers);
$this_identifier = $identifier_value[$this->getBuiltinIdentifier()];
if ($this_identifier < $best_identifier) {
return self::DISPLAY_NEVER;
}
return self::DISPLAY_ALWAYS;
}
return self::DISPLAY_NEVER;
}
public function getEffectiveIOType() {
$io = $this->getIoType();
if ($io != self::IO_DEFAULT) {
return $io;
}
return $this->getDefaultIOType();
}
public function getDefaultIOType() {
if ($this->isBuiltin()) {
$repository = $this->getRepository();
$other_uris = $repository->getURIs();
$any_observe = false;
foreach ($other_uris as $other_uri) {
if ($other_uri->getIoType() == self::IO_OBSERVE) {
$any_observe = true;
break;
}
}
if ($any_observe) {
return self::IO_READ;
} else {
return self::IO_READWRITE;
}
}
return self::IO_NONE;
}
public function getNormalizedURI() {
$vcs = $this->getRepository()->getVersionControlSystem();
$map = array(
PhabricatorRepositoryType::REPOSITORY_TYPE_GIT =>
ArcanistRepositoryURINormalizer::TYPE_GIT,
PhabricatorRepositoryType::REPOSITORY_TYPE_SVN =>
ArcanistRepositoryURINormalizer::TYPE_SVN,
PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL =>
ArcanistRepositoryURINormalizer::TYPE_MERCURIAL,
);
$type = $map[$vcs];
$display = (string)$this->getDisplayURI();
$normalizer = new ArcanistRepositoryURINormalizer($type, $display);
$domain_map = self::getURINormalizerDomainMap();
$normalizer->setDomainMap($domain_map);
return $normalizer->getNormalizedURI();
}
public function getDisplayURI() {
return $this->getURIObject();
}
public function getEffectiveURI() {
return $this->getURIObject();
}
public function getURIEnvelope() {
$uri = $this->getEffectiveURI();
$command_engine = $this->newCommandEngine();
$is_http = $command_engine->isAnyHTTPProtocol();
// For SVN, we use `--username` and `--password` flags separately in the
// CommandEngine, so we don't need to add any credentials here.
$is_svn = $this->getRepository()->isSVN();
$credential_phid = $this->getCredentialPHID();
if ($is_http && !$is_svn && $credential_phid) {
$key = PassphrasePasswordKey::loadFromPHID(
$credential_phid,
PhabricatorUser::getOmnipotentUser());
$uri->setUser($key->getUsernameEnvelope()->openEnvelope());
$uri->setPass($key->getPasswordEnvelope()->openEnvelope());
}
return new PhutilOpaqueEnvelope((string)$uri);
}
private function getURIObject() {
// Users can provide Git/SCP-style URIs in the form "user@host:path".
// In the general case, these are not equivalent to any "ssh://..." form
// because the path is relative.
if ($this->isBuiltin()) {
$builtin_protocol = $this->getForcedProtocol();
$builtin_domain = $this->getForcedHost();
$raw_uri = "{$builtin_protocol}://{$builtin_domain}";
} else {
$raw_uri = $this->getURI();
}
$port = $this->getForcedPort();
$default_ports = array(
'ssh' => 22,
'http' => 80,
'https' => 443,
);
$uri = new PhutilURI($raw_uri);
// Make sure to remove any password from the URI before we do anything
// with it; this should always be provided by the associated credential.
$uri->setPass(null);
$protocol = $this->getForcedProtocol();
if ($protocol) {
$uri->setProtocol($protocol);
}
if ($port) {
$uri->setPort($port);
}
// Remove any explicitly set default ports.
$uri_port = $uri->getPort();
$uri_protocol = $uri->getProtocol();
$uri_default = idx($default_ports, $uri_protocol);
if ($uri_default && ($uri_default == $uri_port)) {
$uri->setPort(null);
}
$user = $this->getForcedUser();
if ($user) {
$uri->setUser($user);
}
$host = $this->getForcedHost();
if ($host) {
$uri->setDomain($host);
}
$path = $this->getForcedPath();
if ($path) {
$uri->setPath($path);
}
return $uri;
}
private function getForcedProtocol() {
$repository = $this->getRepository();
switch ($this->getBuiltinProtocol()) {
case self::BUILTIN_PROTOCOL_SSH:
if ($repository->isSVN()) {
return 'svn+ssh';
} else {
return 'ssh';
}
case self::BUILTIN_PROTOCOL_HTTP:
return 'http';
case self::BUILTIN_PROTOCOL_HTTPS:
return 'https';
default:
return null;
}
}
private function getForcedUser() {
switch ($this->getBuiltinProtocol()) {
case self::BUILTIN_PROTOCOL_SSH:
return AlmanacKeys::getClusterSSHUser();
default:
return null;
}
}
private function getForcedHost() {
$phabricator_uri = PhabricatorEnv::getURI('/');
$phabricator_uri = new PhutilURI($phabricator_uri);
$phabricator_host = $phabricator_uri->getDomain();
switch ($this->getBuiltinProtocol()) {
case self::BUILTIN_PROTOCOL_SSH:
$ssh_host = PhabricatorEnv::getEnvConfig('diffusion.ssh-host');
if ($ssh_host !== null) {
return $ssh_host;
}
return $phabricator_host;
case self::BUILTIN_PROTOCOL_HTTP:
case self::BUILTIN_PROTOCOL_HTTPS:
return $phabricator_host;
default:
return null;
}
}
private function getForcedPort() {
$protocol = $this->getBuiltinProtocol();
if ($protocol == self::BUILTIN_PROTOCOL_SSH) {
return PhabricatorEnv::getEnvConfig('diffusion.ssh-port');
}
// If Phabricator is running on a nonstandard port, use that as the default
// port for URIs with the same protocol.
$is_http = ($protocol == self::BUILTIN_PROTOCOL_HTTP);
$is_https = ($protocol == self::BUILTIN_PROTOCOL_HTTPS);
if ($is_http || $is_https) {
$uri = PhabricatorEnv::getURI('/');
$uri = new PhutilURI($uri);
$port = $uri->getPort();
if (!$port) {
return null;
}
$uri_protocol = $uri->getProtocol();
$use_port =
($is_http && ($uri_protocol == 'http')) ||
($is_https && ($uri_protocol == 'https'));
if (!$use_port) {
return null;
}
return $port;
}
return null;
}
private function getForcedPath() {
if (!$this->isBuiltin()) {
return null;
}
$repository = $this->getRepository();
$id = $repository->getID();
$callsign = $repository->getCallsign();
$short_name = $repository->getRepositorySlug();
$clone_name = $repository->getCloneName();
if ($repository->isGit()) {
$suffix = '.git';
} else if ($repository->isHg()) {
$suffix = '/';
} else {
$suffix = '';
$clone_name = '';
}
switch ($this->getBuiltinIdentifier()) {
case self::BUILTIN_IDENTIFIER_ID:
return "/diffusion/{$id}/{$clone_name}{$suffix}";
case self::BUILTIN_IDENTIFIER_SHORTNAME:
return "/source/{$short_name}{$suffix}";
case self::BUILTIN_IDENTIFIER_CALLSIGN:
return "/diffusion/{$callsign}/{$clone_name}{$suffix}";
default:
return null;
}
}
public function getViewURI() {
$id = $this->getID();
return $this->getRepository()->getPathURI("uri/view/{$id}/");
}
public function getEditURI() {
$id = $this->getID();
return $this->getRepository()->getPathURI("uri/edit/{$id}/");
}
public function getAvailableIOTypeOptions() {
$options = array(
self::IO_DEFAULT,
self::IO_NONE,
);
if ($this->isBuiltin()) {
$options[] = self::IO_READ;
$options[] = self::IO_READWRITE;
} else {
$options[] = self::IO_OBSERVE;
$options[] = self::IO_MIRROR;
}
$map = array();
$io_map = self::getIOTypeMap();
foreach ($options as $option) {
$spec = idx($io_map, $option, array());
$label = idx($spec, 'label', $option);
$short = idx($spec, 'short');
$name = pht('%s: %s', $label, $short);
$map[$option] = $name;
}
return $map;
}
public function getAvailableDisplayTypeOptions() {
$options = array(
self::DISPLAY_DEFAULT,
self::DISPLAY_ALWAYS,
self::DISPLAY_NEVER,
);
$map = array();
$display_map = self::getDisplayTypeMap();
foreach ($options as $option) {
$spec = idx($display_map, $option, array());
$label = idx($spec, 'label', $option);
$short = idx($spec, 'short');
$name = pht('%s: %s', $label, $short);
$map[$option] = $name;
}
return $map;
}
public static function getIOTypeMap() {
return array(
self::IO_DEFAULT => array(
'label' => pht('Default'),
'short' => pht('Use default behavior.'),
),
self::IO_OBSERVE => array(
'icon' => 'fa-download',
'color' => 'green',
'label' => pht('Observe'),
'note' => pht(
'Changes to this URI will be observed and pulled.'),
'short' => pht('Copy from a remote.'),
),
self::IO_MIRROR => array(
'icon' => 'fa-upload',
'color' => 'green',
'label' => pht('Mirror'),
'note' => pht(
'A copy of any changes will be pushed to this URI.'),
'short' => pht('Push a copy to a remote.'),
),
self::IO_NONE => array(
'icon' => 'fa-times',
'color' => 'grey',
'label' => pht('No I/O'),
'note' => pht(
'No changes will be pushed or pulled from this URI.'),
'short' => pht('Do not perform any I/O.'),
),
self::IO_READ => array(
'icon' => 'fa-folder',
'color' => 'blue',
'label' => pht('Read Only'),
'note' => pht(
'A read-only copy of the repository will be served from this URI.'),
'short' => pht('Serve repository in read-only mode.'),
),
self::IO_READWRITE => array(
'icon' => 'fa-folder-open',
'color' => 'blue',
'label' => pht('Read/Write'),
'note' => pht(
'A read/write copy of the repository will be served from this URI.'),
'short' => pht('Serve repository in read/write mode.'),
),
);
}
public static function getDisplayTypeMap() {
return array(
self::DISPLAY_DEFAULT => array(
'label' => pht('Default'),
'short' => pht('Use default behavior.'),
),
self::DISPLAY_ALWAYS => array(
'icon' => 'fa-eye',
'color' => 'green',
'label' => pht('Visible'),
'note' => pht('This URI will be shown to users as a clone URI.'),
'short' => pht('Show as a clone URI.'),
),
self::DISPLAY_NEVER => array(
'icon' => 'fa-eye-slash',
'color' => 'grey',
'label' => pht('Hidden'),
'note' => pht(
'This URI will be hidden from users.'),
'short' => pht('Do not show as a clone URI.'),
),
);
}
public function newCommandEngine() {
$repository = $this->getRepository();
return DiffusionCommandEngine::newCommandEngine($repository)
->setCredentialPHID($this->getCredentialPHID())
->setURI($this->getEffectiveURI());
}
public function getURIScore() {
$score = 0;
$io_points = array(
self::IO_READWRITE => 200,
self::IO_READ => 100,
);
$score += idx($io_points, $this->getEffectiveIOType(), 0);
$protocol_points = array(
self::BUILTIN_PROTOCOL_SSH => 30,
self::BUILTIN_PROTOCOL_HTTPS => 20,
self::BUILTIN_PROTOCOL_HTTP => 10,
);
$score += idx($protocol_points, $this->getBuiltinProtocol(), 0);
$identifier_points = array(
self::BUILTIN_IDENTIFIER_SHORTNAME => 3,
self::BUILTIN_IDENTIFIER_CALLSIGN => 2,
self::BUILTIN_IDENTIFIER_ID => 1,
);
$score += idx($identifier_points, $this->getBuiltinIdentifier(), 0);
return $score;
}
/* -( PhabricatorApplicationTransactionInterface )------------------------- */
public function getApplicationTransactionEditor() {
return new DiffusionURIEditor();
}
public function getApplicationTransactionTemplate() {
return new PhabricatorRepositoryURITransaction();
}
/* -( PhabricatorPolicyInterface )----------------------------------------- */
public function getCapabilities() {
return array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
);
}
public function getPolicy($capability) {
switch ($capability) {
case PhabricatorPolicyCapability::CAN_VIEW:
case PhabricatorPolicyCapability::CAN_EDIT:
return PhabricatorPolicies::getMostOpenPolicy();
}
}
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
return false;
}
/* -( PhabricatorExtendedPolicyInterface )--------------------------------- */
public function getExtendedPolicy($capability, PhabricatorUser $viewer) {
$extended = array();
switch ($capability) {
case PhabricatorPolicyCapability::CAN_EDIT:
// To edit a repository URI, you must be able to edit the
// corresponding repository.
$extended[] = array($this->getRepository(), $capability);
break;
}
return $extended;
}
/* -( PhabricatorConduitResultInterface )---------------------------------- */
public function getFieldSpecificationsForConduit() {
return array(
id(new PhabricatorConduitSearchFieldSpecification())
->setKey('repositoryPHID')
->setType('phid')
->setDescription(pht('The associated repository PHID.')),
id(new PhabricatorConduitSearchFieldSpecification())
->setKey('uri')
->setType('map<string, string>')
->setDescription(pht('The raw and effective URI.')),
id(new PhabricatorConduitSearchFieldSpecification())
->setKey('io')
->setType('map<string, const>')
->setDescription(
pht('The raw, default, and effective I/O Type settings.')),
id(new PhabricatorConduitSearchFieldSpecification())
->setKey('display')
->setType('map<string, const>')
->setDescription(
pht('The raw, default, and effective Display Type settings.')),
id(new PhabricatorConduitSearchFieldSpecification())
->setKey('credentialPHID')
->setType('phid?')
->setDescription(
pht('The associated credential PHID, if one exists.')),
id(new PhabricatorConduitSearchFieldSpecification())
->setKey('disabled')
->setType('bool')
->setDescription(pht('True if the URI is disabled.')),
id(new PhabricatorConduitSearchFieldSpecification())
->setKey('builtin')
->setType('map<string, string>')
->setDescription(
pht('Information about builtin URIs.')),
id(new PhabricatorConduitSearchFieldSpecification())
->setKey('dateCreated')
->setType('int')
->setDescription(
pht('Epoch timestamp when the object was created.')),
id(new PhabricatorConduitSearchFieldSpecification())
->setKey('dateModified')
->setType('int')
->setDescription(
pht('Epoch timestamp when the object was last updated.')),
);
}
public function getFieldValuesForConduit() {
return array(
'repositoryPHID' => $this->getRepositoryPHID(),
'uri' => array(
'raw' => $this->getURI(),
'display' => (string)$this->getDisplayURI(),
'effective' => (string)$this->getEffectiveURI(),
'normalized' => (string)$this->getNormalizedURI(),
),
'io' => array(
'raw' => $this->getIOType(),
'default' => $this->getDefaultIOType(),
'effective' => $this->getEffectiveIOType(),
),
'display' => array(
'raw' => $this->getDisplayType(),
'default' => $this->getDefaultDisplayType(),
'effective' => $this->getEffectiveDisplayType(),
),
'credentialPHID' => $this->getCredentialPHID(),
'disabled' => (bool)$this->getIsDisabled(),
'builtin' => array(
'protocol' => $this->getBuiltinProtocol(),
'identifier' => $this->getBuiltinIdentifier(),
),
'dateCreated' => $this->getDateCreated(),
'dateModified' => $this->getDateModified(),
);
}
public function getConduitSearchAttachments() {
return array();
}
public static function getURINormalizerDomainMap() {
$domain_map = array();
// See T13435. If the domain for a repository URI is same as the install
// base URI, store it as a "<base-uri>" token instead of the actual domain
// so that the index does not fall out of date if the install moves.
$base_uri = PhabricatorEnv::getURI('/');
$base_uri = new PhutilURI($base_uri);
$base_domain = $base_uri->getDomain();
$domain_map['<base-uri>'] = $base_domain;
// Likewise, store a token for the "SSH Host" domain so it can be changed
// without requiring an index rebuild.
$ssh_host = PhabricatorEnv::getEnvConfig('diffusion.ssh-host');
- if (strlen($ssh_host)) {
+ if (phutil_nonempty_string($ssh_host)) {
$domain_map['<ssh-host>'] = $ssh_host;
}
return $domain_map;
}
}

File Metadata

Mime Type
text/x-diff
Expires
Jan 19 2025, 21:29 (6 w, 1 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1128932
Default Alt Text
(21 KB)

Event Timeline