def test_context_local(): responses.add(responses.GET, "https://google.com") # set up two apps with two different set of auth tokens app1 = Flask(__name__) jbp1 = make_jira_blueprint( "https://t1.atlassian.com", "foo1", "bar1", redirect_to="url1" ) app1.register_blueprint(jbp1) app2 = Flask(__name__) jbp2 = make_jira_blueprint( "https://t2.atlassian.com", "foo2", "bar2", redirect_to="url2" ) app2.register_blueprint(jbp2) # outside of a request context, referencing functions on the `jira` object # will raise an exception with pytest.raises(RuntimeError): jira.get("https://google.com") # inside of a request context, `jira` should be a proxy to the correct # blueprint session with app1.test_request_context("/"): jbp1.session.auth.client.get_oauth_signature = mock.Mock(return_value="sig1") jbp2.session.auth.client.get_oauth_signature = mock.Mock(return_value="sig2") app1.preprocess_request() jira.get("https://google.com") auth_header = dict( parse_authorization_header( responses.calls[0].request.headers["Authorization"].decode("utf-8") ) ) assert auth_header["oauth_consumer_key"] == "foo1" assert auth_header["oauth_signature"] == "sig1" with app2.test_request_context("/"): jbp1.session.auth.client.get_oauth_signature = mock.Mock(return_value="sig1") jbp2.session.auth.client.get_oauth_signature = mock.Mock(return_value="sig2") app2.preprocess_request() jira.get("https://google.com") auth_header = dict( parse_authorization_header( responses.calls[1].request.headers["Authorization"].decode("utf-8") ) ) assert auth_header["oauth_consumer_key"] == "foo2" assert auth_header["oauth_signature"] == "sig2"
def test_context_local(): responses.add(responses.GET, "https://google.com") # set up two apps with two different set of auth tokens app1 = Flask(__name__) jbp1 = make_jira_blueprint("https://t1.atlassian.com", "foo1", "bar1", redirect_to="url1") app1.register_blueprint(jbp1) app2 = Flask(__name__) jbp2 = make_jira_blueprint("https://t2.atlassian.com", "foo2", "bar2", redirect_to="url2") app2.register_blueprint(jbp2) # outside of a request context, referencing functions on the `jira` object # will raise an exception with pytest.raises(RuntimeError): jira.get("https://google.com") # inside of a request context, `jira` should be a proxy to the correct # blueprint session with app1.test_request_context("/"): jbp1.session.auth.client.get_oauth_signature = mock.Mock( return_value="sig1") jbp2.session.auth.client.get_oauth_signature = mock.Mock( return_value="sig2") app1.preprocess_request() jira.get("https://google.com") assert len(responses.calls) > 0 auth_header = dict( parse_authorization_header( responses.calls[0].request.headers["Authorization"].decode( "utf-8"))) assert auth_header["oauth_consumer_key"] == "foo1" assert auth_header["oauth_signature"] == "sig1" with app2.test_request_context("/"): jbp1.session.auth.client.get_oauth_signature = mock.Mock( return_value="sig1") jbp2.session.auth.client.get_oauth_signature = mock.Mock( return_value="sig2") app2.preprocess_request() jira.get("https://google.com") assert len(responses.calls) > 0 auth_header = dict( parse_authorization_header( responses.calls[1].request.headers["Authorization"].decode( "utf-8"))) assert auth_header["oauth_consumer_key"] == "foo2" assert auth_header["oauth_signature"] == "sig2"
def test_login_url(): responses.add( responses.POST, "https://example.com/oauth/request_token", body="oauth_token=foobar&oauth_token_secret=bazqux", ) app, _ = make_app() client = app.test_client() resp = client.get( "/login/test-service", base_url="https://a.b.c", follow_redirects=False ) # check that we obtained a request token assert len(responses.calls) == 1 assert "Authorization" in responses.calls[0].request.headers auth_header = dict( parse_authorization_header( responses.calls[0].request.headers["Authorization"].decode("utf-8") ) ) assert auth_header["oauth_consumer_key"] == "client_key" assert "oauth_signature" in auth_header assert auth_header["oauth_callback"] == quote_plus( "https://a.b.c/login/test-service/authorized" ) # check that we redirected the client assert resp.status_code == 302 assert ( resp.headers["Location"] == "https://example.com/oauth/authorize?oauth_token=foobar" )
def test_authorized_url(): responses.add( responses.POST, "https://example.com/oauth/access_token", body="oauth_token=xxx&oauth_token_secret=yyy", ) app, _ = make_app() with app.test_client() as client: resp = client.get( "/login/test-service/authorized?oauth_token=foobar&oauth_verifier=xyz", base_url="https://a.b.c", ) # check that we redirected the client assert resp.status_code == 302 assert resp.headers["Location"] == "https://a.b.c/" # check that we obtained an access token assert len(responses.calls) == 1 assert "Authorization" in responses.calls[0].request.headers auth_header = dict( parse_authorization_header( responses.calls[0].request.headers["Authorization"].decode("utf-8") ) ) assert auth_header["oauth_consumer_key"] == "client_key" assert auth_header["oauth_token"] == "foobar" assert auth_header["oauth_verifier"] == "xyz" # check that we stored the access token and secret in the session assert flask.session["test-service_oauth_token"] == { "oauth_token": "xxx", "oauth_token_secret": "yyy", }
def validate_request(request, consumer_getter): """Checks whether the request has come from an authorized consumer The `request` object is an instance of the twolegged.Request class and is framework agnostic. `consumer_getter` is a simple function to lookup a consumer from it's key. If the request is invalid for any reason other than non-matching signatures, a `InvalidRequest` exception will be raised. :param request : a twolegged.Request subclass :param consumer_getter : function :rtype : boolean """ headers = request.headers() auth_header = headers.get('Authorization') request_values = request.values() if auth_header: authorization = dict(parse_authorization_header(auth_header)) key = authorization['oauth_consumer_key'] signature = unescape(authorization['oauth_signature']) else: key = request_values.get('oauth_consumer_key', None) signature = request_values.get('oauth_signature', None) if key is None or signature is None: raise InvalidRequest(( "Failed to authenticate since necessary parameters were not supplied" )) consumer = consumer_getter(key) if consumer is None: raise InvalidRequest('Consumer not found') return build_signature(request, consumer['secret']) == unescape(signature)
def test_login_url_forwarded_proto(): responses.add( responses.POST, "https://example.com/oauth/request_token", body="oauth_token=foobar&oauth_token_secret=bazqux" ) app, _ = make_app() app.wsgi_app = ProxyFix(app.wsgi_app) with app.test_client() as client: resp = client.get( "/login/test-service", base_url="http://a.b.c", headers={"X-Forwarded-Proto": "https"}, follow_redirects=False, ) auth_header = dict(parse_authorization_header(responses.calls[0].request.headers["Authorization"].decode("utf-8"))) # this should be https assert auth_header["oauth_callback"] == quote_plus("https://a.b.c/login/test-service/authorized")
def test_load_from_config(make_app): responses.add( responses.POST, "https://api.twitter.com/oauth/request_token", body="oauth_token=faketoken&oauth_token_secret=fakesecret", ) app = make_app() app.config["TWITTER_OAUTH_CLIENT_KEY"] = "foo" app.config["TWITTER_OAUTH_CLIENT_SECRET"] = "bar" app.test_client().get("/twitter") auth_header = dict( parse_authorization_header( responses.calls[0].request.headers["Authorization"].decode( "utf-8"))) assert auth_header["oauth_consumer_key"] == "foo"
def test_load_from_config(sign_func, make_app): responses.add( responses.POST, "https://flask.atlassian.net/plugins/servlet/oauth/request-token", body="oauth_token=faketoken&oauth_token_secret=fakesecret", ) app = make_app("https://flask.atlassian.net", redirect_to="index") app.config["JIRA_OAUTH_CONSUMER_KEY"] = "foo" app.config["JIRA_OAUTH_RSA_KEY"] = "bar" resp = app.test_client().get("/jira") auth_header = dict( parse_authorization_header( responses.calls[0].request.headers["Authorization"].decode( "utf-8"))) assert auth_header["oauth_consumer_key"] == "foo" assert sign_func.call_args[0][1] == "bar"
def test_load_from_config(make_app): responses.add( responses.POST, "https://api.twitter.com/oauth/request_token", body="oauth_token=faketoken&oauth_token_secret=fakesecret", ) app = make_app() app.config["TWITTER_OAUTH_CLIENT_KEY"] = "foo" app.config["TWITTER_OAUTH_CLIENT_SECRET"] = "bar" app.test_client().get("/twitter") auth_header = dict( parse_authorization_header( responses.calls[0].request.headers["Authorization"].decode("utf-8") ) ) assert auth_header["oauth_consumer_key"] == "foo"
def test_load_from_config(sign_func, make_app): responses.add( responses.POST, "https://flask.atlassian.net/plugins/servlet/oauth/request-token", body="oauth_token=faketoken&oauth_token_secret=fakesecret", ) app = make_app("https://flask.atlassian.net", redirect_to="index") app.config["JIRA_OAUTH_CONSUMER_KEY"] = "foo" app.config["JIRA_OAUTH_RSA_KEY"] = "bar" resp = app.test_client().get("/jira") auth_header = dict( parse_authorization_header( responses.calls[0].request.headers["Authorization"].decode("utf-8") ) ) assert auth_header["oauth_consumer_key"] == "foo" assert sign_func.call_args[0][1] == "bar"
def test_load_from_config(): responses.add( responses.POST, "https://api.twitter.com/oauth/request_token", body="oauth_token=faketoken&oauth_token_secret=fakesecret", ) app = Flask(__name__) app.secret_key = "anything" app.config["TWITTER_OAUTH_API_KEY"] = "foo" app.config["TWITTER_OAUTH_API_SECRET"] = "bar" twitter_bp = make_twitter_blueprint(redirect_to="index") app.register_blueprint(twitter_bp) app.test_client().get("/twitter") auth_header = dict(parse_authorization_header( responses.calls[0].request.headers['Authorization'].decode('utf-8') )) assert auth_header["oauth_consumer_key"] == "foo"
def test_load_from_config(sign_func): responses.add( responses.POST, "https://flask.atlassian.net/plugins/servlet/oauth/request-token", body="oauth_token=faketoken&oauth_token_secret=fakesecret", ) app = Flask(__name__) app.secret_key = "anything" app.config["JIRA_OAUTH_CONSUMER_KEY"] = "foo" app.config["JIRA_OAUTH_RSA_KEY"] = "bar" jira_bp = make_jira_blueprint("https://flask.atlassian.net", redirect_to="index") app.register_blueprint(jira_bp) resp = app.test_client().get("/jira") auth_header = dict(parse_authorization_header( responses.calls[0].request.headers['Authorization'].decode('utf-8') )) assert auth_header["oauth_consumer_key"] == "foo" assert sign_func.call_args[0][1] == "bar"
def test_load_from_config(sign_func): responses.add( responses.POST, "https://flask.atlassian.net/plugins/servlet/oauth/request-token", body="oauth_token=faketoken&oauth_token_secret=fakesecret", ) app = Flask(__name__) app.secret_key = "anything" app.config["JIRA_OAUTH_CONSUMER_KEY"] = "foo" app.config["JIRA_OAUTH_RSA_KEY"] = "bar" jira_bp = make_jira_blueprint("https://flask.atlassian.net", redirect_to="index") app.register_blueprint(jira_bp) resp = app.test_client().get("/jira") auth_header = dict(parse_authorization_header( responses.calls[0].request.headers['Authorization'].decode('utf-8') )) assert auth_header["oauth_consumer_key"] == "foo" assert sign_func.call_args[0][1] == "bar"
def test_load_from_config(): responses.add( responses.POST, "https://api.twitter.com/oauth/request_token", body="oauth_token=faketoken&oauth_token_secret=fakesecret", ) app = Flask(__name__) app.secret_key = "anything" app.config["TWITTER_OAUTH_API_KEY"] = "foo" app.config["TWITTER_OAUTH_API_SECRET"] = "bar" twitter_bp = make_twitter_blueprint(redirect_to="index") app.register_blueprint(twitter_bp) app.test_client().get("/twitter") auth_header = dict( parse_authorization_header( responses.calls[0].request.headers['Authorization'].decode( 'utf-8'))) assert auth_header["oauth_consumer_key"] == "foo"
def test_login_url_forwarded_proto(): responses.add( responses.POST, "https://example.com/oauth/request_token", body="oauth_token=foobar&oauth_token_secret=bazqux", ) app, _ = make_app() with app.test_client() as client: resp = client.get( "/login/test-service", base_url="http://a.b.c", headers={"X-Forwarded-Proto": "https"}, follow_redirects=False, ) auth_header = dict(parse_authorization_header( responses.calls[0].request.headers['Authorization'].decode('utf-8') )) # this should be https assert auth_header["oauth_callback"] == quote_plus("https://a.b.c/login/test-service/authorized")