WIP: authentication handling for ATST
This commit is contained in:
parent
cb51a20f72
commit
25db6fabbe
@ -4,6 +4,7 @@ import tornado.web
|
|||||||
from tornado.web import url
|
from tornado.web import url
|
||||||
|
|
||||||
from atst.handlers.main import MainHandler
|
from atst.handlers.main import MainHandler
|
||||||
|
from atst.handlers.login import Login
|
||||||
from atst.handlers.workspace import Workspace
|
from atst.handlers.workspace import Workspace
|
||||||
from atst.handlers.request import Request
|
from atst.handlers.request import Request
|
||||||
from atst.handlers.request_new import RequestNew
|
from atst.handlers.request_new import RequestNew
|
||||||
@ -16,7 +17,8 @@ def make_app(config):
|
|||||||
authz_client = ApiClient(config['default']['AUTHZ_BASE_URL'])
|
authz_client = ApiClient(config['default']['AUTHZ_BASE_URL'])
|
||||||
|
|
||||||
app = tornado.web.Application([
|
app = tornado.web.Application([
|
||||||
url( r"/", MainHandler, {'page': 'login'}, name='login' ),
|
url( r"/", Login, {'page': 'login'}, name='main' ),
|
||||||
|
url( r"/login", Login, {'page': 'login'}, name='login' ),
|
||||||
url( r"/home", MainHandler, {'page': 'home'}, name='home' ),
|
url( r"/home", MainHandler, {'page': 'home'}, name='home' ),
|
||||||
url( r"/workspaces",
|
url( r"/workspaces",
|
||||||
Workspace,
|
Workspace,
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import os
|
import os
|
||||||
|
import functools
|
||||||
from webassets import Environment, Bundle
|
from webassets import Environment, Bundle
|
||||||
import tornado.web
|
import tornado.web
|
||||||
from atst.home import home
|
from atst.home import home
|
||||||
@ -19,9 +20,41 @@ helpers = {
|
|||||||
'assets': assets
|
'assets': assets
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def authenticated(method):
|
||||||
|
@functools.wraps(method)
|
||||||
|
def wrapper(self, *args, **kwargs):
|
||||||
|
if not self.current_user:
|
||||||
|
if self.get_cookie('bearer-token'):
|
||||||
|
bearer_token = self.get_cookie('bearer-token')
|
||||||
|
if validate_login_token(bearer_token):
|
||||||
|
self._start_session()
|
||||||
|
else:
|
||||||
|
raise NotImplementedError
|
||||||
|
elif self.request.method in ("GET", "HEAD"):
|
||||||
|
url = self.get_login_url()
|
||||||
|
self.redirect(url)
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
raise tornado.web.HTTPError(403)
|
||||||
|
return method(self, *args, **kwargs)
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
def validate_login_token(token):
|
||||||
|
# check against authnid
|
||||||
|
pass
|
||||||
|
|
||||||
class BaseHandler(tornado.web.RequestHandler):
|
class BaseHandler(tornado.web.RequestHandler):
|
||||||
|
|
||||||
def get_template_namespace(self):
|
def get_template_namespace(self):
|
||||||
ns = super(BaseHandler, self).get_template_namespace()
|
ns = super(BaseHandler, self).get_template_namespace()
|
||||||
ns.update(helpers)
|
ns.update(helpers)
|
||||||
return ns
|
return ns
|
||||||
|
|
||||||
|
def get_current_user(self):
|
||||||
|
if self.get_secure_cookie('atst'):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
False
|
||||||
|
|
||||||
|
def _start_session(self):
|
||||||
|
self.set_secure_cookie('atst', 'valid-user-session')
|
||||||
|
10
atst/handlers/login.py
Normal file
10
atst/handlers/login.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import tornado
|
||||||
|
from atst.handler import BaseHandler
|
||||||
|
|
||||||
|
class Login(BaseHandler):
|
||||||
|
|
||||||
|
def initialize(self, page):
|
||||||
|
self.page = page
|
||||||
|
|
||||||
|
def get(self):
|
||||||
|
self.render( '%s.html.to' % self.page, page = self.page )
|
@ -1,9 +1,11 @@
|
|||||||
from atst.handler import BaseHandler
|
import atst
|
||||||
|
from atst.handler import BaseHandler, authenticated
|
||||||
|
|
||||||
class MainHandler(BaseHandler):
|
class MainHandler(BaseHandler):
|
||||||
|
|
||||||
def initialize(self, page):
|
def initialize(self, page):
|
||||||
self.page = page
|
self.page = page
|
||||||
|
|
||||||
|
@authenticated
|
||||||
def get(self):
|
def get(self):
|
||||||
self.render( '%s.html.to' % self.page, page = self.page )
|
self.render( '%s.html.to' % self.page, page = self.page )
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
from atst.handler import BaseHandler
|
from atst.handler import BaseHandler, authenticated
|
||||||
|
|
||||||
mock_requests = [
|
mock_requests = [
|
||||||
{
|
{
|
||||||
@ -31,5 +31,6 @@ class Request(BaseHandler):
|
|||||||
def initialize(self, page):
|
def initialize(self, page):
|
||||||
self.page = page
|
self.page = page
|
||||||
|
|
||||||
|
@authenticated
|
||||||
def get(self):
|
def get(self):
|
||||||
self.render('requests.html.to', page = self.page, requests = mock_requests )
|
self.render('requests.html.to', page = self.page, requests = mock_requests )
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
from atst.handler import BaseHandler
|
from atst.handler import BaseHandler, authenticated
|
||||||
|
|
||||||
class RequestNew(BaseHandler):
|
class RequestNew(BaseHandler):
|
||||||
screens = [
|
screens = [
|
||||||
@ -22,6 +22,7 @@ class RequestNew(BaseHandler):
|
|||||||
def initialize(self, page):
|
def initialize(self, page):
|
||||||
self.page = page
|
self.page = page
|
||||||
|
|
||||||
|
@authenticated
|
||||||
def get(self, screen = 1):
|
def get(self, screen = 1):
|
||||||
self.render( 'requests/screen-%d.html.to' % int(screen),
|
self.render( 'requests/screen-%d.html.to' % int(screen),
|
||||||
page = self.page,
|
page = self.page,
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
from atst.handler import BaseHandler
|
from atst.handler import BaseHandler, authenticated
|
||||||
import requests
|
|
||||||
import tornado.gen
|
import tornado.gen
|
||||||
|
|
||||||
mock_workspaces = [
|
mock_workspaces = [
|
||||||
@ -13,8 +12,6 @@ mock_workspaces = [
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
session = requests.Session()
|
|
||||||
|
|
||||||
class Workspace(BaseHandler):
|
class Workspace(BaseHandler):
|
||||||
|
|
||||||
def initialize(self, page, authz_client):
|
def initialize(self, page, authz_client):
|
||||||
@ -22,5 +19,6 @@ class Workspace(BaseHandler):
|
|||||||
self.authz_client = authz_client
|
self.authz_client = authz_client
|
||||||
|
|
||||||
@tornado.gen.coroutine
|
@tornado.gen.coroutine
|
||||||
|
@authenticated
|
||||||
def get(self):
|
def get(self):
|
||||||
self.render( 'workspaces.html.to', page = self.page, workspaces = mock_workspaces )
|
self.render( 'workspaces.html.to', page = self.page, workspaces = mock_workspaces )
|
||||||
|
34
tests/test_auth.py
Normal file
34
tests/test_auth.py
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import pytest
|
||||||
|
import tornado.web
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.gen_test
|
||||||
|
def test_redirects_when_not_logged_in(http_client, base_url):
|
||||||
|
response = yield http_client.fetch(
|
||||||
|
base_url + "/home", raise_error=False, follow_redirects=False
|
||||||
|
)
|
||||||
|
assert response.code == 302
|
||||||
|
assert response.error
|
||||||
|
assert response.headers["Location"] == "/login"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.gen_test
|
||||||
|
def test_login_with_valid_bearer_token(app, monkeypatch, http_client, base_url):
|
||||||
|
monkeypatch.setattr("atst.handler.validate_login_token", lambda t: True)
|
||||||
|
response = yield http_client.fetch(
|
||||||
|
base_url + "/home", headers={"Cookie": "bearer-token=anything"}
|
||||||
|
)
|
||||||
|
assert response.headers['Set-Cookie'].startswith('atst')
|
||||||
|
assert response.code == 200
|
||||||
|
assert not response.error
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.gen_test
|
||||||
|
@pytest.mark.skip(reason="need to work out auth error user paths")
|
||||||
|
def test_login_with_invalid_bearer_token(monkeypatch, http_client, base_url):
|
||||||
|
monkeypatch.setattr("atst.handler.validate_login_token", lambda t: False)
|
||||||
|
response = yield http_client.fetch(
|
||||||
|
base_url + "/home",
|
||||||
|
raise_error=False,
|
||||||
|
headers={"Cookie": "bearer-token=anything"},
|
||||||
|
)
|
Loading…
x
Reference in New Issue
Block a user