Thank you very much, for the patches.
Awesome work!
I'll review them and incorporate them later more carefully,
but might I ask some spontaneous questions come in my mind.
Of course, things should be handled in RUM
very clean. That's the purpose of a framework to have a reliable
implementation of functionality.
So let me ask, some questions, why I personally do not run into that trouble (that
must have been hard to debug, really sorry).
Actually, you touched some parts of Albertos design,
so as usual, I can only guess of any reasons and
whether it's a bug or feature.
Two reasons
- My main app makes sure (in terms of middleware), that the session is removed
- I wrap in my complete app repoze.tm2 middleware
Actually rum has a cleanup procedure
which should resolve the problem at least at the end of the request
in case, it runs as full_stack, otherwise, cleanup might be the duty
of the mounting app (oh, even if that's good documented, it's still a heavy pitfall).
I cite the cleanup procedure from
RUMAlchemy's repository.
def cleanup(self, app=None):
# Cleans up session if app is full_stack or repository is not attached
# to any app.
if not app or app.config['full_stack']:
if hasattr(self.session_factory, 'remove'):
self.session_factory.remove()
transaction.abort()
So, my first question for analysis is whether you disabled RUM to be full_stack?
I still remember that you would like to have an official RUM release.
I think 0.4 is feature complete (actually I cannot remember all new features).
Of course, I would like to be sure
that there are no problems with our policy.
So, did I really miss some policy checks, or has the insertion of policy checks just been safety.
I personally run often enough against my policy (usually as I do note have established any rules)
for my many, many custom actions in my own app.
So, I am quite confident, that the policy is checked (for any controller action of any controller
derrived from CRUDController) by this rule.
rum.controller:
@call_action.around( prio=48)
def _check_security(next_method, self, routes):
check_on=routes["resource"]
obj=getattr(self, "obj", None)
if obj is not None:
check_on=obj
parent=getattr(self, "parent_obj",None)
if not parent is None:
remote_name=routes['remote_name']
self.app.policy.check(obj=parent, action="show", attr=remote_name)
self.app.policy.check(obj=check_on,action=routes["action"])
return next_method(self, routes)
Do, I miss something? That would be frightened.
IMHO, the only thing, which must be manually checked are
column level permissions.
I think the rest of the second patch is an adjustment to the first patch.
By the way, have you seen
https://www.ohloh.net/p/rum/contributors ?
I would love to enter more of your patches to our repository.
Cheers,
Michael
> --
> You received this message because you are subscribed to the Google Groups "rum-discuss" group.
> To post to this group, send email to rum-d...@googlegroups.com.
> To unsubscribe from this group, send email to rum-discuss...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/rum-discuss?hl=en.
-------------------------------------------
Dr. rer. nat. Michael Brickenstein
Mathematisches Forschungsinstitut Oberwolfach gGmbH
Schwarzwaldstr. 9 - 11
77709 Oberwolfach
Tel.: 07834/979-31
Fax: 07834/979-38
> Hi Michael,
>
> Sorry it took me so long to answer your questions.
> At the time I wrote the patch, I was using rum-0.3dev_20100617. I
> wanted to take some time to make sure I could still reproduce this on
> the latest release of rum-0.4.
>
> So, I have now set up a working platform with rum-0.4, and I still
> have the same issue. Here's some additional information:
>
> Indeed, its seems the policy is already checked on the class itself by
> the method you copied.
> I don't know why, but the method is never called in my case. I'll try
> to write a simple reproducable testcase later.
I do not know about your case.
But create/update really work a little bit differently.
In the first case, the policy is only checked for the
resource ('create an new instance of that resource')
and in the the second
case it can be checked for a particular instance.
This means, in the case of 'create' the resource/class is passed to your
policy checker function.
> On the other hand, the checks on individual columns/fields work
> perfectly, with my custom policy being called for each column as it
> should.
> The feature I wanted to implement in my policy was a full object check
> (testing the values of several columns together to determine whether
> the action on the object as a whole should be allowed or not).
> My use case for this is: I have several criteria the depend on the
> value of two or more DB columns. Those criteria are complex enough
> that they would be impractical to implement at the DBMS level using
> CHECK constraints or triggers.
>
> Therefore, the patch makes a second call to the policy *AFTER* the
> object as a whole has been created/updated so that my policy can do
> whatever complex checks it needs to do before the object in committed
> into the database (note: the change in RumAlchemy prevents the object
> from being committed immediately after it was updated, so as to make
> this possible).
>
> I don't have a very deep knowledge of rum, so there may be another
> (better/easier) way to achieve this.
Hmm, let's talk about *better*. Easier is more difficult.
I am not sure, whether your use case is really security
or some constraints.
In the last case, it would not be right to do it with the policy.
Do you think, that you could express it as chained/compound validators?
http://formencode.org/Validator.html#id7
If you think so, I can help you to
add this validator to the autogenerated form.
Another way might be subclassing the
CRUDController registering a custom controller.
This is actually very easy.
Cheers,
Michael
I noticed problems with error display and unicode myself, some
time before.
At that time, I noticed that the bug is not specific to rum but
to the generated error controllers of my Pylons application.
Unfortunately I had to postpone fixing it.
Now, I have reinvestigated the issue.
File "/home/michael/owpdbenv/lib/python2.6/site-packages/Pylons-1.0-py2.6.egg/pylons/controllers/core.py", line 105, in _inspect_call
result = self._perform_call(func, args)
File "/home/michael/owpdbenv/lib/python2.6/site-packages/Pylons-1.0-py2.6.egg/pylons/controllers/core.py", line 57, in _perform_call
return func(**args)
File "/mnt/hgfs/programming/owconf/owconf/controllers/error.py", line 26, in document
content = literal(resp.body) or cgi.escape(request.GET.get('message', ''))
File "/home/michael/owpdbenv/lib/python2.6/site-packages/MarkupSafe-0.11-py2.6-linux-i686.egg/markupsafe/__init__.py", line 71, in __new__
return unicode.__new__(cls, base)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 160: ordinal not in range(128)
Since, that's really a problem of the hosting application, I can only hope
that you have encountered a similar problem and my
following solution helps you.
--- a/owconf/controllers/error.py Tue Mar 15 10:53:39 2011 +0100
+++ b/owconf/controllers/error.py Mon Mar 28 01:52:43 2011 -0700
@@ -4,7 +4,9 @@
from pylons import request
from pylons.controllers.util import forward
from pylons.middleware import error_document_template
-from webhelpers.html.builder import literal
+from webhelpers.html.builder import literal as literal_
+
+
from owconf.lib.base import BaseController
@@ -23,6 +25,12 @@
def document(self):
"""Render the error document"""
resp = request.environ.get('pylons.original_response')
+ def literal(l):
+ if isinstance(l, str):
+ default_charset=getattr(resp, 'default_charset', None)
+ if default_charset:
+ l= l.decode(default_charset)
+ return literal_(l)
content = literal(resp.body) or cgi.escape(request.GET.get('message', ''))
page = error_document_template % \
dict(prefix=request.environ.get('SCRIPT_NAME', ''),
Best regards from not so far from France,
Michael
Am 24.03.2011 um 18:35 schrieb F. Poirotte:
>>
>>
>
> I'm using the policy to do constraint checks.
> I'm not sure if compound validators could help me here because the
> constraints need to fetch data from several other tables and I see a
> simple way to do that using formencode (without having to roll my own
> validators).
> The subclassing approaching might work just fine however (I recently
> started reading the "MoreThanCrud" page on the wiki, and I start to
> see how it could be of use here). I'll try it out and keep you posted.
>
> On another note, I got an error when raising a Denial exception which
> contains accentuated characters from the policy.
> Part of the code seems to expect the Denial's message to be of type
> str while others seem to assume unicode.
> I'll probably start a new thread and/or file a bug report for that
> separate issue though.
>
> Thanks again for your valuable inputs,
> François
>
Passing unicode is definitively the way
to go.
In principle, I did the same thing this morning.
Without more brain twisting, I cannot give any reasons why you ran into trouble, and
why your patch helped.
But it looks very, very reasonable.
I pushed it to our repositories.
http://hg.python-rum.org/rum/rev/cf9a24d8ecb3
Thanks a lot :-),
Michael
> For more options, visit this group at http://groups.google.com/group/rum-discuss?hl=en.