diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a3c86cc --- /dev/null +++ b/.gitignore @@ -0,0 +1,89 @@ +# Created by .ignore support plugin (hsz.mobi) +### OSX template +*.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk +### Vagrant template +.vagrant/ +### Vim template +# swap +[._]*.s[a-w][a-z] +[._]s[a-w][a-z] +# session +Session.vim +# temporary +.netrwhist +*~ +# auto-generated tag files +tags +### LibreOffice template +# LibreOffice locks +.~lock.*# +### JetBrains template +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff: +.idea/workspace.xml +.idea/tasks.xml +.idea/dictionaries +.idea/vcs.xml +.idea/jsLibraryMappings.xml + +# Sensitive or high-churn files: +.idea/dataSources.ids +.idea/dataSources.xml +.idea/dataSources.local.xml +.idea/sqlDataSources.xml +.idea/dynamic.xml +.idea/uiDesigner.xml + +# Gradle: +.idea/gradle.xml +.idea/libraries + +# Mongo Explorer plugin: +.idea/mongoSettings.xml + +## File-based project format: +*.iws + +## Plugin-specific files: + +# IntelliJ +/out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + diff --git a/Classes/Controller/SsoController.php b/Classes/Controller/SsoController.php index 46d37af..c46dae0 100644 --- a/Classes/Controller/SsoController.php +++ b/Classes/Controller/SsoController.php @@ -26,70 +26,132 @@ namespace Jahnke\DiscourseSso\Controller; ***************************************************************/ use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Extbase\Mvc\Controller\ActionController; +use \TYPO3\CMS\Extensionmanager\Utility\ConfigurationUtility; /** * Controller for the Member object - * - * @version $Id$ - * @copyright Copyright belongs to the respective authors - * @license http://www.gnu.org/licenses/gpl.html GNU General Public License, version 3 or later */ -class SsoController extends \TYPO3\CMS\Scheduler\Task\AbstractTask +class SsoController extends ActionController { - private function hashs_are_equal($data, $sig) { - if (!$data || !$sig || !is_string($data) || !is_string($sig)) - return false; - if (strlen($data) != strlen($sig)) - return false; - if (strcmp($data, $sig) === 0) - return true; - return false; - } + /** + * Compare if signed data matches given signature. + * + * @param string $data Signed data to be compared with. + * @param string $sig Signature to be compared with. + * + * @return boolean */ - public function authenticateAction() { - $user = NULL; - if (isset($GLOBALS['TSFE']) && isset($GLOBALS['TSFE']->fe_user) && isset($GLOBALS['TSFE']->fe_user->user)) { - $user = $GLOBALS['TSFE']->fe_user->user; + private function _hashsAreEqual($data, $sig) + { + if ($data === null || $sig === null || is_string($data) === false || is_string($sig) === false) { + return false; } - if (isset($user)) { - $sso = urldecode(GeneralUtility::_GP('sso')); - $sig = GeneralUtility::_GP('sig'); - $userId = $user['uid']; - $userEmail = $user['email']; - $userName = $user['username']; - $name = $user['name']; + if (strlen($data) !== strlen($sig)) { + return false; + } - if (!$this->hashs_are_equal(hash_hmac('sha256', $sso, $this->settings['discourse_sso_shared_key']), $sig)) { - header("HTTP/1.1 403 Forbidden"); - $this->throwStatus(403, "Bad SSO request"); - } else { - // valid $sso string available, convert it - parse_str(base64_decode($sso), $receivedPayload); - $nonce = $receivedPayload['nonce']; - $parameters = array( - 'nonce' => $nonce, - 'external_id' => $userId, - 'email' => $userEmail, - 'username' => $userName, - 'name' => $name - ); - $payload = base64_encode(http_build_query($parameters)); - $query = http_build_query(array('sso' => $payload, 'sig' => hash_hmac('sha256', $payload, $this->settings['discourse_sso_shared_key']))); - $statusCode = $this->settings['discourse_sso_redirect_statuscode']; - if (!$statusCode || ($statusCode < 300 || $statusCode > 308)) { - // set default: - $statusCode = 303; - } - $this->redirectToUri($this->settings['discourse_sso_redirect'] . '/session/sso_login?' . $query, 0, 302); - } + if (strcmp($data, $sig) === 0) { + return true; + } + + return false; + + }//end _hashsAreEqual() + + + /** + * Authenticate action. + * + * @return string + */ + public function authenticateAction() + { + /** @var \TYPO3\CMS\Extensionmanager\Utility\ConfigurationUtility $configurationUtility */ + $configurationUtility = $this->objectManager->get(\TYPO3\CMS\Extensionmanager\Utility\ConfigurationUtility::class); + $extensionConfiguration = $configurationUtility->getCurrentConfiguration('tx_dj_discourse_sso'); + + // Check mandatory settings. + if (isset($extensionConfiguration['redirect_url']) === false) { + $errorText = '