Page MenuHomec4science

PassphraseCredentialControl.php
No OneTemporary

File Metadata

Created
Tue, Nov 26, 04:57

PassphraseCredentialControl.php

<?php
final class PassphraseCredentialControl extends AphrontFormControl {
private $options = array();
private $credentialType;
private $defaultUsername;
private $allowNull;
public function setAllowNull($allow_null) {
$this->allowNull = $allow_null;
return $this;
}
public function setDefaultUsername($default_username) {
$this->defaultUsername = $default_username;
return $this;
}
public function setCredentialType($credential_type) {
$this->credentialType = $credential_type;
return $this;
}
public function getCredentialType() {
return $this->credentialType;
}
public function setOptions(array $options) {
assert_instances_of($options, 'PassphraseCredential');
$this->options = $options;
return $this;
}
protected function getCustomControlClass() {
return 'passphrase-credential-control';
}
protected function renderInput() {
$options_map = array();
foreach ($this->options as $option) {
$options_map[$option->getPHID()] = pht(
'%s %s',
$option->getMonogram(),
$option->getName());
}
// The user editing the form may not have permission to see the current
// credential. Populate it into the menu to allow them to save the form
// without making any changes.
$current_phid = $this->getValue();
if (strlen($current_phid) && empty($options_map[$current_phid])) {
$viewer = $this->getViewer();
$user_credential = id(new PassphraseCredentialQuery())
->setViewer($viewer)
->withPHIDs(array($current_phid))
->executeOne();
if (!$user_credential) {
// Pull the credential with the ominipotent viewer so we can look up
// the ID and tell if it's restricted or invalid.
$omnipotent_credential = id(new PassphraseCredentialQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withPHIDs(array($current_phid))
->executeOne();
if ($omnipotent_credential) {
$current_name = pht(
'%s (Restricted Credential)',
$omnipotent_credential->getMonogram());
} else {
$current_name = pht(
'Invalid Credential ("%s")',
$current_phid);
}
} else {
$current_name = pht(
'%s %s',
$user_credential->getMonogram(),
$user_credential->getName());
}
$options_map = array(
$current_phid => $current_name,
) + $options_map;
}
$disabled = $this->getDisabled();
if ($this->allowNull) {
$options_map = array('' => pht('(No Credentials)')) + $options_map;
} else {
if (!$options_map) {
$options_map[''] = pht('(No Existing Credentials)');
$disabled = true;
}
}
Javelin::initBehavior('passphrase-credential-control');
$options = AphrontFormSelectControl::renderSelectTag(
$this->getValue(),
$options_map,
array(
'id' => $this->getControlID(),
'name' => $this->getName(),
'disabled' => $disabled ? 'disabled' : null,
'sigil' => 'passphrase-credential-select',
));
if ($this->credentialType) {
$button = javelin_tag(
'a',
array(
'href' => '#',
'class' => 'button button-grey',
'sigil' => 'passphrase-credential-add',
'mustcapture' => true,
),
pht('Add Credential'));
} else {
$button = null;
}
return javelin_tag(
'div',
array(
'sigil' => 'passphrase-credential-control',
'meta' => array(
'type' => $this->getCredentialType(),
'username' => $this->defaultUsername,
'allowNull' => $this->allowNull,
),
),
array(
$options,
$button,
));
}
/**
* Verify that a given actor has permission to use all of the credentials
* in a list of credential transactions.
*
* In general, the rule here is:
*
* - If you're editing an object and it uses a credential you can't use,
* that's fine as long as you don't change the credential.
* - If you do change the credential, the new credential must be one you
* can use.
*
* @param PhabricatorUser The acting user.
* @param list<PhabricatorApplicationTransaction> List of credential altering
* transactions.
* @return bool True if the transactions are valid.
*/
public static function validateTransactions(
PhabricatorUser $actor,
array $xactions) {
$new_phids = array();
foreach ($xactions as $xaction) {
$new = $xaction->getNewValue();
if (!$new) {
// Removing a credential, so this is OK.
continue;
}
$old = $xaction->getOldValue();
if ($old == $new) {
// This is a no-op transaction, so this is also OK.
continue;
}
// Otherwise, we need to check this credential.
$new_phids[] = $new;
}
if (!$new_phids) {
// No new credentials being set, so this is fine.
return true;
}
$usable_credentials = id(new PassphraseCredentialQuery())
->setViewer($actor)
->withPHIDs($new_phids)
->execute();
$usable_credentials = mpull($usable_credentials, null, 'getPHID');
foreach ($new_phids as $phid) {
if (empty($usable_credentials[$phid])) {
return false;
}
}
return true;
}
}

Event Timeline