
Hi again. I have read the draft implementation of guard in Valentino's sandbox and I like it. However I have some questions: - why the ISessionMenager interface does not include a name attribute (since the default Session class uses the private _name)? - why Session.authenticatedAs has to be a property? - I think that there is no need to store tha password but only the username, so authenticatedAs -> avatarID - what's the use for the guard attribute in Session? - I think that ISessionManager should not have the loggedIn method. - as I can see the code in SessionManager._tick causes the log "Session %r expired" to be issued two times. - what's the use for mind in a web authentication? - why credInterface is a variable? It can be something different from IResource? - Session.sessionLifetime is only used on the server side but never set on the cookie. Only persistent cookies have a not null expiration date. - As I can see in SessionWrappper.locateChild the code request.session = session is executed twice (the first time in getSession. Thanks Manlio Perillo

On Mon, 31 Jul 2006 21:05:26 +0200, Manlio Perillo <manlio_perillo@libero.it> wrote:
Hi again.
I have read the draft implementation of guard in Valentino's sandbox and I like it.
However I have some questions: - why the ISessionMenager interface does not include a name attribute (since the default Session class uses the private _name)?
The reason why it misses the name in the interface is that it's not meant to be accessible from the outside. It's a pretty important internal detail in _this_ SessionManager implementation. There might be many other ways to deal with distributed session rather than simply using name attribute on the sessionmanager and ISessionManager ought to be as generic as possible.
- why Session.authenticatedAs has to be a property?
Because I wasn't able to find a better name that was somewhat compatible to using an explicit get/set. And because it's cleaner IMHO.
- I think that there is no need to store tha password but only the username, so authenticatedAs -> avatarID
Not really... Authentication is rerun for each request because the avatar is not saved and this is the most important detail of that new guard. Also the avatarId is not available in guard because it's a cred implementation detail. And the avatarId might be any object. But I'm open for alternative solutions.
- what's the use for the guard attribute in Session?
It's explained in the docstring of loggedIn (somehow). It's because it makes it easier to access the guard that created the session.
- I think that ISessionManager should not have the loggedIn method.
Why? It allows to change how the application should react to a successfully logged in session without going through guard code overriding a callback, of a very big method, defined as a closure. IMHO it's a lot cleaner to have it this way unless your reasons are sensible.
- as I can see the code in SessionManager._tick causes the log "Session %r expired" to be issued two times.
True.
- what's the use for mind in a web authentication?
I have no idea. There might be a usage, why should you make it impossible to have a usage of it?
- why credInterface is a variable? It can be something different from IResource?
iweb2.IResource? Anyway this is absolutely not a valid concern it's simply a refactoring to allow changing that interface from application level code (again without the need to dig through the code).
- Session.sessionLifetime is only used on the server side but never set on the cookie. Only persistent cookies have a not null expiration date.
True. In fact sessionLifetime is used for transient sessions that die when you restart your browser and from the serverside they last until sessionLifetime is expired. If the session is logged in the cookies are made persistent by default. If you use the persistent session manager you also have the chance to make the session persistent (by using rememberMe url argument in the login form).
- As I can see in SessionWrappper.locateChild the code request.session = session is executed twice (the first time in getSession.
I think you might be right also on this. Although it's not that big of a problem it might be worth fixing it. Just by making getSession automatically set the session on the request (and not only with brand new sessions) and removing all the other places where this assignment is done. And then rerunning tests. Also keep in mind that the most developed version of that code lies in: http://hg.stiq.it/index.cgi/stiq?f=b9671c61c96b;file=stiq/guard.py;style=git... and http://hg.stiq.it/index.cgi/stiq?f=eef00c91fd79;file=stiq/session.py;style=g...

Valentino Volonghi aka Dialtone ha scritto:
On Mon, 31 Jul 2006 21:05:26 +0200, Manlio Perillo <manlio_perillo@libero.it> wrote:
Hi again.
I have read the draft implementation of guard in Valentino's sandbox and I like it.
However I have some questions: - why the ISessionMenager interface does not include a name attribute (since the default Session class uses the private _name)?
The reason why it misses the name in the interface is that it's not meant to be accessible from the outside. It's a pretty important internal detail in _this_ SessionManager implementation. There might be many other ways to deal with distributed session rather than simply using name attribute on the sessionmanager and ISessionManager ought to be as generic as possible.
Ok. Now I also understand your concern about identifying who creates a session. Only a question: in the example you only store (in the database) "permanent" sessions. Not sure about this, but I think that all sessions, except those for anonymous access, should be persisted in the database (to avoid problems in a distributed system).
- why Session.authenticatedAs has to be a property?
Because I wasn't able to find a better name that was somewhat compatible to using an explicit get/set. And because it's cleaner IMHO.
Not sure. ;-)
- I think that there is no need to store tha password but only the username, so authenticatedAs -> avatarID
Not really... Authentication is rerun for each request because the avatar is not saved and this is the most important detail of that new guard.
Here I'm not sure to understand. You mean that the avatarID (username) is not stored in the session object? This seems not the case. Another thing: is it really necessary to create a session for anonymous access? And what about to store the authenticated username in the context (instead of hacking on the site.makeSession)?
Also the avatarId is not available in guard because it's a cred implementation detail. And the avatarId might be any object. But I'm open for alternative solutions.
- what's the use for the guard attribute in Session?
It's explained in the docstring of loggedIn (somehow). It's because it makes it easier to access the guard that created the session.
- I think that ISessionManager should not have the loggedIn method.
Why? It allows to change how the application should react to a successfully logged in session without going through guard code overriding a callback, of a very big method, defined as a closure. IMHO it's a lot cleaner to have it this way unless your reasons are sensible.
I'm against this because I whould like to have a realy reusable SessionManager. The SessionManager is really an useful class and it should not depend over a SessionWrapper (because I can choose to not use a SessionWrapper al all).
- as I can see the code in SessionManager._tick causes the log "Session %r expired" to be issued two times.
True.
- what's the use for mind in a web authentication?
I have no idea. There might be a usage, why should you make it impossible to have a usage of it?
- why credInterface is a variable? It can be something different from IResource?
iweb2.IResource? Anyway this is absolutely not a valid concern it's simply a refactoring to allow changing that interface from application level code (again without the need to dig through the code).
Yes, this is not a valid concern but I like to have code that is as much symple as possible, where I don't have to try to understand every statement. ;-)
[...]
Also keep in mind that the most developed version of that code lies in: http://hg.stiq.it/index.cgi/stiq?f=b9671c61c96b;file=stiq/guard.py;style=git...
and http://hg.stiq.it/index.cgi/stiq?f=eef00c91fd79;file=stiq/session.py;style=g...
Ok, thanks. Now I'm trying to learn as much as possible about web authentication because it seems that it does not exists an unique solution. As an example a valid alternative to store state in the server is to store it in the cookie. NEVOW_SESSION="username=manlio&last_accessed=...&created=..." of course using some cryptography. This has the advantage to work "as is" in a distributed system and to not depend on the number of sessions/users. Thanks and regards Manlio Perillo

