Get private item info as anonymous user
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 3
- Forks
- 0
- Avg merge
- 2d 2h
- Merged PRs (30d)
- 3
Description
I have a custom content type which has a RelationChoice field (z3c.relationfield.schema.RelationChoice) called relation.
In this content type view we need to proxy some info of the related item. Let's call this content type Proxy. I have an item of type Proxy, let's call it ProxyItem, and I chose a News Item for the relation field.
If ProxyItem is public and the related News Item is private, I can still access to the News Item fields as the anonymous user. I can see its title, description, etc, in the ProxyItem view.
@eikichi18 and I went through some debugging and found out that the code ProxyItem.relation.to_object returns the related News Item even if it's public.
This is what we tried in a pdb: (_object is the underlying function called by the to_object property)
> /Users/pieronicolli/.buildout/eggs/z3c.relationfield-0.7-py2.7.egg/z3c/relationfield/relation.py(112)_object()
-> try:
(Pdb) l
107 def _object(id):
108 if id is None:
109 return None
110 intids = component.getUtility(IIntIds)
111 import pdb;pdb.set_trace()
112 -> try:
113 return intids.getObject(id)
114 except KeyError:
115 # XXX catching this error is not the right thing to do.
116 # instead, breaking a relation by removing an object should
117 # be caught and the relation should be adjusted that way.
(Pdb) n
> /Users/pieronicolli/.buildout/eggs/z3c.relationfield-0.7-py2.7.egg/z3c/relationfield/relation.py(113)_object()
-> return intids.getObject(id)
(Pdb) s
--Call--
> /Users/pieronicolli/.buildout/eggs/zope.intid-3.7.2-py2.7.egg/zope/intid/__init__.py(71)getObject()
-> def getObject(self, id):
(Pdb) l
66 return list(self.refs.items())
67
68 def __iter__(self):
69 return self.refs.iterkeys()
70
71 -> def getObject(self, id):
72 return self.refs[id]()
73
74 def queryObject(self, id, default=None):
75 r = self.refs.get(id)
76 if r is not None:
(Pdb) n
> /Users/pieronicolli/.buildout/eggs/zope.intid-3.7.2-py2.7.egg/zope/intid/__init__.py(72)getObject()
-> return self.refs[id]()
(Pdb) s
--Call--
> /Users/pieronicolli/.buildout/eggs/five.intid-1.1.2-py2.7.egg/five/intid/keyreference.py(122)__call__()
-> def __call__(self):
(Pdb) l
117 for item in reversed(chain):
118 new_obj = aq_base(item).__of__(new_obj)
119 obj = new_obj
120 return obj
121
122 -> def __call__(self):
123 return self.wrapped_object
124
125 def __hash__(self):
126 return hash((self.dbname,
127 self.object._p_oid,
(Pdb) n
> /Users/pieronicolli/.buildout/eggs/five.intid-1.1.2-py2.7.egg/five/intid/keyreference.py(123)__call__()
-> return self.wrapped_object
(Pdb) s
--Call--
> /Users/pieronicolli/.buildout/eggs/five.intid-1.1.2-py2.7.egg/five/intid/keyreference.py(98)wrapped_object()
-> @property
(Pdb) l
93 # object. Asking the root object on the wrong db can trigger
94 # an POSKeyError.
95 connection = IConnection(self.object).get_connection(self.root_dbname)
96 return connection[self.root_oid]
97
98 -> @property
99 def wrapped_object(self):
100 if self.path is None:
101 return self.object
102 try:
103 obj = self.root.unrestrictedTraverse(self.path)
(Pdb) n
> /Users/pieronicolli/.buildout/eggs/five.intid-1.1.2-py2.7.egg/five/intid/keyreference.py(100)wrapped_object()
-> if self.path is None:
(Pdb) l
95 connection = IConnection(self.object).get_connection(self.root_dbname)
96 return connection[self.root_oid]
97
98 @property
99 def wrapped_object(self):
100 -> if self.path is None:
101 return self.object
102 try:
103 obj = self.root.unrestrictedTraverse(self.path)
104 except (NotFound, AttributeError,):
105 return self.object
(Pdb) self.path
'/Plone/news/my-news-item'
(Pdb) self.object
<NewsItem at my-news-item>
We stopped after noticing the unrestrictedTraverse call, and came here to ask if it's a wanted behavior or if it's not. In case it's not, should we propose a pull request changing that to a restrictedTraverse call? It feels like a possible breaking change.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with five/intid/keyreference.py, especially the wrapped_object property and its unrestrictedTraverse call, then review the relation.py _object path shown in the report. Determine whether traversal should enforce anonymous-user permissions and whether changing it to restricted traversal would be a breaking change. Done means the intended behavior is documented and private related content is not exposed through a public Proxy item.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100