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

Allow authentication providers to store and customize additional configuration

Summary:
Ref T1536. None of this code is reachable.

For the new web UI for auth edits, give providers more and better customization options for handling the form. Allow them to format transactions.

Also fix the "Auth" application icon.

Test Plan: {F46718}

Reviewers: btrahan, chad

Reviewed By: chad

CC: aran

Maniphest Tasks: T1536

Differential Revision: https://secure.phabricator.com/D6221
This commit is contained in:
epriestley 2013-06-18 10:02:34 -07:00
parent 1eafc2b638
commit e58f383d91
7 changed files with 210 additions and 44 deletions

View file

@ -10,6 +10,10 @@ final class PhabricatorApplicationAuth extends PhabricatorApplication {
return '/auth/'; return '/auth/';
} }
public function getIconName() {
return 'authentication';
}
public function buildMainMenuItems( public function buildMainMenuItems(
PhabricatorUser $user, PhabricatorUser $user,
PhabricatorController $controller = null) { PhabricatorController $controller = null) {

View file

@ -77,34 +77,48 @@ final class PhabricatorAuthEditController
$v_unlink = $config->getShouldAllowUnlink(); $v_unlink = $config->getShouldAllowUnlink();
if ($request->isFormPost()) { if ($request->isFormPost()) {
$properties = $provider->readFormValuesFromRequest($request);
list($errors, $issues, $properties) = $provider->processEditForm(
$request,
$properties);
$xactions = array(); $xactions = array();
if ($is_new) { if (!$errors) {
if ($is_new) {
$xactions[] = id(new PhabricatorAuthProviderConfigTransaction())
->setTransactionType(
PhabricatorAuthProviderConfigTransaction::TYPE_ENABLE)
->setNewValue(1);
$config->setProviderType($provider->getProviderType());
$config->setProviderDomain($provider->getProviderDomain());
}
$xactions[] = id(new PhabricatorAuthProviderConfigTransaction()) $xactions[] = id(new PhabricatorAuthProviderConfigTransaction())
->setTransactionType( ->setTransactionType(
PhabricatorAuthProviderConfigTransaction::TYPE_ENABLE) PhabricatorAuthProviderConfigTransaction::TYPE_REGISTRATION)
->setNewValue(1); ->setNewValue($request->getInt('allowRegistration', 0));
$config->setProviderType($provider->getProviderType()); $xactions[] = id(new PhabricatorAuthProviderConfigTransaction())
$config->setProviderDomain($provider->getProviderDomain()); ->setTransactionType(
} PhabricatorAuthProviderConfigTransaction::TYPE_LINK)
->setNewValue($request->getInt('allowLink', 0));
$xactions[] = id(new PhabricatorAuthProviderConfigTransaction()) $xactions[] = id(new PhabricatorAuthProviderConfigTransaction())
->setTransactionType( ->setTransactionType(
PhabricatorAuthProviderConfigTransaction::TYPE_REGISTRATION) PhabricatorAuthProviderConfigTransaction::TYPE_UNLINK)
->setNewValue($request->getInt('allowRegistration', 0)); ->setNewValue($request->getInt('allowUnlink', 0));
$xactions[] = id(new PhabricatorAuthProviderConfigTransaction()) foreach ($properties as $key => $value) {
->setTransactionType( $xactions[] = id(new PhabricatorAuthProviderConfigTransaction())
PhabricatorAuthProviderConfigTransaction::TYPE_LINK) ->setTransactionType(
->setNewValue($request->getInt('allowLink', 0)); PhabricatorAuthProviderConfigTransaction::TYPE_PROPERTY)
->setMetadataValue('auth:property', $key)
->setNewValue($value);
}
$xactions[] = id(new PhabricatorAuthProviderConfigTransaction())
->setTransactionType(
PhabricatorAuthProviderConfigTransaction::TYPE_UNLINK)
->setNewValue($request->getInt('allowUnlink', 0));
if (!$errors) {
$editor = id(new PhabricatorAuthProviderConfigEditor()) $editor = id(new PhabricatorAuthProviderConfigEditor())
->setActor($viewer) ->setActor($viewer)
->setContentSourceFromRequest($request) ->setContentSourceFromRequest($request)
@ -114,6 +128,9 @@ final class PhabricatorAuthEditController
return id(new AphrontRedirectResponse())->setURI( return id(new AphrontRedirectResponse())->setURI(
$this->getApplicationURI()); $this->getApplicationURI());
} }
} else {
$properties = $provider->readFormValuesFromProvider();
$issues = array();
} }
if ($errors) { if ($errors) {
@ -204,7 +221,7 @@ final class PhabricatorAuthEditController
$str_unlink, $str_unlink,
$v_unlink)); $v_unlink));
$provider->extendEditForm($form); $provider->extendEditForm($request, $form, $properties, $issues);
$form $form
->appendChild( ->appendChild(
@ -224,6 +241,10 @@ final class PhabricatorAuthEditController
->setViewer($viewer) ->setViewer($viewer)
->execute(); ->execute();
foreach ($xactions as $xaction) {
$xaction->setProvider($provider);
}
$xaction_view = id(new PhabricatorApplicationTransactionView()) $xaction_view = id(new PhabricatorApplicationTransactionView())
->setUser($viewer) ->setUser($viewer)
->setTransactions($xactions); ->setTransactions($xactions);

View file

@ -33,8 +33,9 @@ final class PhabricatorAuthProviderConfigEditor
case PhabricatorAuthProviderConfigTransaction::TYPE_UNLINK: case PhabricatorAuthProviderConfigTransaction::TYPE_UNLINK:
return (int)$object->getShouldAllowUnlink(); return (int)$object->getShouldAllowUnlink();
case PhabricatorAuthProviderConfigTransaction::TYPE_PROPERTY: case PhabricatorAuthProviderConfigTransaction::TYPE_PROPERTY:
// TODO $key = $xaction->getMetadataValue(
throw new Exception("TODO"); PhabricatorAuthProviderConfigTransaction::PROPERTY_KEY);
return $object->getProperty($key);
} }
} }
@ -66,8 +67,9 @@ final class PhabricatorAuthProviderConfigEditor
case PhabricatorAuthProviderConfigTransaction::TYPE_UNLINK: case PhabricatorAuthProviderConfigTransaction::TYPE_UNLINK:
return $object->setShouldAllowUnlink($v); return $object->setShouldAllowUnlink($v);
case PhabricatorAuthProviderConfigTransaction::TYPE_PROPERTY: case PhabricatorAuthProviderConfigTransaction::TYPE_PROPERTY:
// TODO $key = $xaction->getMetadataValue(
throw new Exception("TODO"); PhabricatorAuthProviderConfigTransaction::PROPERTY_KEY);
return $object->setProperty($key, $v);
} }
} }