On Tue, 01 Aug 2006 10:40:20 +0200, Manlio Perillo <manlio_perillo@libero.it> wrote:
Only a question: in the example you only store (in the database) "permanent" sessions. Not sure about this, but I think that all sessions, except those for anonymous access, should be persisted in the database (to avoid problems in a distributed system).
Not really unless you want your system on its knees begging for some holidays. Just think about the chance for 1M people to visit your website each day. Your sessions database will shortly be the biggest bottleneck of the application.
Here I'm not sure to understand. You mean that the avatarID (username) is not stored in the session object? This seems not the case.
First of all the avatarID is not the username. The avatarID is the avatarID. Then I repeat that I do not store the avatar anywhere which means that I have to pass through portal.login() for each request and portal.login() requires full credentials. Then I cannot get the avatarId because it is only passed to requestAvatar and the SessionWrapper only sees the result of that call.
Another thing: is it really necessary to create a session for anonymous access?
This is an interesting question. I think I'll probably say yes.
And what about to store the authenticated username in the context (instead of hacking on the site.makeSession)?
Maybe you didn't notice but... The context is going away we have been talking about this for ages and using the context means that the code will need to be trashed in not so long.
I'm against this because I whould like to have a realy reusable SessionManager.
The SessionManager is really an useful class and it should not depend over a SessionWrapper (because I can choose to not use a SessionWrapper al all).
And what does this have to do with the loggedIn method? The reason it is like that is because cookies are dealt with in the sessionwrapper and not in the sessionmanager, but having 2 places to check the rememberMe argument was sub-optimal. If you don't need the sessionmanager you can clearly avoid implementing loggedIn at all, but this doesn't mean the rest of the developers don't need such a callback.
Yes, this is not a valid concern but I like to have code that is as much symple as possible, where I don't have to try to understand every statement. ;-)
Which is yet another reason to have it like it is now.
As an example a valid alternative to store state in the server is to store it in the cookie.
NEVOW_SESSION="username=manlio&last_accessed=...&created=..."
of course using some cryptography.
This has the advantage to work "as is" in a distributed system and to not depend on the number of sessions/users.
You will still need a session object on the serverside. Sessions are a serverside detail and saving state in the database is not hard at all. The problem rises when you want to reach consistency between all the servers.

