While XOTcl has a way to ask to query the object that is calling the current procedure, there does not seem to be a way to find out which object was 'previous' on the stack. I'll illustrate:
Class C
C instproc hello {} { puts "Hello, [self callingobject]" }
C instproc do {} { my hello }
Now if I call [hello] from another object, I will get the object which called [hello]. Of course, if that object calls [do] instead of [hello], then [self callingobject] will end up being the same as [self]. [uplevel] doesn't help here as [self callingobject] will always return the same, whatever stack level I call it from (is this a bug or intentional?). Basically there is no way to check "caller of caller" or, indeed, the "original caller" — ie. the object before [self] which initiated the process.
The reason I want to do this is that I have an access control system which calls something like [checkPermissions]. [checkPermissions] should just return and do nothing if the original calling object is equal to [self]. Now I end up having to passs [checkPermissions] a parameter with [self callingobject].
I guess I could also do this with a filter but that might be overkill for something so simple.
Kristoffer,
[uplevel] doesn't help here as [self callingobject] will always return the same, whatever stack level I call it from (is this a bug or intentional?). Basically there is no way to check "caller of caller".
indeed, i checked the code behind [self callingobject] (and its like, e.g. [self callinglevel]) and it appears to me that this family is not [uplevel]-aware. If you compare with [self proc], you will find that this actually is (also in your example). I spotted the code which unwinds the hybrid xotcl/tcl callstack under [uplevel]. the patch below attached to the email fixes the behaviour and [make test] runs, but i might easily miss sth. out here.
@gustaf neumann: could you please check the patch? i also have the feeling that some refactoring can be done in XOTclCallStackFindLastInvocation(). the patch is against the git master branch (1.6.6).
in the new and rewritten callstack management and introspection for the upcoming major release, this has been solved (i checked it with your example).
Basically there is no way to check "caller of caller".
well, you already guessed in the right direction: provide a filter and manage reentrant/self-directed messages accordingly. so you could keep track of the initial caller of the caller (which is not self).
i am also not quite sure whether "the caller of the caller" makes sense in an "invocation access control" scenario, as the caller-caller was already allowed access to the object (i.e., by calling do()). so a friendclass-like approach would not need that, for instance. while a eiffel-kind of feature export would certainly do. but anyway, in xotcl, nothing is written in stone anyways :)
//stefan
Hi Kristoffer and all
Am 09.07.10 16:11, schrieb Kristoffer Lawson:
Now if I call [hello] from another object, I will get the object which called [hello]. Of course, if that object calls [do] instead of [hello], then [self callingobject] will end up being the same as [self]. [uplevel] doesn't help here as [self callingobject] will always return the same, whatever stack level I call it from (is this a bug or intentional?).
not sure, if it was intentional or not, but you observation is right.
the xotcl 0.* and 1.* series is based on an implementation with a private call stack (in tcl versions before the 8.5, there was no way to extend the tcl call-stack frames with oo specific client-data, tcloo needed this as well, an so tcl got it). the forthcoming 2.0 version has a unified stack (among many other things), so much behavior does not have to re-programmed in xotcl (keeping two stacks on sync).
xotcl 2.0 has this problem magically solved (stefan's patch seems fine as well for the 1.* series from the distance).
The reason I want to do this is that I have an access control system which calls something like [checkPermissions]. [checkPermissions] should just return and do nothing if the original calling object is equal to [self]. Now I end up having to passs [checkPermissions] a parameter with [self callingobject].
I am somewhat confused by your terminology. If you are looking for access control management, look for example at xoRBAC, which follows the role based access control model, standardized by the NIST http://wi.wu-wien.ac.at:8002/home/mark/xoRBAC/index.html
the basic notion in access control is based on <subject> <pred> <object> idea, which subject (individual, user) is allowed to execute which operations (pred) on which objects.
From later mails, it seems that you looking for calling-protection, where the basic question is: which object is allowed to execute which functions/methods. xotcl 2.0 has as well here some efficient built-in mechanisms to implement "static" methods, that are designed to work with the basic xotcl object model (per-class cs. per object, mixins, ...). It costs essentially no performance. This is not a strong protection, but signals maybe unwanted patterns (from a documentation and implementation point of view).
Is protection needed or not? For projects of small teams (1-2 persons), there is in my opinion very little need for that. for larger projects (10-thousands lines of code, developers with different skill levels), some mechanisms flagging the programmers intentions is useful. I was already thinking about optional mechanisms to force all methods to be static by default unless they are defined as public. This would lead automatically to classes with defined primarily interfaces, but this is still just an idea, not sure how this would work out in practice. maybe the option for this will make it into the release.
-gustaf
On 10 Jul 2010, at 09:38, Gustaf Neumann wrote:
I am somewhat confused by your terminology. If you are looking for access control management, look for example at xoRBAC, which follows the role based access control model, standardized by the NIST http://wi.wu-wien.ac.at:8002/home/mark/xoRBAC/index.html
Thanks, Gustaf, for bringing this up. I'll be looking at this.
the basic notion in access control is based on <subject> <pred> <object> idea, which subject (individual, user) is allowed to execute which operations (pred) on which objects.
Yes, I am aware of this, if only on a vague level (having so far avoided the need). As this is all to do with describing, in a web framework, which users are allowed to do what, on the lowest level, this may be overkill. But maybe not.
At the moment I've been experimenting with the idea, stolen from UNIX file permissions, that each object has an owner and a group — both of which are optional. Each object has a set of easy UNIX style permissions, but with the additional concept of a 'friend'. So rwxrwxrwxrwx
That is to say what kind of permissions the user has, the user's friends (if defined), members of the group the object belongs to, and other users.
Each method for the object can be defined to be a read, a write or an 'execute' method (like "Send Email"). The system checks the currently logged in user, the method being called, and the access that user has. Later ACLs could be added.
There may be serious drawbacks with this idea, as I'm just experimenting, but it feels appealingly simple. The benefit of simplicity is that then it is almost no effort to specify a base level of access. That means people actually bother doing it, which then leads to better security :-)