View file

@ -125,11 +125,6 @@ abstract class PhabricatorAuthProvider {
throw new Exception("Not implemented!"); throw new Exception("Not implemented!");
} }
public function extendEditForm(AphrontFormView $form) {
}
public function createProviders() { public function createProviders() {
return array($this); return array($this);
} }
@ -258,4 +253,36 @@ abstract class PhabricatorAuthProvider {
return false; return false;
} }
public function renderConfigPropertyTransactionTitle(
PhabricatorAuthProviderConfigTransaction $xaction) {
return null;
}
public function readFormValuesFromProvider() {
return array();
}
public function readFormValuesFromRequest(AphrontRequest $request) {
return array();
}
public function processEditForm(
AphrontRequest $request,
array $values) {
$errors = array();
$issues = array();
return array($errors, $issues, $values);
}
public function extendEditForm(
AphrontRequest $request,
AphrontFormView $form,
array $values,
array $issues) {
return;
}
} }

View file

@ -170,35 +170,127 @@ abstract class PhabricatorAuthProviderOAuth extends PhabricatorAuthProvider {
return array($this->loadOrCreateAccount($account_id), $response); return array($this->loadOrCreateAccount($account_id), $response);
} }
public function extendEditForm( const PROPERTY_APP_ID = 'oauth:app:id';
AphrontFormView $form) { const PROPERTY_APP_SECRET = 'oauth:app:secret';
$v_id = $this->getOAuthClientID();
public function readFormValuesFromProvider() {
$secret = $this->getOAuthClientSecret(); $secret = $this->getOAuthClientSecret();
if ($secret) { if ($secret) {
$v_secret = str_repeat('*', strlen($secret->openEnvelope())); $secret = $secret->openEnvelope();
} else {
$v_secret = '';
} }
$e_id = strlen($v_id) ? null : true; return array(
$e_secret = strlen($v_secret) ? null : true; self::PROPERTY_APP_ID => $this->getOAuthClientID(),
self::PROPERTY_APP_SECRET => $secret,
);
}
public function readFormValuesFromRequest(AphrontRequest $request) {
return array(
self::PROPERTY_APP_ID => $request->getStr(self::PROPERTY_APP_ID),
self::PROPERTY_APP_SECRET => $request->getStr(self::PROPERTY_APP_SECRET),
);
}
public function processEditForm(
AphrontRequest $request,
array $values) {
$errors = array();
$issues = array();
$key_id = self::PROPERTY_APP_ID;
$key_secret = self::PROPERTY_APP_SECRET;
if (!strlen($values[$key_id])) {
$errors[] = pht('Application ID is required.');
$issues[$key_id] = pht('Required');
}
if (!strlen($values[$key_secret])) {
$errors[] = pht('Application secret is required.');
$issues[$key_id] = pht('Required');
}
// If the user has not changed the secret, don't update it (that is,
// don't cause a bunch of "****" to be written to the database).
if (preg_match('/^[*]+$/', $values[$key_secret])) {
unset($values[$key_secret]);
}
return array($errors, $issues, $values);
}
public function extendEditForm(
AphrontRequest $request,
AphrontFormView $form,
array $values,
array $issues) {
$key_id = self::PROPERTY_APP_ID;
$key_secret = self::PROPERTY_APP_SECRET;
$v_id = $values[$key_id];
$v_secret = $values[$key_secret];
if ($v_secret) {
$v_secret = str_repeat('*', strlen($v_secret));
}
$e_id = idx($issues, $key_id, $request->isFormPost() ? null : true);
$e_secret = idx($issues, $key_secret, $request->isFormPost() ? null : true);
$form $form
->appendChild( ->appendChild(
id(new AphrontFormTextControl()) id(new AphrontFormTextControl())
->setLabel(pht('OAuth App ID')) ->setLabel(pht('OAuth App ID'))
->setName('oauth:app:id') ->setName($key_id)
->setValue($v_id) ->setValue($v_id)
->setError($e_id)) ->setError($e_id))
->appendChild( ->appendChild(
id(new AphrontFormPasswordControl()) id(new AphrontFormPasswordControl())
->setLabel(pht('OAuth App Secret')) ->setLabel(pht('OAuth App Secret'))
->setName('oauth:app:secret') ->setName($key_secret)
->setValue($v_secret) ->setValue($v_secret)
->setError($e_secret)); ->setError($e_secret));
}
public function renderConfigPropertyTransactionTitle(
PhabricatorAuthProviderConfigTransaction $xaction) {
$author_phid = $xaction->getAuthorPHID();
$old = $xaction->getOldValue();
$new = $xaction->getNewValue();
$key = $xaction->getMetadataValue(
PhabricatorAuthProviderConfigTransaction::PROPERTY_KEY);
switch ($key) {
case self::PROPERTY_APP_ID:
if (strlen($old)) {
return pht(
'%s updated the OAuth application ID for this provider from '.
'"%s" to "%s".',
$xaction->renderHandleLink($author_phid),
$old,
$new);
} else {
return pht(
'%s set the OAuth application ID for this provider to '.
'"%s".',
$xaction->renderHandleLink($author_phid),
$new);
}
case self::PROPERTY_APP_SECRET:
if (strlen($old)) {
return pht(
'%s updated the OAuth application secret for this provider.',
$xaction->renderHandleLink($author_phid));
} else {
return pht(
'%s set the OAuth application seceret for this provider.',
$xaction->renderHandleLink($author_phid));
}
}
return parent::renderConfigPropertyTransactionTitle($xaction);
} }
} }

