diff --git a/.travis.yml b/.travis.yml index 2cff046a..c322fccb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,7 @@ before_install: - pip install pipenv - pipenv install --dev script: -- pipenv install ./users +- pipenv install ./users --skip-lock - "./lintstats.sh" - WITH_INTEGRATION=1 pipenv run pytest --cov=accounts --cov=users/arxiv --cov=registry --cov=authenticator --cov-report=term-missing accounts users/arxiv registry authenticator diff --git a/DECISIONS.md b/DECISIONS.md index a9745494..28c11610 100644 --- a/DECISIONS.md +++ b/DECISIONS.md @@ -1,3 +1,5 @@ +# Decision log + 1. To minimize complexity, we'll start with a managed Redis cluster in AWS ElastiCache. In the future, we may consider running our own HA key-value store, and potentially evaluate performance of other backends. @@ -5,3 +7,14 @@ can decide what "admin", "moderator", etc means and inject the relevant scopes. Later on, we will have an RBAC system. We therefore screen off the scope-determination concern from the session-creation concern. + +## 2019-02-28 Rename ``request.session`` to ``request.auth`` + +The auth middleware in ``arxiv.users`` package hands the authenticated session +on ``flask.session``, which clobbers the built-in Flask session interface. This +is a design flaw that's blocking other work. ARXIVNG-1920 + +Starting with v0.3.1, set ``AUTH_UPDATED_SESSION_REF=True`` in your +application config to rename ``request.session`` to ``request.auth``. +``request.auth`` will be the default name for the authenticated session +starting in v0.4.1. diff --git a/Dockerfile-authenticator b/Dockerfile-authenticator index fc7859bd..e3a01bc0 100644 --- a/Dockerfile-authenticator +++ b/Dockerfile-authenticator @@ -11,7 +11,7 @@ ENV LC_ALL en_US.utf-8 ENV LANG en_US.utf-8 RUN pipenv install ADD users/ /opt/arxiv/users/ -RUN pipenv install /opt/arxiv/users/ +RUN pipenv install /opt/arxiv/users/ --skip-lock ENV PATH "/opt/arxiv:${PATH}" @@ -25,9 +25,8 @@ CMD ["--http-socket", ":8000", \ "-M", \ "-t 3000", \ "--manage-script-name", \ - "--processes", "8", \ + "--processes", "1", \ "--threads", "1", \ - "--async", "100", \ - "--ugreen", \ + "--queue", "0", \ "--mount", "/=wsgi.py", \ "--logformat", "%(addr) %(addr) - %(user_id)|%(session_id) [%(rtime)] [%(uagent)] \"%(method) %(uri) %(proto)\" %(status) %(size) %(micros) %(ttfb)"] diff --git a/Dockerfile-registry b/Dockerfile-registry index 4990b50d..adf76037 100644 --- a/Dockerfile-registry +++ b/Dockerfile-registry @@ -9,11 +9,11 @@ RUN pip install -U pip pipenv ENV LC_ALL en_US.utf-8 ENV LANG en_US.utf-8 -ADD Pipfile /opt/arxiv/ +ADD Pipfile Pipfile.lock /opt/arxiv/ RUN pipenv install ADD users/ /opt/arxiv/users/ -RUN pipenv install /opt/arxiv/users/ +RUN pipenv install /opt/arxiv/users/ --skip-lock ENV PATH "/opt/arxiv:${PATH}" @@ -29,9 +29,8 @@ CMD ["uwsgi", "--http-socket", ":8000", \ "-M", \ "-t 3000", \ "--manage-script-name", \ - "--processes", "8", \ + "--processes", "1", \ "--threads", "1", \ - "--async", "100", \ - "--ugreen", \ - "--mount", "/api=wsgi.py", \ + "--queue", "0", \ + "--mount", "/=wsgi.py", \ "--logformat", "%(addr) %(addr) - %(user_id)|%(session_id) [%(rtime)] [%(uagent)] \"%(method) %(uri) %(proto)\" %(status) %(size) %(micros) %(ttfb)"] diff --git a/Pipfile b/Pipfile index f9b7ca2c..ce002bfc 100644 --- a/Pipfile +++ b/Pipfile @@ -18,24 +18,21 @@ requests = "==2.20.0" sqlalchemy = "*" uwsgi = "*" wtforms = "*" -arxiv-base = "==0.12.1" +arxiv-base = "==0.14.3" authlib = "*" openapi-spec-validator = "*" -"4010dd8" = {path = "./users"} bleach = "*" [dev-packages] mimesis = "==2.1.0" -mypy = "*" -pydocstyle = "*" +mypy = "==0.670" +pydocstyle = "==2.1.1" pylint = "*" -sphinx = "*" -sphinx-autodoc-typehints = "*" coverage = "*" coveralls = "*" +astroid = "<2.2" pytest = "*" pytest-cov = "*" -"nose2" = "*" [requires] python_version = "3.6" diff --git a/Pipfile.lock b/Pipfile.lock index 3deb7e44..c3f05a21 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "12808680ec8c4cce8c2c4cab0dce92dd6ce4a50931ac2d6fd9f9594e5e49a945" + "sha256": "f5b5230597e36e7bb139345f811e3eb6791aefad928381040c3baab5c78e820e" }, "pipfile-spec": 6, "requires": { @@ -16,22 +16,19 @@ ] }, "default": { - "4010dd8": { - "path": "./users" - }, "amqp": { "hashes": [ - "sha256:9f181e4aef6562e6f9f45660578fc1556150ca06e836ecb9e733e6ea10b48464", - "sha256:c3d7126bfbc640d076a01f1f4f6e609c0e4348508150c1f61336b0d83c738d2b" + "sha256:16056c952e8029ce8db097edf0d7c2fe2ba9de15d30ba08aee2c5221273d8e23", + "sha256:6816eed27521293ee03aa9ace300a07215b11fee4e845588a9b863a7ba30addb" ], - "version": "==2.4.0" + "version": "==2.4.1" }, "arxiv-base": { "hashes": [ - "sha256:f8fa599e50550e0c6ee9de53030c22c0b8921fca7ac1268753a6b2b0fef177e9" + "sha256:4c2ca540aeed0a06394e6eea12364562e2e4733d4803812f5d7542475dd55d09" ], "index": "pypi", - "version": "==0.12.1" + "version": "==0.14.3" }, "asn1crypto": { "hashes": [ @@ -50,9 +47,9 @@ }, "billiard": { "hashes": [ - "sha256:42d9a227401ac4fba892918bba0a0c409def5435c4b483267ebfe821afaaba0e" + "sha256:756bf323f250db8bf88462cd042c992ba60d8f5e07fc5636c24ba7d6f4261d84" ], - "version": "==3.5.0.5" + "version": "==3.6.0.0" }, "bleach": { "hashes": [ @@ -64,17 +61,17 @@ }, "boto3": { "hashes": [ - "sha256:63cd957ba663f5c10ff48ed904575eaa701314f79f18dbc59bd050311cd5f809", - "sha256:d1338582bc58741f54bd6b43488de6097a82ea45cebed0a3fd936981eadbb3a5" + "sha256:1f43d7a4865b75c4628a5084c2c32b00f356a9fd09f97574a8903c574356890a", + "sha256:4605a0707e857f316a7b01766fb49350e7b3d922458aa9c870f6393ec6fa22ca" ], - "version": "==1.9.86" + "version": "==1.9.102" }, "botocore": { "hashes": [ - "sha256:24444e7580f0114c3e9fff5d2032c6f0cfbf88691b1be3ba27c6922507a902ec", - "sha256:5b01a16f02c3da55068b3aacfa1c37dd8e17141551e1702424b38dd21fa1c792" + "sha256:00d64c0ce9d85a86dfda51999194621fbc9e50e20b56e857ef00dce8a30dac6a", + "sha256:d2e338c2f065b897ae856938af5090c3430ce0f53eddab8f87dad5972c38f975" ], - "version": "==1.12.86" + "version": "==1.12.102" }, "captcha": { "hashes": [ @@ -86,11 +83,11 @@ }, "celery": { "hashes": [ - "sha256:77dab4677e24dc654d42dfbdfed65fa760455b6bb563a0877ecc35f4cfcfc678", - "sha256:ad7a7411772b80a4d6c64f2f7f723200e39fb66cf614a7fdfab76d345acc7b13" + "sha256:62cdf98af78278202b8a3ba1b8215c87ab420eae7eebf0b7ba27b16ebc9f148e", + "sha256:ce1f8068f8330e9552def4161f34ee667a1e3f5f8874425ee5768d05e821afca" ], "index": "pypi", - "version": "==4.2.1" + "version": "==4.3.0rc1" }, "certifi": { "hashes": [ @@ -101,40 +98,36 @@ }, "cffi": { "hashes": [ - "sha256:151b7eefd035c56b2b2e1eb9963c90c6302dc15fbd8c1c0a83a163ff2c7d7743", - "sha256:1553d1e99f035ace1c0544050622b7bc963374a00c467edafac50ad7bd276aef", - "sha256:1b0493c091a1898f1136e3f4f991a784437fac3673780ff9de3bcf46c80b6b50", - "sha256:2ba8a45822b7aee805ab49abfe7eec16b90587f7f26df20c71dd89e45a97076f", - "sha256:3bb6bd7266598f318063e584378b8e27c67de998a43362e8fce664c54ee52d30", - "sha256:3c85641778460581c42924384f5e68076d724ceac0f267d66c757f7535069c93", - "sha256:3eb6434197633b7748cea30bf0ba9f66727cdce45117a712b29a443943733257", - "sha256:495c5c2d43bf6cebe0178eb3e88f9c4aa48d8934aa6e3cddb865c058da76756b", - "sha256:4c91af6e967c2015729d3e69c2e51d92f9898c330d6a851bf8f121236f3defd3", - "sha256:57b2533356cb2d8fac1555815929f7f5f14d68ac77b085d2326b571310f34f6e", - "sha256:770f3782b31f50b68627e22f91cb182c48c47c02eb405fd689472aa7b7aa16dc", - "sha256:79f9b6f7c46ae1f8ded75f68cf8ad50e5729ed4d590c74840471fc2823457d04", - "sha256:7a33145e04d44ce95bcd71e522b478d282ad0eafaf34fe1ec5bbd73e662f22b6", - "sha256:857959354ae3a6fa3da6651b966d13b0a8bed6bbc87a0de7b38a549db1d2a359", - "sha256:87f37fe5130574ff76c17cab61e7d2538a16f843bb7bca8ebbc4b12de3078596", - "sha256:95d5251e4b5ca00061f9d9f3d6fe537247e145a8524ae9fd30a2f8fbce993b5b", - "sha256:9d1d3e63a4afdc29bd76ce6aa9d58c771cd1599fbba8cf5057e7860b203710dd", - "sha256:a36c5c154f9d42ec176e6e620cb0dd275744aa1d804786a71ac37dc3661a5e95", - "sha256:a6a5cb8809091ec9ac03edde9304b3ad82ad4466333432b16d78ef40e0cce0d5", - "sha256:ae5e35a2c189d397b91034642cb0eab0e346f776ec2eb44a49a459e6615d6e2e", - "sha256:b0f7d4a3df8f06cf49f9f121bead236e328074de6449866515cea4907bbc63d6", - "sha256:b75110fb114fa366b29a027d0c9be3709579602ae111ff61674d28c93606acca", - "sha256:ba5e697569f84b13640c9e193170e89c13c6244c24400fc57e88724ef610cd31", - "sha256:be2a9b390f77fd7676d80bc3cdc4f8edb940d8c198ed2d8c0be1319018c778e1", - "sha256:ca1bd81f40adc59011f58159e4aa6445fc585a32bb8ac9badf7a2c1aa23822f2", - "sha256:d5d8555d9bfc3f02385c1c37e9f998e2011f0db4f90e250e5bc0c0a85a813085", - "sha256:e55e22ac0a30023426564b1059b035973ec82186ddddbac867078435801c7801", - "sha256:e90f17980e6ab0f3c2f3730e56d1fe9bcba1891eeea58966e89d352492cc74f4", - "sha256:ecbb7b01409e9b782df5ded849c178a0aa7c906cf8c5a67368047daab282b184", - "sha256:ed01918d545a38998bfa5902c7c00e0fee90e957ce036a4000a88e3fe2264917", - "sha256:edabd457cd23a02965166026fd9bfd196f4324fe6032e866d0f3bd0301cd486f", - "sha256:fdf1c1dc5bafc32bc5d08b054f94d659422b05aba244d6be4ddc1c72d9aa70fb" - ], - "version": "==1.11.5" + "sha256:0b5f895714a7a9905148fc51978c62e8a6cbcace30904d39dcd0d9e2265bb2f6", + "sha256:27cdc7ba35ee6aa443271d11583b50815c4bb52be89a909d0028e86c21961709", + "sha256:2d4a38049ea93d5ce3c7659210393524c1efc3efafa151bd85d196fa98fce50a", + "sha256:3262573d0d60fc6b9d0e0e6e666db0e5045cbe8a531779aa0deb3b425ec5a282", + "sha256:358e96cfffc185ab8f6e7e425c7bb028931ed08d65402fbcf3f4e1bff6e66556", + "sha256:37c7db824b5687fbd7ea5519acfd054c905951acc53503547c86be3db0580134", + "sha256:39b9554dfe60f878e0c6ff8a460708db6e1b1c9cc6da2c74df2955adf83e355d", + "sha256:42b96a77acf8b2d06821600fa87c208046decc13bd22a4a0e65c5c973443e0da", + "sha256:5b37dde5035d3c219324cac0e69d96495970977f310b306fa2df5910e1f329a1", + "sha256:5d35819f5566d0dd254f273d60cf4a2dcdd3ae3003dfd412d40b3fe8ffd87509", + "sha256:5df73aa465e53549bd03c819c1bc69fb85529a5e1a693b7b6cb64408dd3970d1", + "sha256:7075b361f7a4d0d4165439992d0b8a3cdfad1f302bf246ed9308a2e33b046bd3", + "sha256:7678b5a667b0381c173abe530d7bdb0e6e3b98e062490618f04b80ca62686d96", + "sha256:7dfd996192ff8a535458c17f22ff5eb78b83504c34d10eefac0c77b1322609e2", + "sha256:8a3be5d31d02c60f84c4fd4c98c5e3a97b49f32e16861367f67c49425f955b28", + "sha256:9812e53369c469506b123aee9dcb56d50c82fad60c5df87feb5ff59af5b5f55c", + "sha256:9b6f7ba4e78c52c1a291d0c0c0bd745d19adde1a9e1c03cb899f0c6efd6f8033", + "sha256:a85bc1d7c3bba89b3d8c892bc0458de504f8b3bcca18892e6ed15b5f7a52ad9d", + "sha256:aa6b9c843ad645ebb12616de848cc4e25a40f633ccc293c3c9fe34107c02c2ea", + "sha256:bae1aa56ee00746798beafe486daa7cfb586cd395c6ce822ba3068e48d761bc0", + "sha256:bae96e26510e4825d5910a196bf6b5a11a18b87d9278db6d08413be8ea799469", + "sha256:bd78df3b594013b227bf31d0301566dc50ba6f40df38a70ded731d5a8f2cb071", + "sha256:c2711197154f46d06f73542c539a0ff5411f1951fab391e0a4ac8359badef719", + "sha256:d998c20e3deed234fca993fd6c8314cb7cbfda05fd170f1bd75bb5d7421c3c5a", + "sha256:df4f840d77d9e37136f8e6b432fecc9d6b8730f18f896e90628712c793466ce6", + "sha256:f5653c2581acb038319e6705d4e3593677676df14b112f13e0b5b44b6a18df1a", + "sha256:f7c7aa485a2e2250d455148470ffd0195eecc3d845122635202d7467d6f7b4cf", + "sha256:f9e2c66a6493147de835f207f198540a56b26745ce4f272fbc7c2f2cfebeb729" + ], + "version": "==1.12.1" }, "chardet": { "hashes": [ @@ -213,10 +206,10 @@ }, "jmespath": { "hashes": [ - "sha256:6a81d4c9aa62caf061cb517b4d9ad1dd300374cd4706997aff9cd6aedd61fc64", - "sha256:f11b4461f425740a1d908e9a3f7365c3d2e569f6ca68a2ff8bc5bcd9676edd63" + "sha256:3720a4b1bd659dd2eecad0666459b9788813e032b83e7ba58578e48254e0a0e6", + "sha256:bde2aef6f44302dfb30320115b17d030798de8c4110e28d5cf6cf91a7a31074c" ], - "version": "==0.9.3" + "version": "==0.9.4" }, "jsonschema": { "hashes": [ @@ -228,61 +221,61 @@ }, "kombu": { "hashes": [ - "sha256:1ef049243aa05f29e988ab33444ec7f514375540eaa8e0b2e1f5255e81c5e56d", - "sha256:3c9dca2338c5d893f30c151f5d29bfb81196748ab426d33c362ab51f1e8dbf78" + "sha256:529df9e0ecc0bad9fc2b376c3ce4796c41b482cf697b78b71aea6ebe7ca353c8", + "sha256:7a2cbed551103db9a4e2efafe9b63222e012a61a18a881160ad797b9d4e1d0a1" ], - "version": "==4.2.2.post1" + "version": "==4.3.0" }, "markupsafe": { "hashes": [ - "sha256:048ef924c1623740e70204aa7143ec592504045ae4429b59c30054cb31e3c432", - "sha256:130f844e7f5bdd8e9f3f42e7102ef1d49b2e6fdf0d7526df3f87281a532d8c8b", - "sha256:19f637c2ac5ae9da8bfd98cef74d64b7e1bb8a63038a3505cd182c3fac5eb4d9", - "sha256:1b8a7a87ad1b92bd887568ce54b23565f3fd7018c4180136e1cf412b405a47af", - "sha256:1c25694ca680b6919de53a4bb3bdd0602beafc63ff001fea2f2fc16ec3a11834", - "sha256:1f19ef5d3908110e1e891deefb5586aae1b49a7440db952454b4e281b41620cd", - "sha256:1fa6058938190ebe8290e5cae6c351e14e7bb44505c4a7624555ce57fbbeba0d", - "sha256:31cbb1359e8c25f9f48e156e59e2eaad51cd5242c05ed18a8de6dbe85184e4b7", - "sha256:3e835d8841ae7863f64e40e19477f7eb398674da6a47f09871673742531e6f4b", - "sha256:4e97332c9ce444b0c2c38dd22ddc61c743eb208d916e4265a2a3b575bdccb1d3", - "sha256:525396ee324ee2da82919f2ee9c9e73b012f23e7640131dd1b53a90206a0f09c", - "sha256:52b07fbc32032c21ad4ab060fec137b76eb804c4b9a1c7c7dc562549306afad2", - "sha256:52ccb45e77a1085ec5461cde794e1aa037df79f473cbc69b974e73940655c8d7", - "sha256:5c3fbebd7de20ce93103cb3183b47671f2885307df4a17a0ad56a1dd51273d36", - "sha256:5e5851969aea17660e55f6a3be00037a25b96a9b44d2083651812c99d53b14d1", - "sha256:5edfa27b2d3eefa2210fb2f5d539fbed81722b49f083b2c6566455eb7422fd7e", - "sha256:7d263e5770efddf465a9e31b78362d84d015cc894ca2c131901a4445eaa61ee1", - "sha256:83381342bfc22b3c8c06f2dd93a505413888694302de25add756254beee8449c", - "sha256:857eebb2c1dc60e4219ec8e98dfa19553dae33608237e107db9c6078b1167856", - "sha256:98e439297f78fca3a6169fd330fbe88d78b3bb72f967ad9961bcac0d7fdd1550", - "sha256:bf54103892a83c64db58125b3f2a43df6d2cb2d28889f14c78519394feb41492", - "sha256:d9ac82be533394d341b41d78aca7ed0e0f4ba5a2231602e2f05aa87f25c51672", - "sha256:e982fe07ede9fada6ff6705af70514a52beb1b2c3d25d4e873e82114cf3c5401", - "sha256:edce2ea7f3dfc981c4ddc97add8a61381d9642dc3273737e756517cc03e84dd6", - "sha256:efdc45ef1afc238db84cb4963aa689c0408912a0239b0721cb172b4016eb31d6", - "sha256:f137c02498f8b935892d5c0172560d7ab54bc45039de8805075e19079c639a9c", - "sha256:f82e347a72f955b7017a39708a3667f106e6ad4d10b25f237396a7115d8ed5fd", - "sha256:fb7c206e01ad85ce57feeaaa0bf784b97fa3cad0d4a5737bc5295785f5c613a1" - ], - "version": "==1.1.0" + "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473", + "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161", + "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235", + "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5", + "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff", + "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b", + "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1", + "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e", + "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183", + "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66", + "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1", + "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1", + "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e", + "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b", + "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905", + "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735", + "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d", + "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e", + "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d", + "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c", + "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21", + "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2", + "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5", + "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b", + "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6", + "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f", + "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f", + "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7" + ], + "version": "==1.1.1" }, "mysqlclient": { "hashes": [ - "sha256:6883a4dd98903bad375c859ead1a480e1245ea3a8d9b038ea2c091c1865ba673", - "sha256:a62220410e26ce2d2ff94dd0138c3ecfb91db634464a9afb4c8e6b50f0a67e00", - "sha256:e1b9f3a8928ddb4985ca3e3c9f2aa81b19e831bbf6fabf5681ee356738dbbbb2" + "sha256:425e733b05e359a714d6007c0fc44582be66b63e5a3df0a50949274ae16f4bc6", + "sha256:62e4770b6a797b9416bcf70488365b7d6b9c9066878108499c559293bb464380", + "sha256:f257d250f2675d0ef99bd318906f3cfc05cef4a2f385ea695ff32a3f04b9f9a7" ], "index": "pypi", - "version": "==1.4.1" + "version": "==1.4.2.post1" }, "openapi-spec-validator": { "hashes": [ - "sha256:14684aaec4c4f30e911132ffad3c5863047908251647f49114d249dcc2d41f4e", - "sha256:48c83d77b98a1b046973e2cd26b441a6db60a858382e9c3d7d8e63c940a7878f", - "sha256:5946bab0b5c0e4bd915dbcac308561cb7b2f1c219a9b447f93ae26752f9328c6" + "sha256:6788b2f9ceeb87293cd5fda266227be9c3fe541c23328e0c3d31413ad5c3dfc7", + "sha256:941b54012c48090d5459fe091ab26f55d3acd548c7acd5cd7be9e5580712523b", + "sha256:cdc90d33fbf7ab9ef9c4bee27cdbf017aaedd4302b9335ce32f2aa05be56a68a" ], "index": "pypi", - "version": "==0.2.4" + "version": "==0.2.5" }, "pillow": { "hashes": [ @@ -364,11 +357,11 @@ }, "python-dateutil": { "hashes": [ - "sha256:063df5763652e21de43de7d9e00ccf239f953a832941e37be541614732cdfc93", - "sha256:88f9287c0174266bb0d8cedd395cfba9c58e87e5ad86b2ce58859bc11be3cf02" + "sha256:7e6584c74aeed623791615e26efd690f29817a27c73085b78e4bad02493df2fb", + "sha256:c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e" ], "index": "pypi", - "version": "==2.7.5" + "version": "==2.8.0" }, "pytz": { "hashes": [ @@ -379,19 +372,9 @@ }, "pyyaml": { "hashes": [ - "sha256:3d7da3009c0f3e783b2c873687652d83b1bbfd5c88e9813fb7e5b03c0dd3108b", - "sha256:3ef3092145e9b70e3ddd2c7ad59bdd0252a94dfe3949721633e41344de00a6bf", - "sha256:40c71b8e076d0550b2e6380bada1f1cd1017b882f7e16f09a65be98e017f211a", - "sha256:558dd60b890ba8fd982e05941927a3911dc409a63dcb8b634feaa0cda69330d3", - "sha256:a7c28b45d9f99102fa092bb213aa12e0aaf9a6a1f5e395d36166639c1f96c3a1", - "sha256:aa7dd4a6a427aed7df6fb7f08a580d68d9b118d90310374716ae90b710280af1", - "sha256:bc558586e6045763782014934bfaf39d48b8ae85a2713117d16c39864085c613", - "sha256:d46d7982b62e0729ad0175a9bc7e10a566fc07b224d2c79fafb5e032727eaa04", - "sha256:d5eef459e30b09f5a098b9cea68bebfeb268697f78d647bd255a085371ac7f3f", - "sha256:e01d3203230e1786cd91ccfdc8f8454c8069c91bee3962ad93b87a4b2860f537", - "sha256:e170a9e6fcfd19021dd29845af83bb79236068bf5fd4df3327c1be18182b2531" + "sha256:b21fadf0e343c3738cc956be9d24ee7a83d3260ff1a6805f860b4f5d4645b7b9" ], - "version": "==3.13" + "version": "==5.1b1" }, "redis": { "hashes": [ @@ -418,10 +401,10 @@ }, "s3transfer": { "hashes": [ - "sha256:90dc18e028989c609146e241ea153250be451e05ecc0c2832565231dacdf59c1", - "sha256:c7a9ec356982d5e9ab2d4b46391a7d6a950e2b04c472419f5fdec70cc0ada72f" + "sha256:7b9ad3213bff7d357f888e0fab5101b56fa1a0548ee77d121c3a3dbfbef4cb2e", + "sha256:f23d5cb7d862b104401d9021fc82e5fa0e0cf57b7660a1331425aab0c691d021" ], - "version": "==0.1.13" + "version": "==0.2.0" }, "six": { "hashes": [ @@ -432,24 +415,25 @@ }, "sqlalchemy": { "hashes": [ - "sha256:52a42dbf02d0562d6e90e7af59f177f1cc027e72833cc29c3a821eefa009c71d" + "sha256:7dede29f121071da9873e7b8c98091874617858e790dc364ffaab4b09d81216c" ], "index": "pypi", - "version": "==1.2.17" + "version": "==1.3.0b3" }, "urllib3": { "hashes": [ "sha256:61bf29cada3fc2fbefad4fdf059ea4bd1b4a86d2b6d15e1c7c0b582b9752fe39", "sha256:de9529817c93f27c8ccbfead6985011db27bd0ddfcdb2d86f3f663385c6a9c22" ], + "markers": "python_version >= '3.4'", "version": "==1.24.1" }, "uwsgi": { "hashes": [ - "sha256:d2318235c74665a60021a4fc7770e9c2756f9fc07de7b8c22805efe85b5ab277" + "sha256:4972ac538800fb2d421027f49b4a1869b66048839507ccf0aa2fda792d99f583" ], "index": "pypi", - "version": "==2.0.17.1" + "version": "==2.0.18" }, "vine": { "hashes": [ @@ -482,26 +466,20 @@ } }, "develop": { - "alabaster": { - "hashes": [ - "sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359", - "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02" - ], - "version": "==0.7.12" - }, "astroid": { "hashes": [ "sha256:35b032003d6a863f5dcd7ec11abd5cd5893428beaa31ab164982403bcb311f22", "sha256:6a5d668d7dc69110de01cdf7aeec69a679ef486862a0850cc0fd5571505b6b7e" ], + "index": "pypi", "version": "==2.1.0" }, "atomicwrites": { "hashes": [ - "sha256:0312ad34fcad8fac3704d441f7b317e50af620823353ec657a53e981f92920c0", - "sha256:ec9ae8adaae229e4f8446952d204a3e4b5fdd2d099f9be3aaf556120135fb3ee" + "sha256:03472c30eb2c5d1ba9227e4c2ca66ab8287fbfbbda3888aa93dc2e28fc6811b4", + "sha256:75a9445bac02d8d058d5e1fe689654ba5a6556a1dfd8ce6ec55a0ed79866cfa6" ], - "version": "==1.2.1" + "version": "==1.3.0" }, "attrs": { "hashes": [ @@ -510,13 +488,6 @@ ], "version": "==18.2.0" }, - "babel": { - "hashes": [ - "sha256:6778d85147d5d85345c14a26aada5e478ab04e39b078b0745ee6870c2b5cf669", - "sha256:8cba50f48c529ca3fa18cf81fa9403be176d374ac4d60738b839122dfaaa3d23" - ], - "version": "==2.6.0" - }, "certifi": { "hashes": [ "sha256:47f9c83ef4c0c621eaef743f133f09fa8a74a9b75f037e8624f83bd1b6626cb7", @@ -533,58 +504,56 @@ }, "coverage": { "hashes": [ - "sha256:06123b58a1410873e22134ca2d88bd36680479fe354955b3579fb8ff150e4d27", - "sha256:09e47c529ff77bf042ecfe858fb55c3e3eb97aac2c87f0349ab5a7efd6b3939f", - "sha256:0a1f9b0eb3aa15c990c328535655847b3420231af299386cfe5efc98f9c250fe", - "sha256:0cc941b37b8c2ececfed341444a456912e740ecf515d560de58b9a76562d966d", - "sha256:0d34245f824cc3140150ab7848d08b7e2ba67ada959d77619c986f2062e1f0e8", - "sha256:10e8af18d1315de936d67775d3a814cc81d0747a1a0312d84e27ae5610e313b0", - "sha256:1b4276550b86caa60606bd3572b52769860a81a70754a54acc8ba789ce74d607", - "sha256:1e8a2627c48266c7b813975335cfdea58c706fe36f607c97d9392e61502dc79d", - "sha256:258b21c5cafb0c3768861a6df3ab0cfb4d8b495eee5ec660e16f928bf7385390", - "sha256:2b224052bfd801beb7478b03e8a66f3f25ea56ea488922e98903914ac9ac930b", - "sha256:3ad59c84c502cd134b0088ca9038d100e8fb5081bbd5ccca4863f3804d81f61d", - "sha256:447c450a093766744ab53bf1e7063ec82866f27bcb4f4c907da25ad293bba7e3", - "sha256:46101fc20c6f6568561cdd15a54018bb42980954b79aa46da8ae6f008066a30e", - "sha256:4710dc676bb4b779c4361b54eb308bc84d64a2fa3d78e5f7228921eccce5d815", - "sha256:510986f9a280cd05189b42eee2b69fecdf5bf9651d4cd315ea21d24a964a3c36", - "sha256:5535dda5739257effef56e49a1c51c71f1d37a6e5607bb25a5eee507c59580d1", - "sha256:5a7524042014642b39b1fcae85fb37556c200e64ec90824ae9ecf7b667ccfc14", - "sha256:5f55028169ef85e1fa8e4b8b1b91c0b3b0fa3297c4fb22990d46ff01d22c2d6c", - "sha256:6694d5573e7790a0e8d3d177d7a416ca5f5c150742ee703f3c18df76260de794", - "sha256:6831e1ac20ac52634da606b658b0b2712d26984999c9d93f0c6e59fe62ca741b", - "sha256:71afc1f5cd72ab97330126b566bbf4e8661aab7449f08895d21a5d08c6b051ff", - "sha256:7349c27128334f787ae63ab49d90bf6d47c7288c63a0a5dfaa319d4b4541dd2c", - "sha256:77f0d9fa5e10d03aa4528436e33423bfa3718b86c646615f04616294c935f840", - "sha256:828ad813c7cdc2e71dcf141912c685bfe4b548c0e6d9540db6418b807c345ddd", - "sha256:859714036274a75e6e57c7bab0c47a4602d2a8cfaaa33bbdb68c8359b2ed4f5c", - "sha256:85a06c61598b14b015d4df233d249cd5abfa61084ef5b9f64a48e997fd829a82", - "sha256:869ef4a19f6e4c6987e18b315721b8b971f7048e6eaea29c066854242b4e98d9", - "sha256:8cb4febad0f0b26c6f62e1628f2053954ad2c555d67660f28dfb1b0496711952", - "sha256:977e2d9a646773cc7428cdd9a34b069d6ee254fadfb4d09b3f430e95472f3cf3", - "sha256:99bd767c49c775b79fdcd2eabff405f1063d9d959039c0bdd720527a7738748a", - "sha256:a5c58664b23b248b16b96253880b2868fb34358911400a7ba39d7f6399935389", - "sha256:aaa0f296e503cda4bc07566f592cd7a28779d433f3a23c48082af425d6d5a78f", - "sha256:ab235d9fe64833f12d1334d29b558aacedfbca2356dfb9691f2d0d38a8a7bfb4", - "sha256:b3b0c8f660fae65eac74fbf003f3103769b90012ae7a460863010539bb7a80da", - "sha256:bab8e6d510d2ea0f1d14f12642e3f35cefa47a9b2e4c7cea1852b52bc9c49647", - "sha256:c45297bbdbc8bb79b02cf41417d63352b70bcb76f1bbb1ee7d47b3e89e42f95d", - "sha256:d19bca47c8a01b92640c614a9147b081a1974f69168ecd494687c827109e8f42", - "sha256:d64b4340a0c488a9e79b66ec9f9d77d02b99b772c8b8afd46c1294c1d39ca478", - "sha256:da969da069a82bbb5300b59161d8d7c8d423bc4ccd3b410a9b4d8932aeefc14b", - "sha256:ed02c7539705696ecb7dc9d476d861f3904a8d2b7e894bd418994920935d36bb", - "sha256:ee5b8abc35b549012e03a7b1e86c09491457dba6c94112a2482b18589cc2bdb9" + "sha256:029c69deaeeeae1b15bc6c59f0ffa28aa8473721c614a23f2c2976dec245cd12", + "sha256:02abbbebc6e9d5abe13cd28b5e963dedb6ffb51c146c916d17b18f141acd9947", + "sha256:0384e4479aeb780bfb811eb54c3deb37dbc5e197cd19ec1190cb4b33b254f661", + "sha256:1bbfe5b82a3921d285e999c6d256c1e16b31c554c29da62d326f86c173d30337", + "sha256:20bbeef0d08e43ef44e10d5863225e178fe100d5778c616260286202bad9d2b4", + "sha256:210c02f923df33a8d0e461c86fdcbbb17228ff4f6d92609fc06370a98d283c2d", + "sha256:2d0807ba935f540d20b49d5bf1c0237b90ce81e133402feda906e540003f2f7a", + "sha256:35d7a013874a7c927ce997350d314144ffc5465faf787bb4e46e6c4f381ef562", + "sha256:3636f9d0dcb01aed4180ef2e57a4e34bb4cac3ecd203c2a23db8526d86ab2fb4", + "sha256:42f4be770af2455a75e4640f033a82c62f3fb0d7a074123266e143269d7010ef", + "sha256:48440b25ba6cda72d4c638f3a9efa827b5b87b489c96ab5f4ff597d976413156", + "sha256:494fc6f09b776668cb0d69df5caefb9b90867bd280eb1bd004a63c79fbb09e71", + "sha256:4dac8dfd1acf6a3ac657475dfdc66c621f291b1b7422a939cc33c13ac5356473", + "sha256:4e8474771c69c2991d5eab65764289a7dd450bbea050bc0ebb42b678d8222b42", + "sha256:551f10ddfeff56a1325e5a34eff304c5892aa981fd810babb98bfee77ee2fb17", + "sha256:5b104982f1809c1577912519eb249f17d9d7e66304ad026666cb60a5ef73309c", + "sha256:5c62aef73dfc87bfcca32cee149a1a7a602bc74bac72223236b0023543511c88", + "sha256:633151f8d1ad9467b9f7e90854a7f46ed8f2919e8bc7d98d737833e8938fc081", + "sha256:772207b9e2d5bf3f9d283b88915723e4e92d9a62c83f44ec92b9bd0cd685541b", + "sha256:7d5e02f647cd727afc2659ec14d4d1cc0508c47e6cfb07aea33d7aa9ca94d288", + "sha256:8edc25c1449bdf31acfe183e579bb9c75cec59b55220ccefb6a4f960807ef1d0", + "sha256:96d895fba9ed55286368bd4626b8dcbf19b9a529a88e5a6b5c22e0b08c95852a", + "sha256:a77589fec63dc7fa6469d8cd122cc285ec034be43d8a2ba600020ddb14277514", + "sha256:a9798a4111abb0f94584000ba2a2c74841f2cfe5f9254709756367aabbae0541", + "sha256:b33a8f3d6d8946ea1db4ec228606ebc45cf880a7b1d1a26fe8790af677c12b8b", + "sha256:b38ea741ab9e35bfa7015c93c93bbd6a1623428f97a67083fc8ebd366238b91f", + "sha256:b6a5478c904236543c0347db8a05fac6fc0bd574c870e7970faa88e1d9890044", + "sha256:c6248bfc1de36a3844685a2e10ba17c18119ba6252547f921062a323fb31bff1", + "sha256:c6c6f84282d3f8953072295ce5cb96cdc56c91f164ef451a5c03be8abb84ad56", + "sha256:c705ab445936457359b1424ef25ccc0098b0491b26064677c39f1d14a539f056", + "sha256:d95a363d663ceee647291131dbd213af258df24f41350246842481ec3709bd33", + "sha256:e27265eb80cdc5dab55a40ef6f890e04ecc618649ad3da5265f128b141f93f78", + "sha256:eb62a45b448258bd8b9faa2d12dc2b942259715d7e0d85ebbb3d737be83091d7", + "sha256:ebc276c9cb5d917bd2ae959f84ffc279acafa9c9b50b0fa436ebb70bbe2166ea", + "sha256:f05a38b77b6c62cff204b0874034d76709769b53a8a7fc5886e02fc4d099d540", + "sha256:f4d229866d030863d0fe3bf297d6d11e6133ca15bbb41ed2534a8b9a3d6bd061", + "sha256:f95675bd88b51474d4fe5165f3266f419ce754ffadfb97f10323931fa9ac95e5", + "sha256:f95bc54fb6d61b9f9ff09c4ae8ff6a3f5edc937cda3ca36fc937302a7c152bf1", + "sha256:fd0f6be53de40683584e5331c341e65a679dbe5ec489a0697cec7c2ef1a48cda" ], "index": "pypi", - "version": "==4.5.2" + "version": "==5.0a4" }, "coveralls": { "hashes": [ - "sha256:ab638e88d38916a6cedbf80a9cd8992d5fa55c77ab755e262e00b36792b7cd6d", - "sha256:b2388747e2529fa4c669fb1e3e2756e4e07b6ee56c7d9fce05f35ccccc913aa0" + "sha256:6f213e461390973f4a97fb9e9d4ebd4956af296ff0a4d868e622108145835cb7", + "sha256:a7d0078c9e9b5692c03dcd3884647e837836c265c01e98094632feadef767d36" ], "index": "pypi", - "version": "==1.5.1" + "version": "==1.6.0" }, "docopt": { "hashes": [ @@ -592,14 +561,6 @@ ], "version": "==0.6.2" }, - "docutils": { - "hashes": [ - "sha256:02aec4bd92ab067f6ff27a38a38a41173bf01bed8f89157768c1573f53e474a6", - "sha256:51e64ef2ebfb29cae1faa133b3710143496eca21c530f3f71424d77687764274", - "sha256:7a4bd47eaf6596e1295ecb11361139febe29b084a87bf005bf899f9a42edc3c6" - ], - "version": "==0.14" - }, "idna": { "hashes": [ "sha256:156a6814fb5ac1fc6850fb002e0852d56c0c8d2531923a51032d1b70760e186e", @@ -607,27 +568,12 @@ ], "version": "==2.7" }, - "imagesize": { - "hashes": [ - "sha256:3f349de3eb99145973fefb7dbe38554414e5c30abd0c8e4b970a7c9d09f3a1d8", - "sha256:f3832918bc3c66617f92e35f5d70729187676313caa60c187eb0f28b8fe5e3b5" - ], - "version": "==1.1.0" - }, "isort": { "hashes": [ - "sha256:1153601da39a25b14ddc54955dbbacbb6b2d19135386699e2ad58517953b34af", - "sha256:b9c40e9750f3d77e6e4d441d8b0266cf555e7cdabdcff33c4fd06366ca761ef8", - "sha256:ec9ef8f4a9bc6f71eec99e1806bfa2de401650d996c59330782b89a5555c1497" - ], - "version": "==4.3.4" - }, - "jinja2": { - "hashes": [ - "sha256:74c935a1b8bb9a3947c50a54766a969d4846290e1e788ea44c1392163723c3bd", - "sha256:f84be1bb0040caca4cea721fcbbbbd61f9be9464ca236387158b0feea01914a4" + "sha256:6c3110ff0871d3a45f0ba1b8f7cefe38e845887210c80d952479fa7e74e00ad7", + "sha256:78ebda8283402dbe15e1fe8dc73e6d72e5d3c6a0c5e8dc489b2a4372280037af" ], - "version": "==2.10" + "version": "==4.3.8" }, "lazy-object-proxy": { "hashes": [ @@ -663,39 +609,6 @@ ], "version": "==1.3.1" }, - "markupsafe": { - "hashes": [ - "sha256:048ef924c1623740e70204aa7143ec592504045ae4429b59c30054cb31e3c432", - "sha256:130f844e7f5bdd8e9f3f42e7102ef1d49b2e6fdf0d7526df3f87281a532d8c8b", - "sha256:19f637c2ac5ae9da8bfd98cef74d64b7e1bb8a63038a3505cd182c3fac5eb4d9", - "sha256:1b8a7a87ad1b92bd887568ce54b23565f3fd7018c4180136e1cf412b405a47af", - "sha256:1c25694ca680b6919de53a4bb3bdd0602beafc63ff001fea2f2fc16ec3a11834", - "sha256:1f19ef5d3908110e1e891deefb5586aae1b49a7440db952454b4e281b41620cd", - "sha256:1fa6058938190ebe8290e5cae6c351e14e7bb44505c4a7624555ce57fbbeba0d", - "sha256:31cbb1359e8c25f9f48e156e59e2eaad51cd5242c05ed18a8de6dbe85184e4b7", - "sha256:3e835d8841ae7863f64e40e19477f7eb398674da6a47f09871673742531e6f4b", - "sha256:4e97332c9ce444b0c2c38dd22ddc61c743eb208d916e4265a2a3b575bdccb1d3", - "sha256:525396ee324ee2da82919f2ee9c9e73b012f23e7640131dd1b53a90206a0f09c", - "sha256:52b07fbc32032c21ad4ab060fec137b76eb804c4b9a1c7c7dc562549306afad2", - "sha256:52ccb45e77a1085ec5461cde794e1aa037df79f473cbc69b974e73940655c8d7", - "sha256:5c3fbebd7de20ce93103cb3183b47671f2885307df4a17a0ad56a1dd51273d36", - "sha256:5e5851969aea17660e55f6a3be00037a25b96a9b44d2083651812c99d53b14d1", - "sha256:5edfa27b2d3eefa2210fb2f5d539fbed81722b49f083b2c6566455eb7422fd7e", - "sha256:7d263e5770efddf465a9e31b78362d84d015cc894ca2c131901a4445eaa61ee1", - "sha256:83381342bfc22b3c8c06f2dd93a505413888694302de25add756254beee8449c", - "sha256:857eebb2c1dc60e4219ec8e98dfa19553dae33608237e107db9c6078b1167856", - "sha256:98e439297f78fca3a6169fd330fbe88d78b3bb72f967ad9961bcac0d7fdd1550", - "sha256:bf54103892a83c64db58125b3f2a43df6d2cb2d28889f14c78519394feb41492", - "sha256:d9ac82be533394d341b41d78aca7ed0e0f4ba5a2231602e2f05aa87f25c51672", - "sha256:e982fe07ede9fada6ff6705af70514a52beb1b2c3d25d4e873e82114cf3c5401", - "sha256:edce2ea7f3dfc981c4ddc97add8a61381d9642dc3273737e756517cc03e84dd6", - "sha256:efdc45ef1afc238db84cb4963aa689c0408912a0239b0721cb172b4016eb31d6", - "sha256:f137c02498f8b935892d5c0172560d7ab54bc45039de8805075e19079c639a9c", - "sha256:f82e347a72f955b7017a39708a3667f106e6ad4d10b25f237396a7115d8ed5fd", - "sha256:fb7c206e01ad85ce57feeaaa0bf784b97fa3cad0d4a5737bc5295785f5c613a1" - ], - "version": "==1.1.0" - }, "mccabe": { "hashes": [ "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", @@ -713,19 +626,19 @@ }, "more-itertools": { "hashes": [ - "sha256:38a936c0a6d98a38bcc2d03fdaaedaba9f412879461dd2ceff8d37564d6522e4", - "sha256:c0a5785b1109a6bd7fac76d6837fd1feca158e54e521ccd2ae8bfe393cc9d4fc", - "sha256:fe7a7cae1ccb57d33952113ff4fa1bc5f879963600ed74918f1236e212ee50b9" + "sha256:0125e8f60e9e031347105eb1682cef932f5e97d7b9a1a28d9bf00c22a5daef40", + "sha256:590044e3942351a1bdb1de960b739ff4ce277960f2425ad4509446dbace8d9d1" ], - "version": "==5.0.0" + "markers": "python_version > '2.7'", + "version": "==6.0.0" }, "mypy": { "hashes": [ - "sha256:986a7f97808a865405c5fd98fae5ebfa963c31520a56c783df159e9a81e41b3e", - "sha256:cc5df73cc11d35655a8c364f45d07b13c8db82c000def4bd7721be13356533b4" + "sha256:308c274eb8482fbf16006f549137ddc0d69e5a589465e37b99c4564414363ca7", + "sha256:e80fd6af34614a0e898a57f14296d0dacb584648f0339c2e000ddbf0f4cc2f8d" ], "index": "pypi", - "version": "==0.660" + "version": "==0.670" }, "mypy-extensions": { "hashes": [ @@ -734,72 +647,44 @@ ], "version": "==0.4.1" }, - "nose2": { - "hashes": [ - "sha256:9052f2b46807b63d9bdf68e0768da1f8386368889b50043fd5d0889c470258f3" - ], - "index": "pypi", - "version": "==0.8.0" - }, - "packaging": { - "hashes": [ - "sha256:0c98a5d0be38ed775798ece1b9727178c4469d9c3b4ada66e8e6b7849f8732af", - "sha256:9e1cbf8c12b1f1ce0bb5344b8d7ecf66a6f8a6e91bcb0c84593ed6d3ab5c4ab3" - ], - "version": "==19.0" - }, "pluggy": { "hashes": [ - "sha256:8ddc32f03971bfdf900a81961a48ccf2fb677cf7715108f85295c67405798616", - "sha256:980710797ff6a041e9a73a5787804f848996ecaa6f8a1b1e08224a5894f2074a" + "sha256:19ecf9ce9db2fce065a7a0586e07cfb4ac8614fe96edf628a264b1c70116cf8f", + "sha256:84d306a647cc805219916e62aab89caa97a33a1dd8c342e87a37f91073cd4746" ], - "version": "==0.8.1" + "version": "==0.9.0" }, "py": { "hashes": [ - "sha256:bf92637198836372b520efcba9e020c330123be8ce527e535d185ed4b6f45694", - "sha256:e76826342cefe3c3d5f7e8ee4316b80d1dd8a300781612ddbc765c17ba25a6c6" + "sha256:64f65755aee5b381cea27766a3a147c3f15b9b6b9ac88676de66ba2ae36793fa", + "sha256:dc639b046a6e2cff5bbe40194ad65936d6ba360b52b3c3fe1d08a82dd50b5e53" ], - "version": "==1.7.0" + "version": "==1.8.0" }, "pydocstyle": { "hashes": [ - "sha256:2258f9b0df68b97bf3a6c29003edc5238ff8879f1efb6f1999988d934e432bd8", - "sha256:5741c85e408f9e0ddf873611085e819b809fca90b619f5fd7f34bd4959da3dd4", - "sha256:ed79d4ec5e92655eccc21eb0c6cf512e69512b4a97d215ace46d17e4990f2039" + "sha256:08a870edc94508264ed90510db466c6357c7192e0e866561d740624a8fc7d90c", + "sha256:4d5bcde961107873bae621f3d580c3e35a426d3687ffc6f8fb356f6628da5a97", + "sha256:af9fcccb303899b83bec82dc9a1d56c60fc369973223a5e80c3dfa9bdf984405" ], "index": "pypi", - "version": "==3.0.0" - }, - "pygments": { - "hashes": [ - "sha256:5ffada19f6203563680669ee7f53b64dabbeb100eb51b61996085e99c03b284a", - "sha256:e8218dd399a61674745138520d0d4cf2621d7e032439341bc3f647bff125818d" - ], - "version": "==2.3.1" + "version": "==2.1.1" }, "pylint": { "hashes": [ - "sha256:689de29ae747642ab230c6d37be2b969bf75663176658851f456619aacf27492", - "sha256:771467c434d0d9f081741fec1d64dfb011ed26e65e12a28fe06ca2f61c4d556c" + "sha256:daa2dfc3aec7252e5d5c00cb5fb2bfc8a4d43c593f8e58366fb43dc2b13f3ec3", + "sha256:fea08b65e41a13f31133f04af57e103d52c3cca06f044468e0ec53140c18f95a" ], "index": "pypi", - "version": "==2.2.2" - }, - "pyparsing": { - "hashes": [ - "sha256:66c9268862641abcac4a96ba74506e594c884e3f57690a696d21ad8210ed667a", - "sha256:f6c5ef0d7480ad048c054c37632c67fca55299990fff127850181659eea33fc3" - ], - "version": "==2.3.1" + "version": "==2.3.0.dev2" }, "pytest": { "hashes": [ - "sha256:65aeaa77ae87c7fc95de56285282546cfa9c886dc8e5dc78313db1c25e21bc07", - "sha256:6ac6d467d9f053e95aaacd79f831dbecfe730f419c6c7022cb316b365cd9199d" + "sha256:067a1d4bf827ffdd56ad21bd46674703fce77c5957f6c1eef731f6146bfcef1c", + "sha256:9687049d53695ad45cf5fdc7bbd51f0c49f1ea3ecfc4b7f3fde7501b541f17f4" ], "index": "pypi", - "version": "==4.2.0" + "version": "==4.3.0" }, "pytest-cov": { "hashes": [ @@ -809,13 +694,6 @@ "index": "pypi", "version": "==2.6.1" }, - "pytz": { - "hashes": [ - "sha256:32b0891edff07e28efe91284ed9c31e123d84bea3fd98e1f72be2508f43ef8d9", - "sha256:d5f05e487007e29e03409f9398d074e158d920d36eb82eaf66fb1136b0c5374c" - ], - "version": "==2018.9" - }, "requests": { "hashes": [ "sha256:99dcfdaaeb17caf6e526f32b6a7b780461512ab3f1d992187801694cba42770c", @@ -838,60 +716,37 @@ ], "version": "==1.2.1" }, - "sphinx": { - "hashes": [ - "sha256:429e3172466df289f0f742471d7e30ba3ee11f3b5aecd9a840480d03f14bcfe5", - "sha256:c4cb17ba44acffae3d3209646b6baec1e215cad3065e852c68cc569d4df1b9f8" - ], - "index": "pypi", - "version": "==1.8.3" - }, - "sphinx-autodoc-typehints": { - "hashes": [ - "sha256:19fe0b426b7c008181f67f816060da7f046bd8a42723f67a685d26d875bcefd7", - "sha256:f9c06acfec80766fe8f542a6d6a042e751fcf6ce2e2711a7dc00d8b6daf8aa36" - ], - "index": "pypi", - "version": "==1.6.0" - }, - "sphinxcontrib-websupport": { - "hashes": [ - "sha256:68ca7ff70785cbe1e7bccc71a48b5b6d965d79ca50629606c7861a21b206d9dd", - "sha256:9de47f375baf1ea07cdb3436ff39d7a9c76042c10a769c52353ec46e4e8fc3b9" - ], - "version": "==1.1.0" - }, "typed-ast": { "hashes": [ - "sha256:023625bfa9359e29bd6e24cac2a4503495b49761d48a5f1e38333fc4ac4d93fe", - "sha256:07591f7a5fdff50e2e566c4c1e9df545c75d21e27d98d18cb405727ed0ef329c", - "sha256:153e526b0f4ffbfada72d0bb5ffe8574ba02803d2f3a9c605c8cf99dfedd72a2", - "sha256:3ad2bdcd46a4a1518d7376e9f5016d17718a9ed3c6a3f09203d832f6c165de4a", - "sha256:3ea98c84df53ada97ee1c5159bb3bc784bd734231235a1ede14c8ae0775049f7", - "sha256:51a7141ccd076fa561af107cfb7a8b6d06a008d92451a1ac7e73149d18e9a827", - "sha256:52c93cd10e6c24e7ac97e8615da9f224fd75c61770515cb323316c30830ddb33", - "sha256:6344c84baeda3d7b33e157f0b292e4dd53d05ddb57a63f738178c01cac4635c9", - "sha256:64699ca1b3bd5070bdeb043e6d43bc1d0cebe08008548f4a6bee782b0ecce032", - "sha256:74903f2e56bbffe29282ef8a5487d207d10be0f8513b41aff787d954a4cf91c9", - "sha256:7891710dba83c29ee2bd51ecaa82f60f6bede40271af781110c08be134207bf2", - "sha256:91976c56224e26c256a0de0f76d2004ab885a29423737684b4f7ebdd2f46dde2", - "sha256:9bad678a576ecc71f25eba9f1e3fd8d01c28c12a2834850b458428b3e855f062", - "sha256:b4726339a4c180a8b6ad9d8b50d2b6dc247e1b79b38fe2290549c98e82e4fd15", - "sha256:ba36f6aa3f8933edf94ea35826daf92cbb3ec248b89eccdc053d4a815d285357", - "sha256:bbc96bde544fd19e9ef168e4dfa5c3dfe704bfa78128fa76f361d64d6b0f731a", - "sha256:c0c927f1e44469056f7f2dada266c79b577da378bbde3f6d2ada726d131e4824", - "sha256:c0f9a3708008aa59f560fa1bd22385e05b79b8e38e0721a15a8402b089243442", - "sha256:f0bf6f36ff9c5643004171f11d2fdc745aa3953c5aacf2536a0685db9ceb3fb1", - "sha256:f5be39a0146be663cbf210a4d95c3c58b2d7df7b043c9047c5448e358f0550a2", - "sha256:fcd198bf19d9213e5cbf2cde2b9ef20a9856e716f76f9476157f90ae6de06cc6" - ], - "version": "==1.2.0" + "sha256:035a54ede6ce1380599b2ce57844c6554666522e376bd111eb940fbc7c3dad23", + "sha256:037c35f2741ce3a9ac0d55abfcd119133cbd821fffa4461397718287092d9d15", + "sha256:049feae7e9f180b64efacbdc36b3af64a00393a47be22fa9cb6794e68d4e73d3", + "sha256:19228f7940beafc1ba21a6e8e070e0b0bfd1457902a3a81709762b8b9039b88d", + "sha256:2ea681e91e3550a30c2265d2916f40a5f5d89b59469a20f3bad7d07adee0f7a6", + "sha256:3a6b0a78af298d82323660df5497bcea0f0a4a25a0b003afd0ce5af049bd1f60", + "sha256:5385da8f3b801014504df0852bf83524599df890387a3c2b17b7caa3d78b1773", + "sha256:606d8afa07eef77280c2bf84335e24390055b478392e1975f96286d99d0cb424", + "sha256:69245b5b23bbf7fb242c9f8f08493e9ecd7711f063259aefffaeb90595d62287", + "sha256:6f6d839ab09830d59b7fa8fb6917023d8cb5498ee1f1dbd82d37db78eb76bc99", + "sha256:730888475f5ac0e37c1de4bd05eeb799fdb742697867f524dc8a4cd74bcecc23", + "sha256:9819b5162ffc121b9e334923c685b0d0826154e41dfe70b2ede2ce29034c71d8", + "sha256:9e60ef9426efab601dd9aa120e4ff560f4461cf8442e9c0a2b92548d52800699", + "sha256:af5fbdde0690c7da68e841d7fc2632345d570768ea7406a9434446d7b33b0ee1", + "sha256:b64efdbdf3bbb1377562c179f167f3bf301251411eb5ac77dec6b7d32bcda463", + "sha256:bac5f444c118aeb456fac1b0b5d14c6a71ea2a42069b09c176f75e9bd4c186f6", + "sha256:bda9068aafb73859491e13b99b682bd299c1b5fd50644d697533775828a28ee0", + "sha256:d659517ca116e6750101a1326107d3479028c5191f0ecee3c7203c50f5b915b0", + "sha256:eddd3fb1f3e0f82e5915a899285a39ee34ce18fd25d89582bc89fc9fb16cd2c6" + ], + "markers": "python_version < '3.7' and implementation_name == 'cpython'", + "version": "==1.3.1" }, "urllib3": { "hashes": [ "sha256:61bf29cada3fc2fbefad4fdf059ea4bd1b4a86d2b6d15e1c7c0b582b9752fe39", "sha256:de9529817c93f27c8ccbfead6985011db27bd0ddfcdb2d86f3f663385c6a9c22" ], + "markers": "python_version >= '3.4'", "version": "==1.24.1" }, "wrapt": { diff --git a/README.md b/README.md index 370119be..7a5b16bb 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,13 @@ TLS is considered an infrastructure concern, and is therefore out of scope - Clean up and document authenticator service. - Fuzz testing registration? +## Updates + +- Starting with v0.3.1, set ``AUTH_UPDATED_SESSION_REF=True`` in your + application config to rename ``request.session`` to ``request.auth``. + ``request.auth`` will be the default name for the authenticated session + starting in v0.4.1. + ## Dependencies We use pipenv to manage dependencies. To install the dependencies for this diff --git a/users/arxiv/users/auth/__init__.py b/users/arxiv/users/auth/__init__.py index 36eb0210..6867bf10 100644 --- a/users/arxiv/users/auth/__init__.py +++ b/users/arxiv/users/auth/__init__.py @@ -2,6 +2,7 @@ from typing import Optional, Union from datetime import datetime +import warnings from pytz import UTC from flask import Flask, request, Response, make_response, redirect, url_for from werkzeug.http import parse_cookie @@ -121,7 +122,19 @@ def load_session(self) -> None: # Attach the session to the request so that other # components can access it easily. - request.session = session + if self.app.config.get('AUTH_UPDATED_SESSION_REF'): + request.auth = session + else: + # This clobbers the built-in Flask session interface. This is a + # design flaw that's blocking other work. This is deprecated and + # will be removed in 0.4.1. + warnings.warn( + "Accessing the authenticated session via request.session is" + " deprecated, and will be removed in 0.4.1. Use request.auth" + " instead. ARXIVNG-1920.", + DeprecationWarning + ) + request.session = session def detect_and_clobber_dupe_cookies(self) -> Optional[Response]: """ diff --git a/users/arxiv/users/auth/tests/test_decorators.py b/users/arxiv/users/auth/tests/test_decorators.py index aa8147b6..8c9fefaa 100644 --- a/users/arxiv/users/auth/tests/test_decorators.py +++ b/users/arxiv/users/auth/tests/test_decorators.py @@ -79,6 +79,29 @@ def protected(): with self.assertRaises(Forbidden): protected() + @mock.patch(f'{decorators.__name__}.request') + def test_scope_is_present(self, mock_request): + """Session has required scope.""" + mock_request.session = domain.Session( + session_id='fooid', + start_time=datetime.now(tz=UTC), + user=domain.User( + user_id='235678', + email='foo@foo.com', + username='foouser' + ), + authorizations=domain.Authorizations( + scopes=[scopes.VIEW_SUBMISSION, scopes.CREATE_SUBMISSION] + ) + ) + + @decorators.scoped(scopes.CREATE_SUBMISSION) + def protected(): + """A protected function.""" + + # with self.assertRaises(Forbidden): + protected() + @mock.patch(f'{decorators.__name__}.request') def test_user_and_client_are_missing(self, mock_request): """Session does not user nor client information.""" diff --git a/users/arxiv/users/auth/tests/test_extension.py b/users/arxiv/users/auth/tests/test_extension.py index 83b4352d..83c87eff 100644 --- a/users/arxiv/users/auth/tests/test_extension.py +++ b/users/arxiv/users/auth/tests/test_extension.py @@ -57,10 +57,49 @@ def test_legacy_is_valid(self, mock_request, mock_legacy): mock_legacy.sessions.load.return_value = session inst = auth.Auth(mock_app) - inst.load_session() + # ARXIVNG-1920 using request.session is deprecated. + with self.assertWarns(DeprecationWarning): + inst.load_session() self.assertEqual(mock_request.session, session, "Session is attached to the request") + @mock.patch(f'{auth.__name__}.legacy') + @mock.patch(f'{auth.__name__}.request') + def test_auth_session_rename(self, mock_request, mock_legacy): + """ + The auth session is accessed via ``request.auth``. + + Per ARXIVNG-1920 using ``request.session`` is deprecated. + """ + mock_request.environ = {'session': None} + mock_request.cookies = {'foo_cookie': 'sessioncookie123'} + mock_app = mock.MagicMock( + config={'CLASSIC_COOKIE_NAME': 'foo_cookie', + 'AUTH_UPDATED_SESSION_REF': True} + ) + mock_request.session = None + mock_request.auth = None + mock_legacy.is_configured.return_value = True + session = domain.Session( + session_id='fooid', + start_time=datetime.now(tz=UTC), + user=domain.User( + user_id='235678', + email='foo@foo.com', + username='foouser' + ), + authorizations=domain.Authorizations( + scopes=[auth.scopes.VIEW_SUBMISSION] + ) + ) + mock_legacy.sessions.load.return_value = session + + inst = auth.Auth(mock_app) + inst.load_session() + self.assertEqual(mock_request.auth, session, + "Session is attached to the request") + self.assertIsNone(mock_request.session, "request.session is not set") + @mock.patch(f'{auth.__name__}.request') def test_middleware_exception(self, mock_request): """Middleware has passed an exception.""" diff --git a/users/arxiv/users/helpers.py b/users/arxiv/users/helpers.py index 911c0095..d30f94a1 100644 --- a/users/arxiv/users/helpers.py +++ b/users/arxiv/users/helpers.py @@ -6,6 +6,7 @@ import uuid from datetime import timedelta, datetime from arxiv.users import auth, domain +from arxiv.base.globals import get_application_config def generate_token(user_id: str, email: str, username: str, @@ -19,7 +20,8 @@ def generate_token(user_id: str, email: str, username: str, ), submission_groups: str = 'grp_physics', endorsements: List[domain.Category] = [], - scope: List[domain.Scope] = []) -> None: + scope: List[domain.Scope] = [], + verified: bool = False) -> None: """Generate an auth token for dev/testing purposes.""" # Specify the validity period for the session. start = datetime.now(tz=timezone('US/Eastern')) @@ -40,10 +42,11 @@ def generate_token(user_id: str, email: str, username: str, country=country, default_category=default_category, submission_groups=submission_groups.split(',') - ) + ), + verified=verified ), - authorizations=domain.Authorizations(scopes=scope, + authorizations=domain.Authorizations(scopes=[str(s) for s in scope], endorsements=endorsements) ) - token = auth.tokens.encode(session, os.environ['JWT_SECRET']) + token = auth.tokens.encode(session, get_application_config()['JWT_SECRET']) return token diff --git a/users/arxiv/users/tests/test_helpers.py b/users/arxiv/users/tests/test_helpers.py new file mode 100644 index 00000000..17237088 --- /dev/null +++ b/users/arxiv/users/tests/test_helpers.py @@ -0,0 +1,43 @@ +"""Tests for :mod:`.helpers`.""" + +from unittest import TestCase, mock +import os +from flask import Flask +from arxiv import status +from arxiv.base import Base +from arxiv.base.middleware import wrap +from .. import auth, helpers + + +class TestGenerateToken(TestCase): + """Tests for :func:`.helpers.generate_token`.""" + + @mock.patch(f'{helpers.__name__}.get_application_config') + def test_token_is_usable(self, mock_get_config): + """Verify that :func:`.helpers.generate_token` makes usable tokens.""" + mock_get_config.return_value = {'JWT_SECRET': 'thesecret'} + os.environ['JWT_SECRET'] = 'thesecret' + scope = [auth.scopes.VIEW_SUBMISSION, auth.scopes.EDIT_SUBMISSION, + auth.scopes.CREATE_SUBMISSION] + token = helpers.generate_token("1234", "user@foo.com", "theuser", + scope=scope) + + app = Flask('test') + app.config['JWT_SECRET'] = 'thesecret' + Base(app) + auth.Auth(app) # <- Install the Auth extension. + wrap(app, [auth.middleware.AuthMiddleware]) # <- Install middleware. + + @app.route('/') + @auth.decorators.scoped(auth.scopes.EDIT_SUBMISSION) + def protected(): + return "this is protected" + + client = app.test_client() + with app.app_context(): + response = client.get('/') + self.assertEqual(response.status_code, + status.HTTP_401_UNAUTHORIZED) + + response = client.get('/', headers={'Authorization': token}) + self.assertEqual(response.status_code, status.HTTP_200_OK) diff --git a/users/setup.py b/users/setup.py index b167d529..4144b8bb 100644 --- a/users/setup.py +++ b/users/setup.py @@ -4,7 +4,7 @@ setup( name='arxiv-auth', - version='0.2.7', + version='0.3.1', packages=[f'arxiv.{package}' for package in find_packages('./arxiv', exclude=['*test*'])], install_requires=[