Fixed some issues related to the plugin-store purchase query
authorAlexander Ebert <ebert@woltlab.com>
Mon, 15 Dec 2014 01:13:24 +0000 (02:13 +0100)
committerAlexander Ebert <ebert@woltlab.com>
Mon, 15 Dec 2014 01:13:24 +0000 (02:13 +0100)
wcfsetup/install/files/acp/js/WCF.ACP.js
wcfsetup/install/files/acp/templates/packageList.tpl
wcfsetup/install/files/lib/data/package/PackageAction.class.php
wcfsetup/install/files/lib/util/HTTPRequest.class.php
wcfsetup/install/lang/de.xml
wcfsetup/install/lang/en.xml

index 6ca0b951662acaf24e3fc3dc5ea7f90c1c92268b..ec3f849708375f56dbdce00a9d1d558ce0b43757 100644 (file)
@@ -1678,6 +1678,20 @@ WCF.ACP.PluginStore.PurchasedItems.Search = Class.extend({
                        this._dialog.html(data.returnValues.noResults);
                        this._dialog.wcfDialog('open');
                }
+               else if (data.returnValues.noSSL) {
+                       // PHP was compiled w/o OpenSSL support
+                       if (this._dialog === null) {
+                               this._dialog = $('<div />').hide().appendTo(document.body);
+                               this._dialog.html(data.returnValues.noSSL).wcfDialog({
+                                       title: WCF.Language.get('wcf.global.error.title')
+                               });
+                       }
+                       else {
+                               this._dialog.wcfDialog('option', 'title', WCF.Language.get('wcf.global.error.title'));
+                               this._dialog.html(data.returnValues.noSSL);
+                               this._dialog.wcfDialog('open');
+                       }
+               }
                else if (data.returnValues.redirectURL) {
                        // redirect to list of purchased products
                        window.location = data.returnValues.redirectURL;
index da4f0c01bf59170d6b578bcaf28415d0aeb917d3..85647d59edf80a93cac1db8ed81e6d77d4e04957 100644 (file)
@@ -27,7 +27,7 @@
                        new WCF.ACP.Package.Update.Search();
                {/if}
                
-               {if $__wcf->session->getPermission('admin.system.package.canUpdatePackage') && $__wcf->session->getPermission('admin.system.package.canUninstallPackage')}
+               {if $__wcf->session->getPermission('admin.system.package.canInstallPackage') && $__wcf->session->getPermission('admin.system.package.canUpdatePackage')}
                        new WCF.ACP.PluginStore.PurchasedItems.Search();
                {/if}
        });
index c3668d0bb6eab6f63b8b53fe3fec9642eade8a9d..70fd45f324b86ddbabda053e30c64b2fec29fc5c 100644 (file)
@@ -1,6 +1,7 @@
 <?php
 namespace wcf\data\package;
 use wcf\data\AbstractDatabaseObjectAction;
+use wcf\system\database\util\PreparedStatementConditionBuilder;
 use wcf\system\exception\SystemException;
 use wcf\system\request\LinkHandler;
 use wcf\system\WCF;
