Example replacement Identity model...

0 views
Skip to first unread message

Matthew Bevan

unread,
Apr 7, 2006, 4:59:55 AM4/7/06
to TurboGears
Howdy!

There has been much discussion recently about replacing parts of Identity or
updating Identity-related tables, et cetera.

The following was my solution to the problem and I've tried to make it as
simple as possible by only replacing the model the standard SOProvider uses.

For the most part this replacement model works beautifully. By having a
function search "byUserId", and having a function override retrieval of the
"userId", I can easily swap my current username-based system for an e-mail
address-based one.

Unfortunately soprovider doesn't understand having a model of None. That
would be too easy. ;^) So, instead, I just have a Group model that is never
used. (I will likely update this in production to merge user roles and group
roles, and allow for role subtraction. (I.e. "global" rules are included,
then group roles are added or removed from the global ones, then user roles
from those. Etc.)

Enjoy!

P.s. as long as your DB classes act in an SQLObject way (i.e. .get(id) returns
a filled instance, .column is the named column, etc.) than you should be able
to trick soprovider into using almost any DB back-end. Just implement the
table creation function and/or silently drop (empty function).


--- topfloor.config ---
visit.on=True
identity.on=True
identity.failure_url="/authenticate"
identity.soprovider.model.user="content.model.Account"
identity.soprovider.model.group="content.model.Group"
identity.soprovider.model.permission="content.model.Role"
identity.soprovider.encryption_algorithm="md5"
cms.on = True


--- content.model ---
class Account(SQLObject):
class sqlmeta:
table = "accounts"
registry = "content"

Username = UnicodeCol(length=64, alternateID=True)
FullName = UnicodeCol(length=255)
Password = UnicodeCol(length=48, default=None)
EMail = UnicodeCol(length=255, alternateID=True)
Location = UnicodeCol(length=255, default=None)
Language = ForeignKey('Language', default=None)
Biography = UnicodeCol(default=None)
Searchable = BoolCol(default=True)
Portrait = BoolCol(default=False)
Roles = RelatedJoin('Role')
Groups = RelatedJoin('Group')
Created = DateTimeCol(default=datetime.now)
Updated = DateTimeCol(default=datetime.now)

def byUserId(id): return Account.byUsername(id)
byUserId = staticmethod(byUserId)
def _get_userId(self): return self.Username
def _get_permissions(self): return self.Roles
def _get_groups(self): return list()
def _get_password(self): return self.Password

def jsonify_account(obj):
result = jsonify_sqlobject(obj)

del result['Password']
if "Language" in result:
result['Language'] = jsonify(obj.Language.Code)
result['Roles'] = jsonify([p.Role for p in obj.Roles])

return result
jsonify_account = jsonify.when('isinstance(obj, Account)')(jsonify_account)

class Role(SQLObject):
class sqlmeta:
table = "roles"
registry = "content"

Role = UnicodeCol(length=64, alternateID=True)
Description = UnicodeCol(default=None)
Users = RelatedJoin('Account')

def byPermissionId(id): return Role.byRole(id)
byPermissionId = staticmethod(byPermissionId)
def _get_permissionId(self): return self.Role

# Never used. Implemented due to a lack of support for None in cfg.
class Group(SQLObject):
class sqlmeta:
table = "groups"
registry = "content"

groupId = UnicodeCol(length=16, alternateID=True)
displayName = UnicodeCol(length=255)
created = DateTimeCol(default=datetime.now)
users = list()

def _get_permissions(self): return list()

Claudio Martínez

unread,
Apr 8, 2006, 12:59:00 PM4/8/06
to TurboGears
This works too:
Nice if you only want to auth users from a table with only user and
pass columns for simple sites.

class User(SQLObject):
user = StringCol(length=15, alternateID=True)
pass = StringCol(length=32)

def _get_userId(self):
return self.user

User.byUserId = User.byUser

class FalseSQLMeta(type):
def createTable(cls, *args, **kw):
return True

class FalseSQLObject(object):
__metaclass__ = FalseSQLMeta

class Group(FalseSQLObject):
pass

class Perm(FalseSQLObject):
pass

Michele Cella

unread,
Apr 8, 2006, 1:34:20 PM4/8/06
to TurboGears
This is an useful subject, someone to add a link on the trac identity
doc? ;-)

Ciao
Michele

Reply all
Reply to author
Forward
0 new messages