Valentino Volonghi aka Dialtone ha scritto:
On Tue, 01 Aug 2006 10:40:20 +0200, Manlio Perillo <manlio_perillo@libero.it> wrote:
Only a question: in the example you only store (in the database) "permanent" sessions. Not sure about this, but I think that all sessions, except those for anonymous access, should be persisted in the database (to avoid problems in a distributed system).
Not really unless you want your system on its knees begging for some holidays. Just think about the chance for 1M people to visit your website each day. Your sessions database will shortly be the biggest bottleneck of the application.
But then why store sessions in a database at all?
Here I'm not sure to understand. You mean that the avatarID (username) is not stored in the session object? This seems not the case.
First of all the avatarID is not the username. The avatarID is the avatarID. Then I repeat that I do not store the avatar anywhere which means that I have to pass through portal.login() for each request and portal.login() requires full credentials. Then I cannot get the avatarId because it is only passed to requestAvatar and the SessionWrapper only sees the result of that call.
Ok, I missed this.
Another thing: is it really necessary to create a session for anonymous access?
This is an interesting question. I think I'll probably say yes.
I will do some tests.
And what about to store the authenticated username in the context (instead of hacking on the site.makeSession)?
Maybe you didn't notice but... The context is going away we have been talking about this for ages and using the context means that the code will need to be trashed in not so long.
Yes, I know. I was searching for an object with the "right" lifetime, forgetting about the request. By the way: what's the difference beetwen ctx.remember/locate and storing attributes on the context/request?
I'm against this because I whould like to have a realy reusable SessionManager.
The SessionManager is really an useful class and it should not depend over a SessionWrapper (because I can choose to not use a SessionWrapper al all).
And what does this have to do with the loggedIn method? The reason it is like that is because cookies are dealt with in the sessionwrapper and not in the sessionmanager,
Of course!
but having 2 places to check the rememberMe argument was sub-optimal. If you don't need the sessionmanager you can clearly avoid implementing loggedIn at all, but this doesn't mean the rest of the developers don't need such a callback.
Sorry, I did not noticed that it was a callback! Only a question: sessionwrapper is self.guard?
[...]
As an example a valid alternative to store state in the server is to store it in the cookie.
NEVOW_SESSION="username=manlio&last_accessed=...&created=..."
of course using some cryptography.
This has the advantage to work "as is" in a distributed system and to not depend on the number of sessions/users.
You will still need a session object on the serverside. Sessions are a serverside detail and saving state in the database is not hard at all.
I think that serverside state is not needed here, cookies come for this. Sometimes one only needs to know the authenticated username (to personalize some portions of a page). Of course having a full dynamic solution like those offered by guard, with cred integration, is a great thing ang I like it. Another use cases can be to have the login and logout page as fixed resource (and, maybe, on a SSL connection). This solution needs a custom, but I can reuse your SessionManager interface! Thanks and regards Manlio Perillo

