From 1ab9455a9abce75ca2de9b208316acccf5a38dac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Warnon?= Date: Fri, 1 Oct 2021 08:55:26 +0000 Subject: [PATCH 1/4] [IMP] website_slides: refactor slide.slide embed detection This commit slightly changes the embed detection for slides. Currently, we use the same URL to embed slide content within the e-learning module and when the end-user wants to embed that content on an external website. However, we want to know whether the slide is embedded externally or not to show different controls and update some statistics. The code previously relied on the presence of the "referer" header to achieve that detection, if the referer URL comes from a domain that is not this Odoo website -> then it's embedded externally. The issue with that strategy is that it's not very reliable, indeed some modern browsers now completely avoid passing the referer header (mostly for security and privacy reasons). Instead, we change this to let users embed on external websites with a *different* URL. When the embed comes from '/embed_external/', we now easily know that it comes from an external embed and don't have to do some further and potentially tricky processing. We introduced a computed 'embed_code_external' field that is computed the same way as the embed_code except for that small route distinction. This also easily solves any issue that could come with multi-website / different root URLs etc. Task-2654009 Part-of: odoo/odoo#77736 --- addons/website_slides/controllers/main.py | 36 +++++++++++++------ addons/website_slides/models/slide_slide.py | 17 +++++++-- .../views/website_slides_templates_lesson.xml | 5 ++- .../website_slides_templates_lesson_embed.xml | 4 +-- 4 files changed, 45 insertions(+), 17 deletions(-) diff --git a/addons/website_slides/controllers/main.py b/addons/website_slides/controllers/main.py index b1c53ed86ab..e4141799000 100644 --- a/addons/website_slides/controllers/main.py +++ b/addons/website_slides/controllers/main.py @@ -1133,22 +1133,36 @@ class WebsiteSlides(WebsiteProfile): @http.route('/slides/embed/', type='http', auth='public', website=True, sitemap=False) def slides_embed(self, slide_id, page="1", **kw): - # Note : don't use the 'model' in the route (use 'slide_id'), otherwise if public cannot access the embedded - # slide, the error will be the website.403 page instead of the one of the website_slides.embed_slide. - # Do not forget the rendering here will be displayed in the embedded iframe + return self._slide_embed(slide_id, page=page, is_external_embed=False, **kw) + + @http.route('/slides/embed_external/', type='http', auth='public', website=True, sitemap=False) + def slides_embed_external(self, slide_id, page="1", **kw): + return self._slide_embed(slide_id, page=page, is_external_embed=True, **kw) + + def _slide_embed(self, slide_id, page="1", is_external_embed=False, **kw): + """ Note : don't use the 'model' in the route (use 'slide_id'), otherwise if public cannot + access the embedded slide, the error will be the website.403 page instead of the one of the + website_slides.embed_slide. + + Do not forget the rendering here will be displayed in the embedded iframe + + Try accessing slide, and display to corresponding template. + + When the content is embedded *externally*, meaning on a third party website, we do some + additional steps like displaying sharing controls and also updating some KPIs. """ - # try accessing slide, and display to corresponding template try: slide = request.env['slide.slide'].browse(slide_id) - # determine if it is embedded from external web page - referrer_url = request.httprequest.headers.get('Referer', '') - base_url = slide.get_base_url() - is_embedded = referrer_url and not bool(base_url in referrer_url) or False - if is_embedded: - request.env['slide.embed'].sudo()._add_embed_url(slide.id, referrer_url) + referer_url = request.httprequest.headers.get('Referer', '') + if is_external_embed and referer_url: + request.env['slide.embed'].sudo()._add_embed_url( + slide.id, + referer_url + ) + values = self._get_slide_detail(slide) values['page'] = page - values['is_embedded'] = is_embedded + values['is_external_embed'] = is_external_embed self._set_viewed_slide(slide) return request.render('website_slides.embed_slide', values) except AccessError: # TODO : please, make it clean one day, or find another secure way to detect diff --git a/addons/website_slides/models/slide_slide.py b/addons/website_slides/models/slide_slide.py index ed11dcf1116..3ebb23d7899 100644 --- a/addons/website_slides/models/slide_slide.py +++ b/addons/website_slides/models/slide_slide.py @@ -10,6 +10,7 @@ import PyPDF2 import json from dateutil.relativedelta import relativedelta +from markupsafe import Markup from PIL import Image from werkzeug import urls @@ -165,6 +166,8 @@ class Slide(models.Model): dislikes = fields.Integer('Dislikes', compute='_compute_user_info', store=True, compute_sudo=False) user_vote = fields.Integer('User vote', compute='_compute_user_info', compute_sudo=False) embed_code = fields.Html('Embed Code', readonly=True, compute='_compute_embed_code', sanitize=False) + embed_code_external = fields.Html('External Embed Code', readonly=True, compute='_compute_embed_code', sanitize=False, + help="Same as 'Embed Code' but used to embed the content on an external website.") # views embedcount_ids = fields.One2many('slide.embed', 'slide_id', string="Embed Count") slide_views = fields.Integer('# of Website Views', store=True, compute="_compute_slide_views") @@ -320,26 +323,34 @@ class Slide(models.Model): @api.depends('document_id', 'slide_type', 'mime_type') def _compute_embed_code(self): base_url = request and request.httprequest.url_root + for record in self: + embed_code_external = False + if not base_url: base_url = record.get_base_url() if base_url[-1] == '/': base_url = base_url[:-1] if record.datas and (not record.document_id or record.slide_type in ['document', 'presentation']): slide_url = base_url + url_for('/slides/embed/%s?page=1' % record.id) - record.embed_code = '' % (slide_url, 315, 420) + slide_url_external = base_url + url_for('/slides/embed_external/%s?page=1' % record.id) + base_embed_code = Markup('') + record.embed_code = base_embed_code % (slide_url, 315, 420) + embed_code_external = base_embed_code % (slide_url_external, 315, 420) elif record.slide_type == 'video' and record.document_id: if not record.mime_type: # embed youtube video query = urls.url_parse(record.url).query query = query + '&theme=light' if query else 'theme=light' - record.embed_code = '' % (record.document_id, query) + record.embed_code = Markup('') % (record.document_id, query) else: # embed google doc video - record.embed_code = '' % (record.document_id) + record.embed_code = Markup('') % (record.document_id) else: record.embed_code = False + record.embed_code_external = embed_code_external or record.embed_code + @api.onchange('url') def _on_change_url(self): self.ensure_one() diff --git a/addons/website_slides/views/website_slides_templates_lesson.xml b/addons/website_slides/views/website_slides_templates_lesson.xml index 5896f2c6520..a8fca2cf76d 100644 --- a/addons/website_slides/views/website_slides_templates_lesson.xml +++ b/addons/website_slides/views/website_slides_templates_lesson.xml @@ -552,7 +552,10 @@
Embed in your website
- +
Select page to start with
diff --git a/addons/website_slides/views/website_slides_templates_lesson_embed.xml b/addons/website_slides/views/website_slides_templates_lesson_embed.xml index b5edd67fe96..14852a4b2c0 100644 --- a/addons/website_slides/views/website_slides_templates_lesson_embed.xml +++ b/addons/website_slides/views/website_slides_templates_lesson_embed.xml @@ -17,7 +17,7 @@
-
+
@@ -41,7 +41,7 @@ t-attf-data-slideurl="/slides/slide/#{slug(slide)}/pdf_content" t-attf-data-downloadable="#{False}" t-att-data-defaultpage="page"> - + -
+
Select page to start with
diff --git a/addons/website_slides/views/website_slides_templates_lesson_embed.xml b/addons/website_slides/views/website_slides_templates_lesson_embed.xml index 14852a4b2c0..da6d018c82b 100644 --- a/addons/website_slides/views/website_slides_templates_lesson_embed.xml +++ b/addons/website_slides/views/website_slides_templates_lesson_embed.xml @@ -28,9 +28,10 @@
@@ -42,18 +43,12 @@ t-attf-data-downloadable="#{False}" t-att-data-defaultpage="page"> - - - + + + + + +
diff --git a/addons/website_slides/views/website_slides_templates_utils.xml b/addons/website_slides/views/website_slides_templates_utils.xml index 0066097e032..885f0d9c056 100644 --- a/addons/website_slides/views/website_slides_templates_utils.xml +++ b/addons/website_slides/views/website_slides_templates_utils.xml @@ -4,9 +4,18 @@ @@ -41,11 +50,12 @@
Share on Social Networks
+