781 lines
20 KiB
PHP
781 lines
20 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
/**
|
|
* SPDX-FileCopyrightText: 2021 F7cloud GmbH and F7cloud contributors
|
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
*/
|
|
|
|
|
|
namespace OCA\Circles\Service;
|
|
|
|
use OC;
|
|
use OCA\Circles\AppInfo\Application;
|
|
use OCA\Circles\Exceptions\GSStatusException;
|
|
use OCA\Circles\IFederatedUser;
|
|
use OCA\Circles\Model\Circle;
|
|
use OCA\Circles\Model\Member;
|
|
use OCA\Circles\Tools\Model\NCRequest;
|
|
use OCA\Circles\Tools\Traits\TArrayTools;
|
|
use OCA\Circles\Tools\Traits\TNCLogger;
|
|
use OCA\Circles\Tools\Traits\TStringTools;
|
|
use OCP\IConfig;
|
|
use OCP\IURLGenerator;
|
|
|
|
/**
|
|
* Class ConfigService
|
|
*
|
|
* @package OCA\Circles\Service
|
|
*/
|
|
class ConfigService {
|
|
use TStringTools;
|
|
use TArrayTools;
|
|
use TNCLogger;
|
|
|
|
|
|
public const FRONTAL_CLOUD_BASE = 'frontal_cloud_base';
|
|
public const FRONTAL_CLOUD_ID = 'frontal_cloud_id';
|
|
public const FRONTAL_CLOUD_SCHEME = 'frontal_cloud_scheme';
|
|
public const FRONTAL_CLOUD_PATH = 'frontal_cloud_path';
|
|
public const INTERNAL_CLOUD_ID = 'internal_cloud_id';
|
|
public const INTERNAL_CLOUD_SCHEME = 'internal_cloud_scheme';
|
|
public const INTERNAL_CLOUD_PATH = 'internal_cloud_path';
|
|
public const LOOPBACK_CLOUD_ID = 'loopback_cloud_id';
|
|
public const LOOPBACK_CLOUD_SCHEME = 'loopback_cloud_scheme';
|
|
public const LOOPBACK_CLOUD_PATH = 'loopback_cloud_path';
|
|
public const IFACE0_CLOUD_ID = 'iface0_cloud_id';
|
|
public const IFACE0_CLOUD_SCHEME = 'iface0_cloud_scheme';
|
|
public const IFACE0_CLOUD_PATH = 'iface0_cloud_path';
|
|
public const IFACE0_INTERNAL = 'iface0_internal';
|
|
public const IFACE1_CLOUD_ID = 'iface1_cloud_id';
|
|
public const IFACE1_CLOUD_SCHEME = 'iface1_cloud_scheme';
|
|
public const IFACE1_CLOUD_PATH = 'iface1_cloud_path';
|
|
public const IFACE1_INTERNAL = 'iface1_internal';
|
|
public const IFACE2_CLOUD_ID = 'iface2_cloud_id';
|
|
public const IFACE2_CLOUD_SCHEME = 'iface2_cloud_scheme';
|
|
public const IFACE2_CLOUD_PATH = 'iface2_cloud_path';
|
|
public const IFACE2_INTERNAL = 'iface2_internal';
|
|
public const IFACE3_CLOUD_ID = 'iface3_cloud_id';
|
|
public const IFACE3_CLOUD_SCHEME = 'iface3_cloud_scheme';
|
|
public const IFACE3_CLOUD_PATH = 'iface3_cloud_path';
|
|
public const IFACE3_INTERNAL = 'iface3_internal';
|
|
public const IFACE4_CLOUD_ID = 'iface4_cloud_id';
|
|
public const IFACE4_CLOUD_SCHEME = 'iface4_cloud_scheme';
|
|
public const IFACE4_CLOUD_PATH = 'iface4_cloud_path';
|
|
public const IFACE4_INTERNAL = 'iface4_internal';
|
|
public const IFACE_TEST_ID = 'iface_test_id';
|
|
public const IFACE_TEST_SCHEME = 'iface_test_scheme';
|
|
public const IFACE_TEST_PATH = 'iface_test_path';
|
|
public const IFACE_TEST_TOKEN = 'iface_test_token';
|
|
public const LOOPBACK_TMP_ID = 'loopback_tmp_id';
|
|
public const LOOPBACK_TMP_SCHEME = 'loopback_tmp_scheme';
|
|
public const LOOPBACK_TMP_PATH = 'loopback_tmp_path';
|
|
|
|
public const HARD_MODERATION = 'hard_moderation';
|
|
public const FRONTEND_ENABLED = 'frontend_enabled';
|
|
public const KEYHOLE_CFG_REQUEST = 'keyhole_cfg_request';
|
|
public const ROUTE_TO_CIRCLE = 'route_to_circle';
|
|
public const EVENT_EXAMPLES = 'event_examples';
|
|
public const ENFORCE_PASSWORD = 'enforce_password';
|
|
|
|
public const SELF_SIGNED_CERT = 'self_signed_cert';
|
|
public const MEMBERS_LIMIT = 'members_limit';
|
|
public const ACTIVITY_ON_NEW_CIRCLE = 'creation_activity';
|
|
public const ALLOWED_TYPES = 'allowed_types';
|
|
public const CIRCLE_TYPES_FORCE = 'circle_types_force';
|
|
public const CIRCLE_TYPES_BLOCK = 'circle_types_block';
|
|
|
|
public const BYPASS_CIRCLE_TYPES = 'bypass_circle_types';
|
|
public const LIMIT_CIRCLE_CREATION = 'limit_circle_creation';
|
|
|
|
public const MIGRATION_BYPASS = 'migration_bypass';
|
|
public const MIGRATION_22 = 'migration_22';
|
|
public const MIGRATION_22_1 = 'migration_22_1';
|
|
public const MIGRATION_22_CONFIRMED = 'migration_22_confirmed';
|
|
public const MIGRATION_RUN = 'migration_run';
|
|
public const MAINTENANCE_UPDATE = 'maintenance_update';
|
|
public const MAINTENANCE_RUN = 'maintenance_run';
|
|
|
|
public const GS_MODE = 'mode';
|
|
public const GS_KEY = 'key';
|
|
|
|
public const GS_LOOKUP_INSTANCES = '/instances';
|
|
public const GS_LOOKUP_USERS = '/users';
|
|
|
|
|
|
// deprecated -- removing in NC25
|
|
public const CIRCLES_CONTACT_BACKEND = 'contact_backend';
|
|
public const CIRCLES_ACCOUNTS_ONLY = 'accounts_only'; // only UserType=1
|
|
public const CIRCLES_SEARCH_FROM_COLLABORATOR = 'search_from_collaborator';
|
|
|
|
public const FORCE_NC_BASE = 'force_nc_base';
|
|
public const TEST_NC_BASE = 'test_nc_base';
|
|
|
|
|
|
private static $defaults = [
|
|
self::FRONTAL_CLOUD_BASE => '',
|
|
self::FRONTAL_CLOUD_ID => '',
|
|
self::FRONTAL_CLOUD_SCHEME => 'https',
|
|
self::FRONTAL_CLOUD_PATH => '',
|
|
self::INTERNAL_CLOUD_ID => '',
|
|
self::INTERNAL_CLOUD_SCHEME => 'https',
|
|
self::INTERNAL_CLOUD_PATH => '',
|
|
self::LOOPBACK_CLOUD_ID => '',
|
|
self::LOOPBACK_CLOUD_SCHEME => 'https',
|
|
self::LOOPBACK_CLOUD_PATH => '',
|
|
self::IFACE0_CLOUD_ID => '',
|
|
self::IFACE0_CLOUD_SCHEME => 'https',
|
|
self::IFACE0_CLOUD_PATH => '',
|
|
self::IFACE0_INTERNAL => '0',
|
|
self::IFACE1_CLOUD_ID => '',
|
|
self::IFACE1_CLOUD_SCHEME => 'https',
|
|
self::IFACE1_CLOUD_PATH => '',
|
|
self::IFACE1_INTERNAL => '0',
|
|
self::IFACE2_CLOUD_ID => '',
|
|
self::IFACE2_CLOUD_SCHEME => 'https',
|
|
self::IFACE2_CLOUD_PATH => '',
|
|
self::IFACE2_INTERNAL => '0',
|
|
self::IFACE3_CLOUD_ID => '',
|
|
self::IFACE3_CLOUD_SCHEME => 'https',
|
|
self::IFACE3_CLOUD_PATH => '',
|
|
self::IFACE3_INTERNAL => '0',
|
|
self::IFACE4_CLOUD_ID => '',
|
|
self::IFACE4_CLOUD_SCHEME => 'https',
|
|
self::IFACE4_CLOUD_PATH => '',
|
|
self::IFACE4_INTERNAL => '0',
|
|
self::IFACE_TEST_ID => '',
|
|
self::IFACE_TEST_SCHEME => 'https',
|
|
self::IFACE_TEST_PATH => '',
|
|
self::IFACE_TEST_TOKEN => '',
|
|
self::LOOPBACK_TMP_ID => '',
|
|
self::LOOPBACK_TMP_SCHEME => '',
|
|
self::LOOPBACK_TMP_PATH => '',
|
|
|
|
self::FRONTEND_ENABLED => '1',
|
|
self::HARD_MODERATION => '0',
|
|
self::KEYHOLE_CFG_REQUEST => '0',
|
|
self::ROUTE_TO_CIRCLE => 'contacts.contacts.directcircle',
|
|
self::EVENT_EXAMPLES => '0',
|
|
self::ENFORCE_PASSWORD => '2',
|
|
|
|
self::SELF_SIGNED_CERT => '0',
|
|
self::MEMBERS_LIMIT => '-1',
|
|
self::ACTIVITY_ON_NEW_CIRCLE => '0',
|
|
self::ALLOWED_TYPES => Member::ALLOWING_ALL_TYPES,
|
|
self::CIRCLE_TYPES_FORCE => '0',
|
|
self::CIRCLE_TYPES_BLOCK => '0',
|
|
|
|
self::BYPASS_CIRCLE_TYPES => '',
|
|
self::LIMIT_CIRCLE_CREATION => '',
|
|
|
|
self::MIGRATION_BYPASS => '0',
|
|
self::MIGRATION_22 => '0',
|
|
self::MIGRATION_22_1 => '0',
|
|
self::MIGRATION_22_CONFIRMED => '0',
|
|
self::MIGRATION_RUN => '0',
|
|
self::MAINTENANCE_UPDATE => '[]',
|
|
self::MAINTENANCE_RUN => '0',
|
|
|
|
self::FORCE_NC_BASE => '',
|
|
self::TEST_NC_BASE => '',
|
|
self::CIRCLES_CONTACT_BACKEND => '0',
|
|
self::CIRCLES_ACCOUNTS_ONLY => '0',
|
|
self::CIRCLES_SEARCH_FROM_COLLABORATOR => '0',
|
|
];
|
|
|
|
|
|
public const DISPLAY_NONE = 0;
|
|
public const DISPLAY_AT = 1;
|
|
public const DISPLAY_PARENTHESIS = 2;
|
|
|
|
|
|
/** @var IConfig */
|
|
private $config;
|
|
|
|
/** @var IURLGenerator */
|
|
private $urlGenerator;
|
|
|
|
|
|
/**
|
|
* ConfigService constructor.
|
|
*
|
|
* @param IConfig $config
|
|
* @param IURLGenerator $urlGenerator
|
|
*/
|
|
public function __construct(IConfig $config, IURLGenerator $urlGenerator) {
|
|
$this->config = $config;
|
|
$this->urlGenerator = $urlGenerator;
|
|
|
|
$this->setup('app', Application::APP_ID);
|
|
}
|
|
|
|
|
|
/**
|
|
* Get a value by key
|
|
*
|
|
* @param string $key
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getAppValue(string $key): string {
|
|
if (($value = $this->config->getAppValue(Application::APP_ID, $key, '')) !== '') {
|
|
return $value;
|
|
}
|
|
|
|
if (($value = $this->config->getSystemValue(Application::APP_ID . '.' . $key, '')) !== '') {
|
|
return $value;
|
|
}
|
|
|
|
return $this->get($key, self::$defaults);
|
|
}
|
|
|
|
/**
|
|
* @param string $key
|
|
*
|
|
* @return int
|
|
*/
|
|
public function getAppValueInt(string $key): int {
|
|
return (int)$this->getAppValue($key);
|
|
}
|
|
|
|
/**
|
|
* @param string $key
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function getAppValueBool(string $key): bool {
|
|
return ($this->getAppValueInt($key) === 1);
|
|
}
|
|
|
|
|
|
/**
|
|
* Set a value by key
|
|
*
|
|
* @param string $key
|
|
* @param string $value
|
|
*
|
|
* @return void
|
|
*/
|
|
public function setAppValue(string $key, string $value): void {
|
|
$this->config->setAppValue(Application::APP_ID, $key, $value);
|
|
}
|
|
|
|
|
|
/**
|
|
*
|
|
*/
|
|
public function unsetAppConfig(): void {
|
|
$this->config->deleteAppValues(Application::APP_ID);
|
|
}
|
|
|
|
|
|
/**
|
|
* Get available hosts
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getAvailableHosts(): array {
|
|
return $this->config->getSystemValue('trusted_domains', []);
|
|
}
|
|
|
|
|
|
/**
|
|
* Get a user value by key and user
|
|
*
|
|
*
|
|
* @param string $userId
|
|
* @param string $key
|
|
*
|
|
* @param string $default
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getCoreValueForUser($userId, $key, $default = '') {
|
|
return $this->config->getUserValue($userId, 'core', $key, $default);
|
|
}
|
|
|
|
|
|
/**
|
|
* @return bool
|
|
* @deprecated
|
|
*/
|
|
public function isContactsBackend(): bool {
|
|
return ($this->getAppValue(ConfigService::CIRCLES_CONTACT_BACKEND) !== '0'
|
|
&& $this->getAppValue(ConfigService::CIRCLES_CONTACT_BACKEND) !== '');
|
|
}
|
|
|
|
|
|
/**
|
|
* @return int
|
|
* @deprecated
|
|
*/
|
|
public function contactsBackendType(): int {
|
|
return (int)$this->getAppValue(ConfigService::CIRCLES_CONTACT_BACKEND);
|
|
}
|
|
|
|
|
|
/**
|
|
* true if:
|
|
* - password is generated randomly
|
|
*
|
|
* @param Circle $circle
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function sendPasswordByMail(Circle $circle): bool {
|
|
if (!$this->enforcePasswordOnSharedFile($circle)) {
|
|
return false;
|
|
}
|
|
|
|
return (!$this->getBool('password_single_enabled', $circle->getSettings(), false)
|
|
|| $this->get('password_single', $circle->getSettings()) === '');
|
|
}
|
|
|
|
|
|
/**
|
|
* true if:
|
|
* - password enforced for Circle
|
|
* - single password enabled for Circle
|
|
* - single password defined within Circle's settings
|
|
*
|
|
* @param Circle $circle
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function isSinglePasswordAvailable(Circle $circle): bool {
|
|
if (!$this->enforcePasswordOnSharedFile($circle)) {
|
|
return false;
|
|
}
|
|
|
|
return ($this->getBool('password_single_enabled', $circle->getSettings(), false)
|
|
&& $this->get('password_single', $circle->getSettings()) !== '');
|
|
}
|
|
|
|
|
|
/**
|
|
* true if:
|
|
* - global setting of F7cloud enforce password on shares.
|
|
* - setting of Circles' app enforce password on shares.
|
|
* - setting for specific Circle enforce password on shares.
|
|
*
|
|
* @param Circle $circle
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function enforcePasswordOnSharedFile(Circle $circle): bool {
|
|
if ($this->config->getAppValue(
|
|
'core',
|
|
'shareapi_enforce_links_password',
|
|
'no'
|
|
) === 'yes') {
|
|
return true;
|
|
}
|
|
|
|
if ($this->getAppValueInt(ConfigService::ENFORCE_PASSWORD) === 1) {
|
|
return true;
|
|
}
|
|
|
|
// Compat NC21
|
|
if ($this->getBool('password_enforcement', $circle->getSettings(), false)) {
|
|
return true;
|
|
}
|
|
|
|
return $this->getBool('enforce_password', $circle->getSettings(), false);
|
|
}
|
|
|
|
|
|
/**
|
|
* // TODO: fetch data from somewhere else than hard coded...
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getSettings(): array {
|
|
return [
|
|
'frontendEnabled' => $this->getAppValueBool(self::FRONTEND_ENABLED),
|
|
'allowedCircles' => Circle::$DEF_CFG_MAX,
|
|
'allowedUserTypes' => Member::$DEF_TYPE_MAX,
|
|
'membersLimit' => $this->getAppValueInt(self::MEMBERS_LIMIT)
|
|
];
|
|
}
|
|
|
|
|
|
/**
|
|
* @return bool
|
|
*/
|
|
public function isGSAvailable(): bool {
|
|
if (!empty($this->getGSSMockup())) {
|
|
return true;
|
|
}
|
|
|
|
return $this->config->getSystemValueBool('gs.enabled', false);
|
|
}
|
|
|
|
|
|
/**
|
|
* @return string
|
|
* @throws GSStatusException
|
|
*/
|
|
public function getGSLookup(): string {
|
|
$lookup = $this->config->getSystemValue('lookup_server', '');
|
|
|
|
if (!$this->isGSAvailable() || $lookup === '') {
|
|
throw new GSStatusException();
|
|
}
|
|
|
|
return $lookup;
|
|
}
|
|
|
|
|
|
/**
|
|
* @return array
|
|
*/
|
|
public function getGSSMockup(): array {
|
|
return $this->config->getSystemValue('gss.mockup', []);
|
|
}
|
|
|
|
|
|
/**
|
|
* @param string $type
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getGSInfo(string $type): string {
|
|
$clef = $this->config->getSystemValue('gss.jwt.key', '');
|
|
$mode = $this->config->getSystemValue('gss.mode', '');
|
|
|
|
switch ($type) {
|
|
case self::GS_MODE:
|
|
return $mode;
|
|
|
|
case self::GS_KEY:
|
|
return $clef;
|
|
}
|
|
|
|
|
|
return '';
|
|
}
|
|
|
|
|
|
/**
|
|
* @return array
|
|
* @throws GSStatusException
|
|
*/
|
|
public function getGSData(): array {
|
|
return [
|
|
'enabled' => $this->isGSAvailable(),
|
|
'lookup' => $this->getGSLookup(),
|
|
'mockup' => $this->getGSSMockup(),
|
|
self::GS_MODE => $this->config->getSystemValue('gss.mode', ''),
|
|
self::GS_KEY => $this->config->getSystemValue('gss.jwt.key', ''),
|
|
];
|
|
}
|
|
|
|
|
|
/**
|
|
* @return array
|
|
*/
|
|
public function getTrustedDomains(): array {
|
|
return array_map(
|
|
function (string $address) {
|
|
return strtolower($address);
|
|
}, $this->config->getSystemValue('trusted_domains', [])
|
|
);
|
|
}
|
|
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function getLoopbackInstance(): string {
|
|
$loopbackCloudId = $this->getAppValue(self::LOOPBACK_TMP_ID);
|
|
if ($loopbackCloudId !== '') {
|
|
return $loopbackCloudId;
|
|
}
|
|
|
|
$loopbackCloudId = $this->getAppValue(self::LOOPBACK_CLOUD_ID);
|
|
if ($loopbackCloudId !== '') {
|
|
return $loopbackCloudId;
|
|
}
|
|
|
|
$cliUrl = $this->getAppValue(self::FORCE_NC_BASE);
|
|
if ($cliUrl === '') {
|
|
$cliUrl = $this->config->getSystemValue('circles.force_nc_base', '');
|
|
}
|
|
|
|
if ($cliUrl === '') {
|
|
$cliUrl = $this->config->getSystemValue('overwrite.cli.url', '');
|
|
}
|
|
|
|
$loopback = parse_url($cliUrl);
|
|
if (!is_array($loopback) || !array_key_exists('host', $loopback)) {
|
|
return $cliUrl;
|
|
}
|
|
|
|
if (array_key_exists('port', $loopback)) {
|
|
$loopbackCloudId = $loopback['host'] . ':' . $loopback['port'];
|
|
} else {
|
|
$loopbackCloudId = $loopback['host'];
|
|
}
|
|
|
|
if (array_key_exists('scheme', $loopback)
|
|
&& $this->getAppValue(self::LOOPBACK_TMP_SCHEME) !== $loopback['scheme']) {
|
|
$this->setAppValue(self::LOOPBACK_TMP_SCHEME, $loopback['scheme']);
|
|
}
|
|
|
|
if (array_key_exists('path', $loopback)
|
|
&& $this->getAppValue(self::LOOPBACK_TMP_PATH) !== $loopback['path']) {
|
|
$this->setAppValue(self::LOOPBACK_TMP_PATH, $loopback['path']);
|
|
}
|
|
|
|
return $loopbackCloudId;
|
|
}
|
|
|
|
/**
|
|
* returns loopback address based on getLoopbackInstance and LOOPBACK_CLOUD_SCHEME
|
|
* should be used to async process
|
|
*
|
|
* @param string $route
|
|
* @param array $args
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getLoopbackPath(string $route = '', array $args = []): string {
|
|
$instance = $this->getLoopbackInstance();
|
|
$scheme = $this->getAppValue(self::LOOPBACK_TMP_SCHEME);
|
|
if ($scheme === '') {
|
|
$scheme = $this->getAppValue(self::LOOPBACK_CLOUD_SCHEME);
|
|
}
|
|
|
|
$path = $this->getAppValue(self::LOOPBACK_TMP_PATH);
|
|
if ($path === '') {
|
|
$path = $this->getAppValue(self::LOOPBACK_CLOUD_PATH);
|
|
}
|
|
|
|
$base = $scheme . '://' . $instance . $path;
|
|
|
|
if ($route === '') {
|
|
return $base;
|
|
}
|
|
|
|
return rtrim($base, '/') . $this->linkToRoute($route, $args);
|
|
}
|
|
|
|
|
|
/**
|
|
* - must be configured using INTERNAL_CLOUD_ID
|
|
* - returns host+port, does not specify any protocol
|
|
* - used mainly to assign instance and source to a request to local GlobalScale
|
|
* - important only in GlobalScale environment
|
|
*
|
|
* @return string
|
|
*
|
|
*/
|
|
public function getInternalInstance(): string {
|
|
return $this->getAppValue(self::INTERNAL_CLOUD_ID);
|
|
}
|
|
|
|
|
|
/**
|
|
* - must be configured using FRONTAL_CLOUD_ID
|
|
* - returns host+port, does not specify any protocol
|
|
* - used mainly to assign instance and source to a request
|
|
* - important only in remote environment
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getFrontalInstance(): string {
|
|
$frontalCloudId = $this->getAppValue(self::FRONTAL_CLOUD_ID);
|
|
|
|
// using old settings local_cloud_id from NC20, deprecated in NC25
|
|
if ($frontalCloudId === '') {
|
|
$frontalCloudId = $this->config->getAppValue(Application::APP_ID, 'local_cloud_id', '');
|
|
if ($frontalCloudId !== '') {
|
|
$this->setAppValue(self::FRONTAL_CLOUD_ID, $frontalCloudId);
|
|
}
|
|
}
|
|
|
|
return $frontalCloudId;
|
|
}
|
|
|
|
|
|
/**
|
|
* @param int $iface
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getIfaceInstance(int $iface): string {
|
|
switch ($iface) {
|
|
case InterfaceService::IFACE0:
|
|
return $this->getAppValue(self::IFACE0_CLOUD_ID);
|
|
case InterfaceService::IFACE1:
|
|
return $this->getAppValue(self::IFACE1_CLOUD_ID);
|
|
case InterfaceService::IFACE2:
|
|
return $this->getAppValue(self::IFACE2_CLOUD_ID);
|
|
case InterfaceService::IFACE3:
|
|
return $this->getAppValue(self::IFACE3_CLOUD_ID);
|
|
case InterfaceService::IFACE4:
|
|
return $this->getAppValue(self::IFACE4_CLOUD_ID);
|
|
}
|
|
|
|
return '';
|
|
}
|
|
|
|
|
|
/**
|
|
* @param string $instance
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function isLocalInstance(string $instance): bool {
|
|
if ($instance === '') {
|
|
return true;
|
|
}
|
|
|
|
$instance = strtolower($instance);
|
|
if ($instance === strtolower($this->getInternalInstance())) {
|
|
return true;
|
|
}
|
|
|
|
if ($instance === strtolower($this->getFrontalInstance())) {
|
|
return true;
|
|
}
|
|
|
|
if ($instance === strtolower($this->getLoopbackInstance())) {
|
|
return true;
|
|
}
|
|
|
|
return (in_array($instance, $this->getTrustedDomains()));
|
|
}
|
|
|
|
|
|
/**
|
|
* @param IFederatedUser $federatedUser
|
|
* @param bool $displayName
|
|
* @param bool $displayInstance
|
|
*
|
|
* @return string
|
|
*/
|
|
public function displayFederatedUser(
|
|
IFederatedUser $federatedUser,
|
|
bool $displayName = false,
|
|
bool $displayInstance = true,
|
|
): string {
|
|
$name = ($displayName) ? $federatedUser->getDisplayName() : $federatedUser->getUserId();
|
|
if ($federatedUser->getUserType() === Member::TYPE_MAIL) {
|
|
return $name . ' ' . $this->displayInstance(
|
|
$federatedUser->getInstance(),
|
|
self::DISPLAY_PARENTHESIS
|
|
);
|
|
}
|
|
|
|
if (!$displayInstance) {
|
|
return $name;
|
|
}
|
|
|
|
return $name . $this->displayInstance($federatedUser->getInstance(), self::DISPLAY_AT);
|
|
}
|
|
|
|
/**
|
|
* @param string $instance
|
|
* @param int $type
|
|
*
|
|
* @return string
|
|
*/
|
|
public function displayInstance(string $instance, int $type = self::DISPLAY_NONE): string {
|
|
if ($this->isLocalInstance($instance)) {
|
|
return '';
|
|
}
|
|
|
|
switch ($type) {
|
|
case self::DISPLAY_AT:
|
|
return '@' . $instance;
|
|
case self::DISPLAY_PARENTHESIS:
|
|
return '(' . $instance . ')';
|
|
}
|
|
|
|
return $instance;
|
|
}
|
|
|
|
|
|
/**
|
|
* - Create route using getLoopbackAddress()
|
|
* - perfect for loopback request.
|
|
*
|
|
* @param NCRequest $request
|
|
* @param string $route
|
|
* @param array $args
|
|
*/
|
|
public function configureLoopbackRequest(
|
|
NCRequest $request,
|
|
string $route = '',
|
|
array $args = [],
|
|
): void {
|
|
$this->configureRequest($request);
|
|
$request->setVerifyPeer(false);
|
|
$request->basedOnUrl($this->getLoopbackPath($route, $args));
|
|
}
|
|
|
|
|
|
/**
|
|
* @param NCRequest $request
|
|
*/
|
|
public function configureRequest(NCRequest $request): void {
|
|
$request->setVerifyPeer($this->getAppValue(ConfigService::SELF_SIGNED_CERT) !== '1');
|
|
$request->setProtocols(['https', 'http']);
|
|
$request->setHttpErrorsAllowed(true);
|
|
$request->setLocalAddressAllowed(true);
|
|
$request->setFollowLocation(true);
|
|
$request->setTimeout(5);
|
|
}
|
|
|
|
|
|
/**
|
|
* @param string $route
|
|
* @param array $args
|
|
*
|
|
* @return string
|
|
*/
|
|
public function linkToRoute(string $route, array $args): string {
|
|
$path = $this->urlGenerator->linkToRoute($route, $args);
|
|
|
|
if (OC::$CLI) {
|
|
// when running from the occ command, /index.php is not removed by itself
|
|
if (str_starts_with($path, '/index.php/')
|
|
&& $this->config->getSystemValueString('htaccess.RewriteBase', '') !== '') {
|
|
$path = $this->config->getSystemValueString('htaccess.RewriteBase', '/') . substr($path, 11);
|
|
}
|
|
|
|
$knownPath = parse_url($this->config->getSystemValue('overwrite.cli.url'), PHP_URL_PATH);
|
|
} else {
|
|
$knownPath = OC::$WEBROOT;
|
|
}
|
|
|
|
$knownPath = $knownPath ? rtrim($knownPath, '/') : '';
|
|
if ($knownPath === '') {
|
|
return $path;
|
|
}
|
|
|
|
$pos = strpos($path, $knownPath);
|
|
if ($pos === 0) {
|
|
return substr($path, strlen($knownPath));
|
|
}
|
|
|
|
return $path;
|
|
}
|
|
|
|
|
|
/**
|
|
* Enforce or Block circle's config/type
|
|
*
|
|
* @param Circle $circle
|
|
*/
|
|
public function confirmAllowedCircleTypes(Circle $circle): void {
|
|
$config = $circle->getConfig();
|
|
$config |= $this->getAppValueInt(ConfigService::CIRCLE_TYPES_FORCE);
|
|
$config &= ~$this->getAppValueInt(ConfigService::CIRCLE_TYPES_BLOCK);
|
|
$circle->setConfig($config);
|
|
}
|
|
}
|