On Tue, 01 Aug 2006 19:10:23 +0200, Manlio Perillo <manlio_perillo@libero.it> wrote:
Not really unless you want your system on its knees begging for some holidays. Just think about the chance for 1M people to visit your website each day. Your sessions database will shortly be the biggest bottleneck of the application.
But then why store sessions in a database at all?
Beucase registered users that are logged in and required to be remembered are asking for that. Persistent sessions persist even after reboots of the application something that may happen in 2 weeks time.
Yes, I know. I was searching for an object with the "right" lifetime, forgetting about the request.
context lifetime is ending soon.
By the way: what's the difference beetwen ctx.remember/locate and storing attributes on the context/request?
Too long and complicated to explain and not worth it. but storing data on the request is always a bad idea. And storing data on the session is mostly a bad idea. Storing data in the database is not a bad idea.
Sorry, I did not noticed that it was a callback! Only a question: sessionwrapper is self.guard?
what is self? anyway I guess yes, searching for the place where loggedIn is called is a much easier way to find the answer.
I think that serverside state is not needed here, cookies come for this.
Cookies come to identify all the requests coming from the same browser, they are not meant to store server side state, although they can keep 32k of data.
Sometimes one only needs to know the authenticated username (to personalize some portions of a page).
This is something that is already available to authenticated users. I think you mean un-authenticated users here.
Another use cases can be to have the login and logout page as fixed resource (and, maybe, on a SSL connection).
This solution needs a custom, but I can reuse your SessionManager interface!
Not really. You need to change SessionWrapper to do that. And only the locateChild method.

Valentino Volonghi aka Dialtone ha scritto:
On Tue, 01 Aug 2006 19:10:23 +0200, Manlio Perillo <manlio_perillo@libero.it> wrote:
Not really unless you want your system on its knees begging for some holidays. Just think about the chance for 1M people to visit your website each day. Your sessions database will shortly be the biggest bottleneck of the application.
But then why store sessions in a database at all?
Beucase registered users that are logged in and required to be remembered are asking for that.
Ok, but you can store the session in a global dictionary (as done in your default implementation). The sessions are available, at least if the server is not rebooted. I think that a database should be used only if you want to share sessions beetwen distributed servers (or if you are using a server like Apache).
[...]
By the way: what's the difference beetwen ctx.remember/locate and storing attributes on the context/request?
Too long and complicated to explain and not worth it. but storing data on the request is always a bad idea. And storing data on the session is mostly a bad idea. Storing data in the database is not a bad idea.
No, I meant storing data that shoud be stored for the "lifetime of the rendering". As done in formal with the forms data and errors. Where should be this data stored? The request object is not good?
Sorry, I did not noticed that it was a callback! Only a question: sessionwrapper is self.guard?
what is self?
def loggedIn(self, session, request, sessionwrapper):
anyway I guess yes, searching for the place where loggedIn is called is a much easier way to find the answer.
So sessionwrapper parameter is not needed?
I think that serverside state is not needed here, cookies come for this.
Cookies come to identify all the requests coming from the same browser, they are not meant to store server side state, although they can keep 32k of data.
Sometimes one only needs to know the authenticated username (to personalize some portions of a page).
This is something that is already available to authenticated users. I think you mean un-authenticated users here.
Yes, but guard requires a lot of "things" to happen for every request. I would like to do some benchmark, but if I only need to know the authenticated username, maybe I have no need for a session wrapper (but I need the session manager). Thanks and regards Manlio Perillo

