def test_parse_token_response(self): client = MobileApplicationClient(self.client_id) # Parse code and state response = client.parse_request_uri_response(self.response_uri, scope=self.scope) self.assertEqual(response, self.token) self.assertEqual(client.access_token, response.get("access_token")) self.assertEqual(client.refresh_token, response.get("refresh_token")) self.assertEqual(client.token_type, response.get("token_type")) # Mismatching scope self.assertRaises(Warning, client.parse_request_uri_response, self.response_uri, scope="invalid") os.environ['OAUTHLIB_RELAX_TOKEN_SCOPE'] = '4' token = client.parse_request_uri_response(self.response_uri, scope='invalid') self.assertTrue(token.scope_changed) scope_changes_recorded = [] def record_scope_change(sender, message, old, new): scope_changes_recorded.append((message, old, new)) signals.scope_changed.connect(record_scope_change) try: client.parse_request_uri_response(self.response_uri, scope="invalid") self.assertEqual(len(scope_changes_recorded), 1) message, old, new = scope_changes_recorded[0] self.assertEqual(message, 'Scope has changed from "invalid" to "/profile".') self.assertEqual(old, ['invalid']) self.assertEqual(new, ['/profile']) finally: signals.scope_changed.disconnect(record_scope_change) del os.environ['OAUTHLIB_RELAX_TOKEN_SCOPE']
def test_populate_attributes(self): client = MobileApplicationClient(self.client_id) response_uri = (self.response_uri + "&code=EVIL-CODE") client.parse_request_uri_response(response_uri, scope=self.scope) # We must not accidentally pick up any further security # credentials at this point. self.assertIsNone(client.code)
def test_parse_token_response(self): client = MobileApplicationClient(self.client_id) # Parse code and state response = client.parse_request_uri_response(self.response_uri, scope=self.scope) self.assertEqual(response, self.token) self.assertEqual(client.access_token, response.get("access_token")) self.assertEqual(client.refresh_token, response.get("refresh_token")) self.assertEqual(client.token_type, response.get("token_type")) # Mismatching scope self.assertRaises(Warning, client.parse_request_uri_response, self.response_uri, scope="invalid")
def __init__(self, username, password, client_id=None, api_key=None): if client_id is None: client_id = uuid.uuid4() self.client_id = client_id self._api_key = api_key self.username = username self.password = password self.endpoint = MobileApplicationClient(self.client_id)
def test_authorization_url(self): url = 'https://example.com/authorize?foo=bar' web = WebApplicationClient(self.client_id) s = OAuth2Session(client=web) auth_url, state = s.authorization_url(url) self.assertIn(state, auth_url) self.assertIn(self.client_id, auth_url) self.assertIn('response_type=code', auth_url) mobile = MobileApplicationClient(self.client_id) s = OAuth2Session(client=mobile) auth_url, state = s.authorization_url(url) self.assertIn(state, auth_url) self.assertIn(self.client_id, auth_url) self.assertIn('response_type=token', auth_url)
def __init__(self, *, url, client_id, scope, authorization_url, redirect_uri=None, authorization_handler=None, **auth_args): oauth = OAuth2Session( client=MobileApplicationClient(client_id=client_id), scope=scope, redirect_uri=redirect_uri, ) super().__init__(session=oauth, url=url) authorization_url, state = oauth.authorization_url(authorization_url) token = None if authorization_handler is None: token = outh.token_from_fragment(callback_url) else: token = authorization_handler(self, authorization_url, **auth_args) self._set_outh_token(token)
def get_token(): print client_id client = MobileApplicationClient(client_id) print client api = OAuth2Session(client=client, redirect_uri=redirect_uri) authorization_url, state = api.authorization_url(authorization_base_url) print authorization_url print 'Please go here and authorize,', authorization_url redirect_response = raw_input('Paste the full redirect URL here:') token = api.token_from_fragment(redirect_response) with open(token_file, 'w') as f: f.write(json.dumps(token, indent=2)) return api
def setUp(self): # For python 2.6 if not hasattr(self, 'assertIn'): self.assertIn = lambda a, b: self.assertTrue(a in b) self.token = { 'token_type': 'Bearer', 'access_token': 'asdfoiw37850234lkjsdfsdf', 'refresh_token': 'sldvafkjw34509s8dfsdf', 'expires_in': '3600', 'expires_at': fake_time + 3600, } self.client_id = 'foo' self.clients = [ WebApplicationClient(self.client_id, code='asdf345xdf'), LegacyApplicationClient(self.client_id), BackendApplicationClient(self.client_id), ] self.all_clients = self.clients + [MobileApplicationClient(self.client_id)]
def session(): session = requests.session() oauth = OAuth2Session( client=MobileApplicationClient(client_id=OAUTH_CLIENT_ID), scope=OAUTH_SCOPES) authorization_url, state = oauth.authorization_url(LOGIN_URL + "/oauth/authorize") result = session.get(authorization_url) page = html.fromstring(result.text) csrf_token = _get_input_value(page, 'csrf_token') next = list(set(page.xpath("//input[@name='next_redirect']/@value")))[0] payload = { 'username': USERNAME, 'password': PASSWORD, 'next_redirect': next, 'csrf_token': csrf_token } result = session.post(LOGIN_URL, data=payload, headers={'referer': result.url}) assert result.status_code == 200 page = html.fromstring(result.text) authorize_xpath = page.xpath("//form[@id='authorizeForm']") if authorize_xpath: csrf_token = _get_input_value(page, 'csrf_token') payload = {'csrf_token': csrf_token, 'confirm': 'y'} result = session.post(result.url, data=payload, headers={'Referer': result.url}) token = _get_token_from_url(result.url) session.headers.update({'Authorization': 'Bearer {}'.format(token)}) assert result.status_code == 200 session.headers.update({'Accept': 'application/ld+json'}) return session
def auth_smashrun(config): """ Authenticate client with Smashrun """ if config.get('smashrun', 'type') == 'code': client = Smashrun(client_id=config.get('smashrun', 'client_id'), client_secret=config.get('smashrun', 'client_secret')) client.refresh_token( refresh_token=config.get('smashrun', 'refresh_token')) else: mobile = MobileApplicationClient('client') # implicit flow client = Smashrun(client_id='client', client=mobile, token={ 'access_token': config.get('smashrun', 'token'), 'token_type': 'Bearer' }) return client
def do_implicit(self): """ Implicit grant """ self.oauth_client = MobileApplicationClient(self.client_id) (token_url, headers, body) = self.oauth_client.prepare_authorization_request( self.oauth_endpoints['authorization_endpoint'], redirect_url=self.redirect_url, scope=self.scopes, ) # For openid scope, have to add id_token response_type and supply a nonce: # https://www.pingidentity.com/content/developer/en/resources/openid-connect-developers-guide/implicit-client # -profile.html # "Note: To mitigate replay attacks, a nonce value must be included to associate a client session with an # id_token. The client must generate a random value associated with the current session and pass this # along with the request. This nonce value will be returned with the id_token and must be verified to be # the same as the value provided in the initial request." # # oauthlib `lacks client features<https://github.com/oauthlib/oauthlib/issues/615>`_ for OIDC. if 'openid' in self.scopes: self.nonce = uuid.uuid4().hex # TODO: fix this to something more robust or extend oauthlib token_url = token_url.replace( 'response_type=token', 'response_type=token+id_token&nonce={}'.format(self.nonce)) # for the implicit grant type, the parameters are provided to the browser as #fragments rather than # ?query-parameters so they are never available to the redirect server. The user must copy the # browser self._redirect_server( self.redirect_url, token_url, message= "Copy this URL to the clipboard and hit enter on the console. " "Then you can close this window.") input("\n\nCopy URL to clipboard and then hit enter:") token_response_url = pyperclip.paste() self.oauth_tokens = self.oauth_client.parse_request_uri_response( token_response_url) self.set_tokens()
def setup_smashrun(options, config): """ Setup Smashrun API implicit user level authentication """ mobile = MobileApplicationClient('client') # implicit flow client = Smashrun(client_id='client', client=mobile, client_secret='my_secret', redirect_uri='https://httpbin.org/get') auth_url = client.get_auth_url() print( "Go to '%s' and log into Smashrun. After redirection, copy the access_token from the url." % auth_url[0]) print( "Example url: https://httpbin.org/get#access_token=____01234-abcdefghijklmnopABCDEFGHIJLMNOP01234567890&token_type=[...]" ) print( "Example access_token: ____01234-abcdefghijklmnopABCDEFGHIJLMNOP01234567890" ) token = input("Please enter your access token: ") if not config.has_section('smashrun'): config.add_section('smashrun') config.set('smashrun', 'token', urllib.parse.unquote(token)) config.set('smashrun', 'type', 'implicit')
def authorize(): """ Establishes an OAuth2 session to get a token for further API requests :return: Dictionary of authorization parameters (token and version) """ print( "Для работы программы необходимо авторизоваться!\nВ открывшейся вкладке браузера " "разрешите приложению Netology Lesson 3.3 by Roman Vlasenko доступ к вашему\n" "аккаунту ВКонтакте и скопируйте содержимое адресной строки\n") sleep(8) with OAuth2Session(client=MobileApplicationClient(client_id=CLIENT_ID), redirect_uri=REDIRECT_URI, scope="friends") as vk: authorization_url, state = vk.authorization_url(AUTHORIZE_URL, display="page") webbrowser.open_new_tab(authorization_url) vk_response = input( "Вставьте сюда содержимое адресной строки браузера:\n").rstrip() vk.token_from_fragment(vk_response) params = {"v": 5.103, "access_token": vk.access_token} # блок ниже делает тестовый запрос и проверяет, # чтобы API возвращал валидные данные, иначе # вероятнее всего, авторизация не удалась authtest = requests.get(API_URL + "/users.get", params).json() try: assert "response" in authtest print(f"\nДобро пожаловать, {authtest['response'][0]['first_name']}") return params, True except AssertionError: print( f"Тестовый запрос вернул ошибку: {authtest['error']['error_msg']}\n" "Повторная попытка авторизации через 5 с") sleep(5) return main()
def test_implicit_token_uri(self): client = MobileApplicationClient(self.client_id) # Basic, no extra arguments uri = client.prepare_request_uri(self.uri) self.assertURLEqual(uri, self.uri_id) # With redirection uri uri = client.prepare_request_uri(self.uri, redirect_uri=self.redirect_uri) self.assertURLEqual(uri, self.uri_redirect) # With scope uri = client.prepare_request_uri(self.uri, scope=self.scope) self.assertURLEqual(uri, self.uri_scope) # With state uri = client.prepare_request_uri(self.uri, state=self.state) self.assertURLEqual(uri, self.uri_state) # With extra parameters through kwargs uri = client.prepare_request_uri(self.uri, **self.kwargs) self.assertURLEqual(uri, self.uri_kwargs)
def _get_token(self, discard_token): """ Establishes an OAuth2 session to retrieve a token for further API requests. Saves retrieved token to a file. :param discard_token: If True save token to a file :return: VK API token """ print(f'{Y}VKInder\nWe need to authorize you with VK{END}\n') with OAuth2Session(client=MobileApplicationClient(client_id=CLIENT_ID), redirect_uri=REDIRECT_URI, scope="friends, groups, offline, photos") as vk: authorization_url, state = vk.authorization_url(AUTHORIZE_URL) tokenurl = self._login(authorization_url) vk.token_from_fragment(tokenurl) token = vk.access_token if not discard_token: save_token(token) with open('token.txt', 'w') as f: f.write(token) return token
def setUp(self): self.token = { "token_type": "Bearer", "access_token": "asdfoiw37850234lkjsdfsdf", "refresh_token": "sldvafkjw34509s8dfsdf", "expires_in": 3600, "expires_at": fake_time + 3600, } # use someclientid:someclientsecret to easily differentiate between client and user credentials # these are the values used in oauthlib tests self.client_id = "someclientid" self.client_secret = "someclientsecret" self.user_username = "******" self.user_password = "******" self.client_WebApplication = WebApplicationClient(self.client_id, code=CODE) self.client_LegacyApplication = LegacyApplicationClient(self.client_id) self.client_BackendApplication = BackendApplicationClient(self.client_id) self.client_MobileApplication = MobileApplicationClient(self.client_id) self.clients = [ self.client_WebApplication, self.client_LegacyApplication, self.client_BackendApplication, ] self.all_clients = self.clients + [self.client_MobileApplication]
def test_parse_token_response(self): client = MobileApplicationClient(self.client_id) # Parse code and state response = client.parse_request_uri_response(self.response_uri, scope=self.scope) self.assertEqual(response, self.token) self.assertEqual(client.access_token, response.get("access_token")) self.assertEqual(client.refresh_token, response.get("refresh_token")) self.assertEqual(client.token_type, response.get("token_type")) # Mismatching scope self.assertRaises(Warning, client.parse_request_uri_response, self.response_uri, scope="invalid") os.environ['OAUTHLIB_RELAX_TOKEN_SCOPE'] = '4' token = client.parse_request_uri_response(self.response_uri, scope='invalid') self.assertTrue(token.scope_changed) scope_changes_recorded = [] def record_scope_change(sender, message, old, new): scope_changes_recorded.append((message, old, new)) signals.scope_changed.connect(record_scope_change) try: client.parse_request_uri_response(self.response_uri, scope="invalid") self.assertEqual(len(scope_changes_recorded), 1) message, old, new = scope_changes_recorded[0] self.assertEqual( message, 'Scope has changed from "invalid" to "/profile".') self.assertEqual(old, ['invalid']) self.assertEqual(new, ['/profile']) finally: signals.scope_changed.disconnect(record_scope_change) del os.environ['OAUTHLIB_RELAX_TOKEN_SCOPE']
def authenticate_credentials(self, key): logger.debug('Key: {} {}'.format(self.keyword, key)) # take token from header and check the user againts FB graph API headers = { 'Authorization': '{keyword} {key}'.format(keyword=self.keyword, key=key) } # try request on facebook graph api url response = requests.get(app_settings.FACEBOOK_GRAPH_API_ME_URL, headers=headers) response_body = None error = None # if request was not successfull if response.status_code != requests.codes.ok: logger.debug('status code: {}'.format(response.status_code)) # and response is 401: UNAUTHORIZED if response.status_code == status.HTTP_401_UNAUTHORIZED: try: response_body = response.json() error = response_body.get('error') except Exception as e: logger.debug(e) raise exceptions.AuthenticationFailed( _('Authentication failed.')) # and error is type of 'OAuthException' if error and error.get('type') == 'OAuthException': # prepare OAuth session client_id = app_settings.FACEBOOK_APP_ID redirect_uri = app_settings.FACEBOOK_REDIRECT_URI authorization_base_url = app_settings.FACEBOOK_AUTHORIZATION_BASE_URL oauth = OAuth2Session( client=MobileApplicationClient(client_id=client_id), redirect_uri=redirect_uri) # call Facebook API for authorization URL authorization_url, state = oauth.authorization_url( authorization_base_url) # return authorization URL in response for the client raise exceptions.AuthenticationFailed( detail={ 'detail': _('Ivalid token'), 'redirect_url': authorization_url, }) else: raise exceptions.AuthenticationFailed( _('Authentication failed.')) resp_json = response.json() # if request was successfull, return user and access token # authentication was succesfull user = FacebookUser(fb_name=resp_json['name'], fb_id=resp_json['id']) return (user, key)
class Client(object): def __init__(self, username, password, client_id=None, api_key=None): if client_id is None: client_id = uuid.uuid4() self.client_id = client_id self._api_key = api_key self.username = username self.password = password self.endpoint = MobileApplicationClient(self.client_id) @property def api_key(self): if self._api_key is None: self._api_key = self.register() return self._api_key def url_for_workflow(self, workflow): return 'https://%s/view/%s' % (RESOURCE_URL, workflow) def url_for_register(self): return 'https://%s/register' % AUTH_URL def register(self): params = { 'username': self.username, 'password': self.password } response = requests.get(self.url_for_register(), params=params, verify=False) if response.status_code == 201: if 'X-API-Key' in response.headers: return response.headers['X-API-Key'] else: raise RuntimeError('No X-API-Key header in response (%s)' % response.text) elif response.status_code == 401: raise RuntimeError('Not authorized (%s)' % response.text) else: raise RuntimeError('Unexpected response %d from authorization server (%s)' % (response.status_code, response.text)) def view_without_access_token(self, workflow_name): response = requests.get(self.url_for_workflow(workflow_name), verify=False) if response.status_code == 401: return response elif response.status_code == 404: raise RuntimeError('Not found (%s)' % response.text) else: raise RuntimeError('Unexpected response %d from resource server (%s)' % (response.status_code, response.text)) def extract_auth_headers(self, response): try: oauth_url = response.headers['X-OAuth-URL'] # Must be Unicode for oauthlib, le sigh: required_scope = unicode(response.headers['X-Required-Scope']) except KeyError: raise RuntimeError('Did not find expected headers in response from ' 'resource server') return oauth_url, required_scope def authorize(self, oauth_url, redirect_uri, required_scope): headers = { 'X-API-Key': self.api_key, } request_url = self.endpoint.prepare_request_uri(oauth_url, redirect_uri=redirect_uri, scope=required_scope) response = requests.get(request_url, headers=headers, allow_redirects=False, verify=False) if response.status_code == 302: return response elif response.status_code == 401: raise RuntimeError('Not authorized (%s)' % response.text) elif response.status_code == 403: raise RuntimeError('Forbidden (%s)' % response.text) else: raise RuntimeError('Unexpected response %d from authorization server (%s)' % (response.status_code, response.text)) def create_access_token(self, location): return AccessToken(**self.endpoint.parse_request_uri_response(location)) def view_with_access_token(self, workflow_name, access_token): response = requests.get(self.url_for_workflow(workflow_name), params=access_token.as_query_params, verify=False) if response.status_code == 200: return response elif response.status_code == 403: raise RuntimeError('Forbidden (%s)' % response.text) elif response.status_code == 404: raise RuntimeError('Not found (%s)' % response.text) else: raise RuntimeError('Unexpected response %d from resource server (%s)' % (response.status_code, response.text)) def get_access_token_for_view_workflow(self, workflow_name): initial_view_response = self.view_without_access_token(workflow_name) oauth_url, required_scope = self.extract_auth_headers(initial_view_response) authorize_response = self.authorize(oauth_url=oauth_url, redirect_uri=self.url_for_workflow(workflow_name), required_scope=required_scope) return self.create_access_token(authorize_response.headers['Location']) def view_workflow(self, workflow_name, access_token=None): if access_token is None: access_token = self.get_access_token_for_view_workflow(workflow_name) view_response = self.view_with_access_token(workflow_name, access_token) return view_response.text
def setCustomKey(self): client_id = 20013 # scopes possible values: # read_inbox - access a user's global inbox # no_expiry - access_token's with this scope do not expire # write_access - perform write operations as a user # private_info - access full history of a user's private actions on the site scopes = 'read_inbox' authorization_url = 'https://stackoverflow.com/oauth/dialog' redirect_uri = 'https://stackexchange.com/oauth/login_success' # Create an OAuth session and open the auth_url in a browser for the user to authenticate stackApps = OAuth2Session( client=MobileApplicationClient(client_id=client_id), scope=scopes, redirect_uri=redirect_uri) auth_url, state = stackApps.authorization_url(authorization_url) # Try to install web drivers for one of these browsers # Chrome, Firefox, Edge (One of them must be installed) try: driver = webdriver.Chrome(ChromeDriverManager().install()) except ValueError: try: driver = webdriver.Firefox( executable_path=GeckoDriverManager().install()) except ValueError: try: driver = webdriver.Edge( EdgeChromiumDriverManager().install()) except ValueError: print( "You do not have one of these supported browsers: Chrome, Firefox, Edge" ) # Open auth_url in one of the supported browsers driver.get(auth_url) # Close the window after 20s (Assuming that the user logs in within 30 seconds) time.sleep(30) # Close the windows as soon as authorization is done try: WebDriverWait(driver, 1).until( EC.presence_of_element_located((By.TAG_NAME, "h2"))) callback_url = driver.current_url finally: driver.quit() # Extract access token data from callback_url accessTokenData = stackApps.token_from_fragment(callback_url) # Store the access token data in a dictionary jsonDict = { "access_token": accessTokenData['access_token'], "expires": accessTokenData['expires'], "state": state } with open('access_token.json', 'w') as jsonFile: json.dump(jsonDict, jsonFile)
def test_token_from_fragment(self): mobile = MobileApplicationClient(self.client_id) response_url = 'https://i.b/callback#' + urlencode(self.token.items()) auth = OAuth2Session(client=mobile) self.assertEqual(auth.token_from_fragment(response_url), self.token)
secret_codes_file = open(secret_codes_file_path, 'r') secret_codes_string = secret_codes_file.read() secret_codes_file.close() secret_codes_json = json.loads(secret_codes_string) authorization_uri = 'https://www.fitbit.com/oauth2/authorize' token_uri = 'https://api.fitbit.com/oauth2/token' scopes = ['activity', 'heartrate', 'location', 'nutrition', 'profile', 'settings', 'sleep', 'social', 'weight'] token = '' needs_authorization = input('Do you need to reauthorize? (y/n)') # for when you need to authorize # needs_authorization = 'n' # for when you need to run it and you already have the authorization token # Initialize client client = MobileApplicationClient(secret_codes_json['clientId']) fitbit = OAuth2Session(secret_codes_json['clientId'], client=client, scope=scopes) authorization_url = "https://www.fitbit.com/oauth2/authorize" if (needs_authorization == 'y'): # Grab the URL for Fitbit's authorization page. auth_url, state = fitbit.authorization_url(authorization_url) print("Visit this page in your browser: {}".format(auth_url)) # After authenticating, Fitbit will redirect you to the URL you specified in your application settings. It contains the access token. callback_url = input("Paste URL you get back here: ") # Get the access token as a string, and update the secret codes file with it. access_token = callback_url.split("&")[0].split('#')[1].split('=')[1] secret_codes_json['accessToken'] = access_token state = callback_url.split('&')[3].split('=')[1]
from oauthlib.oauth2 import MobileApplicationClient from requests_oauthlib import OAuth2Session client_id = 'd0FVV29VMDR6SUVrcV94cTdabHBoZzoxZjc2MTE1Mzc1YjMxNzhi' token_url = "https://a.mapillary.com/v2/oauth/token" redirect_uri = "https://geoclub.de/mapillary/oauth2.php" auth_url = "https://www.mapillary.com/connect" scopes = ['public:upload'] mobile = MobileApplicationClient(client_id) oauth = OAuth2Session(client=mobile, redirect_uri=redirect_uri, scope=scopes) authorization_url, state = oauth.authorization_url(url=auth_url) print("State:", state) print('Please go to %s and authorize access.' % authorization_url) authorization_response = input('\nEnter the resulting callback URL:\n') f = open("accesstoken3.conf", "w") for line in authorization_response.split("&"): if "access_token" in line: f.write(line.split("=")[1]) f.close() print("Configfile with access token created.")
import requests import json from requests_oauthlib import OAuth2Session from oauthlib.oauth2 import MobileApplicationClient client_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx" scopes = ['Sites.ReadWrite.All', 'Files.ReadWrite.All'] auth_url = 'https://login.microsoftonline.com/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx/oauth2/v2.0/authorize' #OAuth2Session is an extension to requests.Session #used to create an authorization url using the requests.Session interface #MobileApplicationClient is used to get the Implicit Grant oauth = OAuth2Session(client=MobileApplicationClient(client_id=client_id), scope=scopes) authorization_url, state = oauth.authorization_url(auth_url) consent_link = oauth.get(authorization_url) print(consent_link.url)
def __init__(self, mendeley, state): client = MobileApplicationClient(mendeley.client_id) MendeleyLoginAuthenticator.__init__(self, mendeley, client, state)
#!/usr/bin/env python3 from oauthlib.oauth2 import MobileApplicationClient from requests_oauthlib import OAuth2Session import requests server = "https://localhost/default" client_id = "29968236-c3ed-4b6e-ac16-affaeac0a8c2" client = MobileApplicationClient(client_id=client_id) oauth = OAuth2Session(client=client, scope="test") authorization_url, state = oauth.authorization_url(server + "/authorize") print( f"Please go to {authorization_url}, authorize, and copy the redirect uri here:" ) url = input().strip() token = oauth.token_from_fragment(url) print(f"Received: {token}") req = requests.get( server + "/resource", headers={"Authorization": f"Bearer {token['access_token']}"}) print(req)
class ImplicitGrantManager: def __init__(self,cid,oauthPageUrl,receivePort): """ Args: cid (string): The client id from Authorization provider oauthPageUrl (string): The authorization Page url receivedPort (string): The port number to receive request """ self.result=None self.clientId = cid self.oauthPageUrl = oauthPageUrl self.port = receivePort #generate CSRF token self.token = str(uuid.uuid4()) #generate request URL self.oauth = MobileApplicationClient(self.clientId) self.url, headers, body = self.oauth.prepare_authorization_request( self.oauthPageUrl, redirect_url="http://localhost:%s" % self.port, state=self.token ) #start local web server self.wsgi_app = _RedirectWSGIApp( self.port, self.oauth, self._registToken, self._failedRequest ) self.localServer = wsgiref.simple_server.make_server("localhost", self.port, self.wsgi_app, handler_class=_WSGIRequestHandler) thread = threading.Thread(target=self._localServerThread,args=(self.localServer,)) thread.start() def setMessage(self,lang,success,failed,transfer): """ Set Message that viewd in browser Args: lang (string): The message language code (ex:ja,en,...) success (string): The success message failed (string): The failed message transfer (string): The transfer error message that appear in old or Javascript disabled browser """ self.wsgi_app.setMessage(lang,success,failed,transfer) def getUrl(self): """ Get Authorization url Returns: AuthorizationUrl (string) """ return self.url def getToken(self): """ Get accesstoken (success), "" (failed) or None (waiting) If returned "" and the browser stays open, software should close that. Returns: tokenData (dict) or None """ if self.result!=None: self.shutdown() return self.result def _registToken(self,result): self.result=result def _failedRequest(self): self.result="" def __del__(self): self.shutdown() def shutdown(self): if self.localServer: self.localServer.shutdown() self.localServer=None def _localServerThread(self,server): server.serve_forever()