Changeset View
Changeset View
Standalone View
Standalone View
src/applications/auth/provider/PhabricatorAuthProviderShibboleth.php
- This file was added.
<?php | |||||
final class PhabricatorAuthProviderShibboleth | |||||
extends PhabricatorAuthProvider { | |||||
private $adapter; | |||||
public function getProviderName() { | |||||
return pht('Shibboleth'); | |||||
} | |||||
public function getDescriptionForCreate() { | |||||
return pht( | |||||
'Configure a trust relationship for Shibboleth (Single Sign On) '. | |||||
'autheticated users to automatically log in to Phabricator.'); | |||||
} | |||||
public function getDefaultProviderConfig() { | |||||
return parent::getDefaultProviderConfig(); | |||||
} | |||||
public function getAdapter() { | |||||
if (!$this->adapter) { | |||||
$conf = $this->getProviderConfig(); | |||||
$adapter = id(new PhutilAuthAdapterShibboleth()) | |||||
->setShibSessionIdField( | |||||
$conf->getProperty(self::KEY_SHIB_SESSION_ID_FIELD)) | |||||
->setShibApplicationIdField( | |||||
$conf->getProperty(self::KEY_SHIB_APPLICATION_ID_FIELD)) | |||||
->setUseridField( | |||||
$conf->getProperty(self::KEY_USERID_FIELD)) | |||||
->setUsernameField( | |||||
$conf->getProperty(self::KEY_USERNAME_FIELD)) | |||||
->setRealnameField( | |||||
$conf->getProperty(self::KEY_REALNAME_FIELD)) | |||||
->setEmailField( | |||||
$conf->getProperty(self::KEY_EMAIL_FIELD)) | |||||
->setPageURIPattern( | |||||
$conf->getProperty(self::KEY_PAGE_URI_PATTERN)) | |||||
->setImageURIPattern( | |||||
$conf->getProperty(self::KEY_IMAGE_URI_PATTERN)); | |||||
$this->adapter = $adapter; | |||||
} | |||||
return $this->adapter; | |||||
} | |||||
protected function renderLoginForm(AphrontRequest $request, $mode) { | |||||
$viewer = $request->getUser(); | |||||
$dialog = id(new AphrontDialogView()) | |||||
->setSubmitURI($this->getLoginURI()) | |||||
->setUser($viewer); | |||||
if ($mode == 'link') { | |||||
$dialog->setTitle(pht('Link Shibboleth Account')); | |||||
$dialog->addSubmitButton(pht('Link Accounts')); | |||||
$dialog->addCancelButton($this->getSettingsURI()); | |||||
} else if ($mode == 'refresh') { | |||||
$dialog->setTitle(pht('Refresh Shibboleth Account')); | |||||
$dialog->addSubmitButton(pht('Refresh Account')); | |||||
$dialog->addCancelButton($this->getSettingsURI()); | |||||
} else { | |||||
if ($this->shouldAllowRegistration()) { | |||||
$dialog->setTitle(pht('Login or Register with Shibboleth')); | |||||
$dialog->addSubmitButton(pht('Login or Register')); | |||||
} else { | |||||
$dialog->setTitle(pht('Login with Shibboleth')); | |||||
$dialog->addSubmitButton(pht('Login')); | |||||
} | |||||
if ($mode == 'login') { | |||||
$dialog->addCancelButton($this->getStartURI()); | |||||
} | |||||
} | |||||
$errors = array(); | |||||
if ($request->isHTTPPost()) { | |||||
$errors[] = pht('Invalid Shibboleth session.'); | |||||
} | |||||
if ($errors) { | |||||
$errors = id(new AphrontErrorView())->setErrors($errors); | |||||
} | |||||
$dialog->appendChild($errors); | |||||
return $dialog; | |||||
} | |||||
public function processLoginRequest( | |||||
PhabricatorAuthLoginController $controller) { | |||||
$request = $controller->getRequest(); | |||||
$response = null; | |||||
$account = null; | |||||
$adapter = $this->getAdapter(); | |||||
$headers = array(); | |||||
$header_names = $adapter->getHeaderNames(); | |||||
foreach ($header_names as $h) { | |||||
$headers[$h] = $request->getHTTPHeader($h); | |||||
} | |||||
if (! $adapter->setUserDataFromRequest($headers)) { | |||||
$response = $controller->buildProviderPageResponse( | |||||
$this, | |||||
$this->renderLoginForm($request, 'login')); | |||||
return array($account, $response); | |||||
} | |||||
$account_id = $adapter->getAccountID(); | |||||
return array($this->loadOrCreateAccount($account_id), $response); | |||||
} | |||||
const KEY_SHIB_SESSION_ID_FIELD = 'shibboleth:session_id_field'; | |||||
const KEY_SHIB_APPLICATION_ID_FIELD = 'shibboleth:application_id_field'; | |||||
const KEY_USERID_FIELD = 'shibboleth:userid_field'; | |||||
const KEY_USERNAME_FIELD = 'shibboleth:username_field'; | |||||
const KEY_REALNAME_FIELD = 'shibboleth:realname_field'; | |||||
const KEY_EMAIL_FIELD = 'shibboleth:email_field'; | |||||
const KEY_PAGE_URI_PATTERN = 'shibboleth:page_uri_pattern'; | |||||
const KEY_IMAGE_URI_PATTERN = 'shibboleth:image_uri_pattern'; | |||||
private function getPropertyKeys() { | |||||
return array_keys($this->getPropertyLabels()); | |||||
} | |||||
private function getPropertyLabels() { | |||||
return array( | |||||
self::KEY_SHIB_SESSION_ID_FIELD => pht('Session ID field name'), | |||||
self::KEY_SHIB_APPLICATION_ID_FIELD => pht('Application ID field name'), | |||||
self::KEY_USERID_FIELD => pht('User ID field name'), | |||||
self::KEY_USERNAME_FIELD => pht('Username field name'), | |||||
self::KEY_REALNAME_FIELD => pht('Real name field name'), | |||||
self::KEY_EMAIL_FIELD => pht('User email field name'), | |||||
self::KEY_PAGE_URI_PATTERN => pht('User page URI pattern'), | |||||
self::KEY_IMAGE_URI_PATTERN => pht('User image URI pattern'), | |||||
); | |||||
} | |||||
public function readFormValuesFromProvider() { | |||||
$properties = array(); | |||||
foreach ($this->getPropertyLabels() as $key => $ignored) { | |||||
$properties[$key] = $this->getProviderConfig()->getProperty($key); | |||||
} | |||||
return $properties; | |||||
} | |||||
public function readFormValuesFromRequest(AphrontRequest $request) { | |||||
$values = array(); | |||||
foreach ($this->getPropertyKeys() as $key) { | |||||
$values[$key] = $request->getStr($key); | |||||
} | |||||
return $values; | |||||
} | |||||
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) { | |||||
$labels = $this->getPropertyLabels(); | |||||
$captions = array( | |||||
self::KEY_SHIB_SESSION_ID_FIELD => pht('Session ID field name'), | |||||
self::KEY_SHIB_APPLICATION_ID_FIELD => pht('Application ID field name'), | |||||
self::KEY_USERID_FIELD => pht('User ID field name'), | |||||
self::KEY_USERNAME_FIELD => pht('Username field name'), | |||||
self::KEY_REALNAME_FIELD => pht('Real name field name'), | |||||
self::KEY_EMAIL_FIELD => pht('User email field name'), | |||||
self::KEY_PAGE_URI_PATTERN => pht('User page URI pattern'), | |||||
self::KEY_IMAGE_URI_PATTERN => pht('User image URI pattern'), | |||||
); | |||||
foreach ($labels as $key => $label) { | |||||
$caption = idx($captions, $key); | |||||
$value = idx($values, $key); | |||||
$control = null; | |||||
$control = id(new AphrontFormTextControl()) | |||||
->setName($key) | |||||
->setLabel($label) | |||||
->setCaption($caption) | |||||
->setValue($value); | |||||
$form->appendChild($control); | |||||
} | |||||
} | |||||
public function renderConfigPropertyTransactionTitle( | |||||
PhabricatorAuthProviderConfigTransaction $xaction) { | |||||
$author_phid = $xaction->getAuthorPHID(); | |||||
$old = $xaction->getOldValue(); | |||||
$new = $xaction->getNewValue(); | |||||
$key = $xaction->getMetadataValue( | |||||
PhabricatorAuthProviderConfigTransaction::PROPERTY_KEY); | |||||
$labels = $this->getPropertyLabels(); | |||||
if (isset($labels[$key])) { | |||||
$label = $labels[$key]; | |||||
if (!strlen($old)) { | |||||
return pht( | |||||
'%s set the "%s" value to "%s".', | |||||
$xaction->renderHandleLink($author_phid), | |||||
$label, | |||||
$new); | |||||
} else { | |||||
return pht( | |||||
'%s changed the "%s" value from "%s" to "%s".', | |||||
$xaction->renderHandleLink($author_phid), | |||||
$label, | |||||
$old, | |||||
$new); | |||||
} | |||||
} | |||||
return parent::renderConfigPropertyTransactionTitle($xaction); | |||||
} | |||||
public static function getShibbolethProvider() { | |||||
$providers = self::getAllEnabledProviders(); | |||||
foreach ($providers as $provider) { | |||||
if ($provider instanceof PhabricatorAuthProviderShibboleth) { | |||||
return $provider; | |||||
} | |||||
} | |||||
return null; | |||||
} | |||||
} |