View file

@ -9,6 +9,19 @@ final class PhabricatorAuthProviderConfigTransaction
const TYPE_UNLINK = 'config:unlink'; const TYPE_UNLINK = 'config:unlink';
const TYPE_PROPERTY = 'config:property'; const TYPE_PROPERTY = 'config:property';
const PROPERTY_KEY = 'auth:property';
private $provider;
public function setProvider(PhabricatorAuthProvider $provider) {
$this->provider = $provider;
return $this;
}
public function getProvider() {
return $this->provider;
}
public function getApplicationName() { public function getApplicationName() {
return 'auth'; return 'auth';
} }
@ -113,7 +126,14 @@ final class PhabricatorAuthProviderConfigTransaction
} }
break; break;
case self::TYPE_PROPERTY: case self::TYPE_PROPERTY:
// TODO $provider = $this->getProvider();
if ($provider) {
$title = $provider->renderConfigPropertyTransactionTitle($this);
if (strlen($title)) {
return $title;
}
}
return pht( return pht(
'%s edited a property of this provider.', '%s edited a property of this provider.',
$this->renderHandleLink($author_phid)); $this->renderHandleLink($author_phid));

View file

@ -163,7 +163,7 @@ abstract class PhabricatorApplicationTransaction
return $this->handles; return $this->handles;
} }
protected function renderHandleLink($phid) { public function renderHandleLink($phid) {
if ($this->renderingTarget == self::TARGET_HTML) { if ($this->renderingTarget == self::TARGET_HTML) {
return $this->getHandle($phid)->renderLink(); return $this->getHandle($phid)->renderLink();
} else { } else {
@ -171,7 +171,7 @@ abstract class PhabricatorApplicationTransaction
} }
} }
protected function renderHandleList(array $phids) { public function renderHandleList(array $phids) {
$links = array(); $links = array();
foreach ($phids as $phid) { foreach ($phids as $phid) {
$links[] = $this->renderHandleLink($phid); $links[] = $this->renderHandleLink($phid);