Well banging out a spec for UserKit wasn't on my schedule for today, but
it's been a lot of fun seeing it gel together so quickly. I'm sure there is
still a lot of more to go over. Here is the 2nd version:
UserKit
-------
This is a spec for a new Webware component (and WebKit plug-in) named UserKit.
Version: 1/10/2000 #2
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
- Other types of user: IMAP, PAM, SMB, NT
- Roles (see below)
Open questions:
- Should we use some kind of general cache manager that could be reused for
other kinds of objects?
Still needed:
- Good example of using UserKit.
- Definitions of settings/configuration
- WebKit servlet admin page for managing users and roles
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. '''
## Settings
def userClass(self):
def setUserClass(self, userClass):
def userTimeout(self):
def setUserTimeout(self, seconds):
def userCachedTimeout(self):
def setUserCachedTimeout(self, seconds):
## Basic user access
def addUser(self, user):
def userForId(self, id, default=_NoDefault):
''' Returns the user with the given id, pulling that user record into
memory if needed. '''
def userForName(self, name, default=_NoDefault):
''' Returns the user with the given name, pulling that user record into
memory if needed. '''
def users(self):
''' Returns list of all users (regardless of login status). '''
def currentUsers(self):
''' Returns a list of all current users. '''
def numCurrentUsers(self):
''' Returns number of users currently logged in. '''
def putUserToSleep(self, user):
''' Removes the user from memory, archiving him/her if necessary. '''
## Authentication
def authenticateUserWithID(self, name, password)
def authenticateUserWithName(self, name, password)
# OR is that too long? :
def loginId(self, userId, password):
def loginName(self, userName, password):
login = loginName
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)
createDate
lastActivity
lastLogin
values (dictionary with any info you like)
'''
def value(self, name, default=_NoDefault):
def setValue(self, name, value):
def sleep(self):
''' Removes the user from memory (by invoking manager.putUserToSleep()).
You cannot use the user object after invoking sleep(). '''
self._mgr.sleep()
Roles
-----
class Role:
'''
attributes:
name
description
'''
def __init__(self, name, description):
def playsRole(self, role):
return self==role
class HierRole:
'''
HierRole is a hierarchical role. It points to its parent role.
'''
def __init__(self, superrole, name, description):
def playsRole(self, role):
if self!=role:
if self._superrole is None:
return 0
else:
return self._superrole.playsRole(role)
else:
return 1
class RoleUserManager(UserManager):
def addRole(self, role):
def roleForName(self, name):
class RoleUser(Role):
'''
attributes:
roles (list of roles the user belongs to)
roleNames (dictionary keyed by role name; for quick look up)
'''
def playsRole(self, roleOrName):
if type(roleOrName) is types.StringType:
roleOrName = self._manager.roleForName(roleOrName)
for role in self._roles:
if role.playsRole(roleOrName):
return 1
return 0
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.
|