import base64 import hashlib import oauth import urllib from Crypto.PublicKey import RSA from Crypto.Util import number MIXI_CERT = "0xC048F9DD595072FD561EF7D69533FE4F5957520F755BE6E0252B870" \ "03F3D3DD55FF548E78BDD8491B8EA68B0F3038DFE53950B94AFF4E634" \ "4E9C6C050557484B150B81EBD2A624DF81B7C270A6D15BB857AD34A68" \ "C5444A7B60EBDF953DEBAFBAAA36F8E6FB75C4D79EF3714DF74973081" \ "AF5F5B901FF6387CDA44135A665FE5" def signed_request(fn): def verify(self, *args, **kw): # Construct a RSA.pubkey object exponent = 65537 public_key_long = long(MIXI_CERT, 16) public_key = RSA.construct((public_key_long, exponent)) try: # Rebuild the message hash locally oauth_request = oauth.OAuthRequest( http_method=self.request.method, http_url=self.request.url, parameters=self.request.params.mixed()) message = '&'.join(( oauth.escape(oauth_request.get_normalized_http_method()), oauth.escape(oauth_request.get_normalized_http_url()), oauth.escape(oauth_request.get_normalized_parameters()), )) local_hash = hashlib.sha1(message).digest() # Apply the public key to the signature from the remote host sig = base64.decodestring( urllib.unquote(self.request.params.mixed()["oauth_signature"])) remote_hash = public_key.encrypt(sig, '')[0][-20:] # Verify that the locally-built value matches the value # from the remote server if local_hash != remote_hash: raise return fn(self, *args, **kw) except oauth.OAuthError, err: self.response.set_status(401) self.response.out.write(err.message) except: self.response.set_status(401) self.response.out.write('Invalid OAuth Signature.') return verify