Skip to content

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

Open
fulv wants to merge 1 commit into
masterfrom
fulv-patch-1
Open

Let creatorsDefault return None for anonymous user (fixes plone/plone.app.vocabularies/issues/59)#311
fulv wants to merge 1 commit into
masterfrom
fulv-patch-1

Conversation

@fulv

@fulv fulv commented Aug 6, 2020

Copy link
Copy Markdown
Member

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
Copy Markdown

@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

pbauer commented Sep 8, 2020

Copy link
Copy Markdown
Member

@jenkins-plone-org please run jobs

@jensens

jensens commented Sep 8, 2020

Copy link
Copy Markdown
Member

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