[FEATURE] Override authentication information from URL
authorAndreas Wolf <andreas.wolf@typo3.org>
Tue, 24 Apr 2012 10:12:44 +0000 (12:12 +0200)
committerAndreas Wolf <andreas.wolf@typo3.org>
Tue, 24 Apr 2012 10:12:44 +0000 (12:12 +0200)
When saving a URL with authentication information, this information is
now extracted from the URL, saved into the accordant fields and removed
from the URL. This means that a password is never stored unencrypted,
plus users can copy and paste the URL and don't have to care about
manually doing extraction.

Classes/Backend/TceMainHook.php
Classes/Utility/UrlTools.php [new file with mode: 0644]
Tests/Backend/TceMainHookTest.php [new file with mode: 0644]
Tests/Utility/UrlToolsTest.php [new file with mode: 0644]

index e8e17ad..f12aeba 100644 (file)
@@ -11,12 +11,29 @@ class Tx_FalWebdav_Backend_TceMainHook {
                if ($table != 'sys_file_storage') {
                        return;
                }
+               if ($incomingFieldArray['configuration']['data']['sDEF']['lDEF']['driver']['vDEF'] != 'WebDav') {
+                       return;
+               }
+
+               $url = &$incomingFieldArray['configuration']['data']['sDEF']['lDEF']['baseUrl']['vDEF'];
+               $username = &$incomingFieldArray['configuration']['data']['sDEF']['lDEF']['username']['vDEF'];
+               $password = &$incomingFieldArray['configuration']['data']['sDEF']['lDEF']['password']['vDEF'];
+
+               list($cleanedUrl, $extractedUsername, $extractedPassword) = Tx_FalWebdav_Utility_UrlTools::extractUsernameAndPasswordFromUrl($url);
+               if ($cleanedUrl != $url) {
+                       $url = $cleanedUrl;
+               }
+                       // if we found authentication information in the URL, use it instead of the information currently stored
+               if ($extractedUsername != '') {
+                       $username = $extractedUsername;
+                       $password = $extractedPassword;
+               }
 
-               $currentValue = &$incomingFieldArray['configuration']['data']['sDEF']['lDEF']['password']['vDEF'];
                        // skip encryption if we have no password set or the password is already encrypted
-               if ($currentValue == '' || substr($currentValue, 0, 1) == '$') {
+               if ($password == '' || substr($password, 0, 1) == '$') {
                        return;
                }
-               $currentValue = Tx_FalWebdav_Utility_Encryption::encryptPassword($currentValue);
+               $password = Tx_FalWebdav_Utility_Encryption::encryptPassword($password);
        }
+
 }