On Tue, 01 Aug 2006 19:49:41 +0200, Manlio Perillo <manlio_perillo@libero.it> wrote:
Ok, but you can store the session in a global dictionary (as done in your default implementation). The sessions are available, at least if the server is not rebooted.
I think that a database should be used only if you want to share sessions beetwen distributed servers (or if you are using a server like Apache).
This is just wrong. Persistent sessions are useful exactly to avoid re-creating them when rebooting the application.
No, I meant storing data that shoud be stored for the "lifetime of the rendering".
As done in formal with the forms data and errors. Where should be this data stored?
It shouldn't. Pass it through the callee.
The request object is not good?
Not in its current shape and most probably not at all.
So sessionwrapper parameter is not needed?
The guard attribute is on the Session not on the SessionManager and it's a detail that is not exposed because it's just to make it handier for the user to run the 3 lines in the docstring.
Yes, but guard requires a lot of "things" to happen for every request.
I would like to do some benchmark, but if I only need to know the authenticated username, maybe I have no need for a session wrapper (but I need the session manager).
You might just avoid using cred/guard entirely and write your own thing if you like... guard is not meant to work without cred yet you were proposing to rely on the avatarId which is an internal cred thing. Anyway I'd be curious to know how you are going to implement cred integration without a SessionWrapper like resource with the current interface.

Valentino Volonghi aka Dialtone ha scritto:
On Tue, 01 Aug 2006 19:49:41 +0200, Manlio Perillo <manlio_perillo@libero.it> wrote:
Ok, but you can store the session in a global dictionary (as done in your default implementation). The sessions are available, at least if the server is not rebooted.
I think that a database should be used only if you want to share sessions beetwen distributed servers (or if you are using a server like Apache).
This is just wrong. Persistent sessions are useful exactly to avoid re-creating them when rebooting the application.
And what's the problem? Hopefully you are not going to reboot the server every week, and users can always relogin.
No, I meant storing data that shoud be stored for the "lifetime of the rendering".
As done in formal with the forms data and errors. Where should be this data stored?
It shouldn't. Pass it through the callee.
Ok, but this means that *every* current application should be rewritten...
The request object is not good?
Not in its current shape and most probably not at all.
Ok.
So sessionwrapper parameter is not needed?
The guard attribute is on the Session not on the SessionManager
Ok, but you pass a session to the loggedIn method. So you can do (if I'm not wrong): def loggedIn(self, session, request): if request.args.get('rememberMe'): session.guard.makePersistentCookie(session, request, max_age=self.sessionPersistentLifetime) self.makePersistentSession(session)
[...]
Yes, but guard requires a lot of "things" to happen for every request.
I would like to do some benchmark, but if I only need to know the authenticated username, maybe I have no need for a session wrapper (but I need the session manager).
You might just avoid using cred/guard entirely and write your own thing if you like... guard is not meant to work without cred yet you were proposing to rely on the avatarId which is an internal cred thing.
confusing avatarID was a my error...
Anyway I'd be curious to know how you are going to implement cred integration without a SessionWrapper like resource with the current interface.
Of course there will be no cred integration ;-). I don't want (still) to use guard because there are a lot of things that I do not understand. Like support for multiple portals, setResourceForPortal and so. Every time I think I'm beginning to understand, it suffice to read some code (as Weever or Stiq) for understanding that I do not understand ;-). Thanks and regards Manlio Perillo

