handle auth via redirect with parameter

This commit is contained in:
dandds 2018-06-12 15:07:45 -04:00
parent 234bbcea0f
commit 4e61b08330
5 changed files with 49 additions and 50 deletions

View File

@ -4,6 +4,7 @@ import tornado.web
from tornado.web import url
from atst.handlers.main import MainHandler
from atst.handlers.home import Home
from atst.handlers.login import Login
from atst.handlers.workspace import Workspace
from atst.handlers.request import Request
@ -20,7 +21,7 @@ def make_app(config):
authnid_client = ApiClient(config["default"]["AUTHNID_BASE_URL"])
routes = [
url(r"/", Login, {"page": "login"}, name="main"),
url(r"/", Home, {"page": "login"}, name="main"),
url(r"/login", Login, {"page": "login"}, name="login"),
url(r"/home", MainHandler, {"page": "home"}, name="home"),
url(
@ -47,7 +48,7 @@ def make_app(config):
app = tornado.web.Application(
routes,
login_url="/login",
login_url="/",
template_path = home.child('templates'),
static_path = home.child('static'),
cookie_secret=config["default"]["COOKIE_SECRET"],

View File

@ -22,17 +22,9 @@ helpers = {
def authenticated(method):
@functools.wraps(method)
@tornado.gen.coroutine
def wrapper(self, *args, **kwargs):
if not self.current_user:
if self.get_cookie('bearer-token'):
bearer_token = self.get_cookie('bearer-token')
valid = yield validate_login_token(self.application.authnid_client, bearer_token)
if valid:
self._start_session()
else:
raise NotImplementedError
elif self.request.method in ("GET", "HEAD"):
if self.request.method in ("GET", "HEAD"):
url = self.get_login_url()
self.redirect(url)
return
@ -41,17 +33,6 @@ def authenticated(method):
return method(self, *args, **kwargs)
return wrapper
@tornado.gen.coroutine
def validate_login_token(client, token):
try:
response = yield client.post('/api/v1/validate', raise_error=False, json={"token": token})
return response.code == 200
except tornado.httpclient.HTTPError as error:
if error.response.code == 401:
return False
else:
raise error
class BaseHandler(tornado.web.RequestHandler):
def get_template_namespace(self):

10
atst/handlers/home.py Normal file
View File

@ -0,0 +1,10 @@
import tornado
from atst.handler import BaseHandler
class Home(BaseHandler):
def initialize(self, page):
self.page = page
def get(self):
self.render( '%s.html.to' % self.page, page = self.page )

View File

@ -1,10 +1,37 @@
import tornado
from atst.handler import BaseHandler
class Login(BaseHandler):
def initialize(self, page):
self.page = page
@tornado.gen.coroutine
def get(self):
self.render( '%s.html.to' % self.page, page = self.page )
token = self.get_query_argument("bearer-token")
if token:
valid = yield self._validate_login_token(token)
if valid:
self._start_session()
self.redirect("/home")
return
url = self.get_login_url()
self.redirect(url)
return
@tornado.gen.coroutine
def _validate_login_token(self, token):
try:
response = yield self.application.authnid_client.post(
"/api/v1/validate", json={"token": token}
)
return response.code == 200
except tornado.httpclient.HTTPError as error:
if error.response.code == 401:
return False
else:
raise error

View File

@ -1,7 +1,6 @@
import pytest
import tornado.web
from concurrent.futures import ThreadPoolExecutor
from atst.handler import validate_login_token
class MockApiResponse():
@ -11,27 +10,6 @@ class MockApiResponse():
self.json = json
@pytest.mark.gen_test
def test_successful_validate_login_token(monkeypatch, app):
monkeypatch.setattr(
"atst.api_client.ApiClient.get",
lambda x,
y,
json=None: MockApiResponse(200, {"status": "success"}),
)
assert validate_login_token(app.authnid_client, "abc-123")
@pytest.mark.gen_test
def test_unsuccessful_validate_login_token(monkeypatch, app):
monkeypatch.setattr(
"atst.api_client.ApiClient.get",
lambda x,y,json=None: MockApiResponse(401, {"status": "error"}),
)
valid = yield validate_login_token(app.authnid_client, "abc-123")
assert not valid
@pytest.mark.gen_test
def test_redirects_when_not_logged_in(http_client, base_url):
response = yield http_client.fetch(
@ -39,22 +17,24 @@ def test_redirects_when_not_logged_in(http_client, base_url):
)
assert response.code == 302
assert response.error
assert response.headers["Location"] == "/login"
assert response.headers["Location"] == "/"
@pytest.mark.gen_test
def test_login_with_valid_bearer_token(app, monkeypatch, http_client, base_url):
with ThreadPoolExecutor(max_workers=1) as executor:
monkeypatch.setattr(
"atst.handler.validate_login_token",
"atst.handlers.login.Login._validate_login_token",
lambda c,t: executor.submit(lambda: True),
)
response = yield http_client.fetch(
base_url + "/home", headers={"Cookie": "bearer-token=anything"}
base_url + "/login?bearer-token=abc-123",
follow_redirects=False,
raise_error=False
)
assert response.headers["Set-Cookie"].startswith("atst")
assert response.code == 200
assert not response.error
assert response.headers['Location'] == '/home'
assert response.code == 302
@pytest.mark.gen_test