New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[IMP] website: fallback on odoo social by default in all cases #162375
Conversation
@JKE-be Seems like the only flow is when one is emptying manually the main company social fields then creating a website. |
3227588
to
ba3e1c1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not fan to store in db some odoo url that could change in the future.
Imo make more sense to do it in python, e.g. in def social()
controller as fallback, no ?
but really not my war.
It's already hardcoded in the company fields with But indeed, it seems like an even better idea 👍 @http.route(['/website/social/<string:social>'], type='http', auth="public", website=True, sitemap=False)
def social(self, social, **kwargs):
+ default_values = {
+ 'facebook': 'https://www.facebook.com/Odoo',
+ 'github': 'https://github.com/odoo',
+ 'linkedin': 'https://www.linkedin.com/company/odoo',
+ 'youtube': 'https://www.youtube.com/user/OpenERPonlin',
+ 'instagram': 'https://www.instagram.com/explore/tags/odoo/',
+ # etc ...
+ }
- url = getattr(request.website, 'social_%s' % social, False)
+ url = getattr(request.website, 'social_%s' % social, False) or default_values.get(social)
if not url:
raise werkzeug.exceptions.NotFound()
return request.redirect(url, local=False) |
ba3e1c1
to
728ff5b
Compare
This is the diff to switch from default field values at website creation vs fallback when accessing the route. Both seems ok.. Advantage now is that it can be changed easily and not stored, but disadvantage is that if someone empty the field, it will redirect on Odoo social media instead of 404, but in all cases people should not leave social link to a media that they empty so it's not a big deal imo.. |
728ff5b
to
64ab07c
Compare
As discussed on Discord, a possible good solution would have been to fallback on |
64ab07c
to
b0f77af
Compare
b0f77af
to
05901b9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the commit message:
- "depend of" => "depends on" ?
- "have default value set" => "have their default value set" ?
- "should not let" => "should not leave" ?
- "multiple time" => "multiple times"
Is this related to a task ?
Is this not a fix that avoids accidental 404 errors (rather than an imp) ?
05901b9
to
b0f77b2
Compare
Fixed typo.
No, it's just a feedback from the internal team
I think it's a bit in between the fix and the imp, I'd say it tends more in the imp side tho, since there is no real bug but just inconvenience. I also added a test |
b0f77b2
to
0a5dca1
Compare
addons/website/controllers/main.py
Outdated
@http.route(['/website/social/<string:social>'], type='http', auth="public", website=True, sitemap=False) | ||
def social(self, social, **kwargs): | ||
url = getattr(request.website, 'social_%s' % social, False) | ||
url = getattr(request.website, 'social_%s' % social, False) or self._get_social_default_values(social) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't we avoid the security warning with something like:
field_name = f'social_{social}'
url = field_name in request.website and request.website[field_name] or self._get_social_default_values(social)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should not try to avoid security warning just to avoid security warning, it seems more nicely written with getattr
on top of being less diff, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, it's not "hack a way to avoid being detected", IMO it's applying their suggested alternative.
But let's ask for an override to minimize the diff. @odoo/rd-security Edit: the getattr
call existed with the same parameters before the change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that we could also just decide to not protect the route and do request.website[f'social_{social}']
, but since it was like that initially and just a stable quick seo imp, I wouldn't do it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd really rather this was switched to a field access, this is not a case where the getattr
is actually needed / warranted in any way, it's just a bit more convenient. You could try to lobby rd-framework for a get
method on BaseModel
for this sort of situations tho.
Note that if you absolutely don't want to change this you can just add the fallback as a separate assignment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's just a bit more convenient.
It's not about convenience, it's about the controller not returning a 500 error page if requested with a non existing social network. Maybe overkill, but seems like a very short / easy win? It would be easy to just turn it into a simple field access and let it crashes if unknown field, which is probably fine, but now that it was coded like that for ages.. Is it really worth changing?
Note that if you absolutely don't want to change this you can just add the fallback as a separate assignment.
Do you mean 👇 ?
- url = getattr(request.website, 'social_%s' % social, False) or self._get_social_default_urls().get(social)
+ url = getattr(request.website, 'social_%s' % social, False)
+ if not url:
+ url = self._get_social_default_urls().get(social)
if not url:
raise werkzeug.exceptions.NotFound()
return request.redirect(url, local=False)
Just to bypass the required security CI?
It seems to make the code worst just for the sake of bypassing it, isn't it?
Since the code was already there before (I am just adding a fallback), and since it's safe1, it's worth keeping it as is? Less diff, easier to read, less verbose
I'll apply the diff you suggest if you don't want to override the CI (or if there is a real security issue), no problem tho 🤷
Footnotes
-
Well, one could access a
social_x
field on website which is not related to our social network set of fields, but if it's returning the info (can read it), it means there is other ways to get it too, and seems very unlikely ↩
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@odoo/rd-security Would you be able to validate the CI or bounce on the current discussion if you really want to?
As:
- XMO is on timoff
- there is actually no security issue here?
- the diff of this pr is just adding a fallback on top of the discussed code (so not really related)
- I don't want to bypass the security ci by writing (IMHO) code uglier than it could be
It would be nice if it can be approved
addons/website/controllers/main.py
Outdated
@http.route(['/website/social/<string:social>'], type='http', auth="public", website=True, sitemap=False) | ||
def social(self, social, **kwargs): | ||
url = getattr(request.website, 'social_%s' % social, False) | ||
url = getattr(request.website, 'social_%s' % social, False) or self._get_social_default_values(social) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd really rather this was switched to a field access, this is not a case where the getattr
is actually needed / warranted in any way, it's just a bit more convenient. You could try to lobby rd-framework for a get
method on BaseModel
for this sort of situations tho.
Note that if you absolutely don't want to change this you can just add the fallback as a separate assignment.
When a website social media field is empty, it will lead to a 404 page. That's a small issue since the social media links in the website footer and header are leading to 404 "error" pages. This is not ideal for SEO audit etc. And we have noticed multiple times client production websites which had 404 social links. This commit is adding a fallback mechanism to stop serving 404 page but serve Odoo.com social media instead. Seems like a low effort to be 100% sure we don't serve a 404 ever. People should not leave a social link on their website pages if they empty it from the website anyway, so reaching Odoo socials instead or 404 seems correct. Note that all links are copy pasted from the `social_media` module except the instagram account, which was probably not existing 6 years ago so `social_media` used another link to show odoo related posts instead. Note that with demo data, there is a mechanism in place that will use the Odoo social media URLs as default social media URL for the websites. It's done this way: - `base.main_company` company has its social fields populated in XML in `social_media` module - website depends on social_media - website social fields have their default value set to `self.env.ref('base.main_company').social_xxx` in its fields: ```py social_twitter = fields.Char('Twitter Account', default=_default_social_twitter) ```
0a5dca1
to
87f4db7
Compare
The suggestion is not uglier, nor less readable, it’s just two different ways to write the same things but yes I can override if you prefer this way @robodoo override=ci/security and let’s remove this getattr in master please :) I find it a bit odd to fallback on odoo social media btw, it’s incorrect for everybody except us 🤷 |
It's actually already the case for most website, as it's what is hardcoded in Note that for those who empty those fields, they should also remove those media link/icons from the website footer (not only the footer), which most do. |
Note that if But if anyone think it's a bad idea, we could just close this PR, it's also a valid possibility. About the behavior existing outside of this PR (social_media company + default website behavior), I think it might be a bit problematic for visitor to be redirected to Odoo social on client DBs as they could think it's the social media of the DB they are visiting. A bit like Odoo phone number which we removed from the source code for that exact reason. |
quand il y a un doute, il n'y a pas de doute... 404 vs backlink to odoo.com (from probably demo website), One isn't better than the other. |
There is a mechanism in place that will use the Odoo social media URLs as default social media URL for the websites.
It's done this way:
base.main_company
company has its social fields populated in XML insocial_media
moduleself.env.ref('base.main_company').social_xxx
in its fields:But if one does empty those fields on the company, it won't bootstrap those values on website creation.
Maybe some other flows are possible to lead to those empty fields.
Seems like a low effort to be 100% sure we don't have empty fields by default.