def test_adjust_scheme(self): c = typepad.tpclient.TypePadClient() c.endpoint = 'http://api.typepad.com' c.clear_credentials() self.assertScheme(c.endpoint, 'http') c.clear_credentials() c.add_credentials('a', 'b') self.assertScheme(c.endpoint, 'http') c.clear_credentials() c.add_credentials('a', 'b', domain='api.typepad.com') self.assertScheme(c.endpoint, 'http') c.clear_credentials() c.add_credentials(OAuthConsumer('a', 'b'), OAuthToken('c', 'd')) self.assertScheme(c.endpoint, 'https') c.clear_credentials() c.add_credentials(OAuthConsumer('a', 'b'), OAuthToken('c', 'd'), domain='api.example.com') self.assertScheme(c.endpoint, 'http') c.clear_credentials() c.add_credentials(OAuthConsumer('a', 'b'), OAuthToken('c', 'd'), domain='typepad.com') self.assertScheme(c.endpoint, 'http') # This time for sure!! c.clear_credentials() c.add_credentials(OAuthConsumer('a', 'b'), OAuthToken('c', 'd'), domain='api.typepad.com') self.assertScheme(c.endpoint, 'https') # Try it again. c.clear_credentials() c.add_credentials(OAuthConsumer('a', 'b'), OAuthToken('c', 'd'), domain='api.typepad.com') self.assertScheme(c.endpoint, 'https') # Check that clearing works. c.clear_credentials() self.assertScheme(c.endpoint, 'http')
def test_consumer_property(self): c = typepad.tpclient.TypePadClient() c.endpoint = 'http://api.typepad.com' # make sure initial credentials are clear self.assert_(len(c.authorizations) == 0) self.assert_(len(c.credentials.credentials) == 0) # we can specify consumer and token as OAuth objects c.consumer = OAuthConsumer('x', 'y') c.token = OAuthToken('z', 'q') self.assert_(len(c.credentials.credentials) == 1) self.assertScheme(c.endpoint, 'https') # we can specify consumer and token as tuples of key/secrets c.consumer = ('a', 'b') c.token = ('a', 'b') self.assert_(len(c.credentials.credentials) == 1) self.assertScheme(c.endpoint, 'https') # assigning "None" to either token or consumer will # effectively clear credentials also c.token = None self.assert_(len(c.credentials.credentials) == 0) self.assertScheme(c.endpoint, 'http') c.clear_credentials() self.assertScheme(c.endpoint, 'http')
def dropbox_client(): access_token_file = os.path.join(os.environ["HOME"], ".dropbox-tools-access-token") sess = session.DropboxSession(APP_KEY, APP_SECRET, ACCESS_TYPE) try: with open(access_token_file) as f: access_token = OAuthToken.from_string(f.read()) sess.set_token(access_token.key, access_token.secret) except (IOError, EOFError, KeyError): request_token = sess.obtain_request_token() url = sess.build_authorize_url(request_token) print "Please visit\n\n %s\n\nand press the 'Allow' button, then hit 'Enter' here." % url raw_input() # This will fail if the user didn't visit the above URL and hit 'Allow' access_token = sess.obtain_access_token(request_token) # dropbox access tokens don't have serialisation methods on them, my_token = OAuthToken(access_token.key, access_token.secret) with open(access_token_file, "w") as f: f.write(my_token.to_string()) conn = client.DropboxClient(sess) print "linked account:", conn.account_info()["display_name"] return conn
def fetch_access_token(self, unauth_request_token_key, unauth_request_token_secret, oauth_verifier): """ After the user has authorizated API access via the authorization URL, get the (semi-)permanent access key using the user-authorized request token. Keyword arguments: unauth_request_token -- the user-authorized OAuth request token oauth_verifier -- per OAuth 1.0 Revision A """ url = "%s?oauth_verifier=%s" % (YAMMER_ACCESS_TOKEN_URL, oauth_verifier) try: unauth_request_token = OAuthToken(unauth_request_token_key, unauth_request_token_secret) oauth_request = OAuthRequest.from_consumer_and_token( self._consumer, token=unauth_request_token, http_method='POST', http_url=url) oauth_request.sign_request(self._signature, self._consumer, unauth_request_token) headers = oauth_request.to_header() except OAuthError, m: raise YammerError(m.message)
def test_responseful(self): request = { 'uri': mox.Func(self.saver('uri')), 'method': 'POST', 'headers': mox.Func(self.saver('headers')), 'body': mox.Func(self.saver('body')), } response = { 'status': 200, 'content-type': 'application/json', } response_content = '{"blahdeblah": true, "anotherthing": "2010-07-06T16:17:05Z"}' http = typepad.TypePadClient() typepad.client = http http.add_credentials( OAuthConsumer('consumertoken', 'consumersecret'), OAuthToken('tokentoken', 'tokensecret'), domain='api.typepad.com', ) mock = mox.Mox() mock.StubOutWithMock(http, 'request') http.request(**request).AndReturn((httplib2.Response(response), response_content)) mock.ReplayAll() class Moose(typepad.TypePadObject): class Snert(typepad.TypePadObject): volume = typepad.fields.Field() target = typepad.fields.Object('User') class SnertResponse(typepad.TypePadObject): blahdeblah = typepad.fields.Field() anotherthing = typepad.fields.Datetime() snert = typepad.fields.ActionEndpoint(api_name='snert', post_type=Snert, response_type=SnertResponse) moose = Moose() moose._location = 'https://api.typepad.com/meese/7.json' ret = moose.snert(volume=10, target=typepad.User(display_name='fred')) self.assert_(ret is not None) self.assert_(isinstance(ret, Moose.SnertResponse)) mock.VerifyAll() self.assert_(self.uri) self.assertEquals(self.uri, 'https://api.typepad.com/meese/7/snert.json') self.assert_(self.headers) self.assert_(self.body) self.assert_(utils.json_equals({ 'volume': 10, 'target': { 'displayName': 'fred', 'objectType': 'User', }, }, self.body))
def test_real_file(self): request = { 'uri': mox.Func(self.saver('uri')), 'method': 'POST', 'headers': mox.Func(self.saver('headers')), 'body': mox.Func(self.saver('body')), } response = { 'status': 201, } http = typepad.TypePadClient() typepad.client = http http.add_credentials( OAuthConsumer('consumertoken', 'consumersecret'), OAuthToken('tokentoken', 'tokensecret'), domain='api.typepad.com', ) mock = mox.Mox() mock.StubOutWithMock(http, 'request') http.request(**request).AndReturn((response, '')) mock.ReplayAll() asset = typepad.Photo() asset.title = "One-by-one png" asset.content = "This is a 1×1 transparent PNG." fileobj = file(os.path.join(os.path.dirname(__file__), 'onebyone.png')) brupload = typepad.BrowserUploadEndpoint() brupload.upload(asset, fileobj, "image/png", post_type='photo') mock.VerifyAll() response = self.message_from_response(self.headers, self.body) (filepart,) = [part for part in response.get_payload() if part.get_param('name', header='content-disposition') == 'file'] self.assertEquals(filepart.get_content_type(), 'image/png') # If there's a transfer encoding, it has to be the identity encoding. transenc = filepart.get('content-transfer-encoding') self.assert_(transenc is None or transenc == 'identity') # Check that the file content is equivalent without decoding. fileobj.seek(0) filecontent = fileobj.read() fileobj.close() self.assertEquals(filepart.get_payload(decode=False), filecontent) filelength = filepart.get('content-length') self.assertEquals(int(filelength), len(filecontent))
def __init__(self, token): GObject.GObject.__init__(self) self._whoami = None self._error = None self.service = UBUNTU_SSO_SERVICE self.token = token token = OAuthToken(self.token["token"], self.token["token_secret"]) authorizer = OAuthAuthorizer(self.token["consumer_key"], self.token["consumer_secret"], access_token=token) self.worker_thread = RestfulClientWorker(authorizer, self.service) self.worker_thread.start() GObject.timeout_add(200, self._monitor_thread)
def test_redirect(self): request = { 'uri': mox.Func(self.saver('uri')), 'method': 'POST', 'headers': mox.Func(self.saver('headers')), 'body': mox.Func(self.saver('body')), } response = { 'status': 302, 'location': 'http://client.example.com/hi', } http = typepad.TypePadClient() typepad.client = http http.add_credentials( OAuthConsumer('consumertoken', 'consumersecret'), OAuthToken('tokentoken', 'tokensecret'), domain='api.typepad.com', ) mock = mox.Mox() mock.StubOutWithMock(http, 'request') http.request(**request).AndReturn((response, '')) mock.ReplayAll() asset = typepad.Photo() asset.title = "Fake photo" asset.content = "This is a made-up photo for testing automated browser style upload." fileobj = StringIO('hi hello pretend file') brupload = typepad.BrowserUploadEndpoint() brupload.upload(asset, fileobj, "image/png", redirect_to='http://client.example.com/hi', post_type='photo') mock.VerifyAll() # Verify the headers and body. self.assert_(self.headers) self.assert_(self.body) response = self.message_from_response(self.headers, self.body) bodyparts = response.get_payload() self.assertEquals(len(bodyparts), 4) bodyparts = dict((part.get_param('name', header='content-disposition'), part) for part in bodyparts) # Confirm that the redirect_to was sent. self.assert_('redirect_to' in bodyparts) self.assertEquals(bodyparts['redirect_to'].get_payload(), 'http://client.example.com/hi')
def _fetch_token(oauth_request): url = oauth_request.to_url() logging.info('REQUEST url=%s' % url) response = urlfetch.fetch(url) logging.info('RESPONSE => %s' % response.content) # TODO can't do this one until the oauth library gets patched #token = OAuthToken.from_string(response.content) params = cgi.parse_qs(response.content.strip(), keep_blank_values=True) if 'oauth_token' not in params or 'oauth_token_secret' not in params: return None key = params['oauth_token'][0] secret = params['oauth_token_secret'][0] token = OAuthToken(key, secret) logging.info('TOKEN: %s' % token) return token
def lookup_token(self, token_type, token_field): """ :param token_type: type of token to lookup :param token_field: token to look up :note: token_type should always be 'access' as only such tokens are stored in database :returns: OAuthToken object """ assert token_type == 'access' try: token = Token.objects.get(token=token_field) return OAuthToken(token.token, token.token_secret) except Token.DoesNotExist: return None
def test_responseless(self): request = { 'uri': mox.Func(self.saver('uri')), 'method': 'POST', 'headers': mox.Func(self.saver('headers')), 'body': mox.Func(self.saver('body')), } response = { 'status': 204, # no content } http = typepad.TypePadClient() typepad.client = http http.add_credentials( OAuthConsumer('consumertoken', 'consumersecret'), OAuthToken('tokentoken', 'tokensecret'), domain='api.typepad.com', ) mock = mox.Mox() mock.StubOutWithMock(http, 'request') http.request(**request).AndReturn((httplib2.Response(response), '')) mock.ReplayAll() class Moose(typepad.TypePadObject): class Snert(typepad.TypePadObject): volume = typepad.fields.Field() snert = typepad.fields.ActionEndpoint(api_name='snert', post_type=Snert) moose = Moose() moose._location = 'https://api.typepad.com/meese/7.json' ret = moose.snert(volume=10) self.assert_(ret is None) mock.VerifyAll() self.assert_(self.uri) self.assertEquals(self.uri, 'https://api.typepad.com/meese/7/snert.json') self.assert_(self.headers) self.assert_(self.body) self.assert_(utils.json_equals({ 'volume': 10 }, self.body))
def __init__(self, user, token=None): """Initialize an oauth-authenticated test client. :param user: The user to authenticate. :type user: django.contrib.auth.models.User :param token: Optional token to authenticate `user` with. If no `token` is given, the user's first token will be used. :type token: oauth.oauth.OAuthToken """ super(OAuthAuthenticatedClient, self).__init__() if token is None: # Get the user's first token. token = get_auth_tokens(user)[0] assert token.user == user, "Token does not match User." consumer = token.consumer self.consumer = OAuthConsumer(consumer.key.encode("ascii"), consumer.secret.encode("ascii")) self.token = OAuthToken(token.key.encode("ascii"), token.secret.encode("ascii"))
def get(self): user = DropboxUser.get_current(self) if user: token = OAuthToken(user.oauth_token, user.oauth_token_secret) dba = auth.Authenticator(config) db_client = client.DropboxClient(config['server'], config['content_server'], config['port'], dba, token) dirinfo = json.loads(db_client.metadata('dropbox', '').body) if 'contents' in dirinfo: self.response.out.write(dirinfo['contents']) else: self.response.out.write('no contents, bro') else: print "There was no user, bro."
def post(self): uid = self.request.get('uid') if uid is not None: taskqueue.add(url='/tasks/poll', params={'uid': uid}, countdown=POLL_INTERVAL) user = DropboxUser.get_by_uid(uid) token = OAuthToken(user.oauth_token, user.oauth_token_secret) dba = auth.Authenticator(config) db_client = client.DropboxClient(config['server'], config['content_server'], config['port'], dba, token) account_info = json.loads(db_client.account_info().body) size = str(account_info['quota_info']['normal']) if user.size != size: params = {'changed': 'yeah'} urlfetch.fetch(url=user.callback_url, payload=urllib.urlencode(params), method='POST') user.size = size user.put()
def test_basic(self): request = { 'uri': mox.Func(self.saver('uri')), 'method': 'POST', 'headers': mox.Func(self.saver('headers')), 'body': mox.Func(self.saver('body')), } response = { 'status': 201, # created } http = typepad.TypePadClient() typepad.client = http http.add_credentials( OAuthConsumer('consumertoken', 'consumersecret'), OAuthToken('tokentoken', 'tokensecret'), domain='api.typepad.com', ) mock = mox.Mox() mock.StubOutWithMock(http, 'request') http.request(**request).AndReturn((response, '')) mock.ReplayAll() asset = typepad.Photo() asset.title = "Fake photo" asset.content = "This is a made-up photo for testing automated browser style upload." fileobj = StringIO('hi hello pretend file') brupload = typepad.BrowserUploadEndpoint() brupload.upload(asset, fileobj, "image/png", post_type='photo') mock.VerifyAll() self.assert_(self.uri) # We added credentials, so it should be a secure URL. self.assert_(self.uri.startswith('https://api.typepad.com/browser-upload.json')) uriparts = list(urlparse(self.uri)) querydict = cgi.parse_qs(uriparts[4]) # TODO: really verify the signature # Verify the headers and body. self.assert_(self.headers) self.assert_(self.body) responsemsg = self.message_from_response(self.headers, self.body) content_type = responsemsg.get_content_type() self.assert_(content_type) self.assert_(not responsemsg.defects) # Check that the unparsed body has its internal mime headers # separated by full CRLFs, not just LFs. self.assert_('\r\nContent-Type:' in self.body) # Check that boundaries are separated by full CRLFs too. boundary = responsemsg.get_param('boundary') self.assert_(boundary + '\r\n' in self.body) # Make sure we're only putting credentials in the query string, not # the headers. self.assert_('oauth_signature' in querydict) self.assert_('authorization' not in responsemsg) self.assert_('Authorization' not in responsemsg) bodyparts = responsemsg.get_payload() self.assertEquals(len(bodyparts), 3) bodyparts = dict((part.get_param('name', header='content-disposition'), part) for part in bodyparts) self.assertEquals(bodyparts['post_type'].get_payload(), 'photo') self.assert_('redirect_to' not in bodyparts) asset_json = bodyparts['asset'].get_payload() self.assert_(utils.json_equals({ 'title': 'Fake photo', 'content': 'This is a made-up photo for testing automated browser style upload.', 'objectType': 'Photo', }, asset_json)) filepart = bodyparts['file'] self.assertEquals(filepart.get_payload(decode=False), 'hi hello pretend file') filelength = filepart.get('content-length') self.assertEquals(int(filelength), len('hi hello pretend file')) filename = filepart.get_param('filename', header='content-disposition') self.assert_(filename)
def oauth_token(self): """Return OAuthToken with information contained in this model""" return OAuthToken(self.token, self.token_secret)
def _token_set(self, token): consumer = token.consumer self.consumer = OAuthConsumer(consumer.key, consumer.secret) self.token = OAuthToken(token.key, token.secret)
class Yammer(OAuthClient): def __init__(self, consumer_key, consumer_secret, access_token_key=None, access_token_secret=None, proxy_host=None, proxy_port=None, proxy_username=None, proxy_password=None): """ Register applications at https://www.yammer.com/client_applications/new in order to get consumer key and secret. Keyword arguments: consumer key -- identifies a Yammer application consumer secret -- establishes ownership of the consumer key access token key -- an OAuth access token (optional) access token secret -- establishes ownership of the access key (optional) proxy host -- host name of proxy server (optional) proxy port -- port number (optional) proxy username -- used if proxy requires authentication (optional) proxy password -- used if proxy requires authentication (optional) """ self._proxy_host = None self._proxy_host = None self._proxy_username = None self._proxy_password = None self._access_token = None try: self._consumer = OAuthConsumer(consumer_key, consumer_secret) # Could not get HMAC-SHA1 to work but since Yammer is using # HTTPS, plaintext should be fine. # # self._signature = OAuthSignatureMethod_HMAC_SHA1() self._signature = OAuthSignatureMethod_PLAINTEXT() except OAuthError, m: raise YammerError(m.message) if access_token_key and access_token_secret: self._access_token = OAuthToken(access_token_key, access_token_secret) if _use_pycurl: self._connection = pycurl.Curl() self._connection.setopt(pycurl.CONNECTTIMEOUT, YAMMER_TIMEOUT) self._connection.setopt(pycurl.TIMEOUT, YAMMER_TIMEOUT) if debug: self._connection.setopt(pycurl.VERBOSE, 1) else: self._connection = httplib.HTTPSConnection("%s" % YAMMER_URL) if debug: self._connection.set_debuglevel(1) if proxy_host and proxy_port: self._proxy_host = proxy_host self._proxy_port = int(proxy_port) if not _use_pycurl: raise YammerError("Use of proxy settings requires pycurl " "to be installed.") elif self._proxy_host is None or self._proxy_port is None: raise YammerError("Proxy settings missing host and/or port.") elif ((proxy_username and not proxy_password) or (not proxy_username and proxy_password)): raise YammerError("Proxy settings missing username (%s) or " "password (%s)." % (proxy_username, proxy_password)) if proxy_username: self._proxy_username = proxy_username self._proxy_password = proxy_password try: self._connection.setopt(pycurl.PROXY, self._proxy_host) self._connection.setopt(pycurl.PROXYPORT, self._proxy_port) if self._proxy_username: self._connection.setopt( pycurl.PROXYUSERPWD, "%s:%s" % (self._proxy_username, self._proxy_password)) except: raise YammerError("Could not set up proxied connection.")