Use black for formatting
This commit is contained in:
parent
3599440ee6
commit
f9335c7a4e
1
Pipfile
1
Pipfile
@ -15,6 +15,7 @@ pytest-tornado = "==0.5.0"
|
||||
ipython = "*"
|
||||
ipdb = "*"
|
||||
pylint = "*"
|
||||
black = "*"
|
||||
|
||||
[requires]
|
||||
python_version = "3.6"
|
||||
|
72
Pipfile.lock
generated
72
Pipfile.lock
generated
@ -1,7 +1,7 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "3ee82a3d0081be8881d2c211c6d0333b179e78754e953b609e10a51a4ab87c88"
|
||||
"sha256": "4792f21af3f461ea6eb1c7c2f7387a545cb5cfaedaf5f27694e16b6ba0a042fd"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
@ -58,6 +58,13 @@
|
||||
}
|
||||
},
|
||||
"develop": {
|
||||
"appdirs": {
|
||||
"hashes": [
|
||||
"sha256:9e5896d1372858f8dd3344faf4e5014d21849c756c8d5701f78f8a103b372d92",
|
||||
"sha256:d8b24664561d0d34ddfaec54636d502d7cea6e29c3eaf68f3df6180863e2166e"
|
||||
],
|
||||
"version": "==1.4.3"
|
||||
},
|
||||
"appnope": {
|
||||
"hashes": [
|
||||
"sha256:5b26757dc6f79a3b7dc9fab95359328d5747fcb2409d331ea66d0272b90ab2a0",
|
||||
@ -68,10 +75,10 @@
|
||||
},
|
||||
"astroid": {
|
||||
"hashes": [
|
||||
"sha256:0ef2bf9f07c3150929b25e8e61b5198c27b0dca195e156f0e4d5bdd89185ca1a",
|
||||
"sha256:fc9b582dba0366e63540982c3944a9230cbc6f303641c51483fa547dcc22393a"
|
||||
"sha256:ae61ddd0290963f4cf3bd74e6dffce807466bfe25438b2b3598471a1ce40a635",
|
||||
"sha256:f447b5c8b7bd5cba229fb73890ea8088380c8c37ff33417c29a53a553f857419"
|
||||
],
|
||||
"version": "==1.6.5"
|
||||
"version": "==2.0.0.dev3"
|
||||
},
|
||||
"atomicwrites": {
|
||||
"hashes": [
|
||||
@ -94,6 +101,21 @@
|
||||
],
|
||||
"version": "==0.1.0"
|
||||
},
|
||||
"black": {
|
||||
"hashes": [
|
||||
"sha256:22158b89c1a6b4eb333a1e65e791a3f8b998cf3b11ae094adb2570f31f769a44",
|
||||
"sha256:4b475bbd528acce094c503a3d2dbc2d05a4075f6d0ef7d9e7514518e14cc5191"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==18.6b4"
|
||||
},
|
||||
"click": {
|
||||
"hashes": [
|
||||
"sha256:29f99fc6125fbc931b758dc053b3114e55c77a6e4c6c3a2674a2dc986016381d",
|
||||
"sha256:f15516df478d5a56180fbf80e68f206010e6d160fc39fa508b65e035fd75130b"
|
||||
],
|
||||
"version": "==6.7"
|
||||
},
|
||||
"decorator": {
|
||||
"hashes": [
|
||||
"sha256:2c51dff8ef3c447388fe5e4453d24a2bf128d3a4c32af3fabef1f01c6851ab82",
|
||||
@ -227,10 +249,10 @@
|
||||
},
|
||||
"ptyprocess": {
|
||||
"hashes": [
|
||||
"sha256:e64193f0047ad603b71f202332ab5527c5e52aa7c8b609704fc28c0dc20c4365",
|
||||
"sha256:e8c43b5eee76b2083a9badde89fd1bbce6c8942d1045146e100b7b5e014f4f1a"
|
||||
"sha256:923f299cc5ad920c68f2bc0bc98b75b9f838b93b599941a6b63ddbc2476394c0",
|
||||
"sha256:d7cc528d76e76342423ca640335bd3633420dc1366f258cb31d05e865ef5ca1f"
|
||||
],
|
||||
"version": "==0.5.2"
|
||||
"version": "==0.6.0"
|
||||
},
|
||||
"py": {
|
||||
"hashes": [
|
||||
@ -248,11 +270,11 @@
|
||||
},
|
||||
"pylint": {
|
||||
"hashes": [
|
||||
"sha256:a48070545c12430cfc4e865bf62f5ad367784765681b3db442d8230f0960aa3c",
|
||||
"sha256:fff220bcb996b4f7e2b0f6812fd81507b72ca4d8c4d05daf2655c333800cb9b3"
|
||||
"sha256:0990347c0f605927fadb2a9366a0b3d40bd19eb44e4312f0a1ef729a389b2f40",
|
||||
"sha256:19b902f93f2dc3fa45565e54b88702b28379be40107f509a8516dde152460d1f"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.9.2"
|
||||
"version": "==2.0.0.dev1"
|
||||
},
|
||||
"pytest": {
|
||||
"hashes": [
|
||||
@ -283,6 +305,12 @@
|
||||
],
|
||||
"version": "==1.11.0"
|
||||
},
|
||||
"toml": {
|
||||
"hashes": [
|
||||
"sha256:8e86bd6ce8cc11b9620cb637466453d94f5d57ad86f17e98a98d1f73e3baab2d"
|
||||
],
|
||||
"version": "==0.9.4"
|
||||
},
|
||||
"tornado": {
|
||||
"hashes": [
|
||||
"sha256:1b83d5c10550f2653380b4c77331d6f8850f287c4f67d7ce1e1c639d9222fbc7",
|
||||
@ -301,6 +329,30 @@
|
||||
],
|
||||
"version": "==4.3.2"
|
||||
},
|
||||
"typed-ast": {
|
||||
"hashes": [
|
||||
"sha256:0948004fa228ae071054f5208840a1e88747a357ec1101c17217bfe99b299d58",
|
||||
"sha256:25d8feefe27eb0303b73545416b13d108c6067b846b543738a25ff304824ed9a",
|
||||
"sha256:29464a177d56e4e055b5f7b629935af7f49c196be47528cc94e0a7bf83fbc2b9",
|
||||
"sha256:2e214b72168ea0275efd6c884b114ab42e316de3ffa125b267e732ed2abda892",
|
||||
"sha256:3e0d5e48e3a23e9a4d1a9f698e32a542a4a288c871d33ed8df1b092a40f3a0f9",
|
||||
"sha256:519425deca5c2b2bdac49f77b2c5625781abbaf9a809d727d3a5596b30bb4ded",
|
||||
"sha256:57fe287f0cdd9ceaf69e7b71a2e94a24b5d268b35df251a88fef5cc241bf73aa",
|
||||
"sha256:668d0cec391d9aed1c6a388b0d5b97cd22e6073eaa5fbaa6d2946603b4871efe",
|
||||
"sha256:68ba70684990f59497680ff90d18e756a47bf4863c604098f10de9716b2c0bdd",
|
||||
"sha256:6de012d2b166fe7a4cdf505eee3aaa12192f7ba365beeefaca4ec10e31241a85",
|
||||
"sha256:79b91ebe5a28d349b6d0d323023350133e927b4de5b651a8aa2db69c761420c6",
|
||||
"sha256:8550177fa5d4c1f09b5e5f524411c44633c80ec69b24e0e98906dd761941ca46",
|
||||
"sha256:a8034021801bc0440f2e027c354b4eafd95891b573e12ff0418dec385c76785c",
|
||||
"sha256:bc978ac17468fe868ee589c795d06777f75496b1ed576d308002c8a5756fb9ea",
|
||||
"sha256:c05b41bc1deade9f90ddc5d988fe506208019ebba9f2578c622516fd201f5863",
|
||||
"sha256:c9b060bd1e5a26ab6e8267fd46fc9e02b54eb15fffb16d112d4c7b1c12987559",
|
||||
"sha256:edb04bdd45bfd76c8292c4d9654568efaedf76fe78eb246dde69bdb13b2dad87",
|
||||
"sha256:f19f2a4f547505fe9072e15f6f4ae714af51b5a681a97f187971f50c283193b6"
|
||||
],
|
||||
"markers": "python_version < '3.7' and implementation_name == 'cpython'",
|
||||
"version": "==1.1.0"
|
||||
},
|
||||
"wcwidth": {
|
||||
"hashes": [
|
||||
"sha256:3df37372226d6e63e1b1e1eda15c594bca98a22d33a23832a90998faa96bc65e",
|
||||
|
4
app.py
4
app.py
@ -8,8 +8,8 @@ config = make_config()
|
||||
deps = make_deps(config)
|
||||
app = make_app(config, deps)
|
||||
|
||||
if __name__ == '__main__':
|
||||
port = int(config['default']['PORT'])
|
||||
if __name__ == "__main__":
|
||||
port = int(config["default"]["PORT"])
|
||||
app.listen(port)
|
||||
print("Listening on http://localhost:%i" % port)
|
||||
tornado.ioloop.IOLoop.current().start()
|
||||
|
@ -4,54 +4,52 @@ from json import dumps, loads
|
||||
|
||||
|
||||
class ApiClient(object):
|
||||
|
||||
def __init__(self, base_url, api_version=None, validate_cert=True):
|
||||
self.base_url = base_url
|
||||
if api_version:
|
||||
self.base_url = f'{base_url}/api/{api_version}'
|
||||
self.base_url = f"{base_url}/api/{api_version}"
|
||||
self.client = AsyncHTTPClient()
|
||||
self.validate_cert = validate_cert
|
||||
|
||||
@tornado.gen.coroutine
|
||||
def get(self, path, **kwargs):
|
||||
return (yield self.make_request('GET', self.base_url + path, **kwargs))
|
||||
return (yield self.make_request("GET", self.base_url + path, **kwargs))
|
||||
|
||||
@tornado.gen.coroutine
|
||||
def put(self, path, **kwargs):
|
||||
return (yield self.make_request('PUT', self.base_url + path, **kwargs))
|
||||
return (yield self.make_request("PUT", self.base_url + path, **kwargs))
|
||||
|
||||
@tornado.gen.coroutine
|
||||
def post(self, path, **kwargs):
|
||||
return (yield self.make_request('POST', self.base_url + path, **kwargs))
|
||||
return (yield self.make_request("POST", self.base_url + path, **kwargs))
|
||||
|
||||
@tornado.gen.coroutine
|
||||
def patch(self, path, **kwargs):
|
||||
return (yield self.make_request('PATCH', self.base_url + path, **kwargs))
|
||||
return (yield self.make_request("PATCH", self.base_url + path, **kwargs))
|
||||
|
||||
@tornado.gen.coroutine
|
||||
def delete(self, path, **kwargs):
|
||||
return (yield self.make_request('DELETE', self.base_url + path, **kwargs))
|
||||
return (yield self.make_request("DELETE", self.base_url + path, **kwargs))
|
||||
|
||||
@tornado.gen.coroutine
|
||||
def make_request(self, method, url, **kwargs):
|
||||
# If 'json' kwarg is specified, serialize it to 'body' and update
|
||||
# the Content-Type.
|
||||
if 'json' in kwargs:
|
||||
kwargs['body'] = dumps(kwargs['json'])
|
||||
del kwargs['json']
|
||||
headers = kwargs.get('headers', {})
|
||||
headers['Content-Type'] = 'application/json'
|
||||
kwargs['headers'] = headers
|
||||
if not 'validate_cert' in kwargs:
|
||||
kwargs['validate_cert'] = self.validate_cert
|
||||
if "json" in kwargs:
|
||||
kwargs["body"] = dumps(kwargs["json"])
|
||||
del kwargs["json"]
|
||||
headers = kwargs.get("headers", {})
|
||||
headers["Content-Type"] = "application/json"
|
||||
kwargs["headers"] = headers
|
||||
if not "validate_cert" in kwargs:
|
||||
kwargs["validate_cert"] = self.validate_cert
|
||||
|
||||
response = yield self.client.fetch(
|
||||
url, method=method, **kwargs)
|
||||
response = yield self.client.fetch(url, method=method, **kwargs)
|
||||
return self.adapt_response(response)
|
||||
|
||||
def adapt_response(self, response):
|
||||
if 'application/json' in response.headers['Content-Type']:
|
||||
if "application/json" in response.headers["Content-Type"]:
|
||||
json = loads(response.body)
|
||||
setattr(response, 'json', json)
|
||||
setattr(response, 'ok', 200 <= response.code < 300)
|
||||
setattr(response, "json", json)
|
||||
setattr(response, "ok", 200 <= response.code < 300)
|
||||
return response
|
||||
|
60
atst/app.py
60
atst/app.py
@ -20,14 +20,14 @@ def make_app(config, deps, **kwargs):
|
||||
|
||||
routes = [
|
||||
url(r"/", Home, {"page": "login"}, name="main"),
|
||||
url(
|
||||
r"/login",
|
||||
Login,
|
||||
{"authnid_client": deps["authnid_client"]},
|
||||
name="login",
|
||||
),
|
||||
url(r"/login", Login, {"authnid_client": deps["authnid_client"]}, name="login"),
|
||||
url(r"/home", MainHandler, {"page": "home"}, name="home"),
|
||||
url( r"/workspaces/blank", MainHandler, {'page': 'workspaces_blank'}, name='workspaces_blank' ),
|
||||
url(
|
||||
r"/workspaces/blank",
|
||||
MainHandler,
|
||||
{"page": "workspaces_blank"},
|
||||
name="workspaces_blank",
|
||||
),
|
||||
url(
|
||||
r"/workspaces",
|
||||
Workspace,
|
||||
@ -37,13 +37,15 @@ def make_app(config, deps, **kwargs):
|
||||
url(
|
||||
r"/requests",
|
||||
Request,
|
||||
{"page": "requests", 'requests_client': deps['requests_client']},
|
||||
name="requests"),
|
||||
{"page": "requests", "requests_client": deps["requests_client"]},
|
||||
name="requests",
|
||||
),
|
||||
url(
|
||||
r"/requests/new",
|
||||
RequestNew,
|
||||
{"page": "requests_new", "requests_client": deps["requests_client"]},
|
||||
name="request_new"),
|
||||
name="request_new",
|
||||
),
|
||||
url(
|
||||
r"/requests/new/([0-9])",
|
||||
RequestNew,
|
||||
@ -67,12 +69,11 @@ def make_app(config, deps, **kwargs):
|
||||
app = tornado.web.Application(
|
||||
routes,
|
||||
login_url="/",
|
||||
|
||||
template_path = home.child('templates'),
|
||||
static_path = home.child('static'),
|
||||
template_path=home.child("templates"),
|
||||
static_path=home.child("static"),
|
||||
cookie_secret=config["default"]["COOKIE_SECRET"],
|
||||
debug=config['default'].getboolean('DEBUG'),
|
||||
**kwargs
|
||||
debug=config["default"].getboolean("DEBUG"),
|
||||
**kwargs,
|
||||
)
|
||||
app.config = config
|
||||
return app
|
||||
@ -80,23 +81,30 @@ def make_app(config, deps, **kwargs):
|
||||
|
||||
def make_deps(config):
|
||||
# we do not want to do SSL verify services in test and development
|
||||
validate_cert = ENV == 'production'
|
||||
validate_cert = ENV == "production"
|
||||
return {
|
||||
'authz_client': ApiClient(config["default"]["AUTHZ_BASE_URL"], api_version='v1', validate_cert=validate_cert),
|
||||
'authnid_client': ApiClient(config["default"]["AUTHNID_BASE_URL"], api_version='v1', validate_cert=validate_cert),
|
||||
'requests_client': ApiClient(config["default"]["REQUESTS_QUEUE_BASE_URL"], api_version='v1', validate_cert=validate_cert)
|
||||
"authz_client": ApiClient(
|
||||
config["default"]["AUTHZ_BASE_URL"],
|
||||
api_version="v1",
|
||||
validate_cert=validate_cert,
|
||||
),
|
||||
"authnid_client": ApiClient(
|
||||
config["default"]["AUTHNID_BASE_URL"],
|
||||
api_version="v1",
|
||||
validate_cert=validate_cert,
|
||||
),
|
||||
"requests_client": ApiClient(
|
||||
config["default"]["REQUESTS_QUEUE_BASE_URL"],
|
||||
api_version="v1",
|
||||
validate_cert=validate_cert,
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
def make_config():
|
||||
BASE_CONFIG_FILENAME = os.path.join(
|
||||
os.path.dirname(__file__),
|
||||
"../config/base.ini"
|
||||
)
|
||||
BASE_CONFIG_FILENAME = os.path.join(os.path.dirname(__file__), "../config/base.ini")
|
||||
ENV_CONFIG_FILENAME = os.path.join(
|
||||
os.path.dirname(__file__),
|
||||
"../config/",
|
||||
"{}.ini".format(ENV.lower())
|
||||
os.path.dirname(__file__), "../config/", "{}.ini".format(ENV.lower())
|
||||
)
|
||||
config = ConfigParser()
|
||||
|
||||
|
@ -2,7 +2,8 @@ from wtforms.fields.html5 import IntegerField
|
||||
from wtforms.validators import Required, ValidationError
|
||||
from wtforms_tornado import Form
|
||||
|
||||
|
||||
class DateForm(Form):
|
||||
month = IntegerField('Month', validators=[Required()])
|
||||
day = IntegerField('Day', validators=[Required()])
|
||||
year = IntegerField('Year', validators=[Required()])
|
||||
month = IntegerField("Month", validators=[Required()])
|
||||
day = IntegerField("Day", validators=[Required()])
|
||||
year = IntegerField("Year", validators=[Required()])
|
||||
|
@ -1,4 +1,5 @@
|
||||
from wtforms_tornado import Form
|
||||
|
||||
|
||||
class FundingForm(Form):
|
||||
pass
|
||||
|
@ -1,4 +1,5 @@
|
||||
from wtforms_tornado import Form
|
||||
|
||||
|
||||
class OrganizationInfoForm(Form):
|
||||
pass
|
||||
|
@ -1,4 +1,5 @@
|
||||
from wtforms_tornado import Form
|
||||
|
||||
|
||||
class ReadinessForm(Form):
|
||||
pass
|
||||
|
@ -1,44 +1,73 @@
|
||||
from wtforms.fields.html5 import IntegerField
|
||||
from wtforms.fields import RadioField, StringField, SelectField, TextAreaField, FormField
|
||||
from wtforms.fields import (
|
||||
RadioField,
|
||||
StringField,
|
||||
SelectField,
|
||||
TextAreaField,
|
||||
FormField,
|
||||
)
|
||||
from wtforms.validators import Required, ValidationError
|
||||
from wtforms_tornado import Form
|
||||
from .date import DateForm
|
||||
|
||||
|
||||
class RequestForm(Form):
|
||||
application_name = StringField('Application name', validators=[Required()])
|
||||
application_description = TextAreaField('Application description', validators=[Required()])
|
||||
dollar_value = IntegerField('Estimated dollar value of use', validators=[Required()])
|
||||
input_estimate = SelectField('How did you arrive at this estimate?', validators=[Required()],
|
||||
choices=[('','- Select -'),
|
||||
('calculator','CSP usage calculator'),
|
||||
('B','Option B'),
|
||||
('C','Option C') ])
|
||||
application_name = StringField("Application name", validators=[Required()])
|
||||
application_description = TextAreaField(
|
||||
"Application description", validators=[Required()]
|
||||
)
|
||||
dollar_value = IntegerField(
|
||||
"Estimated dollar value of use", validators=[Required()]
|
||||
)
|
||||
input_estimate = SelectField(
|
||||
"How did you arrive at this estimate?",
|
||||
validators=[Required()],
|
||||
choices=[
|
||||
("", "- Select -"),
|
||||
("calculator", "CSP usage calculator"),
|
||||
("B", "Option B"),
|
||||
("C", "Option C"),
|
||||
],
|
||||
)
|
||||
# no way to apply a label to a whole nested form like this
|
||||
date_start = FormField(DateForm)
|
||||
period_of_performance = SelectField('Desired period of performance', validators=[Required()],
|
||||
choices=[('','- Select -'),
|
||||
('value1','30 days'),
|
||||
('value2','60 days'),
|
||||
('value3','90 days') ])
|
||||
classification_level = RadioField('Classification level', validators=[Required()],
|
||||
choices=[('unclassified', 'Unclassified'),
|
||||
('secret', 'Secret'),
|
||||
('top-secret', 'Top Secret') ])
|
||||
primary_service_branch = StringField('Primary service branch usage', validators=[Required()])
|
||||
cloud_model = RadioField('Cloud model service', validators=[Required()],
|
||||
choices=[('iaas', 'IaaS'),
|
||||
('paas', 'PaaS'),
|
||||
('both', 'Both') ])
|
||||
number_of_cores = IntegerField('Number of cores', validators=[Required()])
|
||||
total_ram = IntegerField('Total RAM', validators=[Required()])
|
||||
object_storage = IntegerField('Total object storage', validators=[Required()])
|
||||
server_storage = IntegerField('Total server storage', validators=[Required()])
|
||||
total_active_users = IntegerField('Total active users', validators=[Required()])
|
||||
total_peak_users = IntegerField('Total peak users', validators=[Required()])
|
||||
total_requests = IntegerField('Total requests', validators=[Required()])
|
||||
total_environments = IntegerField('Total environments', validators=[Required()])
|
||||
period_of_performance = SelectField(
|
||||
"Desired period of performance",
|
||||
validators=[Required()],
|
||||
choices=[
|
||||
("", "- Select -"),
|
||||
("value1", "30 days"),
|
||||
("value2", "60 days"),
|
||||
("value3", "90 days"),
|
||||
],
|
||||
)
|
||||
classification_level = RadioField(
|
||||
"Classification level",
|
||||
validators=[Required()],
|
||||
choices=[
|
||||
("unclassified", "Unclassified"),
|
||||
("secret", "Secret"),
|
||||
("top-secret", "Top Secret"),
|
||||
],
|
||||
)
|
||||
primary_service_branch = StringField(
|
||||
"Primary service branch usage", validators=[Required()]
|
||||
)
|
||||
cloud_model = RadioField(
|
||||
"Cloud model service",
|
||||
validators=[Required()],
|
||||
choices=[("iaas", "IaaS"), ("paas", "PaaS"), ("both", "Both")],
|
||||
)
|
||||
number_of_cores = IntegerField("Number of cores", validators=[Required()])
|
||||
total_ram = IntegerField("Total RAM", validators=[Required()])
|
||||
object_storage = IntegerField("Total object storage", validators=[Required()])
|
||||
server_storage = IntegerField("Total server storage", validators=[Required()])
|
||||
total_active_users = IntegerField("Total active users", validators=[Required()])
|
||||
total_peak_users = IntegerField("Total peak users", validators=[Required()])
|
||||
total_requests = IntegerField("Total requests", validators=[Required()])
|
||||
total_environments = IntegerField("Total environments", validators=[Required()])
|
||||
|
||||
# this is just an example validation; obviously this is wrong.
|
||||
def validate_total_ram(self,field):
|
||||
def validate_total_ram(self, field):
|
||||
if (field.data % 2) != 0:
|
||||
raise ValidationError("RAM must be in increments of 2.")
|
||||
|
@ -1,4 +1,5 @@
|
||||
from wtforms_tornado import Form
|
||||
|
||||
|
||||
class ReviewForm(Form):
|
||||
pass
|
||||
|
@ -2,34 +2,31 @@ from webassets import Environment, Bundle
|
||||
import tornado.web
|
||||
from atst.home import home
|
||||
|
||||
assets = Environment(
|
||||
directory = home.child('scss'),
|
||||
url = '/static')
|
||||
css = Bundle(
|
||||
'atat.scss',
|
||||
filters = 'scss',
|
||||
output = '../static/assets/out.css',
|
||||
depends = ('**/*.scss'))
|
||||
assets = Environment(directory=home.child("scss"), url="/static")
|
||||
css = Bundle(
|
||||
"atat.scss",
|
||||
filters="scss",
|
||||
output="../static/assets/out.css",
|
||||
depends=("**/*.scss"),
|
||||
)
|
||||
|
||||
assets.register( 'css', css )
|
||||
helpers = {
|
||||
'assets': assets,
|
||||
}
|
||||
assets.register("css", css)
|
||||
helpers = {"assets": assets}
|
||||
|
||||
|
||||
class BaseHandler(tornado.web.RequestHandler):
|
||||
def get_template_namespace(self):
|
||||
ns = super(BaseHandler, self).get_template_namespace()
|
||||
helpers['config'] = self.application.config
|
||||
helpers["config"] = self.application.config
|
||||
ns.update(helpers)
|
||||
return ns
|
||||
|
||||
def get_current_user(self):
|
||||
if self.get_secure_cookie('atst'):
|
||||
return '9cb348f0-8102-4962-88c4-dac8180c904c'
|
||||
if self.get_secure_cookie("atst"):
|
||||
return "9cb348f0-8102-4962-88c4-dac8180c904c"
|
||||
else:
|
||||
return False
|
||||
|
||||
# this is a temporary implementation until we have real sessions
|
||||
def _start_session(self):
|
||||
self.set_secure_cookie('atst', 'valid-user-session')
|
||||
self.set_secure_cookie("atst", "valid-user-session")
|
||||
|
@ -1,11 +1,12 @@
|
||||
from atst.handler import BaseHandler
|
||||
|
||||
|
||||
class Dev(BaseHandler):
|
||||
def initialize(self, action):
|
||||
self.action = action
|
||||
|
||||
def get(self):
|
||||
if self.action == 'login':
|
||||
if self.action == "login":
|
||||
self._login()
|
||||
|
||||
def _login(self):
|
||||
|
@ -1,9 +1,9 @@
|
||||
from atst.handler import BaseHandler
|
||||
|
||||
class Home(BaseHandler):
|
||||
|
||||
class Home(BaseHandler):
|
||||
def initialize(self, page):
|
||||
self.page = page
|
||||
|
||||
def get(self):
|
||||
self.render( '%s.html.to' % self.page, page = self.page )
|
||||
self.render("%s.html.to" % self.page, page=self.page)
|
||||
|
@ -3,7 +3,6 @@ from atst.handler import BaseHandler
|
||||
|
||||
|
||||
class Login(BaseHandler):
|
||||
|
||||
def initialize(self, authnid_client):
|
||||
self.authnid_client = authnid_client
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
import tornado
|
||||
from atst.handler import BaseHandler
|
||||
|
||||
class MainHandler(BaseHandler):
|
||||
|
||||
class MainHandler(BaseHandler):
|
||||
def initialize(self, page):
|
||||
self.page = page
|
||||
|
||||
@tornado.web.authenticated
|
||||
def get(self):
|
||||
self.render( '%s.html.to' % self.page, page = self.page )
|
||||
self.render("%s.html.to" % self.page, page=self.page)
|
||||
|
@ -2,43 +2,45 @@ import tornado
|
||||
from atst.handler import BaseHandler
|
||||
|
||||
mock_requests = [
|
||||
{
|
||||
'order_id' : 36552612,
|
||||
'date' : '5/17/2018',
|
||||
'is_new' : True,
|
||||
'full_name' : 'Friedrich Straat',
|
||||
'app_count' : 2,
|
||||
'status' : 'Pending'
|
||||
},
|
||||
{
|
||||
'order_id' : 87362910,
|
||||
'date' : '10/2/2017',
|
||||
'is_new' : False,
|
||||
'full_name' : 'Pietro Quirinis',
|
||||
'app_count' : 1,
|
||||
'status' : 'Complete'
|
||||
},
|
||||
{
|
||||
'order_id' : 29938172,
|
||||
'date' : '1/7/2017',
|
||||
'is_new' : False,
|
||||
'full_name' : 'Marina Borsetti',
|
||||
'app_count' : 1,
|
||||
'status' : 'Denied'
|
||||
},
|
||||
]
|
||||
{
|
||||
"order_id": 36552612,
|
||||
"date": "5/17/2018",
|
||||
"is_new": True,
|
||||
"full_name": "Friedrich Straat",
|
||||
"app_count": 2,
|
||||
"status": "Pending",
|
||||
},
|
||||
{
|
||||
"order_id": 87362910,
|
||||
"date": "10/2/2017",
|
||||
"is_new": False,
|
||||
"full_name": "Pietro Quirinis",
|
||||
"app_count": 1,
|
||||
"status": "Complete",
|
||||
},
|
||||
{
|
||||
"order_id": 29938172,
|
||||
"date": "1/7/2017",
|
||||
"is_new": False,
|
||||
"full_name": "Marina Borsetti",
|
||||
"app_count": 1,
|
||||
"status": "Denied",
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
def map_request(request):
|
||||
return {
|
||||
'order_id': request['id'],
|
||||
'is_new': False,
|
||||
'status': 'Pending',
|
||||
'app_count': 1,
|
||||
'is_new': False,
|
||||
'date': '',
|
||||
'full_name': 'Richard Howard'
|
||||
"order_id": request["id"],
|
||||
"is_new": False,
|
||||
"status": "Pending",
|
||||
"app_count": 1,
|
||||
"is_new": False,
|
||||
"date": "",
|
||||
"full_name": "Richard Howard",
|
||||
}
|
||||
|
||||
|
||||
class Request(BaseHandler):
|
||||
def initialize(self, page, requests_client):
|
||||
self.page = page
|
||||
@ -48,7 +50,8 @@ class Request(BaseHandler):
|
||||
@tornado.gen.coroutine
|
||||
def get(self):
|
||||
response = yield self.requests_client.get(
|
||||
'/users/{}/requests'.format(self.get_current_user()))
|
||||
requests = response.json['requests']
|
||||
"/users/{}/requests".format(self.get_current_user())
|
||||
)
|
||||
requests = response.json["requests"]
|
||||
mapped_requests = [map_request(request) for request in requests]
|
||||
self.render('requests.html.to', page=self.page, requests=mapped_requests)
|
||||
self.render("requests.html.to", page=self.page, requests=mapped_requests)
|
||||
|
@ -11,35 +11,21 @@ from tornado.httpclient import HTTPError
|
||||
|
||||
class RequestNew(BaseHandler):
|
||||
screens = [
|
||||
{ 'title' : 'Details of Use',
|
||||
'form' : RequestForm,
|
||||
'subitems' : [
|
||||
{'title' : 'Application Details',
|
||||
'id' : 'application-details'},
|
||||
{'title' : 'Computation',
|
||||
'id' : 'computation' },
|
||||
{'title' : 'Storage',
|
||||
'id' : 'storage' },
|
||||
{'title' : 'Usage',
|
||||
'id' : 'usage' },
|
||||
]},
|
||||
{
|
||||
'title' : 'Organizational Info',
|
||||
'form' : OrganizationInfoForm,
|
||||
},
|
||||
{
|
||||
'title' : 'Funding/Contracting',
|
||||
'form' : FundingForm,
|
||||
},
|
||||
{
|
||||
'title' : 'Readiness Survey',
|
||||
'form' : ReadinessForm,
|
||||
},
|
||||
{
|
||||
'title' : 'Review & Submit',
|
||||
'form' : ReviewForm,
|
||||
}
|
||||
]
|
||||
{
|
||||
"title": "Details of Use",
|
||||
"form": RequestForm,
|
||||
"subitems": [
|
||||
{"title": "Application Details", "id": "application-details"},
|
||||
{"title": "Computation", "id": "computation"},
|
||||
{"title": "Storage", "id": "storage"},
|
||||
{"title": "Usage", "id": "usage"},
|
||||
],
|
||||
},
|
||||
{"title": "Organizational Info", "form": OrganizationInfoForm},
|
||||
{"title": "Funding/Contracting", "form": FundingForm},
|
||||
{"title": "Readiness Survey", "form": ReadinessForm},
|
||||
{"title": "Review & Submit", "form": ReviewForm},
|
||||
]
|
||||
|
||||
def initialize(self, page, requests_client):
|
||||
self.page = page
|
||||
@ -50,12 +36,15 @@ class RequestNew(BaseHandler):
|
||||
def post(self, screen=1, request_id=None):
|
||||
self.check_xsrf_cookie()
|
||||
screen = int(screen)
|
||||
form = self.screens[ screen - 1 ]['form'](self.request.arguments)
|
||||
form = self.screens[screen - 1]["form"](self.request.arguments)
|
||||
if form.validate():
|
||||
response = yield self.create_or_update_request(form.data, request_id)
|
||||
if response.ok:
|
||||
where = self.application.default_router.reverse_url(
|
||||
'request_form_update', str(screen + 1), request_id or response.json['id'])
|
||||
"request_form_update",
|
||||
str(screen + 1),
|
||||
request_id or response.json["id"],
|
||||
)
|
||||
self.redirect(where)
|
||||
else:
|
||||
self.set_status(response.code)
|
||||
@ -69,39 +58,39 @@ class RequestNew(BaseHandler):
|
||||
if request_id:
|
||||
request = yield self.get_request(request_id)
|
||||
if request.ok:
|
||||
form_data = request.json['body'] if request else {}
|
||||
form = self.screens[ int(screen) - 1 ]['form'](data=form_data)
|
||||
form_data = request.json["body"] if request else {}
|
||||
form = self.screens[int(screen) - 1]["form"](data=form_data)
|
||||
|
||||
self.show_form(screen=screen, form=form, request_id=request_id)
|
||||
|
||||
def show_form(self, screen=1, form=None, request_id=None):
|
||||
if not form:
|
||||
form = self.screens[ int(screen) - 1 ]['form'](self.request.arguments)
|
||||
self.render('requests/screen-%d.html.to' % int(screen),
|
||||
f=form,
|
||||
page=self.page,
|
||||
screens=self.screens,
|
||||
current=int(screen),
|
||||
next_screen=int(screen) + 1,
|
||||
request_id=request_id)
|
||||
form = self.screens[int(screen) - 1]["form"](self.request.arguments)
|
||||
self.render(
|
||||
"requests/screen-%d.html.to" % int(screen),
|
||||
f=form,
|
||||
page=self.page,
|
||||
screens=self.screens,
|
||||
current=int(screen),
|
||||
next_screen=int(screen) + 1,
|
||||
request_id=request_id,
|
||||
)
|
||||
|
||||
@tornado.gen.coroutine
|
||||
def get_request(self, request_id):
|
||||
request = yield self.requests_client.get(
|
||||
'/users/{}/requests/{}'.format(self.get_current_user(), request_id),
|
||||
raise_error=False)
|
||||
"/users/{}/requests/{}".format(self.get_current_user(), request_id),
|
||||
raise_error=False,
|
||||
)
|
||||
return request
|
||||
|
||||
@tornado.gen.coroutine
|
||||
def create_or_update_request(self, form_data, request_id=None):
|
||||
request_data = {
|
||||
'creator_id': self.get_current_user(),
|
||||
'request': form_data
|
||||
}
|
||||
request_data = {"creator_id": self.get_current_user(), "request": form_data}
|
||||
if request_id:
|
||||
response = yield self.requests_client.patch(
|
||||
'/requests/{}'.format(request_id), json=request_data)
|
||||
"/requests/{}".format(request_id), json=request_data
|
||||
)
|
||||
else:
|
||||
response = yield self.requests_client.post(
|
||||
'/requests', json=request_data)
|
||||
response = yield self.requests_client.post("/requests", json=request_data)
|
||||
return response
|
||||
|
@ -3,17 +3,15 @@ import tornado
|
||||
|
||||
mock_workspaces = [
|
||||
{
|
||||
'name' : 'Unclassified IaaS and PaaS for Defense Digital Service (DDS)',
|
||||
'id': '5966187a-eff9-44c3-aa15-4de7a65ac7ff',
|
||||
'task_order' : {
|
||||
'number' : 123456,
|
||||
},
|
||||
'user_count' : 23,
|
||||
"name": "Unclassified IaaS and PaaS for Defense Digital Service (DDS)",
|
||||
"id": "5966187a-eff9-44c3-aa15-4de7a65ac7ff",
|
||||
"task_order": {"number": 123456},
|
||||
"user_count": 23,
|
||||
}
|
||||
]
|
||||
|
||||
class Workspace(BaseHandler):
|
||||
|
||||
class Workspace(BaseHandler):
|
||||
def initialize(self, page, authz_client):
|
||||
self.page = page
|
||||
self.authz_client = authz_client
|
||||
@ -21,4 +19,4 @@ class Workspace(BaseHandler):
|
||||
@tornado.gen.coroutine
|
||||
@tornado.web.authenticated
|
||||
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)
|
||||
|
@ -1,3 +1,3 @@
|
||||
from unipath import Path
|
||||
|
||||
home = Path( __file__ ).parent.parent
|
||||
home = Path(__file__).parent.parent
|
||||
|
18
pyproject.toml
Normal file
18
pyproject.toml
Normal file
@ -0,0 +1,18 @@
|
||||
[tool.black]
|
||||
line-length = 88
|
||||
py36 = true
|
||||
include = '\.pyi?$'
|
||||
exclude = '''
|
||||
/(
|
||||
\.git
|
||||
| \.hg
|
||||
| \.mypy_cache
|
||||
| \.tox
|
||||
| \.venv
|
||||
| _build
|
||||
| buck-out
|
||||
| build
|
||||
| dist
|
||||
| node_modules
|
||||
)/
|
||||
'''
|
@ -7,9 +7,9 @@ from tests.mocks import MockApiClient, MockRequestsClient
|
||||
@pytest.fixture
|
||||
def app():
|
||||
TEST_DEPS = {
|
||||
'authz_client': MockApiClient('authz'),
|
||||
'requests_client': MockRequestsClient('requests'),
|
||||
'authnid_client': MockApiClient('authnid'),
|
||||
"authz_client": MockApiClient("authz"),
|
||||
"requests_client": MockRequestsClient("requests"),
|
||||
"authnid_client": MockApiClient("authnid"),
|
||||
}
|
||||
|
||||
config = make_config()
|
||||
|
@ -4,9 +4,11 @@ from atst.forms.request import RequestForm
|
||||
|
||||
form = RequestForm()
|
||||
|
||||
|
||||
def test_form_has_expected_fields():
|
||||
label = form.application_name.label
|
||||
assert label.text == 'Application name'
|
||||
assert label.text == "Application name"
|
||||
|
||||
|
||||
def test_form_can_validate_total_ram():
|
||||
form.application_name.data = 5
|
||||
|
@ -1,13 +1,17 @@
|
||||
import re
|
||||
import pytest
|
||||
|
||||
ERROR_CLASS = 'usa-input-error-message'
|
||||
ERROR_CLASS = "usa-input-error-message"
|
||||
|
||||
|
||||
@pytest.mark.gen_test
|
||||
def test_submit_invalid_request_form(monkeypatch, http_client, base_url):
|
||||
monkeypatch.setattr('atst.handlers.request_new.RequestNew.get_current_user', lambda s: True)
|
||||
monkeypatch.setattr('atst.handlers.request_new.RequestNew.check_xsrf_cookie', lambda s: True)
|
||||
monkeypatch.setattr(
|
||||
"atst.handlers.request_new.RequestNew.get_current_user", lambda s: True
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"atst.handlers.request_new.RequestNew.check_xsrf_cookie", lambda s: True
|
||||
)
|
||||
# this just needs to send a known invalid form value
|
||||
response = yield http_client.fetch(
|
||||
base_url + "/requests/new",
|
||||
@ -15,15 +19,19 @@ def test_submit_invalid_request_form(monkeypatch, http_client, base_url):
|
||||
headers={"Content-Type": "application/x-www-form-urlencoded"},
|
||||
body="total_ram=5",
|
||||
)
|
||||
assert response.effective_url == base_url + '/requests/new'
|
||||
assert response.effective_url == base_url + "/requests/new"
|
||||
assert re.search(ERROR_CLASS, response.body.decode())
|
||||
|
||||
|
||||
@pytest.mark.gen_test
|
||||
def test_submit_valid_request_form(monkeypatch, http_client, base_url):
|
||||
monkeypatch.setattr('atst.handlers.request_new.RequestNew.get_current_user', lambda s: True)
|
||||
monkeypatch.setattr('atst.handlers.request_new.RequestNew.check_xsrf_cookie', lambda s: True)
|
||||
monkeypatch.setattr('atst.forms.request.RequestForm.validate', lambda s: True)
|
||||
monkeypatch.setattr(
|
||||
"atst.handlers.request_new.RequestNew.get_current_user", lambda s: True
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"atst.handlers.request_new.RequestNew.check_xsrf_cookie", lambda s: True
|
||||
)
|
||||
monkeypatch.setattr("atst.forms.request.RequestForm.validate", lambda s: True)
|
||||
|
||||
# this just needs to send a known invalid form value
|
||||
response = yield http_client.fetch(
|
||||
@ -32,4 +40,4 @@ def test_submit_valid_request_form(monkeypatch, http_client, base_url):
|
||||
headers={"Content-Type": "application/x-www-form-urlencoded"},
|
||||
body="meaning=42",
|
||||
)
|
||||
assert '/requests/new/2' in response.effective_url
|
||||
assert "/requests/new/2" in response.effective_url
|
||||
|
@ -10,33 +10,34 @@ class MockApiClient(ApiClient):
|
||||
|
||||
@tornado.gen.coroutine
|
||||
def get(self, path, **kwargs):
|
||||
return self._get_response('GET', path)
|
||||
return self._get_response("GET", path)
|
||||
|
||||
@tornado.gen.coroutine
|
||||
def put(self, path, **kwargs):
|
||||
return self._get_response('PUT', path)
|
||||
return self._get_response("PUT", path)
|
||||
|
||||
@tornado.gen.coroutine
|
||||
def patch(self, path, **kwargs):
|
||||
return self._get_response('PATCH', path)
|
||||
return self._get_response("PATCH", path)
|
||||
|
||||
@tornado.gen.coroutine
|
||||
def post(self, path, **kwargs):
|
||||
return self._get_response('POST', path)
|
||||
return self._get_response("POST", path)
|
||||
|
||||
@tornado.gen.coroutine
|
||||
def delete(self, path, **kwargs):
|
||||
return self._get_response('DELETE', path)
|
||||
return self._get_response("DELETE", path)
|
||||
|
||||
def _get_response(self, verb, path, code=200, json=None):
|
||||
response = HTTPResponse(
|
||||
request=HTTPRequest(path, verb),
|
||||
code=code,
|
||||
headers={'Content-Type': 'application/json'})
|
||||
headers={"Content-Type": "application/json"},
|
||||
)
|
||||
|
||||
setattr(response, 'ok', 200 <= code < 300)
|
||||
setattr(response, "ok", 200 <= code < 300)
|
||||
if json:
|
||||
setattr(response, 'json', json)
|
||||
setattr(response, "json", json)
|
||||
|
||||
return response
|
||||
|
||||
@ -45,18 +46,17 @@ class MockRequestsClient(MockApiClient):
|
||||
@tornado.gen.coroutine
|
||||
def get(self, path, **kwargs):
|
||||
json = {
|
||||
'id': '66b8ef71-86d3-48ef-abc2-51bfa1732b6b',
|
||||
'creator': '49903ae7-da4a-49bf-a6dc-9dff5d004238',
|
||||
'body': {}
|
||||
"id": "66b8ef71-86d3-48ef-abc2-51bfa1732b6b",
|
||||
"creator": "49903ae7-da4a-49bf-a6dc-9dff5d004238",
|
||||
"body": {},
|
||||
}
|
||||
return self._get_response('GET', path, 200, json=json)
|
||||
return self._get_response("GET", path, 200, json=json)
|
||||
|
||||
@tornado.gen.coroutine
|
||||
def post(self, path, **kwargs):
|
||||
json = {
|
||||
'id': '66b8ef71-86d3-48ef-abc2-51bfa1732b6b',
|
||||
'creator': '49903ae7-da4a-49bf-a6dc-9dff5d004238',
|
||||
'body': {}
|
||||
"id": "66b8ef71-86d3-48ef-abc2-51bfa1732b6b",
|
||||
"creator": "49903ae7-da4a-49bf-a6dc-9dff5d004238",
|
||||
"body": {},
|
||||
}
|
||||
return self._get_response('POST', path, 202, json=json)
|
||||
|
||||
return self._get_response("POST", path, 202, json=json)
|
||||
|
@ -6,5 +6,5 @@ from atst.api_client import ApiClient
|
||||
@pytest.mark.gen_test
|
||||
def test_api_client(http_client, base_url):
|
||||
client = ApiClient(base_url)
|
||||
response = yield client.get('')
|
||||
response = yield client.get("")
|
||||
assert response.code == 200
|
||||
|
@ -9,10 +9,10 @@ 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
|
||||
)
|
||||
location = response.headers['Location']
|
||||
location = response.headers["Location"]
|
||||
assert response.code == 302
|
||||
assert response.error
|
||||
assert re.match('/\??', location)
|
||||
assert re.match("/\??", location)
|
||||
|
||||
|
||||
@pytest.mark.gen_test
|
||||
@ -22,16 +22,15 @@ def test_login_with_valid_bearer_token(app, monkeypatch, http_client, base_url):
|
||||
return True
|
||||
|
||||
monkeypatch.setattr(
|
||||
"atst.handlers.login.Login._validate_login_token",
|
||||
_validate_login_token
|
||||
"atst.handlers.login.Login._validate_login_token", _validate_login_token
|
||||
)
|
||||
response = yield http_client.fetch(
|
||||
base_url + "/login?bearer-token=abc-123",
|
||||
follow_redirects=False,
|
||||
raise_error=False
|
||||
raise_error=False,
|
||||
)
|
||||
assert response.headers["Set-Cookie"].startswith("atst")
|
||||
assert response.headers['Location'] == '/home'
|
||||
assert response.headers["Location"] == "/home"
|
||||
assert response.code == 302
|
||||
|
||||
|
||||
|
@ -4,15 +4,15 @@ import pytest
|
||||
@pytest.mark.gen_test
|
||||
def test_routes(http_client, base_url):
|
||||
for path in (
|
||||
'/',
|
||||
'/home',
|
||||
'/workspaces',
|
||||
'/requests',
|
||||
'/requests/new',
|
||||
'/requests/new/1',
|
||||
'/users',
|
||||
'/reports',
|
||||
'/calculator'
|
||||
):
|
||||
"/",
|
||||
"/home",
|
||||
"/workspaces",
|
||||
"/requests",
|
||||
"/requests/new",
|
||||
"/requests/new/1",
|
||||
"/users",
|
||||
"/reports",
|
||||
"/calculator",
|
||||
):
|
||||
response = yield http_client.fetch(base_url + path)
|
||||
assert response.code == 200
|
||||
|
Loading…
x
Reference in New Issue
Block a user