Merge pull request #54 from jhuapl-lglenden/develop-updates

Updates from latest internal development branch.
This commit is contained in:
Laura Glendenning
2021-08-19 12:36:48 -04:00
committed by GitHub
25 changed files with 504 additions and 103 deletions

3
.env
View File

@@ -19,6 +19,9 @@ EXPOSED_SERVER_TYPE_PROD=http
EXPOSED_SERVER_NAME_PROD=annotation
EXPOSED_PORT_PROD=80
# This key must be set to a string of your choice to have a secure deployment.
BACKEND_SECRET_KEY=
AUTH_MODULE=eve
#MONGO_URI=
#VEGAS_CLIENT_SECRET=

View File

@@ -93,21 +93,25 @@ See [Docker Environments](#docker-environments).
### Getting started with the "eve" auth module
1. Set `AUTH_MODULE=eve` in the `.env` file.
2. On first setup, the database will have no users in it. To add users, either import the testing
2. Set the `BACKEND_SECRET_KEY` variable in the `.env` file. If this is not done, the default
testing value will be used which is NOT secure as it is checked in to this repo.
3. On first setup, the database will have no users in it. To add users, either import the testing
dataset, or use the scripts in `scripts/data` in the backend to manage users. (See the
*User management using "eve" auth module* sections in
[Development Environment](#development-environment) and
[Docker Environments](#docker-environments) below for exact commands.) Once an admin
user has been added, users can also be added/managed by logging in as that user and using the
Admin Dashboad.
3. Log in with the user credentials.
4. Log in with the user credentials.
### Getting started with the "vegas" auth module
1. Set `AUTH_MODULE=vegas` and `VEGAS_CLIENT_SECRET` in the `.env` file. `VEGAS_CLIENT_SECRET`
must be obtained by contacting one of the PINE developers and being authorized to use it.
2. VEGAS users are managed externally.
3. Log in with your JHED credentials.
2. Set the `BACKEND_SECRET_KEY` variable in the `.env` file. If this is not done, the default
testing value will be used which is NOT secure as it is checked in to this repo.
3. VEGAS users are managed externally.
4. Log in with your JHED credentials.
----------------------------------------------------------------------------------------------------
@@ -154,8 +158,11 @@ Once the dev stack is up and running, the following ports are accessible:
The backend API is documented using an [OpenAPI specification](https://swagger.io/specification/).
This specification covers the main REST API used by PINE. A copy of the
[Swagger UI](https://swagger.io/tools/swagger-ui/) is hosted at `http[s]://<backendURL>/api/ui` and
the specification itself is hosted at `http[s]://<backendURL>/api/openapi.yaml`.
[Swagger UI](https://swagger.io/tools/swagger-ui/) is hosted at `http[s]://<backendURL>/swagger` and
the specification itself is hosted at `http[s]://<backendURL>/openapi.yaml`. The easiest way to
use the Swagger UI is to log in to PINE via the normal web UI and then open the Swagger UI. This
allows the browser to set the user session cookie based on your logged in credentials and then that
cookie will be used in all calls to the Swagger UI/API.
This specification is found in the source code at `backend/pine/backend/api/openapi.yaml`.
*NOTE* however that this file is autogenerated by the `./update_openapi.sh` script. The "base"

View File

@@ -121,6 +121,7 @@ stages:
VEGAS_SERVER: https://slife.jh.edu
VEGAS_CLIENT_ID: 1976d9d4-be86-44ce-aa0f-c5a4b295c701
VEGAS_CLIENT_SECRET: $(vegas-client-secret-dev)
BACKEND_SECRET_KEY: $(backend-secret-key-dev)
eve:
MONGO_URI: $(mongo-uri-dev)
azure-secret:
@@ -149,6 +150,7 @@ stages:
VEGAS_SERVER: https://my.jh.edu
VEGAS_CLIENT_ID: b7590f07-cbd9-48b1-82f4-8aab02470831
VEGAS_CLIENT_SECRET: $(vegas-client-secret-prod)
BACKEND_SECRET_KEY: $(backend-secret-key-prod)
eve:
MONGO_URI: $(mongo-uri-prod)
azure-secret:

View File

@@ -24,6 +24,7 @@ matplotlib = "~=3.4.2"
scipy = "~=1.7.1"
tabulate = "~=0.8.9"
multiprocessing-logging = "~=0.3.1"
flask-httpauth = "~=4.4.0"
[dev-packages]

136
backend/Pipfile.lock generated
View File

@@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
"sha256": "45a7e976255520c4f430a83e1eb1fa4f6b4a0133332812a01a92702c594b8970"
"sha256": "3a30a022ccd4fbe028c8cf2c8f741b9c7f7fa72e039dba391da62a20e58c5273"
},
"pipfile-spec": 6,
"requires": {
@@ -137,6 +137,8 @@
"sha256:3d8427734c781ea5f1b41d6589c293089704d4759e34597dce91014ac125aad1",
"sha256:7ec5d3b029f5fa2b179325908b9cd93db28ab7b85bb6c1db56b10e0b54235177",
"sha256:8e56e16617872b0957d1c9742a3f94b43533447fd78321514abbe7db216aa250",
"sha256:b01fd6f2737816cb1e08ed4807ae194404790eac7ad030b34f2ce72b332f5586",
"sha256:bf40af59ca2465b24e54f671b2de2c59257ddc4f7e5706dbd6930e26823668d3",
"sha256:de4e5f7f68220d92b7637fc99847475b59154b7a1b3868fb7385337af54ac9ca",
"sha256:eb8cc2afe8b05acbd84a43905832ec78e7b3873fb124ca190f574dca7389a87d",
"sha256:ee77aa129f481be46f8d92a1a7db57269a2f23052d5f2433b4621bb457081cc9"
@@ -167,6 +169,14 @@
"index": "pypi",
"version": "==3.0.10"
},
"flask-httpauth": {
"hashes": [
"sha256:bcaaa7a35a3cba0b2eafd4f113b3016bf70eb78087456d96484c3c18928b813a",
"sha256:d9131122cdc5709dda63790f6e9b3142d8101447d424b0b95ffd4ee279f49539"
],
"index": "pypi",
"version": "==4.4.0"
},
"idna": {
"hashes": [
"sha256:14475042e284991034cb48e06f6851428fb14c4dc953acd9be9a5e95c7b6dd7a",
@@ -236,30 +246,50 @@
"sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b",
"sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567",
"sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff",
"sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724",
"sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74",
"sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646",
"sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35",
"sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6",
"sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6",
"sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad",
"sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26",
"sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38",
"sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac",
"sha256:3c112550557578c26af18a1ccc9e090bfe03832ae994343cfdacd287db6a6ae7",
"sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6",
"sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75",
"sha256:49e3ceeabbfb9d66c3aef5af3a60cc43b85c33df25ce03d0031a608b0a8b2e3f",
"sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135",
"sha256:53edb4da6925ad13c07b6d26c2a852bd81e364f95301c66e930ab2aef5b5ddd8",
"sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a",
"sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a",
"sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9",
"sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864",
"sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914",
"sha256:6557b31b5e2c9ddf0de32a691f2312a32f77cd7681d8af66c2692efdbef84c18",
"sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8",
"sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2",
"sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d",
"sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b",
"sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b",
"sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f",
"sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb",
"sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833",
"sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28",
"sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415",
"sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902",
"sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d",
"sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9",
"sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d",
"sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145",
"sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066",
"sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c",
"sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1",
"sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f",
"sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53",
"sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134",
"sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85",
"sha256:f5653a225f31e113b152e56f154ccbe59eeb1c7487b39b9d9f9cdb58e6c79dc5",
"sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94",
"sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509",
@@ -271,28 +301,30 @@
},
"matplotlib": {
"hashes": [
"sha256:0bea5ec5c28d49020e5d7923c2725b837e60bc8be99d3164af410eb4b4c827da",
"sha256:1c1779f7ab7d8bdb7d4c605e6ffaa0614b3e80f1e3c8ccf7b9269a22dbc5986b",
"sha256:21b31057bbc5e75b08e70a43cefc4c0b2c2f1b1a850f4a0f7af044eb4163086c",
"sha256:32fa638cc10886885d1ca3d409d4473d6a22f7ceecd11322150961a70fab66dd",
"sha256:3a5c18dbd2c7c366da26a4ad1462fe3e03a577b39e3b503bbcf482b9cdac093c",
"sha256:5826f56055b9b1c80fef82e326097e34dc4af8c7249226b7dd63095a686177d1",
"sha256:6382bc6e2d7e481bcd977eb131c31dee96e0fb4f9177d15ec6fb976d3b9ace1a",
"sha256:6475d0209024a77f869163ec3657c47fed35d9b6ed8bccba8aa0f0099fbbdaa8",
"sha256:6a6a44f27aabe720ec4fd485061e8a35784c2b9ffa6363ad546316dfc9cea04e",
"sha256:7a58f3d8fe8fac3be522c79d921c9b86e090a59637cb88e3bc51298d7a2c862a",
"sha256:7ad19f3fb6145b9eb41c08e7cbb9f8e10b91291396bee21e9ce761bb78df63ec",
"sha256:85f191bb03cb1a7b04b5c2cca4792bef94df06ef473bc49e2818105671766fee",
"sha256:956c8849b134b4a343598305a3ca1bdd3094f01f5efc8afccdebeffe6b315247",
"sha256:a9d8cb5329df13e0cdaa14b3b43f47b5e593ec637f13f14db75bb16e46178b05",
"sha256:b1d5a2cedf5de05567c441b3a8c2651fbde56df08b82640e7f06c8cd91e201f6",
"sha256:b26535b9de85326e6958cdef720ecd10bcf74a3f4371bf9a7e5b2e659c17e153",
"sha256:c541ee5a3287efe066bbe358320853cf4916bc14c00c38f8f3d8d75275a405a9",
"sha256:d8d994cefdff9aaba45166eb3de4f5211adb4accac85cbf97137e98f26ea0219",
"sha256:df815378a754a7edd4559f8c51fc7064f779a74013644a7f5ac7a0c31f875866"
"sha256:01c9de93a2ca0d128c9064f23709362e7fefb34910c7c9e0b8ab0de8258d5eda",
"sha256:41b6e307458988891fcdea2d8ecf84a8c92d53f84190aa32da65f9505546e684",
"sha256:48e1e0859b54d5f2e29bb78ca179fd59b971c6ceb29977fb52735bfd280eb0f5",
"sha256:54a026055d5f8614f184e588f6e29064019a0aa8448450214c0b60926d62d919",
"sha256:556965514b259204637c360d213de28d43a1f4aed1eca15596ce83f768c5a56f",
"sha256:5c988bb43414c7c2b0a31bd5187b4d27fd625c080371b463a6d422047df78913",
"sha256:6a724e3a48a54b8b6e7c4ae38cd3d07084508fa47c410c8757e9db9791421838",
"sha256:6be8df61b1626e1a142c57e065405e869e9429b4a6dab4a324757d0dc4d42235",
"sha256:844a7b0233e4ff7fba57e90b8799edaa40b9e31e300b8d5efc350937fa8b1bea",
"sha256:85f0c9cf724715e75243a7b3087cf4a3de056b55e05d4d76cc58d610d62894f3",
"sha256:a78a3b51f29448c7f4d4575e561f6b0dbb8d01c13c2046ab6c5220eb25c06506",
"sha256:b884715a59fec9ad3b6048ecf3860f3b2ce965e676ef52593d6fa29abcf7d330",
"sha256:b8b53f336a4688cfce615887505d7e41fd79b3594bf21dd300531a4f5b4f746a",
"sha256:c70b6311dda3e27672f1bf48851a0de816d1ca6aaf3d49365fbdd8e959b33d2b",
"sha256:ebfb01a65c3f5d53a8c2a8133fec2b5221281c053d944ae81ff5822a68266617",
"sha256:eeb1859efe7754b1460e1d4991bbd4a60a56f366bc422ef3a9c5ae05f0bc70b5",
"sha256:f15edcb0629a0801738925fe27070480f446fcaa15de65946ff946ad99a59a40",
"sha256:f1c5efc278d996af8a251b2ce0b07bbeccb821f25c8c9846bdcb00ffc7f158aa",
"sha256:f72657f1596199dc1e4e7a10f52a4784ead8a711f4e5b59bea95bdb97cf0e4fd",
"sha256:fc4f526dfdb31c9bd6b8ca06bf9fab663ca12f3ec9cdf4496fb44bc680140318",
"sha256:fcd6f1954943c0c192bfbebbac263f839d7055409f1173f80d8b11a224d236da"
],
"index": "pypi",
"version": "==3.4.2"
"version": "==3.4.3"
},
"multiprocessing-logging": {
"hashes": [
@@ -311,37 +343,39 @@
},
"numpy": {
"hashes": [
"sha256:01721eefe70544d548425a07c80be8377096a54118070b8a62476866d5208e33",
"sha256:0318c465786c1f63ac05d7c4dbcecd4d2d7e13f0959b01b534ea1e92202235c5",
"sha256:05a0f648eb28bae4bcb204e6fd14603de2908de982e761a2fc78efe0f19e96e1",
"sha256:1412aa0aec3e00bc23fbb8664d76552b4efde98fb71f60737c83efbac24112f1",
"sha256:25b40b98ebdd272bc3020935427a4530b7d60dfbe1ab9381a39147834e985eac",
"sha256:2d4d1de6e6fb3d28781c73fbde702ac97f03d79e4ffd6598b880b2d95d62ead4",
"sha256:38e8648f9449a549a7dfe8d8755a5979b45b3538520d1e735637ef28e8c2dc50",
"sha256:4a3d5fb89bfe21be2ef47c0614b9c9c707b7362386c9a3ff1feae63e0267ccb6",
"sha256:635e6bd31c9fb3d475c8f44a089569070d10a9ef18ed13738b03049280281267",
"sha256:73101b2a1fef16602696d133db402a7e7586654682244344b8329cdcbbb82172",
"sha256:791492091744b0fe390a6ce85cc1bf5149968ac7d5f0477288f78c89b385d9af",
"sha256:7a708a79c9a9d26904d1cca8d383bf869edf6f8e7650d85dbc77b041e8c5a0f8",
"sha256:88c0b89ad1cc24a5efbb99ff9ab5db0f9a86e9cc50240177a571fbe9c2860ac2",
"sha256:8a326af80e86d0e9ce92bcc1e65c8ff88297de4fa14ee936cb2293d414c9ec63",
"sha256:8a92c5aea763d14ba9d6475803fc7904bda7decc2a0a68153f587ad82941fec1",
"sha256:91c6f5fc58df1e0a3cc0c3a717bb3308ff850abdaa6d2d802573ee2b11f674a8",
"sha256:95b995d0c413f5d0428b3f880e8fe1660ff9396dcd1f9eedbc311f37b5652e16",
"sha256:9749a40a5b22333467f02fe11edc98f022133ee1bfa8ab99bda5e5437b831214",
"sha256:978010b68e17150db8765355d1ccdd450f9fc916824e8c4e35ee620590e234cd",
"sha256:9a513bd9c1551894ee3d31369f9b07460ef223694098cf27d399513415855b68",
"sha256:a75b4498b1e93d8b700282dc8e655b8bd559c0904b3910b144646dbbbc03e062",
"sha256:c6a2324085dd52f96498419ba95b5777e40b6bcbc20088fddb9e8cbb58885e8e",
"sha256:d7a4aeac3b94af92a9373d6e77b37691b86411f9745190d2c351f410ab3a791f",
"sha256:d9e7912a56108aba9b31df688a4c4f5cb0d9d3787386b87d504762b6754fbb1b",
"sha256:dff4af63638afcc57a3dfb9e4b26d434a7a602d225b42d746ea7fe2edf1342fd",
"sha256:e46ceaff65609b5399163de5893d8f2a82d3c77d5e56d976c8b5fb01faa6b671",
"sha256:f01f28075a92eede918b965e86e8f0ba7b7797a95aa8d35e1cc8821f5fc3ad6a",
"sha256:fd7d7409fa643a91d0a05c7554dd68aa9c9bb16e186f6ccfe40d6e003156e33a"
"sha256:09858463db6dd9f78b2a1a05c93f3b33d4f65975771e90d2cf7aadb7c2f66edf",
"sha256:209666ce9d4a817e8a4597cd475b71b4878a85fa4b8db41d79fdb4fdee01dde2",
"sha256:298156f4d3d46815eaf0fcf0a03f9625fc7631692bd1ad851517ab93c3168fc6",
"sha256:30fc68307c0155d2a75ad19844224be0f2c6f06572d958db4e2053f816b859ad",
"sha256:423216d8afc5923b15df86037c6053bf030d15cc9e3224206ef868c2d63dd6dc",
"sha256:426a00b68b0d21f2deb2ace3c6d677e611ad5a612d2c76494e24a562a930c254",
"sha256:466e682264b14982012887e90346d33435c984b7fead7b85e634903795c8fdb0",
"sha256:51a7b9db0a2941434cd930dacaafe0fc9da8f3d6157f9d12f761bbde93f46218",
"sha256:52a664323273c08f3b473548bf87c8145b7513afd63e4ebba8496ecd3853df13",
"sha256:550564024dc5ceee9421a86fc0fb378aa9d222d4d0f858f6669eff7410c89bef",
"sha256:5de64950137f3a50b76ce93556db392e8f1f954c2d8207f78a92d1f79aa9f737",
"sha256:640c1ccfd56724f2955c237b6ccce2e5b8607c3bc1cc51d3933b8c48d1da3723",
"sha256:7fdc7689daf3b845934d67cb221ba8d250fdca20ac0334fea32f7091b93f00d3",
"sha256:805459ad8baaf815883d0d6f86e45b3b0b67d823a8f3fa39b1ed9c45eaf5edf1",
"sha256:92a0ab128b07799dd5b9077a9af075a63467d03ebac6f8a93e6440abfea4120d",
"sha256:9f2dc79c093f6c5113718d3d90c283f11463d77daa4e83aeeac088ec6a0bda52",
"sha256:a5109345f5ce7ddb3840f5970de71c34a0ff7fceb133c9441283bb8250f532a3",
"sha256:a55e4d81c4260386f71d22294795c87609164e22b28ba0d435850fbdf82fc0c5",
"sha256:a9da45b748caad72ea4a4ed57e9cd382089f33c5ec330a804eb420a496fa760f",
"sha256:b160b9a99ecc6559d9e6d461b95c8eec21461b332f80267ad2c10394b9503496",
"sha256:b342064e647d099ca765f19672696ad50c953cac95b566af1492fd142283580f",
"sha256:b5e8590b9245803c849e09bae070a8e1ff444f45e3f0bed558dd722119eea724",
"sha256:bf75d5825ef47aa51d669b03ce635ecb84d69311e05eccea083f31c7570c9931",
"sha256:c01b59b33c7c3ba90744f2c695be571a3bd40ab2ba7f3d169ffa6db3cfba614f",
"sha256:d96a6a7d74af56feb11e9a443150216578ea07b7450f7c05df40eec90af7f4a7",
"sha256:dd0e3651d210068d13e18503d75aaa45656eef51ef0b261f891788589db2cc38",
"sha256:e167b9805de54367dcb2043519382be541117503ce99e3291cc9b41ca0a83557",
"sha256:e42029e184008a5fd3d819323345e25e2337b0ac7f5c135b7623308530209d57",
"sha256:f545c082eeb09ae678dd451a1b1dbf17babd8a0d7adea02897a76e639afca310",
"sha256:fde50062d67d805bc96f1a9ecc0d37bfc2a8f02b937d2c50824d186aa91f2419"
],
"markers": "python_version >= '3.7'",
"version": "==1.21.1"
"markers": "python_version < '3.11' and python_version >= '3.7'",
"version": "==1.21.2"
},
"overrides": {
"hashes": [

View File

@@ -4,6 +4,7 @@ openapi: "3.0.2"
security:
- cookieAuth: []
- eveBasicAuth: []
tags:
- name: admin

View File

@@ -4,6 +4,8 @@ openapi: "3.0.2"
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
tags:
- name: annotations

View File

@@ -21,9 +21,8 @@ info:
url: https://github.com/JHUAPL/PINE/blob/master/LICENSE
servers:
- url: http://localhost:5000
- url: https://localhost:8888/api
- url: https://dev-nlpannotator.pm.jh.edu/api
- url: /api
description: This server.
paths: {}
@@ -31,4 +30,8 @@ components:
securitySchemes:
cookieAuth:
$ref: "./components.yaml#/securitySchemes/cookieAuth"
eveBasicAuth:
$ref: "./components.yaml#/securitySchemes/eveBasicAuth"
vegasBearerAuth:
$ref: "./components.yaml#/securitySchemes/vegasBearerAuth"
schemas: {}

View File

@@ -4,13 +4,46 @@ securitySchemes:
cookieAuth:
description: |
This is the basic authentication mechanism for the PINE backend, used by all auth modules.
This an example command to provision and print the session key using eve:
`curl -X POST -H "Content-Type:application/json" -d '{"username":"ada@pine.jhuapl.edu","password":"ada@pine.jhuapl.edu"}' http://localhost:5000/auth/login --cookie-jar - --output /dev/null --silent | grep -o -P "session\s.+" | sed -e 's/session\s/session=/' -`
The easiest way to use this auth using the Swagger UI is to log in using the normal PINE web
UI, which will set the cookie in the browser. Then the Swagger UI will use the same cookie
for all its calls.
type: apiKey
in: cookie
name: session
eveBasicAuth:
description: |
If the eve auth module is used, you can use basic authentication via a header and the
cookie/session will be created using that login information. This is basically the same as
logging in before each call. It is less efficient than using the cookie auth but also does
not rely on cookies or session state which can be difficult to use outside a browser.
type: http
scheme: basic
vegasBearerAuth:
description: |
If the vegas auth module is used, you can get a VEGAS access token outside of PINE and set it
as an auth bearer header and the cookie/session will be created using that login information.
This is basically the same as authenticating your token before each call. It is less
efficient than using the cookie auth but also does not rely on cookies or session state which
can be difficult to use outside a browser.
An example call to get a VEGAS token might look like:
`curl -H "Authentication: hmac <encoded HMAC creds>" -H "Date: 1629328547884"
-d "grant_type=client_credentials" -X POST https://slife.jh.edu/VEGAS/api/oauth2/accesstoken`.
This will return a JSON object of the form `{"access_token": "...", "refresh_token": "...",
"token_type":"bearer","issued_at":1629328554626,"expires_in":1800}`. Grab the `access_token`
string and use it as an auth bearer header.
type: http
scheme: bearer
bearerFormat: JWT
parameters:
userIdParam:

View File

@@ -25,9 +25,8 @@ info:
name: AGPL-3.0
url: 'https://github.com/JHUAPL/PINE/blob/master/LICENSE'
servers:
- url: 'http://localhost:5000'
- url: 'https://localhost:8888/api'
- url: 'https://dev-nlpannotator.pm.jh.edu/api'
- url: /api
description: This server.
paths:
/admin/users:
get:
@@ -93,6 +92,7 @@ paths:
example: Error message from the server.
security:
- cookieAuth: []
- eveBasicAuth: []
post:
summary: Create New User
description: >
@@ -215,6 +215,7 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
'/admin/users/{user_id}':
get:
summary: Get User Details
@@ -258,6 +259,7 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
put:
summary: Update user details.
description: >
@@ -350,6 +352,7 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
delete:
summary: Delete User
description: >
@@ -382,6 +385,7 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
'/admin/users/{user_id}/password':
put:
summary: Update User Password
@@ -438,6 +442,7 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
/admin/system/export:
get:
summary: Export Database
@@ -469,6 +474,7 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
/admin/system/import:
put:
summary: Import Database (Update)
@@ -537,6 +543,7 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
post:
summary: Import Database (Replace)
description: >
@@ -598,6 +605,7 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
'/annotations/mine/by_document_id/{doc_id}':
get:
summary: Get My Document Annotations
@@ -698,6 +706,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
post:
summary: Save My Annotations
description: >
@@ -794,6 +804,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
'/annotations/mine/by_collection_id/{collection_id}':
post:
summary: Set Collection Annotations
@@ -909,6 +921,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
'/annotations/others/by_document_id/{doc_id}':
get:
summary: Get Others' Document Annotations
@@ -949,6 +963,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
'/annotations/by_document_id/{doc_id}':
get:
summary: Get All Document Annotations
@@ -989,6 +1005,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
/auth/module:
get:
summary: Get Auth Module
@@ -1072,7 +1090,18 @@ paths:
Example: `curl -X GET http://localhost:5000/auth/logged_in_user --cookie
session.cookie`
Note that this operation does not REQUIRE the user to be logged in, but
it is marked as
requiring security so that the Swagger UI will send in whatever you have
configured.
operationId: auth_logged_in_user
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
tags:
- auth
responses:
@@ -1114,6 +1143,8 @@ paths:
operationId: auth_user_details
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
tags:
- auth
responses:
@@ -1148,6 +1179,7 @@ paths:
operationId: auth_eve_update_user_details
security:
- cookieAuth: []
- eveBasicAuth: []
tags:
- auth_eve
requestBody:
@@ -1239,6 +1271,8 @@ paths:
- auth
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
responses:
'200':
description: Successfully logged out.
@@ -1325,6 +1359,7 @@ paths:
- auth_eve
security:
- cookieAuth: []
- eveBasicAuth: []
responses:
'200':
description: Returns all users.
@@ -1353,6 +1388,7 @@ paths:
- auth_eve
security:
- cookieAuth: []
- eveBasicAuth: []
requestBody:
content:
application/json:
@@ -1442,10 +1478,11 @@ paths:
description: An auth token obtained by Vegas out-of-band from PINE.
type: object
properties: &ref_48
auth_token:
access_token:
type: string
token_type:
type: string
example: bearer
additionalProperties: &ref_49 {}
responses:
'200':
@@ -1523,6 +1560,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
'/collections/unarchived/{page}':
get:
summary: Get Paginated Unarchived Collections
@@ -1565,6 +1604,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
/collections/archived:
get:
summary: Get Archived Collections
@@ -1595,6 +1636,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
'/collections/archived/{page}':
get:
summary: Get Paginated Archived Collections
@@ -1637,6 +1680,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
'/collections/archive/{collection_id}':
put:
summary: Archive Collection
@@ -1677,6 +1722,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
'/collections/unarchive/{collection_id}':
put:
summary: Unarchive Collection
@@ -1717,6 +1764,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
'/collections/by_id/{collection_id}':
get:
summary: Get Collection
@@ -1757,6 +1806,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
'/collections/by_id/{collection_id}/download':
get:
summary: Download Collection Data
@@ -1797,6 +1848,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
'/collections/add_annotator/{collection_id}':
post:
summary: Add Collection Annotator
@@ -1883,6 +1936,8 @@ paths:
example: Error message from the server.
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
'/collections/add_viewer/{collection_id}':
post:
summary: Add Collection Viewer
@@ -1970,6 +2025,8 @@ paths:
example: Error message from the server.
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
'/collections/add_label/{collection_id}':
post:
summary: Add Collection Label
@@ -2055,6 +2112,8 @@ paths:
example: Error message from the server.
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
/collections:
post:
summary: Create Collection
@@ -2276,6 +2335,8 @@ paths:
example: Error message from the server.
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
'/collections/static_images/{collection_id}':
get:
summary: Get Collection Static Images
@@ -2319,6 +2380,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
'/collections/images/{collection_id}':
get:
summary: Get Collection Images
@@ -2360,6 +2423,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
'/collections/image_exists/{collection_id}/{path}':
get:
summary: Check Collection Image
@@ -2408,6 +2473,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
'/collections/image/{collection_id}/{path}':
get:
summary: Get Collection Image
@@ -2457,6 +2524,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
post:
summary: Upload Collection Image
description: >
@@ -2533,6 +2602,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
'/collections/user_permissions/{collection_id}':
get:
summary: Get Collection User Permissions
@@ -2591,6 +2662,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
'/documents/by_id/{doc_id}':
get:
summary: Get Document
@@ -2649,6 +2722,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
delete:
summary: Delete Document
description: >
@@ -2732,6 +2807,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
/documents/by_ids:
delete:
summary: Delete Documents
@@ -2787,6 +2864,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
'/documents/count_by_collection_id/{collection_id}':
get:
summary: Get Collection Document Count
@@ -2828,6 +2907,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
'/documents/by_collection_id_all/{collection_id}':
get:
summary: Get All Collection Documents
@@ -2873,6 +2954,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
'/documents/by_collection_id_paginated/{collection_id}':
get:
summary: Get Paginated Collection Documents
@@ -2933,6 +3016,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
'/documents/user_permissions/{doc_id}':
get:
summary: Get User Document Permissions
@@ -2973,6 +3058,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
'/documents/metadata/{doc_id}':
put:
summary: Update Document Metadata
@@ -3031,6 +3118,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
/documents:
post:
summary: Create Document
@@ -3110,6 +3199,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
'/iaa_reports/by_collection_id/{collection_id}':
get:
summary: Get IAA Report for Collection
@@ -3242,6 +3333,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
post:
summary: Create IAA Report for Collection
description: >
@@ -3286,6 +3379,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
/pipelines:
get:
summary: Get Pipelines
@@ -3386,6 +3481,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
'/pipelines/by_id/{pipeline_id}':
get:
summary: Get Pipeline
@@ -3431,6 +3528,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
'/pipelines/classifiers/by_collection_id/{collection_id}':
get:
summary: Get Collection Classifier
@@ -3499,6 +3598,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
/pipelines/metrics:
get:
summary: Get Collection Metrics
@@ -3572,6 +3673,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
'/pipelines/metrics/by_classifier_id/{classifier_id}':
get:
summary: Get Classifier Metrics
@@ -3626,6 +3729,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
'/pipelines/next_document/by_classifier_id/{classifier_id}':
get:
summary: Get Next Document to Annotate
@@ -3669,6 +3774,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
'/pipelines/next_document/by_classifier_id/{classifier_id}/{doc_id}':
post:
summary: Advance Next Document
@@ -3723,6 +3830,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
'/pipelines/status/{pipeline_id}':
get:
summary: Get Pipeline Status
@@ -3833,6 +3942,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
'/pipelines/classifiers/status/{classifier_id}':
get:
summary: Get Classifier Status
@@ -3872,6 +3983,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
'/pipelines/running_jobs/{classifier_id}':
get:
summary: Get Classifier Running Jobs
@@ -3913,6 +4026,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
'/pipelines/job_results/{classifier_id}/{job_id}':
get:
summary: Get Classifier Job Results
@@ -3981,6 +4096,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
'/pipelines/train/{classifier_id}':
post:
summary: Train Classifier
@@ -4072,6 +4189,8 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
'/pipelines/predict/{classifier_id}':
post:
summary: Predict Using Classifier
@@ -4230,10 +4349,16 @@ paths:
content: *ref_1
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
components:
securitySchemes:
cookieAuth:
description: >
This is the basic authentication mechanism for the PINE backend, used by
all auth modules.
This an example command to provision and print the session key using
eve:
@@ -4242,9 +4367,68 @@ components:
'{"username":"ada@pine.jhuapl.edu","password":"ada@pine.jhuapl.edu"}'
http://localhost:5000/auth/login --cookie-jar - --output /dev/null
--silent | grep -o -P "session\s.+" | sed -e 's/session\s/session=/' -`
The easiest way to use this auth using the Swagger UI is to log in using
the normal PINE web
UI, which will set the cookie in the browser. Then the Swagger UI will
use the same cookie
for all its calls.
type: apiKey
in: cookie
name: session
eveBasicAuth:
description: >
If the eve auth module is used, you can use basic authentication via a
header and the
cookie/session will be created using that login information. This is
basically the same as
logging in before each call. It is less efficient than using the cookie
auth but also does
not rely on cookies or session state which can be difficult to use
outside a browser.
type: http
scheme: basic
vegasBearerAuth:
description: >
If the vegas auth module is used, you can get a VEGAS access token
outside of PINE and set it
as an auth bearer header and the cookie/session will be created using
that login information.
This is basically the same as authenticating your token before each
call. It is less
efficient than using the cookie auth but also does not rely on cookies
or session state which
can be difficult to use outside a browser.
An example call to get a VEGAS token might look like:
`curl -H "Authentication: hmac <encoded HMAC creds>" -H "Date:
1629328547884"
-d "grant_type=client_credentials" -X POST
https://slife.jh.edu/VEGAS/api/oauth2/accesstoken`.
This will return a JSON object of the form `{"access_token": "...",
"refresh_token": "...",
"token_type":"bearer","issued_at":1629328554626,"expires_in":1800}`.
Grab the `access_token`
string and use it as an auth bearer header.
type: http
scheme: bearer
bearerFormat: JWT
schemas:
UserRoles:
description: The role (for permissions) of the user.

View File

@@ -7,7 +7,7 @@ import sys
from . import log
log.setup_logging()
from flask import Flask, abort, jsonify
from flask import Flask, abort, jsonify, redirect, render_template, request, send_file
from flask import __version__ as flask_version
from werkzeug import exceptions
@@ -38,7 +38,7 @@ def handle_uncaught_exception(e):
def create_app(test_config = None):
# create and configure the app
app = Flask(__name__, instance_relative_config=True)
app = Flask(__name__, instance_relative_config=True, template_folder="api/swagger-ui")
app.config.from_object(config)
app.register_error_handler(exceptions.HTTPException, handle_error)
@@ -78,6 +78,28 @@ def create_app(test_config = None):
LOGGER.info(about)
return jsonify(about)
@app.route("/openapi.yaml", methods=["GET"])
def openapi_spec():
# Specify statically where the openapi file is, relative path
return send_file("api/openapi.yaml", mimetype='text/yaml', as_attachment=False)
@app.route("/swagger", methods=["GET"], strict_slashes=False)
def swagger_ui_index():
# forward to /api/ui/index.html, taking proxy prefix into account if set
url = request.headers.get("X-Forwarded-Prefix", "") + "/swagger/index.html"
LOGGER.info("Redirecting to {}".format(url))
return redirect(url)
@app.route("/swagger/<file>", methods=["GET"])
def swagger_ui(file: str):
if file == "index.html":
# get url for /api/openapi.yaml, taking proxy prefix into account if set
url = request.headers.get("X-Forwarded-Prefix", "") + "/openapi.yaml"
LOGGER.info("Grabbing spec from {}".format(url))
return render_template("index.html", spec_url=url)
else:
return send_file("api/swagger-ui/{}".format(file))
from . import cors
cors.init_app(app)
@@ -105,7 +127,13 @@ def create_app(test_config = None):
from .pineiaa import bp as iaabp
iaabp.init_app(app)
from .api import bp as apibp
apibp.init_app(app)
if app.env == "development":
# if running dev stack, map /api/<rule> to <rule>
for rule in app.url_map.iter_rules():
if rule.rule.startswith("/api"):
continue
rule_copy = rule.empty()
rule_copy.rule = "/api" + rule_copy.rule
app.url_map.add(rule_copy)
return app

View File

@@ -61,7 +61,9 @@ def flask_get_logged_in_user() -> Response:
@bp.route("/logged_in_user_details", methods = ["GET"])
@login_required
def flask_get_logged_in_user_details() -> Response:
return jsonify(module.get_logged_in_user_details().to_dict())
details = module.get_logged_in_user_details()
if details != None: details = details.to_dict()
return jsonify(details)
@bp.route("/login_form", methods = ["GET"])
def flask_get_login_form() -> Response:

View File

@@ -1,6 +1,9 @@
# (C) 2019 The Johns Hopkins University Applied Physics Laboratory LLC.
import logging
from flask import jsonify, request, Response, session
from flask_httpauth import HTTPBasicAuth
from overrides import overrides
from werkzeug import exceptions
@@ -8,6 +11,10 @@ from . import bp, login_required, password
from .. import log, models
from ..data import users
logger = logging.getLogger(__name__)
auth = HTTPBasicAuth()
class EveUser(models.AuthUser):
def __init__(self, data):
@@ -37,6 +44,26 @@ class EveUser(models.AuthUser):
def get_details(self) -> models.UserDetails:
return models.UserDetails(self.data["firstname"], self.data["lastname"], self.data["description"])
@auth.verify_password
def eve_login(username: str, passwd: str):
if not username or not passwd:
return None
try:
user = users.get_user(username)
except exceptions.HTTPException:
try:
user = users.get_user_by_email(username)
if not user:
raise exceptions.Unauthorized(description = "User \"{}\" doesn't exist.".format(username))
except exceptions.HTTPException:
raise exceptions.Unauthorized(description = "User \"{}\" doesn't exist.".format(username))
if not "passwdhash" in user or not user["passwdhash"]:
raise exceptions.Unauthorized(description = "Your first-time password needs to be set by an administrator.")
if password.check_password(passwd, user["passwdhash"]):
return user
else:
return None
class EveModule(bp.AuthModule):
def __init__(self, app, bp):
@@ -85,30 +112,37 @@ class EveModule(bp.AuthModule):
models.LoginFormField("password", "Password", models.LoginFormFieldType.PASSWORD)
], "Login")
def login(self) -> Response:
if not request.json or "username" not in request.json or "password" not in request.json:
raise exceptions.BadRequest(description = "Missing username and/or password.")
username = request.json["username"]
passwd = request.json["password"]
try:
user = users.get_user(username)
except exceptions.HTTPException:
try:
user = users.get_user_by_email(username)
if not user:
raise exceptions.Unauthorized(description = "User \"{}\" doesn't exist.".format(username))
except exceptions.HTTPException:
raise exceptions.Unauthorized(description = "User \"{}\" doesn't exist.".format(username))
if not "passwdhash" in user or not user["passwdhash"]:
raise exceptions.Unauthorized(description = "Your first-time password needs to be set by an administrator.")
valid = password.check_password(passwd, user["passwdhash"])
if not valid:
raise exceptions.Unauthorized(description = "Incorrect password for user \"{}\".".format(username))
def _set_user(self, user):
session["auth"] = {
"user": EveUser(user).to_dict(),
"user_data": user
}
log.access_flask_login()
@auth.login_required(optional=True)
@overrides
def get_logged_in_user(self):
# if user set in cookie, use that
user = super(EveModule, self).get_logged_in_user()
if user != None:
return user
# otherwise check basic auth
user = auth.current_user()
if user != None:
logger.info("User has logged in via basic auth; setting session.")
self._set_user(user)
return super(EveModule, self).get_logged_in_user()
def login(self) -> Response:
if not request.json or "username" not in request.json or "password" not in request.json:
raise exceptions.BadRequest(description = "Missing username and/or password.")
username = request.json["username"]
passwd = request.json["password"]
user = eve_login(username, passwd)
if user == None:
raise exceptions.Unauthorized(description = "Incorrect password for user \"{}\".".format(username))
self._set_user(user)
return jsonify(self.get_logged_in_user())
def get_all_users(self):

View File

@@ -9,6 +9,7 @@ import typing
from authlib.integrations.flask_client import OAuth
from flask import current_app, jsonify, redirect, request, Response, session
from flask_httpauth import HTTPTokenAuth
import jwt
from overrides import overrides
from werkzeug import exceptions
@@ -17,6 +18,7 @@ from . import bp
from .. import log, models
LOGGER = logging.getLogger(__name__)
auth = HTTPTokenAuth(scheme="Bearer")
class OAuthUser(models.AuthUser):
@@ -61,6 +63,7 @@ class OAuthModule(bp.AuthModule):
bp.route("/login", methods=["POST"])(self.login)
bp.route("/authorize", methods=["GET"])(self.authorize_get)
bp.route("/authorize", methods=["POST"])(self.authorize_post)
auth.verify_token_callback = lambda t: self.verify_token(t)
@abc.abstractmethod
def register_oauth(self, oauth, app):
@@ -82,8 +85,23 @@ class OAuthModule(bp.AuthModule):
def get_login_form(self) -> models.LoginForm:
return models.LoginForm([], self.get_login_form_button_text())
def make_user(self, decoded: dict) -> OAuthUser:
return OAuthUser(decoded, id_field="sub")
@auth.login_required(optional=True)
@overrides
def get_logged_in_user(self):
# if user set in cookie, use that
user = super(OAuthModule, self).get_logged_in_user()
if user != None:
return user
# otherwise check bearer auth
ret = auth.current_user()
if ret != None:
(token, user) = ret
if user != None:
LOGGER.info("User has logged in via bearer auth; setting session.")
self._update_session(user, token)
return super(OAuthModule, self).get_logged_in_user()
def login(self) -> Response:
if "return_to" in request.args:
@@ -92,14 +110,13 @@ class OAuthModule(bp.AuthModule):
redirect = self.app.authorize_redirect(response_type = "token")
return jsonify(redirect.headers["Location"])
def _authorize(self, authorization_response):
try:
token = self.app.fetch_access_token(authorization_response = authorization_response)
except Exception as e:
traceback.print_exc()
sys.stderr.flush()
raise exceptions.SecurityError(description = str(e))
access_token = token["access_token"]
def make_user(self, decoded: dict) -> OAuthUser:
return OAuthUser(decoded, id_field="sub")
def verify_token(self, access_token: str) -> OAuthUser:
if not access_token:
return None
LOGGER.info("Verifying token: \"%s\"", access_token)
try:
decoded = jwt.decode(access_token, options={"verify_signature": False})
decoded = jwt.decode(access_token, self.secret, audience=decoded["aud"], algorithms=self.algorithms)
@@ -108,12 +125,25 @@ class OAuthModule(bp.AuthModule):
sys.stderr.flush()
raise exceptions.SecurityError(description = str(e))
LOGGER.info("Decoded and validated token: {}".format(decoded))
return ({"access_token": access_token}, self.make_user(decoded))
def _update_session(self, user: OAuthUser, token: dict):
session["auth"] = {
"user": self.make_user(decoded).to_dict(),
"user_data": decoded,
"user": user.to_dict(),
"user_data": user.data,
"token": token
}
log.access_flask_login()
def _authorize(self, authorization_response):
try:
token = self.app.fetch_access_token(authorization_response = authorization_response)
except Exception as e:
traceback.print_exc()
sys.stderr.flush()
raise exceptions.SecurityError(description = str(e))
(_, user) = self.verify_token(token["access_token"])
self._update_session(user, token)
return jsonify(self.get_logged_in_user())
def authorize_post(self):

View File

@@ -67,10 +67,11 @@ components:
description: An auth token obtained by Vegas out-of-band from PINE.
type: object
properties:
auth_token:
access_token:
type: string
token_type:
type: string
example: bearer
additionalProperties: {}
paths:
@@ -143,7 +144,14 @@ paths:
If there is no user logged, in `null` is returned.
Example: `curl -X GET http://localhost:5000/auth/logged_in_user --cookie session.cookie`
Note that this operation does not REQUIRE the user to be logged in, but it is marked as
requiring security so that the Swagger UI will send in whatever you have configured.
operationId: auth_logged_in_user
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
tags: [auth]
responses:
"200":
@@ -167,6 +175,8 @@ paths:
operationId: auth_user_details
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
tags: [auth]
responses:
"200":
@@ -188,6 +198,7 @@ paths:
operationId: auth_eve_update_user_details
security:
- cookieAuth: []
- eveBasicAuth: []
tags: [auth_eve]
requestBody:
content:
@@ -236,6 +247,8 @@ paths:
tags: [auth]
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
responses:
"200":
description: Successfully logged out.
@@ -302,6 +315,7 @@ paths:
tags: [auth_eve]
security:
- cookieAuth: []
- eveBasicAuth: []
responses:
"200":
description: Returns all users.
@@ -325,6 +339,7 @@ paths:
tags: [auth_eve]
security:
- cookieAuth: []
- eveBasicAuth: []
requestBody:
content:
application/json:

View File

@@ -4,6 +4,8 @@ openapi: "3.0.2"
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
tags:
- name: collections

View File

@@ -4,7 +4,8 @@ import os
# default configuration values
SECRET_KEY = "Cq13XII=%"
SECRET_KEY = os.environ.get("BACKEND_SECRET_KEY", "Cq13XII=%")
if not SECRET_KEY: SECRET_KEY = "Cq13XII=%"
DEBUG = True
if os.environ.get("EVE_SERVER"):

View File

@@ -4,6 +4,8 @@ openapi: "3.0.2"
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
tags:
- name: documents

View File

@@ -4,6 +4,8 @@ openapi: "3.0.2"
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
tags:
- name: iaa_reports

View File

@@ -4,6 +4,8 @@ openapi: "3.0.2"
security:
- cookieAuth: []
- eveBasicAuth: []
- vegasBearerAuth: []
tags:
- name: pipelines

View File

@@ -56,6 +56,7 @@ services:
PINE_LOGGING_CONFIG_FILE: /nlp-web-app/shared/logging.python.json
DOCUMENT_IMAGE_DIR: /mnt/azure
PINE_VERSION: ${PINE_VERSION:?Please set PINE_VERSION environment variable.}
BACKEND_SECRET_KEY: ${BACKEND_SECRET_KEY}
# Expose the following to test:
# ports:
# - ${BACKEND_PORT}:${BACKEND_PORT}

View File

@@ -185,7 +185,7 @@ DOMAIN={
if os.environ.get("MONGO_URI"):
MONGO_URI = os.environ.get("MONGO_URI")
#LOGGER.info("Eve using MONGO_URI={}".format(MONGO_URI))
LOGGER.info("Eve using externally configured MONGO_URI")
else:
MONGO_HOST = "localhost"
MONGO_PORT = int(os.environ.get("MONGO_PORT", 27017))

View File

@@ -16,10 +16,13 @@ server {
try_files $uri$args $uri$args/ $uri $uri/ /index.html =404;
}
include snippets/api-rules.conf;
location /api {
include proxy_params;
proxy_set_header X-Forwarded-Prefix /api;
rewrite ^/api(.*) $1 break;
proxy_pass ${BACKEND_SERVER};
}
}

View File

@@ -18,6 +18,8 @@ server {
try_files $uri$args $uri$args/ $uri $uri/ /index.html =404;
}
include snippets/api-rules.conf;
location /api {
include proxy_params;
proxy_set_header X-Forwarded-Prefix /api;
@@ -25,6 +27,7 @@ server {
proxy_pass ${BACKEND_SERVER};
proxy_redirect http://$http_host/ https://$http_host/;
}
}
server {

View File

@@ -0,0 +1,6 @@
# special cases for redirecting inside api module
# the X-Forwarded-Prefix header doesn't work if this nginx is behind another nginx
rewrite ^/openapi.yaml?$ /api/openapi.yaml;
rewrite ^/swagger?$ /api/swagger;
rewrite ^/swagger/?$ /api/swagger/;
rewrite ^/swagger/(.+)?$ /api/swagger/$1;