def get_access_token(self): if (not hasattr(current_app, "token")): client_credential = ( "%s:%s" % (self.soovii.consumer_key, self.soovii.consumer_secret)) headers = { "Authorization": "Basic " + to_unicode(base64.encodestring( to_bytes(client_credential))).replace("\n", "") } body = self.api_client.prepare_request_body( get_syscfg_val(8), get_syscfg_val(9)) # 对于网址类型的型的项目用户名密码,随意填写,如"soovii", "soovii" resp, content = self.soovii.http_request( self.soovii.access_token_url, headers, to_bytes(body), method="POST") if resp.code not in (200, 201): logger.info('Invalid response') else: dic = json.loads(to_unicode(content)) current_app.token = dic return dic else: return current_app.token
def handle_oauth2_response_discord(self, args): """Handles an oauth2 authorization response.""" client = self.make_client() remote_args = { "client_id": self.consumer_key, "client_secret": self.consumer_secret, "code": args.get("code"), "redirect_uri": session.get("%s_oauthredir" % self.name), "scope": "identify", } log.debug("Prepare oauth2 remote args %r", remote_args) remote_args.update(self.access_token_params) headers = copy(self._access_token_headers) if self.access_token_method == "POST": headers.update( {"Content-Type": "application/x-www-form-urlencoded"}) body = client.prepare_request_body(**remote_args) response = requests.request( self.access_token_method, self.expand_url(self.access_token_url), headers=headers, data=to_bytes(body, self.encoding), ) if response.status_code not in (200, 201): raise OAuthException( "Invalid response from %s" % self.name, type="invalid_response", data=to_bytes(body, self.encoding), ) return jsonify(response.text.encode("utf8")) elif self.access_token_method == "GET": qs = client.prepare_request_body(**remote_args) url = self.expand_url(self.access_token_url) url += ("?" in url and "&" or "?") + qs response = requests.request(self.access_token_method, url, headers=headers) if response.status_code not in (200, 201): raise OAuthException( "Invalid response from %s" % self.name, type="invalid_response", data=to_bytes(body, self.encoding), ) return jsonify(response.text.encode("utf8")) else: raise OAuthException("Unsupported access_token_method: %s" % self.access_token_method)
def validate_title(self, field): data = u'%s%s' % (field.data, self.content.data) key = hashlib.md5(to_bytes(data)).hexdigest() if cache.get(key): raise StopValidation("Duplicate requesting") # avoid duplicate requesting cache.set(key, 1, 100)
def test_get_authorize(self): rv = self.client.get('/oauth/authorize') assert 'Missing+client_id+parameter' in rv.location client = self.client rv = client.get('/oauth/authorize?client_id=ios&response_type=code') assert rv.status_code == 200 user = self.login() rv = client.get('/oauth/authorize?client_id=ios&response_type=code') assert rv.status_code == 200 assert to_bytes(user.username) in rv.data oauth_client = OAuthClient.query.first() rv = client.get('/oauth/authorize?%s' % url_encode({ 'client_id': oauth_client.client_id, 'response_type': 'code', 'scope': 'user', })) assert b'user:email' in rv.data assert b'user:write' in rv.data rv = client.get('/oauth/authorize?%s' % url_encode({ 'client_id': oauth_client.client_id, 'response_type': 'code', 'scope': 'user:email', })) assert b'user:email' in rv.data assert b'user:write' not in rv.data
def handle_oauth2_response(self): """Handles an oauth2 authorization response. This method overrides the one provided by OAuthRemoteApp in order to support Basic HTTP Authentication. """ if self.access_token_method != 'POST': raise OAuthException( ('Unsupported access_token_method: {}. ' 'Only POST is supported.').format(self.access_token_method) ) client = self.make_client() remote_args = { 'code': request.args.get('code'), 'client_secret': self.consumer_secret, 'redirect_uri': ( session.get('%s_oauthredir' % self.name) or url_for('invenio_oauthclient.authorized', remote_app=self.name, _external=True) ), } remote_args.update(self.access_token_params) # build the Basic HTTP Authentication code b2access_basic_auth = base64.encodestring(bytes('{0}:{1}'.format( self.consumer_key, self.consumer_secret), 'utf-8')).decode('ascii').replace('\n', '') body = client.prepare_request_body(**remote_args) resp, content = self.http_request( self.expand_url(self.access_token_url), # set the Authentication header headers={ 'Authorization': 'Basic {}'.format(b2access_basic_auth), }, data=to_bytes(body, self.encoding), method=self.access_token_method, ) data = parse_response(resp, content, content_type=self.content_type) if resp.code not in (200, 201): raise OAuthException( 'Invalid response from %s' % self.name, type='invalid_response', data=data ) return data
def handle_oauth2_response(self): """Handles an oauth2 authorization response. This method overrides the one provided by OAuthRemoteApp in order to support Basic HTTP Authentication. """ if self.access_token_method != 'POST': raise OAuthException( ('Unsupported access_token_method: {}. ' 'Only POST is supported.').format(self.access_token_method)) client = self.make_client() remote_args = { 'code': request.args.get('code'), 'client_secret': self.consumer_secret, 'redirect_uri': (session.get('%s_oauthredir' % self.name) or url_for('invenio_oauthclient.authorized', remote_app=self.name, _external=True)), } remote_args.update(self.access_token_params) # build the Basic HTTP Authentication code b2access_basic_auth = base64.encodestring( bytes('{0}:{1}'.format(self.consumer_key, self.consumer_secret), 'utf-8')).decode('ascii').replace('\n', '') body = client.prepare_request_body(**remote_args) resp, content = self.http_request( self.expand_url(self.access_token_url), # set the Authentication header headers={ 'Authorization': 'Basic {}'.format(b2access_basic_auth), }, data=to_bytes(body, self.encoding), method=self.access_token_method, ) data = parse_response(resp, content, content_type=self.content_type) if resp.code not in (200, 201): raise OAuthException('Invalid response from %s' % self.name, type='invalid_response', data=data) return data
def handle_oauth2_response_spotify(self, args): """Handles an oauth2 authorization response.""" client = self.make_client() remote_args = { "code": args.get("code"), "redirect_uri": session.get("%s_oauthredir" % self.name), } log.debug("Prepare oauth2 remote args %r", remote_args) remote_args.update(self.access_token_params) data = f"{self._consumer_key}:{self._consumer_secret}" encoded = str(base64.b64encode(data.encode("utf-8")), "utf-8") headers = {"Authorization": f"Basic {encoded}"} if self.access_token_method == "POST": headers.update( {"Content-Type": "application/x-www-form-urlencoded"}) body = client.prepare_request_body(**remote_args) resp, content = self.http_request( self.expand_url(self.access_token_url), headers=headers, data=to_bytes(body, self.encoding), method=self.access_token_method, ) elif self.access_token_method == "GET": qs = client.prepare_request_body(**remote_args) url = self.expand_url(self.access_token_url) url += ("?" in url and "&" or "?") + qs resp, content = self.http_request(url, headers=headers, method=self.access_token_method) else: raise OAuthException("Unsupported access_token_method: %s" % self.access_token_method) data = OAuth.parse_response(resp, content, content_type=self.content_type) if resp.code not in (200, 201): raise OAuthException( "Invalid response from %s" % self.name, type="invalid_response", data=data, ) return data
def handle_oauth2_response(self): if self.access_token_method != 'POST': raise OAuthException('Unsupported access_token_method: %s' % self.access_token_method) client = self.make_client() remote_args = { 'code': request.args.get('code'), 'client_secret': self.consumer_secret, 'redirect_uri': session.get('%s_oauthredir' % self.name) } remote_args.update(self.access_token_params) reddit_basic_auth = base64.encodestring( '%s:%s' % (REDDIT_APP_ID, REDDIT_APP_SECRET)).replace('\n', '') body = client.prepare_request_body(**remote_args) while True: resp, content = self.http_request( self.expand_url(self.access_token_url), headers={ 'Content-Type': 'application/x-www-form-urlencoded', 'Authorization': 'Basic %s' % reddit_basic_auth, 'User-Agent': REDDIT_USER_AGENT }, data=to_bytes(body, self.encoding), method=self.access_token_method, ) # Reddit API is rate-limited, so if we get 429, we need to retry if resp.code != 429: break time.sleep(1) data = parse_response(resp, content, content_type=self.content_type) if resp.code not in (200, 201): raise OAuthException('Invalid response from %s' % self.name, type='invalid_response', data=data) return data
def handle_oauth2_response(self): if self.access_token_method != 'POST': raise OAuthException( 'Unsupported access_token_method: %s' % self.access_token_method ) client = self.make_client() remote_args = { 'code': request.args.get('code'), 'client_secret': self.consumer_secret, 'redirect_uri': session.get('%s_oauthredir' % self.name) } remote_args.update(self.access_token_params) reddit_basic_auth = base64.encodestring('%s:%s' % (REDDIT_APP_ID, REDDIT_APP_SECRET)).replace('\n', '') body = client.prepare_request_body(**remote_args) while True: resp, content = self.http_request( self.expand_url(self.access_token_url), headers={'Content-Type': 'application/x-www-form-urlencoded', 'Authorization': 'Basic %s' % reddit_basic_auth, 'User-Agent': REDDIT_USER_AGENT}, data=to_bytes(body, self.encoding), method=self.access_token_method, ) # Reddit API is rate-limited, so if we get 429, we need to retry if resp.code != 429: break time.sleep(1) data = parse_response(resp, content, content_type=self.content_type) if resp.code not in (200, 201): raise OAuthException( 'Invalid response from %s' % self.name, type='invalid_response', data=data ) return data
def test_get_api_index(self): rv = self.client.get('/api/') assert to_bytes(API_VERSION) in rv.data
def validate_content(self, field): key = hashlib.md5(to_bytes(field.data)).hexdigest() if cache.get(key): raise StopValidation("Duplicate requesting") # avoid duplicate requesting cache.set(key, 1, 100)
def encode_base64(text): text = to_bytes(text) return to_unicode(base64.b64encode(text))
def request( self, url, data=None, headers=None, format="urlencoded", method="GET", content_type=None, token=None, discord=False, ): """ Sends a request to the remote server with OAuth tokens attached. :param data: the data to be sent to the server. :param headers: an optional dictionary of headers. :param format: the format for the `data`. Can be `urlencoded` for URL encoded data or `json` for JSON. :param method: the HTTP request method to use. :param content_type: an optional content type. If a content type is provided, the data is passed as it, and the `format` is ignored. :param token: an optional token to pass, if it is None, token will be generated by tokengetter. """ headers = dict(headers or {}) if token is None: token = self.get_request_token() client = self.make_client(token) url = self.expand_url(url) if method == "GET": assert format == "urlencoded" if data: url = add_params_to_uri(url, data) data = None else: if content_type is None: data, content_type = OAuth.encode_request_data(data, format) if content_type is not None: headers["Content-Type"] = content_type if self.request_token_url: # oauth1 uri, headers, body = client.sign(url, http_method=method, body=data, headers=headers) else: # oauth2 uri, headers, body = client.add_token(url, http_method=method, body=data, headers=headers) if hasattr(self, "pre_request"): # This is designed for some rubbish services like weibo. # Since they don't follow the standards, we need to # change the uri, headers, or body. uri, headers, body = self.pre_request(uri, headers, body) if body: data = to_bytes(body, self.encoding) else: data = None if discord: response = requests.request(method, uri, headers=headers, data=to_bytes(body, self.encoding)) if response.status_code not in (200, 201): raise OAuthException("Invalid response from %s" % self.name, type="invalid_response", data=data) return jsonify(response.text.encode("utf8")) resp, content = self.http_request(uri, headers, data=to_bytes(body, self.encoding), method=method) return OAuthResponse(resp, content, self.content_type)