WIP: authentication handling for ATST

This commit is contained in:
dandds 2018-06-11 15:54:16 -04:00
parent cb51a20f72
commit 25db6fabbe
8 changed files with 89 additions and 8 deletions

View File

@ -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,

View File

@ -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
View 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 )

View File

@ -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 )

View File

@ -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 )

View File

@ -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,

View File

@ -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
View 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"},
)