Merge pull request #101 from nextcloud-gmbh/setupcheck

Setup check
pull/113/head
Julius Härtl 2018-12-03 13:36:16 +01:00 zatwierdzone przez GitHub
commit e4529162db
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
3 zmienionych plików z 163 dodań i 27 usunięć

Wyświetl plik

@ -40,9 +40,11 @@ use OCA\Social\Exceptions\SocialAppConfigException;
use OCA\Social\Service\ActivityPub\DocumentService;
use OCA\Social\Service\ActivityPub\PersonService;
use OCA\Social\Service\ActorService;
use OCA\Social\Service\CheckService;
use OCA\Social\Service\ConfigService;
use OCA\Social\Service\MiscService;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\ContentSecurityPolicy;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\Http\FileDisplayResponse;
@ -52,6 +54,7 @@ use OCP\IConfig;
use OCP\IL10N;
use OCP\IRequest;
use OCP\IURLGenerator;
use OCP\Http\Client\IClientService;
class NavigationController extends Controller {
@ -86,6 +89,9 @@ class NavigationController extends Controller {
/** @var PersonService */
private $personService;
/** @var CheckService */
private $checkService;
/**
* NavigationController constructor.
*
@ -97,13 +103,14 @@ class NavigationController extends Controller {
* @param DocumentService $documentService
* @param ConfigService $configService
* @param PersonService $personService
* @param CheckService $checkService
* @param MiscService $miscService
* @param IL10N $l10n
*/
public function __construct(
IRequest $request, $userId, IConfig $config, IURLGenerator $urlGenerator,
ActorService $actorService, DocumentService $documentService, ConfigService $configService,
PersonService $personService,
PersonService $personService, CheckService $checkService,
MiscService $miscService, IL10N $l10n
) {
parent::__construct(Application::APP_NAME, $request);
@ -111,6 +118,7 @@ class NavigationController extends Controller {
$this->userId = $userId;
$this->config = $config;
$this->urlGenerator = $urlGenerator;
$this->checkService = $checkService;
$this->actorService = $actorService;
$this->documentService = $documentService;
@ -138,42 +146,37 @@ class NavigationController extends Controller {
'public' => false,
'firstrun' => false,
'setup' => false,
'isAdmin' => \OC::$server->getGroupManager()->isAdmin($this->userId),
'cliUrl' => $this->getCliUrl()
]
];
$checks = $this->checkService->checkDefault();
$data['serverData']['checks'] = $checks;
try {
$data['serverData']['cloudAddress'] = $this->configService->getCloudAddress();
} catch (SocialAppConfigException $e) {
$cloudAddress = rtrim(
$this->config->getSystemValue('overwrite.cli.url', ''), '/'
);
$frontControllerActive = ($this->config->getSystemValue('htaccess.IgnoreFrontController', false) === true || getenv('front_controller_active') === 'true');
$cloudAddress = $this->setupCloudAddress();
if ($cloudAddress !== ''){
if (!$frontControllerActive){
$cloudAddress .= '/index.php';
}
$this->configService->setCloudAddress($cloudAddress);
$data['serverData']['cloudAddress'] = $cloudAddress;
} else {
$data['serverData']['setup'] = true;
$data['serverData']['isAdmin'] = \OC::$server->getGroupManager()
->isAdmin($this->userId);
if ($data['serverData']['isAdmin']) {
$cloudAddress = $this->request->getParam('cloudAddress');
if ($cloudAddress !== null) {
$this->configService->setCloudAddress($cloudAddress);
} else {
$data['serverData']['cliUrl'] = $this->config->getSystemValue(
'overwrite.cli.url', \OC::$server->getURLGenerator()
->getBaseUrl()
);
return new TemplateResponse(Application::APP_NAME, 'main', $data);
}
}
}
}
/*
* Create social user account if it doesn't exist yet
*/
try {
$this->actorService->createActor($this->userId, $this->userId);
$data['serverData']['firstrun'] = true;
@ -185,13 +188,31 @@ class NavigationController extends Controller {
// neither.
}
$csp = new ContentSecurityPolicy();
$csp->addAllowedImageDomain('*');
$response = new TemplateResponse(Application::APP_NAME, 'main', $data);
$response->setContentSecurityPolicy($csp);
return $response;
return new TemplateResponse(Application::APP_NAME, 'main', $data);
}
private function setupCloudAddress(): string {
$frontControllerActive = ($this->config->getSystemValue('htaccess.IgnoreFrontController', false) === true || getenv('front_controller_active') === 'true');
$cloudAddress = rtrim($this->config->getSystemValue('overwrite.cli.url', ''), '/');
if ($cloudAddress !== '') {
if (!$frontControllerActive) {
$cloudAddress .= '/index.php';
}
$this->configService->setCloudAddress($cloudAddress);
return $cloudAddress;
}
return '';
}
private function getCliUrl() {
$url = rtrim($this->urlGenerator->getBaseUrl(), '/');
$frontControllerActive = ($this->config->getSystemValue('htaccess.IgnoreFrontController', false) === true || getenv('front_controller_active') === 'true');
if (!$frontControllerActive) {
$url .= '/index.php';
}
return $url;
}
/**
* Display the navigation page of the Social app.
@ -301,4 +322,3 @@ class NavigationController extends Controller {
}
}

Wyświetl plik

@ -0,0 +1,105 @@
<?php
/**
* @copyright Copyright (c) 2018 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
* @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\Social\Service;
use OCP\AppFramework\Http;
use OCP\Http\Client\IClientService;
use OCP\ICache;
use OCP\IConfig;
use OCP\IRequest;
use OCP\IURLGenerator;
class CheckService {
private $cache;
private $config;
private $clientService;
private $request;
private $urlGenerator;
const CACHE_PREFIX = 'social_check_';
public function __construct(ICache $cache, IConfig $config, IClientService $clientService, IRequest $request, IURLGenerator $urlGenerator) {
$this->cache = $cache;
$this->config = $config;
$this->clientService = $clientService;
$this->request = $request;
$this->urlGenerator = $urlGenerator;
}
public function checkDefault(): array {
$checks = [];
$checks['wellknown'] = $this->checkWellKnown();
$success = true;
foreach ($checks as $check) {
if (!$check) {
$success = false;
}
}
return [
'success' => $success,
'checks' => $checks
];
}
public function checkWellKnown(): bool {
$state = (bool) ($this->cache->get(self::CACHE_PREFIX . 'wellknown') === 'true');
if ($state === true) {
return true;
}
$address = $this->config->getAppValue('social', 'address', '');
if ($address !== '' && $this->requestWellKnown($address)) {
return true;
}
if ($this->requestWellKnown($this->request->getServerProtocol() . '://' . $this->request->getServerHost())) {
return true;
}
if ($this->requestWellKnown($this->urlGenerator->getBaseUrl())) {
return true;
}
return false;
}
private function requestWellKnown($base) {
try {
$url = $base . '/.well-known/webfinger';
$response = $this->clientService->newClient()->get($url);
if ($response->getStatusCode() === Http::STATUS_OK) {
$this->cache->set(self::CACHE_PREFIX . 'wellknown', 'true', 3600);
return true;
}
} catch (\GuzzleHttp\Exception\ClientException $e) {
} catch (\Exception $e) {
}
return false;
}
}

Wyświetl plik

@ -4,16 +4,19 @@
<app-navigation :menu="menu" />
</div>
<div id="app-content">
<div class="social__wrapper">
<Search v-if="searchTerm != ''" :term="searchTerm" />
<router-view v-if="searchTerm === ''" :key="$route.fullPath" />
<div v-if="serverData.isAdmin && !serverData.checks.success" class="setup">
<h3 v-if="!serverData.checks.checks.wellknown">{{ t('social', '.well-known/webfinger isn\'t properly set up!') }}</h3>
<p v-if="!serverData.checks.checks.wellknown">{{ t('social', 'Social needs the .well-known automatic discovery to be properly set up. If Nextcloud is not installed in the root of the domain, it is often the case that Nextcloud can\'t configure this automatically. To use Social, the admin of this Nextcloud instance needs to manually configure the .well-known redirects: ') }}<a class="external_link" href="https://docs.nextcloud.com/server/15/go.php?to=admin-setup-well-known-URL" target="_blank"
rel="noreferrer noopener">{{ t('social', 'Open documentation') }} </a></p>
</div>
<Search v-if="searchTerm != ''" :term="searchTerm" />
<router-view v-if="searchTerm === ''" :key="$route.fullPath" />
</div>
</div>
<div v-else class="setup">
<template v-if="serverData.isAdmin">
<h2>{{ t('social', 'Social app setup') }}</h2>
<p>{{ t('social', 'ActivityPub requires a fixed URL to make entries unique. Please configure a URL base. Note that this cannot be changed later without resetting the social app data.') }}</p>
<p>{{ t('social', 'ActivityPub requires a fixed URL to make entries unique. Note that this can not be changed later without resetting the Social app.') }}</p>
<form @submit.prevent="setCloudAddress">
<p>
<label class="hidden">{{ t('social', 'ActivityPub URL base') }}</label>
@ -21,10 +24,15 @@
required>
<input :value="t('social', 'Finish setup')" type="submit" class="primary">
</p>
<template v-if="!serverData.checks.success">
<h3 v-if="!serverData.checks.checks.wellknown">{{ t('social', '.well-known/webfinger isn\'t properly set up!') }}</h3>
<p v-if="!serverData.checks.checks.wellknown">{{ t('social', 'Social needs the .well-known automatic discovery to be properly set up. If Nextcloud is not installed in the root of the domain, it is often the case that Nextcloud can\'t configure this automatically. To use Social, the admin of this Nextcloud instance needs to manually configure the .well-known redirects: ') }}<a class="external_link" href="https://docs.nextcloud.com/server/15/go.php?to=admin-setup-well-known-URL" target="_blank"
rel="noreferrer noopener">{{ t('social', 'Open documentation') }} </a></p>
</template>
</form>
</template>
<template v-else>
<p>{{ t('social', 'The social app requires to be setup by the server administrator.') }}</p>
<p>{{ t('social', 'The Social app needs to be set up by the server administrator.') }}</p>
</template>
</div>
</template>
@ -57,6 +65,9 @@
#social-spacer a:focus {
border: none !important;
}
a.external_link {
text-decoration: underline;
}
</style>