policy(minor): add data class for policy request
This commit is contained in:
parent
f58bc61999
commit
64b75cab84
2
Pipfile
2
Pipfile
|
@ -31,7 +31,7 @@ lxml = "*"
|
||||||
markdown = "*"
|
markdown = "*"
|
||||||
oauthlib = "*"
|
oauthlib = "*"
|
||||||
packaging = "*"
|
packaging = "*"
|
||||||
psycopg2 = "*"
|
psycopg2-binary = "*"
|
||||||
pycryptodome = "*"
|
pycryptodome = "*"
|
||||||
pyyaml = "*"
|
pyyaml = "*"
|
||||||
qrcode = "*"
|
qrcode = "*"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"_meta": {
|
"_meta": {
|
||||||
"hash": {
|
"hash": {
|
||||||
"sha256": "cd82871d9aca8cfd548a6a62856196b2211524f12fbd416dfe5218aad9471e44"
|
"sha256": "b7dff8588b702e20c77b5e52a82e5c5c596cc25790b8906dc9eabe5b1b836893"
|
||||||
},
|
},
|
||||||
"pipfile-spec": 6,
|
"pipfile-spec": 6,
|
||||||
"requires": {
|
"requires": {
|
||||||
|
@ -33,24 +33,24 @@
|
||||||
},
|
},
|
||||||
"asn1crypto": {
|
"asn1crypto": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:2f1adbb7546ed199e3c90ef23ec95c5cf3585bac7d11fb7eb562a3fe89c64e87",
|
"sha256:d02bf8ea1b964a5ff04ac7891fe3a39150045d1e5e4fe99273ba677d11b92a04",
|
||||||
"sha256:9d5c20441baf0cb60a4ac34cc447c6c189024b6b4c6cd7877034f4965c464e49"
|
"sha256:f822954b90c4c44f002e2cd46d636ab630f1fe4df22c816a82b66505c404eb2a"
|
||||||
],
|
],
|
||||||
"version": "==0.24.0"
|
"version": "==1.0.0"
|
||||||
},
|
},
|
||||||
"attrs": {
|
"attrs": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:69c0dbf2ed392de1cb5ec704444b08a5ef81680a61cb899dc08127123af36a79",
|
"sha256:ec20e7a4825331c1b5ebf261d111e16fa9612c1f7a5e1f884f12bd53a664dfd2",
|
||||||
"sha256:f0b870f674851ecbfbbbd364d6b5cbdff9dcedbc7f3f5e18a6891057f21fe399"
|
"sha256:f913492e1663d3c36f502e5e9ba6cd13cf19d7fab50aa13239e420fef95e1396"
|
||||||
],
|
],
|
||||||
"version": "==19.1.0"
|
"version": "==19.2.0"
|
||||||
},
|
},
|
||||||
"autobahn": {
|
"autobahn": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:27688cbddd5545fc2ee2614ec8fa65119f1a2122606ce2ef7756392c33e3ec0f",
|
"sha256:734385b00547448b3f30a752cbfd2900d15924d77dc4a1699b8bce1ea8899f39",
|
||||||
"sha256:a24826ad0bcc35d32cb4576a092fa744e8b6738bd6320d2de857ad8a71df0bec"
|
"sha256:7ab1e51a9c9bf0aa6ccbe765635b79b9a659019d38904fa3c2072670f097a25d"
|
||||||
],
|
],
|
||||||
"version": "==19.9.3"
|
"version": "==19.10.1"
|
||||||
},
|
},
|
||||||
"automat": {
|
"automat": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
|
@ -59,13 +59,6 @@
|
||||||
],
|
],
|
||||||
"version": "==0.7.0"
|
"version": "==0.7.0"
|
||||||
},
|
},
|
||||||
"backports.functools-lru-cache": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:9d98697f088eb1b0fa451391f91afb5e3ebde16bbdb272819fd091151fda4f1a",
|
|
||||||
"sha256:f0b0e4eba956de51238e17573b7087e852dfe9854afd2e9c873f73fc0ca0a6dd"
|
|
||||||
],
|
|
||||||
"version": "==1.5"
|
|
||||||
},
|
|
||||||
"beautifulsoup4": {
|
"beautifulsoup4": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:05668158c7b85b791c5abde53e50265e16f98ad601c402ba44d70f96c4159612",
|
"sha256:05668158c7b85b791c5abde53e50265e16f98ad601c402ba44d70f96c4159612",
|
||||||
|
@ -92,10 +85,10 @@
|
||||||
},
|
},
|
||||||
"certifi": {
|
"certifi": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:046832c04d4e752f37383b628bc601a7ea7211496b4638f6514d0e5b9acc4939",
|
"sha256:e4f3620cfea4f83eedc95b24abd9cd56f3c4b146dd0177e83a21b4eb49e21e50",
|
||||||
"sha256:945e3ba63a0b9f577b1395204e13c3a231f9bc0223888be653286534e5873695"
|
"sha256:fd7c7c74727ddcf00e9acd26bba8da604ffec95bf1c2144e67aff7a8b50e6cef"
|
||||||
],
|
],
|
||||||
"version": "==2019.6.16"
|
"version": "==2019.9.11"
|
||||||
},
|
},
|
||||||
"cffi": {
|
"cffi": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
|
@ -132,11 +125,11 @@
|
||||||
},
|
},
|
||||||
"channels": {
|
"channels": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:9191a85800673b790d1d74666fb7676f430600b71b662581e97dd69c9aedd29a",
|
"sha256:5759b4b89fc354101299e5f24b49e83421c12c653c913161858be4c24364a26d",
|
||||||
"sha256:af7cdba9efb3f55b939917d1b15defb5d40259936013e60660e5e9aff98db4c5"
|
"sha256:d0289e4a3aa6f1df34693b14d5c1d147832a16622c13e1f1eff5b22ff2f2c748"
|
||||||
],
|
],
|
||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==2.2.0"
|
"version": "==2.3.0"
|
||||||
},
|
},
|
||||||
"chardet": {
|
"chardet": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
|
@ -147,18 +140,18 @@
|
||||||
},
|
},
|
||||||
"cheroot": {
|
"cheroot": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:427e7e3ce51ad5a6e5cf953252b5782d5dfbeb544c09910634971bc06df6621b",
|
"sha256:6168371ab9aaf574ac5f75675f244bbfebf990202bf75048065e9d675b9ae719",
|
||||||
"sha256:74d733c55178812253d855990f7ad7b31ab4ee8dab80e4803bd5e52299c50395"
|
"sha256:8cc7c28961db2e13d0cac6b234a589a314c1844f7bbf54e67888ac9a2e25ac59"
|
||||||
],
|
],
|
||||||
"version": "==6.5.8"
|
"version": "==7.0.0"
|
||||||
},
|
},
|
||||||
"cherrypy": {
|
"cherrypy": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:16fc226a280cd772ede7c309d3964002196784ac6615d8bface52be12ff51230",
|
"sha256:033368d25fcc6bca143e7efe9adbfd3a6d91cc0d90c37a649261935f116aafab",
|
||||||
"sha256:488ea5e639885c75330686c1d7d3dfbd002f784c027a3fe5b374b41926b8cba3"
|
"sha256:683e687e7c7b1ba31ef86a113b1eafd0407269fed175bf488d3c839d37d1cc60"
|
||||||
],
|
],
|
||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==18.2.0"
|
"version": "==18.3.0"
|
||||||
},
|
},
|
||||||
"colorlog": {
|
"colorlog": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
|
@ -228,11 +221,11 @@
|
||||||
},
|
},
|
||||||
"django": {
|
"django": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:148a4a2d1a85b23883b0a4e99ab7718f518a83675e4485e44dc0c1d36988c5fa",
|
"sha256:4025317ca01f75fc79250ff7262a06d8ba97cd4f82e93394b2a0a6a4a925caeb",
|
||||||
"sha256:deb70aa038e59b58593673b15e9a711d1e5ccd941b5973b30750d5d026abfd56"
|
"sha256:a8ca1033acac9f33995eb2209a6bf18a4681c3e5269a878e9a7e0b7384ed1ca3"
|
||||||
],
|
],
|
||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==2.2.5"
|
"version": "==2.2.6"
|
||||||
},
|
},
|
||||||
"django-cors-middleware": {
|
"django-cors-middleware": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
|
@ -280,11 +273,11 @@
|
||||||
},
|
},
|
||||||
"django-otp": {
|
"django-otp": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:246b11ee38ec1cea2e2312311a830740d1a8d0384ba15e7b70e03f851d790157",
|
"sha256:79c8253be97246df86540d551dc705e8fe6ca76af8e8c77f78314cd1b513c2cf",
|
||||||
"sha256:cefbf5e7295498c767752d77828ce3f56cdb0373915e56fe4f87d99604742394"
|
"sha256:c5bf3916dca5d53cb377aa6dea40aa785c164013fbf750384137362dfa278cf5"
|
||||||
],
|
],
|
||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==0.7.0"
|
"version": "==0.7.2"
|
||||||
},
|
},
|
||||||
"django-recaptcha": {
|
"django-recaptcha": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
|
@ -327,11 +320,11 @@
|
||||||
},
|
},
|
||||||
"drf-yasg": {
|
"drf-yasg": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:68fded2ffdf46e03f33e766184b7d8f1e1a5236f94acfd0c4ba932a57b812566",
|
"sha256:4cfec631880ae527a91ec7cd3241aea2f82189f59e2f089119aa687761afb227",
|
||||||
"sha256:fcef74709ead2b365410be3d12afbfd0a6e49d1efe615a15a929da7e950bb83c"
|
"sha256:504cce09035cf1bace63b84d9d778b772f86bb37d8a71ed6f723346362e633b2"
|
||||||
],
|
],
|
||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==1.16.1"
|
"version": "==1.17.0"
|
||||||
},
|
},
|
||||||
"eight": {
|
"eight": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
|
@ -362,10 +355,10 @@
|
||||||
},
|
},
|
||||||
"importlib-metadata": {
|
"importlib-metadata": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:0c505102757e7fa28b9f0958d8bc81301159dea16e2649858c92edc158b78a83",
|
"sha256:aa18d7378b00b40847790e7c27e11673d7fed219354109d0e7b9e5b25dc3ad26",
|
||||||
"sha256:9a9f75ce32e78170905888acbf2376a81d3f21ecb3bb4867050413411d3ca7a9"
|
"sha256:d5f18a79777f3aa179c145737780282e27b508fc8fd688cb17c7a813e8bd39af"
|
||||||
],
|
],
|
||||||
"version": "==0.21"
|
"version": "==0.23"
|
||||||
},
|
},
|
||||||
"incremental": {
|
"incremental": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
|
@ -402,10 +395,10 @@
|
||||||
},
|
},
|
||||||
"kombu": {
|
"kombu": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:55274dc75eb3c3994538b0973a0fadddb236b698a4bc135b8aa4981e0a710b8f",
|
"sha256:31edb84947996fdda065b6560c128d5673bb913ff34aa19e7b84755217a24deb",
|
||||||
"sha256:e5f0312dfb9011bebbf528ccaf118a6c2b5c3b8244451f08381fb23e7715809b"
|
"sha256:c9078124ce2616b29cf6607f0ac3db894c59154252dee6392cdbbe15e5c4b566"
|
||||||
],
|
],
|
||||||
"version": "==4.6.4"
|
"version": "==4.6.5"
|
||||||
},
|
},
|
||||||
"ldap3": {
|
"ldap3": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
|
@ -501,11 +494,11 @@
|
||||||
},
|
},
|
||||||
"packaging": {
|
"packaging": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:a7ac867b97fdc07ee80a8058fe4435ccd274ecc3b0ed61d852d7d53055528cf9",
|
"sha256:28b924174df7a2fa32c1953825ff29c61e2f5e082343165438812f00d3a7fc47",
|
||||||
"sha256:c491ca87294da7cc01902edbe30a5bc6c4c28172b5138ab4e4aa1b9d7bfaeafe"
|
"sha256:d9551545c6d761f3def1677baf08ab2a3ca17c56879e70fecba2fc4dde4ed108"
|
||||||
],
|
],
|
||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==19.1"
|
"version": "==19.2"
|
||||||
},
|
},
|
||||||
"portend": {
|
"portend": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
|
@ -514,19 +507,36 @@
|
||||||
],
|
],
|
||||||
"version": "==2.5"
|
"version": "==2.5"
|
||||||
},
|
},
|
||||||
"psycopg2": {
|
"psycopg2-binary": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:128d0fa910ada0157bba1cb74a9c5f92bb8a1dca77cf91a31eb274d1f889e001",
|
"sha256:080c72714784989474f97be9ab0ddf7b2ad2984527e77f2909fcd04d4df53809",
|
||||||
"sha256:227fd46cf9b7255f07687e5bde454d7d67ae39ca77e170097cdef8ebfc30c323",
|
"sha256:110457be80b63ff4915febb06faa7be002b93a76e5ba19bf3f27636a2ef58598",
|
||||||
"sha256:2315e7f104681d498ccf6fd70b0dba5bce65d60ac92171492bfe228e21dcc242",
|
"sha256:171352a03b22fc099f15103959b52ee77d9a27e028895d7e5fde127aa8e3bac5",
|
||||||
"sha256:4b5417dcd2999db0f5a891d54717cfaee33acc64f4772c4bc574d4ff95ed9d80",
|
"sha256:19d013e7b0817087517a4b3cab39c084d78898369e5c46258aab7be4f233d6a1",
|
||||||
"sha256:640113ddc943522aaf71294e3f2d24013b0edd659b7820621492c9ebd3a2fb0b",
|
"sha256:249b6b21ae4eb0f7b8423b330aa80fab5f821b9ffc3f7561a5e2fd6bb142cf5d",
|
||||||
"sha256:897a6e838319b4bf648a574afb6cabcb17d0488f8c7195100d48d872419f4457",
|
"sha256:2ac0731d2d84b05c7bb39e85b7e123c3a0acd4cda631d8d542802c88deb9e87e",
|
||||||
"sha256:8dceca81409898c870e011c71179454962dec152a1a6b86a347f4be74b16d864",
|
"sha256:2b6d561193f0dc3f50acfb22dd52ea8c8dfbc64bcafe3938b5f209cc17cb6f00",
|
||||||
"sha256:b1b8e41da09a0c3ef0b3d4bb72da0dde2abebe583c1e8462973233fd5ad0235f",
|
"sha256:2bd23e242e954214944481124755cbefe7c2cf563b1a54cd8d196d502f2578bf",
|
||||||
"sha256:cb407fccc12fc29dc331f2b934913405fa49b9b75af4f3a72d0f50f57ad2ca23",
|
"sha256:3e1239242ca60b3725e65ab2f13765fc199b03af9eaf1b5572f0e97bdcee5b43",
|
||||||
"sha256:d3a27550a8185e53b244ad7e79e307594b92fede8617d80200a8cce1fba2c60f",
|
"sha256:3eb70bb697abbe86b1d2b1316370c02ba320bfd1e9e35cf3b9566a855ea8e4e5",
|
||||||
"sha256:f0e6b697a975d9d3ccd04135316c947dd82d841067c7800ccf622a8717e98df1"
|
"sha256:51a2fc7e94b98bd1bb5d4570936f24fc2b0541b63eccadf8fdea266db8ad2f70",
|
||||||
|
"sha256:52f1bdafdc764b7447e393ed39bb263eccb12bfda25a4ac06d82e3a9056251f6",
|
||||||
|
"sha256:5b3581319a3951f1e866f4f6c5e42023db0fae0284273b82e97dfd32c51985cd",
|
||||||
|
"sha256:63c1b66e3b2a3a336288e4bcec499e0dc310cd1dceaed1c46fa7419764c68877",
|
||||||
|
"sha256:8123a99f24ecee469e5c1339427bcdb2a33920a18bb5c0d58b7c13f3b0298ba3",
|
||||||
|
"sha256:85e699fcabe7f817c0f0a412d4e7c6627e00c412b418da7666ff353f38e30f67",
|
||||||
|
"sha256:8dbff4557bbef963697583366400822387cccf794ccb001f1f2307ed21854c68",
|
||||||
|
"sha256:908d21d08d6b81f1b7e056bbf40b2f77f8c499ab29e64ec5113052819ef1c89b",
|
||||||
|
"sha256:af39d0237b17d0a5a5f638e9dffb34013ce2b1d41441fd30283e42b22d16858a",
|
||||||
|
"sha256:af51bb9f055a3f4af0187149a8f60c9d516cf7d5565b3dac53358796a8fb2a5b",
|
||||||
|
"sha256:b2ecac57eb49e461e86c092761e6b8e1fd9654dbaaddf71a076dcc869f7014e2",
|
||||||
|
"sha256:cd37cc170678a4609becb26b53a2bc1edea65177be70c48dd7b39a1149cabd6e",
|
||||||
|
"sha256:d17e3054b17e1a6cb8c1140f76310f6ede811e75b7a9d461922d2c72973f583e",
|
||||||
|
"sha256:d305313c5a9695f40c46294d4315ed3a07c7d2b55e48a9010dad7db7a66c8b7f",
|
||||||
|
"sha256:dd0ef0eb1f7dd18a3f4187226e226a7284bda6af5671937a221766e6ef1ee88f",
|
||||||
|
"sha256:e1adff53b56db9905db48a972fb89370ad5736e0450b96f91bcf99cadd96cfd7",
|
||||||
|
"sha256:f0d43828003c82dbc9269de87aa449e9896077a71954fbbb10a614c017e65737",
|
||||||
|
"sha256:f78e8b487de4d92640105c1389e5b90be3496b1d75c90a666edd8737cc2dbab7"
|
||||||
],
|
],
|
||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==2.8.3"
|
"version": "==2.8.3"
|
||||||
|
@ -710,35 +720,35 @@
|
||||||
},
|
},
|
||||||
"ruamel.yaml.clib": {
|
"ruamel.yaml.clib": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:0bbe19d3e099f8ba384e1846e6b54f245f58aeec8700edbbf9abb87afa54fd82",
|
"sha256:1e77424825caba5553bbade750cec2277ef130647d685c2b38f68bc03453bac6",
|
||||||
"sha256:2f38024592613f3a8772bbc2904be027d9abf463518ba145f2d0c8e6da27009f",
|
"sha256:392b7c371312abf27fb549ec2d5e0092f7ef6e6c9f767bfb13e83cb903aca0fd",
|
||||||
"sha256:44449b3764a3f75815eea8ae5930b98e8326be64a90b0f782747318f861abfe0",
|
"sha256:4d55386129291b96483edcb93b381470f7cd69f97585829b048a3d758d31210a",
|
||||||
"sha256:5710be9a357801c31c1eaa37b9bc92d38176d785af5b2f0c9751385c5dc9659a",
|
"sha256:550168c02d8de52ee58c3d8a8193d5a8a9491a5e7b2462d27ac5bf63717574c9",
|
||||||
"sha256:5a089acb6833ed5f412e24cbe3e665683064c1429824d2819137b5ade54435c3",
|
"sha256:57933a6986a3036257ad7bf283529e7c19c2810ff24c86f4a0cfeb49d2099919",
|
||||||
"sha256:6143386ddd61599ea081c012a69a16e5bdd7b3c6c231bd039534365a48940f30",
|
"sha256:615b0396a7fad02d1f9a0dcf9f01202bf9caefee6265198f252c865f4227fcc6",
|
||||||
"sha256:6726aaf851f5f9e4cbdd3e1e414bc700bdd39220e8bc386415fd41c87b1b53c2",
|
"sha256:77556a7aa190be9a2bd83b7ee075d3df5f3c5016d395613671487e79b082d784",
|
||||||
"sha256:68fbc3b5d94d145a391452f886ae5fca240cb7e3ab6bd66e1a721507cdaac28a",
|
"sha256:7aee724e1ff424757b5bd8f6c5bbdb033a570b2b4683b17ace4dbe61a99a657b",
|
||||||
"sha256:75ebddf99ba9e0b48f32b5bdcf9e5a2b84c017da9e0db7bf11995fa414aa09cd",
|
"sha256:8073c8b92b06b572e4057b583c3d01674ceaf32167801fe545a087d7a1e8bf52",
|
||||||
"sha256:79948a6712baa686773a43906728e20932c923f7b2a91be7347993be2d745e55",
|
"sha256:9c6d040d0396c28d3eaaa6cb20152cb3b2f15adf35a0304f4f40a3cf9f1d2448",
|
||||||
"sha256:8a2dd8e8b08d369558cade05731172c4b5e2f4c5097762c6b352bd28fd9f9dc4",
|
"sha256:a0ff786d2a7dbe55f9544b3f6ebbcc495d7e730df92a08434604f6f470b899c5",
|
||||||
"sha256:c747acdb5e8c242ab2280df6f0c239e62838af4bee647031d96b3db2f9cefc04",
|
"sha256:b1b7fcee6aedcdc7e62c3a73f238b3d080c7ba6650cd808bce8d7761ec484070",
|
||||||
"sha256:cadc8eecd27414dca30366b2535cb5e3f3b47b4e2d6be7a0b13e4e52e459ff9f",
|
"sha256:b66832ea8077d9b3f6e311c4a53d06273db5dc2db6e8a908550f3c14d67e718c",
|
||||||
"sha256:cee86ecc893a6a8ecaa7c6a9c2d06f75f614176210d78a5f155f8e78d6989509",
|
"sha256:d0d3ac228c9bbab08134b4004d748cf9f8743504875b3603b3afbb97e3472947",
|
||||||
"sha256:e59af39e895aff28ee5f55515983cab3466d1a029c91c04db29da1c0f09cf333",
|
"sha256:d10e9dd744cf85c219bf747c75194b624cc7a94f0c80ead624b06bfa9f61d3bc",
|
||||||
"sha256:eee7ecd2eee648884fae6c51ae50c814acdcc5d6340dc96c970158aebcd25ac6",
|
"sha256:ea4362548ee0cbc266949d8a441238d9ad3600ca9910c3fe4e82ee3a50706973",
|
||||||
"sha256:ef8d4522d231cb9b29f6cdd0edc8faac9d9715c60dc7becbd6eb82c915a98e5b",
|
"sha256:ed5b3698a2bb241b7f5cbbe277eaa7fe48b07a58784fba4f75224fd066d253ad",
|
||||||
"sha256:f504d45230cc9abf2810623b924ae048b224a90adb01f97db4e766cfdda8e6eb"
|
"sha256:f9dcc1ae73f36e8059589b601e8e4776b9976effd76c21ad6a855a74318efd6e"
|
||||||
],
|
],
|
||||||
"markers": "platform_python_implementation == 'CPython' and python_version < '3.8'",
|
"markers": "platform_python_implementation == 'CPython' and python_version < '3.8'",
|
||||||
"version": "==0.1.2"
|
"version": "==0.2.0"
|
||||||
},
|
},
|
||||||
"sentry-sdk": {
|
"sentry-sdk": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:528f936118679e9a52dacb96bfefe20acb5d63e0797856c64a582cc3c2bc1f9e",
|
"sha256:15e51e74b924180c98bcd636cb4634945b0a99a124d50b433c3a9dc6a582e8db",
|
||||||
"sha256:b4edcb1296fee107439345d0f8b23432b8732b7e28407f928367d0a4a36301a9"
|
"sha256:1d6a2ee908ec6d8f96c27d78bc39e203df4d586d287c233140af7d8d1aca108a"
|
||||||
],
|
],
|
||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==0.11.2"
|
"version": "==0.12.3"
|
||||||
},
|
},
|
||||||
"service-identity": {
|
"service-identity": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
|
@ -765,10 +775,10 @@
|
||||||
},
|
},
|
||||||
"soupsieve": {
|
"soupsieve": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:8662843366b8d8779dec4e2f921bebec9afd856a5ff2e82cd419acc5054a1a92",
|
"sha256:605f89ad5fdbfefe30cdc293303665eff2d188865d4dbe4eb510bba1edfbfce3",
|
||||||
"sha256:a5a6166b4767725fd52ae55fee8c8b6137d9a51e9f1edea461a062a759160118"
|
"sha256:b91d676b330a0ebd5b21719cb6e9b57c57d433671f65b9c28dd3461d9a1ed0b6"
|
||||||
],
|
],
|
||||||
"version": "==1.9.3"
|
"version": "==1.9.4"
|
||||||
},
|
},
|
||||||
"sqlparse": {
|
"sqlparse": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
|
@ -777,6 +787,14 @@
|
||||||
],
|
],
|
||||||
"version": "==0.3.0"
|
"version": "==0.3.0"
|
||||||
},
|
},
|
||||||
|
"structlog": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:5feae03167620824d3ae3e8915ea8589fc28d1ad6f3edf3cc90ed7c7cb33fab5",
|
||||||
|
"sha256:db441b81c65b0f104a7ce5d86c5432be099956b98b8a2c8be0b3fb3a7a0b1536"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==19.1.0"
|
||||||
|
},
|
||||||
"tempora": {
|
"tempora": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:cb60b1d2b1664104e307f8e5269d7f4acdb077c82e35cd57246ae14a3427d2d6",
|
"sha256:cb60b1d2b1664104e307f8e5269d7f4acdb077c82e35cd57246ae14a3427d2d6",
|
||||||
|
@ -828,11 +846,18 @@
|
||||||
"secure"
|
"secure"
|
||||||
],
|
],
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:b246607a25ac80bedac05c6f282e3cdaf3afb65420fd024ac94435cabe6e18d1",
|
"sha256:3de946ffbed6e6746608990594d08faac602528ac7015ac28d33cee6a45b7398",
|
||||||
"sha256:dbe59173209418ae49d485b87d1681aefa36252ee85884c31346debd19463232"
|
"sha256:9a107b99a5393caf59c7aa3c1249c16e6879447533d0887f4336dde834c7be86"
|
||||||
],
|
],
|
||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==1.25.3"
|
"version": "==1.25.6"
|
||||||
|
},
|
||||||
|
"uwsgi": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:4972ac538800fb2d421027f49b4a1869b66048839507ccf0aa2fda792d99f583"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==2.0.18"
|
||||||
},
|
},
|
||||||
"vine": {
|
"vine": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
|
@ -904,6 +929,7 @@
|
||||||
"sha256:6560e1e1749f68c64a4b5dee4e091fce798d2f0d84ebe638cf0e0585a343acf4",
|
"sha256:6560e1e1749f68c64a4b5dee4e091fce798d2f0d84ebe638cf0e0585a343acf4",
|
||||||
"sha256:b65db1bbaac9f9f4d190199bb8680af6f6f84fd3769a5ea883df8a91fe68b4c4"
|
"sha256:b65db1bbaac9f9f4d190199bb8680af6f6f84fd3769a5ea883df8a91fe68b4c4"
|
||||||
],
|
],
|
||||||
|
"index": "pypi",
|
||||||
"version": "==2.2.5"
|
"version": "==2.2.5"
|
||||||
},
|
},
|
||||||
"autopep8": {
|
"autopep8": {
|
||||||
|
@ -921,13 +947,6 @@
|
||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==1.6.2"
|
"version": "==1.6.2"
|
||||||
},
|
},
|
||||||
"bleach": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:213336e49e102af26d9cde77dd2d0397afabc5a6bf2fed985dc35b5d1e285a16",
|
|
||||||
"sha256:3fdf7f77adcf649c9911387df51254b813185e32b2c6619f690b593a617e19fa"
|
|
||||||
],
|
|
||||||
"version": "==3.1.0"
|
|
||||||
},
|
|
||||||
"bumpversion": {
|
"bumpversion": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:6744c873dd7aafc24453d8b6a1a0d6d109faf63cd0cd19cb78fd46e74932c77e",
|
"sha256:6744c873dd7aafc24453d8b6a1a0d6d109faf63cd0cd19cb78fd46e74932c77e",
|
||||||
|
@ -936,19 +955,13 @@
|
||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==0.5.3"
|
"version": "==0.5.3"
|
||||||
},
|
},
|
||||||
"certifi": {
|
"colorama": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:046832c04d4e752f37383b628bc601a7ea7211496b4638f6514d0e5b9acc4939",
|
"sha256:05eed71e2e327246ad6b38c540c4a3117230b19679b875190486ddd2d721422d",
|
||||||
"sha256:945e3ba63a0b9f577b1395204e13c3a231f9bc0223888be653286534e5873695"
|
"sha256:f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48"
|
||||||
],
|
],
|
||||||
"version": "==2019.6.16"
|
"index": "pypi",
|
||||||
},
|
"version": "==0.4.1"
|
||||||
"chardet": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
|
|
||||||
"sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"
|
|
||||||
],
|
|
||||||
"version": "==3.0.4"
|
|
||||||
},
|
},
|
||||||
"coverage": {
|
"coverage": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
|
@ -990,11 +1003,11 @@
|
||||||
},
|
},
|
||||||
"django": {
|
"django": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:148a4a2d1a85b23883b0a4e99ab7718f518a83675e4485e44dc0c1d36988c5fa",
|
"sha256:4025317ca01f75fc79250ff7262a06d8ba97cd4f82e93394b2a0a6a4a925caeb",
|
||||||
"sha256:deb70aa038e59b58593673b15e9a711d1e5ccd941b5973b30750d5d026abfd56"
|
"sha256:a8ca1033acac9f33995eb2209a6bf18a4681c3e5269a878e9a7e0b7384ed1ca3"
|
||||||
],
|
],
|
||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==2.2.5"
|
"version": "==2.2.6"
|
||||||
},
|
},
|
||||||
"django-debug-toolbar": {
|
"django-debug-toolbar": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
|
@ -1004,14 +1017,6 @@
|
||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==2.0"
|
"version": "==2.0"
|
||||||
},
|
},
|
||||||
"docutils": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:6c4f696463b79f1fb8ba0c594b63840ebd41f059e92b31957c46b74a4599b6d0",
|
|
||||||
"sha256:9e4d7ecfc600058e07ba661411a2b7de2fd0fafa17d1a7f7361cd47b1175c827",
|
|
||||||
"sha256:a2aeea129088da402665e92e0b25b04b073c04b2dce4ab65caaa38b7ce2e1a99"
|
|
||||||
],
|
|
||||||
"version": "==0.15.2"
|
|
||||||
},
|
|
||||||
"dodgy": {
|
"dodgy": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:65e13cf878d7aff129f1461c13cb5fd1bb6dfe66bb5327e09379c3877763280c"
|
"sha256:65e13cf878d7aff129f1461c13cb5fd1bb6dfe66bb5327e09379c3877763280c"
|
||||||
|
@ -1020,24 +1025,17 @@
|
||||||
},
|
},
|
||||||
"gitdb2": {
|
"gitdb2": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:83361131a1836661a155172932a13c08bda2db3674e4caa32368aa6eb02f38c2",
|
"sha256:1b6df1433567a51a4a9c1a5a0de977aa351a405cc56d7d35f3388bad1f630350",
|
||||||
"sha256:e3a0141c5f2a3f635c7209d56c496ebe1ad35da82fe4d3ec4aaa36278d70648a"
|
"sha256:96bbb507d765a7f51eb802554a9cfe194a174582f772e0d89f4e87288c288b7b"
|
||||||
],
|
],
|
||||||
"version": "==2.0.5"
|
"version": "==2.0.6"
|
||||||
},
|
},
|
||||||
"gitpython": {
|
"gitpython": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:947cc75913e7b6da108458136607e2ee0e40c20be1e12d4284e7c6c12956c276",
|
"sha256:631263cc670aa56ce3d3c414cf0fe2e840f2e913514b138ea28d88a477bbcd21",
|
||||||
"sha256:d2f4945f8260f6981d724f5957bc076398ada55cb5d25aaee10108bcdc894100"
|
"sha256:6e97b9f0954807f30c2dd8e3165731ed6c477a1b365f194b69d81d7940a08332"
|
||||||
],
|
],
|
||||||
"version": "==3.0.2"
|
"version": "==3.0.3"
|
||||||
},
|
|
||||||
"idna": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407",
|
|
||||||
"sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"
|
|
||||||
],
|
|
||||||
"version": "==2.8"
|
|
||||||
},
|
},
|
||||||
"isort": {
|
"isort": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
|
@ -1091,13 +1089,6 @@
|
||||||
],
|
],
|
||||||
"version": "==0.4.1"
|
"version": "==0.4.1"
|
||||||
},
|
},
|
||||||
"pkginfo": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:7424f2c8511c186cd5424bbf31045b77435b37a8d604990b79d4e70d741148bb",
|
|
||||||
"sha256:a6d9e40ca61ad3ebd0b72fbadd4fba16e4c0e4df0428c041e01e06eb6ee71f32"
|
|
||||||
],
|
|
||||||
"version": "==1.5.0.1"
|
|
||||||
},
|
|
||||||
"prospector": {
|
"prospector": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:aba551e53dc1a5a432afa67385eaa81d7b4cf4c162dc1a4d0ee00b3a0712ad90"
|
"sha256:aba551e53dc1a5a432afa67385eaa81d7b4cf4c162dc1a4d0ee00b3a0712ad90"
|
||||||
|
@ -1126,13 +1117,6 @@
|
||||||
],
|
],
|
||||||
"version": "==1.6.0"
|
"version": "==1.6.0"
|
||||||
},
|
},
|
||||||
"pygments": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:71e430bc85c88a430f000ac1d9b331d2407f681d6f6aec95e8bcfbc3df5b0127",
|
|
||||||
"sha256:881c4c157e45f30af185c1ffe8d549d48ac9127433f2c380c24b84572ad66297"
|
|
||||||
],
|
|
||||||
"version": "==2.4.2"
|
|
||||||
},
|
|
||||||
"pylint": {
|
"pylint": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:5d77031694a5fb97ea95e828c8d10fc770a1df6eb3906067aaed42201a8a6a09",
|
"sha256:5d77031694a5fb97ea95e828c8d10fc770a1df6eb3906067aaed42201a8a6a09",
|
||||||
|
@ -1163,9 +1147,10 @@
|
||||||
},
|
},
|
||||||
"pylint-plugin-utils": {
|
"pylint-plugin-utils": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:8d9e31d5ea8b7b0003e1f0f136b44a5235896a32e47c5bc2ef1143e9f6ba0b74"
|
"sha256:2f30510e1c46edf268d3a195b2849bd98a1b9433229bb2ba63b8d776e1fc4d0a",
|
||||||
|
"sha256:57625dcca20140f43731311cd8fd879318bf45a8b0fd17020717a8781714a25a"
|
||||||
],
|
],
|
||||||
"version": "==0.5"
|
"version": "==0.6"
|
||||||
},
|
},
|
||||||
"pytz": {
|
"pytz": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
|
@ -1193,27 +1178,6 @@
|
||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==5.1.2"
|
"version": "==5.1.2"
|
||||||
},
|
},
|
||||||
"readme-renderer": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:bb16f55b259f27f75f640acf5e00cf897845a8b3e4731b5c1a436e4b8529202f",
|
|
||||||
"sha256:c8532b79afc0375a85f10433eca157d6b50f7d6990f337fa498c96cd4bfc203d"
|
|
||||||
],
|
|
||||||
"version": "==24.0"
|
|
||||||
},
|
|
||||||
"requests": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4",
|
|
||||||
"sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31"
|
|
||||||
],
|
|
||||||
"version": "==2.22.0"
|
|
||||||
},
|
|
||||||
"requests-toolbelt": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:380606e1d10dc85c3bd47bf5a6095f815ec007be7a8b69c878507068df059e6f",
|
|
||||||
"sha256:968089d4584ad4ad7c171454f0a5c6dac23971e9472521ea3b6d49d610aa6fc0"
|
|
||||||
],
|
|
||||||
"version": "==0.9.1"
|
|
||||||
},
|
|
||||||
"requirements-detector": {
|
"requirements-detector": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:9fbc4b24e8b7c3663aff32e3eba34596848c6b91bd425079b386973bd8d08931"
|
"sha256:9fbc4b24e8b7c3663aff32e3eba34596848c6b91bd425079b386973bd8d08931"
|
||||||
|
@ -1242,9 +1206,10 @@
|
||||||
},
|
},
|
||||||
"snowballstemmer": {
|
"snowballstemmer": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:713e53b79cbcf97bc5245a06080a33d54a77e7cce2f789c835a143bcdb5c033e"
|
"sha256:209f257d7533fdb3cb73bdbd24f436239ca3b2fa67d56f6ff88e86be08cc5ef0",
|
||||||
|
"sha256:df3bac3df4c2c01363f3dd2cfa78cce2840a79b9f1c2d2de9ce8d31683992f52"
|
||||||
],
|
],
|
||||||
"version": "==1.9.1"
|
"version": "==2.0.0"
|
||||||
},
|
},
|
||||||
"sqlparse": {
|
"sqlparse": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
|
@ -1260,21 +1225,6 @@
|
||||||
],
|
],
|
||||||
"version": "==1.31.0"
|
"version": "==1.31.0"
|
||||||
},
|
},
|
||||||
"tqdm": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:1be3e4e3198f2d0e47b928e9d9a8ec1b63525db29095cec1467f4c5a4ea8ebf9",
|
|
||||||
"sha256:7e39a30e3d34a7a6539378e39d7490326253b7ee354878a92255656dc4284457"
|
|
||||||
],
|
|
||||||
"version": "==4.35.0"
|
|
||||||
},
|
|
||||||
"twine": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:b2cec0dc1ac55bd74280d257f43763cf0cf928bdcd0de0fd70be70aa1195e3b0",
|
|
||||||
"sha256:e37d5a73d77b095b85314dde807bfb85b580b5b9d137f5b21332f4636990d97a"
|
|
||||||
],
|
|
||||||
"index": "pypi",
|
|
||||||
"version": "==1.14.0"
|
|
||||||
},
|
|
||||||
"typed-ast": {
|
"typed-ast": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:18511a0b3e7922276346bcb47e2ef9f38fb90fd31cb9223eed42c85d1312344e",
|
"sha256:18511a0b3e7922276346bcb47e2ef9f38fb90fd31cb9223eed42c85d1312344e",
|
||||||
|
@ -1304,24 +1254,6 @@
|
||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==2.5.1"
|
"version": "==2.5.1"
|
||||||
},
|
},
|
||||||
"urllib3": {
|
|
||||||
"extras": [
|
|
||||||
"secure"
|
|
||||||
],
|
|
||||||
"hashes": [
|
|
||||||
"sha256:b246607a25ac80bedac05c6f282e3cdaf3afb65420fd024ac94435cabe6e18d1",
|
|
||||||
"sha256:dbe59173209418ae49d485b87d1681aefa36252ee85884c31346debd19463232"
|
|
||||||
],
|
|
||||||
"index": "pypi",
|
|
||||||
"version": "==1.25.3"
|
|
||||||
},
|
|
||||||
"webencodings": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78",
|
|
||||||
"sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"
|
|
||||||
],
|
|
||||||
"version": "==0.5.1"
|
|
||||||
},
|
|
||||||
"wrapt": {
|
"wrapt": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:565a021fd19419476b9362b05eeaa094178de64f8361e44468f9e9d7843901e1"
|
"sha256:565a021fd19419476b9362b05eeaa094178de64f8361e44468f9e9d7843901e1"
|
||||||
|
|
|
@ -59,11 +59,7 @@ spec:
|
||||||
- --http 0.0.0.0:8000
|
- --http 0.0.0.0:8000
|
||||||
- --wsgi-file passbook/root/wsgi.py
|
- --wsgi-file passbook/root/wsgi.py
|
||||||
- --master
|
- --master
|
||||||
- --processes 24
|
- --enable-threads
|
||||||
- --threads 2
|
|
||||||
- --offload-threads 4
|
|
||||||
- --stats 0.0.0.0:8001
|
|
||||||
- --stats-http
|
|
||||||
envFrom:
|
envFrom:
|
||||||
- configMapRef:
|
- configMapRef:
|
||||||
name: {{ include "passbook.fullname" . }}-config
|
name: {{ include "passbook.fullname" . }}-config
|
||||||
|
|
|
@ -3,7 +3,6 @@ import re
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from random import SystemRandom
|
from random import SystemRandom
|
||||||
from time import sleep
|
from time import sleep
|
||||||
from typing import List
|
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
|
|
||||||
from django.contrib.auth.models import AbstractUser
|
from django.contrib.auth.models import AbstractUser
|
||||||
|
@ -18,6 +17,7 @@ from structlog import get_logger
|
||||||
from passbook.core.signals import password_changed
|
from passbook.core.signals import password_changed
|
||||||
from passbook.lib.models import CreatedUpdatedModel, UUIDModel
|
from passbook.lib.models import CreatedUpdatedModel, UUIDModel
|
||||||
from passbook.policy.exceptions import PolicyException
|
from passbook.policy.exceptions import PolicyException
|
||||||
|
from passbook.policy.struct import PolicyRequest, PolicyResult
|
||||||
|
|
||||||
LOGGER = get_logger(__name__)
|
LOGGER = get_logger(__name__)
|
||||||
|
|
||||||
|
@ -26,20 +26,6 @@ def default_nonce_duration():
|
||||||
"""Default duration a Nonce is valid"""
|
"""Default duration a Nonce is valid"""
|
||||||
return now() + timedelta(hours=4)
|
return now() + timedelta(hours=4)
|
||||||
|
|
||||||
|
|
||||||
class PolicyResult:
|
|
||||||
"""Small data-class to hold policy results"""
|
|
||||||
|
|
||||||
passing: bool = False
|
|
||||||
messages: List[str] = []
|
|
||||||
|
|
||||||
def __init__(self, passing: bool, *messages: str):
|
|
||||||
self.passing = passing
|
|
||||||
self.messages = messages
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return f"<PolicyResult passing={self.passing}>"
|
|
||||||
|
|
||||||
class Group(UUIDModel):
|
class Group(UUIDModel):
|
||||||
"""Custom Group model which supports a basic hierarchy"""
|
"""Custom Group model which supports a basic hierarchy"""
|
||||||
|
|
||||||
|
@ -244,7 +230,7 @@ class Policy(UUIDModel, CreatedUpdatedModel):
|
||||||
return self.name
|
return self.name
|
||||||
return "%s action %s" % (self.name, self.action)
|
return "%s action %s" % (self.name, self.action)
|
||||||
|
|
||||||
def passes(self, user: User) -> PolicyResult:
|
def passes(self, request: PolicyRequest) -> PolicyResult:
|
||||||
"""Check if user instance passes this policy"""
|
"""Check if user instance passes this policy"""
|
||||||
raise PolicyException()
|
raise PolicyException()
|
||||||
|
|
||||||
|
@ -288,11 +274,11 @@ class FieldMatcherPolicy(Policy):
|
||||||
description = "%s: %s" % (self.name, description)
|
description = "%s: %s" % (self.name, description)
|
||||||
return description
|
return description
|
||||||
|
|
||||||
def passes(self, user: User) -> PolicyResult:
|
def passes(self, request: PolicyRequest) -> PolicyResult:
|
||||||
"""Check if user instance passes this role"""
|
"""Check if user instance passes this role"""
|
||||||
if not hasattr(user, self.user_field):
|
if not hasattr(request.user, self.user_field):
|
||||||
raise ValueError("Field does not exist")
|
raise ValueError("Field does not exist")
|
||||||
user_field_value = getattr(user, self.user_field, None)
|
user_field_value = getattr(request.user, self.user_field, None)
|
||||||
LOGGER.debug("Checked '%s' %s with '%s'...",
|
LOGGER.debug("Checked '%s' %s with '%s'...",
|
||||||
user_field_value, self.match_action, self.value)
|
user_field_value, self.match_action, self.value)
|
||||||
passes = False
|
passes = False
|
||||||
|
@ -328,11 +314,11 @@ class PasswordPolicy(Policy):
|
||||||
|
|
||||||
form = 'passbook.core.forms.policies.PasswordPolicyForm'
|
form = 'passbook.core.forms.policies.PasswordPolicyForm'
|
||||||
|
|
||||||
def passes(self, user: User) -> PolicyResult:
|
def passes(self, request: PolicyRequest) -> PolicyResult:
|
||||||
# Only check if password is being set
|
# Only check if password is being set
|
||||||
if not hasattr(user, '__password__'):
|
if not hasattr(request.user, '__password__'):
|
||||||
return PolicyResult(True)
|
return PolicyResult(True)
|
||||||
password = getattr(user, '__password__')
|
password = getattr(request.user, '__password__')
|
||||||
|
|
||||||
filter_regex = r''
|
filter_regex = r''
|
||||||
if self.amount_lowercase > 0:
|
if self.amount_lowercase > 0:
|
||||||
|
@ -379,7 +365,7 @@ class WebhookPolicy(Policy):
|
||||||
|
|
||||||
form = 'passbook.core.forms.policies.WebhookPolicyForm'
|
form = 'passbook.core.forms.policies.WebhookPolicyForm'
|
||||||
|
|
||||||
def passes(self, user: User) -> PolicyResult:
|
def passes(self, request: PolicyRequest) -> PolicyResult:
|
||||||
"""Call webhook asynchronously and report back"""
|
"""Call webhook asynchronously and report back"""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
@ -398,7 +384,7 @@ class DebugPolicy(Policy):
|
||||||
|
|
||||||
form = 'passbook.core.forms.policies.DebugPolicyForm'
|
form = 'passbook.core.forms.policies.DebugPolicyForm'
|
||||||
|
|
||||||
def passes(self, user: User) -> PolicyResult:
|
def passes(self, request: PolicyRequest) -> PolicyResult:
|
||||||
"""Wait random time then return result"""
|
"""Wait random time then return result"""
|
||||||
wait = SystemRandom().randrange(self.wait_min, self.wait_max)
|
wait = SystemRandom().randrange(self.wait_min, self.wait_max)
|
||||||
LOGGER.debug("Policy '%s' waiting for %ds", self.name, wait)
|
LOGGER.debug("Policy '%s' waiting for %ds", self.name, wait)
|
||||||
|
@ -417,8 +403,8 @@ class GroupMembershipPolicy(Policy):
|
||||||
|
|
||||||
form = 'passbook.core.forms.policies.GroupMembershipPolicyForm'
|
form = 'passbook.core.forms.policies.GroupMembershipPolicyForm'
|
||||||
|
|
||||||
def passes(self, user: User) -> PolicyResult:
|
def passes(self, request: PolicyRequest) -> PolicyResult:
|
||||||
return PolicyResult(self.group.user_set.filter(pk=user.pk).exists())
|
return PolicyResult(self.group.user_set.filter(pk=request.user.pk).exists())
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
||||||
|
@ -430,10 +416,11 @@ class SSOLoginPolicy(Policy):
|
||||||
|
|
||||||
form = 'passbook.core.forms.policies.SSOLoginPolicyForm'
|
form = 'passbook.core.forms.policies.SSOLoginPolicyForm'
|
||||||
|
|
||||||
def passes(self, user) -> PolicyResult:
|
def passes(self, request: PolicyRequest) -> PolicyResult:
|
||||||
"""Check if user instance passes this policy"""
|
"""Check if user instance passes this policy"""
|
||||||
from passbook.core.auth.view import AuthenticationView
|
from passbook.core.auth.view import AuthenticationView
|
||||||
return PolicyResult(user.session.get(AuthenticationView.SESSION_IS_SSO_LOGIN, False))
|
is_sso_login = request.user.session.get(AuthenticationView.SESSION_IS_SSO_LOGIN, False)
|
||||||
|
return PolicyResult(is_sso_login)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,8 @@ from django.utils.timezone import now
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
from structlog import get_logger
|
from structlog import get_logger
|
||||||
|
|
||||||
from passbook.core.models import Policy, PolicyResult, User
|
from passbook.core.models import Policy
|
||||||
|
from passbook.policy.struct import PolicyRequest, PolicyResult
|
||||||
|
|
||||||
LOGGER = get_logger(__name__)
|
LOGGER = get_logger(__name__)
|
||||||
|
|
||||||
|
@ -20,15 +21,16 @@ class PasswordExpiryPolicy(Policy):
|
||||||
|
|
||||||
form = 'passbook.password_expiry_policy.forms.PasswordExpiryPolicyForm'
|
form = 'passbook.password_expiry_policy.forms.PasswordExpiryPolicyForm'
|
||||||
|
|
||||||
def passes(self, user: User) -> PolicyResult:
|
def passes(self, request: PolicyRequest) -> PolicyResult:
|
||||||
"""If password change date is more than x days in the past, call set_unusable_password
|
"""If password change date is more than x days in the past, call set_unusable_password
|
||||||
and show a notice"""
|
and show a notice"""
|
||||||
actual_days = (now() - user.password_change_date).days
|
actual_days = (now() - request.user.password_change_date).days
|
||||||
days_since_expiry = (now() - (user.password_change_date + timedelta(days=self.days))).days
|
days_since_expiry = (now() - (request.user.password_change_date + timedelta(days=self.days)
|
||||||
|
)).days
|
||||||
if actual_days >= self.days:
|
if actual_days >= self.days:
|
||||||
if not self.deny_only:
|
if not self.deny_only:
|
||||||
user.set_unusable_password()
|
request.user.set_unusable_password()
|
||||||
user.save()
|
request.user.save()
|
||||||
message = _(('Password expired %(days)d days ago. '
|
message = _(('Password expired %(days)d days ago. '
|
||||||
'Please update your password.') % {
|
'Please update your password.') % {
|
||||||
'days': days_since_expiry
|
'days': days_since_expiry
|
||||||
|
|
|
@ -7,8 +7,9 @@ from django.core.cache import cache
|
||||||
from django.http import HttpRequest
|
from django.http import HttpRequest
|
||||||
from structlog import get_logger
|
from structlog import get_logger
|
||||||
|
|
||||||
from passbook.core.models import Policy, PolicyResult, User
|
from passbook.core.models import Policy, User
|
||||||
from passbook.policy.task import PolicyTask
|
from passbook.policy.task import PolicyTask
|
||||||
|
from passbook.policy.struct import PolicyResult, PolicyRequest
|
||||||
|
|
||||||
LOGGER = get_logger()
|
LOGGER = get_logger()
|
||||||
|
|
||||||
|
@ -47,11 +48,8 @@ class PolicyEngine:
|
||||||
if not self.__user:
|
if not self.__user:
|
||||||
raise ValueError("User not set.")
|
raise ValueError("User not set.")
|
||||||
cached_policies = []
|
cached_policies = []
|
||||||
kwargs = {
|
request = PolicyRequest(self.__user)
|
||||||
'__password__': getattr(self.__user, '__password__', None),
|
request.http_request = self.__request
|
||||||
'session': dict(getattr(self.__request, 'session', {}).items()),
|
|
||||||
'request': self.__request,
|
|
||||||
}
|
|
||||||
for policy in self.policies:
|
for policy in self.policies:
|
||||||
cached_policy = cache.get(_cache_key(policy, self.__user), None)
|
cached_policy = cache.get(_cache_key(policy, self.__user), None)
|
||||||
if cached_policy:
|
if cached_policy:
|
||||||
|
@ -60,14 +58,13 @@ class PolicyEngine:
|
||||||
else:
|
else:
|
||||||
LOGGER.debug("Looking up real class of policy...")
|
LOGGER.debug("Looking up real class of policy...")
|
||||||
# TODO: Rewrite this to lookup all policies at once
|
# TODO: Rewrite this to lookup all policies at once
|
||||||
policy = Policy.objects.get_subclass(pk=policy.id)
|
policy = Policy.objects.get_subclass(pk=policy.pk)
|
||||||
LOGGER.debug("Evaluating policy %s", policy.pk.hex)
|
LOGGER.debug("Evaluating policy %s", policy.pk.hex)
|
||||||
our_end, task_end = Pipe(False)
|
our_end, task_end = Pipe(False)
|
||||||
task = PolicyTask()
|
task = PolicyTask()
|
||||||
task.ret = task_end
|
task.ret = task_end
|
||||||
task.user = self.__user
|
task.request = request
|
||||||
task.policy = policy
|
task.policy = policy
|
||||||
task.params = kwargs
|
|
||||||
LOGGER.debug("Starting Process %s", task.__class__.__name__)
|
LOGGER.debug("Starting Process %s", task.__class__.__name__)
|
||||||
task.start()
|
task.start()
|
||||||
self.__proc_list.append((our_end, task))
|
self.__proc_list.append((our_end, task))
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
"""policy structs"""
|
||||||
|
from typing import List
|
||||||
|
|
||||||
|
from django.http import HttpRequest
|
||||||
|
|
||||||
|
|
||||||
|
class PolicyRequest:
|
||||||
|
"""Data-class to hold policy request data"""
|
||||||
|
|
||||||
|
user: 'passbook.core.models.User'
|
||||||
|
http_request: HttpRequest
|
||||||
|
|
||||||
|
def __init__(self, user: 'passbook.core.models.User'):
|
||||||
|
self.user = user
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"<PolicyRequest user={self.user}>"
|
||||||
|
|
||||||
|
|
||||||
|
class PolicyResult:
|
||||||
|
"""Small data-class to hold policy results"""
|
||||||
|
|
||||||
|
passing: bool = False
|
||||||
|
messages: List[str] = []
|
||||||
|
|
||||||
|
def __init__(self, passing: bool, *messages: str):
|
||||||
|
self.passing = passing
|
||||||
|
self.messages = messages
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"<PolicyResult passing={self.passing}>"
|
|
@ -1,12 +1,12 @@
|
||||||
"""passbook policy task"""
|
"""passbook policy task"""
|
||||||
from multiprocessing import Process
|
from multiprocessing import Process
|
||||||
from multiprocessing.connection import Connection
|
from multiprocessing.connection import Connection
|
||||||
from typing import Any, Dict
|
|
||||||
|
|
||||||
from structlog import get_logger
|
from structlog import get_logger
|
||||||
|
|
||||||
from passbook.core.models import Policy, PolicyResult, User
|
from passbook.core.models import Policy
|
||||||
from passbook.policy.exceptions import PolicyException
|
from passbook.policy.exceptions import PolicyException
|
||||||
|
from passbook.policy.struct import PolicyRequest, PolicyResult
|
||||||
|
|
||||||
LOGGER = get_logger(__name__)
|
LOGGER = get_logger(__name__)
|
||||||
|
|
||||||
|
@ -18,18 +18,15 @@ class PolicyTask(Process):
|
||||||
"""Evaluate a single policy within a seprate process"""
|
"""Evaluate a single policy within a seprate process"""
|
||||||
|
|
||||||
ret: Connection
|
ret: Connection
|
||||||
user: User
|
|
||||||
policy: Policy
|
policy: Policy
|
||||||
params: Dict[str, Any]
|
request: PolicyRequest
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
"""Task wrapper to run policy checking"""
|
"""Task wrapper to run policy checking"""
|
||||||
for key, value in self.params.items():
|
|
||||||
setattr(self.user, key, value)
|
|
||||||
LOGGER.debug("Running policy `%s`#%s for user %s...", self.policy.name,
|
LOGGER.debug("Running policy `%s`#%s for user %s...", self.policy.name,
|
||||||
self.policy.pk.hex, self.user)
|
self.policy.pk.hex, self.request.user)
|
||||||
try:
|
try:
|
||||||
policy_result = self.policy.passes(self.user)
|
policy_result = self.policy.passes(self.request)
|
||||||
except PolicyException as exc:
|
except PolicyException as exc:
|
||||||
LOGGER.debug(exc)
|
LOGGER.debug(exc)
|
||||||
policy_result = PolicyResult(False, str(exc))
|
policy_result = PolicyResult(False, str(exc))
|
||||||
|
@ -37,7 +34,7 @@ class PolicyTask(Process):
|
||||||
if self.policy.negate:
|
if self.policy.negate:
|
||||||
policy_result = not policy_result
|
policy_result = not policy_result
|
||||||
LOGGER.debug("Policy %r#%s got %s", self.policy.name, self.policy.pk.hex, policy_result)
|
LOGGER.debug("Policy %r#%s got %s", self.policy.name, self.policy.pk.hex, policy_result)
|
||||||
# cache_key = _cache_key(self.policy, self.user)
|
# cache_key = _cache_key(self.policy, self.request.user)
|
||||||
# cache.set(cache_key, (self.policy.action, policy_result, message))
|
# cache.set(cache_key, (self.policy.action, policy_result, message))
|
||||||
# LOGGER.debug("Cached entry as %s", cache_key)
|
# LOGGER.debug("Cached entry as %s", cache_key)
|
||||||
self.ret.send(policy_result)
|
self.ret.send(policy_result)
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
"""passbook suspicious request policy"""
|
"""passbook suspicious request policy"""
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
|
from ipware import get_client_ip
|
||||||
|
|
||||||
from passbook.core.models import Policy, PolicyResult, User
|
from passbook.core.models import Policy, User
|
||||||
|
from passbook.policy.struct import PolicyRequest, PolicyResult
|
||||||
|
|
||||||
|
|
||||||
class SuspiciousRequestPolicy(Policy):
|
class SuspiciousRequestPolicy(Policy):
|
||||||
|
@ -14,14 +16,14 @@ class SuspiciousRequestPolicy(Policy):
|
||||||
|
|
||||||
form = 'passbook.suspicious_policy.forms.SuspiciousRequestPolicyForm'
|
form = 'passbook.suspicious_policy.forms.SuspiciousRequestPolicyForm'
|
||||||
|
|
||||||
def passes(self, user: User) -> PolicyResult:
|
def passes(self, request: PolicyRequest) -> PolicyResult:
|
||||||
remote_ip = user.remote_ip
|
remote_ip, _ = get_client_ip(request.http_request)
|
||||||
passing = True
|
passing = True
|
||||||
if self.check_ip:
|
if self.check_ip:
|
||||||
ip_scores = IPScore.objects.filter(ip=remote_ip, score__lte=self.threshold)
|
ip_scores = IPScore.objects.filter(ip=remote_ip, score__lte=self.threshold)
|
||||||
passing = passing and ip_scores.exists()
|
passing = passing and ip_scores.exists()
|
||||||
if self.check_username:
|
if self.check_username:
|
||||||
user_scores = UserScore.objects.filter(user=user, score__lte=self.threshold)
|
user_scores = UserScore.objects.filter(user=request.user, score__lte=self.threshold)
|
||||||
passing = passing and user_scores.exists()
|
passing = passing and user_scores.exists()
|
||||||
return PolicyResult(passing)
|
return PolicyResult(passing)
|
||||||
|
|
||||||
|
|
Reference in New Issue