auths = RelatedJoin('Auth', intermediateTable='user_auth',
joinColumn='user_id', otherColumn='auth_id')
def _get_password(self):
for a in self.auths:
if isinstance(a, ClassicAuth):
return a.password
return None
def _get_user_name(self):
for a in self.auths:
if isinstance(a, ClassicAuth):
return a.user_name
return None
@classmethod
def by_user_name(cls, user_name):
auth = ClassicAuth.by_user_name(user_name)
assert len(auth.users) < 2
for u in auth.users:
return u
return None
@classmethod
def get_by(cls, auth):
assert len(auth.users) < 2
for u in auth.users:
return u
return None
_get_user_nameと_get_password、by_user_nameはあらたに作るAuth ClassからTurboGearsのidentityがおこなうpasswordによる認証に情報を転送してもらうのに使います。
つぎにAuth関係のclassです。
class Auth(InheritableSQLObject):
users = RelatedJoin('User', intermediateTable='user_auth',
joinColumn='auth_id', otherColumn='user_id')
def flush(self):
pass
class OpenIDAuth(Auth):
url = UnicodeCol(length=255, alternateID=True,
alternateMethodName='by_url')
@classmethod
def get_by(cls, url):
try:
return cls.by_url(url)
except SQLObjectNotFound:
return None
class ClassicAuth(Auth):
user_name = UnicodeCol(length=40, alternateID=True,
alternateMethodName='by_user_name')
password = UnicodeCol(length=40)
def set_password_raw(self, password):
"""Saves the password as-is to the database."""
self._SO_set_password(password)
def _set_password(self, cleartext_password):
"""Runs cleartext_password through the hash algorithm before saving."""
password_hash = identity.encrypt_password(cleartext_password)
self._SO_set_password(password_hash)
ClassicAuthの中身はもとからあるUserのメンバをかっぱらってきただけです。
あまりいうことはないでしょう。
最後にcontrollerです。OpenIDLoginControllerに手を加えます。__init__にauth_classも渡すようにします。んで、loginFinishをつぎのように書き換えます。元のコードは、User::user_nameにopenid_urlを突っ込むという横着がされていますが、これをAuthというレイヤーを導入することでもうちょっとマトモにしただけのことです。
if response.status == 'success':
openid_url = kws['openid.identity']
auth = self.auth_class.get_by(url=openid_url)
if not auth:
auth = self.auth_class(url=openid_url)
assert isinstance(auth, model.OpenIDAuth)
info = response.extensionResponse(self.sreg_uri, require_signed=False)
# User object needs to handle this attribute if it wants to do anything
# with the data
assert isinstance(info, dict)
u = self.user_class.get_by(auth=auth)
if not u:
if info.has_key('email'):
email_address = info['email']
else:
email_address = openid_url
if info.has_key('nickname'):
display_name = info['nickname']
else:
display_name = openid_url #ugh!
u = self.user_class(email_address=email_address, display_name=display_name)
u.addAuth(auth)
もっと手間取るかとおもったが、やる気が降臨したら一瞬だった。
0 件のコメント:
コメントを投稿