1
0
Fork 0
mirror of https://github.com/wallabag/wallabag.git synced 2025-07-22 17:18:37 +00:00

Allow other fields to be send using API

Entry API can now have these new fields:
- content
- language
- preview_picture
- published_at

Re-use the ContentProxy to be able to do the same using the web UI (in the future).
htmLawed is used to clean stuff from content, I hope it’ll be enough to avoid security breach.

Lower content validation when we want to update an entry with content already defined. Before, language & content_type were required. If there weren’t provided, we re-fetched the content using graby. I think these fields aren’t required for an entry to be created. So I removed them.
Which means some import from the v1 export won’t be re-fetched since they provide content, url & title.

Also, remove liberation link from Readability import to avoid overlaping import (from wallabag v1, which had the same link)
This commit is contained in:
Jeremy Benoist 2017-05-11 08:14:29 +02:00
parent 4423b88c5b
commit e668a8124c
No known key found for this signature in database
GPG key ID: BCA73962457ACC3C
7 changed files with 74 additions and 43 deletions

View file

@ -280,6 +280,10 @@ class EntryRestController extends WallabagRestController
* {"name"="tags", "dataType"="string", "required"=false, "format"="tag1,tag2,tag3", "description"="a comma-separated list of tags."},
* {"name"="starred", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="entry already starred"},
* {"name"="archive", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="entry already archived"},
* {"name"="content", "dataType"="string", "required"=false, "description"="Content of the entry"},
* {"name"="language", "dataType"="string", "required"=false, "description"="Language of the entry"},
* {"name"="preview_picture", "dataType"="string", "required"=false, "description"="Preview picture of the entry"},
* {"name"="published_at", "dataType"="datetime", "format"="YYYY-MM-DDTHH:II:SS+TZ", "required"=false, "description"="Published date of the entry"},
* }
* )
*
@ -293,30 +297,42 @@ class EntryRestController extends WallabagRestController
$title = $request->request->get('title');
$isArchived = $request->request->get('archive');
$isStarred = $request->request->get('starred');
$content = $request->request->get('content');
$language = $request->request->get('language');
$picture = $request->request->get('preview_picture');
$publishedAt = $request->request->get('published_at');
$entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId($url, $this->getUser()->getId());
if (false === $entry) {
$entry = new Entry($this->getUser());
try {
$entry = $this->get('wallabag_core.content_proxy')->updateEntry(
$entry,
$url
);
} catch (\Exception $e) {
$this->get('logger')->error('Error while saving an entry', [
'exception' => $e,
'entry' => $entry,
]);
$entry->setUrl($url);
}
}
if (!is_null($title)) {
$entry->setTitle($title);
try {
$entry = $this->get('wallabag_core.content_proxy')->updateEntry(
$entry,
$url,
[
'title' => $title,
'html' => $content,
'url' => $url,
'language' => $language,
'date' => $publishedAt,
// faking the preview picture
'open_graph' => [
'og_image' => $picture,
],
]
);
} catch (\Exception $e) {
$this->get('logger')->error('Error while saving an entry', [
'exception' => $e,
'entry' => $entry,
]);
$entry->setUrl($url);
}
$tags = $request->request->get('tags', '');
$tags = $request->request->get('tags', []);
if (!empty($tags)) {
$this->get('wallabag_core.tags_assigner')->assignTagsToEntry($entry, $tags);
}

View file

@ -45,6 +45,18 @@ class ContentProxy
*/
public function updateEntry(Entry $entry, $url, array $content = [])
{
// ensure content is a bit cleaned up
if (!empty($content['html'])) {
$content['html'] = htmLawed($content['html'], [
'safe' => 1,
// which means: do not remove iframe elements
'elements' => '*+iframe',
'deny_attribute' => 'style',
'comment' => 1,
'cdata' => 1,
]);
}
// do we have to fetch the content or the provided one is ok?
if (empty($content) || false === $this->validateContent($content)) {
$fetchedContent = $this->graby->fetchContent($url);
@ -57,7 +69,7 @@ class ContentProxy
}
$title = $content['title'];
if (!$title && isset($content['open_graph']['og_title'])) {
if (!$title && !empty($content['open_graph']['og_title'])) {
$title = $content['open_graph']['og_title'];
}
@ -65,7 +77,7 @@ class ContentProxy
if (false === $html) {
$html = $this->fetchingErrorMessage;
if (isset($content['open_graph']['og_description'])) {
if (!empty($content['open_graph']['og_description'])) {
$html .= '<p><i>But we found a short description: </i></p>';
$html .= $content['open_graph']['og_description'];
}
@ -76,8 +88,12 @@ class ContentProxy
$entry->setContent($html);
$entry->setHttpStatus(isset($content['status']) ? $content['status'] : '');
if (isset($content['date']) && null !== $content['date'] && '' !== $content['date']) {
$entry->setPublishedAt(new \DateTime($content['date']));
if (!empty($content['date'])) {
try {
$entry->setPublishedAt(new \DateTime($content['date']));
} catch (\Exception $e) {
$this->logger->warn('Error while defining date', ['e' => $e, 'url' => $url, 'date' => $content['date']]);
}
}
if (!empty($content['authors'])) {
@ -97,12 +113,12 @@ class ContentProxy
$entry->setDomainName($domainName);
}
if (isset($content['open_graph']['og_image']) && $content['open_graph']['og_image']) {
if (!empty($content['open_graph']['og_image'])) {
$entry->setPreviewPicture($content['open_graph']['og_image']);
}
// if content is an image define as a preview too
if (isset($content['content_type']) && in_array($this->mimeGuesser->guess($content['content_type']), ['jpeg', 'jpg', 'gif', 'png'], true)) {
if (!empty($content['content_type']) && in_array($this->mimeGuesser->guess($content['content_type']), ['jpeg', 'jpg', 'gif', 'png'], true)) {
$entry->setPreviewPicture($content['url']);
}
@ -128,6 +144,6 @@ class ContentProxy
*/
private function validateContent(array $content)
{
return isset($content['title']) && isset($content['html']) && isset($content['url']) && isset($content['language']) && isset($content['content_type']);
return !empty($content['title']) && !empty($content['html']) && !empty($content['url']);
}
}