Add option to disable web requests for privacy

fixes #647
This commit is contained in:
Marcel Klehr 2019-09-13 01:55:49 +02:00
parent 39fa6b8f8b
commit c2fb8d9a01
5 changed files with 99 additions and 23 deletions

View File

@ -4,6 +4,7 @@ namespace OCA\Bookmarks;
use Marcelklehr\LinkPreview\Client as LinkPreview;
use Marcelklehr\LinkPreview\Exceptions\ConnectionErrorException;
use OCP\ILogger;
use OCP\IConfig;
use OCP\Http\Client\IClientService;
use OCA\Bookmarks\Http\RequestFactory;
use OCA\Bookmarks\Http\Client;
@ -14,11 +15,15 @@ class LinkExplorer {
private $logger;
public function __construct(IClientService $clientService, ILogger $logger) {
private $config;
public function __construct(IClientService $clientService, ILogger $logger, IConfig $config) {
$client = $clientService->newClient();
$this->linkPreview = new LinkPreview(new Client($client), new RequestFactory());
$this->linkPreview->getParser('general')->setMinimumImageDimensions(150, 550);
$this->logger = $logger;
$this->config = $config;
$this->enabled = $config->getAppValue('bookmarks', 'privacy.enableScraping', true);
}
/**
@ -29,6 +34,10 @@ class LinkExplorer {
public function get($url) {
$data = ['url' => $url];
if ($this->enabled === 'false') {
return $data;
}
// Use LinkPreview to get the meta data
try {
libxml_use_internal_errors(false);

View File

@ -22,6 +22,7 @@ namespace OCA\Bookmarks\Previews;
use OCA\Bookmarks\FileCache;
use OCP\ICache;
use OCP\ILogger;
use OCP\IConfig;
use OCP\Http\Client\IClientService;
use OCP\Http\Client\IClient;
use OCA\Bookmarks\LinkExplorer;
@ -45,15 +46,20 @@ class DefaultPreviewService implements IPreviewService {
/** @var ILogger */
private $logger;
/** @var IConfig */
private $config;
/**
* @param CacheFactory $cacheFactory
* @param LinkExplorer $linkExplorer
*/
public function __construct(FileCache $cache, LinkExplorer $linkExplorer, IClientService $clientService, ILogger $logger) {
public function __construct(FileCache $cache, LinkExplorer $linkExplorer, IClientService $clientService, ILogger $logger, IConfig $config) {
$this->cache = $cache;
$this->linkExplorer = $linkExplorer;
$this->client = $clientService->newClient();
$this->logger = $logger;
$this->config = $config;
$this->enabled = $config->getAppValue('bookmarks', 'privacy.enableScraping', true);
}
protected function buildKey($url) {
@ -73,6 +79,9 @@ class DefaultPreviewService implements IPreviewService {
* @return string|null image data
*/
public function getImage($bookmark) {
if ($this->enabled === 'false') {
return null;
}
if (!isset($bookmark)) {
return null;
}
@ -84,7 +93,7 @@ class DefaultPreviewService implements IPreviewService {
if (isset($site['image']['large'])) {
return $this->getOrFetchImageUrl($site['image']['large']);
}
return null;
return null;
}
public function scrapeUrl($url) {

View File

@ -22,6 +22,7 @@ namespace OCA\Bookmarks\Previews;
use OCA\Bookmarks\FileCache;
use OCP\ILogger;
use OCP\IConfig;
use OCP\Http\Client\IClientService;
use OCA\Bookmarks\LinkExplorer;
@ -30,11 +31,14 @@ class FaviconPreviewService extends DefaultPreviewService {
* @param ICacheFactory $cacheFactory
* @param LinkExplorer $linkExplorer
*/
public function __construct(FileCache $cache, LinkExplorer $linkExplorer, IClientService $clientService, ILogger $logger) {
parent::__construct($cache, $linkExplorer, $clientService, $logger);
public function __construct(FileCache $cache, LinkExplorer $linkExplorer, IClientService $clientService, ILogger $logger, IConfig $config) {
parent::__construct($cache, $linkExplorer, $clientService, $logger, $config);
}
public function getImage($bookmark) {
if ($this->enabled === 'false') {
return null;
}
if (!isset($bookmark)) {
return null;
}

View File

@ -47,9 +47,6 @@ class ScreenlyPreviewService implements IPreviewService {
private $height = 800;
/**
* @param ICacheFactory $cacheFactory
*/
public function __construct(FileCache $cache, IConfig $config, IClientService $clientService, ILogger $logger) {
$this->config = $config;
$this->apiUrl = $config->getAppValue('bookmarks', 'previews.screenly.url', 'http://screeenly.com/api/v1/fullsize');
@ -57,6 +54,7 @@ class ScreenlyPreviewService implements IPreviewService {
$this->cache = $cache;
$this->client = $clientService->newClient();
$this->logger = $logger;
$this->enabled = $config->getAppValue('bookmarks', 'privacy.enableScraping', true);
}
private function buildKey($url) {
@ -68,6 +66,9 @@ class ScreenlyPreviewService implements IPreviewService {
* @return string|null image data
*/
public function getImage($bookmark) {
if ($this->enabled === 'false') {
return null;
}
if (!isset($bookmark)) {
return null;
}

View File

@ -3,25 +3,71 @@
<figure v-if="loading" class="icon-loading loading" />
<h2>{{ t('bookmarks', 'Previews') }}</h2>
<p>
{{ t('bookmarks', 'In order to display real screenshots of your bookmarked websites, Bookmarks can use a third-party service to generate those.') }}
{{
t(
'bookmarks',
'In order to display real screenshots of your bookmarked websites, Bookmarks can use a third-party service to generate those.'
)
}}
</p>
<h3>{{ t('bookmarks', 'Screeenly') }}</h3>
<p>
{{ t('bookmarks', 'You can either sign up for free at screeenly.com or setup your own server.') }}
{{
t(
'bookmarks',
'You can either sign up for free at screeenly.com or setup your own server.'
)
}}
</p>
<p>
<label>{{ t('bookmarks', 'Screeenly API URL') }}
<input v-model="settings['previews.screenly.url']" type="text" @input="onChange"></label>
<input
v-model="settings['previews.screenly.url']"
type="text"
@input="onChange"
></label>
</p>
<p>
<label>{{ t('bookmarks','Screeenly API key') }}
<input v-model="settings['previews.screenly.token']" type="text" @input="onChange"></label>
<label>{{ t('bookmarks', 'Screeenly API key') }}
<input
v-model="settings['previews.screenly.token']"
type="text"
@input="onChange"
></label>
</p>
<h2>{{ t('bookmarks', 'Privacy') }}</h2>
<p>
{{
t(
'bookmarks',
'Bookmarks will try to access web pages that you add to automatically add information about them.'
)
}}
</p>
<p>
<input
id="enableScraping"
v-model="settings['privacy.enableScraping']"
type="checkbox"
class="checkbox"
@input="onChange"
>
<label for="enableScraping">{{
t(
'bookmarks',
'Enable accessing and collecting information from the web pages you add'
)
}}</label>
</p>
</div>
</template>
<script>
const SETTINGS = ['previews.screenly.url', 'previews.screenly.token'];
const SETTINGS = [
'previews.screenly.url',
'previews.screenly.token',
'privacy.enableScraping'
];
export default {
name: 'ViewAdmin',
@ -46,6 +92,9 @@ export default {
try {
for (const setting of SETTINGS) {
this.settings[setting] = await this.getValue(setting);
if (['true', 'false'].includes(this.settings[setting])) {
this.settings[setting] = (this.settings[setting] === 'true');
}
}
} catch (e) {
this.error = this.t('bookmarks', 'Failed to load settings');
@ -73,10 +122,12 @@ export default {
async setValue(setting, value) {
try {
await new Promise((resolve, reject) => OCP.AppConfig.setValue('bookmarks', setting, value, {
success: resolve,
error: reject
}));
await new Promise((resolve, reject) =>
OCP.AppConfig.setValue('bookmarks', setting, value, {
success: resolve,
error: reject
})
);
} catch (e) {
this.error = this.t('bookmarks', 'Failed to save settings');
throw e;
@ -85,10 +136,12 @@ export default {
async getValue(setting) {
try {
const resDocument = await new Promise((resolve, reject) => OCP.AppConfig.getValue('bookmarks', setting, null, {
success: resolve,
error: reject
}));
const resDocument = await new Promise((resolve, reject) =>
OCP.AppConfig.getValue('bookmarks', setting, null, {
success: resolve,
error: reject
})
);
if (resDocument.querySelector('status').textContent !== 'ok') {
this.error = this.t('bookmarks', 'Failed to load settings');
console.error('Failed request', resDocument);
@ -105,7 +158,7 @@ export default {
};
</script>
<style>
figure[class^=icon-] {
figure[class^='icon-'] {
display: inline-block;
}