diff options
author | Lukas Reschke <lukas@owncloud.com> | 2015-04-09 10:07:32 +0200 |
---|---|---|
committer | Lukas Reschke <lukas@owncloud.com> | 2015-04-09 10:07:32 +0200 |
commit | ba52f6f8fc0d88000332e9e64c48a56c526823d9 (patch) | |
tree | 3aa8f934e0d0183e1a842c4163f83dac887bed96 /lib | |
parent | 56f1ffe820383ac82c208552213848c6a8deec6d (diff) | |
parent | 98698e05e86a85e3f9aa813c314c3ed6739fbb43 (diff) | |
download | nextcloud-server-ba52f6f8fc0d88000332e9e64c48a56c526823d9.tar.gz nextcloud-server-ba52f6f8fc0d88000332e9e64c48a56c526823d9.zip |
Merge pull request #15314 from owncloud/app-categories-15274
Add different trust levels to AppStore interface
Diffstat (limited to 'lib')
-rw-r--r-- | lib/private/app.php | 110 | ||||
-rw-r--r-- | lib/private/app/appmanager.php | 2 | ||||
-rw-r--r-- | lib/private/installer.php | 17 | ||||
-rw-r--r-- | lib/private/ocsclient.php | 263 | ||||
-rw-r--r-- | lib/private/server.php | 14 | ||||
-rw-r--r-- | lib/private/templatelayout.php | 2 | ||||
-rw-r--r-- | lib/public/app/iappmanager.php | 5 |
7 files changed, 249 insertions, 164 deletions
diff --git a/lib/private/app.php b/lib/private/app.php index 4b3d4b82b82..aec67e6efd6 100644 --- a/lib/private/app.php +++ b/lib/private/app.php @@ -61,6 +61,7 @@ class OC_App { static private $loadedApps = array(); static private $altLogin = array(); private static $shippedApps = null; + const officialApp = 200; /** * clean the appId @@ -306,8 +307,13 @@ class OC_App { * @return int */ public static function downloadApp($app) { - $appData= OCSClient::getApplication($app); - $download= OCSClient::getApplicationDownload($app, 1); + $ocsClient = new OCSClient( + \OC::$server->getHTTPClientService(), + \OC::$server->getConfig(), + \OC::$server->getLogger() + ); + $appData = $ocsClient->getApplication($app); + $download= $ocsClient->getApplicationDownload($app); if(isset($download['downloadlink']) and $download['downloadlink']!='') { // Replace spaces in download link without encoding entire URL $download['downloadlink'] = str_replace(' ', '%20', $download['downloadlink']); @@ -507,7 +513,7 @@ class OC_App { /** * search for an app in all app-directories * - * @param $appId + * @param string $appId * @return mixed (bool|string) */ protected static function findAppInDirectories($appId) { @@ -726,6 +732,8 @@ class OC_App { /** * register a personal form to be shown + * @param string $app + * @param string $page */ public static function registerPersonal($app, $page) { self::$personalForms[] = $app . '/' . $page . '.php'; @@ -780,8 +788,9 @@ class OC_App { } /** - * Lists all apps, this is used in apps.php + * List all apps, this is used in apps.php * + * @param bool $onlyLocal * @return array */ public static function listAllApps($onlyLocal = false) { @@ -819,8 +828,7 @@ class OC_App { if (isset($info['shipped']) and ($info['shipped'] == 'true')) { $info['internal'] = true; - $info['internallabel'] = (string)$l->t('Recommended'); - $info['internalclass'] = 'recommendedapp'; + $info['level'] = self::officialApp; $info['removable'] = false; } else { $info['internal'] = false; @@ -845,7 +853,7 @@ class OC_App { } } if ($onlyLocal) { - $remoteApps = array(); + $remoteApps = []; } else { $remoteApps = OC_App::getAppstoreApps(); } @@ -865,34 +873,6 @@ class OC_App { } else { $combinedApps = $appList; } - // bring the apps into the right order with a custom sort function - usort($combinedApps, function ($a, $b) { - - // priority 1: active - if ($a['active'] != $b['active']) { - return $b['active'] - $a['active']; - } - - // priority 2: shipped - $aShipped = (array_key_exists('shipped', $a) && $a['shipped'] === 'true') ? 1 : 0; - $bShipped = (array_key_exists('shipped', $b) && $b['shipped'] === 'true') ? 1 : 0; - if ($aShipped !== $bShipped) { - return ($bShipped - $aShipped); - } - - // priority 3: recommended - $internalClassA = isset($a['internalclass']) ? $a['internalclass'] : ''; - $internalClassB = isset($b['internalclass']) ? $b['internalclass'] : ''; - if ($internalClassA != $internalClassB) { - $aTemp = ($internalClassA == 'recommendedapp' ? 1 : 0); - $bTemp = ($internalClassB == 'recommendedapp' ? 1 : 0); - return ($bTemp - $aTemp); - } - - // priority 4: alphabetical - return strcasecmp($a['name'], $b['name']); - - }); return $combinedApps; } @@ -913,15 +893,24 @@ class OC_App { } /** - * get a list of all apps on apps.owncloud.com - * - * @return array|false multi-dimensional array of apps. - * Keys: id, name, type, typename, personid, license, detailpage, preview, changed, description + * Get a list of all apps on the appstore + * @param string $filter + * @param string $category + * @return array|bool multi-dimensional array of apps. + * Keys: id, name, type, typename, personid, license, detailpage, preview, changed, description */ public static function getAppstoreApps($filter = 'approved', $category = null) { - $categories = array($category); + $categories = [$category]; + + $ocsClient = new OCSClient( + \OC::$server->getHTTPClientService(), + \OC::$server->getConfig(), + \OC::$server->getLogger() + ); + + if (is_null($category)) { - $categoryNames = OCSClient::getCategories(); + $categoryNames = $ocsClient->getCategories(); if (is_array($categoryNames)) { // Check that categories of apps were retrieved correctly if (!$categories = array_keys($categoryNames)) { @@ -933,34 +922,36 @@ class OC_App { } $page = 0; - $remoteApps = OCSClient::getApplications($categories, $page, $filter); - $app1 = array(); + $remoteApps = $ocsClient->getApplications($categories, $page, $filter); + $apps = []; $i = 0; $l = \OC::$server->getL10N('core'); foreach ($remoteApps as $app) { $potentialCleanId = self::getInternalAppIdByOcs($app['id']); // enhance app info (for example the description) - $app1[$i] = OC_App::parseAppInfo($app); - $app1[$i]['author'] = $app['personid']; - $app1[$i]['ocs_id'] = $app['id']; - $app1[$i]['internal'] = 0; - $app1[$i]['active'] = ($potentialCleanId !== false) ? self::isEnabled($potentialCleanId) : false; - $app1[$i]['update'] = false; - $app1[$i]['groups'] = false; - $app1[$i]['score'] = $app['score']; - $app1[$i]['removable'] = false; + $apps[$i] = OC_App::parseAppInfo($app); + $apps[$i]['author'] = $app['personid']; + $apps[$i]['ocs_id'] = $app['id']; + $apps[$i]['internal'] = 0; + $apps[$i]['active'] = ($potentialCleanId !== false) ? self::isEnabled($potentialCleanId) : false; + $apps[$i]['update'] = false; + $apps[$i]['groups'] = false; + $apps[$i]['score'] = $app['score']; + $apps[$i]['removable'] = false; if ($app['label'] == 'recommended') { - $app1[$i]['internallabel'] = (string)$l->t('Recommended'); - $app1[$i]['internalclass'] = 'recommendedapp'; + $apps[$i]['internallabel'] = (string)$l->t('Recommended'); + $apps[$i]['internalclass'] = 'recommendedapp'; } $i++; } - if (empty($app1)) { + + + if (empty($apps)) { return false; } else { - return $app1; + return $apps; } } @@ -1084,7 +1075,12 @@ class OC_App { public static function installApp($app) { $l = \OC::$server->getL10N('core'); $config = \OC::$server->getConfig(); - $appData=OCSClient::getApplication($app); + $ocsClient = new OCSClient( + \OC::$server->getHTTPClientService(), + $config, + \OC::$server->getLogger() + ); + $appData = $ocsClient->getApplication($app); // check if app is a shipped app or not. OCS apps have an integer as id, shipped apps use a string if (!is_numeric($app)) { diff --git a/lib/private/app/appmanager.php b/lib/private/app/appmanager.php index 2a147d4de6f..c9d4a777c4a 100644 --- a/lib/private/app/appmanager.php +++ b/lib/private/app/appmanager.php @@ -203,7 +203,7 @@ class AppManager implements IAppManager { /** * Clear the cached list of apps when enabling/disabling an app */ - protected function clearAppsCache() { + public function clearAppsCache() { $settingsMemCache = $this->memCacheFactory->create('settings'); $settingsMemCache->clear('listApps'); } diff --git a/lib/private/installer.php b/lib/private/installer.php index e30344b1b10..41f13f0f5f9 100644 --- a/lib/private/installer.php +++ b/lib/private/installer.php @@ -222,8 +222,13 @@ class OC_Installer{ * @throws Exception */ public static function updateAppByOCSId($ocsId) { - $appData = OCSClient::getApplication($ocsId); - $download = OCSClient::getApplicationDownload($ocsId, 1); + $ocsClient = new OCSClient( + \OC::$server->getHTTPClientService(), + \OC::$server->getConfig(), + \OC::$server->getLogger() + ); + $appData = $ocsClient->getApplication($ocsId); + $download = $ocsClient->getApplicationDownload($ocsId); if (isset($download['downloadlink']) && trim($download['downloadlink']) !== '') { $download['downloadlink'] = str_replace(' ', '%20', $download['downloadlink']); @@ -385,8 +390,12 @@ class OC_Installer{ $ocsid=OC_Appconfig::getValue( $app, 'ocsid', ''); if($ocsid<>'') { - - $ocsdata=OCSClient::getApplication($ocsid); + $ocsClient = new OCSClient( + \OC::$server->getHTTPClientService(), + \OC::$server->getConfig(), + \OC::$server->getLogger() + ); + $ocsdata = $ocsClient->getApplication($ocsid); $ocsversion= (string) $ocsdata['version']; $currentversion=OC_App::getAppVersion($app); if (version_compare($ocsversion, $currentversion, '>')) { diff --git a/lib/private/ocsclient.php b/lib/private/ocsclient.php index f69426ddafe..84469cb5e0d 100644 --- a/lib/private/ocsclient.php +++ b/lib/private/ocsclient.php @@ -32,36 +32,75 @@ namespace OC; +use OCP\Http\Client\IClientService; +use OCP\IConfig; +use OCP\ILogger; + /** - * This class provides an easy way for apps to store config values in the - * database. + * Class OCSClient is a class for communication with the ownCloud appstore + * + * @package OC */ - class OCSClient { + /** @var IClientService */ + private $httpClientService; + /** @var IConfig */ + private $config; + /** @var ILogger */ + private $logger; + + /** + * @param IClientService $httpClientService + * @param IConfig $config + * @param ILogger $logger + */ + public function __construct(IClientService $httpClientService, + IConfig $config, + ILogger $logger) { + $this->httpClientService = $httpClientService; + $this->config = $config; + $this->logger = $logger; + } /** * Returns whether the AppStore is enabled (i.e. because the AppStore is disabled for EE) * * @return bool */ - public static function isAppStoreEnabled() { - if (\OC::$server->getConfig()->getSystemValue('appstoreenabled', true) === false ) { - return false; - } - - return true; + public function isAppStoreEnabled() { + return $this->config->getSystemValue('appstoreenabled', true) === true; } /** * Get the url of the OCS AppStore server. * * @return string of the AppStore server - * - * This function returns the url of the OCS AppStore server. It´s possible - * to set it in the config file or it will fallback to the default */ - private static function getAppStoreURL() { - return \OC::$server->getConfig()->getSystemValue('appstoreurl', 'https://api.owncloud.com/v1'); + private function getAppStoreUrl() { + return $this->config->getSystemValue('appstoreurl', 'https://api.owncloud.com/v1'); + } + + /** + * @param string $body + * @param string $action + * @return null|\SimpleXMLElement + */ + private function loadData($body, $action) { + $loadEntities = libxml_disable_entity_loader(true); + $data = @simplexml_load_string($body); + libxml_disable_entity_loader($loadEntities); + + if($data === false) { + $this->logger->error( + sprintf('Could not get %s, content was no valid XML', $action), + [ + 'app' => 'core', + ] + ); + return null; + } + + return $data; } /** @@ -71,36 +110,41 @@ class OCSClient { * @note returns NULL if config value appstoreenabled is set to false * This function returns a list of all the application categories on the OCS server */ - public static function getCategories() { - if (!self::isAppStoreEnabled()) { + public function getCategories() { + if (!$this->isAppStoreEnabled()) { return null; } - $url = self::getAppStoreURL() . '/content/categories'; - $client = \OC::$server->getHTTPClientService()->newClient(); + $client = $this->httpClientService->newClient(); try { - $response = $client->get($url, ['timeout' => 5]); + $response = $client->get( + $this->getAppStoreUrl() . '/content/categories', + [ + 'timeout' => 5, + ] + ); } catch(\Exception $e) { + $this->logger->error( + sprintf('Could not get categories: %s', $e->getMessage()), + [ + 'app' => 'core', + ] + ); return null; } - if($response->getStatusCode() !== 200) { + $data = $this->loadData($response->getBody(), 'categories'); + if($data === null) { return null; } - $loadEntities = libxml_disable_entity_loader(true); - $data = simplexml_load_string($response->getBody()); - libxml_disable_entity_loader($loadEntities); - $tmp = $data->data; $cats = []; foreach ($tmp->category as $value) { - $id = (int)$value->id; $name = (string)$value->name; $cats[$id] = $name; - } return $cats; @@ -108,50 +152,54 @@ class OCSClient { /** * Get all the applications from the OCS server - * - * @return array|null an array of application data or null - * - * This function returns a list of all the applications on the OCS server - * @param array|string $categories + * @param array $categories * @param int $page * @param string $filter + * @return array An array of application data */ - public static function getApplications($categories, $page, $filter) { - if (!self::isAppStoreEnabled()) { - return (array()); + public function getApplications(array $categories, $page, $filter) { + if (!$this->isAppStoreEnabled()) { + return []; } - if (is_array($categories)) { - $categoriesString = implode('x', $categories); - } else { - $categoriesString = $categories; - } - - $version = '&version=' . implode('x', \OC_Util::getVersion()); - $filterUrl = '&filter=' . urlencode($filter); - $url = self::getAppStoreURL() . '/content/data?categories=' . urlencode($categoriesString) - . '&sortmode=new&page=' . urlencode($page) . '&pagesize=100' . $filterUrl . $version; - $apps = []; - - $client = \OC::$server->getHTTPClientService()->newClient(); + $client = $this->httpClientService->newClient(); try { - $response = $client->get($url, ['timeout' => 5]); + $response = $client->get( + $this->getAppStoreUrl() . '/content/data', + [ + 'timeout' => 5, + 'query' => [ + 'version' => implode('x', \OC_Util::getVersion()), + 'filter' => $filter, + 'categories' => implode('x', $categories), + 'sortmode' => 'new', + 'page' => $page, + 'pagesize' => 100, + 'approved' => $filter + ], + ] + ); } catch(\Exception $e) { - return null; + $this->logger->error( + sprintf('Could not get applications: %s', $e->getMessage()), + [ + 'app' => 'core', + ] + ); + return []; } - if($response->getStatusCode() !== 200) { - return null; + $data = $this->loadData($response->getBody(), 'applications'); + if($data === null) { + return []; } - $loadEntities = libxml_disable_entity_loader(true); - $data = simplexml_load_string($response->getBody()); - libxml_disable_entity_loader($loadEntities); - $tmp = $data->data->content; $tmpCount = count($tmp); + + $apps = []; for ($i = 0; $i < $tmpCount; $i++) { - $app = array(); + $app = []; $app['id'] = (string)$tmp[$i]->id; $app['name'] = (string)$tmp[$i]->name; $app['label'] = (string)$tmp[$i]->label; @@ -159,6 +207,7 @@ class OCSClient { $app['type'] = (string)$tmp[$i]->typeid; $app['typename'] = (string)$tmp[$i]->typename; $app['personid'] = (string)$tmp[$i]->personid; + $app['profilepage'] = (string)$tmp[$i]->profilepage; $app['license'] = (string)$tmp[$i]->license; $app['detailpage'] = (string)$tmp[$i]->detailpage; $app['preview'] = (string)$tmp[$i]->smallpreviewpic1; @@ -167,9 +216,11 @@ class OCSClient { $app['description'] = (string)$tmp[$i]->description; $app['score'] = (string)$tmp[$i]->score; $app['downloads'] = (int)$tmp[$i]->downloads; + $app['level'] = (int)$tmp[$i]->approved; $apps[] = $app; } + return $apps; } @@ -182,84 +233,94 @@ class OCSClient { * * This function returns an applications from the OCS server */ - public static function getApplication($id) { - if (!self::isAppStoreEnabled()) { + public function getApplication($id) { + if (!$this->isAppStoreEnabled()) { return null; } - $url = self::getAppStoreURL() . '/content/data/' . urlencode($id); - $client = \OC::$server->getHTTPClientService()->newClient(); + + $client = $this->httpClientService->newClient(); try { - $response = $client->get($url, ['timeout' => 5]); + $response = $client->get( + $this->getAppStoreUrl() . '/content/data/' . urlencode($id), + [ + 'timeout' => 5, + ] + ); } catch(\Exception $e) { + $this->logger->error( + sprintf('Could not get application: %s', $e->getMessage()), + [ + 'app' => 'core', + ] + ); return null; } - if($response->getStatusCode() !== 200) { + $data = $this->loadData($response->getBody(), 'application'); + if($data === null) { return null; } - $loadEntities = libxml_disable_entity_loader(true); - $data = simplexml_load_string($response->getBody()); - libxml_disable_entity_loader($loadEntities); - $tmp = $data->data->content; - if (is_null($tmp)) { - \OC_Log::write('core', 'Invalid OCS content returned for app ' . $id, \OC_Log::FATAL); - return null; - } + $app = []; - $app['id'] = $tmp->id; - $app['name'] = $tmp->name; - $app['version'] = $tmp->version; - $app['type'] = $tmp->typeid; - $app['label'] = $tmp->label; - $app['typename'] = $tmp->typename; - $app['personid'] = $tmp->personid; - $app['detailpage'] = $tmp->detailpage; - $app['preview1'] = $tmp->smallpreviewpic1; - $app['preview2'] = $tmp->smallpreviewpic2; - $app['preview3'] = $tmp->smallpreviewpic3; + $app['id'] = (int)$tmp->id; + $app['name'] = (string)$tmp->name; + $app['version'] = (string)$tmp->version; + $app['type'] = (string)$tmp->typeid; + $app['label'] = (string)$tmp->label; + $app['typename'] = (string)$tmp->typename; + $app['personid'] = (string)$tmp->personid; + $app['profilepage'] = (string)$tmp->profilepage; + $app['detailpage'] = (string)$tmp->detailpage; + $app['preview1'] = (string)$tmp->smallpreviewpic1; + $app['preview2'] = (string)$tmp->smallpreviewpic2; + $app['preview3'] = (string)$tmp->smallpreviewpic3; $app['changed'] = strtotime($tmp->changed); - $app['description'] = $tmp->description; - $app['detailpage'] = $tmp->detailpage; - $app['score'] = $tmp->score; + $app['description'] = (string)$tmp->description; + $app['detailpage'] = (string)$tmp->detailpage; + $app['score'] = (int)$tmp->score; return $app; } /** * Get the download url for an application from the OCS server - * + * @param $id * @return array|null an array of application data or null - * - * This function returns an download url for an applications from the OCS server - * @param string $id - * @param integer $item */ - public static function getApplicationDownload($id, $item) { - if (!self::isAppStoreEnabled()) { + public function getApplicationDownload($id) { + if (!$this->isAppStoreEnabled()) { return null; } - $url = self::getAppStoreURL() . '/content/download/' . urlencode($id) . '/' . urlencode($item); - $client = \OC::$server->getHTTPClientService()->newClient(); + $url = $this->getAppStoreUrl() . '/content/download/' . urlencode($id) . '/1'; + $client = $this->httpClientService->newClient(); try { - $response = $client->get($url, ['timeout' => 5]); + $response = $client->get( + $url, + [ + 'timeout' => 5, + ] + ); } catch(\Exception $e) { + $this->logger->error( + sprintf('Could not get application download URL: %s', $e->getMessage()), + [ + 'app' => 'core', + ] + ); return null; } - if($response->getStatusCode() !== 200) { + $data = $this->loadData($response->getBody(), 'application download URL'); + if($data === null) { return null; } - $loadEntities = libxml_disable_entity_loader(true); - $data = simplexml_load_string($response->getBody()); - libxml_disable_entity_loader($loadEntities); - $tmp = $data->data->content; - $app = array(); + $app = []; if (isset($tmp->downloadlink)) { - $app['downloadlink'] = $tmp->downloadlink; + $app['downloadlink'] = (string)$tmp->downloadlink; } else { $app['downloadlink'] = ''; } diff --git a/lib/private/server.php b/lib/private/server.php index 6b35998afa8..6df7722973e 100644 --- a/lib/private/server.php +++ b/lib/private/server.php @@ -400,6 +400,13 @@ class Server extends SimpleContainer implements IServerContainer { new \OC_Defaults() ); }); + $this->registerService('OcsClient', function(Server $c) { + return new OCSClient( + $this->getHTTPClientService(), + $this->getConfig(), + $this->getLogger() + ); + }); } /** @@ -841,6 +848,13 @@ class Server extends SimpleContainer implements IServerContainer { } /** + * @return \OC\OCSClient + */ + public function getOcsClient() { + return $this->query('OcsClient'); + } + + /** * @return \OCP\IDateTimeZone */ public function getDateTimeZone() { diff --git a/lib/private/templatelayout.php b/lib/private/templatelayout.php index ee1412fba74..448276ca7fe 100644 --- a/lib/private/templatelayout.php +++ b/lib/private/templatelayout.php @@ -107,7 +107,7 @@ class OC_TemplateLayout extends OC_Template { $userDisplayName = OC_User::getDisplayName(); $this->assign('user_displayname', $userDisplayName); $this->assign('user_uid', OC_User::getUser()); - $this->assign('appsmanagement_active', strpos(\OC::$server->getRequest()->getRequestUri(), OC_Helper::linkToRoute('settings_apps')) === 0 ); + $this->assign('appsmanagement_active', strpos(\OC::$server->getRequest()->getRequestUri(), \OC::$server->getURLGenerator()->linkToRoute('settings.AppSettings.viewApps')) === 0 ); $this->assign('enableAvatars', $this->config->getSystemValue('enable_avatars', true)); $this->assign('userAvatarSet', \OC_Helper::userAvatarSet(OC_User::getUser())); } else if ($renderAs == 'error') { diff --git a/lib/public/app/iappmanager.php b/lib/public/app/iappmanager.php index f50a7f64174..69b8c335d67 100644 --- a/lib/public/app/iappmanager.php +++ b/lib/public/app/iappmanager.php @@ -78,4 +78,9 @@ interface IAppManager { * @return string[] */ public function getInstalledApps(); + + /** + * Clear the cached list of apps when enabling/disabling an app + */ + public function clearAppsCache(); } |