From: Chuck E. <ec...@mi...> - 2001-01-10 18:23:32
|
Geoff's previous message makes a good point about two things: - lack of user management - lack of server side persistence One of the items on my "major components to provide list" is UserKit, which could be used to address these items as well as role based security. Here is a real quick, first-cut spec on UserKit including Geoff's ideas as well as my own. If there is enough interest, we can turn this into a mature spec and then crank it out. If you have feedback on the design points, class interfaces, etc. feel free to chime in. -Chuck UserKit ------- This is a spec for a new Webware component (and WebKit plug-in) named UserKit. Design points include: - Provides for user management - Including: - passwords - storing misc data - persisting that data on server side - Persistence techniques: - File system (one pickled file per user) - SQL - store values in known columns - put extra key-value pairs in catch all column as pickled string - Shelve - Roles (see below) The Basics ---------- class UserManager: ''' You can instantiate this or use it as a mix-in. Since it retains data in memory, the most likely candidate to mix-in with in WebKit would be Application. ''' def addUser(self, user): def userForId(self, id): def userForName(self, name): def users(self): # returns list of all users def setUserClass(self, userClass): class User: ''' attributes: name password e-mail (? do we need this separate or does it go in values below?) id (simply number, used internally for indexing (like prehaps an indexed INT column in SQL) externalId (longer more cryptic string for setting permanent cookies on the browser. not guessable; therefore prevents imposters) lastLogin values (dictionary with any info you like) ''' def value(self, name, default=_NoDefault): def setValue(self, name, value): Roles ----- class Role: ''' attributes: name comment data (dictionary with any info you like) ''' class RoleUserManager: def addRole(self, role): def roleForName(self, name): class RoleUser: ''' attributes: roles (list of roles the user belongs to) roleNames (dictionary keyed by role name; for quick look up) ''' def playsRole(self, roleOrName): def roles(self): def setRoles(self, listOfRoles): Role notes: - We could augment Page (or even Servlet) to disallow serving content if the user doesn't play any of the roles required by the Page. Each page would advertise a dictionary mapping operation names ('view', 'edit', etc.) to a list or set of roles that are allowed to do so. |
From: Chuck E. <ec...@mi...> - 2001-02-15 03:47:38
|
I reviewed the UserKit doc. One thing I noticed is that HierRole only has one parent roles. Python has given me a sense of value regarding multiple inheritance, so I will change HierRole to have a list of parent roles. Also, regarding persistence techniques like memory, pickle, SQL and MiddleKit, I think this functionality will have to be provided as mix-ins rather than subclasses. For example, we have a UserManager and a RoleUserManager and there could be other UserManagers in the future, either in the kit or provided by people. It just seems natural to provide mix-ins for the archiving. I still don't feel like I have archiving set in my mind. I just might find out what it looks like when I get there. -Chuck |
From: Luke O. <lu...@ro...> - 2001-12-19 23:24:20
|
Hello all - Today I'm giddy to say that I have officially begun a migration from Coldfusion to Webware for future development at our company. We'll be running on W2000/IIS for a while, with two database options, Access and PostgreSQL. (Most likely both accessed through ADO/ODBC.) Webkit (CGI) is running on our development server, along with a simple ISAPI filter to perform very simple URL rewrites. We're a database and web design house, so there is no single big project that is going to be converted. New development will be in Python/Webware, but we have a lot of behind the scenes utilities and customer tools written in ColdFusion. Some of these (a somewhat generic database view/edit utility, for example) will probably be useful for webware in general once I convert them, so I'll let you know. Here comes my actual question. We're currently using a rather hacked together set of Coldfusion custome tages for user authentication and permissions. Authentication is similar in concept to SecurePage (database-backed), with permissions as non-inheritable 'Roles' specifying which pages can by accessed by that Role, a user can have any number of roles. There are two 'special' roles, Administrator and World (users having Administrator role get the equivalent of playsRole no matter what, pages in World role skip any checking). Altogether, sort of a first-run at what UserKit seems to be trying to be. I've read the Wiki stuff on UserHandling, just curious I should base a rewrite of our system off of SecurePage, or if UserKit is functional enough. I don't care whether concepts/API will change in future revisions, I'm happy to help test it, suggest changes, whatever. I just want to know I can get a functional system up now. (Permissions use is very light in most of our applications.) Thanks, Luke ===== ------------------ Reference Counting Garbage Collection: Look out philosophy majors, things really DO cease to exist when no one is looking at them! ------------------ __________________________________________________ Do You Yahoo!? Check out Yahoo! Shopping and Yahoo! Auctions for all of your unique holiday gifts! Buy at http://shopping.yahoo.com or bid at http://auctions.yahoo.com |
From: Ian B. <ia...@co...> - 2001-12-20 00:13:20
|
On Wed, 2001-12-19 at 17:22, Luke Opperman wrote: > Altogether, sort of a first-run at what UserKit seems to be > trying to be. I've read the Wiki stuff on UserHandling, > just curious I should base a rewrite of our system off of > SecurePage, or if UserKit is functional enough. I don't > care whether concepts/API will change in future revisions, > I'm happy to help test it, suggest changes, whatever. I > just want to know I can get a functional system up now. > (Permissions use is very light in most of our > applications.) I'm just coming to the end of working up a demo application -- I had hoped to get it done before I left for Christmas, but I don't think that will happen. So close... but I guess it doesn't matter if I spend a bit of time rheuminating, since I don't think I'll get it finished before tomorrow morning. Anyway, as part of it I set up my own ad hoc user objects. It has made me feel less enthusiastic about UserKit... the basic problem it solves isn't very difficult. OTOH, my user objects (and most people's) are more complex than UserKit's objects, and integrating the two seems more complicated and less elegant than just implementing the basic roles and such myself. Especially since my permission system doesn't work like UserKit assumes -- I don't ask whether a user is part of a role, but whether the user has any role that has a certain permission, and if that role is for the particular project that is being accessed (or any parent project). So the way I check permissions is with a SQL statement that joins many tables. I want to do that directly, as that single SQL statement will be faster than doing lots of individual accesses and joining them on the Python side. For basic usage, maybe UserKit will be fine... I've felt unclear about just what classes are abstract, and which ones you are supposed to use, how you extend them, etc. Maybe just with some documentation, UserKit will be flexible enough for whatever, by doing the appropriate subclassing. Ian |
From: marcelo s. <mar...@gm...> - 2006-04-21 15:24:19
|
Hi Does someone know where I can find UserKit's tutorial? Is it possible to use UserKit with SQLObject? Thank you Regards |
From: Geoff T. <gta...@na...> - 2001-01-10 19:24:11
|
Chuck, Looks like a nice design. I hope something like this gets written, although I don't know if I can help out anytime soon. Is RoleUser intended to be a subclass of User (and RoleUserManager a subclass of UserManager)? It looks like it, but you didn't write class RoleUser(User): -- - Geoff Talvola Parlance Corporation gtalvola@NameConnector.com |
From: Chuck E. <ec...@mi...> - 2001-01-10 20:24:17
|
At 02:29 PM 1/10/2001 -0500, Geoff Talvola wrote: >Chuck, > >Looks like a nice design. I hope something like this gets written, >although I don't know if I can help out anytime soon. I'll be happy to write it, but I'm looking for feedback from everyone so we end up with a design that is fairly complete, extensible and flexible. >Is RoleUser intended to be a subclass of User (and RoleUserManager a >subclass of UserManager)? It looks like it, but you didn't write > > class RoleUser(User): Yes, you're right. I forgot that. -Chuck |
From: Tom S. <tom...@li...> - 2001-01-11 00:00:13
|
Chuck Esterbrook wrote: > > Geoff's previous message makes a good point about two things: > - lack of user management > - lack of server side persistence > > One of the items on my "major components to provide list" is UserKit, which > could be used to address these items as well as role based security. > > Here is a real quick, first-cut spec on UserKit including Geoff's ideas as > well as my own. If there is enough interest, we can turn this into a mature > spec and then crank it out. absolutely. I think, this is one of the missing points in Webware. A UserKit would be fantastic.. > If you have feedback on the design points, class interfaces, etc. feel free > to chime in. I'll try. I hope my comments are constructive enough... Overall impression: good > -Chuck > > UserKit > ------- > This is a spec for a new Webware component (and WebKit plug-in) named UserKit. > > Design points include: > - Provides for user management > - Including: > - passwords > - storing misc data > - persisting that data on server side > - Persistence techniques: > - File system (one pickled file per user) > - SQL > - store values in known columns > - put extra key-value pairs in catch all column as pickled string > - Shelve a lot more. See the development in Zope: PAMUser, SMBUser, NTUser, IMAPUser,... Important: One needs a simple example here how to put everything together. It will be interesting then to see how the different mechanisms get implemented by different Webware users. It will be much easier than in Zope! > - Roles (see below) > > The Basics > ---------- > class UserManager: > ''' You can instantiate this or use it as a mix-in. Since it retains data > in memory, the most likely candidate to mix-in with in WebKit would be > Application. ''' Ah, Memory: User Caching comes to my mind. One need to know how many users are in Memory (logged in, the famous: "there are 100 Users logged in") and a mechanism to dynamically put Users in Memory (when they log in) and to throw them away again (with an activity manager. Simple Session timeouts are not enough. I think a method for throwing a user out of memory is enough, one can then implement different cache clearing strategies (with dervied classes). In my case this would be: no activity for 5 Minutes => put user out of memory. It would be a bad idea to suck everything into memory and then manipulate the data there (I have thousands of users!). I would use a general cache manager class which could be used for other things to (reminds me of EJB technology). SQLCache, FilesystemCache,... As in the Session case, on could configure some aspects in Application.config 'UserStore': SQL, # for the default persistance mechanism 'UserTimeOut': 10, # much more agressive than sessions, which can stay longer, # at least on the filesystem or in a database 'UserTimeoutStrategy': 'Timeout strategy classname' # if you log access to userdata, you already have # a memory clearing strategy by sweeping # periodically over the "in memory" users # an throwing away the unused Well, I'm a little bit to implementation specific here, but it came to my mind.. > def addUser(self, user): > def userForId(self, id): > def userForName(self, name): > def users(self): # returns list of all users Users in memory or generally all users? The last case is quite usesless with thousands of users. Does the UserManager handle authentication? authenticateUserWithID(self, name, password) authenticateUserWithName(self, name, password) this names are to long.. :-( Where do they belong? Intuitively a UserManager should handle Authentication. Should be an abstract method and overloaded in RoleUserManager other derived classes > def setUserClass(self, userClass): Waht is the exact meaning ot this method? Set the Persistance mechanism? > class User: > ''' > attributes: > name > password > e-mail (? do we need this separate or does it go in values below?) > id (simply number, used internally for indexing (like prehaps an indexed > INT column in SQL) > externalId (longer more cryptic string for setting permanent cookies on > the browser. not guessable; therefore prevents imposters) very good idea.. > lastLogin lastActivity (a timestamp, usefull for clearing the data out of memory. see above) createDate , when the user got his account (=> "is member since ...."). If you forget to collect this kind of data, you will never get it again (I made this mistake some time ago :-)) > values (dictionary with any info you like) > ''' > def value(self, name, default=_NoDefault): > def setValue(self, name, value): setValues(self, **args): e.g. setValues(id=10, name=me, password='secret', ...) same for __init__(self, **args) the "getDomains" stuff from Zope is not necessary.... > Roles > ----- > > class Role: > ''' > attributes: > name > comment > data (dictionary with any info you like) data extendible or just a specified dictionary format, which could be populated by Configuration files? > ''' > class RoleUserManager (UserManager) # was remark from Geoff > def addRole(self, role): how do you construct role? > def roleForName(self, name): class RoleUser (User): # was remark from Geoff > ''' > attributes: > roles (list of roles the user belongs to) > roleNames (dictionary keyed by role name; for quick look up) > ''' > def playsRole(self, roleOrName): does this mean the same as hasRole(self, roleOrName) ore something else? > def roles(self): > def setRoles(self, listOfRoles): > > Role notes: > - We could augment Page (or even Servlet) to disallow serving content if > the user doesn't play any of the roles required by the Page. Each page cool. Could also be interesting to be able to configure through something like RolesUser.config which uses setRoles() with data from this file. > would advertise a dictionary mapping operation names ('view', 'edit', etc.) > to a list or set of roles that are allowed to do so. Puhh, was exhausting writing this mail ... I have a lot more to tell here, but I think this is enough for a first run. I hope you find time to start writing the UserKit :-) your APIs are very clear, which makes coding in Webware a real pleasure. I took a lok at SessionMemoryStore.py. I think there you have the same problem with many sessions. You need to clear some sessions out more agressively, otherwise your applications blows up in an uncontrollable way with many users (I'll try to use the megacool httpsession.py to produce this effect) I'm thinking also about a project here SessionMemoryFilesystemStore.py (put some of the stuff dynamically to the filesystem, when memory grows to much. depending on user activity) SessionSQLStore.py or is anybody else working on that? -- Tom Schwaller http://www.linux-community.de |
From: Chuck E. <ec...@mi...> - 2001-01-11 01:52:32
|
I've returned your favor with an equally long e-mail... At 01:02 AM 1/11/2001 +0000, Tom Schwaller wrote: >a lot more. See the development in Zope: PAMUser, SMBUser, NTUser, >IMAPUser,... I added notes for these. >Ah, Memory: User Caching comes to my mind. One need to know how many >users are in Memory (logged in, the famous: "there are 100 Users logged in") >and a mechanism to dynamically put Users in Memory (when they log in) >and to throw them away again (with an activity manager. Simple Session >timeouts are not enough. I think a method for throwing a user out of >memory is enough, one can then implement different cache clearing strategies >(with dervied classes). In my case this would be: no activity for 5 >Minutes => put user out of memory. It would be a bad idea to suck >everything into memory and then manipulate the data there (I have >thousands of users!). I would use a general cache manager class which >could be used for other things to (reminds me of EJB technology). >SQLCache, FilesystemCache,... I added all of this as well. For the generic cache manager, I put a question about it. I don't think I have the mindset to approach the general cache manager tonight. Although, I certainly welcome any willing person to throw a spec out there if they like. :-) >As in the Session case, on could configure some aspects in >Application.config > >'UserStore': SQL, # for the default persistance mechanism >'UserTimeOut': 10, # much more agressive than sessions, which can stay >longer, > # at least on the filesystem or in a database Is your UserTimeOut: 1. the time after which a user object is pushed out of memory (and onto storage if changed)? 2. the time after which a user is considered logged out due to inactivity? My first thought is that UserManager would have both. >'UserTimeoutStrategy': 'Timeout strategy classname' > # if you log access to userdata, you already have > # a memory clearing strategy by sweeping > # periodically over the "in memory" users > # an throwing away the unused What is this? Is there a class interface you would propose for it? > > def addUser(self, user): > > def userForId(self, id): > > def userForName(self, name): > > def users(self): # returns list of all users > >Users in memory or generally all users? The last case >is quite usesless with thousands of users. I augmented the interface to have "currentUsers()" which is in memory. users() is not useless. I would be bothered if I could not easily iterate through all the users on a site. I might wish to put together some kind of report about them... >Does the UserManager handle authentication? > >authenticateUserWithID(self, name, password) >authenticateUserWithName(self, name, password) Added. > > def setUserClass(self, userClass): > >Waht is the exact meaning ot this method? >Set the Persistance mechanism? A vague thought on my part that perhaps UserManager would have a createUser() method. That way you wouldn't have to import the user class or even know what it was. WebKit code might look something like: userMgr = self.application().userManager() user = userMgr.createUser('chuck', 'foobar') user.addRole('admin') I guess I'm thinking that addRole() might take either a string with the name of the role or the role object. If that's confusing, we could have addRole() and addRoleNamed() instead. > > class User: > > ''' > > attributes: > > name > > password > > e-mail (? do we need this separate or does it go in > values below?) > > id (simply number, used internally for indexing (like > prehaps an indexed > > INT column in SQL) > > externalId (longer more cryptic string for setting > permanent cookies on > > the browser. not guessable; therefore prevents imposters) > >very good idea.. > > > lastLogin > >lastActivity (a timestamp, usefull for clearing the data out of memory. >see above) Added. >createDate , when the user got his account (=> "is member since ...."). >If you forget to collect this kind of data, you will never get it again >(I made this mistake some time ago :-)) Added. > > values (dictionary with any info you like) > > ''' > > def value(self, name, default=_NoDefault): > > def setValue(self, name, value): > >setValues(self, **args): e.g. setValues(id=10, name=me, >password='secret', ...) >same for __init__(self, **args) Hmmm, does setValues() replace the values in existence. e.g. if my values are {'x': 1} does setValues({'y': 2}) give {'y': 2} or {'x': 1, 'y': 2}? Also, I was going to have actual attributes for the well known items such as name and password. >the "getDomains" stuff from Zope is not necessary.... Good since I don't know what it is. Although I will be attending the Zope tutorial at python9. :-) I'll try not to heckle the instructor. > > Roles > > ----- > > > > class Role: > > ''' > > attributes: > > name > > comment > > data (dictionary with any info you like) > >data extendible or just a specified dictionary format, >which could be populated by Configuration files? Er, I should have called this values as well, although I'm wondering if that's really necessary. It makes more sense with Users where there can often be a lot ad hoc items you might like to add. That's probably not the case with Role. Removed for now. And I changed 'comment' to 'description'. I also added a note that we would want a WebKit servlet based admin page for managing users and roles. Gee, it's funny how projects always blow up so quickly. :-) >class RoleUserManager (UserManager) # was remark from Geoff > > > def addRole(self, role): > >how do you construct role? There was a Role class just above this. You instantiate it. > > def roleForName(self, name): > >class RoleUser (User): # was remark from Geoff > > > ''' > > attributes: > > roles (list of roles the user belongs to) > > roleNames (dictionary keyed by role name; for quick > look up) > > ''' > > def playsRole(self, roleOrName): > >does this mean the same as hasRole(self, roleOrName) ore something else? Sort of. Again I forgot to complete my thought in this area. I'd like to allow for hierarchical roles. e.g., a particular role can inherit another role. Sort of like exceptions in Python. A KeyError is also a LookupError, so if you capture LookupError, you also capture KeyError. Likewise if an Admin is a PowerUser, then saying user.playsRole('PowerUser') captures admins as well. I have added a new HierRole class. I don't like the name. Feel free to suggest. > > def roles(self): > > def setRoles(self, listOfRoles): > > > > Role notes: > > - We could augment Page (or even Servlet) to disallow serving > content if > > the user doesn't play any of the roles required by the Page. Each page > >cool. Could also be interesting to be able to configure through >something like RolesUser.config which uses setRoles() with data from this >file. Yes. I added a note that more specs on configuration are needed. I think those will come more naturally (or at least safely) after the class API has settled down. > > would advertise a dictionary mapping operation names ('view', 'edit', etc.) > > to a list or set of roles that are allowed to do so. > >Puhh, was exhausting writing this mail ... I have a lot >more to tell here, but I think this is enough for >a first run. I hope you find time to start writing the >UserKit :-) Well I've incorporated all your suggestions and more. I'll post a new copy. >your APIs are very clear, which makes coding in Webware >a real pleasure. Thanks. >I took a lok at SessionMemoryStore.py. I think >there you have the same problem with many sessions. >You need to clear some sessions out more agressively, otherwise >your applications blows up in an uncontrollable way >with many users (I'll try to use the megacool httpsession.py >to produce this effect) An explosion derived from beating up WebKit with httpsession.py would be really sweet. >I'm thinking also about a project here > >SessionMemoryFilesystemStore.py (put some of the stuff dynamically >to the filesystem, when memory grows to much. depending on user >activity) I'd be interested to know the stats surrounding this. How many simultaneous users do you get before memory becomes an issue? How much memory is saved when pushing them out to disk? Also, you can always switch to the file store if you were in an immediate bind. >SessionSQLStore.py > >or is anybody else working on that? Not that I know of. -Chuck |
From: Jay L. <js...@js...> - 2001-01-12 05:59:50
|
Tom Schwaller wrote: > > > I took a lok at SessionMemoryStore.py. I think > there you have the same problem with many sessions. > You need to clear some sessions out more agressively, otherwise > your applications blows up in an uncontrollable way > with many users (I'll try to use the megacool httpsession.py > to produce this effect) > > I'm thinking also about a project here > > SessionMemoryFilesystemStore.py (put some of the stuff dynamically > to the filesystem, when memory grows to much. depending on user > activity) > > SessionSQLStore.py > > or is anybody else working on that? > > I wrote this last weekend. I'll finish cleaning it up and submit it. Basically, I added a new SessionStore, DynamicMemoryStore (or something like that), which moves Sessions to disk after a while, just like you suggested. My initial implementation was to take the normal session clearing sweep and make it run more often, but in the intermediate sweeps it would just move the sessions to disk. I'm stumbling on explaining it. I'll just get it clean and submit. Jay |
From: Tom S. <tom...@li...> - 2001-01-12 11:32:59
|
Jay Love wrote: > > Tom Schwaller wrote: > > > > > > > I took a look at SessionMemoryStore.py. I think > > there you have the same problem with many sessions. > > You need to clear some sessions out more agressively, otherwise > > your applications blows up in an uncontrollable way > > with many users (I'll try to use the megacool httpsession.py > > to produce this effect) > > > > I'm thinking also about a project here > > > > SessionMemoryFilesystemStore.py (put some of the stuff dynamically > > to the filesystem, when memory grows to much. depending on user > > activity) > > > > SessionSQLStore.py > > > > or is anybody else working on that? > > > > > > I wrote this last weekend. I'll finish cleaning it up and submit it. > Basically, I added a new SessionStore, DynamicMemoryStore (or something I like that name :-) > like that), which moves Sessions to disk after a while, just like you > suggested. My initial implementation was to take the normal session > clearing sweep and make it run more often, but in the intermediate > sweeps it would just move the sessions to disk. > > I'm stumbling on explaining it. I'll just get it clean and submit. cool, this will be interesting code to read. this triggered some thoughts about scheduling, but I will start a new thread for it.. -- Tom Schwaller http://www.linux-community.de |