diff --git a/Classes/Utility/UrlTools.php b/Classes/Utility/UrlTools.php
new file mode 100644 (file)
index 0000000..18f9247
--- /dev/null
@@ -0,0 +1,30 @@
+<?php
+
+/**
+ * Utility methods for encrypting/decrypting data. Currently only supports Blowfish encryption in CBC mode,
+ *
+ * @author Andreas Wolf <andreas.wolf@ikt-werk.de>
+ */
+class Tx_FalWebdav_Utility_UrlTools {
+       /**
+        * Helper method to extract the username and password from a url. Returns username, password and the url without
+        * authentication info.
+        *
+        * @param string
+        * @return array An array with the cleaned url, the username and the password as entries
+        */
+       public static function extractUsernameAndPasswordFromUrl($url) {
+               $urlInfo = parse_url($url);
+
+               $user = $pass = '';
+               if (isset($urlInfo['user'])) {
+                       $user = $urlInfo['user'];
+                       unset($urlInfo['user']);
+               }
+               if (isset($urlInfo['pass'])) {
+                       $pass = $urlInfo['pass'];
+                       unset($urlInfo['pass']);
+               }
+               return array(t3lib_utility_Http::buildUrl($urlInfo), $user, $pass);
+       }
+}
\ No newline at end of file
diff --git a/Tests/Backend/TceMainHookTest.php b/Tests/Backend/TceMainHookTest.php
new file mode 100644 (file)
index 0000000..aec2260
--- /dev/null
@@ -0,0 +1,96 @@
+<?php
+/*                                                                        *
+ * This script belongs to the TYPO3 project.                              *
+ *                                                                        *
+ * It is free software; you can redistribute it and/or modify it under    *
+ * the terms of the GNU General Public License as published by the Free   *
+ * Software Foundation, either version 2 of the License, or (at your      *
+ * option) any later version.                                             *
+ *                                                                        *
+ * This script is distributed in the hope that it will be useful, but     *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN-    *
+ * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General      *
+ * Public License for more details.                                       *
+ *                                                                        *
+ * You should have received a copy of the GNU General Public License      *
+ * along with the script.                                                 *
+ * If not, see http://www.gnu.org/licenses/gpl.html                       *
+ *                                                                        *
+ * The TYPO3 project - inspiring people to share!                         *
+ *                                                                        */
+
+/**
+ * Testcase for the WebDAV driver configuration TCEmain hook.
+ *
+ * @author Andreas Wolf <andreas.wolf@ikt-werk.de>
+ * @package TYPO3
+ * @subpackage fal_webdav
+ */
+class Tx_FalWebdav_Backend_TceMainHookTest extends Tx_Phpunit_TestCase {
+
+       /**
+        * @var Tx_FalWebdav_Backend_TceMainHook
+        */
+       protected $fixture;
+
+       public function setUp() {
+               $this->fixture = new Tx_FalWebdav_Backend_TceMainHook();
+       }
+
+       protected function prepareFieldArrayFixture(array $fieldValues) {
+               $fieldArray = array(
+                       'configuration' => array(
+                               'data' => array(
+                                       'sDEF' => array(
+                                               'lDEF' => array(
+                                                               // preset the driver as the TCEmain hook checks this
+                                                       'driver' => array(
+                                                               'vDEF' => 'WebDav'
+                                                       )
+                                               )
+                                       )
+                               )
+                       )
+               );
+
+               foreach ($fieldValues as $field => $value) {
+                       $fieldArray['configuration']['data']['sDEF']['lDEF'][$field] = array(
+                               'vDEF' => $value
+                       );
+               }
+               return $fieldArray;
+       }
+
+       /**
+        * @test
+        */
+       public function usernameAndPasswordFromUrlOverrideSetValuesInConfigurationFields() {
+               $fieldArray = $this->prepareFieldArrayFixture(array(
+                       'baseUrl' => 'http://newUser:newPass@localhost/some/storage/',
+                       'username' => 'oldUser',
+                       'password' => 'oldPassword'
+               ));
+
+               $this->fixture->processDatamap_preProcessFieldArray($fieldArray, 'sys_file_storage', -1, new StdClass());
+
+               $this->assertEquals('newUser', $fieldArray['configuration']['data']['sDEF']['lDEF']['username']['vDEF']);
+               $this->assertEquals('newPass', Tx_FalWebdav_Utility_Encryption::decryptPassword($fieldArray['configuration']['data']['sDEF']['lDEF']['password']['vDEF']));
+               $this->assertEquals('http://localhost/some/storage/', $fieldArray['configuration']['data']['sDEF']['lDEF']['baseUrl']['vDEF']);
+       }
+
+       /**
+        * @test
+        */
+       public function usernameAndPasswordInConfigurationFieldsAreLeftUnchangedIfNoAuthenticationInfoIsGivenInUrl() {
+               $fieldArray = $this->prepareFieldArrayFixture(array(
+                       'baseUrl' => 'http://localhost/some/storage/',
+                       'username' => 'oldUser',
+                       'password' => 'oldPassword'
+               ));
+
+               $this->fixture->processDatamap_preProcessFieldArray($fieldArray, 'sys_file_storage', -1, new StdClass());
+
+               $this->assertEquals('oldUser', $fieldArray['configuration']['data']['sDEF']['lDEF']['username']['vDEF']);
+               $this->assertEquals('oldPassword', Tx_FalWebdav_Utility_Encryption::decryptPassword($fieldArray['configuration']['data']['sDEF']['lDEF']['password']['vDEF']));
+       }
+}
diff --git a/Tests/Utility/UrlToolsTest.php b/Tests/Utility/UrlToolsTest.php
new file mode 100644 (file)
index 0000000..8295ee3
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+/**
+ * Testcase for the url tools class
+ *
+ * @author Andreas Wolf <andreas.wolf@ikt-werk.de>
+ */
+class Tx_FalWebdav_Utility_UrlToolsTest extends Tx_Phpunit_TestCase {
+
+       public function urlDataProvider() {
+               return array(
+                       'regular URL with username and password' => array(
+                               'http://someuser:somepass@localhost/test.php',
+                               array('http://localhost/test.php', 'someuser', 'somepass')
+                       ),
+                       'URL with just user' => array(
+                               'http://someuser@localhost/test.php',
+                               array('http://localhost/test.php', 'someuser', '')
+                       ),
+                       'HTTPS URL with username and password' => array(
+                               'https://someuser:somepass@localhost/test.php',
+                               array('https://localhost/test.php', 'someuser', 'somepass')
+                       ),
+                       'URL without authentication' => array(
+                               'http://localhost/test.php',
+                               array('http://localhost/test.php', '', '')
+                       )
+               );
+       }
+
+       /**
+        * @test
+        * @dataProvider urlDataProvider
+        */
+       public function usernameAndPasswordAreProperlyExtractedFromUrl($url, $expectedOutput) {
+               $output = Tx_FalWebdav_Utility_UrlTools::extractUsernameAndPasswordFromUrl($url);
+
+               $this->assertEquals($expectedOutput, $output);
+       }
+}