diff --git a/.gitignore b/.gitignore index c6899f9..98556a3 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ local_settings.py *.dump .cache node_modules +.pytest_cache diff --git a/docker-compose.yml b/docker-compose.yml index 6871ce3..b404118 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,6 +3,8 @@ version: "2" services: db: image: postgres:9.4 + ports: + - "8574:5432" # run the site with the django dev-server web: diff --git a/requirements-dev.txt b/requirements-dev.txt index affa9bf..98c74f7 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,21 +1,21 @@ -r requirements.txt -pytest==3.3.1 \ - --hash=sha256:ae4a2d0bae1098bbe938ecd6c20a526d5d47a94dc42ad7331c9ad06d0efe4962 \ - --hash=sha256:cf8436dc59d8695346fcd3ab296de46425ecab00d64096cebe79fb51ecb2eb93 +pytest==3.4.0 \ + --hash=sha256:95fa025cd6deb5d937e04e368a00552332b58cae23f63b76c8c540ff1733ab6d \ + --hash=sha256:6074ea3b9c999bd6d0df5fa9d12dd95ccd23550df2a582f5f5b848331d2e82ca pytest-django==3.1.2 \ --hash=sha256:00995c2999b884a38ae9cd30a8c00ed32b3d38c1041250ea84caf18085589662 \ --hash=sha256:038ccc5a9daa1b1b0eb739ab7dce54e495811eca5ea3af4815a2a3ac45152309 mock==2.0.0 --hash=sha256:5ce3c71c5545b472da17b72268978914d0252980348636840bd34a00b5cc96c1 -factory-boy==2.9.2 \ - --hash=sha256:b8334bcc3c5b10af9a83ab5b8786f98cb322638dc1e6d320cad01c7f2b420e87 \ - --hash=sha256:340c602f6fed2d8dd160397f28f2c0219e937f0488460450e8e5bf2add020ed6 +factory-boy==2.10.0 \ + --hash=sha256:be2abc8092294e4097935a29b4e37f5b9ed3e4205e2e32df215c0315b625995e \ + --hash=sha256:bd5a096d0f102d79b6c78cef1c8c0b650f2e1a3ecba351c735c6d2df8dabd29c python-dateutil==2.6.1 \ --hash=sha256:95511bae634d69bc7329ba55e646499a842bc4ec342ad54a8cdb65645a0aad3c \ --hash=sha256:891c38b2a02f5bb1be3e4793866c8df49c7d19baabf9c1bad62547e0b4866aca -Sphinx==1.6.5 \ - --hash=sha256:fdf77f4f30d84a314c797d67fe7d1b46665e6c48a25699d7bf0610e05a2221d4 \ - --hash=sha256:c6de5dbdbb7a0d7d2757f4389cc00e8f6eb3c49e1772378967a12cfcf2cfe098 +Sphinx==1.6.6 \ + --hash=sha256:b8baed19394af85b21755c68c7ec4eac57e8a482ed89cd01cd5d5ff72200fe0f \ + --hash=sha256:c39a6fa41bd3ec6fc10064329a664ed3a3ca2e27640a823dc520c682e4433cdb pbr==3.1.1 \ --hash=sha256:60c25b7dfd054ef9bb0ae327af949dd4676aa09ac3a9471cdc871d8a9213f9ac \ --hash=sha256:05f61c71aaefc02d8e37c0a3eeb9815ff526ea28b3b76324769e6158d7f95be1 @@ -33,9 +33,9 @@ docutils==0.14 \ alabaster==0.7.10 \ --hash=sha256:2eef172f44e8d301d25aff8068fddd65f767a3f04b5f15b0f4922f113aa1c732 \ --hash=sha256:37cdcb9e9954ed60912ebc1ca12a9d12178c26637abdf124e3cde2341c257fe0 -babel==2.5.1 \ - --hash=sha256:f20b2acd44f587988ff185d8949c3e208b4b3d5d20fcab7d91fe481ffa435528 \ - --hash=sha256:6007daf714d0cd5524bbe436e2d42b3c20e68da66289559341e48d2cd6d25811 +babel==2.5.3 \ + --hash=sha256:ad209a68d7162c4cff4b29cdebe3dec4cef75492df501b0049a9433c96ce6f80 \ + --hash=sha256:8ce4cb6fdd4393edd323227cba3a077bceb2a6ce5201c902c65e730046f41f14 snowballstemmer==1.2.1 --hash=sha256:9f3bcd3c401c3e862ec0ebe6d2c069ebc012ce142cce209c098ccb5b09136e89 urlwait==0.4 \ --hash=sha256:fc39ff2c8abbcaad5043e1f79699dcb15a036cc4b0ff4d1aa825ea105d4889ff \ @@ -58,9 +58,9 @@ requests-mock==1.4.0 \ pytest-wholenodeid==0.2 \ --hash=sha256:6bc4edaf560c8b45ac4669bb8b99d8fbbb7f6e5af8dc7727200cd4d3ef4668c2 \ --hash=sha256:bdcb4df88ca182a19752ef95150c0881deaafc2c593ef67c61515894e5309206 -Faker==0.8.8 \ - --hash=sha256:2f6ccc9da046d4cd20401734cf6a1ac73a4e4d8256e7b283496ee6827ad2eb60 \ - --hash=sha256:e928cf853ef69d7471421f2a3716a1239e43de0fa9855f4016ee0c9f1057328a +Faker==0.8.10 \ + --hash=sha256:91c3e79db508f6e2b8ff3d3099fee0967c95ce02caa1f4028096641696336fc0 \ + --hash=sha256:9da4c829d5592202a614d2db3c3e05d17684f5b590b7dbd6d7e70dc1053213a6 sphinxcontrib-websupport==1.0.1 \ --hash=sha256:7a85961326aa3a400cd4ad3c816d70ed6f7c740acd7ce5d78cd0a67825072eb9 \ --hash=sha256:f4932e95869599b89bf4f80fc3989132d83c9faa5bf633e7b5e0c25dffb75da2 diff --git a/requirements.txt b/requirements.txt index fb97d01..5ad2985 100644 --- a/requirements.txt +++ b/requirements.txt @@ -48,9 +48,9 @@ dj-database-url==0.4.2 \ --hash=sha256:e16d94c382ea0564c48038fa7fe8d9c890ef1ab1a8ec4cb48e732c124b9482fd # base -Django==1.11.9 \ - --hash=sha256:90952c46d2b7b042db00e98b05f5dd97a5775822948d46fd82ff074d8ac75853 \ - --hash=sha256:353d129f22e1d24980d6061666f435781141c2dfd852f14ffc8a670175821034 +Django==2.0.2 \ + --hash=sha256:7c8ff92285406fb349e765e9ade685eec7271d6f5c3f918e495a74768b765c99 \ + --hash=sha256:dc3b61d054f1bced64628c62025d480f655303aea9f408e5996c339a543b45f0 bleach==2.1.2 \ --hash=sha256:cf567e7ed30ea5e05b31231d88ae170af1c5544758b9d7bebbc20590b7c30b1e \ --hash=sha256:38fc8cbebea4e787d8db55d6f324820c7f74362b70db9142c1ac7920452d1a19 @@ -63,23 +63,24 @@ Jinja2==2.10 \ django-jinja==2.4.1 \ --hash=sha256:ceaa0eeebc4d91a5800967e50f4f087f0b6457503e3c2af85dc199bed8732a9a \ --hash=sha256:8a49d73de616a12075eee14c6d3bbab936261a463457d40348d8b8e2995cfbed -Unidecode==0.04.21 \ - --hash=sha256:61f807220eda0203a774a09f84b4304a3f93b5944110cc132af29ddb81366883 \ - --hash=sha256:280a6ab88e1f2eb5af79edff450021a0d3f0448952847cd79677e55e58bad051 +Unidecode==1.0.22 \ + --hash=sha256:72f49d3729f3d8f5799f710b97c1451c5163102e76d64d20e170aedbbd923582 \ + --hash=sha256:8c33dd588e0c9bc22a76eaa0c715a5434851f726131bd44a6c26471746efabf5 MarkupSafe==1.0 \ --hash=sha256:a6be69091dac236ea9c6bc7d012beab42010fa914c459791d627dad4910eb665 django-jinja-markdown==1.0.1 --hash=sha256:233dcde5d6895416f5613e4ca030e88f18a163e4b676e7aa815d191754f53085 -Markdown==2.6.10 \ - --hash=sha256:cfa536d1ee8984007fcecc5a38a493ff05c174cb74cb2341dafd175e6bc30851 +Markdown==2.6.11 \ + --hash=sha256:9ba587db9daee7ec761cfc656272be6aabe2ed300fece21208e4aab2e457bc8f \ + --hash=sha256:a856869c7ff079ad84a3e19cd87a64998350c2b94e9e08e44270faef33400f81 six==1.11.0 \ --hash=sha256:832dc0e10feb1aa2c68dcc57dbb658f1c7e65b9b61af69048abc87a2db00a0eb \ --hash=sha256:70e8a77beed4562e7f14fe23a786b54f6296e34344c23bc42f07b15018ff98e9 html5lib==1.0.1 \ --hash=sha256:20b159aa3badc9d5ee8f5c647e5efd02ed2a66ab8d354930bd9ff139fc1dc0a3 \ --hash=sha256:66cb0dcfdbbc4f9c3ba1a63fdb511ffdbd4f513b2b6d81b80cd26ce6b3fb3736 -django-pipeline==1.6.13 \ - --hash=sha256:81d8dd2db4c582bdfd0dc1df875c6b538c0a5ee233e954a52ae17f3ce904f604 \ - --hash=sha256:d67ac0fc2556e3c5b5080ee96f8e661bda9a1e4b46b8fffbef3fb5524b6ef11e +django-pipeline==1.6.14 \ + --hash=sha256:b56f2cfdb113dc1cb05257d8eb8d145fc0ade6f0d1236fb425df15bd059dce15 \ + --hash=sha256:ef67aaf58959a2959e13fc114001cee5beec05ac18a81cc700ea9f1c8e3f40a8 https://github.com/pmac/django-gravatar/archive/5f88e14fb6dd3134a46e2a961ab2782591e85f28.tar.gz#egg=django-gravatar2==1.4.0 \ --hash=sha256:45ff4567de125c16b718c1b1829a2e000e6f7901149e0a05a1f65cdc3076aa62 PyJWT==1.5.3 \ @@ -91,14 +92,14 @@ defusedxml==0.5.0 \ requests==2.18.4 \ --hash=sha256:6a1b267aa90cac58ac3a765d067950e7dbbf75b1da07e895d1f594193a40a38b \ --hash=sha256:9c443e7324ba5b85070c4a818ade28bfabedf16ea10206da1132edaa6dda237e -raven==6.4.0 \ - --hash=sha256:2c9cd4d8c267f57db625305aaa89e7dd852d6864c13c7b84f4d4500df07bebd9 \ - --hash=sha256:b8edbb3335ed6c23cb168ced37fb523c1b91d9f3b0eddb90934249977841a902 +raven==6.5.0 \ + --hash=sha256:0adae40e004dfe2181d1f2883aa3d4ca1cf16dbe449ae4b445b011c6eb220a90 \ + --hash=sha256:84da75114739191bdf2388f296ffd6177e83567a7fbaf2701e034ad6026e4f3b contextlib2==0.5.5 \ --hash=sha256:f5260a6e679d2ff42ec91ec5252f4eeffdcf21053db9113bd0a8e4d953769c00 \ --hash=sha256:509f9419ee91cdd00ba34443217d5ca51f5a364a404e1dce9e8979cea969ca48 -newrelic==2.98.0.81 \ - --hash=sha256:965214625392d41b9620c6928a6b10036bf1e2a2b797cdb6682650e95e1f616e +newrelic==2.100.0.84 \ + --hash=sha256:b75123173ac5e8a20aa9d8120e20a7bf45c38a5aa5a4672fac6ce4c3e0c8046e django-cache-url==2.0.0 \ --hash=sha256:d7e7d3f3fadaa38ab7c655afafc85c2a1b06a3ddc0002af4ae021c1948307f8b \ --hash=sha256:f0009452c4d63468714c7ff59266085947f3f3cc0947b3b2e87121bb27538d6c @@ -139,12 +140,12 @@ pytz==2017.3 \ --hash=sha256:dd2e4ca6ce3785c8dd342d1853dd9052b19290d5bf66060846e5dc6b8d6667f7 \ --hash=sha256:699d18a2a56f19ee5698ab1123bbcc1d269d061996aeb1eda6d89248d3542b82 \ --hash=sha256:fae4cffc040921b8a2d60c6cf0b5d662c1190fe54d718271db4eb17d44a185b7 -mozilla-django-oidc==0.4.2 \ - --hash=sha256:650716143525bb4bae553dd8c740a1c5986baf6aeae115cba01f6a217ee5fa4f \ - --hash=sha256:77c29c47d67750d3c53fcd51f1aa496a2cdd65dd27a1f2a15e56ecc3c3714f19 -python-jose==1.4.0 \ - --hash=sha256:fed56224664af0ebc3947853f1bed23b5609f90c7b02e3dce5ef5757d0301664 \ - --hash=sha256:18e19f200f37a8ee6247921572807cc63ee034abdbf6854df1ae7c1f505cabcc +mozilla-django-oidc==0.5.0 \ + --hash=sha256:ab6dcccf4841472c1e82244d66503e87ffae0ad7d38d6187fcca54810eceb7a6 \ + --hash=sha256:56d72b3a35cbe9b313e4ec19a01943d4ca698562476d3387c3ab30e66d33bcf8 +python-jose==2.0.2 \ + --hash=sha256:3b35cdb0e55a88581ff6d3f12de753aa459e940b50fe7ca5aa25149bc94cb37b \ + --hash=sha256:391f860dbe274223d73dd87de25e4117bf09e8fe5f93a417663b1f2d7b591165 pycrypto==2.6.1 \ --hash=sha256:f2ce1e989b272cfcb677616763e0a2e7ec659effa67a88aa92b3a65528f60a3c ecdsa==0.13 \ @@ -164,9 +165,9 @@ idna==2.6 \ urllib3==1.22 \ --hash=sha256:06330f386d6e4b195fbfc736b297f58c5a892e4440e54d294d7004e3a9bbea1b \ --hash=sha256:cc44da8e1145637334317feebd728bd869a35285b93cbb4cca2577da7e62db4f -certifi==2017.11.5 \ - --hash=sha256:244be0d93b71e93fc0a0a479862051414d0e00e16435707e5bf5000f92e04694 \ - --hash=sha256:5ec74291ca1136b40f0379e1128ff80e866597e4e2c1e755739a913bbc3613c0 +certifi==2018.1.18 \ + --hash=sha256:14131608ad2fd56836d33a71ee60fa1c82bc9d2c8d98b7bdbc631fe1b3cd1296 \ + --hash=sha256:edbc3f203427eef571f79a7692bb160a2b0f7ccaa31953e99bd17e307cf63f7d email_validator==1.0.3 \ --hash=sha256:ddc4b5b59fa699bb10127adcf7ad4de78fde4ec539a072b104b8bb16da666ae5 UkPostcodeParser==1.1.2 \ @@ -176,9 +177,6 @@ UkPostcodeParser==1.1.2 \ dnspython==1.15.0 \ --hash=sha256:861e6e58faa730f9845aaaa9c6c832851fbf89382ac52915a51f89c71accdd31 \ --hash=sha256:40f563e1f7a7b80dc5a4e76ad75c23da53d62f1e15e6e517293b04e1f84ead7c -django-soapbox==1.5 \ - --hash=sha256:a65810a406416e3a945feb6c834a58fac341f506e7d1ea1b8abc488df5562f7e \ - --hash=sha256:9f330db2b4098d24d7a2c4c9de63b0cc4d5579c69c2a904621914371f8039200 cryptography==2.1.4 \ --hash=sha256:69285f5615507b6625f89ea1048addd1d9218585fb886eb90bdebb1d2b2d26f5 \ --hash=sha256:6cb1224da391fa90f1be524eafb375b62baf8d3df9690b32e8cc475ccfccee5e \ @@ -203,38 +201,34 @@ cryptography==2.1.4 \ --hash=sha256:a3c180d12ffb1d8ee5b33a514a5bcb2a9cc06cc89aa74038015591170c82f55d \ --hash=sha256:8487524a1212223ca6dc7e2c8913024618f7ff29855c98869088e3818d5f6733 \ --hash=sha256:e4d967371c5b6b2e67855066471d844c5d52d210c36c28d49a8507b96e2c5291 -cffi==1.11.2 \ - --hash=sha256:2c707e97ad7b0417713543be7cb87315c015bb5dd97903480168d60ebe3e313e \ - --hash=sha256:6d8c7e20eb90be9e1ccce8e8dd4ee5163b37289fc5708f9eeafc00adc07ba891 \ - --hash=sha256:627298d788edcb317b6a01347428501e773f5e8f2988407231c07e50e3f6c1cf \ - --hash=sha256:bdd28cf8302eeca1b4c70ec727de384d4f6ea640b0e698934fd9b4c3bc88eeb1 \ - --hash=sha256:248198cb714fe09f5c60b6acba3675d52199c6142641536796cdf89dd45e5590 \ - --hash=sha256:c962cb68987cbfb70b034f153bfa467c615c0b55305d39b3237c4bdbdbc8b0f4 \ - --hash=sha256:401ba2f6c1f1672b6c38670e1c00fa5f84f841edd30c32742dab5c7151cd89bf \ - --hash=sha256:3ac9be5763238da1d6fa467c43e3f86472626837a478588c94165df09e62e120 \ - --hash=sha256:d54a7c37f954fdbb971873c935a77ddc33690cec9b7ac254d9f948c43c32fa83 \ - --hash=sha256:1c103c0ee8235c47c4892288b2287014f33e7cb24b9d4a665be3aa744377dcb9 \ - --hash=sha256:d7461ef8671ae40f991384bbc4a6b1b79f4e7175d8052584be44041996f46517 \ - --hash=sha256:4d9bf1b23896bcd4d042e823f50ad36fb6d8e1e645a3dfb2fe2f070851489b92 \ - --hash=sha256:61cf049b1c649d8eec360a1a1d09a61c37b9b2d542364506e8feb4afd232363d \ - --hash=sha256:ce3da410ae2ab8709565cc3b18fbe9a0eb96ea7b2189416098c48d839ecced84 \ - --hash=sha256:e72d8b5056f967ecb57e166537408bc913f2f97dc568027fb6342fcfa9f81d64 \ - --hash=sha256:11a8ba88ef6ae89110ef029dae7f1a293365e50bdd0c6ca973beed80cec95ae4 \ - --hash=sha256:974f69112721ba2e8a6acd0f6b68a5e11432710a3eca4e4e6f4d7aaf99214ed1 \ - --hash=sha256:062c66dabc3faf8e0db1ca09a6b8e308846e5d35f43bed1a68c492b0d96ac171 \ - --hash=sha256:03a9b9efc280dbe6be149a7fa689f59a822df009eee633fdaf55a6f38795861f \ - --hash=sha256:8b3d6dc9981cedfb1ddcd4600ec0c7f5ac2c6ad2dc482011c7eecb4ae9c819e0 \ - --hash=sha256:09b7d195d163b515ef7c2b2e26a689c9816c83d5319cceac6c36ffdab97ab048 \ - --hash=sha256:943b94667749d1cfcd964e215a20b9c891deae913202ee8eacaf2b94164b155f \ - --hash=sha256:89829f5cfbcb5ad568a3d61bd23a8e33ad69b488d8f6a385e0097a4c20742a9b \ - --hash=sha256:ba78da7c940b041cdbb5aaff5afe11e8a8f25fe19564c12eefea5c5bd86930ca \ - --hash=sha256:a79b15b9bb4726672865cf5b0f63dee4835974a2b11b49652d70d49003f5d1f4 \ - --hash=sha256:f6799913eb510b682de971ddef062bbb4a200f190e55cae81c413bc1fd4733c1 \ - --hash=sha256:e7f5ad6b12f21b77d3a37d5c67260e464f4e9068eb0c0622f61d0e30390b31b6 \ - --hash=sha256:5f96c92d5f5713ccb71e76dfa14cf819c59ecb9778e94bcb541e13e6d96d1ce5 \ - --hash=sha256:5357b465e3d6b98972b7810f9969c913d365e75b09b7ba813f5f0577fe1ac9f4 \ - --hash=sha256:75e1de9ba7c155d89bcf67d149b1c741df553c8158536e8d27e63167403159af \ - --hash=sha256:ab87dd91c0c4073758d07334c1e5f712ce8fe48f007b86f8238773963ee700a6 +cffi==1.11.4 \ + --hash=sha256:5d0d7023b72794ea847725680e2156d1d01bc698a9007fccce46d03c904fe093 \ + --hash=sha256:86903c0afab4a3390170aca61f753f5adad8ffff947030719ee44dedc5b68403 \ + --hash=sha256:7d35678a54da0d3f1bc30e3a58a232043753d57c691875b5a75e4e062793bc9a \ + --hash=sha256:824cac33906be5c8e976f0d950924d88ec058989ef9cd2f77f5cd53cec417635 \ + --hash=sha256:6ca52651f6bd4b8647cb7dee15c82619de3e13490f8e0bc0620830a2245b51d1 \ + --hash=sha256:a183959a4b1e01d6172aeed356e2523ec8682596075aa6cf0003fe08da959a49 \ + --hash=sha256:9532c5bc0108bd0fe43c0eb3faa2ef98a2db60fc0d4019f106b88d46803dd663 \ + --hash=sha256:96652215ef328262b5f1d5647632bd342ac6b31dfbc495b21f1ab27cb06d621d \ + --hash=sha256:6c99d19225e3135f6190a3bfce2a614cae8eaa5dcaf9e0705d4ccb79a3959a3f \ + --hash=sha256:12cbf4c04c1ad07124bfc9e928c01e282feac9ec7dd72a18042d4fc56456289a \ + --hash=sha256:69c37089ccf10692361c8d14dbf4138b00b46741ffe9628755054499f06ed548 \ + --hash=sha256:b8d1454ef627098dc76ccfd6211a08065e6f84efe3754d8d112049fec3768e71 \ + --hash=sha256:cd13f347235410c592f6e36395ee1c136a64b66534f10173bfa4df1dc88f47d0 \ + --hash=sha256:0640f12f04f257c4467075a804a4920a5d07ef91e11c525fc65d715c08231c81 \ + --hash=sha256:89a8d05b96bdeca8fdc89c5fa9469a357d30f6c066262e92c0c8d2e4d3c53cae \ + --hash=sha256:a67c430a9bde73ae85b0c885fcf41b556760e42ea74c16dc70431a349989b448 \ + --hash=sha256:7a831170b621e98f45ed1d5758325be19619a593924127a0a47af9a72a117319 \ + --hash=sha256:796d0379102e6da5215acfcd20e8e69cca9d97309215b4ce088fe175b1c2f586 \ + --hash=sha256:0fe3b3d571543a4065059d1d3d6d39f4ca6da0f2207ad13547094522e32ead46 \ + --hash=sha256:678135090c311780382b1dd3f828f715583ea8a69687ed053c047d3cec6625d6 \ + --hash=sha256:f4992cd7b4c867f453d44c213ee29e8fd484cf81cfece4b6e836d0982b6fa1cf \ + --hash=sha256:6d191fb20138fe1948727b20e7b96582b7b7e676135eabf72d910e10bf7bfa65 \ + --hash=sha256:ec208ca16e57904dd7f4c7568665f80b1f7eb7e3214be014560c28def219060d \ + --hash=sha256:b3653644d6411bf4bd64c1f2ca3cb1b093f98c68439ade5cef328609bbfabf8c \ + --hash=sha256:f4719d0bafc5f0a67b2ec432086d40f653840698d41fa6e9afa679403dea9d78 \ + --hash=sha256:87f837459c3c78d75cb4f5aadf08a7104db15e8c7618a5c732e60f252279c7a6 \ + --hash=sha256:df9083a992b17a28cd4251a3f5c879e0198bb26c9e808c4647e0a18739f1d11d asn1crypto==0.24.0 \ --hash=sha256:2f1adbb7546ed199e3c90ef23ec95c5cf3585bac7d11fb7eb562a3fe89c64e87 \ --hash=sha256:9d5c20441baf0cb60a4ac34cc447c6c189024b6b4c6cd7877034f4965c464e49 @@ -249,6 +243,30 @@ pyOpenSSL==17.5.0 \ text-unidecode==1.1 \ --hash=sha256:d0afd5e8a7ac69bfb1372e1bbfa3c63c22e3db8ae1284690e96b45c4430d08d0 \ --hash=sha256:02efd86b9c0f489f858d8cead62e94d3760dab444054b258734716f7602330a3 -futures==3.1.1 \ - --hash=sha256:c4884a65654a7c45435063e14ae85280eb1f111d94e542396717ba9828c4337f \ - --hash=sha256:51ecb45f0add83c806c68e4b06106f90db260585b25ef2abfcda0bd95c0132fd +pycryptodome==3.4.11 \ + --hash=sha256:444053c24b336daa7f84bf872df7a6b9950697559926aea5775f5aa757b67a3e \ + --hash=sha256:29d3a581cfcc68ca66f7c5d4830944556ddca9e2747e214bde8028972bb1901f \ + --hash=sha256:89a0a233ed3a216ae117323d8fb0da38f1ca344dc1021559e38416cce23592a0 \ + --hash=sha256:5d390f8c6562173b913f0359cd87d5bc2e3245cc88ec4edf59d8c52107f24d29 \ + --hash=sha256:7bda0f395fd8ef6b1fa7cded00d5cca72005ff158fc30703e1337fe32fbf2102 \ + --hash=sha256:bdd8581dae617b9fbe6e8dbdd96590c02fc33eebc411b0273fd62b4d468d0bb7 \ + --hash=sha256:44ad06faf5ee589c1127a18610695a65815ed5db724b58687294ee907ec546ba \ + --hash=sha256:c8922f187fcac3b2afa6d200ef00cd4e69719799b54b4f2f2741b2e4c96ccd61 \ + --hash=sha256:2aeded7095564b8a068402531c7407517cd714a0fe9872f76c69bd4400b07613 \ + --hash=sha256:c88e9a04d3ed89689bc76ce0a90b018cdd4edb94ab99ce31264f2e15bad9d752 \ + --hash=sha256:64a0cccf590546e7de602378f21482cb06cd1a1995cdfb121b123394c48b05c3 \ + --hash=sha256:21fd74571b3579cbf36792916ad76a4ecf91581a112bb78ec48e20389dcdb912 \ + --hash=sha256:11ca73effcc15596b62d601a6b3c48ea607fb5219546d406312520d63c446bf5 \ + --hash=sha256:ce3110812d8823c3182fc7f841031387ee6fda27d8696da8949a99b026048e7e \ + --hash=sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 \ + --hash=sha256:d9ae42a88c716a7ca9a53966562968921883211b6390eeab22e5b735dbc49f49 \ + --hash=sha256:d3136fe71a37882ca457bea5917f1db5431f18f1bd91b0f7c4cec57ac4d57016 \ + --hash=sha256:0ebbcdbd21b5d8569c5b44137e2071d28c14a7460afdd8b1f6398a1548c4773a \ + --hash=sha256:5ce44a755be8aef369d1057a38bff01501db0b89ba38c3292578f42ed401f355 \ + --hash=sha256:1d3065b741ec8d269327e4487eacd187e0bf909e7a73d0a959da1a0918b16fa9 \ + --hash=sha256:cb81302f3295a14722f6c26c44ab4023d66f8394db4c316ccf5658dbada2ac91 \ + --hash=sha256:4fd2584719895ff041cf48766014ef6b5a170f5caf0e2dc735837b182e78d081 \ + --hash=sha256:c5dd29e9f1b733e74311bf95d0e544e91bd1d14bc0366e8f443562d8d9920b7d +sqlparse==0.2.4 \ + --hash=sha256:d9cf190f51cbb26da0412247dfe4fb5f4098edb73db84e02f9fc21fdca31fed4 \ + --hash=sha256:ce028444cfab83be538752a2ffdb56bc417b7784ff35bb9a3062413717807dec diff --git a/standup/api/tests/test_views.py b/standup/api/tests/test_views.py index 42fc55e..48c78c8 100644 --- a/standup/api/tests/test_views.py +++ b/standup/api/tests/test_views.py @@ -1,6 +1,6 @@ import json -from django.core.urlresolvers import reverse +from django.urls import reverse from django.utils.encoding import force_bytes from django.test import Client, TestCase diff --git a/standup/api/urls.py b/standup/api/urls.py index 1a920cc..2b40aca 100644 --- a/standup/api/urls.py +++ b/standup/api/urls.py @@ -1,12 +1,11 @@ -from django.conf.urls import url +from django.urls import path from . import views urlpatterns = [ - url(r'^v1/status/(?P\d{1,8})/$', views.StatusDelete.as_view(), name='api.status-delete'), - url(r'^v1/status/', views.StatusCreate.as_view(), name='api.status-create'), + path('v1/status//', views.StatusDelete.as_view(), name='api.status-delete'), + path('v1/status/', views.StatusCreate.as_view(), name='api.status-create'), # FIXME(willkg): Re-enable this after we've reimplemented the UpdateUser view - # url(r'^v1/user/(?P[a-zA-Z0-9]+)/$', views.UpdateUser.as_view(), name='api.user-update'), - url(r'v1/messages/$', views.site_messages, name='api.site_messages'), + # path('v1/user//', views.UpdateUser.as_view(), name='api.user-update'), ] diff --git a/standup/api/views.py b/standup/api/views.py index 8bab5b1..25f5404 100644 --- a/standup/api/views.py +++ b/standup/api/views.py @@ -11,11 +11,8 @@ from django.utils.encoding import force_str from django.utils.text import slugify from django.views.decorators.csrf import csrf_exempt -from django.views.decorators.http import require_safe from django.views.generic import View -from soapbox.models import Message - from .models import SystemToken from standup.status.models import Project, Status, StandupUser @@ -73,12 +70,6 @@ def __init__(self, content, status=None, cors=False): self['Access-Control-Allow-Origin'] = '*' -@require_safe -def site_messages(request): - messages = [m.message for m in Message.objects.match('/api/')] - return HttpResponseJSON(messages, cors=True) - - class APIView(View): """API view that looks at the world in JSON""" @classmethod diff --git a/standup/settings.py b/standup/settings.py index c636e2a..485461f 100644 --- a/standup/settings.py +++ b/standup/settings.py @@ -51,7 +51,6 @@ def path(*paths): 'pipeline', 'django_gravatar', 'raven.contrib.django.raven_compat', - 'soapbox', 'standup.api', 'standup.status', diff --git a/standup/status/jinja2/base.html b/standup/status/jinja2/base.html index 19b3f10..93cce93 100644 --- a/standup/status/jinja2/base.html +++ b/standup/status/jinja2/base.html @@ -69,7 +69,7 @@ Search
  • - {% if user.is_authenticated() %} + {% if user.is_authenticated %} {{ gravatar(user, 22) }}
    • My statuses
    • @@ -91,9 +91,12 @@
      - {% for message in get_messages_for_page(request) %} -
      {{ message }}
      - {% endfor %} + {# FIXME(willkg): hard-coded messages #} +
      + We've switched the way we use Auth0. If you have problems, see + our FAQ. +
      + {# ENDFIXME #} {% if messages %} {% for message in messages %}
      {{ message }}
      @@ -101,7 +104,7 @@ {% endif %}
      {% block before_content %} - {% if user.is_authenticated() %} + {% if user.is_authenticated %} {{ statusize() }} {% endif %} {% endblock %} @@ -131,7 +134,7 @@
      - {% if user.is_authenticated() %} + {% if user.is_authenticated %}
      {% csrf_token %}
      diff --git a/standup/status/migrations/0001_initial.py b/standup/status/migrations/0001_initial.py index dd22dac..a7b4618 100644 --- a/standup/status/migrations/0001_initial.py +++ b/standup/status/migrations/0001_initial.py @@ -48,10 +48,12 @@ class Migration(migrations.Migration): ('created', models.DateTimeField(default=django.utils.timezone.now)), ('content', models.TextField()), ('content_html', models.TextField()), - ('project', models.ForeignKey(to='status.Project', null=True, blank=True, related_name='statuses')), + ('project', models.ForeignKey(to='status.Project', null=True, blank=True, + on_delete=models.SET_DEFAULT, related_name='statuses')), ('reply_to', models.ForeignKey(to='status.Status', null=True, blank=True, - on_delete=django.db.models.deletion.SET_DEFAULT, default=None)), - ('user', models.ForeignKey(to='status.StandupUser', related_name='statuses')), + on_delete=models.SET_DEFAULT, default=None)), + ('user', models.ForeignKey(to='status.StandupUser', on_delete=models.SET_DEFAULT, + related_name='statuses')), ], options={ 'db_table': 'status', @@ -74,8 +76,8 @@ class Migration(migrations.Migration): name='TeamUser', fields=[ ('id', models.AutoField(serialize=False, auto_created=True, verbose_name='ID', primary_key=True)), - ('team', models.ForeignKey(to='status.Team')), - ('user', models.ForeignKey(to='status.StandupUser')), + ('team', models.ForeignKey(to='status.Team', on_delete=models.SET_DEFAULT)), + ('user', models.ForeignKey(to='status.StandupUser', on_delete=models.SET_DEFAULT)), ], options={ 'db_table': 'team_users', diff --git a/standup/status/migrations/0002_standupuser_user.py b/standup/status/migrations/0002_standupuser_user.py index 098d778..720caf6 100644 --- a/standup/status/migrations/0002_standupuser_user.py +++ b/standup/status/migrations/0002_standupuser_user.py @@ -16,6 +16,11 @@ class Migration(migrations.Migration): migrations.AddField( model_name='standupuser', name='user', - field=models.OneToOneField(null=True, to=settings.AUTH_USER_MODEL, related_name='profile'), + field=models.OneToOneField( + null=True, + to=settings.AUTH_USER_MODEL, + on_delete=models.CASCADE, + related_name='profile' + ), ), ] diff --git a/standup/status/migrations/0004_auto_20160902_2117.py b/standup/status/migrations/0004_auto_20160902_2117.py index d141962..dddf15d 100644 --- a/standup/status/migrations/0004_auto_20160902_2117.py +++ b/standup/status/migrations/0004_auto_20160902_2117.py @@ -27,6 +27,10 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='standupuser', name='user', - field=models.OneToOneField(to=settings.AUTH_USER_MODEL, related_name='profile'), + field=models.OneToOneField( + to=settings.AUTH_USER_MODEL, + on_delete=models.CASCADE, + related_name='profile' + ), ), ] diff --git a/standup/status/migrations/0020_auto_20180209_1625.py b/standup/status/migrations/0020_auto_20180209_1625.py new file mode 100644 index 0000000..91b31ef --- /dev/null +++ b/standup/status/migrations/0020_auto_20180209_1625.py @@ -0,0 +1,35 @@ +# Generated by Django 2.0.2 on 2018-02-09 16:25 + +from django.db import migrations + + +def fwds(apps, schema_editor): + ContentType = apps.get_model('contenttypes', 'ContentType') + Permission = apps.get_model('auth', 'Permission') + + content_types = ContentType.objects.filter(app_label='soapbox') + for ct in content_types: + Permission.objects.filter(content_type=ct).delete() + ct.delete() + + +def bkwds(apps, schema_editor): + # No going back + pass + + +class Migration(migrations.Migration): + + dependencies = [ + ('status', '0019_fix-reply-migration'), + ] + + operations = [ + # Drop the table + migrations.RunSQL(""" + DROP TABLE IF EXISTS soapbox_message + """), + + # Fix content types and permissions + migrations.RunPython(fwds, bkwds) + ] diff --git a/standup/status/models.py b/standup/status/models.py index 4f3a160..70c9185 100644 --- a/standup/status/models.py +++ b/standup/status/models.py @@ -2,9 +2,9 @@ from collections import OrderedDict from django.contrib.auth.models import User -from django.core.urlresolvers import reverse, NoReverseMatch from django.db import models from django.utils.timezone import now +from django.urls import reverse, NoReverseMatch from bleach.callbacks import nofollow from bleach.linkifier import Linker @@ -164,8 +164,11 @@ class Status(models.Model): """A standup update for a user on a given project.""" created = models.DateTimeField(default=now) - user = models.ForeignKey(StandupUser, related_name='statuses') - project = models.ForeignKey('Project', related_name='statuses', null=True, blank=True) + user = models.ForeignKey(StandupUser, on_delete=models.CASCADE, related_name='statuses') + project = models.ForeignKey( + 'Project', related_name='statuses', on_delete=models.SET_DEFAULT, default=None, + null=True, blank=True + ) content = models.TextField() class Meta: diff --git a/standup/status/templatetags/filters.py b/standup/status/templatetags/filters.py index b747a4b..123738e 100644 --- a/standup/status/templatetags/filters.py +++ b/standup/status/templatetags/filters.py @@ -1,15 +1,6 @@ from urllib.parse import urlencode from django_jinja import library -from soapbox.models import Message - - -@library.global_function -def get_messages_for_page(request): - if request.path_info: - return Message.objects.match(request.path_info) - - return [] @library.global_function diff --git a/standup/status/tests/test_security.py b/standup/status/tests/test_security.py deleted file mode 100644 index abba0e1..0000000 --- a/standup/status/tests/test_security.py +++ /dev/null @@ -1,25 +0,0 @@ -from django.core.urlresolvers import reverse -from django.test import TestCase, override_settings - - -class NoSniffTestCase(TestCase): - """Tests x-content-type-options == 'nosniff'""" - @override_settings(SECURE_CONTENT_TYPE_NOSNIFF=False) - def test_xsniff_off(self): - resp = self.client.get(reverse('status.index')) - assert resp.status_code == 200 - assert resp.get('x-content-type-options') is None - - @override_settings(SECURE_CONTENT_TYPE_NOSNIFF=True) - def test_xsniff_on(self): - resp = self.client.get(reverse('status.index')) - assert resp.status_code == 200 - assert resp.get('x-content-type-options') == 'nosniff' - - -class XFrameOptionsTestCase(TestCase): - """Verifies xframeoptions == 'SAMEORIGIN'""" - def test_xframe_options(self): - resp = self.client.get(reverse('status.index')) - assert resp.status_code == 200 - assert resp['x-frame-options'] == 'SAMEORIGIN' diff --git a/standup/status/tests/test_views.py b/standup/status/tests/test_views.py index 0dc9038..71a6a5f 100644 --- a/standup/status/tests/test_views.py +++ b/standup/status/tests/test_views.py @@ -1,4 +1,4 @@ -from django.core.urlresolvers import reverse +from django.urls import reverse from django.test import override_settings, TestCase from standup.status.tests.factories import StatusFactory diff --git a/standup/status/urls.py b/standup/status/urls.py index 8278eff..caa7f7f 100644 --- a/standup/status/urls.py +++ b/standup/status/urls.py @@ -1,40 +1,37 @@ from django.conf import settings -from django.conf.urls import url +from django.urls import path from . import views -SLUG_RE = r'(?P[-a-zA-Z0-9_@]+)' - urlpatterns = [ - url(r'^$', views.HomeView.as_view(), name='status.index'), - url(r'^team/{}/$'.format(SLUG_RE), views.TeamView.as_view(), name='status.team'), - url(r'^project/{}/$'.format(SLUG_RE), views.ProjectView.as_view(), name='status.project'), - url(r'^user/{}/$'.format(SLUG_RE), views.UserView.as_view(), name='status.user'), - url(r'^status/(?P\d{1,8})/$', views.StatusView.as_view(), name='status.status'), - url(r'^weekly/$', views.WeeklyView.as_view(), name='status.weekly'), - url(r'^statusize/$', views.statusize, name='status.statusize'), - url(r'^search/$', views.SearchView.as_view(), name='status.search'), + path('', views.HomeView.as_view(), name='status.index'), + path('team//', views.TeamView.as_view(), name='status.team'), + path('project//', views.ProjectView.as_view(), name='status.project'), + path('user//', views.UserView.as_view(), name='status.user'), + path('status//', views.StatusView.as_view(), name='status.status'), + path('weekly/', views.WeeklyView.as_view(), name='status.weekly'), + path('statusize/', views.statusize, name='status.statusize'), + path('search/', views.SearchView.as_view(), name='status.search'), # profile and signin - url(r'^accounts/profile/$', views.ProfileView.as_view(), name='users.profile'), - url(r'^accounts/login/$', views.LoginView.as_view(), name='users.loginform'), + path('accounts/profile/', views.ProfileView.as_view(), name='users.profile'), + path('accounts/login/', views.LoginView.as_view(), name='users.loginform'), # feeds - url(r'^statuses.xml$', views.MainFeed(), name='status.index_feed'), - url(r'^user/{}.xml$'.format(SLUG_RE), views.UserFeed(), name='status.user_feed'), - url(r'^team/{}.xml$'.format(SLUG_RE), views.TeamFeed(), name='status.team_feed'), - url(r'^project/{}.xml$'.format(SLUG_RE), views.ProjectFeed(), - name='status.project_feed'), - url(r'^statistics/$', views.statistics, name='status.statistics'), + path('statuses.xml', views.MainFeed(), name='status.index_feed'), + path('user/.xml', views.UserFeed(), name='status.user_feed'), + path('team/.xml', views.TeamFeed(), name='status.team_feed'), + path('project/.xml', views.ProjectFeed(), name='status.project_feed'), + path('statistics/', views.statistics, name='status.statistics'), # csp - url(r'^csp-violation-capture$', views.csp_violation_capture), + path('csp-violation-capture', views.csp_violation_capture), # robots - url(r'^robots\.txt$', views.robots_txt), + path('robots.txt', views.robots_txt), ] if getattr(settings, 'SITE_TITLE', '').endswith('-stage'): # This is for debugging, so we only want it running in dev and in stage environments. - urlpatterns.append(url(r'^errormenow$', views.errormenow)) + urlpatterns.append(path('errormenow', views.errormenow)) diff --git a/standup/status/views.py b/standup/status/views.py index d1dff3c..67eab68 100644 --- a/standup/status/views.py +++ b/standup/status/views.py @@ -8,11 +8,11 @@ from django.contrib import messages from django.contrib.syndication.views import Feed from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage -from django.core.urlresolvers import reverse from django.http import Http404 from django.http import (HttpResponse, HttpResponseBadRequest, HttpResponseForbidden, HttpResponseRedirect) from django.shortcuts import render +from django.urls import reverse from django.utils.feedgenerator import Atom1Feed from django.views.decorators.csrf import csrf_exempt from django.views.decorators.http import require_POST @@ -30,6 +30,7 @@ class PaginateStatusesMixin(object): def paginate_statuses(self, per_page=20): qs = self.get_status_queryset() + qs = qs.all() page = self.request.GET.get('page') paginator = Paginator(qs, per_page) try: @@ -130,11 +131,11 @@ class SearchView(PaginateStatusesMixin, TemplateView): template_name = 'status/search.html' def get_status_queryset(self): + obs = Status.objects.all() query = self.request.GET.get('query') - if not query: - return [] - - return Status.objects.filter(generate_query('content', query)) + if query: + obs = obs.filter(generate_query('content', query)) + return obs def get_context_data(self, **kwargs): ctx = super().get_context_data(**kwargs) diff --git a/standup/urls.py b/standup/urls.py index 637dd7e..aa2d72f 100644 --- a/standup/urls.py +++ b/standup/urls.py @@ -1,5 +1,5 @@ -from django.conf.urls import include, url from django.contrib import admin +from django.urls import include, path from django_jinja import views @@ -11,9 +11,9 @@ handler500 = views.ServerError.as_view() urlpatterns = [ - url(r'^api/', include('standup.api.urls')), - url(r'^admin/', include(admin.site.urls)), - url(r'', include('standup.status.urls')), + path('api/', include('standup.api.urls')), + path('admin/', admin.site.urls), + path('', include('standup.status.urls')), - url(r'oidc/', include('mozilla_django_oidc.urls')), + path('oidc/', include('mozilla_django_oidc.urls')), ]