Skip to content
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

Let creatorsDefault return None for anonymous user (fixes plone/plone.app.vocabularies/issues/59) #311

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

fulv
Copy link
Member

@fulv fulv commented Aug 6, 2020

This would fix plone/plone.app.vocabularies#59, but I'm only floating this change as an idea, hoping for some feedback.

z3c.form.widget.Widget.update() passes the result of creatorsDefault (which is called by an IValue adapter's get() method) to plone.app.z3cform.converters.AjaxSelectWidgetConverter.toWidgetValue().

getSecurityManager().getUser() returns a regular <PropertiedUser> for most requests and thus the return value is a tuple, e.g. ('admin',).

However, for ajax requests, e.g. /++add++MyContentType/++widget++form.widgets.IMyBehavior.behavior_field, the user is anonymous:

(Pdb) user
<SpecialUser 'Anonymous User'>
(Pdb) pp user.__dict__
{'__': '', 'domains': [], 'name': 'Anonymous User', 'roles': ('Anonymous',)}

Thus, the return value is the tuple (None,). This breaks AjaxSelectWidgets when the content type includes the Dublin Core behavior or just the ownership field, even though the field itself is a RelationList with a value_type=RelationChoice( source=CatalogSource(portal_type='MyContentType) ). In other words, even though the broken field has no need for the item's creator, the creator gets calculated anyway when the request is handled.

The problem with the tuple (None,) is that toWidgetValue() does not know how to deal with it and so it returns None instead of field.missing_value as it should.

This could be fixed in at least four different places:

  1. plone.app.dexterity.behaviors.metadata.creatorsDefault
  2. plone.app.z3cform.converters.AjaxSelectWidgetConverter.toWidgetValue
  3. z3c.form.widget.Widget.update
  4. have getSecurityManager().getUser() return the logged in user even on Ajax requests.
  • (1.) is the origin of the unexpected value, however, I don't know if making it return None for anonymous users would make any other code mad.
  • (2.) is the place that does not expect a (None,) tuple instead of None, so this could be fixed by simply adding a check for (None,).
  • (3.) is the "middleman" between 1 and 2, so it could convert (None,) to None before passing it on.
  • (4.) I have no idea what this would entail.

I'll add tests and changelog, etc if this is the way to go.

This would fix plone/plone.app.vocabularies#59, but I'm only floating this change as an idea, hoping for some feedback.

`z3c.form.widget.Widget.update()` passes the result of `creatorsDefault` (which is called by an `IValue` adapter's `get()` method) to `plone.app.z3cform.converters.AjaxSelectWidgetConverter.toWidgetValue()`.

`getSecurityManager().getUser()` returns a regular `<PropertiedUser>` for most requests and thus the return value is a tuple, e.g. `('admin',)`.

However, for ajax requests, e.g. `/++add++MyContentType/++widget++form.widgets.IMyBehavior.behavior_field`, the user is anonymous:

```
(Pdb) user
<SpecialUser 'Anonymous User'>
(Pdb) pp user.__dict__
{'__': '', 'domains': [], 'name': 'Anonymous User', 'roles': ('Anonymous',)}
```

Thus, the return value is the tuple `(None,)`.  This breaks `AjaxSelectWidgets` when the content type includes the Dublin Core behavior or just the ownership field, even though the field itself is a `RelationList` with a `value_type=RelationChoice( source=CatalogSource(portal_type='MyContentType) )`.  In other words, even though the broken field has no need for the item's creator, the creator gets calculated anyway when the request is handled.

The problem with the tuple `(None,)` is that `toWidgetValue()` does not know how to deal with it and so it returns `None` instead of `field.missing_value` as it should.

This could be fixed in at least four different places:

1. plone.app.dexterity.behaviors.metadata.creatorsDefault
2. plone.app.z3cform.converters.AjaxSelectWidgetConverter.toWidgetValue
3. z3c.form.widget.Widget.update
4. have getSecurityManager().getUser() return the logged in user even on Ajax requests.

1. is the origin of the unexpected value, however, I don't know if making it return `None` for anonymous users would make any other code mad.
2. is the place that does not expect a `(None,)` tuple instead of `None`, so this could be fixed by simply adding a check for `(None,)`.
3. is the "middleman" between 1 and 2, so it could convert `(None,)` to `None` before passing it on.
4. I have no idea what this would entail.
@mister-roboto
Copy link

@fulv thanks for creating this Pull Request and help improve Plone!

To ensure that these changes do not break other parts of Plone, the Plone test suite matrix needs to pass.

Whenever you feel that the pull request is ready to be tested, either start all jenkins jobs pull requests by yourself, or simply add a comment in this pull request stating:

@jenkins-plone-org please run jobs

With this simple comment all the jobs will be started automatically.

Happy hacking!

@pbauer
Copy link
Member

pbauer commented Sep 8, 2020

@jenkins-plone-org please run jobs

@jensens
Copy link
Member

jensens commented Sep 8, 2020

I think this one is fine. (except that the changelog/news entry is missing)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

RelationChoice field leads to ValueError in principals
4 participants