diff --git a/.pylintrc b/.pylintrc index 8484c1697..2c9222f7f 100644 --- a/.pylintrc +++ b/.pylintrc @@ -1,6 +1,6 @@ [MASTER] -disable=redefined-outer-name,arguments-differ,no-self-use,cyclic-import,fixme,locally-disabled,unpacking-non-sequence,too-many-ancestors,too-many-branches,too-few-public-methods +disable=redefined-outer-name,arguments-differ,no-self-use,cyclic-import,fixme,locally-disabled,unpacking-non-sequence,too-many-ancestors,too-many-branches,too-few-public-methods,import-outside-toplevel load-plugins=pylint_django,pylint.extensions.bad_builtin extension-pkg-whitelist=lxml const-rgx=[a-zA-Z0-9_]{1,40}$ diff --git a/Pipfile b/Pipfile index 6e33fb799..d87f95786 100644 --- a/Pipfile +++ b/Pipfile @@ -23,7 +23,7 @@ django-rest-framework = "*" django-storages = "*" djangorestframework-guardian = "*" drf-yasg = "*" -kombu = "==4.5.0" +kombu = "*" ldap3 = "*" lxml = "*" oauthlib = "*" @@ -53,6 +53,6 @@ coverage = "*" django-debug-toolbar = "*" isort = "*" prospector = "*" -pylint = "==2.3.1" +pylint = "*" pylint-django = "*" unittest-xml-reporting = "*" diff --git a/Pipfile.lock b/Pipfile.lock index 1c6398252..7ce5fb84e 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "865b57ef5ef326de114d39d8505f60f19b5f7e42a50d988ea3fc9dfc9b9371ec" + "sha256": "5d1d5f5f9664ce6ffb10e89d3780c9e04d4f8f372129baaf3293e44432a2f16d" }, "pipfile-spec": 6, "requires": { @@ -46,26 +46,26 @@ }, "boto3": { "hashes": [ - "sha256:d280f2bf7dc373e8aeab296f81aadefabf8780ff8c8ad27cdc36f8f112ca95ed", - "sha256:edbf4636e700c46e49f555ac87ab48b8c385fde604528db15fc5189d5a73dc72" + "sha256:982823e7c992d27e5954c81db93238ffc42c7a1210d863b4f5e048fdc088040e", + "sha256:f05ee90a738c2f1ec8088121030229f26ef6a809fb9a1338de2118fd088dd99a" ], "index": "pypi", - "version": "==1.10.33" + "version": "==1.10.45" }, "botocore": { "hashes": [ - "sha256:4861785b52b0b3f97da91613c31f8e501f12517c9c79482b44efbdb56b69aefc", - "sha256:9cc87d7906693c9c8fe862c574a1bebbe22a0475d6991e9b7251bc93cb1954d9" + "sha256:88ee646f7a0fe6a418681c6f119a590fae23d8439c48c2aec6878f7f89430b1f", + "sha256:f48ba1ef04b25323c1d27fa6399795baa0ca9d316911b87be4d33acda5cef07c" ], - "version": "==1.13.33" + "version": "==1.13.45" }, "celery": { "hashes": [ - "sha256:4c4532aa683f170f40bd76f928b70bc06ff171a959e06e71bf35f2f9d6031ef9", - "sha256:528e56767ae7e43a16cfef24ee1062491f5754368d38fcfffa861cdb9ef219be" + "sha256:7c544f37a84a5eadc44cab1aa8c9580dff94636bb81978cdf9bf8012d9ea7d8f", + "sha256:d3363bb5df72d74420986a435449f3c3979285941dff57d5d97ecba352a0e3e2" ], "index": "pypi", - "version": "==4.3.0" + "version": "==4.4.0" }, "certifi": { "hashes": [ @@ -169,19 +169,19 @@ }, "django": { "hashes": [ - "sha256:a4ad4f6f9c6a4b7af7e2deec8d0cbff28501852e5010d6c2dc695d3d1fae7ca0", - "sha256:fa98ec9cc9bf5d72a08ebf3654a9452e761fbb8566e3f80de199cbc15477e891" + "sha256:662a1ff78792e3fd77f16f71b1f31149489434de4b62a74895bd5d6534e635a5", + "sha256:687c37153486cf26c3fdcbdd177ef16de38dc3463f094b5f9c9955d91f277b14" ], "index": "pypi", - "version": "==2.2.8" + "version": "==2.2.9" }, "django-cors-middleware": { "hashes": [ - "sha256:85904a3401e7bc0c86502ff2b01d726917af3aaa7dafb77799b27ace637e8c92", - "sha256:bca8888ed33a94ba5472bde37ed71ec3d08231d6817fd4d799296b016073da95" + "sha256:5bbdea85e22909d596e26f6e0dbc174d5521429fa3943ae02a2c6c48e76c88c7", + "sha256:856dbe4d7aae65844ccc68acb49c6da7dbf7cbacaf5bcf37019f4c0c60b3be84" ], "index": "pypi", - "version": "==1.4.0" + "version": "==1.5.0" }, "django-dbbackup": { "hashes": [ @@ -208,11 +208,11 @@ }, "django-model-utils": { "hashes": [ - "sha256:3f130a262e45d73e0950d2be76af4bf4ee86804dd60e5f90afc5cd948fcfe760", - "sha256:682f58c1de330cedcda58cc85d5232c5b47a9e2cb67bef4541fb43fdaeb18e96" + "sha256:9cf882e5b604421b62dbe57ad2b18464dc9c8f963fc3f9831badccae66c1139c", + "sha256:adf09e5be15122a7f4e372cb5a6dd512bbf8d78a23a90770ad0983ee9d909061" ], "index": "pypi", - "version": "==3.2.0" + "version": "==4.0.0" }, "django-oauth-toolkit": { "hashes": [ @@ -230,11 +230,11 @@ }, "django-otp": { "hashes": [ - "sha256:1b6025bbbd2517b7c246828b1d11c83d53567904836ae6d57bc0058f3cd18b50", - "sha256:76a698466178ce40473726ffd8c33f68d1c47f27c53f67fa4aeeb6fdde74d37b" + "sha256:1f16c2b93fe484706ff16ac6f5e64ecc73dd240318c333e0560384ba548d3837", + "sha256:cd4975539be478417033561e9832a1a69a583189f680e92a649f412c661f90aa" ], "index": "pypi", - "version": "==0.7.4" + "version": "==0.7.5" }, "django-prometheus": { "hashes": [ @@ -254,11 +254,11 @@ }, "django-redis": { "hashes": [ - "sha256:af0b393864e91228dd30d8c85b5c44d670b5524cb161b7f9e41acc98b6e5ace7", - "sha256:f46115577063d00a890867c6964ba096057f07cb756e78e0503b89cd18e4e083" + "sha256:a5b1e3ffd3198735e6c529d9bdf38ca3fcb3155515249b98dc4d966b8ddf9d2b", + "sha256:e1aad4cc5bd743d8d0b13d5cae0cef5410eaace33e83bff5fc3a139ad8db50b4" ], "index": "pypi", - "version": "==4.10.0" + "version": "==4.11.0" }, "django-rest-framework": { "hashes": [ @@ -277,10 +277,10 @@ }, "djangorestframework": { "hashes": [ - "sha256:5488aed8f8df5ec1d70f04b2114abc52ae6729748a176c453313834a9ee179c8", - "sha256:dc81cbf9775c6898a580f6f1f387c4777d12bd87abf0f5406018d32ccae71090" + "sha256:05809fc66e1c997fd9a32ea5730d9f4ba28b109b9da71fccfa5ff241201fd0a4", + "sha256:e782087823c47a26826ee5b6fa0c542968219263fb3976ec3c31edab23a4001f" ], - "version": "==3.10.3" + "version": "==3.11.0" }, "djangorestframework-guardian": { "hashes": [ @@ -328,11 +328,11 @@ }, "importlib-metadata": { "hashes": [ - "sha256:3a8b2dfd0a2c6a3636e7c016a7e54ae04b997d30e69d5eacdca7a6c2221a1402", - "sha256:41e688146d000891f32b1669e8573c57e39e5060e7f5f647aa617cd9a9568278" + "sha256:073a852570f92da5f744a3472af1b61e28e9f78ccf0c9117658dc32b15de7b45", + "sha256:d95141fbfa7ef2ec65cfd945e2af7e5a6ddbd7c8d9a25e66ff3be8e3daf9f60f" ], "markers": "python_version < '3.8'", - "version": "==1.2.0" + "version": "==1.3.0" }, "inflection": { "hashes": [ @@ -369,11 +369,11 @@ }, "kombu": { "hashes": [ - "sha256:389ba09e03b15b55b1a7371a441c894fd8121d174f5583bbbca032b9ea8c9edd", - "sha256:7b92303af381ef02fad6899fd5f5a9a96031d781356cd8e505fa54ae5ddee181" + "sha256:2a9e7adff14d046c9996752b2c48b6d9185d0b992106d5160e1a179907a5d4ac", + "sha256:67b32ccb6fea030f8799f8fd50dd08e03a4b99464ebc4952d71d8747b1a52ad1" ], "index": "pypi", - "version": "==4.5.0" + "version": "==4.6.7" }, "ldap3": { "hashes": [ @@ -450,10 +450,10 @@ }, "more-itertools": { "hashes": [ - "sha256:53ff73f186307d9c8ef17a9600309154a6ae27f25579e80af4db8f047ba14bc2", - "sha256:a0ea684c39bc4315ba7aae406596ef191fd84f873d2d2751f84d64e81a7a2d45" + "sha256:b84b238cce0d9adad5ed87e745778d20a3f8487d0f0cb8b8a586816c7496458d", + "sha256:c833ef592a0324bcc6a60e48440da07645063c453880c9477ceb22490aec1564" ], - "version": "==8.0.0" + "version": "==8.0.2" }, "oauthlib": { "hashes": [ @@ -625,10 +625,10 @@ }, "pyparsing": { "hashes": [ - "sha256:20f995ecd72f2a1f4bf6b072b63b22e2eb457836601e76d6e5dfcd75436acc1f", - "sha256:4ca62001be367f01bd3e92ecbb79070272a9d4964dce6a48a82ff0b8bc7e683a" + "sha256:4c830582a84fb022400b85429791bc551f1f4871c33f23e44f353119e92f969f", + "sha256:c342dccb5250c08d45fd6f8b4a559613ca603b57498511740e65cd11a2e7dcec" ], - "version": "==2.4.5" + "version": "==2.4.6" }, "pyrsistent": { "hashes": [ @@ -638,11 +638,11 @@ }, "python-dateutil": { "hashes": [ - "sha256:7e6584c74aeed623791615e26efd690f29817a27c73085b78e4bad02493df2fb", - "sha256:c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e" + "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c", + "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a" ], "markers": "python_version >= '2.7'", - "version": "==2.8.0" + "version": "==2.8.1" }, "pytz": { "hashes": [ @@ -752,6 +752,7 @@ "sha256:a0ff786d2a7dbe55f9544b3f6ebbcc495d7e730df92a08434604f6f470b899c5", "sha256:b1b7fcee6aedcdc7e62c3a73f238b3d080c7ba6650cd808bce8d7761ec484070", "sha256:b66832ea8077d9b3f6e311c4a53d06273db5dc2db6e8a908550f3c14d67e718c", + "sha256:be018933c2f4ee7de55e7bd7d0d801b3dfb09d21dad0cce8a97995fd3e44be30", "sha256:d0d3ac228c9bbab08134b4004d748cf9f8743504875b3603b3afbb97e3472947", "sha256:d10e9dd744cf85c219bf747c75194b624cc7a94f0c80ead624b06bfa9f61d3bc", "sha256:ea4362548ee0cbc266949d8a441238d9ad3600ca9910c3fe4e82ee3a50706973", @@ -770,11 +771,11 @@ }, "sentry-sdk": { "hashes": [ - "sha256:a7c2c8d3f53b6b57454830cd6a4b73d272f1ba91952f59e6545b3cf885f3c22f", - "sha256:bfc486af718c268cf49ff43d6334ed4db7333ace420240b630acdd8f8a3a8f60" + "sha256:05285942901d38c7ce2498aba50d8e87b361fc603281a5902dda98f3f8c5e145", + "sha256:c6b919623e488134a728f16326c6f0bcdab7e3f59e7f4c472a90eea4d6d8fe82" ], "index": "pypi", - "version": "==0.13.4" + "version": "==0.13.5" }, "service-identity": { "hashes": [ @@ -824,11 +825,10 @@ }, "uritemplate": { "hashes": [ - "sha256:01c69f4fe8ed503b2951bef85d996a9d22434d2431584b5b107b2981ff416fbd", - "sha256:1b9c467a940ce9fb9f50df819e8ddd14696f89b9a8cc87ac77952ba416e0a8fd", - "sha256:c02643cebe23fc8adb5e6becffe201185bf06c40bda5c0b4028a93f1527d011d" + "sha256:07620c3f3f8eed1f12600845892b0e036a2420acf513c53f7de0abd911a5894f", + "sha256:5af8ad10cec94f215e3f48112de2022e1d5a37ed427fbd88652fa908f2ab7cae" ], - "version": "==3.0.0" + "version": "==3.0.1" }, "urllib3": { "extras": [ @@ -867,10 +867,10 @@ }, "astroid": { "hashes": [ - "sha256:6560e1e1749f68c64a4b5dee4e091fce798d2f0d84ebe638cf0e0585a343acf4", - "sha256:b65db1bbaac9f9f4d190199bb8680af6f6f84fd3769a5ea883df8a91fe68b4c4" + "sha256:71ea07f44df9568a75d0f354c49143a4575d90645e9fead6dfb52c26a85ed13a", + "sha256:840947ebfa8b58f318d42301cf8c0a20fd794a33b61cc4638e28e9e61ba32f42" ], - "version": "==2.2.5" + "version": "==2.3.3" }, "autopep8": { "hashes": [ @@ -897,57 +897,56 @@ }, "colorama": { "hashes": [ - "sha256:05eed71e2e327246ad6b38c540c4a3117230b19679b875190486ddd2d721422d", - "sha256:f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48" + "sha256:7d73d2a99753107a36ac6b455ee49046802e59d9d076ef8e47b61499fa29afff", + "sha256:e96da0d330793e2cb9485e9ddfd918d456036c7149416295932478192f4436a1" ], "index": "pypi", - "version": "==0.4.1" + "version": "==0.4.3" }, "coverage": { "hashes": [ - "sha256:08907593569fe59baca0bf152c43f3863201efb6113ecb38ce7e97ce339805a6", - "sha256:0be0f1ed45fc0c185cfd4ecc19a1d6532d72f86a2bac9de7e24541febad72650", - "sha256:141f08ed3c4b1847015e2cd62ec06d35e67a3ac185c26f7635f4406b90afa9c5", - "sha256:19e4df788a0581238e9390c85a7a09af39c7b539b29f25c89209e6c3e371270d", - "sha256:23cc09ed395b03424d1ae30dcc292615c1372bfba7141eb85e11e50efaa6b351", - "sha256:245388cda02af78276b479f299bbf3783ef0a6a6273037d7c60dc73b8d8d7755", - "sha256:331cb5115673a20fb131dadd22f5bcaf7677ef758741312bee4937d71a14b2ef", - "sha256:386e2e4090f0bc5df274e720105c342263423e77ee8826002dcffe0c9533dbca", - "sha256:3a794ce50daee01c74a494919d5ebdc23d58873747fa0e288318728533a3e1ca", - "sha256:60851187677b24c6085248f0a0b9b98d49cba7ecc7ec60ba6b9d2e5574ac1ee9", - "sha256:63a9a5fc43b58735f65ed63d2cf43508f462dc49857da70b8980ad78d41d52fc", - "sha256:6b62544bb68106e3f00b21c8930e83e584fdca005d4fffd29bb39fb3ffa03cb5", - "sha256:6ba744056423ef8d450cf627289166da65903885272055fb4b5e113137cfa14f", - "sha256:7494b0b0274c5072bddbfd5b4a6c6f18fbbe1ab1d22a41e99cd2d00c8f96ecfe", - "sha256:826f32b9547c8091679ff292a82aca9c7b9650f9fda3e2ca6bf2ac905b7ce888", - "sha256:93715dffbcd0678057f947f496484e906bf9509f5c1c38fc9ba3922893cda5f5", - "sha256:9a334d6c83dfeadae576b4d633a71620d40d1c379129d587faa42ee3e2a85cce", - "sha256:af7ed8a8aa6957aac47b4268631fa1df984643f07ef00acd374e456364b373f5", - "sha256:bf0a7aed7f5521c7ca67febd57db473af4762b9622254291fbcbb8cd0ba5e33e", - "sha256:bf1ef9eb901113a9805287e090452c05547578eaab1b62e4ad456fcc049a9b7e", - "sha256:c0afd27bc0e307a1ffc04ca5ec010a290e49e3afbe841c5cafc5c5a80ecd81c9", - "sha256:dd579709a87092c6dbee09d1b7cfa81831040705ffa12a1b248935274aee0437", - "sha256:df6712284b2e44a065097846488f66840445eb987eb81b3cc6e4149e7b6982e1", - "sha256:e07d9f1a23e9e93ab5c62902833bf3e4b1f65502927379148b6622686223125c", - "sha256:e2ede7c1d45e65e209d6093b762e98e8318ddeff95317d07a27a2140b80cfd24", - "sha256:e4ef9c164eb55123c62411f5936b5c2e521b12356037b6e1c2617cef45523d47", - "sha256:eca2b7343524e7ba246cab8ff00cab47a2d6d54ada3b02772e908a45675722e2", - "sha256:eee64c616adeff7db37cc37da4180a3a5b6177f5c46b187894e633f088fb5b28", - "sha256:ef824cad1f980d27f26166f86856efe11eff9912c4fed97d3804820d43fa550c", - "sha256:efc89291bd5a08855829a3c522df16d856455297cf35ae827a37edac45f466a7", - "sha256:fa964bae817babece5aa2e8c1af841bebb6d0b9add8e637548809d040443fee0", - "sha256:ff37757e068ae606659c28c3bd0d923f9d29a85de79bf25b2b34b148473b5025" + "sha256:0101888bd1592a20ccadae081ba10e8b204d20235d18d05c6f7d5e904a38fc10", + "sha256:04b961862334687549eb91cd5178a6fbe977ad365bddc7c60f2227f2f9880cf4", + "sha256:1ca43dbd739c0fc30b0a3637a003a0d2c7edc1dd618359d58cc1e211742f8bd1", + "sha256:1cbb88b34187bdb841f2599770b7e6ff8e259dc3bb64fc7893acf44998acf5f8", + "sha256:232f0b52a5b978288f0bbc282a6c03fe48cd19a04202df44309919c142b3bb9c", + "sha256:24bcfa86fd9ce86b73a8368383c39d919c497a06eebb888b6f0c12f13e920b1a", + "sha256:25b8f60b5c7da71e64c18888f3067d5b6f1334b9681876b2fb41eea26de881ae", + "sha256:2714160a63da18aed9340c70ed514973971ee7e665e6b336917ff4cca81a25b1", + "sha256:2ca2cd5264e84b2cafc73f0045437f70c6378c0d7dbcddc9ee3fe192c1e29e5d", + "sha256:2cc707fc9aad2592fc686d63ef72dc0031fc98b6fb921d2f5395d9ab84fbc3ef", + "sha256:348630edea485f4228233c2f310a598abf8afa5f8c716c02a9698089687b6085", + "sha256:40fbfd6b044c9db13aeec1daf5887d322c710d811f944011757526ef6e323fd9", + "sha256:46c9c6a1d1190c0b75ec7c0f339088309952b82ae8d67a79ff1319eb4e749b96", + "sha256:591506e088901bdc25620c37aec885e82cc896528f28c57e113751e3471fc314", + "sha256:5ac71bba1e07eab403b082c4428f868c1c9e26a21041436b4905c4c3d4e49b08", + "sha256:5f622f19abda4e934938e24f1d67599249abc201844933a6f01aaa8663094489", + "sha256:65bead1ac8c8930cf92a1ccaedcce19a57298547d5d1db5c9d4d068a0675c38b", + "sha256:7362a7f829feda10c7265b553455de596b83d1623b3d436b6d3c51c688c57bf6", + "sha256:7f2675750c50151f806070ec11258edf4c328340916c53bac0adbc465abd6b1e", + "sha256:960d7f42277391e8b1c0b0ae427a214e1b31a1278de6b73f8807b20c2e913bba", + "sha256:a50b0888d8a021a3342d36a6086501e30de7d840ab68fca44913e97d14487dc1", + "sha256:b7dbc5e8c39ea3ad3db22715f1b5401cd698a621218680c6daf42c2f9d36e205", + "sha256:bb3d29df5d07d5399d58a394d0ef50adf303ab4fbf66dfd25b9ef258effcb692", + "sha256:c0fff2733f7c2950f58a4fd09b5db257b00c6fec57bf3f68c5bae004d804b407", + "sha256:c792d3707a86c01c02607ae74364854220fb3e82735f631cd0a345dea6b4cee5", + "sha256:c90bda74e16bcd03861b09b1d37c0a4158feda5d5a036bb2d6e58de6ff65793e", + "sha256:cfce79ce41cc1a1dc7fc85bb41eeeb32d34a4cf39a645c717c0550287e30ff06", + "sha256:eeafb646f374988c22c8e6da5ab9fb81367ecfe81c70c292623373d2a021b1a1", + "sha256:f425f50a6dd807cb9043d15a4fcfba3b5874a54d9587ccbb748899f70dc18c47", + "sha256:fcd4459fe35a400b8f416bc57906862693c9f88b66dc925e7f2a933e77f6b18b", + "sha256:ff3936dd5feaefb4f91c8c1f50a06c588b5dc69fba4f7d9c79a6617ad80bb7df" ], "index": "pypi", - "version": "==4.5.4" + "version": "==5.0.1" }, "django": { "hashes": [ - "sha256:a4ad4f6f9c6a4b7af7e2deec8d0cbff28501852e5010d6c2dc695d3d1fae7ca0", - "sha256:fa98ec9cc9bf5d72a08ebf3654a9452e761fbb8566e3f80de199cbc15477e891" + "sha256:662a1ff78792e3fd77f16f71b1f31149489434de4b62a74895bd5d6534e635a5", + "sha256:687c37153486cf26c3fdcbdd177ef16de38dc3463f094b5f9c9955d91f277b14" ], "index": "pypi", - "version": "==2.2.8" + "version": "==2.2.9" }, "django-debug-toolbar": { "hashes": [ @@ -1034,10 +1033,10 @@ }, "prospector": { "hashes": [ - "sha256:aba551e53dc1a5a432afa67385eaa81d7b4cf4c162dc1a4d0ee00b3a0712ad90" + "sha256:ea910794b53cfefcb5dfb6b4eb0323e42d1a88132e165b85b016cc7f0b6ae635" ], "index": "pypi", - "version": "==1.1.7" + "version": "==1.2.0" }, "pycodestyle": { "hashes": [ @@ -1048,25 +1047,25 @@ }, "pydocstyle": { "hashes": [ - "sha256:04c84e034ebb56eb6396c820442b8c4499ac5eb94a3bda88951ac3dc519b6058", - "sha256:66aff87ffe34b1e49bff2dd03a88ce6843be2f3346b0c9814410d34987fbab59" + "sha256:4167fe954b8f27ebbbef2fbcf73c6e8ad1e7bb31488fce44a69fdfc4b0cd0fae", + "sha256:a0de36e549125d0a16a72a8c8c6c9ba267750656e72e466e994c222f1b6e92cb" ], - "version": "==4.0.1" + "version": "==5.0.1" }, "pyflakes": { "hashes": [ - "sha256:08bd6a50edf8cffa9fa09a463063c425ecaaf10d1eb0335a7e8b1401aef89e6f", - "sha256:8d616a382f243dbf19b54743f280b80198be0bca3a5396f1d2e1fca6223e8805" + "sha256:17dbeb2e3f4d772725c777fabc446d5634d1038f234e77343108ce445ea69ce0", + "sha256:d976835886f8c5b31d47970ed689944a0262b5f3afa00a5a7b4dc81e5449f8a2" ], - "version": "==1.6.0" + "version": "==2.1.1" }, "pylint": { "hashes": [ - "sha256:5d77031694a5fb97ea95e828c8d10fc770a1df6eb3906067aaed42201a8a6a09", - "sha256:723e3db49555abaf9bf79dc474c6b9e2935ad82230b10c1138a71ea41ac0fff1" + "sha256:3db5468ad013380e987410a8d6956226963aed94ecb5f9d3a28acca6d9ac36cd", + "sha256:886e6afc935ea2590b462664b161ca9a5e40168ea99e5300935f6591ad467df4" ], "index": "pypi", - "version": "==2.3.1" + "version": "==2.4.4" }, "pylint-celery": { "hashes": [ @@ -1076,11 +1075,11 @@ }, "pylint-django": { "hashes": [ - "sha256:75c69d1ec2275918c37f175976da20e2f1e1e62e067098a685cd263ffa833dfd", - "sha256:c7cb6384ea7b33ea77052a5ae07358c10d377807390ef27b2e6ff997303fadb7" + "sha256:9bdb0e022b19881218a25ffb8ad05e83b83bc5cdbc58e5ee8ffbe99965193f6c", + "sha256:9eea6a026eaa5ecfad5fed7a33faf77ef55a43cc78afbcaf2f6ddd071156b3f8" ], "index": "pypi", - "version": "==2.0.10" + "version": "==2.0.12" }, "pylint-flask": { "hashes": [ @@ -1189,7 +1188,7 @@ "sha256:fdc1c9bbf79510b76408840e009ed65958feba92a88833cdceecff93ae8fff66", "sha256:ffde2fbfad571af120fcbfbbc61c72469e72f550d676c3342492a9dfdefb8f12" ], - "markers": "implementation_name == 'cpython'", + "markers": "implementation_name == 'cpython' and python_version < '3.8'", "version": "==1.4.0" }, "unittest-xml-reporting": { diff --git a/passbook/api/v1/openid.py b/passbook/api/v1/openid.py index 82f683960..a928da179 100644 --- a/passbook/api/v1/openid.py +++ b/passbook/api/v1/openid.py @@ -9,7 +9,7 @@ class OpenIDUserInfoView(ScopedResourceMixin, View): required_scopes = ['openid:userinfo'] - def get(self, request, *args, **kwargs): + def get(self, request, *_, **__): """Passbook v1 OpenID API""" payload = { 'sub': request.user.uuid.int, diff --git a/passbook/audit/signals.py b/passbook/audit/signals.py index 8362bd819..cbfe171f5 100644 --- a/passbook/audit/signals.py +++ b/passbook/audit/signals.py @@ -8,26 +8,35 @@ from passbook.core.signals import (invitation_created, invitation_used, @receiver(user_logged_in) -def on_user_logged_in(sender, request, user, **kwargs): +# pylint: disable=unused-argument +def on_user_logged_in(sender, request, user, **_): """Log successful login""" Event.new(EventAction.LOGIN).from_http(request) + @receiver(user_logged_out) -def on_user_logged_out(sender, request, user, **kwargs): +# pylint: disable=unused-argument +def on_user_logged_out(sender, request, user, **_): """Log successfully logout""" Event.new(EventAction.LOGOUT).from_http(request) + @receiver(user_signed_up) -def on_user_signed_up(sender, request, user, **kwargs): +# pylint: disable=unused-argument +def on_user_signed_up(sender, request, user, **_): """Log successfully signed up""" Event.new(EventAction.SIGN_UP).from_http(request) + @receiver(invitation_created) -def on_invitation_created(sender, request, invitation, **kwargs): +# pylint: disable=unused-argument +def on_invitation_created(sender, request, invitation, **_): """Log Invitation creation""" Event.new(EventAction.INVITE_CREATED, invitation_uuid=invitation.uuid.hex).from_http(request) + @receiver(invitation_used) -def on_invitation_used(sender, request, invitation, **kwargs): +# pylint: disable=unused-argument +def on_invitation_used(sender, request, invitation, **_): """Log Invitation usage""" Event.new(EventAction.INVITE_USED, invitation_uuid=invitation.uuid.hex).from_http(request) diff --git a/passbook/core/signals.py b/passbook/core/signals.py index 741af6094..4dea5a5a7 100644 --- a/passbook/core/signals.py +++ b/passbook/core/signals.py @@ -12,6 +12,7 @@ invitation_created = Signal(providing_args=['request', 'invitation']) invitation_used = Signal(providing_args=['request', 'invitation', 'user']) password_changed = Signal(providing_args=['user', 'password']) + @receiver(post_save) # pylint: disable=unused-argument def invalidate_policy_cache(sender, instance, **_): diff --git a/passbook/core/views/authentication.py b/passbook/core/views/authentication.py index 3acd6183b..86fe12633 100644 --- a/passbook/core/views/authentication.py +++ b/passbook/core/views/authentication.py @@ -78,6 +78,7 @@ class LoginView(UserPassesTestMixin, FormView): def invalid_login(self, request: HttpRequest, disabled_user: User = None) -> HttpResponse: """Handle login for disabled users/invalid login attempts""" + LOGGER.debug("invalid_login", user=disabled_user) messages.error(request, _('Failed to authenticate.')) return self.render_to_response(self.get_context_data()) diff --git a/passbook/factors/otp/settings.py b/passbook/factors/otp/settings.py index d622ebab1..41aa07799 100644 --- a/passbook/factors/otp/settings.py +++ b/passbook/factors/otp/settings.py @@ -1,6 +1,5 @@ """passbook OTP Settings""" -OTP_TOTP_ISSUER = 'passbook' MIDDLEWARE = [ 'django_otp.middleware.OTPMiddleware', ] diff --git a/passbook/factors/otp/utils.py b/passbook/factors/otp/utils.py index 3366853a3..802c69255 100644 --- a/passbook/factors/otp/utils.py +++ b/passbook/factors/otp/utils.py @@ -1,22 +1,17 @@ """passbook OTP Utils""" -from django.conf import settings from django.utils.http import urlencode def otpauth_url(accountname, secret, issuer=None, digits=6): """Create otpauth according to https://github.com/google/google-authenticator/wiki/Key-Uri-Format""" - - accountname = accountname - issuer = issuer if issuer else getattr(settings, 'OTP_TOTP_ISSUER') - # Ensure that the secret parameter is the FIRST parameter of the URI, this # allows Microsoft Authenticator to work. query = [ ('secret', secret), ('digits', digits), - ('issuer', issuer), + ('issuer', 'passbook'), ] return 'otpauth://totp/%s:%s?%s' % (issuer, accountname, urlencode(query)) diff --git a/passbook/factors/otp/views.py b/passbook/factors/otp/views.py index 7961992c6..3715f5b0c 100644 --- a/passbook/factors/otp/views.py +++ b/passbook/factors/otp/views.py @@ -26,6 +26,7 @@ OTP_SESSION_KEY = 'passbook_factors_otp_key' OTP_SETTING_UP_KEY = 'passbook_factors_otp_setup' LOGGER = get_logger() + class UserSettingsView(LoginRequiredMixin, TemplateView): """View for user settings to control OTP""" @@ -37,15 +38,16 @@ class UserSettingsView(LoginRequiredMixin, TemplateView): static = StaticDevice.objects.filter(user=self.request.user, confirmed=True) if static.exists(): kwargs['static_tokens'] = StaticToken.objects.filter(device=static.first()) \ - .order_by('token') + .order_by('token') totp_devices = TOTPDevice.objects.filter(user=self.request.user, confirmed=True) kwargs['state'] = totp_devices.exists() and static.exists() return kwargs + class DisableView(LoginRequiredMixin, View): """Disable TOTP for user""" - def get(self, request, *args, **kwargs): + def get(self, request: HttpRequest) -> HttpResponse: """Delete all the devices for user""" static = get_object_or_404(StaticDevice, user=request.user, confirmed=True) static_tokens = StaticToken.objects.filter(device=static).order_by('token') @@ -59,6 +61,7 @@ class DisableView(LoginRequiredMixin, View): Event.new(EventAction.CUSTOM, message='User disabled OTP.').from_http(request) return redirect(reverse('passbook_factors_otp:otp-user-settings')) + class EnableView(LoginRequiredMixin, FormView): """View to set up OTP""" @@ -133,6 +136,7 @@ class EnableView(LoginRequiredMixin, FormView): Event.new(EventAction.CUSTOM, message='User enabled OTP.').from_http(self.request) return redirect('passbook_factors_otp:otp-user-settings') + class QRView(NeverCacheMixin, View): """View returns an SVG image with the OTP token information""" diff --git a/passbook/factors/view.py b/passbook/factors/view.py index 2e06c201e..1b5e7a498 100644 --- a/passbook/factors/view.py +++ b/passbook/factors/view.py @@ -15,18 +15,18 @@ from passbook.lib.utils.urls import is_url_absolute from passbook.policies.engine import PolicyEngine LOGGER = get_logger() +# Argument used to redirect user after login +NEXT_ARG_NAME = 'next' + def _redirect_with_qs(view, get_query_set=None): """Wrapper to redirect whilst keeping GET Parameters""" target = reverse(view) if get_query_set: - target += '?' + urlencode({key: value for key, value in get_query_set.items()}) + target += '?' + urlencode(get_query_set) return redirect(target) -# Argument used to redirect user after login -NEXT_ARG_NAME = 'next' - class AuthenticationView(UserPassesTestMixin, View): """Wizard-like Multi-factor authenticator""" @@ -165,5 +165,6 @@ class AuthenticationView(UserPassesTestMixin, View): del self.request.session[key] LOGGER.debug("Cleaned up sessions") + class FactorPermissionDeniedView(PermissionDeniedView): """User could not be authenticated""" diff --git a/passbook/lib/config.py b/passbook/lib/config.py index 4bf9abf5a..07abcea70 100644 --- a/passbook/lib/config.py +++ b/passbook/lib/config.py @@ -81,7 +81,7 @@ class ConfigLoader: except yaml.YAMLError as exc: raise ImproperlyConfigured from exc except PermissionError as exc: - LOGGER.warning('Permission denied while reading %s', path) + LOGGER.warning('Permission denied while reading file', path=path, error=exc) def update_from_dict(self, update: dict): """Update config from dict""" @@ -143,6 +143,7 @@ class ConfigLoader: CONFIG = ConfigLoader() + def signal_handler(sender, **_): """Add all loaded config files to autoreload watcher""" for path in CONFIG.loaded_file: diff --git a/passbook/policies/reputation/signals.py b/passbook/policies/reputation/signals.py index 570396ef9..f53c7fd06 100644 --- a/passbook/policies/reputation/signals.py +++ b/passbook/policies/reputation/signals.py @@ -27,12 +27,14 @@ def update_score(request, username, amount): @receiver(user_login_failed) -def handle_failed_login(sender, request, credentials, **kwargs): +# pylint: disable=unused-argument +def handle_failed_login(sender, request, credentials, **_): """Lower Score for failed loging attempts""" update_score(request, credentials.get('username'), -1) @receiver(user_logged_in) -def handle_successful_login(sender, request, user, **kwargs): +# pylint: disable=unused-argument +def handle_successful_login(sender, request, user, **_): """Raise score for successful attempts""" update_score(request, user.username, 1) diff --git a/passbook/providers/saml/views.py b/passbook/providers/saml/views.py index cc8bc1929..a932cd12c 100644 --- a/passbook/providers/saml/views.py +++ b/passbook/providers/saml/views.py @@ -116,9 +116,10 @@ class LoginProcessView(AccessRequiredView): """Processor-based login continuation. Presents a SAML 2.0 Assertion for POSTing back to the Service Provider.""" + # pylint: disable=unused-argument def get(self, request, application): """Handle get request, i.e. render form""" - LOGGER.debug("Request: %s", request) + LOGGER.debug("SAMLLoginProcessView", request=request, method='get') # Check if user has access if self.provider.application.skip_authorization: ctx = self.provider.processor.generate_response() @@ -137,9 +138,10 @@ class LoginProcessView(AccessRequiredView): except exceptions.CannotHandleAssertion as exc: LOGGER.debug(exc) + # pylint: disable=unused-argument def post(self, request, application): """Handle post request, return back to ACS""" - LOGGER.debug("Request: %s", request) + LOGGER.debug("SAMLLoginProcessView", request=request, method='post') # Check if user has access if request.POST.get('ACSUrl', None): # User accepted request @@ -163,6 +165,7 @@ class LogoutView(CSRFExemptMixin, AccessRequiredView): returns a standard logged-out page. (SalesForce and others use this method, though it's technically not SAML 2.0).""" + # pylint: disable=unused-argument def get(self, request, application): """Perform logout""" logout(request) @@ -183,6 +186,7 @@ class SLOLogout(CSRFExemptMixin, AccessRequiredView): """Receives a SAML 2.0 LogoutRequest from a Service Provider, logs out the user and returns a standard logged-out page.""" + # pylint: disable=unused-argument def post(self, request, application): """Perform logout""" request.session['SAMLRequest'] = request.POST['SAMLRequest'] @@ -224,6 +228,7 @@ class DescriptorDownloadView(AccessRequiredView): class InitiateLoginView(AccessRequiredView): """IdP-initiated Login""" + # pylint: disable=unused-argument def get(self, request, application): """Initiates an IdP-initiated link to a simple SP resource/target URL.""" self.provider.processor.init_deep_link(request, '') diff --git a/passbook/sources/ldap/connector.py b/passbook/sources/ldap/connector.py index d5735a3d5..57a80d8fe 100644 --- a/passbook/sources/ldap/connector.py +++ b/passbook/sources/ldap/connector.py @@ -20,7 +20,7 @@ class Connector: def __init__(self, source: LDAPSource): self._source = source - self._server = ldap3.Server(source.server_uri) # Implement URI parsing + self._server = ldap3.Server(source.server_uri) # Implement URI parsing def bind(self): """Bind using Source's Credentials""" @@ -171,7 +171,7 @@ class Connector: temp_connection.bind() return user except ldap3.core.exceptions.LDAPInvalidCredentialsResult as exception: - LOGGER.debug("LDAPInvalidCredentialsResult", user=user) + LOGGER.debug("LDAPInvalidCredentialsResult", user=user, error=exception) except ldap3.core.exceptions.LDAPException as exception: LOGGER.warning(exception) return None diff --git a/passbook/sources/oauth/clients.py b/passbook/sources/oauth/clients.py index 01e15b5c4..79cde0695 100644 --- a/passbook/sources/oauth/clients.py +++ b/passbook/sources/oauth/clients.py @@ -20,7 +20,7 @@ class BaseOAuthClient: _session = None - def __init__(self, source, token=''): # nosec + def __init__(self, source, token=''): # nosec self.source = source self.token = token self._session = Session() @@ -151,6 +151,7 @@ class OAuthClient(BaseOAuthClient): class OAuth2Client(BaseOAuthClient): """OAuth2 Client""" + # pylint: disable=unused-argument def check_application_state(self, request, callback): "Check optional state parameter." stored = request.session.get(self.session_key, None) @@ -192,6 +193,7 @@ class OAuth2Client(BaseOAuthClient): else: return response.text + # pylint: disable=unused-argument def get_application_state(self, request, callback): "Generate state optional parameter." return get_random_string(32) @@ -238,7 +240,7 @@ class OAuth2Client(BaseOAuthClient): return 'oauth-client-{0}-request-state'.format(self.source.name) -def get_client(source, token=''): # nosec +def get_client(source, token=''): # nosec "Return the API client for the given source." cls = OAuth2Client if source.request_token_url: diff --git a/passbook/sources/oauth/views/core.py b/passbook/sources/oauth/views/core.py index 4e128ea49..03f3e6e41 100644 --- a/passbook/sources/oauth/views/core.py +++ b/passbook/sources/oauth/views/core.py @@ -72,7 +72,7 @@ class OAuthCallback(OAuthClientMixin, View): source_id = None source = None - def get(self, request, *args, **kwargs): + def get(self, request, *_, **kwargs): """View Get handler""" slug = kwargs.get('source_slug', '') try: @@ -221,7 +221,8 @@ class DisconnectView(LoginRequiredMixin, View): })) return self.get(request, source_slug) - def get(self, request, source): + # pylint: disable=unused-argument + def get(self, request, source_slug): """Show delete form""" return render(request, 'generic/delete.html', { 'object': self.source,