On Tue, 01 Aug 2006 21:05:15 +0200, Manlio Perillo <manlio_perillo@libero.it> wrote:
And what's the problem? Hopefully you are not going to reboot the server every week, and users can always relogin.
I as a user _HATE_ when I lose my session just because the developers rebooted the application. I even hate when the browser loses the session between restarts. You might also be browsing the website when suddenly you are logged out because of a restart.
Ok, but this means that *every* current application should be rewritten...
There are more than a couple examples that are not inside the *every* keyword. Anyway yes. If you want to update nevow on those installations to use web2 you'll have to rewrite part of the application. This should sound as a "You should start coding the right way immediately before having a big codebase".
Ok, but you pass a session to the loggedIn method. So you can do (if I'm not wrong):
def loggedIn(self, session, request):
if request.args.get('rememberMe'): session.guard.makePersistentCookie(session, request, max_age=self.sessionPersistentLifetime) self.makePersistentSession(session)
You have dropped the rest of the explanation that is quite important.
Of course there will be no cred integration ;-).
Well.. Then I'm not interested. Your solution is going to be nevow specific and thus unusable for my usecases.
I don't want (still) to use guard because there are a lot of things that I do not understand.
Why are you using Nevow or Twisted at all then? Even _I_ do not understand completely what Nevow does with the context in its internals... guard (even in its current shape) is much less complicated than the whole context business.
Like support for multiple portals, setResourceForPortal and so.
This has nothing to do with guard. I suggest reading the cred tutorial from twisted.
Every time I think I'm beginning to understand, it suffice to read some code (as Weever or Stiq) for understanding that I do not understand ;-).
Weever is pretty old now and has been replaced almost completely by Stiq. No-one should read Weever code.

Valentino Volonghi aka Dialtone ha scritto:
On Tue, 01 Aug 2006 21:05:15 +0200, Manlio Perillo <manlio_perillo@libero.it> wrote:
And what's the problem? Hopefully you are not going to reboot the server every week, and users can always relogin.
I as a user _HATE_ when I lose my session just because the developers rebooted the application. I even hate when the browser loses the session between restarts. You might also be browsing the website when suddenly you are logged out because of a restart.
But in this case your solution does not always works. The user can have a transient session.
[...]
I don't want (still) to use guard because there are a lot of things that I do not understand.
Why are you using Nevow or Twisted at all then? Even _I_ do not understand completely what Nevow does with the context in its internals... guard (even in its current shape) is much less complicated than the whole context business.
Like support for multiple portals, setResourceForPortal and so.
This has nothing to do with guard. I suggest reading the cred tutorial from twisted.
setResourceForPortal is actually very trivial ;-) It just store the resource on the session object. The problem is with multiple portals support: any examples? Some considerations ------------------- Now I think to understand why Guard store a session for anonymous users. For cred point of view anonymous user is just like an ordinary user. Since Guard store resources on the session object, it needs to create sessions for anonymous users. However this poses a security problem (session fixation). The anonymous user is registered with the Credentials Checker in the same way as an ordinary user. However the credentials checker can handle this case specially; as an example it does not require to access a database for a DatabasePasswordDB. This means that resources for anonymous users can not be stored on sessions, requiring a new login to the portal and no need for sessions at all. Only ordinary users resources can/should be stored on the session. This also means that the guard implementation in the sanbox (as is) **does** not needs to create sessions for anonymous users. What we need is to run some benchmarks: 1) access to a simple resource 2) access to a guard protected resource 3) access to a guard draft (in Valentino sandox) protected resource Tests 2 and 3 should be repeated for a Credentials Checker that simulate an access to a time consuming resource to authenticate users. Thanks and regards Manlio Perillo

On Thu, 03 Aug 2006 11:12:17 +0200, Manlio Perillo <manlio_perillo@libero.it> wrote:
I as a user _HATE_ when I lose my session just because the developers rebooted the application. I even hate when the browser loses the session between restarts. You might also be browsing the website when suddenly you are logged out because of a restart.
But in this case your solution does not always works. The user can have a transient session.
Sure... When he is not logged in.

Valentino Volonghi aka Dialtone ha scritto:
On Thu, 03 Aug 2006 11:12:17 +0200, Manlio Perillo <manlio_perillo@libero.it> wrote:
I as a user _HATE_ when I lose my session just because the developers rebooted the application. I even hate when the browser loses the session between restarts. You might also be browsing the website when suddenly you are logged out because of a restart.
But in this case your solution does not always works. The user can have a transient session.
Sure... When he is not logged in.
Does this means that you are going to make all sessions permanent *without* asking users permission? Regards Manlio Perillo
participants (2)
-
Manlio Perillo
-
Valentino Volonghi aka Dialtone