@@ -38,19 +39,32 @@ class PackageAction extends AbstractDatabaseObjectAction {
         */
        protected $permissionsUpdate = array('admin.system.package.canUpdatePackage');
        
+       /**
+        * @see \wcf\data\AbstractDatabaseObjectAction::$requireACP
+        */
+       protected $requireACP = array('searchForPurchasedItems');
+       
+       /**
+        * Validates parameters to search for purchased items in the WoltLab Plugin-Store.
+        */
        public function validateSearchForPurchasedItems() {
-               // TODO: validate permissions
+               WCF::getSession()->checkPermissions(array('admin.system.package.canInstallPackage', 'admin.system.package.canUpdatePackage'));
                
                $this->readString('password', true);
                $this->readString('username', true);
                
                if (empty($this->parameters['username'])) {
+                       $conditions = new PreparedStatementConditionBuilder();
+                       $conditions->add("serverURL IN (?)", array(array('http://store.woltlab.com/maelstrom/', 'http://store.woltlab.com/typhoon/')));
+                       $conditions->add("loginUsername <> ''");
+                       $conditions->add("loginPassword <> ''");
+                       
                        // check if user has already provided credentials
                        $sql = "SELECT  loginUsername, loginPassword
                                FROM    wcf".WCF_N."_package_update_server
-                               WHERE   serverURL = ?";
+                               ".$conditions;
                        $statement = WCF::getDB()->prepareStatement($sql, 1);
-                       $statement->execute(array('http://store.woltlab.com/typhoon/'));
+                       $statement->execute($conditions->getParameters());
                        $row = $statement->fetchArray();
                        if (!empty($row['loginUsername']) && !empty($row['loginPassword'])) {
                                $this->parameters['password'] = $row['loginPassword'];
@@ -59,14 +73,25 @@ class PackageAction extends AbstractDatabaseObjectAction {
                }
        }
        
+       /**
+        * Searches for purchased items in the WoltLab Plugin-Store.
+        * 
+        * @return array<string>
+        */
        public function searchForPurchasedItems() {
+               if (!HTTPRequest::supportSSL()) {
+                       return array(
+                               'noSSL' => WCF::getLanguage()->get('wcf.acp.pluginStore.api.noSSL')
+                       );
+               }
+               
                if (empty($this->parameters['username']) || empty($this->parameters['password'])) {
                        return array(
                                'template' => $this->renderAuthorizationDialog(false)
                        );
                }
                
-               $request = new HTTPRequest('https://www.woltlab.com/api/1.0/customer/purchases/list.json', array(
+               $request = new HTTPRequest('https://api.woltlab.com/1.0/customer/purchases/list.json', array(
                        'method' => 'POST'
                ), array(
                        'username' => $this->parameters['username'],
@@ -83,7 +108,7 @@ class PackageAction extends AbstractDatabaseObjectAction {
                        case 200:
                                if (empty($response['products'])) {
                                        return array(
-                                               'noResults' => WCF::getLanguage()->get('wcf.acp.pluginstore.purchasedItems.noResults')
+                                               'noResults' => WCF::getLanguage()->get('wcf.acp.pluginStore.purchasedItems.noResults')
                                        );
                                }
                                else {
@@ -105,11 +130,17 @@ class PackageAction extends AbstractDatabaseObjectAction {
                        
                        // any other kind of errors
                        default:
-                               throw new SystemException(WCF::getLanguage()->getDynamicVariable('wcf.acp.pluginstore.api.error', array('status' => $code)));
+                               throw new SystemException(WCF::getLanguage()->getDynamicVariable('wcf.acp.pluginStore.api.error', array('status' => $code)));
                        break;
                }
        }
        
+       /**
+        * Renders the authentication dialog.
+        * 
+        * @param       boolean         $rejected
+        * @return      string
+        */
        protected function renderAuthorizationDialog($rejected) {
                WCF::getTPL()->assign(array(
                        'rejected' => $rejected
index 867eb942bd7819b34717bab9ec78935c2e220ab6..c1a02bfc283dda5083f5a25e19a3c24c48467d81 100644 (file)
@@ -128,6 +128,12 @@ final class HTTPRequest {
         */
        private $statusCode = 0;
        
+       /**
+        * true if PHP supports SSL/TLS
+        * @var boolean
+        */
+       private static $hasSSLSupport = null;
+       
        /**
         * Constructs a new instance of HTTPRequest.
         * 
@@ -601,4 +607,25 @@ final class HTTPRequest {
                $this->replyBody = '';
                $this->statusCode = 0;
        }
+       
+       /**
+        * Returns true if PHP supports SSL/TLS.
+        * 
+        * @return      boolean
+        */
+       public static function supportSSL() {
+               if (static::$hasSSLSupport === null) {
+                       static::$hasSSLSupport = false;
+                       
+                       $transports = stream_get_transports();
+                       foreach ($transports as $transport) {
+                               if (preg_match('~^(ssl(v[23])?|tls(v[0-9\.]+)?)$~', $transport)) {
+                                       static::$hasSSLSupport = true;
+                                       break;
+                               }
+                       }
+               }
+               
+               return static::$hasSSLSupport;
+       }
 }
index f0da942c7e5457d836df1f6114065d2dd41a0060..fbcc1c84f658e62e315bec9db13ddb11763bb4f0 100644 (file)
@@ -1254,15 +1254,16 @@ GmbH=Gesellschaft mit beschränkter Haftung]]></item>
        
        <category name="wcf.acp.pluginStore">
                <item name="wcf.acp.pluginStore.api.error"><![CDATA[Fehler {@$status}: Der Server konnte die Anfrage nicht erfolgreich bearbeiten.]]></item>
+               <item name="wcf.acp.pluginStore.api.noSSL"><![CDATA[Die Abfrage der erworbenen Produkte aus dem Plugin-Store kann nur über eine sichere Verbindung erfolgen.<br /><br />Ihre PHP-Version wurde ohne Unterstützung für OpenSSL kompiliert und kann daher keine sicheren Verbindungen aufbauen, bitte wenden Sie sich an Ihren Anbieter oder System-Administrator um diesen Umstand zu korrigieren.]]></item>
                <item name="wcf.acp.pluginStore.authorization"><![CDATA[Autorisierung erforderlich]]></item>
                <item name="wcf.acp.pluginStore.authorization.credentials"><![CDATA[Zugangsdaten]]></item>
-               <item name="wcf.acp.pluginStore.authorization.credentials.description"><![CDATA[Geben Sie bitte Benutzername und Passwort für Ihr WoltLab.com-Benutzerkonto an.]]></item>
+               <item name="wcf.acp.pluginStore.authorization.credentials.description"><![CDATA[Bitte geben Sie Benutzername und Passwort für Ihr WoltLab.com-Benutzerkonto ein.]]></item>
                <item name="wcf.acp.pluginStore.authorization.credentials.rejected"><![CDATA[Ihre Zugangsdaten wurden vom Server abgewiesen, bitte überprüfen Sie Benutzername und Passwort!]]></item>
                <item name="wcf.acp.pluginStore.authorization.username"><![CDATA[Benutzername]]></item>
                <item name="wcf.acp.pluginStore.authorization.password"><![CDATA[Password]]></item>
                <item name="wcf.acp.pluginStore.authorization.saveCredentials"><![CDATA[Zugangsdaten für aktuelle Sitzung speichern]]></item>
-               <item name="wcf.acp.pluginStore.purchasedItems.button.search"><![CDATA[Gekaufte Produkte (Plugin-Store)]]></item>
-               <item name="wcf.acp.pluginStore.purchasedItems"><![CDATA[Gekaufte Produkte (Plugin-Store)]]></item>
+               <item name="wcf.acp.pluginStore.purchasedItems.button.search"><![CDATA[Erworbene Produkte (Plugin-Store)]]></item>
+               <item name="wcf.acp.pluginStore.purchasedItems"><![CDATA[Erworbene Produkte (Plugin-Store)]]></item>
                <item name="wcf.acp.pluginStore.purchasedItems.noResults"><![CDATA[Die Suche ergab keine Treffer, entweder haben Sie noch keine Produkte erworben oder diese sind nicht kompatibel.]]></item>
                <item name="wcf.acp.pluginStore.purchasedItems.status.update"><![CDATA[Neuere Version verfügbar]]></item>
                <item name="wcf.acp.pluginStore.purchasedItems.status.unavailable"><![CDATA[Paket-Server nicht installiert]]></item>
index 59da981e6759559400256b0d8a14a0d59fa63caa..b8e6ed6c410706ea441f54a95c5c3b64dc78afb1 100644 (file)
@@ -1253,6 +1253,7 @@ GmbH=Gesellschaft mit beschränkter Haftung]]></item>
        
        <category name="wcf.acp.pluginStore">
                <item name="wcf.acp.pluginStore.api.error"><![CDATA[Error {@$status}: The server was unable to process your request.]]></item>
+               <item name="wcf.acp.pluginStore.api.noSSL"><![CDATA[Querying the Plugin-Store to fetch the purchased products requires a secure connection.<br /><br />Your PHP version has been compiled without OpenSSL support required to establish secure connections, please contact your hosting company or system-administrator to resolve this shortcoming.]]></item>
                <item name="wcf.acp.pluginStore.authorization"><![CDATA[Authorization Required]]></item>
                <item name="wcf.acp.pluginStore.authorization.credentials"><![CDATA[Credentials]]></item>
                <item name="wcf.acp.pluginStore.authorization.credentials.description"><![CDATA[Please enter your WoltLab.com username and password.]]></item>