python-openid : Key-Value Formの応答で”openid.”をKey名から落としている実装

実際の応答を決めるのはEncoderクラス。OpenIDResponseのインスタンスを返答データに変換する。

openid/server/server.py

class Encoder(object):
    responseFactory = WebResponse
    def encode(self, response):
        encode_as = response.whichEncoding()
        if encode_as == ENCODE_KVFORM:
            wr = self.responseFactory(body=response.encodeToKVForm())
            if isinstance(response, Exception):
                wr.code = HTTP_ERROR
        elif encode_as == ENCODE_URL:
            location = response.encodeToURL()
            wr = self.responseFactory(code=HTTP_REDIRECT,
                                      headers={'location': location})
        elif encode_as == ENCODE_HTML_FORM:
            wr = self.responseFactory(code=HTTP_OK,
                                      body=response.toFormMarkup())
        else:
            raise EncodingError(response)
        return wr

ENCODE_* の初期値はどこだ?

(op)hdknr@debuniid:~/.virtualenvs/op/src/djopenid$ find  ../../lib/python2.5/site-packages/openid/ -name "*.py" -exec grep -H ENCODE_ {} \;
../../lib/python2.5/site-packages/openid/server/server.py:@group Response Encodings: ENCODE_KVFORM, ENCODE_HTML_FORM, ENCODE_URL
../../lib/python2.5/site-packages/openid/server/server.py:ENCODE_KVFORM = (‘kvform’,)
../../lib/python2.5/site-packages/openid/server/server.py:ENCODE_URL = (‘URL/redirect’,)
../../lib/python2.5/site-packages/openid/server/server.py:ENCODE_HTML_FORM = (‘HTML form’,)
../../lib/python2.5/site-packages/openid/server/server.py:        ENCODE_HTML_FORM.  Convenience method for server authors.
../../lib/python2.5/site-packages/openid/server/server.py:        return self.whichEncoding() == ENCODE_HTML_FORM
../../lib/python2.5/site-packages/openid/server/server.py:        @returns: one of ENCODE_URL, ENCODE_HTML_FORM, or ENCODE_KVFORM.
../../lib/python2.5/site-packages/openid/server/server.py:        @change: 2.1.0 added the ENCODE_HTML_FORM response.
../../lib/python2.5/site-packages/openid/server/server.py:                return ENCODE_HTML_FORM
../../lib/python2.5/site-packages/openid/server/server.py:                return ENCODE_URL
../../lib/python2.5/site-packages/openid/server/server.py:            return ENCODE_KVFORM
../../lib/python2.5/site-packages/openid/server/server.py:        if encode_as == ENCODE_KVFORM:
../../lib/python2.5/site-packages/openid/server/server.py:        elif encode_as == ENCODE_URL:
../../lib/python2.5/site-packages/openid/server/server.py:        elif encode_as == ENCODE_HTML_FORM:
../../lib/python2.5/site-packages/openid/server/server.py:        @returns: one of ENCODE_URL, ENCODE_KVFORM, or None.  If None,
../../lib/python2.5/site-packages/openid/server/server.py:                return ENCODE_HTML_FORM
../../lib/python2.5/site-packages/openid/server/server.py:                return ENCODE_URL
../../lib/python2.5/site-packages/openid/server/server.py:                return ENCODE_KVFORM
../../lib/python2.5/site-packages/openid/server/server.py:#         @returns: one of ENCODE_URL, ENCODE_KVFORM, or None.  If None,

OpenIDResponseクラスで、以下のように判定。

    def whichEncoding(self):
        """How should I be encoded?

        @returns: one of ENCODE_URL, ENCODE_HTML_FORM, or ENCODE_KVFORM.

        @change: 2.1.0 added the ENCODE_HTML_FORM response.
        """
        if self.request.mode in BROWSER_REQUEST_MODES:
            if self.fields.getOpenIDNamespace() == OPENID2_NS and \
               len(self.encodeToURL()) > OPENID1_URL_LIMIT:
                return ENCODE_HTML_FORM
            else:
                return ENCODE_URL
        else:
            return ENCODE_KVFORM

つまり、ブラウザからリクエスト来るときだけENCODE_URLされます。

BROWSER_REQUEST_MODES = ['checkid_setup', 'checkid_immediate']

ENCODE_KVFORMはOpenIDResponseが持っているMessageクラスのインスタンスである,self.fields

    def __init__(self, request):
        self.request = request
        self.fields = Message(request.namespace)

に対して、

    def encodeToKVForm(self):
        return self.fields.toKVForm()

しています。

fields のクラスは, openid/message.py で定義されていて、

class Message(object):
    # ...
    def toKVForm(self):
        return kvform.dictToKV(self.toArgs())

   def toArgs(self):
        post_args = self.toPostArgs()
        kvargs = {}
        for k, v in post_args.iteritems():
            if not k.startswith('openid.'):
                raise ValueError(
                    'This message can only be encoded as a POST, because it '
                    'contains arguments that are not prefixed with "openid."')
            else:
                kvargs[k[7:]] = v   # Dropping "openid." (7 characters )

        return kvargs

のように、toArgs() でKey-ValueのKeyから先頭の”openid."が取り除かれるのです。

カテゴリー: 未分類 パーマリンク

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中