Skip to content
SitesManager.php 7.3 KiB
Newer Older
Pierre Ozoux's avatar
Pierre Ozoux committed
<?php
/**
 * @copyright Copyright (c) 2017 Joas Schilling <coding@schilljs.com>
 *
 * @license GNU AGPL version 3 or any later version
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

namespace OCA\IndieExternal;

use OCA\IndieExternal\Exceptions\GroupNotFoundException;
use OCA\IndieExternal\Exceptions\IconNotFoundException;
use OCA\IndieExternal\Exceptions\InvalidDeviceException;
use OCA\IndieExternal\Exceptions\InvalidNameException;
use OCA\IndieExternal\Exceptions\InvalidTypeException;
use OCA\IndieExternal\Exceptions\InvalidURLException;
use OCA\IndieExternal\Exceptions\LanguageNotFoundException;
use OCA\IndieExternal\Exceptions\SiteNotFoundException;
use OCP\App\IAppManager;
use OCP\Files\IAppData;
use OCP\Files\NotFoundException;
use OCP\Files\SimpleFS\ISimpleFile;
use OCP\IConfig;
use OCP\IGroupManager;
use OCP\IRequest;
use OCP\IUser;
use OCP\IUserSession;
use OCP\L10N\IFactory;

class SitesManager {

	const TYPE_LINK = 'link';
	const TYPE_SETTING = 'settings';
	const TYPE_LOGIN = 'guest';
	const TYPE_QUOTA = 'quota';

	const DEVICE_ALL = '';
	const DEVICE_ANDROID = 'android';
	const DEVICE_IOS = 'ios';
	const DEVICE_DESKTOP = 'desktop';
	const DEVICE_BROWSER = 'browser';

	/** @var IRequest */
	protected $request;

	/** @var IConfig */
	protected $config;

	/** @var IFactory */
	protected $languageFactory;

	/** @var IAppManager */
	protected $appManager;

	/** @var IGroupManager */
	protected $groupManager;

	/** @var IUserSession */
	protected $userSession;

	/** @var IAppData */
	protected $appData;


	public function __construct(IRequest $request,
								IConfig $config,
								IAppManager $appManager,
								IGroupManager $groupManager,
								IUserSession $userSession,
								IFactory $languageFactory,
								IAppData $appData) {
		$this->request = $request;
		$this->config = $config;
		$this->appManager = $appManager;
		$this->groupManager = $groupManager;
		$this->userSession = $userSession;
		$this->languageFactory = $languageFactory;
		$this->appData = $appData;
	}

	/**
	 * @param int $id
	 * @return array
	 * @throws SiteNotFoundException
	 */
	public function getSiteById($id) {
		$sites = $this->getSites();

		if (isset($sites[$id])) {
			$site = $sites[$id];

			$user = $this->userSession->getUser();
			$email= $user instanceof IUser ? $user->getEMailAddress() : '';
			$uid  = $user instanceof IUser ? $user->getUID() : '';
			$displayName = $user instanceof IUser ? $user->getDisplayName() : '';
			$chat_url = getenv('CHAT_URL', true) ?: getenv('CHAT_URL');
			$saml_idp_url = getenv('SAML_IDP_URL', true) ?: getenv('SAML_IDP_URL');
			$saml_realm = getenv('SAML_REALM', true) ?: getenv('SAML_REALM');
Timothee Gosselin's avatar
Timothee Gosselin committed
			$quota_url = "/settings/users";
Pierre Ozoux's avatar
Pierre Ozoux committed

Timothee Gosselin's avatar
Timothee Gosselin committed
			$site['url'] = str_replace(['{email}', '{uid}', '{displayname}', '{chat_url}', '{saml_idp_url}', '{saml_realm}', '{quota_url}'], [$email, $uid, $displayName, $chat_url, $saml_idp_url, $saml_realm, $quota_url], $site['url']);
Pierre Ozoux's avatar
Pierre Ozoux committed

Pierre Ozoux's avatar
Pierre Ozoux committed
			if ($site['name'] === 'Visio') {
Hugo Renard's avatar
Hugo Renard committed
				$visio_url = getenv('VISIO_URL', true);
				if ($visio_url) { // if VISIO_URL is empty, we use the default provided in the json 
Hugo Renard's avatar
Hugo Renard committed
					$site['url'] = $visio_url;
			if ($site['kind'] === 'support') {
				$support_url = getenv('SUPPORT_URL', true) ?: getenv('SUPPORT_URL');
				if ($support_url) {
					$site['url'] = $support_url;
				}
			}

Pierre Ozoux's avatar
Pierre Ozoux committed
			return $site;
		}

		throw new SiteNotFoundException();
	}

	/**
	 * @return array[]
	 */
	public function getSitesToDisplay() {
		$sites = $this->getSites();
		$lang = $this->languageFactory->findLanguage();
		$device = $this->getDeviceFromUserAgent();

		$user = $this->userSession->getUser();
		if ($user instanceof IUser) {
			$groups = $this->groupManager->getUserGroupIds($this->userSession->getUser());
		} else {
			$groups = [];
		}

		$email= $user instanceof IUser ? $user->getEMailAddress() : '';
		$uid  = $user instanceof IUser ? $user->getUID() : '';
		$displayName = $user instanceof IUser ? $user->getDisplayName() : '';
Pierre Ozoux's avatar
Pierre Ozoux committed
		$saml_idp_url = getenv('SAML_IDP_URL', true) ?: getenv('SAML_IDP_URL');
		$saml_realm = getenv('SAML_REALM', true) ?: getenv('SAML_REALM');

		$langSites = [];
		foreach ($sites as $id => $site) {
			if ($site['lang'] !== '' && $site['lang'] !== $lang) {
				continue;
			}

			if ($site['device'] !== self::DEVICE_ALL && $site['device'] !== $device) {
				continue;
			}

			if (!empty($site['groups']) && empty(array_intersect($site['groups'], $groups))) {
				continue;
			}

			if ($site['name'] === 'Chat') {
				$chat_url = getenv('CHAT_URL', true) ?: getenv('CHAT_URL');
				if (!$chat_url) { // if CHAT_URL is empty or false, continue the loop and skip this item
					continue;
				} else {
					$site['url'] = str_replace(['{chat_url}'], [$chat_url], $site['url']);
				}
			}
			
			if ($site['kind'] === 'SSO') {
				if (!$saml_idp_url || !$saml_realm) {
					continue;
				} else {
					$site['url'] = str_replace(['{saml_idp_url}', '{saml_realm}'], [$saml_idp_url, $saml_realm], $site['url']);
				}
			}
			
Pierre Ozoux's avatar
Pierre Ozoux committed
			if ($site['name'] === 'Visio') {
Hugo Renard's avatar
Hugo Renard committed
				$visio_url = getenv('VISIO_URL', true);
				if (!$visio_url) { // if VISIO_URL is empty, we use the default provided in the json 
					continue;
				} else {
					$site['url'] = $visio_url;
			}

			if ($site['kind'] === 'support') {
				$support_url = getenv('SUPPORT_URL', true) ?: getenv('SUPPORT_URL');
				if ($support_url) {
					$site['url'] = $support_url;
				}
			}
Timothee Gosselin's avatar
Timothee Gosselin committed
			if ($site['kind'] === 'quota') {
				$nextcloud_url = getenv('OVERWRITE_CLI_URL', true) ?: getenv('OVERWRITE_CLI_URL');
				if ($nextcloud_url) {
					$site['url'] = "/settings/users";
				}
			}

			$site['url'] = str_replace(['{email}', '{uid}', '{displayname}'], [$email, $uid, $displayName], $site['url']);
Pierre Ozoux's avatar
Pierre Ozoux committed

			$langSites[$id] = $site;
		}

		return $langSites;
	}

	/**
	 * @return array[]
	 */
	public function getSites() {
		$jsonEncodedList = file_get_contents(__DIR__ .  '/sites.json');
		$sites = json_decode($jsonEncodedList, true);

		$sites = array_map([$this, 'fillSiteArray'], $sites);

		return $sites;
	}

	/**
	 * Adds default values for new attributes of sites
	 * @param array $site
	 * @return array
	 */
	protected function fillSiteArray(array $site) {
		return array_merge([
				'icon' => 'external.svg',
				'lang' => '',
				'type' => self::TYPE_LINK,
				'device' => self::DEVICE_ALL,
				'groups' => [],
				'redirect' => false,
			],
			$site
		);
	}

	/**
	 * @return string
	 */
	protected function getDeviceFromUserAgent() {
		if ($this->request->isUserAgent([IRequest::USER_AGENT_CLIENT_ANDROID])) {
			return self::DEVICE_ANDROID;
		}
		if ($this->request->isUserAgent([IRequest::USER_AGENT_CLIENT_IOS])) {
			return self::DEVICE_IOS;
		}
		if ($this->request->isUserAgent([IRequest::USER_AGENT_CLIENT_DESKTOP])) {
			return self::DEVICE_DESKTOP;
		}
		return self::DEVICE_BROWSER;
	}
}