Compare commits
	
		
			772 Commits
		
	
	
		
			version/0.
			...
			version/0.
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 5265064b10 | |||
| ee8313142f | |||
| 45dd004d00 | |||
| c4ebc5c085 | |||
| 31c42f1104 | |||
| 8b7f665c82 | |||
| 4915205678 | |||
| 07da5f7122 | |||
| f91e02a0ec | |||
| c62794c738 | |||
| 7664b428e7 | |||
| 9f3f34389e | |||
| 30ca926b38 | |||
| eeb62f543f | |||
| 6a7ffa855e | |||
| 0c5aff21bc | |||
| b0f426e51a | |||
| ed0094eba2 | |||
| 4c1b6d5f48 | |||
| 41a7e1ef07 | |||
| 4ff41be74a | |||
| 7067d1f236 | |||
| 73116b9d1a | |||
| 147212a5f9 | |||
| 5502c319d4 | |||
| d18b76a47d | |||
| 90ce704def | |||
| 790139f8bc | |||
| f4be007803 | |||
| 448ca62661 | |||
| 4824e5c8ba | |||
| c4facd53b4 | |||
| ef913abc7a | |||
| 55fc5a6068 | |||
| f22c89c998 | |||
| 2a78d2d0a0 | |||
| b0ddc6a8c0 | |||
| 8080b0380e | |||
| ddfa2abbaa | |||
| 5fc5e54f47 | |||
| 7462d56182 | |||
| 3f92d1c420 | |||
| d4fa60f509 | |||
| 052bf88c3d | |||
| 07d047c887 | |||
| 23193314f1 | |||
| 1912b29dc5 | |||
| 46410428d9 | |||
| 1774e33c24 | |||
| c961327d27 | |||
| fe1ff7fc76 | |||
| 82d12ecfdf | |||
| 6ed822fa38 | |||
| 4d1658b35e | |||
| 08302a04bf | |||
| 8b4558fcd0 | |||
| 80a36a3441 | |||
| b1b63fbb7f | |||
| fe6bfb1620 | |||
| e6d64bf5b3 | |||
| 270739a45a | |||
| df8995deed | |||
| fdfc6472d2 | |||
| bc495828e7 | |||
| fa138a273f | |||
| 5555dd4dde | |||
| 084ff2994f | |||
| ee8a61d164 | |||
| 60a363e4bf | |||
| e2804b9755 | |||
| 9330a03273 | |||
| beabba2890 | |||
| eeeb14a045 | |||
| ff3f126832 | |||
| 73225917cd | |||
| 8b7a285f4a | |||
| 3a4c6a5d67 | |||
| 0664f0b6b2 | |||
| fab9f1cb1b | |||
| b3c54308b7 | |||
| c1a72a0474 | |||
| 4377d1e86e | |||
| cafe2f1e1f | |||
| c329a724e8 | |||
| 969da05437 | |||
| c61c84e9f3 | |||
| e08c5ff875 | |||
| d1fd616b8d | |||
| cc4bbc049b | |||
| 24a3e787dd | |||
| 13a20478fd | |||
| f58ee7fb52 | |||
| 4d45dc31a9 | |||
| f6b5fbc2cf | |||
| db69c3e38d | |||
| 5ba55356a9 | |||
| 6104b7c9ba | |||
| bcef8369ff | |||
| 0fe555a76e | |||
| c903c81bd5 | |||
| 2c43bfb13f | |||
| 24ecab0878 | |||
| 6285c79341 | |||
| 5f7c56fab4 | |||
| 6338b14a5b | |||
| 62ff3667f9 | |||
| 3b97eef641 | |||
| b05d66466b | |||
| 220144c919 | |||
| 3b9402420d | |||
| 1324143146 | |||
| 595144cdd9 | |||
| b3e714a741 | |||
| 2b3ae1e2d5 | |||
| 886845306a | |||
| de6aaec088 | |||
| 137e0854ab | |||
| b6a0e895bc | |||
| 05c791b1c0 | |||
| 669f3051e8 | |||
| d945b56561 | |||
| 27333bbff1 | |||
| 80c800f233 | |||
| 5d17d3dd31 | |||
| 8c64fcd17f | |||
| 753110583e | |||
| 4206a8c43e | |||
| 7cc9ae45bc | |||
| 09ef58350c | |||
| 0b70007926 | |||
| 2c5d6e8187 | |||
| 10d3f9ac2f | |||
| a6301055f0 | |||
| 9a1b8eb7c8 | |||
| 2ee45f388c | |||
| 9a9feea5ff | |||
| 8540e787d3 | |||
| db26ce808e | |||
| 802d568273 | |||
| 7b6524357f | |||
| 83013f063d | |||
| 333ee3eed4 | |||
| e68352b09c | |||
| df1cb88abc | |||
| 5596caedbc | |||
| 7bd65120b9 | |||
| 227966e727 | |||
| 406f69080b | |||
| 2ce31dfaa5 | |||
| b23afcfc3b | |||
| 7ed3ceb960 | |||
| 615cd7870d | |||
| b907105f4a | |||
| 023423c6e7 | |||
| a5319fc2fe | |||
| 8cfd3f9a2b | |||
| 814c797c64 | |||
| 776ad3cfbf | |||
| 74ddf70cb7 | |||
| a7a839a29c | |||
| 9859c5db0a | |||
| fe503c8de0 | |||
| 43a583e2d2 | |||
| f289025d8e | |||
| 19cb310446 | |||
| 47f6d0ac59 | |||
| 922cbf932d | |||
| c104eeebe6 | |||
| 80c3246333 | |||
| 461fed5567 | |||
| d5f6714ed7 | |||
| c42ed6bc99 | |||
| 57fed2b92b | |||
| e45b33c6c2 | |||
| 137e90355b | |||
| 7500e622f6 | |||
| d49c58f326 | |||
| 9814d3be03 | |||
| fc9f86cccc | |||
| 6fd19c0a37 | |||
| 10cb412532 | |||
| e12780f78f | |||
| 9dec13c225 | |||
| 69120da45c | |||
| 5b2bf7519a | |||
| 631cf77f89 | |||
| 6676e95011 | |||
| 3219cffb52 | |||
| d4f149bc02 | |||
| 206cf4967d | |||
| a67c53f46a | |||
| e989c61793 | |||
| 99bab03cce | |||
| a7567ad8c6 | |||
| 2ffa2fc6b8 | |||
| 8de87d9acb | |||
| 1d03b36750 | |||
| 8dc3c49a2f | |||
| f6461b08d7 | |||
| a3a3dde1c8 | |||
| f111604b70 | |||
| 4315d1a03c | |||
| 9def45c8d7 | |||
| 358922b09b | |||
| fbc3ac6b30 | |||
| 4f785da452 | |||
| ff4bd1c91f | |||
| 7a96f9e894 | |||
| c27d257146 | |||
| 9bccf9bb0a | |||
| c0b05a62f4 | |||
| c140c39d07 | |||
| 9a700e506b | |||
| 8e488670ad | |||
| fd5b2298e5 | |||
| caeaf8d5a9 | |||
| c46f0781fc | |||
| 0aad0604d8 | |||
| 131c3fdb32 | |||
| 8a6009c278 | |||
| 3456527f10 | |||
| 28b913136d | |||
| f700899640 | |||
| 5ba45d3037 | |||
| 212e966dd4 | |||
| 08c0eb2ec6 | |||
| 872ecd93a6 | |||
| f8af9d6ce0 | |||
| c3e43a7c2f | |||
| 273af0f1cb | |||
| 2a85e5ae87 | |||
| 114bb1b0bd | |||
| 97b5d120f8 | |||
| e1f0fe45cb | |||
| bc0f4973d8 | |||
| 5400882d78 | |||
| 8de66b27ad | |||
| 179f0097c0 | |||
| b40bffdf38 | |||
| 2e9496bb74 | |||
| d9d765c6cd | |||
| 10cc6856a4 | |||
| 813dd2894f | |||
| 80d90b91e8 | |||
| fff05e35ac | |||
| 75bb59a22a | |||
| 3ce69bb391 | |||
| 4eb7c5f94b | |||
| aac7e6be90 | |||
| c77f4204c0 | |||
| 5f4452470b | |||
| 9a1270c693 | |||
| 7b9d1a1159 | |||
| cdbe1f6161 | |||
| e43db2e065 | |||
| d1c74d2160 | |||
| f2119ce567 | |||
| 2c4dcb9cf0 | |||
| 93b8266821 | |||
| 443797d9b0 | |||
| a4365ca02c | |||
| 3750083667 | |||
| 66ef067ecf | |||
| b489b0e691 | |||
| f2154d9875 | |||
| 80a50f9bdb | |||
| dc8b89a6b9 | |||
| 8df55f22aa | |||
| f6c322be27 | |||
| a144552059 | |||
| 535d529193 | |||
| 6ed2e137a2 | |||
| 45bd63c720 | |||
| 736e13fc35 | |||
| 966fff008c | |||
| 64f15eadbd | |||
| 81b66ecdcd | |||
| 53e5cf7826 | |||
| 82654b3fd9 | |||
| 9b72c604dd | |||
| 5fb1b8044c | |||
| b8daab4377 | |||
| c5b91bdae8 | |||
| 39a208c55f | |||
| a5bfef9b6b | |||
| f1f4cbef9b | |||
| 8388120b06 | |||
| 2bf96828f1 | |||
| 22838e66fe | |||
| 484dd6de09 | |||
| b743736c26 | |||
| af91e2079b | |||
| cad1c17f14 | |||
| 120d32e4dc | |||
| 238b489e07 | |||
| 4daa70c894 | |||
| f8599438df | |||
| 155c9a4c3f | |||
| 8433b5e583 | |||
| dc5ba144f1 | |||
| 521a8b5356 | |||
| 3453077d7b | |||
| 70ede8581a | |||
| 6e9d297f02 | |||
| 6a7545fd43 | |||
| a8926cbd07 | |||
| 64d7b009ab | |||
| 2b5fddb7bf | |||
| b99d23c119 | |||
| 03905b74ff | |||
| 6b8a59cfbd | |||
| d6fdcd3ef9 | |||
| 53ebc551d2 | |||
| 3d4f43d6e3 | |||
| 074cde7cd5 | |||
| 382e563590 | |||
| ca61a7cc21 | |||
| fa2870afe0 | |||
| 0f46207ea4 | |||
| 1e7d912144 | |||
| f4a676e2fb | |||
| b2c10e2387 | |||
| 8c329dca7d | |||
| 83da175749 | |||
| 995c87938f | |||
| 40678b2f84 | |||
| 8dbbe9102b | |||
| 2f51f354de | |||
| 04b815a33e | |||
| 2a4d68911b | |||
| 4d5a2d61ff | |||
| efd88c27ad | |||
| 80d361ccd2 | |||
| 6ed4501615 | |||
| 8d34faa28e | |||
| a3ae827839 | |||
| 88c1ad4c1c | |||
| 1147c4901b | |||
| 063181d7a7 | |||
| 1285ba6fbb | |||
| a09a1793ec | |||
| 50caa3ac3e | |||
| 9440d24358 | |||
| 26bf6fd22f | |||
| e2f836feae | |||
| b6326f399c | |||
| ea6a1422f7 | |||
| 8fd86a28ff | |||
| d88283a7a9 | |||
| 32a15f84c0 | |||
| 93ba4b7f62 | |||
| 187780dab2 | |||
| d988f37afc | |||
| 295c0bae3f | |||
| 38a22ddf13 | |||
| d06f1abb89 | |||
| 027a64fad2 | |||
| 84fc54ddaa | |||
| 0b5caa85f5 | |||
| 14e0a17dbc | |||
| 3c04afa31f | |||
| 40a2a26904 | |||
| c8b3c6e51a | |||
| e0272a6422 | |||
| b290bbf6d7 | |||
| 8d875cb01d | |||
| 36b1f8ba36 | |||
| 6c889eff27 | |||
| 9d8675e54b | |||
| 22ae986c0b | |||
| 2bef5f3911 | |||
| 3c2b8e5ee1 | |||
| c96571bdba | |||
| 2dfd93afb1 | |||
| f1d77d475c | |||
| 1d22e30c70 | |||
| 07b7951390 | |||
| 995615d0a0 | |||
| ac273aab75 | |||
| 44cd03654d | |||
| 3e2375f970 | |||
| 38ad8e5fd3 | |||
| c481558a46 | |||
| e27a05a7fc | |||
| e4886f0c6f | |||
| 8b2ce5476a | |||
| 1b82283a20 | |||
| 7f3d0113c2 | |||
| 0f6dd33a6b | |||
| 5b79b3fd22 | |||
| d68c72f1fa | |||
| 9267d0c1dd | |||
| 865abc005a | |||
| a2725d5b82 | |||
| 4a05bc6e02 | |||
| 4e8238603a | |||
| ff25c1c057 | |||
| 78cddca0d7 | |||
| 4742ee1d93 | |||
| 0c2dc309e7 | |||
| 144935d10f | |||
| 74ad1b6759 | |||
| 591d2f89a1 | |||
| 7c353f9297 | |||
| cd1af15c56 | |||
| 878169ea2e | |||
| 38dfb03668 | |||
| e2631cec0e | |||
| 5dad853f8a | |||
| 9f00843441 | |||
| f31cd7dec6 | |||
| 1c1afca31f | |||
| fbd4bdef33 | |||
| 5b22f9b6c3 | |||
| 083e317028 | |||
| 95416623b3 | |||
| 813b2676de | |||
| aeca66a288 | |||
| 04a5428148 | |||
| 73b173b92a | |||
| 7cbf20a71c | |||
| 7a98e6d92b | |||
| 49e915f98b | |||
| 3aa2f1e892 | |||
| bc4b7ef44d | |||
| 9400b01a55 | |||
| e57da71dcf | |||
| 7268afaaf9 | |||
| 205183445c | |||
| a08bdfdbcd | |||
| e6c47fee26 | |||
| a5629c5155 | |||
| 41689fe3ce | |||
| 8e84208e2c | |||
| 32a48fa07a | |||
| 773a9c0692 | |||
| 8808e3afe0 | |||
| ecea85f8ca | |||
| 5dfa141e35 | |||
| 447e81d0b8 | |||
| e138076e1d | |||
| 721d133dc3 | |||
| 75b687ecbe | |||
| bdd1863177 | |||
| e5b85e8e6a | |||
| d7481c9de7 | |||
| 571373866e | |||
| e36d7928e4 | |||
| 2be026dd44 | |||
| d5b9de3569 | |||
| e22620b0ec | |||
| ba74a3213d | |||
| d9ecb7070d | |||
| fc4a46bd9c | |||
| 78301b7bab | |||
| 7bf7bde856 | |||
| 9bdff14403 | |||
| f124314eab | |||
| 684e4ffdcf | |||
| d9ff5c69c8 | |||
| 8142e3df45 | |||
| 73920899de | |||
| 13666965a7 | |||
| 86f16e2781 | |||
| 2ed8e72c62 | |||
| edeed18ae8 | |||
| d24133d8a2 | |||
| b9733e56aa | |||
| cd34413914 | |||
| c3a4a76d43 | |||
| a59a29b256 | |||
| dce1edbe53 | |||
| 264d43827a | |||
| 6207226bdf | |||
| ebf33f39c9 | |||
| 696cd1f247 | |||
| b7b3abc462 | |||
| 575739d07c | |||
| 2d7e70eebf | |||
| 387f3c981f | |||
| 865435fb25 | |||
| b10c5306b9 | |||
| 7c706369cd | |||
| 20dd6355c1 | |||
| ba8d5d6e27 | |||
| c448f87027 | |||
| 2b8c70a61f | |||
| 9d7ed9a0ed | |||
| ff69b4affe | |||
| d77afd1ded | |||
| c3909f9196 | |||
| fa55ba5ef0 | |||
| 766518ee0e | |||
| 74b2b26a20 | |||
| 4ebbc6f065 | |||
| 3bd1eadd51 | |||
| 8eb3f0f708 | |||
| 31ea2e7139 | |||
| 323b4b4a5d | |||
| 7b8e1bea92 | |||
| f986dc89ad | |||
| b21fd10093 | |||
| 6f9c19b142 | |||
| f45643ca87 | |||
| 85f8bea784 | |||
| b428ec5237 | |||
| 92428529ad | |||
| f6761b5b0b | |||
| 307b04f4ca | |||
| 6a520a5697 | |||
| f22dbba931 | |||
| 82cf482fba | |||
| a6afb99edd | |||
| ac5f8465b9 | |||
| 218acb9e38 | |||
| 927c718fdd | |||
| b7a6d6e739 | |||
| 0946d6a25d | |||
| c1e98e2f0c | |||
| 807cbbeaaf | |||
| 6c358c4e0a | |||
| 74cd0bc08f | |||
| b08ec0477e | |||
| 328c999cb9 | |||
| c37e382c15 | |||
| 784dd0fdd6 | |||
| e6256cb9c8 | |||
| 4520e3f8b8 | |||
| 23146de2bf | |||
| e24f4fe3a8 | |||
| 8e6b69f96f | |||
| 979bea17ed | |||
| 30dba285d9 | |||
| 99fadf2e55 | |||
| b606e3d0cb | |||
| be642bc874 | |||
| 49a347b32f | |||
| 089b48aad1 | |||
| 2997cb83b1 | |||
| 08f0aca894 | |||
| 80ea7c40b7 | |||
| 019a0cb14d | |||
| 97290755e7 | |||
| 7f150c96b4 | |||
| 73558f30d1 | |||
| dfcfd87644 | |||
| 2c0f0a68a8 | |||
| 3d73aac3ab | |||
| e4fbcd3735 | |||
| 44c0eb37cf | |||
| adc3dcc2c4 | |||
| bac8227371 | |||
| 73d4d9dfe0 | |||
| afdac5f3f8 | |||
| dabce36667 | |||
| 3bd56ce522 | |||
| 540419d5c1 | |||
| ed1fcc3930 | |||
| c22ddc5394 | |||
| 0544864a3f | |||
| 0b9fc9e444 | |||
| e862b97005 | |||
| cffe09b02e | |||
| 846a86fb62 | |||
| 463c130351 | |||
| ffca957838 | |||
| 543e949a48 | |||
| feb80049aa | |||
| 5c59c8ccb6 | |||
| 1fadd82c65 | |||
| 7e7736126d | |||
| 5e0915afce | |||
| bf6c9e8c4a | |||
| 3353aa0298 | |||
| d4cb1a98c7 | |||
| 13f4ea0b8b | |||
| 261d57ad7b | |||
| 4086252979 | |||
| 8bdf12cff1 | |||
| 65a065c4ee | |||
| a691ee529c | |||
| f1c4a62612 | |||
| 358e39ced0 | |||
| 48c3f68cfc | |||
| 1849a7c383 | |||
| 82d14f37c3 | |||
| a0261eafa3 | |||
| 2a27325dfd | |||
| a6dee2e8ed | |||
| 2ff1635696 | |||
| 1cb6b5e984 | |||
| 1fe420fd80 | |||
| 50172e58d8 | |||
| d7483d129f | |||
| 34ed0b3594 | |||
| f008a3e20c | |||
| 9de950220f | |||
| 567c90b4c6 | |||
| ae19236366 | |||
| f9babe7089 | |||
| 78c74cd469 | |||
| 32abb27e61 | |||
| 8478b03892 | |||
| e972f2b289 | |||
| 22c4fb1414 | |||
| 0154def916 | |||
| fc69b6851d | |||
| 44a3c7fa5f | |||
| 37111fd07b | |||
| 4e6653e299 | |||
| 143a575369 | |||
| c782585287 | |||
| 7718b3b3b8 | |||
| 8ff9e72972 | |||
| ef6ef68a39 | |||
| 48a04744e0 | |||
| 6446ca8bb2 | |||
| b9991465ee | |||
| 3d8242be06 | |||
| 344a8817c3 | |||
| 3afb0d4f6d | |||
| c9714893bb | |||
| 3185a86b22 | |||
| a53f7a49ac | |||
| ca3bcc565d | |||
| 432176ea2f | |||
| c1dae0b599 | |||
| e70d3b6286 | |||
| 17e6bc921b | |||
| 46111e7cac | |||
| 3b7e47dbe2 | |||
| fff99f0e3d | |||
| 2e15b24f0a | |||
| 088b9592cd | |||
| b1e4e32b83 | |||
| d91a852eda | |||
| 171c5b9759 | |||
| 64290b2a37 | |||
| 72769b8a0a | |||
| 1018309413 | |||
| 6d0ecd228e | |||
| 40a651e66c | |||
| a390bb7b59 | |||
| 245ec65cbb | |||
| 17eea4a10c | |||
| 862fb0f5d2 | |||
| ec73b53340 | |||
| 9110f7fee3 | |||
| 54cc1fdeef | |||
| 8f42a7f0b4 | |||
| 2c221ea819 | |||
| 93e0441b58 | |||
| 7f1455cb12 | |||
| 59fc223a85 | |||
| 0a6f555c23 | |||
| 6a4233d6fd | |||
| 15fa7e9652 | |||
| f2acc154cd | |||
| d21ec6c9a5 | |||
| 43dd858cd5 | |||
| 34cbf5f702 | |||
| 3c6e94b6a8 | |||
| 1cd149c815 | |||
| 4c6f562805 | |||
| e59c4ec1c7 | |||
| 1169db7530 | |||
| 1453008796 | |||
| 2209b6d603 | |||
| ccbc0384f9 | |||
| a48924c896 | |||
| dc8d8dd2b6 | |||
| afca94ceb8 | |||
| 0b86231a36 | |||
| c0df1f38b8 | |||
| 2b8fed8f4e | |||
| c7322a32a0 | |||
| 64b75cab84 | |||
| f58bc61999 | |||
| fb8ccc0283 | |||
| c38012f147 | |||
| 3676ff21c2 | |||
| 920e705d75 | |||
| de0b137b1e | |||
| d44ac6e2a3 | |||
| 71039a4012 | |||
| 8745ac7932 | |||
| 7f70048423 | |||
| 97dbfc8885 | |||
| 149ea22a93 | |||
| 404ed5406d | |||
| b8656858ec | |||
| 6b0f0e8993 | |||
| aec1ccd88d | |||
| bee5c200b6 | |||
| 9d640efc88 | |||
| f0907841dd | |||
| 2bffc12ef9 | |||
| 2ff9ec6522 | |||
| 43a54f5c54 | |||
| 7bff2734aa | |||
| 84768c0ec6 | |||
| f4499a5459 | |||
| b3aede5bba | |||
| 531ea1c039 | |||
| c2c5ff6912 | |||
| 9cddab8fd5 | |||
| 06d15d8a27 | |||
| b5c711854b | |||
| 4cf6c36f34 | |||
| 75a6f6c875 | |||
| 62abe3f256 | |||
| 9296c41650 | |||
| 7fb48fde6d | |||
| 174472bb45 | |||
| 17575ed921 | |||
| b1b1a27444 | |||
| f97a5eeefb | |||
| 10fd96981e | |||
| 67e3eb549c | |||
| 30a6d1f0b1 | |||
| 3d1fa9f048 | |||
| 1d2be6e68b | |||
| c21e343986 | |||
| ff37ed095c | |||
| 8623a2c3fc | |||
| 23d277eaf1 | |||
| 75ced59451 | |||
| bccf424c5e | |||
| 2f9ae40d20 | |||
| 11e1eec3fb | |||
| 765c5633df | |||
| 6344b1aafb | |||
| ed25801e6e | |||
| 4d0148193f | |||
| 804ae15c2e | |||
| b35a9fad86 | |||
| a4f83bd28a | |||
| 796f83c3d0 | |||
| 2099bbb713 | |||
| 67beba8f78 | |||
| a798412e17 | |||
| 3b2c2d781f | |||
| 98c844f3d6 | |||
| 2645bd0132 | |||
| 2c4fc56b49 | |||
| 0ec1468058 | |||
| 5d1a3043b2 | |||
| b46958d1f9 | |||
| 5daa8d5fe3 | |||
| 31846f1d05 | |||
| 1fac964b8b | |||
| dfa6ed8ac2 | |||
| 66fe10299e | |||
| e0a3ec033f | |||
| 7033ec0ab9 | |||
| 4004579905 | |||
| 9fe9e48a5c | |||
| 595a6c7fe6 | |||
| 11b5860d4a | |||
| 9bdbff4cda | |||
| e0d597eeac | |||
| f576985cc9 | |||
| 22a6aef60b | |||
| ec0a6e7854 | |||
| 6904608e6f | |||
| cb3732cb2b | |||
| 57de6cbafc | |||
| b1dda764a9 | |||
| 5ec2102487 | |||
| 9f8fb7378a | |||
| 98cd646044 | |||
| 0cba1b4c45 | 
@ -1,5 +1,5 @@
 | 
			
		||||
[bumpversion]
 | 
			
		||||
current_version = 0.1.33-beta
 | 
			
		||||
current_version = 0.9.0-pre1
 | 
			
		||||
tag = True
 | 
			
		||||
commit = True
 | 
			
		||||
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)\-(?P<release>.*)
 | 
			
		||||
@ -15,45 +15,11 @@ values =
 | 
			
		||||
	beta
 | 
			
		||||
	stable
 | 
			
		||||
 | 
			
		||||
[bumpversion:file:client-packages/allauth/setup.py]
 | 
			
		||||
[bumpversion:file:helm/values.yaml]
 | 
			
		||||
 | 
			
		||||
[bumpversion:file:client-packages/sentry-auth-passbook/setup.py]
 | 
			
		||||
[bumpversion:file:helm/Chart.yaml]
 | 
			
		||||
 | 
			
		||||
[bumpversion:file:helm/passbook/values.yaml]
 | 
			
		||||
 | 
			
		||||
[bumpversion:file:helm/passbook/Chart.yaml]
 | 
			
		||||
 | 
			
		||||
[bumpversion:file:.gitlab-ci.yml]
 | 
			
		||||
[bumpversion:file:.github/workflows/release.yml]
 | 
			
		||||
 | 
			
		||||
[bumpversion:file:passbook/__init__.py]
 | 
			
		||||
 | 
			
		||||
[bumpversion:file:passbook/api/__init__.py]
 | 
			
		||||
 | 
			
		||||
[bumpversion:file:passbook/core/__init__.py]
 | 
			
		||||
 | 
			
		||||
[bumpversion:file:passbook/admin/__init__.py]
 | 
			
		||||
 | 
			
		||||
[bumpversion:file:passbook/captcha_factor/__init__.py]
 | 
			
		||||
 | 
			
		||||
[bumpversion:file:passbook/oauth_client/__init__.py]
 | 
			
		||||
 | 
			
		||||
[bumpversion:file:passbook/ldap/__init__.py]
 | 
			
		||||
 | 
			
		||||
[bumpversion:file:passbook/lib/__init__.py]
 | 
			
		||||
 | 
			
		||||
[bumpversion:file:passbook/hibp_policy/__init__.py]
 | 
			
		||||
 | 
			
		||||
[bumpversion:file:passbook/password_expiry_policy/__init__.py]
 | 
			
		||||
 | 
			
		||||
[bumpversion:file:passbook/saml_idp/__init__.py]
 | 
			
		||||
 | 
			
		||||
[bumpversion:file:passbook/audit/__init__.py]
 | 
			
		||||
 | 
			
		||||
[bumpversion:file:passbook/oauth_provider/__init__.py]
 | 
			
		||||
 | 
			
		||||
[bumpversion:file:passbook/otp/__init__.py]
 | 
			
		||||
 | 
			
		||||
[bumpversion:file:passbook/app_gw/__init__.py]
 | 
			
		||||
 | 
			
		||||
[bumpversion:file:passbook/suspicious_policy/__init__.py]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,12 +1,10 @@
 | 
			
		||||
[run]
 | 
			
		||||
source = passbook
 | 
			
		||||
omit =
 | 
			
		||||
    env/
 | 
			
		||||
    */wsgi.py
 | 
			
		||||
    manage.py
 | 
			
		||||
    */migrations/*
 | 
			
		||||
    */apps.py
 | 
			
		||||
    passbook/management/commands/nexus_upload.py
 | 
			
		||||
    passbook/management/commands/web.py
 | 
			
		||||
    passbook/management/commands/worker.py
 | 
			
		||||
    docs/
 | 
			
		||||
@ -23,6 +21,7 @@ exclude_lines =
 | 
			
		||||
    def __str__
 | 
			
		||||
    def __repr__
 | 
			
		||||
    if self\.debug
 | 
			
		||||
    if TYPE_CHECKING
 | 
			
		||||
 | 
			
		||||
    # Don't complain if tests don't hit defensive assertion code:
 | 
			
		||||
    raise AssertionError
 | 
			
		||||
 | 
			
		||||
@ -2,3 +2,5 @@ env
 | 
			
		||||
helm
 | 
			
		||||
passbook-ui
 | 
			
		||||
static
 | 
			
		||||
*.env.yml
 | 
			
		||||
node_modules/
 | 
			
		||||
 | 
			
		||||
@ -9,3 +9,6 @@ insert_final_newline = true
 | 
			
		||||
 | 
			
		||||
[html]
 | 
			
		||||
indent_size = 2
 | 
			
		||||
 | 
			
		||||
[yaml]
 | 
			
		||||
indent_size = 2
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										20
									
								
								.fossa.yml
									
									
									
									
									
										Executable file
									
								
							
							
						
						@ -0,0 +1,20 @@
 | 
			
		||||
# Generated by FOSSA CLI (https://github.com/fossas/fossa-cli)
 | 
			
		||||
# Visit https://fossa.com to learn more
 | 
			
		||||
 | 
			
		||||
version: 2
 | 
			
		||||
cli:
 | 
			
		||||
  server: https://app.fossa.com
 | 
			
		||||
  fetcher: custom
 | 
			
		||||
  project: git@github.com:BeryJu/passbook.git
 | 
			
		||||
analyze:
 | 
			
		||||
  modules:
 | 
			
		||||
  - name: static
 | 
			
		||||
    type: npm
 | 
			
		||||
    target: passbook/static/static
 | 
			
		||||
    path: passbook/static/static
 | 
			
		||||
  - name: .
 | 
			
		||||
    type: pip
 | 
			
		||||
    target: .
 | 
			
		||||
    path: .
 | 
			
		||||
    options:
 | 
			
		||||
      strategy: pipenv
 | 
			
		||||
							
								
								
									
										1
									
								
								.github/FUNDING.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1 @@
 | 
			
		||||
custom: ["https://www.paypal.me/octocat"]
 | 
			
		||||
							
								
								
									
										38
									
								
								.github/workflows/ci-cleanup.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,38 @@
 | 
			
		||||
name: passbook-ci-cleanup
 | 
			
		||||
on:
 | 
			
		||||
  - delete
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  delete-server:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: Delete docker tag
 | 
			
		||||
        env:
 | 
			
		||||
          DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
 | 
			
		||||
          DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
 | 
			
		||||
        run: curl
 | 
			
		||||
          -u $DOCKER_USERNAME:$DOCKER_PASSWORD
 | 
			
		||||
          -X "DELETE"
 | 
			
		||||
          "https://hub.docker.com/v2/repositories/$DOCKER_USERNAME/passbook/tags/${GITHUB_REF##*/}/"
 | 
			
		||||
  delete-gatekeeper:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: Delete docker tag
 | 
			
		||||
        env:
 | 
			
		||||
          DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
 | 
			
		||||
          DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
 | 
			
		||||
        run: curl
 | 
			
		||||
          -u $DOCKER_USERNAME:$DOCKER_PASSWORD
 | 
			
		||||
          -X "DELETE"
 | 
			
		||||
          "https://hub.docker.com/v2/repositories/$DOCKER_USERNAME/passbook-gatekeeper/tags/${GITHUB_REF##*/}/"
 | 
			
		||||
  delete-static:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: Delete docker tag
 | 
			
		||||
        env:
 | 
			
		||||
          DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
 | 
			
		||||
          DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
 | 
			
		||||
        run: curl
 | 
			
		||||
          -u $DOCKER_USERNAME:$DOCKER_PASSWORD
 | 
			
		||||
          -X "DELETE"
 | 
			
		||||
          "https://hub.docker.com/v2/repositories/$DOCKER_USERNAME/passbook-static/tags/${GITHUB_REF##*/}/"
 | 
			
		||||
							
								
								
									
										202
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,202 @@
 | 
			
		||||
name: passbook-ci
 | 
			
		||||
on:
 | 
			
		||||
  - push
 | 
			
		||||
env:
 | 
			
		||||
  POSTGRES_DB: passbook
 | 
			
		||||
  POSTGRES_USER: passbook
 | 
			
		||||
  POSTGRES_PASSWORD: "EK-5jnKfjrGRm<77"
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  # Linting
 | 
			
		||||
  pylint:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v1
 | 
			
		||||
      - uses: actions/setup-python@v1
 | 
			
		||||
        with:
 | 
			
		||||
          python-version: '3.8'
 | 
			
		||||
      - name: Install dependencies
 | 
			
		||||
        run: sudo pip install -U wheel pipenv && pipenv install --dev
 | 
			
		||||
      - name: Lint with pylint
 | 
			
		||||
        run: pipenv run pylint passbook
 | 
			
		||||
  black:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v1
 | 
			
		||||
      - uses: actions/setup-python@v1
 | 
			
		||||
        with:
 | 
			
		||||
          python-version: '3.8'
 | 
			
		||||
      - name: Install dependencies
 | 
			
		||||
        run: sudo pip install -U wheel pipenv && pipenv install --dev
 | 
			
		||||
      - name: Lint with black
 | 
			
		||||
        run: pipenv run black --check passbook
 | 
			
		||||
  prospector:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v1
 | 
			
		||||
      - uses: actions/setup-python@v1
 | 
			
		||||
        with:
 | 
			
		||||
          python-version: '3.8'
 | 
			
		||||
      - name: Install dependencies
 | 
			
		||||
        run: sudo pip install -U wheel pipenv && pipenv install --dev && pipenv install --dev prospector --skip-lock
 | 
			
		||||
      - name: Lint with prospector
 | 
			
		||||
        run: pipenv run prospector
 | 
			
		||||
  bandit:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v1
 | 
			
		||||
      - uses: actions/setup-python@v1
 | 
			
		||||
        with:
 | 
			
		||||
          python-version: '3.8'
 | 
			
		||||
      - name: Install dependencies
 | 
			
		||||
        run: sudo pip install -U wheel pipenv && pipenv install --dev
 | 
			
		||||
      - name: Lint with bandit
 | 
			
		||||
        run: pipenv run bandit -r passbook
 | 
			
		||||
  pyright:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v1
 | 
			
		||||
      - uses: actions/setup-node@v1
 | 
			
		||||
      - uses: actions/setup-python@v1
 | 
			
		||||
        with:
 | 
			
		||||
          python-version: '3.8'
 | 
			
		||||
      - name: Install pyright
 | 
			
		||||
        run: npm install -g pyright
 | 
			
		||||
      - name: Show pyright version
 | 
			
		||||
        run: pyright --version
 | 
			
		||||
      - name: Install dependencies
 | 
			
		||||
        run: sudo pip install -U wheel pipenv && pipenv install --dev
 | 
			
		||||
      - name: Lint with pyright
 | 
			
		||||
        run: pipenv run pyright
 | 
			
		||||
  # Actual CI tests
 | 
			
		||||
  migrations:
 | 
			
		||||
    needs:
 | 
			
		||||
      - pylint
 | 
			
		||||
      - black
 | 
			
		||||
      - prospector
 | 
			
		||||
    services:
 | 
			
		||||
      postgres:
 | 
			
		||||
        image: postgres:latest
 | 
			
		||||
        env:
 | 
			
		||||
          POSTGRES_DB: passbook
 | 
			
		||||
          POSTGRES_USER: passbook
 | 
			
		||||
          POSTGRES_PASSWORD: "EK-5jnKfjrGRm<77"
 | 
			
		||||
        ports:
 | 
			
		||||
          - 5432:5432
 | 
			
		||||
      redis:
 | 
			
		||||
        image: redis:latest
 | 
			
		||||
        ports:
 | 
			
		||||
          - 6379:6379
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v1
 | 
			
		||||
      - uses: actions/setup-python@v1
 | 
			
		||||
        with:
 | 
			
		||||
          python-version: '3.8'
 | 
			
		||||
      - name: Install dependencies
 | 
			
		||||
        run: sudo pip install -U wheel pipenv && pipenv install --dev
 | 
			
		||||
      - name: Run migrations
 | 
			
		||||
        run: pipenv run ./manage.py migrate
 | 
			
		||||
  coverage:
 | 
			
		||||
    needs:
 | 
			
		||||
      - pylint
 | 
			
		||||
      - black
 | 
			
		||||
      - prospector
 | 
			
		||||
    services:
 | 
			
		||||
      postgres:
 | 
			
		||||
        image: postgres:latest
 | 
			
		||||
        env:
 | 
			
		||||
          POSTGRES_DB: passbook
 | 
			
		||||
          POSTGRES_USER: passbook
 | 
			
		||||
          POSTGRES_PASSWORD: "EK-5jnKfjrGRm<77"
 | 
			
		||||
        ports:
 | 
			
		||||
          - 5432:5432
 | 
			
		||||
      redis:
 | 
			
		||||
        image: redis:latest
 | 
			
		||||
        ports:
 | 
			
		||||
          - 6379:6379
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v1
 | 
			
		||||
      - uses: actions/setup-python@v1
 | 
			
		||||
        with:
 | 
			
		||||
          python-version: '3.8'
 | 
			
		||||
      - name: Install dependencies
 | 
			
		||||
        run: sudo pip install -U wheel pipenv && pipenv install --dev
 | 
			
		||||
      - name: Run coverage
 | 
			
		||||
        run: pipenv run ./scripts/coverage.sh
 | 
			
		||||
      - name: Create XML Report
 | 
			
		||||
        run: pipenv run coverage xml
 | 
			
		||||
      - uses: codecov/codecov-action@v1
 | 
			
		||||
        with:
 | 
			
		||||
          token: ${{ secrets.CODECOV_TOKEN }}
 | 
			
		||||
  # Build
 | 
			
		||||
  build-server:
 | 
			
		||||
    needs:
 | 
			
		||||
      - migrations
 | 
			
		||||
      - coverage
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v1
 | 
			
		||||
      - name: Docker Login Registry
 | 
			
		||||
        env:
 | 
			
		||||
          DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
 | 
			
		||||
          DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
 | 
			
		||||
        run: docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD
 | 
			
		||||
      - name: Building Docker Image
 | 
			
		||||
        run: docker build
 | 
			
		||||
          --no-cache
 | 
			
		||||
          -t beryju/passbook:${GITHUB_REF##*/}
 | 
			
		||||
          -f Dockerfile .
 | 
			
		||||
      - name: Push Docker Container to Registry
 | 
			
		||||
        run: docker push beryju/passbook:${GITHUB_REF##*/}
 | 
			
		||||
  build-gatekeeper:
 | 
			
		||||
    needs:
 | 
			
		||||
      - migrations
 | 
			
		||||
      - coverage
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v1
 | 
			
		||||
      - name: Docker Login Registry
 | 
			
		||||
        env:
 | 
			
		||||
          DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
 | 
			
		||||
          DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
 | 
			
		||||
        run: docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD
 | 
			
		||||
      - name: Building Docker Image
 | 
			
		||||
        run: |
 | 
			
		||||
          cd gatekeeper
 | 
			
		||||
          docker build \
 | 
			
		||||
          --no-cache \
 | 
			
		||||
          -t beryju/passbook-gatekeeper:${GITHUB_REF##*/} \
 | 
			
		||||
          -f Dockerfile .
 | 
			
		||||
      - name: Push Docker Container to Registry
 | 
			
		||||
        run: docker push beryju/passbook-gatekeeper:${GITHUB_REF##*/}
 | 
			
		||||
  build-static:
 | 
			
		||||
    needs:
 | 
			
		||||
      - migrations
 | 
			
		||||
      - coverage
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    services:
 | 
			
		||||
      postgres:
 | 
			
		||||
        image: postgres:latest
 | 
			
		||||
        env:
 | 
			
		||||
          POSTGRES_DB: passbook
 | 
			
		||||
          POSTGRES_USER: passbook
 | 
			
		||||
          POSTGRES_PASSWORD: "EK-5jnKfjrGRm<77"
 | 
			
		||||
      redis:
 | 
			
		||||
        image: redis:latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v1
 | 
			
		||||
      - name: Docker Login Registry
 | 
			
		||||
        env:
 | 
			
		||||
          DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
 | 
			
		||||
          DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
 | 
			
		||||
        run: docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD
 | 
			
		||||
      - name: Building Docker Image
 | 
			
		||||
        run: docker build
 | 
			
		||||
          --no-cache
 | 
			
		||||
          --network=$(docker network ls | grep github | awk '{print $1}')
 | 
			
		||||
          -t beryju/passbook-static:${GITHUB_REF##*/}
 | 
			
		||||
          -f static.Dockerfile .
 | 
			
		||||
      - name: Push Docker Container to Registry
 | 
			
		||||
        run: docker push beryju/passbook-static:${GITHUB_REF##*/}
 | 
			
		||||
							
								
								
									
										89
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,89 @@
 | 
			
		||||
name: passbook-release
 | 
			
		||||
on:
 | 
			
		||||
  release
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  # Build
 | 
			
		||||
  build-server:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v1
 | 
			
		||||
      - name: Docker Login Registry
 | 
			
		||||
        env:
 | 
			
		||||
          DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
 | 
			
		||||
          DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
 | 
			
		||||
        run: docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD
 | 
			
		||||
      - name: Building Docker Image
 | 
			
		||||
        run: docker build
 | 
			
		||||
          --no-cache
 | 
			
		||||
          -t beryju/passbook:0.9.0-pre1
 | 
			
		||||
          -t beryju/passbook:latest
 | 
			
		||||
          -f Dockerfile .
 | 
			
		||||
      - name: Push Docker Container to Registry (versioned)
 | 
			
		||||
        run: docker push beryju/passbook:0.9.0-pre1
 | 
			
		||||
      - name: Push Docker Container to Registry (latest)
 | 
			
		||||
        run: docker push beryju/passbook:latest
 | 
			
		||||
  build-gatekeeper:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v1
 | 
			
		||||
      - name: Docker Login Registry
 | 
			
		||||
        env:
 | 
			
		||||
          DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
 | 
			
		||||
          DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
 | 
			
		||||
        run: docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD
 | 
			
		||||
      - name: Building Docker Image
 | 
			
		||||
        run: |
 | 
			
		||||
          cd gatekeeper
 | 
			
		||||
          docker build \
 | 
			
		||||
          --no-cache \
 | 
			
		||||
          -t beryju/passbook-gatekeeper:0.9.0-pre1 \
 | 
			
		||||
          -t beryju/passbook-gatekeeper:latest \
 | 
			
		||||
          -f Dockerfile .
 | 
			
		||||
      - name: Push Docker Container to Registry (versioned)
 | 
			
		||||
        run: docker push beryju/passbook-gatekeeper:0.9.0-pre1
 | 
			
		||||
      - name: Push Docker Container to Registry (latest)
 | 
			
		||||
        run: docker push beryju/passbook-gatekeeper:latest
 | 
			
		||||
  build-static:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    services:
 | 
			
		||||
      postgres:
 | 
			
		||||
        image: postgres:latest
 | 
			
		||||
        env:
 | 
			
		||||
          POSTGRES_DB: passbook
 | 
			
		||||
          POSTGRES_USER: passbook
 | 
			
		||||
          POSTGRES_PASSWORD: "EK-5jnKfjrGRm<77"
 | 
			
		||||
      redis:
 | 
			
		||||
        image: redis:latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v1
 | 
			
		||||
      - name: Docker Login Registry
 | 
			
		||||
        env:
 | 
			
		||||
          DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
 | 
			
		||||
          DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
 | 
			
		||||
        run: docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD
 | 
			
		||||
      - name: Building Docker Image
 | 
			
		||||
        run: docker build
 | 
			
		||||
          --no-cache
 | 
			
		||||
          --network=$(docker network ls | grep github | awk '{print $1}')
 | 
			
		||||
          -t beryju/passbook-static:0.9.0-pre1
 | 
			
		||||
          -t beryju/passbook-static:latest
 | 
			
		||||
          -f static.Dockerfile .
 | 
			
		||||
      - name: Push Docker Container to Registry (versioned)
 | 
			
		||||
        run: docker push beryju/passbook-static:0.9.0-pre1
 | 
			
		||||
      - name: Push Docker Container to Registry (latest)
 | 
			
		||||
        run: docker push beryju/passbook-static:latest
 | 
			
		||||
  test-release:
 | 
			
		||||
    needs:
 | 
			
		||||
      - build-server
 | 
			
		||||
      - build-static
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v1
 | 
			
		||||
      - name: Run test suite in final docker images
 | 
			
		||||
        run: |
 | 
			
		||||
          export PASSBOOK_DOMAIN=localhost
 | 
			
		||||
          docker-compose pull
 | 
			
		||||
          docker-compose up --no-start
 | 
			
		||||
          docker-compose start postgresql redis
 | 
			
		||||
          docker-compose run -u root server bash -c "pip install --no-cache -r requirements-dev.txt && ./manage.py test"
 | 
			
		||||
							
								
								
									
										60
									
								
								.github/workflows/tag.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,60 @@
 | 
			
		||||
on:
 | 
			
		||||
  push:
 | 
			
		||||
    tags:
 | 
			
		||||
    - 'version/*'
 | 
			
		||||
 | 
			
		||||
name: passbook-version-tag
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  build:
 | 
			
		||||
    name: Create Release from Tag
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@master
 | 
			
		||||
      - name: Pre-release test
 | 
			
		||||
        run: |
 | 
			
		||||
          export PASSBOOK_DOMAIN=localhost
 | 
			
		||||
          docker-compose pull
 | 
			
		||||
          docker build \
 | 
			
		||||
            --no-cache \
 | 
			
		||||
            -t beryju/passbook:latest \
 | 
			
		||||
            -f Dockerfile .
 | 
			
		||||
          docker-compose up --no-start
 | 
			
		||||
          docker-compose start postgresql redis
 | 
			
		||||
          docker-compose run -u root server bash -c "pip install --no-cache -r requirements-dev.txt && ./manage.py test"
 | 
			
		||||
      - name: Install Helm
 | 
			
		||||
        run: |
 | 
			
		||||
          apt update && apt install -y curl
 | 
			
		||||
          curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash
 | 
			
		||||
      - name: Helm package
 | 
			
		||||
        run: |
 | 
			
		||||
          helm dependency update helm/
 | 
			
		||||
          helm package helm/
 | 
			
		||||
          mv passbook-*.tgz passbook-chart.tgz
 | 
			
		||||
      - name: Extract verison number
 | 
			
		||||
        id: get_version
 | 
			
		||||
        uses: actions/github-script@0.2.0
 | 
			
		||||
        with:
 | 
			
		||||
          github-token: ${{ secrets.GITHUB_TOKEN }}
 | 
			
		||||
          script: |
 | 
			
		||||
            return context.payload.ref.replace(/\/refs\/tags\/version\//, '');
 | 
			
		||||
      - name: Create Release
 | 
			
		||||
        id: create_release
 | 
			
		||||
        uses: actions/create-release@v1.0.0
 | 
			
		||||
        env:
 | 
			
		||||
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
 | 
			
		||||
        with:
 | 
			
		||||
          tag_name: ${{ github.ref }}
 | 
			
		||||
          release_name: Release ${{ steps.get_version.outputs.result }}
 | 
			
		||||
          draft: false
 | 
			
		||||
          prerelease: false
 | 
			
		||||
      - name: Upload packaged Helm Chart
 | 
			
		||||
        id: upload-release-asset
 | 
			
		||||
        uses: actions/upload-release-asset@v1.0.1
 | 
			
		||||
        env:
 | 
			
		||||
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
 | 
			
		||||
        with:
 | 
			
		||||
          upload_url: ${{ steps.create_release.outputs.upload_url }}
 | 
			
		||||
          asset_path: ./passbook-chart.tgz
 | 
			
		||||
          asset_name: passbook-chart.tgz
 | 
			
		||||
          asset_content_type: application/gzip
 | 
			
		||||
							
								
								
									
										7
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						@ -63,6 +63,7 @@ coverage.xml
 | 
			
		||||
*.cover
 | 
			
		||||
.hypothesis/
 | 
			
		||||
.pytest_cache/
 | 
			
		||||
unittest.xml
 | 
			
		||||
 | 
			
		||||
# Translations
 | 
			
		||||
*.mo
 | 
			
		||||
@ -184,10 +185,14 @@ dmypy.json
 | 
			
		||||
[Ii]nclude
 | 
			
		||||
[Ll]ib64
 | 
			
		||||
[Ll]ocal
 | 
			
		||||
[Ss]cripts
 | 
			
		||||
pyvenv.cfg
 | 
			
		||||
pip-selfcheck.json
 | 
			
		||||
 | 
			
		||||
# End of https://www.gitignore.io/api/python,django
 | 
			
		||||
/static/
 | 
			
		||||
local.env.yml
 | 
			
		||||
.vscode/
 | 
			
		||||
 | 
			
		||||
### Helm ###
 | 
			
		||||
# Chart dependencies
 | 
			
		||||
**/charts/*.tgz
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										163
									
								
								.gitlab-ci.yml
									
									
									
									
									
								
							
							
						
						@ -1,163 +0,0 @@
 | 
			
		||||
# Global Variables
 | 
			
		||||
stages:
 | 
			
		||||
  - build-buildimage
 | 
			
		||||
  - test
 | 
			
		||||
  - build
 | 
			
		||||
  - docs
 | 
			
		||||
  - deploy
 | 
			
		||||
image: docker.pkg.beryju.org/passbook-build-base:latest
 | 
			
		||||
services:
 | 
			
		||||
  - postgres:latest
 | 
			
		||||
  - redis:latest
 | 
			
		||||
 | 
			
		||||
variables:
 | 
			
		||||
  POSTGRES_DB: passbook
 | 
			
		||||
  POSTGRES_USER: passbook
 | 
			
		||||
  POSTGRES_PASSWORD: "EK-5jnKfjrGRm<77"
 | 
			
		||||
 | 
			
		||||
create-build-image:
 | 
			
		||||
  image:
 | 
			
		||||
    name: gcr.io/kaniko-project/executor:debug
 | 
			
		||||
    entrypoint: [""]
 | 
			
		||||
  before_script:
 | 
			
		||||
    - echo "{\"auths\":{\"docker.$NEXUS_URL\":{\"auth\":\"$NEXUS_AUTH\"}}}" > /kaniko/.docker/config.json
 | 
			
		||||
  script:
 | 
			
		||||
    - /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile.build-base --destination docker.pkg.beryju.org/passbook-build-base:latest --destination docker.pkg.beryju.org/passbook-build-base:0.1.33-beta
 | 
			
		||||
  stage: build-buildimage
 | 
			
		||||
  only:
 | 
			
		||||
    refs:
 | 
			
		||||
      - tags
 | 
			
		||||
      - /^version/.*$/
 | 
			
		||||
 | 
			
		||||
isort:
 | 
			
		||||
  script:
 | 
			
		||||
    - isort -c -sg env
 | 
			
		||||
  stage: test
 | 
			
		||||
migrations:
 | 
			
		||||
  script:
 | 
			
		||||
    - python manage.py migrate
 | 
			
		||||
  stage: test
 | 
			
		||||
prospector:
 | 
			
		||||
  script:
 | 
			
		||||
    - prospector
 | 
			
		||||
  stage: test
 | 
			
		||||
pylint:
 | 
			
		||||
  script:
 | 
			
		||||
    - pylint passbook
 | 
			
		||||
  stage: test
 | 
			
		||||
coverage:
 | 
			
		||||
  script:
 | 
			
		||||
    - python manage.py collectstatic --no-input
 | 
			
		||||
    - coverage run manage.py test
 | 
			
		||||
    - coverage report
 | 
			
		||||
  stage: test
 | 
			
		||||
bandit:
 | 
			
		||||
  script:
 | 
			
		||||
    - bandit -r passbook
 | 
			
		||||
  stage: test
 | 
			
		||||
 | 
			
		||||
package-docker:
 | 
			
		||||
  image:
 | 
			
		||||
    name: gcr.io/kaniko-project/executor:debug
 | 
			
		||||
    entrypoint: [""]
 | 
			
		||||
  before_script:
 | 
			
		||||
    - echo "{\"auths\":{\"docker.$NEXUS_URL\":{\"auth\":\"$NEXUS_AUTH\"}}}" > /kaniko/.docker/config.json
 | 
			
		||||
  script:
 | 
			
		||||
    - /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --destination docker.pkg.beryju.org/passbook:latest --destination docker.pkg.beryju.org/passbook:0.1.33-beta
 | 
			
		||||
  stage: build
 | 
			
		||||
  only:
 | 
			
		||||
    - tags
 | 
			
		||||
    - /^version/.*$/
 | 
			
		||||
package-helm:
 | 
			
		||||
  stage: build
 | 
			
		||||
  script:
 | 
			
		||||
    - curl https://raw.githubusercontent.com/helm/helm/master/scripts/get | bash
 | 
			
		||||
    - helm init --client-only
 | 
			
		||||
    - helm package helm/passbook
 | 
			
		||||
    - ./manage.py nexus_upload --method put --url $NEXUS_URL --auth $NEXUS_AUTH --repo helm *.tgz
 | 
			
		||||
  only:
 | 
			
		||||
    - tags
 | 
			
		||||
    - /^version/.*$/
 | 
			
		||||
package-debian:
 | 
			
		||||
  before_script:
 | 
			
		||||
    - apt update
 | 
			
		||||
    - apt install -y --no-install-recommends build-essential debhelper devscripts equivs python3 python3-dev python3-pip libsasl2-dev libldap2-dev
 | 
			
		||||
    - mk-build-deps debian/control
 | 
			
		||||
    - apt install ./*build-deps*deb -f -y
 | 
			
		||||
    - python3 -m pip install -U virtualenv pip
 | 
			
		||||
    - virtualenv env
 | 
			
		||||
    - source env/bin/activate
 | 
			
		||||
    - pip3 install -U -r requirements.txt -r requirements-dev.txt
 | 
			
		||||
    - ./manage.py collectstatic --no-input
 | 
			
		||||
  image: ubuntu:18.04
 | 
			
		||||
  script:
 | 
			
		||||
    - debuild -us -uc
 | 
			
		||||
    - cp ../passbook*.deb .
 | 
			
		||||
    - ./manage.py nexus_upload --method post --url $NEXUS_URL --auth $NEXUS_AUTH --repo apt passbook*deb
 | 
			
		||||
  artifacts:
 | 
			
		||||
    paths:
 | 
			
		||||
      - passbook*deb
 | 
			
		||||
    expire_in: 2 days
 | 
			
		||||
  stage: build
 | 
			
		||||
  only:
 | 
			
		||||
    - tags
 | 
			
		||||
    - /^version/.*$/
 | 
			
		||||
 | 
			
		||||
package-client-package-allauth:
 | 
			
		||||
  script:
 | 
			
		||||
    - cd client-packages/allauth
 | 
			
		||||
    - python setup.py sdist
 | 
			
		||||
    - twine upload --username $TWINE_USERNAME --password $TWINE_PASSWORD dist/*
 | 
			
		||||
  stage: build
 | 
			
		||||
  only:
 | 
			
		||||
    refs:
 | 
			
		||||
      - tags
 | 
			
		||||
      - /^version/.*$/
 | 
			
		||||
    changes:
 | 
			
		||||
      - client-packages/allauth/**
 | 
			
		||||
 | 
			
		||||
package-client-package-sentry:
 | 
			
		||||
  script:
 | 
			
		||||
    - cd client-packages/sentry-auth-passbook
 | 
			
		||||
    - python setup.py sdist
 | 
			
		||||
    - twine upload --username $TWINE_USERNAME --password $TWINE_PASSWORD dist/*
 | 
			
		||||
  stage: build
 | 
			
		||||
  only:
 | 
			
		||||
    refs:
 | 
			
		||||
      - tags
 | 
			
		||||
      - /^version/.*$/
 | 
			
		||||
    changes:
 | 
			
		||||
      - client-packages/sentry-auth-passbook/**
 | 
			
		||||
# docs:
 | 
			
		||||
#   stage: docs
 | 
			
		||||
#   only:
 | 
			
		||||
#   - master
 | 
			
		||||
#   - tags
 | 
			
		||||
#   - /^debian/.*$/
 | 
			
		||||
#   environment:
 | 
			
		||||
#     name: docs
 | 
			
		||||
#     url: "https://passbook.beryju.org/docs/"
 | 
			
		||||
#   script:
 | 
			
		||||
#     - apt update
 | 
			
		||||
#     - apt install -y rsync
 | 
			
		||||
#     - "mkdir ~/.ssh"
 | 
			
		||||
#     - "cp .gitlab/known_hosts ~/.ssh/"
 | 
			
		||||
#     - "pip3 install -U -r requirements-docs.txt"
 | 
			
		||||
#     - "eval $(ssh-agent -s)"
 | 
			
		||||
#     - "echo \"${CI_SSH_PRIVATE}\" | ssh-add -"
 | 
			
		||||
#     - mkdocs build
 | 
			
		||||
#     - 'rsync -avh --delete web/* "beryjuorg@ory1-web-prod-1.ory1.beryju.org:passbook.beryju.org/"'
 | 
			
		||||
#     - 'rsync -avh --delete site/* "beryjuorg@ory1-web-prod-1.ory1.beryju.org:passbook.beryju.org/docs/"'
 | 
			
		||||
 | 
			
		||||
# deploy:
 | 
			
		||||
#   environment:
 | 
			
		||||
#     name: production
 | 
			
		||||
#     url: https://passbook-prod.default.k8s.beryju.org/
 | 
			
		||||
#   stage: deploy
 | 
			
		||||
#   only:
 | 
			
		||||
#   - tags
 | 
			
		||||
#   - /^version/.*$/
 | 
			
		||||
#   script:
 | 
			
		||||
#     - curl https://raw.githubusercontent.com/helm/helm/master/scripts/get | bash
 | 
			
		||||
#     - helm init
 | 
			
		||||
#     - helm upgrade passbook-prod helm/passbook --devel
 | 
			
		||||
							
								
								
									
										6
									
								
								.isort.cfg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,6 @@
 | 
			
		||||
[settings]
 | 
			
		||||
multi_line_output=3
 | 
			
		||||
include_trailing_comma=True
 | 
			
		||||
force_grid_wrap=0
 | 
			
		||||
use_parentheses=True
 | 
			
		||||
line_length=88
 | 
			
		||||
@ -3,11 +3,9 @@ test-warnings: true
 | 
			
		||||
doc-warnings: false
 | 
			
		||||
 | 
			
		||||
ignore-paths:
 | 
			
		||||
  - env
 | 
			
		||||
  - migrations
 | 
			
		||||
  - docs
 | 
			
		||||
  - node_modules
 | 
			
		||||
  - client-packages
 | 
			
		||||
 | 
			
		||||
uses:
 | 
			
		||||
 - django
 | 
			
		||||
  - django
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										11
									
								
								.pylintrc
									
									
									
									
									
								
							
							
						
						@ -1,12 +1,9 @@
 | 
			
		||||
[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,too-many-ancestors,too-few-public-methods,import-outside-toplevel,bad-continuation,signature-differs
 | 
			
		||||
load-plugins=pylint_django,pylint.extensions.bad_builtin
 | 
			
		||||
#,pylint.extensions.docparams
 | 
			
		||||
extension-pkg-whitelist=lxml
 | 
			
		||||
const-rgx=[a-zA-Z0-9_]{1,40}$
 | 
			
		||||
 | 
			
		||||
[SIMILARITIES]
 | 
			
		||||
 | 
			
		||||
# Minimum lines number of a similarity.
 | 
			
		||||
min-similarity-lines=20
 | 
			
		||||
ignored-modules=django-otp
 | 
			
		||||
jobs=12
 | 
			
		||||
ignore=migrations
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										114
									
								
								.vscode/.ropeproject/config.py
									
									
									
									
										vendored
									
									
								
							
							
						
						@ -1,114 +0,0 @@
 | 
			
		||||
# The default ``config.py``
 | 
			
		||||
# flake8: noqa
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def set_prefs(prefs):
 | 
			
		||||
    """This function is called before opening the project"""
 | 
			
		||||
 | 
			
		||||
    # Specify which files and folders to ignore in the project.
 | 
			
		||||
    # Changes to ignored resources are not added to the history and
 | 
			
		||||
    # VCSs.  Also they are not returned in `Project.get_files()`.
 | 
			
		||||
    # Note that ``?`` and ``*`` match all characters but slashes.
 | 
			
		||||
    # '*.pyc': matches 'test.pyc' and 'pkg/test.pyc'
 | 
			
		||||
    # 'mod*.pyc': matches 'test/mod1.pyc' but not 'mod/1.pyc'
 | 
			
		||||
    # '.svn': matches 'pkg/.svn' and all of its children
 | 
			
		||||
    # 'build/*.o': matches 'build/lib.o' but not 'build/sub/lib.o'
 | 
			
		||||
    # 'build//*.o': matches 'build/lib.o' and 'build/sub/lib.o'
 | 
			
		||||
    prefs['ignored_resources'] = ['*.pyc', '*~', '.ropeproject',
 | 
			
		||||
                                  '.hg', '.svn', '_svn', '.git', '.tox']
 | 
			
		||||
 | 
			
		||||
    # Specifies which files should be considered python files.  It is
 | 
			
		||||
    # useful when you have scripts inside your project.  Only files
 | 
			
		||||
    # ending with ``.py`` are considered to be python files by
 | 
			
		||||
    # default.
 | 
			
		||||
    # prefs['python_files'] = ['*.py']
 | 
			
		||||
 | 
			
		||||
    # Custom source folders:  By default rope searches the project
 | 
			
		||||
    # for finding source folders (folders that should be searched
 | 
			
		||||
    # for finding modules).  You can add paths to that list.  Note
 | 
			
		||||
    # that rope guesses project source folders correctly most of the
 | 
			
		||||
    # time; use this if you have any problems.
 | 
			
		||||
    # The folders should be relative to project root and use '/' for
 | 
			
		||||
    # separating folders regardless of the platform rope is running on.
 | 
			
		||||
    # 'src/my_source_folder' for instance.
 | 
			
		||||
    # prefs.add('source_folders', 'src')
 | 
			
		||||
 | 
			
		||||
    # You can extend python path for looking up modules
 | 
			
		||||
    # prefs.add('python_path', '~/python/')
 | 
			
		||||
 | 
			
		||||
    # Should rope save object information or not.
 | 
			
		||||
    prefs['save_objectdb'] = True
 | 
			
		||||
    prefs['compress_objectdb'] = False
 | 
			
		||||
 | 
			
		||||
    # If `True`, rope analyzes each module when it is being saved.
 | 
			
		||||
    prefs['automatic_soa'] = True
 | 
			
		||||
    # The depth of calls to follow in static object analysis
 | 
			
		||||
    prefs['soa_followed_calls'] = 0
 | 
			
		||||
 | 
			
		||||
    # If `False` when running modules or unit tests "dynamic object
 | 
			
		||||
    # analysis" is turned off.  This makes them much faster.
 | 
			
		||||
    prefs['perform_doa'] = True
 | 
			
		||||
 | 
			
		||||
    # Rope can check the validity of its object DB when running.
 | 
			
		||||
    prefs['validate_objectdb'] = True
 | 
			
		||||
 | 
			
		||||
    # How many undos to hold?
 | 
			
		||||
    prefs['max_history_items'] = 32
 | 
			
		||||
 | 
			
		||||
    # Shows whether to save history across sessions.
 | 
			
		||||
    prefs['save_history'] = True
 | 
			
		||||
    prefs['compress_history'] = False
 | 
			
		||||
 | 
			
		||||
    # Set the number spaces used for indenting.  According to
 | 
			
		||||
    # :PEP:`8`, it is best to use 4 spaces.  Since most of rope's
 | 
			
		||||
    # unit-tests use 4 spaces it is more reliable, too.
 | 
			
		||||
    prefs['indent_size'] = 4
 | 
			
		||||
 | 
			
		||||
    # Builtin and c-extension modules that are allowed to be imported
 | 
			
		||||
    # and inspected by rope.
 | 
			
		||||
    prefs['extension_modules'] = []
 | 
			
		||||
 | 
			
		||||
    # Add all standard c-extensions to extension_modules list.
 | 
			
		||||
    prefs['import_dynload_stdmods'] = True
 | 
			
		||||
 | 
			
		||||
    # If `True` modules with syntax errors are considered to be empty.
 | 
			
		||||
    # The default value is `False`; When `False` syntax errors raise
 | 
			
		||||
    # `rope.base.exceptions.ModuleSyntaxError` exception.
 | 
			
		||||
    prefs['ignore_syntax_errors'] = False
 | 
			
		||||
 | 
			
		||||
    # If `True`, rope ignores unresolvable imports.  Otherwise, they
 | 
			
		||||
    # appear in the importing namespace.
 | 
			
		||||
    prefs['ignore_bad_imports'] = False
 | 
			
		||||
 | 
			
		||||
    # If `True`, rope will insert new module imports as
 | 
			
		||||
    # `from <package> import <module>` by default.
 | 
			
		||||
    prefs['prefer_module_from_imports'] = False
 | 
			
		||||
 | 
			
		||||
    # If `True`, rope will transform a comma list of imports into
 | 
			
		||||
    # multiple separate import statements when organizing
 | 
			
		||||
    # imports.
 | 
			
		||||
    prefs['split_imports'] = False
 | 
			
		||||
 | 
			
		||||
    # If `True`, rope will remove all top-level import statements and
 | 
			
		||||
    # reinsert them at the top of the module when making changes.
 | 
			
		||||
    prefs['pull_imports_to_top'] = True
 | 
			
		||||
 | 
			
		||||
    # If `True`, rope will sort imports alphabetically by module name instead
 | 
			
		||||
    # of alphabetically by import statement, with from imports after normal
 | 
			
		||||
    # imports.
 | 
			
		||||
    prefs['sort_imports_alphabetically'] = False
 | 
			
		||||
 | 
			
		||||
    # Location of implementation of
 | 
			
		||||
    # rope.base.oi.type_hinting.interfaces.ITypeHintingFactory In general
 | 
			
		||||
    # case, you don't have to change this value, unless you're an rope expert.
 | 
			
		||||
    # Change this value to inject you own implementations of interfaces
 | 
			
		||||
    # listed in module rope.base.oi.type_hinting.providers.interfaces
 | 
			
		||||
    # For example, you can add you own providers for Django Models, or disable
 | 
			
		||||
    # the search type-hinting in a class hierarchy, etc.
 | 
			
		||||
    prefs['type_hinting_factory'] = (
 | 
			
		||||
        'rope.base.oi.type_hinting.factory.default_type_hinting_factory')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def project_opened(project):
 | 
			
		||||
    """This function is called after opening the project"""
 | 
			
		||||
    # Do whatever you like here!
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								.vscode/.ropeproject/objectdb
									
									
									
									
										vendored
									
									
								
							
							
						
						
							
								
								
									
										11
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							
							
						
						@ -1,11 +0,0 @@
 | 
			
		||||
{
 | 
			
		||||
  "python.pythonPath": "env/bin/python",
 | 
			
		||||
  "editor.tabSize": 4,
 | 
			
		||||
  "[html]": {
 | 
			
		||||
    "editor.tabSize": 2
 | 
			
		||||
  },
 | 
			
		||||
  "cSpell.words": [
 | 
			
		||||
    "SAML",
 | 
			
		||||
    "passbook"
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										47
									
								
								Dockerfile
									
									
									
									
									
								
							
							
						
						@ -1,34 +1,35 @@
 | 
			
		||||
FROM python:3.6-slim-stretch as build
 | 
			
		||||
FROM python:3.8-slim-buster as locker
 | 
			
		||||
 | 
			
		||||
COPY ./passbook/ /app/passbook
 | 
			
		||||
COPY ./manage.py /app/
 | 
			
		||||
COPY ./requirements.txt /app/
 | 
			
		||||
COPY ./Pipfile /app/
 | 
			
		||||
COPY ./Pipfile.lock /app/
 | 
			
		||||
 | 
			
		||||
WORKDIR /app/
 | 
			
		||||
 | 
			
		||||
RUN apt-get update && apt-get install build-essential libssl-dev libffi-dev libpq-dev -y && \
 | 
			
		||||
    mkdir /app/static/ && \
 | 
			
		||||
    pip install -r requirements.txt && \
 | 
			
		||||
    pip install psycopg2 && \
 | 
			
		||||
    ./manage.py collectstatic --no-input && \
 | 
			
		||||
    apt-get remove --purge -y build-essential && \
 | 
			
		||||
    apt-get autoremove --purge -y
 | 
			
		||||
RUN pip install pipenv && \
 | 
			
		||||
    pipenv lock -r > requirements.txt && \
 | 
			
		||||
    pipenv lock -rd > requirements-dev.txt
 | 
			
		||||
 | 
			
		||||
FROM python:3.6-slim-stretch
 | 
			
		||||
FROM python:3.8-slim-buster
 | 
			
		||||
 | 
			
		||||
COPY ./passbook/ /app/passbook
 | 
			
		||||
COPY ./manage.py /app/
 | 
			
		||||
COPY ./requirements.txt /app/
 | 
			
		||||
COPY --from=build /app/static /app/static/
 | 
			
		||||
COPY --from=locker /app/requirements.txt /app/
 | 
			
		||||
COPY --from=locker /app/requirements-dev.txt /app/
 | 
			
		||||
 | 
			
		||||
WORKDIR /app/
 | 
			
		||||
 | 
			
		||||
RUN apt-get update && apt-get install build-essential libssl-dev libffi-dev libpq-dev -y && \
 | 
			
		||||
    pip install -r requirements.txt && \
 | 
			
		||||
    pip install psycopg2 && \
 | 
			
		||||
    adduser --system --home /app/ passbook && \
 | 
			
		||||
    chown -R passbook /app/ && \
 | 
			
		||||
    apt-get remove --purge -y build-essential && \
 | 
			
		||||
    apt-get autoremove --purge -y
 | 
			
		||||
RUN apt-get update && \
 | 
			
		||||
    apt-get install -y --no-install-recommends postgresql-client-11 && \
 | 
			
		||||
    rm -rf /var/lib/apt/ && \
 | 
			
		||||
    pip install -r requirements.txt  --no-cache-dir && \
 | 
			
		||||
    adduser --system --no-create-home --uid 1000 --group --home /app passbook
 | 
			
		||||
 | 
			
		||||
COPY ./passbook/ /app/passbook
 | 
			
		||||
COPY ./manage.py /app/
 | 
			
		||||
COPY ./docker/uwsgi.ini /app/
 | 
			
		||||
COPY ./docker/bootstrap.sh /bootstrap.sh
 | 
			
		||||
COPY ./docker/wait_for_db.py /app/wait_for_db.py
 | 
			
		||||
 | 
			
		||||
WORKDIR /app/
 | 
			
		||||
 | 
			
		||||
USER passbook
 | 
			
		||||
 | 
			
		||||
ENTRYPOINT [ "/bootstrap.sh" ]
 | 
			
		||||
 | 
			
		||||
@ -1,12 +0,0 @@
 | 
			
		||||
FROM python:3.6
 | 
			
		||||
 | 
			
		||||
COPY ./passbook/ /app/passbook
 | 
			
		||||
COPY ./client-packages/ /app/client-packages
 | 
			
		||||
COPY ./requirements.txt /app/
 | 
			
		||||
COPY ./requirements-dev.txt /app/
 | 
			
		||||
 | 
			
		||||
WORKDIR /app/
 | 
			
		||||
 | 
			
		||||
RUN apt-get update && apt-get install libssl-dev libffi-dev libpq-dev -y && \
 | 
			
		||||
     pip install -U -r requirements-dev.txt && \
 | 
			
		||||
     rm -rf /app/*
 | 
			
		||||
							
								
								
									
										2
									
								
								LICENSE
									
									
									
									
									
								
							
							
						
						@ -1,6 +1,6 @@
 | 
			
		||||
MIT License
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2018 BeryJu.org
 | 
			
		||||
Copyright (c) 2019 BeryJu.org
 | 
			
		||||
 | 
			
		||||
Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										60
									
								
								Pipfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,60 @@
 | 
			
		||||
[[source]]
 | 
			
		||||
name = "pypi"
 | 
			
		||||
url = "https://pypi.org/simple"
 | 
			
		||||
verify_ssl = true
 | 
			
		||||
 | 
			
		||||
[packages]
 | 
			
		||||
boto3 = "*"
 | 
			
		||||
celery = "*"
 | 
			
		||||
defusedxml = "*"
 | 
			
		||||
django = "*"
 | 
			
		||||
django-cors-middleware = "*"
 | 
			
		||||
django-dbbackup = "*"
 | 
			
		||||
django-filter = "*"
 | 
			
		||||
django-guardian = "*"
 | 
			
		||||
django-model-utils = "*"
 | 
			
		||||
django-oauth-toolkit = "*"
 | 
			
		||||
django-oidc-provider = "*"
 | 
			
		||||
django-otp = "*"
 | 
			
		||||
django-prometheus = "*"
 | 
			
		||||
django-recaptcha = "*"
 | 
			
		||||
django-redis = "*"
 | 
			
		||||
django-rest-framework = "*"
 | 
			
		||||
django-storages = "*"
 | 
			
		||||
djangorestframework-guardian = "*"
 | 
			
		||||
drf-yasg = "*"
 | 
			
		||||
kombu = "*"
 | 
			
		||||
ldap3 = "*"
 | 
			
		||||
lxml = "*"
 | 
			
		||||
oauthlib = "*"
 | 
			
		||||
packaging = "*"
 | 
			
		||||
psycopg2-binary = "*"
 | 
			
		||||
pycryptodome = "*"
 | 
			
		||||
pyuwsgi = "*"
 | 
			
		||||
pyyaml = "*"
 | 
			
		||||
qrcode = "*"
 | 
			
		||||
requests-oauthlib = "*"
 | 
			
		||||
sentry-sdk = "*"
 | 
			
		||||
service_identity = "*"
 | 
			
		||||
signxml = "*"
 | 
			
		||||
structlog = "*"
 | 
			
		||||
swagger-spec-validator = "*"
 | 
			
		||||
urllib3 = {extras = ["secure"],version = "*"}
 | 
			
		||||
 | 
			
		||||
[requires]
 | 
			
		||||
python_version = "3.8"
 | 
			
		||||
 | 
			
		||||
[dev-packages]
 | 
			
		||||
autopep8 = "*"
 | 
			
		||||
bandit = "*"
 | 
			
		||||
bumpversion = "*"
 | 
			
		||||
colorama = "*"
 | 
			
		||||
coverage = "*"
 | 
			
		||||
django-debug-toolbar = "*"
 | 
			
		||||
pylint = "*"
 | 
			
		||||
pylint-django = "*"
 | 
			
		||||
unittest-xml-reporting = "*"
 | 
			
		||||
black = "*"
 | 
			
		||||
 | 
			
		||||
[pipenv]
 | 
			
		||||
allow_prereleases = true
 | 
			
		||||
							
								
								
									
										1189
									
								
								Pipfile.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										92
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,92 @@
 | 
			
		||||
<img src="passbook/static/static/passbook/logo.svg" height="50" alt="passbook logo"><img src="passbook/static/static/passbook/brand_inverted.svg" height="50" alt="passbook">
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||

 | 
			
		||||

 | 
			
		||||

 | 
			
		||||

 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
## What is passbook?
 | 
			
		||||
 | 
			
		||||
passbook is an open-source Identity Provider focused on flexibility and versatility. You can use passbook in an existing environment to add support for new protocols. passbook is also a great solution for implementing signup/recovery/etc in your application, so you don't have to deal with it.
 | 
			
		||||
 | 
			
		||||
## Installation
 | 
			
		||||
 | 
			
		||||
For small/test setups it is recommended to use docker-compose.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
wget https://raw.githubusercontent.com/BeryJu/passbook/master/docker-compose.yml
 | 
			
		||||
# Optionally enable Error-reporting
 | 
			
		||||
# export PASSBOOK_ERROR_REPORTING=true
 | 
			
		||||
# Optionally deploy a different version
 | 
			
		||||
# export PASSBOOK_TAG=0.8.15-beta
 | 
			
		||||
# If this is a productive installation, set a different PostgreSQL Password
 | 
			
		||||
# export PG_PASS=$(pwgen 40 1)
 | 
			
		||||
docker-compose pull
 | 
			
		||||
docker-compose up -d
 | 
			
		||||
docker-compose exec server ./manage.py migrate
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
For bigger setups, there is a Helm Chart in the `helm/` directory. This is documented [here](https://passbook.beryju.org//installation/kubernetes/)
 | 
			
		||||
 | 
			
		||||
## Screenshots
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
## Development
 | 
			
		||||
 | 
			
		||||
To develop on passbook, you need a system with Python 3.7+ (3.8 is recommended). passbook uses [pipenv](https://pipenv.pypa.io/en/latest/) for managing dependencies.
 | 
			
		||||
 | 
			
		||||
To get started, run
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
python3 -m pip install pipenv
 | 
			
		||||
git clone https://github.com/BeryJu/passbook.git
 | 
			
		||||
cd passbook
 | 
			
		||||
pipenv shell
 | 
			
		||||
pipenv sync -d
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Since passbook uses PostgreSQL-specific fields, you also need a local PostgreSQL instance to develop. passbook also uses redis for caching and message queueing.
 | 
			
		||||
For these databases you can use [Postgres.app](https://postgresapp.com/) and [Redis.app](https://jpadilla.github.io/redisapp/) on macOS or use it via docker-comppose:
 | 
			
		||||
 | 
			
		||||
```yaml
 | 
			
		||||
version: '3.7'
 | 
			
		||||
 | 
			
		||||
services:
 | 
			
		||||
  postgresql:
 | 
			
		||||
    container_name: postgres
 | 
			
		||||
    image: postgres:11
 | 
			
		||||
    volumes:
 | 
			
		||||
    - db-data:/var/lib/postgresql/data
 | 
			
		||||
    ports:
 | 
			
		||||
    - 127.0.0.1:5432:5432
 | 
			
		||||
    restart: always
 | 
			
		||||
  redis:
 | 
			
		||||
    container_name: redis
 | 
			
		||||
    image: redis
 | 
			
		||||
    ports:
 | 
			
		||||
    - 127.0.0.1:6379:6379
 | 
			
		||||
    restart: always
 | 
			
		||||
 | 
			
		||||
volumes:
 | 
			
		||||
  db-data:
 | 
			
		||||
    driver: local
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
To tell passbook about these databases, create a file in the project root called `local.env.yml` with the following contents:
 | 
			
		||||
 | 
			
		||||
```yaml
 | 
			
		||||
debug: true
 | 
			
		||||
postgresql:
 | 
			
		||||
  user: postgres
 | 
			
		||||
 | 
			
		||||
log_level: debug
 | 
			
		||||
error_reporting: false
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Security
 | 
			
		||||
 | 
			
		||||
See [SECURITY.md](SECURITY.md)
 | 
			
		||||
							
								
								
									
										13
									
								
								SECURITY.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,13 @@
 | 
			
		||||
# Security Policy
 | 
			
		||||
 | 
			
		||||
## Supported Versions
 | 
			
		||||
 | 
			
		||||
As passbook is currently in a pre-stable, only the latest "stable" version is supported. After passbook 1.0, this will change.
 | 
			
		||||
 | 
			
		||||
| Version  | Supported          |
 | 
			
		||||
| -------- | ------------------ |
 | 
			
		||||
| 0.8.15   | :white_check_mark: |
 | 
			
		||||
 | 
			
		||||
## Reporting a Vulnerability
 | 
			
		||||
 | 
			
		||||
To report a vulnerability, send am email to [security@beryju.org](mailto:security@beryju.org)
 | 
			
		||||
@ -1,35 +0,0 @@
 | 
			
		||||
"""passbook provider"""
 | 
			
		||||
from allauth.socialaccount.providers.base import ProviderAccount
 | 
			
		||||
from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class PassbookAccount(ProviderAccount):
 | 
			
		||||
    """passbook account"""
 | 
			
		||||
 | 
			
		||||
    def to_str(self):
 | 
			
		||||
        dflt = super().to_str()
 | 
			
		||||
        return self.account.extra_data.get('username', dflt)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class PassbookProvider(OAuth2Provider):
 | 
			
		||||
    """passbook provider"""
 | 
			
		||||
 | 
			
		||||
    id = 'passbook'
 | 
			
		||||
    name = 'passbook'
 | 
			
		||||
    account_class = PassbookAccount
 | 
			
		||||
 | 
			
		||||
    def extract_uid(self, data):
 | 
			
		||||
        return str(data['sub'])
 | 
			
		||||
 | 
			
		||||
    def extract_common_fields(self, data):
 | 
			
		||||
        return {
 | 
			
		||||
            'email': data.get('email'),
 | 
			
		||||
            'username': data.get('preferred_username'),
 | 
			
		||||
            'name': data.get('name'),
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    def get_default_scope(self):
 | 
			
		||||
        return ['openid:userinfo']
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
provider_classes = [PassbookProvider] # noqa
 | 
			
		||||
@ -1,6 +0,0 @@
 | 
			
		||||
"""passbook provider"""
 | 
			
		||||
from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns
 | 
			
		||||
 | 
			
		||||
from allauth_passbook.provider import PassbookProvider
 | 
			
		||||
 | 
			
		||||
urlpatterns = default_urlpatterns(PassbookProvider)
 | 
			
		||||
@ -1,37 +0,0 @@
 | 
			
		||||
"""passbook adapter"""
 | 
			
		||||
import requests
 | 
			
		||||
from allauth.socialaccount import app_settings
 | 
			
		||||
from allauth.socialaccount.providers.oauth2.views import (OAuth2Adapter,
 | 
			
		||||
                                                          OAuth2CallbackView,
 | 
			
		||||
                                                          OAuth2LoginView)
 | 
			
		||||
 | 
			
		||||
from allauth_passbook.provider import PassbookProvider
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class PassbookOAuth2Adapter(OAuth2Adapter):
 | 
			
		||||
    """passbook OAuth2 Adapter"""
 | 
			
		||||
    provider_id = PassbookProvider.id
 | 
			
		||||
    # pylint: disable=no-member
 | 
			
		||||
    settings = app_settings.PROVIDERS.get(provider_id, {}) # noqa
 | 
			
		||||
    provider_base_url = settings.get("PASSBOOK_URL", 'https://id.beryju.org')
 | 
			
		||||
 | 
			
		||||
    access_token_url = '{0}/application/oauth/token/'.format(provider_base_url)
 | 
			
		||||
    authorize_url = '{0}/application/oauth/authorize/'.format(provider_base_url)
 | 
			
		||||
    profile_url = '{0}/api/v1/openid/'.format(
 | 
			
		||||
        provider_base_url)
 | 
			
		||||
 | 
			
		||||
    def complete_login(self, request, app, access_token, **kwargs):
 | 
			
		||||
        headers = {
 | 
			
		||||
            'Authorization': 'Bearer {0}'.format(access_token.token),
 | 
			
		||||
            'Content-Type': 'application/json',
 | 
			
		||||
        }
 | 
			
		||||
        extra_data = requests.get(self.profile_url, headers=headers)
 | 
			
		||||
 | 
			
		||||
        return self.get_provider().sociallogin_from_response(
 | 
			
		||||
            request,
 | 
			
		||||
            extra_data.json()
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
oauth2_login = OAuth2LoginView.adapter_view(PassbookOAuth2Adapter) # noqa
 | 
			
		||||
oauth2_callback = OAuth2CallbackView.adapter_view(PassbookOAuth2Adapter) # noqa
 | 
			
		||||
@ -1 +0,0 @@
 | 
			
		||||
django-allauth
 | 
			
		||||
@ -1,33 +0,0 @@
 | 
			
		||||
"""passbook allauth setup.py"""
 | 
			
		||||
from setuptools import setup
 | 
			
		||||
 | 
			
		||||
setup(
 | 
			
		||||
    name='django-allauth-passbook',
 | 
			
		||||
    version='0.1.33-beta',
 | 
			
		||||
    description='passbook support for django-allauth',
 | 
			
		||||
    # long_description='\n'.join(read_simple('docs/index.md')[2:]),
 | 
			
		||||
    long_description_content_type='text/markdown',
 | 
			
		||||
    author='BeryJu.org',
 | 
			
		||||
    author_email='hello@beryju.org',
 | 
			
		||||
    packages=['allauth_passbook'],
 | 
			
		||||
    include_package_data=True,
 | 
			
		||||
    install_requires=['django-allauth'],
 | 
			
		||||
    keywords='django allauth passbook',
 | 
			
		||||
    license='MIT',
 | 
			
		||||
    classifiers=[
 | 
			
		||||
        'Intended Audience :: Developers',
 | 
			
		||||
        'Topic :: Software Development :: Libraries :: Python Modules',
 | 
			
		||||
        'Environment :: Web Environment',
 | 
			
		||||
        'Topic :: Internet',
 | 
			
		||||
        'License :: OSI Approved :: MIT License',
 | 
			
		||||
        'Operating System :: OS Independent',
 | 
			
		||||
        'Programming Language :: Python',
 | 
			
		||||
        'Programming Language :: Python :: 3.4',
 | 
			
		||||
        'Programming Language :: Python :: 3.5',
 | 
			
		||||
        'Programming Language :: Python :: 3.6',
 | 
			
		||||
        'Framework :: Django',
 | 
			
		||||
        'Framework :: Django :: 1.11',
 | 
			
		||||
        'Framework :: Django :: 2.0',
 | 
			
		||||
        'Framework :: Django :: 2.1',
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
@ -1,5 +0,0 @@
 | 
			
		||||
*.pyc
 | 
			
		||||
*.egg-info/
 | 
			
		||||
*.eggs
 | 
			
		||||
/dist
 | 
			
		||||
/build
 | 
			
		||||
@ -1,32 +0,0 @@
 | 
			
		||||
sudo: false
 | 
			
		||||
language: python
 | 
			
		||||
services:
 | 
			
		||||
  - memcached
 | 
			
		||||
  - postgresql
 | 
			
		||||
  - redis-server
 | 
			
		||||
python:
 | 
			
		||||
  - '2.7'
 | 
			
		||||
cache:
 | 
			
		||||
  directories:
 | 
			
		||||
    - node_modules
 | 
			
		||||
    - "$HOME/.cache/pip"
 | 
			
		||||
deploy:
 | 
			
		||||
  provider: pypi
 | 
			
		||||
  user: getsentry
 | 
			
		||||
  password:
 | 
			
		||||
    secure: kVmxKHkBWRLYyZme05p+WZSJmb8GjHV9uyuaSCVMRlqWCW+GXRB7P1xXR2jb9URTlNdcs56Ab/UrwzCbMFGC8LmwCeFVgIR/ltytVZG2FgXZPWaeA4dH25qK2oGWgzJ/xeiMpmuJqN9hRl25MX6jG7FZKvrrOkG7+8tpPd1yO+uYWZQbnebZMjcPBqEpn7CC0hR39GSoyVAbydpMe5hwENGQM26CepcicdrelfawItoUrXrkJzBHkIQQTO/xRSbCtRJOtzI5lwtv3GP0hcbOy5tI5dhG/93pLwZRc5+dZaCaP7oaVeOcBjN0zfINRQobt8d6h2Qgvd/YyFkGi0/xKn1zMmKIVLOG6VsYwEAUq8wNOsP4A/jdm4Y0J/1oEZStCkpaGpx85TYi4kq1hWQdyqaVJSPhh4Tk4roIaS2zOYQl+nIpbHqmJ4FJrg1il+TCdjBXobATQ1mKRBUrjD+RDzH/r4ogbd8+UwvvvevpqS2K+/wgT6UD0MzDInv9S29CUQvuFhPoqyJb5XRddHMRE9EEK/2Z8tFN91sDATnqfXHgwnvu00q/nKP5JnijBPzGmx7ydgUViIukklDrlPvo9BbRJz0Vr2vbAvMTrLMLCXqi5CwTm+v+iaOf/YaCziaG2vx0eVASYjpOLCedSgRZBubPM8z4E/HMXhChN7sVDWk=
 | 
			
		||||
  on:
 | 
			
		||||
    tags: true
 | 
			
		||||
  distributions: sdist bdist_wheel
 | 
			
		||||
env:
 | 
			
		||||
  global:
 | 
			
		||||
    - PIP_DOWNLOAD_CACHE=".pip_download_cache"
 | 
			
		||||
before_install:
 | 
			
		||||
  - pip install codecov
 | 
			
		||||
install:
 | 
			
		||||
  - make develop
 | 
			
		||||
script:
 | 
			
		||||
  - PYFLAKES_NODOCTEST=1 flake8
 | 
			
		||||
  - coverage run --source=. -m py.test tests
 | 
			
		||||
after_success:
 | 
			
		||||
  - codecov
 | 
			
		||||
@ -1,201 +0,0 @@
 | 
			
		||||
                              Apache License
 | 
			
		||||
                        Version 2.0, January 2004
 | 
			
		||||
                     http://www.apache.org/licenses/
 | 
			
		||||
 | 
			
		||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 | 
			
		||||
 | 
			
		||||
1. Definitions.
 | 
			
		||||
 | 
			
		||||
   "License" shall mean the terms and conditions for use, reproduction,
 | 
			
		||||
   and distribution as defined by Sections 1 through 9 of this document.
 | 
			
		||||
 | 
			
		||||
   "Licensor" shall mean the copyright owner or entity authorized by
 | 
			
		||||
   the copyright owner that is granting the License.
 | 
			
		||||
 | 
			
		||||
   "Legal Entity" shall mean the union of the acting entity and all
 | 
			
		||||
   other entities that control, are controlled by, or are under common
 | 
			
		||||
   control with that entity. For the purposes of this definition,
 | 
			
		||||
   "control" means (i) the power, direct or indirect, to cause the
 | 
			
		||||
   direction or management of such entity, whether by contract or
 | 
			
		||||
   otherwise, or (ii) ownership of fifty percent (50%) or more of the
 | 
			
		||||
   outstanding shares, or (iii) beneficial ownership of such entity.
 | 
			
		||||
 | 
			
		||||
   "You" (or "Your") shall mean an individual or Legal Entity
 | 
			
		||||
   exercising permissions granted by this License.
 | 
			
		||||
 | 
			
		||||
   "Source" form shall mean the preferred form for making modifications,
 | 
			
		||||
   including but not limited to software source code, documentation
 | 
			
		||||
   source, and configuration files.
 | 
			
		||||
 | 
			
		||||
   "Object" form shall mean any form resulting from mechanical
 | 
			
		||||
   transformation or translation of a Source form, including but
 | 
			
		||||
   not limited to compiled object code, generated documentation,
 | 
			
		||||
   and conversions to other media types.
 | 
			
		||||
 | 
			
		||||
   "Work" shall mean the work of authorship, whether in Source or
 | 
			
		||||
   Object form, made available under the License, as indicated by a
 | 
			
		||||
   copyright notice that is included in or attached to the work
 | 
			
		||||
   (an example is provided in the Appendix below).
 | 
			
		||||
 | 
			
		||||
   "Derivative Works" shall mean any work, whether in Source or Object
 | 
			
		||||
   form, that is based on (or derived from) the Work and for which the
 | 
			
		||||
   editorial revisions, annotations, elaborations, or other modifications
 | 
			
		||||
   represent, as a whole, an original work of authorship. For the purposes
 | 
			
		||||
   of this License, Derivative Works shall not include works that remain
 | 
			
		||||
   separable from, or merely link (or bind by name) to the interfaces of,
 | 
			
		||||
   the Work and Derivative Works thereof.
 | 
			
		||||
 | 
			
		||||
   "Contribution" shall mean any work of authorship, including
 | 
			
		||||
   the original version of the Work and any modifications or additions
 | 
			
		||||
   to that Work or Derivative Works thereof, that is intentionally
 | 
			
		||||
   submitted to Licensor for inclusion in the Work by the copyright owner
 | 
			
		||||
   or by an individual or Legal Entity authorized to submit on behalf of
 | 
			
		||||
   the copyright owner. For the purposes of this definition, "submitted"
 | 
			
		||||
   means any form of electronic, verbal, or written communication sent
 | 
			
		||||
   to the Licensor or its representatives, including but not limited to
 | 
			
		||||
   communication on electronic mailing lists, source code control systems,
 | 
			
		||||
   and issue tracking systems that are managed by, or on behalf of, the
 | 
			
		||||
   Licensor for the purpose of discussing and improving the Work, but
 | 
			
		||||
   excluding communication that is conspicuously marked or otherwise
 | 
			
		||||
   designated in writing by the copyright owner as "Not a Contribution."
 | 
			
		||||
 | 
			
		||||
   "Contributor" shall mean Licensor and any individual or Legal Entity
 | 
			
		||||
   on behalf of whom a Contribution has been received by Licensor and
 | 
			
		||||
   subsequently incorporated within the Work.
 | 
			
		||||
 | 
			
		||||
2. Grant of Copyright License. Subject to the terms and conditions of
 | 
			
		||||
   this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
   copyright license to reproduce, prepare Derivative Works of,
 | 
			
		||||
   publicly display, publicly perform, sublicense, and distribute the
 | 
			
		||||
   Work and such Derivative Works in Source or Object form.
 | 
			
		||||
 | 
			
		||||
3. Grant of Patent License. Subject to the terms and conditions of
 | 
			
		||||
   this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
   (except as stated in this section) patent license to make, have made,
 | 
			
		||||
   use, offer to sell, sell, import, and otherwise transfer the Work,
 | 
			
		||||
   where such license applies only to those patent claims licensable
 | 
			
		||||
   by such Contributor that are necessarily infringed by their
 | 
			
		||||
   Contribution(s) alone or by combination of their Contribution(s)
 | 
			
		||||
   with the Work to which such Contribution(s) was submitted. If You
 | 
			
		||||
   institute patent litigation against any entity (including a
 | 
			
		||||
   cross-claim or counterclaim in a lawsuit) alleging that the Work
 | 
			
		||||
   or a Contribution incorporated within the Work constitutes direct
 | 
			
		||||
   or contributory patent infringement, then any patent licenses
 | 
			
		||||
   granted to You under this License for that Work shall terminate
 | 
			
		||||
   as of the date such litigation is filed.
 | 
			
		||||
 | 
			
		||||
4. Redistribution. You may reproduce and distribute copies of the
 | 
			
		||||
   Work or Derivative Works thereof in any medium, with or without
 | 
			
		||||
   modifications, and in Source or Object form, provided that You
 | 
			
		||||
   meet the following conditions:
 | 
			
		||||
 | 
			
		||||
   (a) You must give any other recipients of the Work or
 | 
			
		||||
       Derivative Works a copy of this License; and
 | 
			
		||||
 | 
			
		||||
   (b) You must cause any modified files to carry prominent notices
 | 
			
		||||
       stating that You changed the files; and
 | 
			
		||||
 | 
			
		||||
   (c) You must retain, in the Source form of any Derivative Works
 | 
			
		||||
       that You distribute, all copyright, patent, trademark, and
 | 
			
		||||
       attribution notices from the Source form of the Work,
 | 
			
		||||
       excluding those notices that do not pertain to any part of
 | 
			
		||||
       the Derivative Works; and
 | 
			
		||||
 | 
			
		||||
   (d) If the Work includes a "NOTICE" text file as part of its
 | 
			
		||||
       distribution, then any Derivative Works that You distribute must
 | 
			
		||||
       include a readable copy of the attribution notices contained
 | 
			
		||||
       within such NOTICE file, excluding those notices that do not
 | 
			
		||||
       pertain to any part of the Derivative Works, in at least one
 | 
			
		||||
       of the following places: within a NOTICE text file distributed
 | 
			
		||||
       as part of the Derivative Works; within the Source form or
 | 
			
		||||
       documentation, if provided along with the Derivative Works; or,
 | 
			
		||||
       within a display generated by the Derivative Works, if and
 | 
			
		||||
       wherever such third-party notices normally appear. The contents
 | 
			
		||||
       of the NOTICE file are for informational purposes only and
 | 
			
		||||
       do not modify the License. You may add Your own attribution
 | 
			
		||||
       notices within Derivative Works that You distribute, alongside
 | 
			
		||||
       or as an addendum to the NOTICE text from the Work, provided
 | 
			
		||||
       that such additional attribution notices cannot be construed
 | 
			
		||||
       as modifying the License.
 | 
			
		||||
 | 
			
		||||
   You may add Your own copyright statement to Your modifications and
 | 
			
		||||
   may provide additional or different license terms and conditions
 | 
			
		||||
   for use, reproduction, or distribution of Your modifications, or
 | 
			
		||||
   for any such Derivative Works as a whole, provided Your use,
 | 
			
		||||
   reproduction, and distribution of the Work otherwise complies with
 | 
			
		||||
   the conditions stated in this License.
 | 
			
		||||
 | 
			
		||||
5. Submission of Contributions. Unless You explicitly state otherwise,
 | 
			
		||||
   any Contribution intentionally submitted for inclusion in the Work
 | 
			
		||||
   by You to the Licensor shall be under the terms and conditions of
 | 
			
		||||
   this License, without any additional terms or conditions.
 | 
			
		||||
   Notwithstanding the above, nothing herein shall supersede or modify
 | 
			
		||||
   the terms of any separate license agreement you may have executed
 | 
			
		||||
   with Licensor regarding such Contributions.
 | 
			
		||||
 | 
			
		||||
6. Trademarks. This License does not grant permission to use the trade
 | 
			
		||||
   names, trademarks, service marks, or product names of the Licensor,
 | 
			
		||||
   except as required for reasonable and customary use in describing the
 | 
			
		||||
   origin of the Work and reproducing the content of the NOTICE file.
 | 
			
		||||
 | 
			
		||||
7. Disclaimer of Warranty. Unless required by applicable law or
 | 
			
		||||
   agreed to in writing, Licensor provides the Work (and each
 | 
			
		||||
   Contributor provides its Contributions) on an "AS IS" BASIS,
 | 
			
		||||
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 | 
			
		||||
   implied, including, without limitation, any warranties or conditions
 | 
			
		||||
   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
 | 
			
		||||
   PARTICULAR PURPOSE. You are solely responsible for determining the
 | 
			
		||||
   appropriateness of using or redistributing the Work and assume any
 | 
			
		||||
   risks associated with Your exercise of permissions under this License.
 | 
			
		||||
 | 
			
		||||
8. Limitation of Liability. In no event and under no legal theory,
 | 
			
		||||
   whether in tort (including negligence), contract, or otherwise,
 | 
			
		||||
   unless required by applicable law (such as deliberate and grossly
 | 
			
		||||
   negligent acts) or agreed to in writing, shall any Contributor be
 | 
			
		||||
   liable to You for damages, including any direct, indirect, special,
 | 
			
		||||
   incidental, or consequential damages of any character arising as a
 | 
			
		||||
   result of this License or out of the use or inability to use the
 | 
			
		||||
   Work (including but not limited to damages for loss of goodwill,
 | 
			
		||||
   work stoppage, computer failure or malfunction, or any and all
 | 
			
		||||
   other commercial damages or losses), even if such Contributor
 | 
			
		||||
   has been advised of the possibility of such damages.
 | 
			
		||||
 | 
			
		||||
9. Accepting Warranty or Additional Liability. While redistributing
 | 
			
		||||
   the Work or Derivative Works thereof, You may choose to offer,
 | 
			
		||||
   and charge a fee for, acceptance of support, warranty, indemnity,
 | 
			
		||||
   or other liability obligations and/or rights consistent with this
 | 
			
		||||
   License. However, in accepting such obligations, You may act only
 | 
			
		||||
   on Your own behalf and on Your sole responsibility, not on behalf
 | 
			
		||||
   of any other Contributor, and only if You agree to indemnify,
 | 
			
		||||
   defend, and hold each Contributor harmless for any liability
 | 
			
		||||
   incurred by, or claims asserted against, such Contributor by reason
 | 
			
		||||
   of your accepting any such warranty or additional liability.
 | 
			
		||||
 | 
			
		||||
END OF TERMS AND CONDITIONS
 | 
			
		||||
 | 
			
		||||
APPENDIX: How to apply the Apache License to your work.
 | 
			
		||||
 | 
			
		||||
   To apply the Apache License to your work, attach the following
 | 
			
		||||
   boilerplate notice, with the fields enclosed by brackets "[]"
 | 
			
		||||
   replaced with your own identifying information. (Don't include
 | 
			
		||||
   the brackets!)  The text should be enclosed in the appropriate
 | 
			
		||||
   comment syntax for the file format. We also recommend that a
 | 
			
		||||
   file or class name and description of purpose be included on the
 | 
			
		||||
   same "printed page" as the copyright notice for easier
 | 
			
		||||
   identification within third-party archives.
 | 
			
		||||
 | 
			
		||||
Copyright 2016 Functional Software, Inc.
 | 
			
		||||
 | 
			
		||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
you may not use this file except in compliance with the License.
 | 
			
		||||
You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
See the License for the specific language governing permissions and
 | 
			
		||||
limitations under the License.
 | 
			
		||||
@ -1,3 +0,0 @@
 | 
			
		||||
include setup.py package.json webpack.config.js README.rst MANIFEST.in LICENSE AUTHORS
 | 
			
		||||
recursive-include sentry_auth_supervisr/templates *
 | 
			
		||||
global-exclude *~
 | 
			
		||||
@ -1,26 +0,0 @@
 | 
			
		||||
.PHONY: clean develop install-tests lint publish test
 | 
			
		||||
 | 
			
		||||
develop:
 | 
			
		||||
	pip install "pip>=7"
 | 
			
		||||
	pip install -e .
 | 
			
		||||
	make install-tests
 | 
			
		||||
 | 
			
		||||
install-tests:
 | 
			
		||||
	pip install .[tests]
 | 
			
		||||
 | 
			
		||||
lint:
 | 
			
		||||
	@echo "--> Linting python"
 | 
			
		||||
	flake8
 | 
			
		||||
	@echo ""
 | 
			
		||||
 | 
			
		||||
test:
 | 
			
		||||
	@echo "--> Running Python tests"
 | 
			
		||||
	py.test tests || exit 1
 | 
			
		||||
	@echo ""
 | 
			
		||||
 | 
			
		||||
publish:
 | 
			
		||||
	python setup.py sdist bdist_wheel upload
 | 
			
		||||
 | 
			
		||||
clean:
 | 
			
		||||
	rm -rf *.egg-info src/*.egg-info
 | 
			
		||||
	rm -rf dist build
 | 
			
		||||
@ -1,55 +0,0 @@
 | 
			
		||||
GitHub Auth for Sentry
 | 
			
		||||
======================
 | 
			
		||||
 | 
			
		||||
An SSO provider for Sentry which enables GitHub organization-restricted authentication.
 | 
			
		||||
 | 
			
		||||
Install
 | 
			
		||||
-------
 | 
			
		||||
 | 
			
		||||
::
 | 
			
		||||
 | 
			
		||||
    $ pip install https://github.com/getsentry/sentry-auth-github/archive/master.zip
 | 
			
		||||
 | 
			
		||||
Setup
 | 
			
		||||
-----
 | 
			
		||||
 | 
			
		||||
Create a new application under your organization in GitHub. Enter the **Authorization
 | 
			
		||||
callback URL** as the prefix to your Sentry installation:
 | 
			
		||||
 | 
			
		||||
::
 | 
			
		||||
 | 
			
		||||
    https://example.sentry.com
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Once done, grab your API keys and drop them in your ``sentry.conf.py``:
 | 
			
		||||
 | 
			
		||||
.. code-block:: python
 | 
			
		||||
 | 
			
		||||
    GITHUB_APP_ID = ""
 | 
			
		||||
 | 
			
		||||
    GITHUB_API_SECRET = ""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Verified email addresses can optionally be required:
 | 
			
		||||
 | 
			
		||||
.. code-block:: python
 | 
			
		||||
 | 
			
		||||
    GITHUB_REQUIRE_VERIFIED_EMAIL = True
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Optionally you may also specify the domain (for GHE users):
 | 
			
		||||
 | 
			
		||||
.. code-block:: python
 | 
			
		||||
 | 
			
		||||
    GITHUB_BASE_DOMAIN = "git.example.com"
 | 
			
		||||
 | 
			
		||||
    GITHUB_API_DOMAIN = "api.git.example.com"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
If Subdomain isolation is disabled in GHE:
 | 
			
		||||
 | 
			
		||||
.. code-block:: python
 | 
			
		||||
 | 
			
		||||
    GITHUB_BASE_DOMAIN = "git.example.com"
 | 
			
		||||
 | 
			
		||||
    GITHUB_API_DOMAIN = "git.example.com/api/v3"
 | 
			
		||||
@ -1,14 +0,0 @@
 | 
			
		||||
from __future__ import absolute_import
 | 
			
		||||
 | 
			
		||||
# Run tests against sqlite for simplicity
 | 
			
		||||
import os
 | 
			
		||||
import os.path
 | 
			
		||||
import sys
 | 
			
		||||
 | 
			
		||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__)))
 | 
			
		||||
 | 
			
		||||
os.environ.setdefault('DB', 'sqlite')
 | 
			
		||||
 | 
			
		||||
pytest_plugins = [
 | 
			
		||||
    'sentry.utils.pytest'
 | 
			
		||||
]
 | 
			
		||||
@ -1,7 +0,0 @@
 | 
			
		||||
from __future__ import absolute_import
 | 
			
		||||
 | 
			
		||||
from sentry.auth import register
 | 
			
		||||
 | 
			
		||||
from .provider import PassbookOAuth2Provider
 | 
			
		||||
 | 
			
		||||
register('passbook', PassbookOAuth2Provider)
 | 
			
		||||
@ -1,45 +0,0 @@
 | 
			
		||||
from __future__ import absolute_import, print_function
 | 
			
		||||
 | 
			
		||||
from requests.exceptions import RequestException
 | 
			
		||||
 | 
			
		||||
from sentry import http
 | 
			
		||||
from sentry.utils import json
 | 
			
		||||
 | 
			
		||||
from .constants import BASE_DOMAIN
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class PassbookApiError(Exception):
 | 
			
		||||
    def __init__(self, message='', status=0):
 | 
			
		||||
        super(PassbookApiError, self).__init__(message)
 | 
			
		||||
        self.status = status
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class PassbookClient(object):
 | 
			
		||||
    def __init__(self, client_id, client_secret):
 | 
			
		||||
        self.client_id = client_id
 | 
			
		||||
        self.client_secret = client_secret
 | 
			
		||||
        self.http = http.build_session()
 | 
			
		||||
 | 
			
		||||
    def _request(self, path, access_token):
 | 
			
		||||
        params = {
 | 
			
		||||
            'client_id': self.client_id,
 | 
			
		||||
            'client_secret': self.client_secret,
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        headers = {
 | 
			
		||||
            'Authorization': 'Bearer {0}'.format(access_token),
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        try:
 | 
			
		||||
            req = self.http.get('https://{0}/{1}'.format(BASE_DOMAIN, path.lstrip('/')),
 | 
			
		||||
                params=params,
 | 
			
		||||
                headers=headers,
 | 
			
		||||
            )
 | 
			
		||||
        except RequestException as e:
 | 
			
		||||
            raise PassbookApiError(unicode(e), status=getattr(e, 'status_code', 0))
 | 
			
		||||
        if req.status_code < 200 or req.status_code >= 300:
 | 
			
		||||
            raise PassbookApiError(req.content, status=req.status_code)
 | 
			
		||||
        return json.loads(req.content)
 | 
			
		||||
 | 
			
		||||
    def get_user(self, access_token):
 | 
			
		||||
        return self._request('/api/v1/openid/', access_token)
 | 
			
		||||
@ -1,14 +0,0 @@
 | 
			
		||||
from __future__ import absolute_import, print_function
 | 
			
		||||
 | 
			
		||||
from django.conf import settings
 | 
			
		||||
 | 
			
		||||
CLIENT_ID = getattr(settings, 'PASSBOOK_APP_ID', None)
 | 
			
		||||
 | 
			
		||||
CLIENT_SECRET = getattr(settings, 'PASSBOOK_API_SECRET', None)
 | 
			
		||||
 | 
			
		||||
SCOPE = 'openid:userinfo'
 | 
			
		||||
 | 
			
		||||
BASE_DOMAIN = getattr(settings, 'PASSBOOK_BASE_DOMAIN', 'id.beryju.org')
 | 
			
		||||
 | 
			
		||||
ACCESS_TOKEN_URL = 'https://{0}/application/oauth/token/'.format(BASE_DOMAIN)
 | 
			
		||||
AUTHORIZE_URL = 'https://{0}/application/oauth/authorize/'.format(BASE_DOMAIN)
 | 
			
		||||
@ -1,62 +0,0 @@
 | 
			
		||||
from __future__ import absolute_import, print_function
 | 
			
		||||
 | 
			
		||||
from sentry.auth.exceptions import IdentityNotValid
 | 
			
		||||
from sentry.auth.providers.oauth2 import (OAuth2Callback, OAuth2Login,
 | 
			
		||||
                                          OAuth2Provider)
 | 
			
		||||
 | 
			
		||||
from .client import PassbookApiError, PassbookClient
 | 
			
		||||
from .constants import (ACCESS_TOKEN_URL, AUTHORIZE_URL, CLIENT_ID,
 | 
			
		||||
                        CLIENT_SECRET, SCOPE)
 | 
			
		||||
from .views import FetchUser, PassbookConfigureView
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class PassbookOAuth2Provider(OAuth2Provider):
 | 
			
		||||
    access_token_url = ACCESS_TOKEN_URL
 | 
			
		||||
    authorize_url = AUTHORIZE_URL
 | 
			
		||||
    name = 'Passbook'
 | 
			
		||||
    client_id = CLIENT_ID
 | 
			
		||||
    client_secret = CLIENT_SECRET
 | 
			
		||||
 | 
			
		||||
    def __init__(self, **config):
 | 
			
		||||
        super(PassbookOAuth2Provider, self).__init__(**config)
 | 
			
		||||
 | 
			
		||||
    def get_configure_view(self):
 | 
			
		||||
        return PassbookConfigureView.as_view()
 | 
			
		||||
 | 
			
		||||
    def get_auth_pipeline(self):
 | 
			
		||||
        return [
 | 
			
		||||
            OAuth2Login(
 | 
			
		||||
                authorize_url=self.authorize_url,
 | 
			
		||||
                client_id=self.client_id,
 | 
			
		||||
                scope=SCOPE,
 | 
			
		||||
            ),
 | 
			
		||||
            OAuth2Callback(
 | 
			
		||||
                access_token_url=self.access_token_url,
 | 
			
		||||
                client_id=self.client_id,
 | 
			
		||||
                client_secret=self.client_secret,
 | 
			
		||||
            ),
 | 
			
		||||
            FetchUser(
 | 
			
		||||
                client_id=self.client_id,
 | 
			
		||||
                client_secret=self.client_secret,
 | 
			
		||||
            ),
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
    def get_refresh_token_url(self):
 | 
			
		||||
        return ACCESS_TOKEN_URL
 | 
			
		||||
 | 
			
		||||
    def build_identity(self, state):
 | 
			
		||||
        data = state['data']
 | 
			
		||||
        user_data = state['user']
 | 
			
		||||
        return {
 | 
			
		||||
            'id': user_data['email'],
 | 
			
		||||
            'email': user_data['email'],
 | 
			
		||||
            'name': user_data['name'],
 | 
			
		||||
            'data': self.get_oauth_data(data),
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    def build_config(self, state):
 | 
			
		||||
        return {}
 | 
			
		||||
 | 
			
		||||
    def refresh_identity(self, auth_identity):
 | 
			
		||||
        client = PassbookClient(self.client_id, self.client_secret)
 | 
			
		||||
        access_token = auth_identity.data['access_token']
 | 
			
		||||
@ -1,75 +0,0 @@
 | 
			
		||||
from __future__ import absolute_import, print_function
 | 
			
		||||
 | 
			
		||||
from django import forms
 | 
			
		||||
 | 
			
		||||
from sentry.auth.view import AuthView, ConfigureView
 | 
			
		||||
from sentry.models import AuthIdentity
 | 
			
		||||
 | 
			
		||||
from .client import PassbookClient
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def _get_name_from_email(email):
 | 
			
		||||
    """
 | 
			
		||||
    Given an email return a capitalized name. Ex. john.smith@example.com would return John Smith.
 | 
			
		||||
    """
 | 
			
		||||
    name = email.rsplit('@', 1)[0]
 | 
			
		||||
    name = ' '.join([n_part.capitalize() for n_part in name.split('.')])
 | 
			
		||||
    return name
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class FetchUser(AuthView):
 | 
			
		||||
    def __init__(self, client_id, client_secret, *args, **kwargs):
 | 
			
		||||
        self.client = PassbookClient(client_id, client_secret)
 | 
			
		||||
        super(FetchUser, self).__init__(*args, **kwargs)
 | 
			
		||||
 | 
			
		||||
    def handle(self, request, helper):
 | 
			
		||||
        access_token = helper.fetch_state('data')['access_token']
 | 
			
		||||
 | 
			
		||||
        user = self.client.get_user(access_token)
 | 
			
		||||
 | 
			
		||||
        # A user hasn't set their name in their Passbook profile so it isn't
 | 
			
		||||
        # populated in the response
 | 
			
		||||
        if not user.get('name'):
 | 
			
		||||
            user['name'] = _get_name_from_email(user['email'])
 | 
			
		||||
 | 
			
		||||
        helper.bind_state('user', user)
 | 
			
		||||
 | 
			
		||||
        return helper.next_step()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ConfirmEmailForm(forms.Form):
 | 
			
		||||
    email = forms.EmailField(label='Email')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ConfirmEmail(AuthView):
 | 
			
		||||
    def handle(self, request, helper):
 | 
			
		||||
        user = helper.fetch_state('user')
 | 
			
		||||
 | 
			
		||||
        # TODO(dcramer): this isnt ideal, but our current flow doesnt really
 | 
			
		||||
        # support this behavior;
 | 
			
		||||
        try:
 | 
			
		||||
            auth_identity = AuthIdentity.objects.select_related('user').get(
 | 
			
		||||
                auth_provider=helper.auth_provider,
 | 
			
		||||
                ident=user['id'],
 | 
			
		||||
            )
 | 
			
		||||
        except AuthIdentity.DoesNotExist:
 | 
			
		||||
            pass
 | 
			
		||||
        else:
 | 
			
		||||
            user['email'] = auth_identity.user.email
 | 
			
		||||
 | 
			
		||||
        if user.get('email'):
 | 
			
		||||
            return helper.next_step()
 | 
			
		||||
 | 
			
		||||
        form = ConfirmEmailForm(request.POST or None)
 | 
			
		||||
        if form.is_valid():
 | 
			
		||||
            user['email'] = form.cleaned_data['email']
 | 
			
		||||
            helper.bind_state('user', user)
 | 
			
		||||
            return helper.next_step()
 | 
			
		||||
 | 
			
		||||
        return self.respond('sentry_auth_passbook/enter-email.html', {
 | 
			
		||||
            'form': form,
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
class PassbookConfigureView(ConfigureView):
 | 
			
		||||
    def dispatch(self, request, organization, auth_provider):
 | 
			
		||||
        return self.render('sentry_auth_passbook/configure.html')
 | 
			
		||||
@ -1,12 +0,0 @@
 | 
			
		||||
[wheel]
 | 
			
		||||
universal = 1
 | 
			
		||||
 | 
			
		||||
[pytest]
 | 
			
		||||
python_files = test*.py
 | 
			
		||||
addopts = --tb=native -p no:doctest
 | 
			
		||||
norecursedirs = bin dist docs htmlcov script hooks node_modules .* {args}
 | 
			
		||||
 | 
			
		||||
[flake8]
 | 
			
		||||
ignore = F999,E501,E128,E124,E402,W503,E731,C901
 | 
			
		||||
max-line-length = 100
 | 
			
		||||
exclude = .tox,.git,*/migrations/*,node_modules/*,docs/*
 | 
			
		||||
@ -1,45 +0,0 @@
 | 
			
		||||
#!/usr/bin/env python
 | 
			
		||||
"""
 | 
			
		||||
sentry-auth-passbook
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
:copyright: (c) 2016 Functional Software, Inc
 | 
			
		||||
"""
 | 
			
		||||
from setuptools import find_packages, setup
 | 
			
		||||
 | 
			
		||||
install_requires = [
 | 
			
		||||
    'sentry>=7.0.0',
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
tests_require = [
 | 
			
		||||
    'mock',
 | 
			
		||||
    'flake8>=2.0,<2.1',
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
setup(
 | 
			
		||||
    name='sentry-auth-passbook',
 | 
			
		||||
    version='0.1.33-beta',
 | 
			
		||||
    author='BeryJu.org',
 | 
			
		||||
    author_email='support@beryju.org',
 | 
			
		||||
    url='https://passbook.beryju.org',
 | 
			
		||||
    description='passbook authentication provider for Sentry',
 | 
			
		||||
    long_description=__doc__,
 | 
			
		||||
    license='MIT',
 | 
			
		||||
    packages=find_packages(exclude=['tests']),
 | 
			
		||||
    zip_safe=False,
 | 
			
		||||
    install_requires=install_requires,
 | 
			
		||||
    tests_require=tests_require,
 | 
			
		||||
    extras_require={'tests': tests_require},
 | 
			
		||||
    include_package_data=True,
 | 
			
		||||
    entry_points={
 | 
			
		||||
        'sentry.apps': [
 | 
			
		||||
            'auth_passbook = sentry_auth_passbook',
 | 
			
		||||
        ],
 | 
			
		||||
    },
 | 
			
		||||
    classifiers=[
 | 
			
		||||
        'Intended Audience :: Developers',
 | 
			
		||||
        'Intended Audience :: System Administrators',
 | 
			
		||||
        'Operating System :: OS Independent',
 | 
			
		||||
        'Topic :: Software Development'
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
@ -1,6 +0,0 @@
 | 
			
		||||
from sentry.testutils import TestCase
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class GitHubOAuth2ProviderTest(TestCase):
 | 
			
		||||
    def test_simple(self):
 | 
			
		||||
        pass
 | 
			
		||||
@ -1,17 +0,0 @@
 | 
			
		||||
from __future__ import absolute_import, print_function
 | 
			
		||||
 | 
			
		||||
import pytest
 | 
			
		||||
from sentry_auth_sentry.views import _get_name_from_email
 | 
			
		||||
 | 
			
		||||
expected_data = [
 | 
			
		||||
    ('john.smith@example.com', 'John Smith'),
 | 
			
		||||
    ('john@example.com', 'John'),
 | 
			
		||||
    ('XYZ-234=3523@example.com', 'Xyz-234=3523'),
 | 
			
		||||
    ('XYZ.1111@example.com', 'Xyz 1111'),
 | 
			
		||||
    ('JOHN@example.com', 'John'),
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.parametrize("email,expected_name", expected_data)
 | 
			
		||||
def test_get_name_from_email(email, expected_name):
 | 
			
		||||
    assert _get_name_from_email(email) == expected_name
 | 
			
		||||
							
								
								
									
										253
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
								
							
							
						
						@ -1,253 +0,0 @@
 | 
			
		||||
passbook (0.1.33) stable; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * bump version: 0.1.31-beta -> 0.1.32-beta
 | 
			
		||||
  * fix EntityID being None in SAML Metadata
 | 
			
		||||
  * fix SAML Request not being parsed all the time
 | 
			
		||||
  * add Rancher SAML processor
 | 
			
		||||
  * remove unused import
 | 
			
		||||
  * fix broken icon for helm chart
 | 
			
		||||
  * switch to custom CI base image with dependencies installed
 | 
			
		||||
  * remove included CI file
 | 
			
		||||
 | 
			
		||||
  -- Jens Langhammer <jens.langhammer@beryju.org>  Thu, 18 Apr 2019 08:23:55 +0000
 | 
			
		||||
 | 
			
		||||
passbook (0.1.32) stable; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * bump version: 0.1.30-beta -> 0.1.31-beta
 | 
			
		||||
  * automatically add response_type if not given in OAuth Request
 | 
			
		||||
 | 
			
		||||
 -- Jens Langhammer <jens.langhammer@beryju.org>  Wed, 17 Apr 2019 12:25:58 +0000
 | 
			
		||||
 | 
			
		||||
passbook (0.1.31) stable; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * bump version: 0.1.29-beta -> 0.1.30-beta
 | 
			
		||||
  * allow setting authentication_header to empty string (disabling the header)
 | 
			
		||||
  * use global urllib Pools
 | 
			
		||||
  * try to fix app_gw being null
 | 
			
		||||
  * only enable sentry when not DEBUG
 | 
			
		||||
  * move logging to separate thread
 | 
			
		||||
  * move actual proxying logic to separate class
 | 
			
		||||
  * remove logging to increase speed, add more caching to policy and rewriter
 | 
			
		||||
 | 
			
		||||
 -- Jens Langhammer <jens.langhammer@beryju.org>  Sat, 13 Apr 2019 15:56:55 +0000
 | 
			
		||||
 | 
			
		||||
passbook (0.1.30) stable; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * bump version: 0.1.28-beta -> 0.1.29-beta
 | 
			
		||||
  * don't use context manager in web command
 | 
			
		||||
 | 
			
		||||
 -- Jens Langhammer <jens.langhammer@beryju.org>  Thu, 11 Apr 2019 12:21:58 +0000
 | 
			
		||||
 | 
			
		||||
passbook (0.1.29) stable; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * bump version: 0.1.27-beta -> 0.1.28-beta
 | 
			
		||||
  * Add libpq-dev dependency so psycopg2 build works
 | 
			
		||||
  * switch to whitenoise for static files
 | 
			
		||||
  * replace cherrypy with daphne
 | 
			
		||||
  * Run collectstatic before coverage, use autoreload on celery worker
 | 
			
		||||
 | 
			
		||||
 -- Jens Langhammer <jens.langhammer@beryju.org>  Thu, 11 Apr 2019 12:00:27 +0000
 | 
			
		||||
 | 
			
		||||
passbook (0.1.28) stable; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * bump version: 0.1.26-beta -> 0.1.27-beta
 | 
			
		||||
  * fix allauth client's formatting
 | 
			
		||||
  * switch from raven to sentry_sdk
 | 
			
		||||
  * add ability to have non-expiring nonces, clean up expired nonces
 | 
			
		||||
  * fully remove raven and switch WSGI and logging to sentry_sdk
 | 
			
		||||
  * fix failing CI
 | 
			
		||||
  * trigger autoreload from config files
 | 
			
		||||
  * Choose upstream more cleverly
 | 
			
		||||
  * Move code from django-revproxy to app_gw to fix cookie bug
 | 
			
		||||
  * Implement websocket proxy
 | 
			
		||||
  * switch kubernetes deployment to daphne server
 | 
			
		||||
  * set default log level to warn, fix clean_nonces not working
 | 
			
		||||
 | 
			
		||||
 -- Jens Langhammer <jens.langhammer@beryju.org>  Thu, 11 Apr 2019 08:46:44 +0000
 | 
			
		||||
 | 
			
		||||
passbook (0.1.27) stable; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * bump version: 0.1.25-beta -> 0.1.26-beta
 | 
			
		||||
  * fix broken app_gw
 | 
			
		||||
 | 
			
		||||
 -- Jens Langhammer <jens.langhammer@beryju.org>  Fri, 22 Mar 2019 13:50:31 +0000
 | 
			
		||||
 | 
			
		||||
passbook (0.1.26) stable; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * bump version: 0.1.24-beta -> 0.1.25-beta
 | 
			
		||||
  * always parse url instead of once
 | 
			
		||||
  * validate upstream in form
 | 
			
		||||
  * add custom template views
 | 
			
		||||
 | 
			
		||||
 -- Jens Langhammer <jens.langhammer@beryju.org>  Fri, 22 Mar 2019 11:47:08 +0000
 | 
			
		||||
 | 
			
		||||
passbook (0.1.25) stable; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * initial implementation of reverse proxy, using django-revproxy from within a middleware
 | 
			
		||||
  * fix TypeError: can only concatenate list (not "str") to list
 | 
			
		||||
  * bump version: 0.1.23-beta -> 0.1.24-beta
 | 
			
		||||
  * add redis dependency back in for caching
 | 
			
		||||
  * utilise cache in PolicyEngine
 | 
			
		||||
  * explicitly use redis db
 | 
			
		||||
  * invalidate cache when policy is saved
 | 
			
		||||
  * add redis as service in CI for unittests
 | 
			
		||||
  * add timeout field to policy to prevent stuck policies
 | 
			
		||||
  * Don't use LoginRequired for PermissionDenied View
 | 
			
		||||
  * Check for policies in app_gw
 | 
			
		||||
  * Better handle policy timeouts
 | 
			
		||||
  * cleanup post-migration mess
 | 
			
		||||
  * prevent ZeroDivisionError
 | 
			
		||||
  * Redirect to login on reverse proxy
 | 
			
		||||
  * cleanup property_mapping list
 | 
			
		||||
  * add compiled regex to RewriteRule
 | 
			
		||||
  * implement actual Rewriting logic
 | 
			
		||||
  * Invalidate cache when ApplicationGateway instance is saved
 | 
			
		||||
  * validate server_name in form
 | 
			
		||||
 | 
			
		||||
 -- Jens Langhammer <jens.langhammer@beryju.org>  Thu, 21 Mar 2019 15:47:58 +0000
 | 
			
		||||
 | 
			
		||||
passbook (0.1.24) stable; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * bump version: 0.1.22-beta -> 0.1.23-beta
 | 
			
		||||
  * add modal for OAuth Providers showing the URLs
 | 
			
		||||
  * remove user field from form. Closes #32
 | 
			
		||||
 | 
			
		||||
 -- Jens Langhammer <jens.langhammer@beryju.org>  Wed, 20 Mar 2019 21:59:21 +0000
 | 
			
		||||
 | 
			
		||||
passbook (0.1.23) stable; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * add support for OpenID-Connect Discovery
 | 
			
		||||
 | 
			
		||||
 -- Jens Langhammer <jens.langhammer@beryju.org>  Thu, 18 Mar 2019 20:19:27 +0000
 | 
			
		||||
 | 
			
		||||
passbook (0.1.22) stable; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * bump version: 0.1.20-beta -> 0.1.21-beta
 | 
			
		||||
  * fix missing debug template
 | 
			
		||||
  * move icons to single folder, cleanup
 | 
			
		||||
  * fix layout when on mobile viewport and scrolling
 | 
			
		||||
  * fix delete form not working
 | 
			
		||||
  * point to correct icons
 | 
			
		||||
  * add Azure AD Source
 | 
			
		||||
  * Fix OAuth Client's disconnect view having invalid URL names
 | 
			
		||||
 | 
			
		||||
 -- Jens Langhammer <jens.langhammer@beryju.org>  Thu, 14 Mar 2019 20:19:27 +0000
 | 
			
		||||
 | 
			
		||||
passbook (0.1.21) stable; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * bump version: 0.1.19-beta -> 0.1.20-beta
 | 
			
		||||
  * add request debug view
 | 
			
		||||
  * detect HTTPS from reverse proxy
 | 
			
		||||
 | 
			
		||||
 -- Jens Langhammer <jens.langhammer@beryju.org>  Thu, 14 Mar 2019 17:01:49 +0000
 | 
			
		||||
 | 
			
		||||
passbook (0.1.20) stable; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * bump version: 0.1.18-beta -> 0.1.19-beta
 | 
			
		||||
  * fix GitHub Pretend again
 | 
			
		||||
  * add user settings for Sources
 | 
			
		||||
 | 
			
		||||
 -- Jens Langhammer <jens.langhammer@beryju.org>  Wed, 13 Mar 2019 15:49:44 +0000
 | 
			
		||||
 | 
			
		||||
passbook (0.1.18) stable; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * bump version: 0.1.16-beta -> 0.1.17-beta
 | 
			
		||||
  * fix Server Error when downloading metadata
 | 
			
		||||
  * add sentry client
 | 
			
		||||
  * fix included yaml file
 | 
			
		||||
  * adjust versions for client packages, auto build client-packages
 | 
			
		||||
  * bump version: 0.1.17-beta -> 0.1.18-beta
 | 
			
		||||
  * fix API Call for sentry-client, add missing template
 | 
			
		||||
  * fix GitHub Pretend throwing a 500 error
 | 
			
		||||
 | 
			
		||||
 -- Jens Langhammer <jens.langhammer@beryju.org>  Wed, 13 Mar 2019 14:14:10 +0000
 | 
			
		||||
 | 
			
		||||
passbook (0.1.17) stable; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * bump version: 0.1.15-beta -> 0.1.16-beta
 | 
			
		||||
  * remove Application.user_is_authorized
 | 
			
		||||
  * don't use celery heartbeat, use TCP keepalive instead
 | 
			
		||||
  * switch to vertical navigation
 | 
			
		||||
 | 
			
		||||
 -- Jens Langhammer <jens.langhammer@beryju.org>  Tue, 12 Mar 2019 14:54:27 +0000
 | 
			
		||||
 | 
			
		||||
passbook (0.1.16) stable; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * Replace redis with RabbitMQ
 | 
			
		||||
  * updated debian package to suggest RabbitMQ
 | 
			
		||||
  * update helm chart to require RabbitMQ
 | 
			
		||||
  * fix invalid default config in debian package
 | 
			
		||||
 | 
			
		||||
 -- Jens Langhammer <jens.langhammer@beryju.org>  Mon, 11 Mar 2019 10:28:36 +0000
 | 
			
		||||
 | 
			
		||||
passbook (0.1.14) stable; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * bump version: 0.1.11-beta -> 0.1.12-beta
 | 
			
		||||
  * Fix DoesNotExist error when running PolicyEngine against None user
 | 
			
		||||
  * allow custom email server for helm installs
 | 
			
		||||
  * fix UserChangePasswordView not requiring Login
 | 
			
		||||
 | 
			
		||||
 -- Jens Langhammer <jens.langhammer@beryju.org>  Mon, 11 Mar 2019 10:28:36 +0000
 | 
			
		||||
 | 
			
		||||
passbook (0.1.12) stable; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * bump version: 0.1.10-beta -> 0.1.11-beta
 | 
			
		||||
  * rewrite PasswordFactor to use backends setting instead of trying all backends
 | 
			
		||||
  * install updated helm release from local folder
 | 
			
		||||
  * disable automatic k8s deployment for now
 | 
			
		||||
  * fix OAuth Authorization View not requiring authentication
 | 
			
		||||
 | 
			
		||||
 -- Jens Langhammer <jens.langhammer@beryju.org>  Mon, 11 Mar 2019 08:50:29 +0000
 | 
			
		||||
 | 
			
		||||
passbook (0.1.11) stable; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * add group administration
 | 
			
		||||
  * bump version: 0.1.9-beta -> 0.1.10-beta
 | 
			
		||||
  * fix helm labels being on deployments and not pods
 | 
			
		||||
  * automatically deploy after release
 | 
			
		||||
  * use Django's Admin FilteredSelectMultiple for Group Membership
 | 
			
		||||
  * always use FilteredSelectMultiple for many-to-many fields
 | 
			
		||||
  * Add Group Member policy
 | 
			
		||||
  * add LDAP Group Membership Policy
 | 
			
		||||
 | 
			
		||||
 -- Jens Langhammer <jens.langhammer@beryju.org>  Sun, 10 Mar 2019 18:55:31 +0000
 | 
			
		||||
 | 
			
		||||
passbook (0.1.10) stable; urgency=high
 | 
			
		||||
 | 
			
		||||
  * bump version: 0.1.7-beta -> 0.1.8-beta
 | 
			
		||||
  * consistently using PolicyEngine
 | 
			
		||||
  * add more Verbosity to PolicyEngine, rewrite SAML Authorisation check
 | 
			
		||||
  * slightly refactor Factor View, add more unittests
 | 
			
		||||
  * add impersonation middleware, add to templates
 | 
			
		||||
  * bump version: 0.1.8-beta -> 0.1.9-beta
 | 
			
		||||
  * fix k8s service routing http traffic to workers
 | 
			
		||||
  * Fix button on policy test page
 | 
			
		||||
  * better show loading state when testing a policy
 | 
			
		||||
 | 
			
		||||
 -- Jens Langhammer <jens.langhammer@beryju.org>  Sun, 10 Mar 2019 14:52:40 +0000
 | 
			
		||||
 | 
			
		||||
passbook (0.1.7) stable; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * bump version: 0.1.3-beta -> 0.1.4-beta
 | 
			
		||||
  * implicitly add kubernetes-healthcheck-host in helm configmap
 | 
			
		||||
  * fix debian build (again)
 | 
			
		||||
  * add PropertyMapping Model, add Subclass for SAML, test with AWS
 | 
			
		||||
  * add custom DynamicArrayField to better handle arrays
 | 
			
		||||
  * format data before inserting it
 | 
			
		||||
  * bump version: 0.1.4-beta -> 0.1.5-beta
 | 
			
		||||
  * fix static files missing for debian package
 | 
			
		||||
  * fix password not getting set on user import
 | 
			
		||||
  * remove audit's login attempt
 | 
			
		||||
  * add passing property to PolicyEngine
 | 
			
		||||
  * fix captcha factor not loading keys from Factor class
 | 
			
		||||
  * bump version: 0.1.5-beta -> 0.1.6-beta
 | 
			
		||||
  * fix MATCH_EXACT not working as intended
 | 
			
		||||
  * Improve access control for saml
 | 
			
		||||
 | 
			
		||||
 -- Jens Langhammer <jens.langhammer@beryju.org>  Fri, 08 Mar 2019 20:37:05 +0000
 | 
			
		||||
 | 
			
		||||
passbook (0.1.4) stable; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * initial debian package release
 | 
			
		||||
 | 
			
		||||
 -- Jens Langhammer <jens.langhammer@beryju.org>  Wed, 06 Mar 2019 18:22:41 +0000
 | 
			
		||||
							
								
								
									
										1
									
								
								debian/compat
									
									
									
									
										vendored
									
									
								
							
							
						
						@ -1 +0,0 @@
 | 
			
		||||
10
 | 
			
		||||
							
								
								
									
										20
									
								
								debian/config
									
									
									
									
										vendored
									
									
								
							
							
						
						@ -1,20 +0,0 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
# config maintainer script for passbook
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
# source debconf stuff
 | 
			
		||||
. /usr/share/debconf/confmodule
 | 
			
		||||
 | 
			
		||||
dbc_first_version=1.0.0
 | 
			
		||||
dbc_dbuser=passbook
 | 
			
		||||
dbc_dbname=passbook
 | 
			
		||||
 | 
			
		||||
# source dbconfig-common shell library, and call the hook function
 | 
			
		||||
if [ -f /usr/share/dbconfig-common/dpkg/config.pgsql ]; then
 | 
			
		||||
    . /usr/share/dbconfig-common/dpkg/config.pgsql
 | 
			
		||||
    dbc_go passbook "$@"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
#DEBHELPER#
 | 
			
		||||
 | 
			
		||||
exit 0
 | 
			
		||||
							
								
								
									
										14
									
								
								debian/control
									
									
									
									
										vendored
									
									
								
							
							
						
						@ -1,14 +0,0 @@
 | 
			
		||||
Source: passbook
 | 
			
		||||
Section: admin
 | 
			
		||||
Priority: optional
 | 
			
		||||
Maintainer: BeryJu.org <support@beryju.org>
 | 
			
		||||
Uploaders: Jens Langhammer <jens@beryju.org>, BeryJu.org <support@beryju.org>
 | 
			
		||||
Build-Depends: debhelper (>= 10), dh-systemd (>= 1.5), dh-exec, wget, dh-exec, python3 (>= 3.5) | python3.6 | python3.7, libpq-dev
 | 
			
		||||
Standards-Version: 3.9.6
 | 
			
		||||
 | 
			
		||||
Package: passbook
 | 
			
		||||
Architecture: all
 | 
			
		||||
Recommends: mysql-server, rabbitmq-server, redis-server
 | 
			
		||||
Pre-Depends: adduser, libldap2-dev, libsasl2-dev
 | 
			
		||||
Depends: python3 (>= 3.5) | python3.6 | python3.7, python3-pip, dbconfig-pgsql | dbconfig-no-thanks, ${misc:Depends}
 | 
			
		||||
Description: Authentication Provider/Proxy supporting protocols like SAML, OAuth, LDAP and more.
 | 
			
		||||
							
								
								
									
										22
									
								
								debian/copyright
									
									
									
									
										vendored
									
									
								
							
							
						
						@ -1,22 +0,0 @@
 | 
			
		||||
MIT License
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2019 BeryJu.org
 | 
			
		||||
 | 
			
		||||
Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
in the Software without restriction, including without limitation the rights
 | 
			
		||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
furnished to do so, subject to the following conditions:
 | 
			
		||||
 | 
			
		||||
The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
copies or substantial portions of the Software.
 | 
			
		||||
 | 
			
		||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
SOFTWARE.
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										4
									
								
								debian/dirs
									
									
									
									
										vendored
									
									
								
							
							
						
						@ -1,4 +0,0 @@
 | 
			
		||||
etc/passbook/
 | 
			
		||||
etc/passbook/config.d/
 | 
			
		||||
var/log/passbook/
 | 
			
		||||
usr/share/passbook/
 | 
			
		||||
							
								
								
									
										81
									
								
								debian/etc/passbook/config.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						@ -1,81 +0,0 @@
 | 
			
		||||
http:
 | 
			
		||||
    host: 0.0.0.0
 | 
			
		||||
    port: 8000
 | 
			
		||||
secret_key_file: /etc/passbook/secret_key
 | 
			
		||||
log:
 | 
			
		||||
    level:
 | 
			
		||||
        console: INFO
 | 
			
		||||
        file: DEBUG
 | 
			
		||||
    file: /var/log/passbook/passbook.log
 | 
			
		||||
debug: false
 | 
			
		||||
secure_proxy_header:
 | 
			
		||||
  HTTP_X_FORWARDED_PROTO: https
 | 
			
		||||
rabbitmq: guest:guest@localhost/passbook
 | 
			
		||||
redis: localhost/0
 | 
			
		||||
 | 
			
		||||
# Error reporting, sends stacktrace to sentry.services.beryju.org
 | 
			
		||||
error_report_enabled: true
 | 
			
		||||
 | 
			
		||||
primary_domain: passbook.local
 | 
			
		||||
 | 
			
		||||
passbook:
 | 
			
		||||
  sign_up:
 | 
			
		||||
    # Enables signup, created users are stored in internal Database and created in LDAP if ldap.create_users is true
 | 
			
		||||
    enabled: true
 | 
			
		||||
  password_reset:
 | 
			
		||||
    # Enable password reset, passwords are reset in internal Database and in LDAP if ldap.reset_password is true
 | 
			
		||||
    enabled: true
 | 
			
		||||
    # Verification the user has to provide in order to be able to reset passwords. Can be any combination of `email`, `2fa`, `security_questions`
 | 
			
		||||
    verification:
 | 
			
		||||
      - email
 | 
			
		||||
  # Text used in title, on login page and multiple other places
 | 
			
		||||
  branding: passbook
 | 
			
		||||
  login:
 | 
			
		||||
    # Override URL used for logo
 | 
			
		||||
    logo_url: null
 | 
			
		||||
    # Override URL used for Background on Login page
 | 
			
		||||
    bg_url: null
 | 
			
		||||
    # Optionally add a subtext, placed below logo on the login page
 | 
			
		||||
    subtext: null
 | 
			
		||||
  footer:
 | 
			
		||||
    links:
 | 
			
		||||
      # Optionally add links to the footer on the login page
 | 
			
		||||
      #  - name: test
 | 
			
		||||
      #    href: https://test
 | 
			
		||||
  # Specify which fields can be used to authenticate. Can be any combination of `username` and `email`
 | 
			
		||||
  uid_fields:
 | 
			
		||||
    - username
 | 
			
		||||
    - email
 | 
			
		||||
  session:
 | 
			
		||||
    remember_age: 2592000 # 60 * 60 * 24 * 30, one month
 | 
			
		||||
# Provider-specific settings
 | 
			
		||||
ldap:
 | 
			
		||||
  # Which field from `uid_fields` maps to which LDAP Attribute
 | 
			
		||||
  login_field_map:
 | 
			
		||||
    username: sAMAccountName
 | 
			
		||||
    email: mail # or userPrincipalName
 | 
			
		||||
  user_attribute_map:
 | 
			
		||||
    active_directory:
 | 
			
		||||
      username: "%(sAMAccountName)s"
 | 
			
		||||
      email: "%(mail)s"
 | 
			
		||||
      name: "%(displayName)"
 | 
			
		||||
oauth_client:
 | 
			
		||||
  # List of python packages with sources types to load.
 | 
			
		||||
  types:
 | 
			
		||||
    - passbook.oauth_client.source_types.discord
 | 
			
		||||
    - passbook.oauth_client.source_types.facebook
 | 
			
		||||
    - passbook.oauth_client.source_types.github
 | 
			
		||||
    - passbook.oauth_client.source_types.google
 | 
			
		||||
    - passbook.oauth_client.source_types.reddit
 | 
			
		||||
    - passbook.oauth_client.source_types.supervisr
 | 
			
		||||
    - passbook.oauth_client.source_types.twitter
 | 
			
		||||
saml_idp:
 | 
			
		||||
  # List of python packages with provider types to load.
 | 
			
		||||
  types:
 | 
			
		||||
    - passbook.saml_idp.processors.generic
 | 
			
		||||
    - passbook.saml_idp.processors.aws
 | 
			
		||||
    - passbook.saml_idp.processors.gitlab
 | 
			
		||||
    - passbook.saml_idp.processors.nextcloud
 | 
			
		||||
    - passbook.saml_idp.processors.salesforce
 | 
			
		||||
    - passbook.saml_idp.processors.shibboleth
 | 
			
		||||
    - passbook.saml_idp.processors.wordpress_orange
 | 
			
		||||
							
								
								
									
										2
									
								
								debian/gbp.conf
									
									
									
									
										vendored
									
									
								
							
							
						
						@ -1,2 +0,0 @@
 | 
			
		||||
[buildpackage]
 | 
			
		||||
export-dir=../build-area
 | 
			
		||||
							
								
								
									
										8
									
								
								debian/install
									
									
									
									
										vendored
									
									
								
							
							
						
						@ -1,8 +0,0 @@
 | 
			
		||||
passbook		/usr/share/passbook/
 | 
			
		||||
static			/usr/share/passbook/
 | 
			
		||||
manage.py		/usr/share/passbook/
 | 
			
		||||
passbook.sh		/usr/share/passbook/
 | 
			
		||||
vendor			/usr/share/passbook/
 | 
			
		||||
 | 
			
		||||
debian/etc/passbook								/etc/
 | 
			
		||||
debian/templates/database.yml					/usr/share/passbook/
 | 
			
		||||
							
								
								
									
										14
									
								
								debian/passbook-worker.service
									
									
									
									
										vendored
									
									
								
							
							
						
						@ -1,14 +0,0 @@
 | 
			
		||||
[Unit]
 | 
			
		||||
Description=passbook - Authentication Provider/Proxy (Background worker)
 | 
			
		||||
After=network.target
 | 
			
		||||
Requires=network.target
 | 
			
		||||
 | 
			
		||||
[Service]
 | 
			
		||||
User=passbook
 | 
			
		||||
Group=passbook
 | 
			
		||||
WorkingDirectory=/usr/share/passbook
 | 
			
		||||
Type=simple
 | 
			
		||||
ExecStart=/usr/share/passbook/passbook.sh worker
 | 
			
		||||
 | 
			
		||||
[Install]
 | 
			
		||||
WantedBy=multi-user.target
 | 
			
		||||
							
								
								
									
										14
									
								
								debian/passbook.service
									
									
									
									
										vendored
									
									
								
							
							
						
						@ -1,14 +0,0 @@
 | 
			
		||||
[Unit]
 | 
			
		||||
Description=passbook - Authentication Provider/Proxy
 | 
			
		||||
After=network.target
 | 
			
		||||
Requires=network.target
 | 
			
		||||
 | 
			
		||||
[Service]
 | 
			
		||||
User=passbook
 | 
			
		||||
Group=passbook
 | 
			
		||||
WorkingDirectory=/usr/share/passbook
 | 
			
		||||
Type=simple
 | 
			
		||||
ExecStart=/usr/share/passbook/passbook.sh web
 | 
			
		||||
 | 
			
		||||
[Install]
 | 
			
		||||
WantedBy=multi-user.target
 | 
			
		||||
							
								
								
									
										36
									
								
								debian/postinst
									
									
									
									
										vendored
									
									
								
							
							
						
						@ -1,36 +0,0 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
. /usr/share/debconf/confmodule
 | 
			
		||||
. /usr/share/dbconfig-common/dpkg/postinst.pgsql
 | 
			
		||||
 | 
			
		||||
# you can set the default database encoding to something else
 | 
			
		||||
dbc_pgsql_createdb_encoding="UTF8"
 | 
			
		||||
dbc_generate_include=template:/etc/passbook/config.d/database.yml
 | 
			
		||||
dbc_generate_include_args="-o template_infile=/usr/share/passbook/database.yml"
 | 
			
		||||
dbc_go passbook "$@"
 | 
			
		||||
 | 
			
		||||
if [ -z "`getent group passbook`" ]; then
 | 
			
		||||
	addgroup --quiet --system passbook
 | 
			
		||||
fi
 | 
			
		||||
if [ -z "`getent passwd passbook`" ]; then
 | 
			
		||||
	echo " * Creating user and group passbook..."
 | 
			
		||||
	adduser --quiet --system --home /usr/share/passbook --shell /bin/false --ingroup passbook --disabled-password --disabled-login --gecos "passbook User" passbook  >> /var/log/passbook/passbook.log 2>&1
 | 
			
		||||
fi
 | 
			
		||||
echo " * Updating binary packages (psycopg2)"
 | 
			
		||||
python3 -m pip install --target=/usr/share/passbook/vendor/ --no-cache-dir --upgrade --force-reinstall psycopg2 >> /var/log/passbook/passbook.log 2>&1
 | 
			
		||||
if [ ! -f '/etc/passbook/secret_key' ]; then
 | 
			
		||||
	echo " * Generating Secret Key"
 | 
			
		||||
	python3 -c 'import random; result = "".join([random.choice("abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)") for i in range(50)]); print(result)' > /etc/passbook/secret_key 2> /dev/null
 | 
			
		||||
fi
 | 
			
		||||
chown -R passbook: /usr/share/passbook/
 | 
			
		||||
chown -R passbook: /etc/passbook/
 | 
			
		||||
chown -R passbook: /var/log/passbook/
 | 
			
		||||
chmod 440 /etc/passbook/secret_key
 | 
			
		||||
echo " * Running Database Migration"
 | 
			
		||||
/usr/share/passbook/passbook.sh migrate
 | 
			
		||||
echo " * A superuser can be created with this command '/usr/share/passbook/passbook.sh createsuperuser'"
 | 
			
		||||
echo " * You should probably also adjust your settings in '/etc/passbook/config.yml'"
 | 
			
		||||
 | 
			
		||||
#DEBHELPER#
 | 
			
		||||
							
								
								
									
										24
									
								
								debian/postrm
									
									
									
									
										vendored
									
									
								
							
							
						
						@ -1,24 +0,0 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
if [ -f /usr/share/debconf/confmodule ]; then
 | 
			
		||||
    . /usr/share/debconf/confmodule
 | 
			
		||||
fi
 | 
			
		||||
if [ -f /usr/share/dbconfig-common/dpkg/postrm.pgsql ]; then
 | 
			
		||||
    . /usr/share/dbconfig-common/dpkg/postrm.pgsql
 | 
			
		||||
    dbc_go passbook "$@"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if [ "$1" = "purge" ]; then
 | 
			
		||||
    if which ucf >/dev/null 2>&1; then
 | 
			
		||||
        ucf --purge /etc/passbook/config.d/database.yml
 | 
			
		||||
        ucfr --purge passbook /etc/passbook/config.d/database.yml
 | 
			
		||||
    fi
 | 
			
		||||
    rm -rf /etc/passbook/
 | 
			
		||||
    rm -rf /usr/share/passbook/
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
#DEBHELPER#
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										10
									
								
								debian/prerm
									
									
									
									
										vendored
									
									
								
							
							
						
						@ -1,10 +0,0 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
. /usr/share/debconf/confmodule
 | 
			
		||||
. /usr/share/dbconfig-common/dpkg/prerm.pgsql
 | 
			
		||||
dbc_go passbook "$@"
 | 
			
		||||
 | 
			
		||||
#DEBHELPER#
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										27
									
								
								debian/rules
									
									
									
									
										vendored
									
									
								
							
							
						
						@ -1,27 +0,0 @@
 | 
			
		||||
#!/usr/bin/make -f
 | 
			
		||||
 | 
			
		||||
# Uncomment this to turn on verbose mode.
 | 
			
		||||
# export DH_VERBOSE=1
 | 
			
		||||
 | 
			
		||||
%:
 | 
			
		||||
	dh $@ --with=systemd
 | 
			
		||||
 | 
			
		||||
build-arch:
 | 
			
		||||
	python3 -m pip install setuptools
 | 
			
		||||
	python3 -m pip install --target=vendor/ -r requirements.txt
 | 
			
		||||
 | 
			
		||||
override_dh_strip:
 | 
			
		||||
	dh_strip --exclude=psycopg2
 | 
			
		||||
 | 
			
		||||
override_dh_shlibdeps:
 | 
			
		||||
	dh_shlibdeps --exclude=psycopg2
 | 
			
		||||
 | 
			
		||||
override_dh_installinit:
 | 
			
		||||
	dh_installinit --name=passbook
 | 
			
		||||
	dh_installinit --name=passbook-worker
 | 
			
		||||
	dh_systemd_enable --name=passbook
 | 
			
		||||
	dh_systemd_enable --name=passbook-worker
 | 
			
		||||
	dh_systemd_start
 | 
			
		||||
 | 
			
		||||
# override_dh_usrlocal to do nothing
 | 
			
		||||
override_dh_usrlocal:
 | 
			
		||||
							
								
								
									
										1
									
								
								debian/source/format
									
									
									
									
										vendored
									
									
								
							
							
						
						@ -1 +0,0 @@
 | 
			
		||||
3.0 (native)
 | 
			
		||||
							
								
								
									
										8
									
								
								debian/templates/database.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						@ -1,8 +0,0 @@
 | 
			
		||||
databases:
 | 
			
		||||
  default:
 | 
			
		||||
    engine: django.db.backends.postgresql
 | 
			
		||||
    name: _DBC_DBNAME_
 | 
			
		||||
    user: _DBC_DBUSER_
 | 
			
		||||
    password: _DBC_DBPASS_
 | 
			
		||||
    host: _DBC_DBSERVER_
 | 
			
		||||
    port: _DBC_DBPORT_
 | 
			
		||||
							
								
								
									
										85
									
								
								docker-compose.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,85 @@
 | 
			
		||||
---
 | 
			
		||||
version: '3.2'
 | 
			
		||||
 | 
			
		||||
services:
 | 
			
		||||
  postgresql:
 | 
			
		||||
    image: postgres
 | 
			
		||||
    volumes:
 | 
			
		||||
      - database:/var/lib/postgresql/data
 | 
			
		||||
    networks:
 | 
			
		||||
      - internal
 | 
			
		||||
    environment:
 | 
			
		||||
      - POSTGRES_PASSWORD=${PG_PASS:-thisisnotagoodpassword}
 | 
			
		||||
      - POSTGRES_USER=passbook
 | 
			
		||||
      - POSTGRES_DB=passbook
 | 
			
		||||
    labels:
 | 
			
		||||
      - traefik.enable=false
 | 
			
		||||
  redis:
 | 
			
		||||
    image: redis
 | 
			
		||||
    networks:
 | 
			
		||||
      - internal
 | 
			
		||||
    labels:
 | 
			
		||||
      - traefik.enable=false
 | 
			
		||||
  server:
 | 
			
		||||
    image: beryju/passbook:${PASSBOOK_TAG:-latest}
 | 
			
		||||
    command:
 | 
			
		||||
      - uwsgi
 | 
			
		||||
      - uwsgi.ini
 | 
			
		||||
    environment:
 | 
			
		||||
      - PASSBOOK_REDIS__HOST=redis
 | 
			
		||||
      - PASSBOOK_ERROR_REPORTING=${PASSBOOK_ERROR_REPORTING:-false}
 | 
			
		||||
      - PASSBOOK_POSTGRESQL__HOST=postgresql
 | 
			
		||||
      - PASSBOOK_POSTGRESQL__PASSWORD=${PG_PASS:-thisisnotagoodpassword}
 | 
			
		||||
    ports:
 | 
			
		||||
      - 8000
 | 
			
		||||
    networks:
 | 
			
		||||
      - internal
 | 
			
		||||
    labels:
 | 
			
		||||
      - traefik.port=8000
 | 
			
		||||
      - traefik.docker.network=internal
 | 
			
		||||
      - traefik.frontend.rule=PathPrefix:/
 | 
			
		||||
  worker:
 | 
			
		||||
    image: beryju/passbook:${PASSBOOK_TAG:-latest}
 | 
			
		||||
    command:
 | 
			
		||||
      - celery
 | 
			
		||||
      - worker
 | 
			
		||||
      - --autoscale=10,3
 | 
			
		||||
      - -E
 | 
			
		||||
      - -B
 | 
			
		||||
      - -A=passbook.root.celery
 | 
			
		||||
      - -s=/tmp/celerybeat-schedule
 | 
			
		||||
    networks:
 | 
			
		||||
      - internal
 | 
			
		||||
    labels:
 | 
			
		||||
      - traefik.enable=false
 | 
			
		||||
    environment:
 | 
			
		||||
      - PASSBOOK_REDIS__HOST=redis
 | 
			
		||||
      - PASSBOOK_ERROR_REPORTING=${PASSBOOK_ERROR_REPORTING:-false}
 | 
			
		||||
      - PASSBOOK_POSTGRESQL__HOST=postgresql
 | 
			
		||||
      - PASSBOOK_POSTGRESQL__PASSWORD=${PG_PASS:-thisisnotagoodpassword}
 | 
			
		||||
  static:
 | 
			
		||||
    image: beryju/passbook-static:latest
 | 
			
		||||
    networks:
 | 
			
		||||
      - internal
 | 
			
		||||
    labels:
 | 
			
		||||
      - traefik.frontend.rule=PathPrefix:/static, /robots.txt
 | 
			
		||||
      - traefik.port=80
 | 
			
		||||
      - traefik.docker.network=internal
 | 
			
		||||
  traefik:
 | 
			
		||||
    image: traefik:1.7
 | 
			
		||||
    command: --api --docker
 | 
			
		||||
    volumes:
 | 
			
		||||
      - /var/run/docker.sock:/var/run/docker.sock:ro
 | 
			
		||||
    ports:
 | 
			
		||||
      - "0.0.0.0:80:80"
 | 
			
		||||
      - "0.0.0.0:443:443"
 | 
			
		||||
      - "0.0.0.0:8080:8080"
 | 
			
		||||
    networks:
 | 
			
		||||
      - internal
 | 
			
		||||
 | 
			
		||||
volumes:
 | 
			
		||||
  database:
 | 
			
		||||
    driver: local
 | 
			
		||||
 | 
			
		||||
networks:
 | 
			
		||||
  internal: {}
 | 
			
		||||
							
								
								
									
										3
									
								
								docker/bootstrap.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						@ -0,0 +1,3 @@
 | 
			
		||||
#!/bin/bash -ex
 | 
			
		||||
/app/wait_for_db.py
 | 
			
		||||
"$@"
 | 
			
		||||
							
								
								
									
										10
									
								
								docker/uwsgi.ini
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,10 @@
 | 
			
		||||
[uwsgi]
 | 
			
		||||
http = 0.0.0.0:8000
 | 
			
		||||
wsgi-file = passbook/root/wsgi.py
 | 
			
		||||
processes = 2
 | 
			
		||||
master = true
 | 
			
		||||
threads = 2
 | 
			
		||||
enable-threads = true
 | 
			
		||||
uid = passbook
 | 
			
		||||
gid = passbook
 | 
			
		||||
disable-logging = True
 | 
			
		||||
							
								
								
									
										41
									
								
								docker/wait_for_db.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						@ -0,0 +1,41 @@
 | 
			
		||||
#!/usr/bin/env python
 | 
			
		||||
"""This file needs to be run from the root of the project to correctly
 | 
			
		||||
import passbook. This is done by the dockerfile."""
 | 
			
		||||
from time import sleep
 | 
			
		||||
 | 
			
		||||
from psycopg2 import OperationalError, connect
 | 
			
		||||
from redis import Redis
 | 
			
		||||
from redis.exceptions import RedisError
 | 
			
		||||
from structlog import get_logger
 | 
			
		||||
 | 
			
		||||
from passbook.lib.config import CONFIG
 | 
			
		||||
 | 
			
		||||
LOGGER = get_logger()
 | 
			
		||||
 | 
			
		||||
while True:
 | 
			
		||||
    try:
 | 
			
		||||
        conn = connect(
 | 
			
		||||
            dbname=CONFIG.y("postgresql.name"),
 | 
			
		||||
            user=CONFIG.y("postgresql.user"),
 | 
			
		||||
            password=CONFIG.y("postgresql.password"),
 | 
			
		||||
            host=CONFIG.y("postgresql.host"),
 | 
			
		||||
        )
 | 
			
		||||
        conn.cursor()
 | 
			
		||||
        break
 | 
			
		||||
    except OperationalError:
 | 
			
		||||
        sleep(1)
 | 
			
		||||
        LOGGER.warning("PostgreSQL Connection failed, retrying...")
 | 
			
		||||
 | 
			
		||||
while True:
 | 
			
		||||
    try:
 | 
			
		||||
        redis = Redis(
 | 
			
		||||
            host=CONFIG.y("redis.host"),
 | 
			
		||||
            port=6379,
 | 
			
		||||
            db=CONFIG.y("redis.message_queue_db"),
 | 
			
		||||
            password=CONFIG.y("redis.password"),
 | 
			
		||||
        )
 | 
			
		||||
        redis.ping()
 | 
			
		||||
        break
 | 
			
		||||
    except RedisError:
 | 
			
		||||
        sleep(1)
 | 
			
		||||
        LOGGER.warning("Redis Connection failed, retrying...")
 | 
			
		||||
							
								
								
									
										3
									
								
								docs/build.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						@ -0,0 +1,3 @@
 | 
			
		||||
#!/bin/bash -x
 | 
			
		||||
pip install -U mkdocs mkdocs-material
 | 
			
		||||
mkdocs gh-deploy
 | 
			
		||||
							
								
								
									
										55
									
								
								docs/expressions/index.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,55 @@
 | 
			
		||||
# Expressions
 | 
			
		||||
 | 
			
		||||
Expressions allow you to write custom Logic using Python code.
 | 
			
		||||
 | 
			
		||||
Expressions are used in different places throughout passbook, and can do different things.
 | 
			
		||||
 | 
			
		||||
!!! info
 | 
			
		||||
    These functions/objects are available wherever expressions are used. For more specific information, see [Expression Policies](../policies/expression.md) and [Property Mappings](../property-mappings/expression.md)
 | 
			
		||||
 | 
			
		||||
## Global objects
 | 
			
		||||
 | 
			
		||||
- `pb_logger`: structlog BoundLogger. ([ref](https://www.structlog.org/en/stable/api.html#structlog.BoundLogger))
 | 
			
		||||
- `requests`: requests Session object. ([ref](https://requests.readthedocs.io/en/master/user/advanced/))
 | 
			
		||||
 | 
			
		||||
## Generally available functions
 | 
			
		||||
 | 
			
		||||
### `regex_match(value: Any, regex: str) -> bool`
 | 
			
		||||
 | 
			
		||||
Check if `value` matches Regular Expression `regex`.
 | 
			
		||||
 | 
			
		||||
Example:
 | 
			
		||||
 | 
			
		||||
```python
 | 
			
		||||
return regex_match(request.user.username, '.*admin.*')
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### `regex_replace(value: Any, regex: str, repl: str) -> str`
 | 
			
		||||
 | 
			
		||||
Replace anything matching `regex` within `value` with `repl` and return it.
 | 
			
		||||
 | 
			
		||||
Example:
 | 
			
		||||
 | 
			
		||||
```python
 | 
			
		||||
user_email_local = regex_replace(request.user.email, '(.+)@.+', '')
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### `pb_is_group_member(user: User, **group_filters) -> bool`
 | 
			
		||||
 | 
			
		||||
Check if `user` is member of a group matching `**group_filters`.
 | 
			
		||||
 | 
			
		||||
Example:
 | 
			
		||||
 | 
			
		||||
```python
 | 
			
		||||
return pb_is_group_member(request.user, name="test_group")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### `pb_user_by(**filters) -> Optional[User]`
 | 
			
		||||
 | 
			
		||||
Fetch a user matching `**filters`. Returns None if no user was found.
 | 
			
		||||
 | 
			
		||||
Example:
 | 
			
		||||
 | 
			
		||||
```python
 | 
			
		||||
other_user = pb_user_by(username="other_user")
 | 
			
		||||
```
 | 
			
		||||
							
								
								
									
										21
									
								
								docs/expressions/reference/user-object.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,21 @@
 | 
			
		||||
# Passbook User Object
 | 
			
		||||
 | 
			
		||||
The User object has the following attributes:
 | 
			
		||||
 | 
			
		||||
 - `username`: User's Username
 | 
			
		||||
 - `email` User's E-Mail
 | 
			
		||||
 - `name` User's Display Name
 | 
			
		||||
 - `is_staff` Boolean field if user is staff
 | 
			
		||||
 - `is_active` Boolean field if user is active
 | 
			
		||||
 - `date_joined` Date User joined/was created
 | 
			
		||||
 - `password_change_date` Date Password was last changed
 | 
			
		||||
 - `attributes` Dynamic Attributes
 | 
			
		||||
 | 
			
		||||
## Examples
 | 
			
		||||
 | 
			
		||||
List all the User's Group Names
 | 
			
		||||
 | 
			
		||||
```python
 | 
			
		||||
for group in user.groups.all():
 | 
			
		||||
    yield group.name
 | 
			
		||||
```
 | 
			
		||||
							
								
								
									
										36
									
								
								docs/flow/examples/login.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,36 @@
 | 
			
		||||
# Login Flow
 | 
			
		||||
 | 
			
		||||
This document describes how a simple authentication flow can be created.
 | 
			
		||||
 | 
			
		||||
This flow is created automatically when passbook is installed.
 | 
			
		||||
 | 
			
		||||
1. Create an **Identification** stage
 | 
			
		||||
 | 
			
		||||
    > Here you can select whichever fields the user can identify themselves with
 | 
			
		||||
    > Select the Template **Default Login**, as this template shows the (optional) Flows
 | 
			
		||||
    > Here you can also link optional enrollment and recovery flows.
 | 
			
		||||
 | 
			
		||||
2. Create a **Password** stage
 | 
			
		||||
 | 
			
		||||
    > Select the Backend you want the password to be checked against. Select "passbook-internal Userdatabase".
 | 
			
		||||
 | 
			
		||||
3. Create a **User Login** stage
 | 
			
		||||
 | 
			
		||||
    > This stage doesn't have any options.
 | 
			
		||||
 | 
			
		||||
4. Create a flow
 | 
			
		||||
 | 
			
		||||
    > Create a flow with the delegation of **Authentication**
 | 
			
		||||
    > Assign a name and a slug. The slug is used in the URL when the flow is executed.
 | 
			
		||||
 | 
			
		||||
5. Bind the stages to the flow
 | 
			
		||||
 | 
			
		||||
    > Bind the **Identification** Stage with an order of 0
 | 
			
		||||
    > Bind the **Password** Stage with an order of 1
 | 
			
		||||
    > Bind the **User Login** Stage with an order of 2
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
!!! notice
 | 
			
		||||
 | 
			
		||||
    This flow can used by any user, authenticated and un-authenticated. This means any authenticated user that visits this flow can login again.
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								docs/flow/examples/login.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 110 KiB  | 
							
								
								
									
										45
									
								
								docs/flow/flows.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,45 @@
 | 
			
		||||
# Flows
 | 
			
		||||
 | 
			
		||||
Flows are a method of describing a sequence of stages. A stage represents a single verification or logic step. They are used to authenticate users, enroll them, and more.
 | 
			
		||||
 | 
			
		||||
Upon Flow execution, a plan is generated, which contains all stages. This means upon execution, all attached policies are evaluated. This behaviour can be altered by enabling the **Re-evaluate Policies** option on the binding.
 | 
			
		||||
 | 
			
		||||
To determine which flow is linked, passbook searches all Flows with the required designation and chooses the first instance the current user has access to.
 | 
			
		||||
 | 
			
		||||
## Permissions
 | 
			
		||||
 | 
			
		||||
Flows can have policies assigned to them, which determines if the current user is allowed to see and use this flow.
 | 
			
		||||
 | 
			
		||||
## Designation
 | 
			
		||||
 | 
			
		||||
Flows are designated for a single Purpose. This designation changes when a Flow is used. The following designations are available:
 | 
			
		||||
 | 
			
		||||
### Authentication
 | 
			
		||||
 | 
			
		||||
This is designates a flow to be used for authentication.
 | 
			
		||||
 | 
			
		||||
The authentication flow should always contain a [**User Login**](stages/user_login.md) stage, which attaches the staged user to the current session.
 | 
			
		||||
 | 
			
		||||
### Invalidation
 | 
			
		||||
 | 
			
		||||
This designates a flow to be used for the invalidation of a session.
 | 
			
		||||
 | 
			
		||||
This stage should always contain a [**User Logout**](stages/user_logout.md) stage, which resets the current session.
 | 
			
		||||
 | 
			
		||||
### Enrollment
 | 
			
		||||
 | 
			
		||||
This designates a flow for enrollment. This flow can contain any amount of Prompt stages, E-Mail verification or Captchas. At the end to create the user, you can use the [**User Write**](stages/user_write.md) stage, which either updates the currently staged user, or if none exists, creates a new one.
 | 
			
		||||
 | 
			
		||||
### Unenrollment
 | 
			
		||||
 | 
			
		||||
This designates a flow for unenrollment. This flow can contain any amount of verification, like [**E-Mail**](stages/email/index.md) or [**Captcha**](stages/captcha/index.md). To finally delete the account, use the [**User Delete**](stages/user_delete.md) stage.
 | 
			
		||||
 | 
			
		||||
### Recovery
 | 
			
		||||
 | 
			
		||||
This designates a flow for recovery. This flow normally contains an [**Identification**](stages/identification/index.md) stage to find the user. Then it can contain any amount of verification, like [**E-Mail**](stages/email/index.md) or [**Captcha**](stages/captcha/index.md).
 | 
			
		||||
Afterwards, use the [**Prompt**](stages/prompt/index.md) stage to ask the user for a new password and use [**User Write**](stages/user_write.md) to update the password.
 | 
			
		||||
 | 
			
		||||
### Change Password
 | 
			
		||||
 | 
			
		||||
This designates a flow for password changing. This flow can contain any amount of verification, like [**E-Mail**](stages/email/index.md) or [**Captcha**](stages/captcha/index.md).
 | 
			
		||||
Afterwards, use the [**Prompt**](stages/prompt/index.md) stage to ask the user for a new password and use [**User Write**](stages/user_write.md) to update the password.
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								docs/flow/stages/captcha/captcha-admin.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 140 KiB  | 
							
								
								
									
										7
									
								
								docs/flow/stages/captcha/index.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,7 @@
 | 
			
		||||
# Captcha stage
 | 
			
		||||
 | 
			
		||||
This stage adds a form of verification using [Google's ReCaptcha](https://www.google.com/recaptcha/intro/v3.html).
 | 
			
		||||
 | 
			
		||||
This stage has two required fields. You need a Public and a Private key, both of which you can acquire at https://www.google.com/recaptcha/admin.
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								docs/flow/stages/dummy/dummy.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.3 MiB  | 
							
								
								
									
										5
									
								
								docs/flow/stages/dummy/index.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,5 @@
 | 
			
		||||
# Dummy stage
 | 
			
		||||
 | 
			
		||||
This stage is used for development, and has no function. It presents the User with a form, that requires a single confirmation.
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								docs/flow/stages/email/email-recovery.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 51 KiB  | 
							
								
								
									
										5
									
								
								docs/flow/stages/email/index.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,5 @@
 | 
			
		||||
# E-Mail
 | 
			
		||||
 | 
			
		||||
This stage can be used for E-Mail verification. passbook's background worker will send an E-Mail using the specified connection details. When an E-Mail can't be delivered, it is automatically periodically retried.
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
							
								
								
									
										25
									
								
								docs/flow/stages/identification/index.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,25 @@
 | 
			
		||||
# Identification
 | 
			
		||||
 | 
			
		||||
This stage provides a ready-to-go form for users to identify themselves.
 | 
			
		||||
 | 
			
		||||
## Options
 | 
			
		||||
 | 
			
		||||
### User Fields
 | 
			
		||||
 | 
			
		||||
Select which fields the user can use to identify themselves. Multiple fields can be specified and separated with a comma.
 | 
			
		||||
Valid choices:
 | 
			
		||||
 | 
			
		||||
- email
 | 
			
		||||
- username
 | 
			
		||||
 | 
			
		||||
### Template
 | 
			
		||||
 | 
			
		||||
This specifies which template is rendered. Currently there are two templates.
 | 
			
		||||
 | 
			
		||||
The `Login` template shows configured Sources below the login form, as well as linking to the defined Enrollment and Recovery flows.
 | 
			
		||||
 | 
			
		||||
The `Recovery` template shows only the form.
 | 
			
		||||
 | 
			
		||||
### Enrollment/Recovery Flow
 | 
			
		||||
 | 
			
		||||
These fields specify if and which flows are linked on the form. The enrollment flow is linked as `Need an account? Sign up.`, and the recovery flow is linked as `Forgot username or password?`.
 | 
			
		||||
							
								
								
									
										7
									
								
								docs/flow/stages/invitation/index.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,7 @@
 | 
			
		||||
# Invitation Stage
 | 
			
		||||
 | 
			
		||||
This stage can be used to invite users. You can use this enroll users with preset values.
 | 
			
		||||
 | 
			
		||||
If the option `Continue Flow without Invitation`, this stage will continue when no invitation token is present.
 | 
			
		||||
 | 
			
		||||
If you want to check if a user has used an invitation within a policy, you can check `request.context.invitation_in_effect`.
 | 
			
		||||
							
								
								
									
										7
									
								
								docs/flow/stages/otp/index.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,7 @@
 | 
			
		||||
# OTP Stage
 | 
			
		||||
 | 
			
		||||
This stage offers a generic Time-based One-time Password authentication step.
 | 
			
		||||
 | 
			
		||||
You can optionally enforce this step, which will force every user without OTP setup to configure it.
 | 
			
		||||
 | 
			
		||||
This stage uses a 6-digit Code with a 30 second time-drift. This is currently not changeable.
 | 
			
		||||
							
								
								
									
										3
									
								
								docs/flow/stages/password/index.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,3 @@
 | 
			
		||||
# Password Stage
 | 
			
		||||
 | 
			
		||||
This is a generic password prompt, which authenticates the currently `pending_user`. This stage allows the selection of the Backend the user is authenticated against.
 | 
			
		||||
							
								
								
									
										42
									
								
								docs/flow/stages/prompt/index.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,42 @@
 | 
			
		||||
# Prompt Stage
 | 
			
		||||
 | 
			
		||||
This stage is used to show the user arbitrary prompts.
 | 
			
		||||
 | 
			
		||||
## Prompt
 | 
			
		||||
 | 
			
		||||
The prompt can be any of the following types:
 | 
			
		||||
 | 
			
		||||
|          |                                                                  |
 | 
			
		||||
|----------|------------------------------------------------------------------|
 | 
			
		||||
| text     | Arbitrary text, no client-side validation is done.               |
 | 
			
		||||
| email    | E-Mail input, requires a valid E-Mail adress                     |
 | 
			
		||||
| password | Password Input                                                   |
 | 
			
		||||
| number   | Number Input, any number is allowed                              |
 | 
			
		||||
| checkbox | Simple Checkbox                                                  |
 | 
			
		||||
| hidden   | Hidden Input field, allows for the pre-setting of default values |
 | 
			
		||||
 | 
			
		||||
A Prompt has the following attributes:
 | 
			
		||||
 | 
			
		||||
### `field_key`
 | 
			
		||||
 | 
			
		||||
HTML name used for the prompt. This key is also used to later retrieve the data in expression policies:
 | 
			
		||||
 | 
			
		||||
```python
 | 
			
		||||
request.context.get('prompt_data').get('<field_key>')
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### `label`
 | 
			
		||||
 | 
			
		||||
Label used to describe the Field. This might not be shown depending on the template selected.
 | 
			
		||||
 | 
			
		||||
### `required`
 | 
			
		||||
 | 
			
		||||
Flag that decides whether or not this field is required.
 | 
			
		||||
 | 
			
		||||
### `placeholder`
 | 
			
		||||
 | 
			
		||||
Field placeholder, shown within the input field. This field is also used by the `hidden` type as the actual value.
 | 
			
		||||
 | 
			
		||||
### `order`
 | 
			
		||||
 | 
			
		||||
Numerical index of the prompt. This applies to all stages this prompt is a part of.
 | 
			
		||||
							
								
								
									
										16
									
								
								docs/flow/stages/prompt/validation.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,16 @@
 | 
			
		||||
# Prompt Validation
 | 
			
		||||
 | 
			
		||||
Further validation of prompts can be done using policies.
 | 
			
		||||
 | 
			
		||||
To validate that two password fields are identical, create the following expression policy:
 | 
			
		||||
 | 
			
		||||
```python
 | 
			
		||||
if request.context.get('prompt_data').get('password') == request.context.get('prompt_data').get('password_repeat'):
 | 
			
		||||
    return True
 | 
			
		||||
 | 
			
		||||
pb_message("Passwords don't match.")
 | 
			
		||||
return False
 | 
			
		||||
```
 | 
			
		||||
This policy expects you two have two password fields with `field_key` set to `password` and `password_repeat`.
 | 
			
		||||
 | 
			
		||||
Afterwards bind this policy to the prompt stage you want to validate.
 | 
			
		||||
							
								
								
									
										8
									
								
								docs/flow/stages/user_delete.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,8 @@
 | 
			
		||||
# User Delete Stage
 | 
			
		||||
 | 
			
		||||
!!! danger
 | 
			
		||||
    This stage deletes the `pending_user` without any confirmation. You have to make sure the user is aware of this.
 | 
			
		||||
 | 
			
		||||
This stage is intended for an unenrollment flow. It deletes the currently pending user.
 | 
			
		||||
 | 
			
		||||
The pending user is also removed from the current session.
 | 
			
		||||
							
								
								
									
										5
									
								
								docs/flow/stages/user_login.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,5 @@
 | 
			
		||||
# User Login Stage
 | 
			
		||||
 | 
			
		||||
This stage attaches a currently pending user to the current session.
 | 
			
		||||
 | 
			
		||||
It can be used after `user_write` during an enrollment flow, or after a `password` stage during an authentication flow.
 | 
			
		||||
							
								
								
									
										3
									
								
								docs/flow/stages/user_logout.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,3 @@
 | 
			
		||||
# User Logout Stage
 | 
			
		||||
 | 
			
		||||
Opposite stage of [User Login Stages](user_login.md). It removes the user from the current session.
 | 
			
		||||
							
								
								
									
										3
									
								
								docs/flow/stages/user_write.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,3 @@
 | 
			
		||||
# User Write Stage
 | 
			
		||||
 | 
			
		||||
This stages writes data from the current context to the current pending user. If no user is pending, a new one is created.
 | 
			
		||||
@ -1,2 +1,2 @@
 | 
			
		||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
 | 
			
		||||
  width="270px" height="20px" viewBox="0 0 270 10" enable-background="new 0 0 270 10" xml:space="preserve"><defs><style>.cls-1{isolation:isolate;}.cls-2{fill:#fff;}</style></defs><g class="cls-1"><path class="cls-2" d="M1.65,11V2.45H2.87V3a2.81,2.81,0,0,1,.47-.45A1.13,1.13,0,0,1,4,2.38,1.11,1.11,0,0,1,5.1,3a1.55,1.55,0,0,1,.16.5,5.61,5.61,0,0,1,0,.81V6.58c0,.45,0,.77,0,1a1.17,1.17,0,0,1-.55.9,1.23,1.23,0,0,1-.7.16,1.35,1.35,0,0,1-.64-.16A1.53,1.53,0,0,1,2.89,8h0v3ZM4.08,4.43a1.21,1.21,0,0,0-.14-.6.51.51,0,0,0-.46-.22A.54.54,0,0,0,3,3.82a.8.8,0,0,0-.17.54V6.73A.68.68,0,0,0,3,7.2a.6.6,0,0,0,.44.18A.53.53,0,0,0,4,7.17a1,1,0,0,0,.12-.5Z"/><path class="cls-2" d="M8.63,8.54V7.91h0a2.24,2.24,0,0,1-.48.52,1.13,1.13,0,0,1-.69.18A1.39,1.39,0,0,1,7,8.54a1.09,1.09,0,0,1-.43-.24,1.32,1.32,0,0,1-.33-.49A2.33,2.33,0,0,1,6.11,7a4.89,4.89,0,0,1,.08-.91,1.51,1.51,0,0,1,.31-.65,1.44,1.44,0,0,1,.59-.38A3.19,3.19,0,0,1,8,4.93h.59V4.33a1,1,0,0,0-.13-.52A.52.52,0,0,0,8,3.61a.71.71,0,0,0-.44.15.78.78,0,0,0-.26.46H6.13A2,2,0,0,1,6.69,2.9a1.73,1.73,0,0,1,.57-.38A2,2,0,0,1,8,2.38a2.18,2.18,0,0,1,.72.12,1.71,1.71,0,0,1,.59.36,2,2,0,0,1,.38.6,2.18,2.18,0,0,1,.14.84V8.54Zm0-2.62-.34,0a1.2,1.2,0,0,0-.67.18.76.76,0,0,0-.29.68.89.89,0,0,0,.17.56A.55.55,0,0,0,8,7.53a.63.63,0,0,0,.49-.2.91.91,0,0,0,.17-.58Z"/><path class="cls-2" d="M13,4.16a.59.59,0,0,0-.2-.47.65.65,0,0,0-.42-.16.59.59,0,0,0-.45.19.66.66,0,0,0-.15.43.8.8,0,0,0,.08.33.85.85,0,0,0,.44.29l.71.29a1.73,1.73,0,0,1,.95.72,2,2,0,0,1,.26,1,1.85,1.85,0,0,1-.52,1.3,1.56,1.56,0,0,1-.58.39,1.88,1.88,0,0,1-2-.32,1.58,1.58,0,0,1-.4-.57,1.81,1.81,0,0,1-.17-.8h1.15a1.11,1.11,0,0,0,.17.47.56.56,0,0,0,.49.22.71.71,0,0,0,.47-.18A.59.59,0,0,0,13,6.8a.69.69,0,0,0-.13-.43,1.08,1.08,0,0,0-.48-.32l-.59-.21a2.08,2.08,0,0,1-.9-.64,1.66,1.66,0,0,1-.33-1,1.89,1.89,0,0,1,.14-.72,1.78,1.78,0,0,1,.4-.57,1.5,1.5,0,0,1,.56-.36,1.82,1.82,0,0,1,.7-.13,1.93,1.93,0,0,1,.69.13,1.6,1.6,0,0,1,.54.38,1.85,1.85,0,0,1,.36.57,1.82,1.82,0,0,1,.13.7Z"/><path class="cls-2" d="M17.2,4.16a.63.63,0,0,0-.2-.47.69.69,0,0,0-.43-.16.55.55,0,0,0-.44.19.62.62,0,0,0-.16.43.68.68,0,0,0,.09.33.81.81,0,0,0,.43.29l.72.29a1.7,1.7,0,0,1,.94.72,2,2,0,0,1,.26,1,1.85,1.85,0,0,1-.52,1.3,1.61,1.61,0,0,1-.57.39,1.81,1.81,0,0,1-.74.15,1.76,1.76,0,0,1-1.24-.47,1.61,1.61,0,0,1-.41-.57,2,2,0,0,1-.17-.8h1.15a1.12,1.12,0,0,0,.18.47.53.53,0,0,0,.48.22.72.72,0,0,0,.48-.18.59.59,0,0,0,.21-.48.69.69,0,0,0-.14-.43,1,1,0,0,0-.48-.32l-.58-.21a2.06,2.06,0,0,1-.91-.64,1.66,1.66,0,0,1-.33-1A1.89,1.89,0,0,1,15,3.44a1.78,1.78,0,0,1,.4-.57,1.58,1.58,0,0,1,.56-.36,1.82,1.82,0,0,1,.7-.13,1.93,1.93,0,0,1,.69.13,1.75,1.75,0,0,1,.55.38,1.85,1.85,0,0,1,.36.57,2,2,0,0,1,.13.7Z"/><path class="cls-2" d="M19.2,8.54V0h1.22V3h0a1.53,1.53,0,0,1,.48-.47,1.39,1.39,0,0,1,.65-.16,1.26,1.26,0,0,1,.69.16,1.35,1.35,0,0,1,.4.39,1.18,1.18,0,0,1,.15.51,7.72,7.72,0,0,1,0,1V6.73a5.56,5.56,0,0,1-.05.8,1.56,1.56,0,0,1-.15.5,1.12,1.12,0,0,1-1.07.58,1.15,1.15,0,0,1-.7-.18A3.79,3.79,0,0,1,20.42,8v.55Zm2.44-4.21a1,1,0,0,0-.13-.51A.5.5,0,0,0,21,3.61a.57.57,0,0,0-.44.18.66.66,0,0,0-.18.48V6.63a.83.83,0,0,0,.17.54.52.52,0,0,0,.45.21.49.49,0,0,0,.45-.22,1.11,1.11,0,0,0,.15-.6Z"/><path class="cls-2" d="M23.76,4.49a4.83,4.83,0,0,1,0-.68A1.55,1.55,0,0,1,24,3.26a1.59,1.59,0,0,1,.62-.64,1.84,1.84,0,0,1,1-.24,1.87,1.87,0,0,1,1,.24,1.59,1.59,0,0,1,.62.64,1.55,1.55,0,0,1,.18.55,4.83,4.83,0,0,1,.05.68v2a4.72,4.72,0,0,1-.05.68,1.55,1.55,0,0,1-.18.55,1.59,1.59,0,0,1-.62.64,1.87,1.87,0,0,1-1,.24,1.84,1.84,0,0,1-1-.24A1.59,1.59,0,0,1,24,7.73a1.55,1.55,0,0,1-.18-.55,4.72,4.72,0,0,1,0-.68ZM25,6.69a.72.72,0,0,0,.17.52.53.53,0,0,0,.43.17A.55.55,0,0,0,26,7.21a.72.72,0,0,0,.16-.52V4.3A.74.74,0,0,0,26,3.78a.55.55,0,0,0-.44-.17.53.53,0,0,0-.43.17A.74.74,0,0,0,25,4.3Z"/><path class="cls-2" d="M28.2,4.49a4.83,4.83,0,0,1,.05-.68,1.55,1.55,0,0,1,.18-.55,1.59,1.59,0,0,1,.62-.64,1.84,1.84,0,0,1,1-.24,1.87,1.87,0,0,1,1,.24,1.59,1.59,0,0,1,.62.64,1.55,1.55,0,0,1,.18.55,4.83,4.83,0,0,1,.05.68v2a4.72,4.72,0,0,1-.05.68,1.55,1.55,0,0,1-.18.55,1.59,1.59,0,0,1-.62.64,1.87,1.87,0,0,1-1,.24,1.84,1.84,0,0,1-1-.24,1.59,1.59,0,0,1-.62-.64,1.55,1.55,0,0,1-.18-.55,4.72,4.72,0,0,1-.05-.68Zm1.22,2.2a.72.72,0,0,0,.17.52.53.53,0,0,0,.43.17.55.55,0,0,0,.44-.17.72.72,0,0,0,.16-.52V4.3a.74.74,0,0,0-.16-.52A.55.55,0,0,0,30,3.61a.53.53,0,0,0-.43.17.74.74,0,0,0-.17.52Z"/><path class="cls-2" d="M32.75,8.54V0H34V5.11h0l1.47-2.66H36.7L35.24,4.93,37,8.54H35.66l-1.1-2.63L34,6.83V8.54Z"/></g></svg>
 | 
			
		||||
  width="120px" height="20px" viewBox="15 0 10 10" enable-background="new 0 0 270 10" xml:space="preserve"><defs><style>.cls-1{isolation:isolate;}.cls-2{fill:#fff;}</style></defs><g class="cls-1"><path class="cls-2" d="M1.65,11V2.45H2.87V3a2.81,2.81,0,0,1,.47-.45A1.13,1.13,0,0,1,4,2.38,1.11,1.11,0,0,1,5.1,3a1.55,1.55,0,0,1,.16.5,5.61,5.61,0,0,1,0,.81V6.58c0,.45,0,.77,0,1a1.17,1.17,0,0,1-.55.9,1.23,1.23,0,0,1-.7.16,1.35,1.35,0,0,1-.64-.16A1.53,1.53,0,0,1,2.89,8h0v3ZM4.08,4.43a1.21,1.21,0,0,0-.14-.6.51.51,0,0,0-.46-.22A.54.54,0,0,0,3,3.82a.8.8,0,0,0-.17.54V6.73A.68.68,0,0,0,3,7.2a.6.6,0,0,0,.44.18A.53.53,0,0,0,4,7.17a1,1,0,0,0,.12-.5Z"/><path class="cls-2" d="M8.63,8.54V7.91h0a2.24,2.24,0,0,1-.48.52,1.13,1.13,0,0,1-.69.18A1.39,1.39,0,0,1,7,8.54a1.09,1.09,0,0,1-.43-.24,1.32,1.32,0,0,1-.33-.49A2.33,2.33,0,0,1,6.11,7a4.89,4.89,0,0,1,.08-.91,1.51,1.51,0,0,1,.31-.65,1.44,1.44,0,0,1,.59-.38A3.19,3.19,0,0,1,8,4.93h.59V4.33a1,1,0,0,0-.13-.52A.52.52,0,0,0,8,3.61a.71.71,0,0,0-.44.15.78.78,0,0,0-.26.46H6.13A2,2,0,0,1,6.69,2.9a1.73,1.73,0,0,1,.57-.38A2,2,0,0,1,8,2.38a2.18,2.18,0,0,1,.72.12,1.71,1.71,0,0,1,.59.36,2,2,0,0,1,.38.6,2.18,2.18,0,0,1,.14.84V8.54Zm0-2.62-.34,0a1.2,1.2,0,0,0-.67.18.76.76,0,0,0-.29.68.89.89,0,0,0,.17.56A.55.55,0,0,0,8,7.53a.63.63,0,0,0,.49-.2.91.91,0,0,0,.17-.58Z"/><path class="cls-2" d="M13,4.16a.59.59,0,0,0-.2-.47.65.65,0,0,0-.42-.16.59.59,0,0,0-.45.19.66.66,0,0,0-.15.43.8.8,0,0,0,.08.33.85.85,0,0,0,.44.29l.71.29a1.73,1.73,0,0,1,.95.72,2,2,0,0,1,.26,1,1.85,1.85,0,0,1-.52,1.3,1.56,1.56,0,0,1-.58.39,1.88,1.88,0,0,1-2-.32,1.58,1.58,0,0,1-.4-.57,1.81,1.81,0,0,1-.17-.8h1.15a1.11,1.11,0,0,0,.17.47.56.56,0,0,0,.49.22.71.71,0,0,0,.47-.18A.59.59,0,0,0,13,6.8a.69.69,0,0,0-.13-.43,1.08,1.08,0,0,0-.48-.32l-.59-.21a2.08,2.08,0,0,1-.9-.64,1.66,1.66,0,0,1-.33-1,1.89,1.89,0,0,1,.14-.72,1.78,1.78,0,0,1,.4-.57,1.5,1.5,0,0,1,.56-.36,1.82,1.82,0,0,1,.7-.13,1.93,1.93,0,0,1,.69.13,1.6,1.6,0,0,1,.54.38,1.85,1.85,0,0,1,.36.57,1.82,1.82,0,0,1,.13.7Z"/><path class="cls-2" d="M17.2,4.16a.63.63,0,0,0-.2-.47.69.69,0,0,0-.43-.16.55.55,0,0,0-.44.19.62.62,0,0,0-.16.43.68.68,0,0,0,.09.33.81.81,0,0,0,.43.29l.72.29a1.7,1.7,0,0,1,.94.72,2,2,0,0,1,.26,1,1.85,1.85,0,0,1-.52,1.3,1.61,1.61,0,0,1-.57.39,1.81,1.81,0,0,1-.74.15,1.76,1.76,0,0,1-1.24-.47,1.61,1.61,0,0,1-.41-.57,2,2,0,0,1-.17-.8h1.15a1.12,1.12,0,0,0,.18.47.53.53,0,0,0,.48.22.72.72,0,0,0,.48-.18.59.59,0,0,0,.21-.48.69.69,0,0,0-.14-.43,1,1,0,0,0-.48-.32l-.58-.21a2.06,2.06,0,0,1-.91-.64,1.66,1.66,0,0,1-.33-1A1.89,1.89,0,0,1,15,3.44a1.78,1.78,0,0,1,.4-.57,1.58,1.58,0,0,1,.56-.36,1.82,1.82,0,0,1,.7-.13,1.93,1.93,0,0,1,.69.13,1.75,1.75,0,0,1,.55.38,1.85,1.85,0,0,1,.36.57,2,2,0,0,1,.13.7Z"/><path class="cls-2" d="M19.2,8.54V0h1.22V3h0a1.53,1.53,0,0,1,.48-.47,1.39,1.39,0,0,1,.65-.16,1.26,1.26,0,0,1,.69.16,1.35,1.35,0,0,1,.4.39,1.18,1.18,0,0,1,.15.51,7.72,7.72,0,0,1,0,1V6.73a5.56,5.56,0,0,1-.05.8,1.56,1.56,0,0,1-.15.5,1.12,1.12,0,0,1-1.07.58,1.15,1.15,0,0,1-.7-.18A3.79,3.79,0,0,1,20.42,8v.55Zm2.44-4.21a1,1,0,0,0-.13-.51A.5.5,0,0,0,21,3.61a.57.57,0,0,0-.44.18.66.66,0,0,0-.18.48V6.63a.83.83,0,0,0,.17.54.52.52,0,0,0,.45.21.49.49,0,0,0,.45-.22,1.11,1.11,0,0,0,.15-.6Z"/><path class="cls-2" d="M23.76,4.49a4.83,4.83,0,0,1,0-.68A1.55,1.55,0,0,1,24,3.26a1.59,1.59,0,0,1,.62-.64,1.84,1.84,0,0,1,1-.24,1.87,1.87,0,0,1,1,.24,1.59,1.59,0,0,1,.62.64,1.55,1.55,0,0,1,.18.55,4.83,4.83,0,0,1,.05.68v2a4.72,4.72,0,0,1-.05.68,1.55,1.55,0,0,1-.18.55,1.59,1.59,0,0,1-.62.64,1.87,1.87,0,0,1-1,.24,1.84,1.84,0,0,1-1-.24A1.59,1.59,0,0,1,24,7.73a1.55,1.55,0,0,1-.18-.55,4.72,4.72,0,0,1,0-.68ZM25,6.69a.72.72,0,0,0,.17.52.53.53,0,0,0,.43.17A.55.55,0,0,0,26,7.21a.72.72,0,0,0,.16-.52V4.3A.74.74,0,0,0,26,3.78a.55.55,0,0,0-.44-.17.53.53,0,0,0-.43.17A.74.74,0,0,0,25,4.3Z"/><path class="cls-2" d="M28.2,4.49a4.83,4.83,0,0,1,.05-.68,1.55,1.55,0,0,1,.18-.55,1.59,1.59,0,0,1,.62-.64,1.84,1.84,0,0,1,1-.24,1.87,1.87,0,0,1,1,.24,1.59,1.59,0,0,1,.62.64,1.55,1.55,0,0,1,.18.55,4.83,4.83,0,0,1,.05.68v2a4.72,4.72,0,0,1-.05.68,1.55,1.55,0,0,1-.18.55,1.59,1.59,0,0,1-.62.64,1.87,1.87,0,0,1-1,.24,1.84,1.84,0,0,1-1-.24,1.59,1.59,0,0,1-.62-.64,1.55,1.55,0,0,1-.18-.55,4.72,4.72,0,0,1-.05-.68Zm1.22,2.2a.72.72,0,0,0,.17.52.53.53,0,0,0,.43.17.55.55,0,0,0,.44-.17.72.72,0,0,0,.16-.52V4.3a.74.74,0,0,0-.16-.52A.55.55,0,0,0,30,3.61a.53.53,0,0,0-.43.17.74.74,0,0,0-.17.52Z"/><path class="cls-2" d="M32.75,8.54V0H34V5.11h0l1.47-2.66H36.7L35.24,4.93,37,8.54H35.66l-1.1-2.63L34,6.83V8.54Z"/></g></svg>
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB  | 
							
								
								
									
										2
									
								
								docs/images/brand_inverted.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,2 @@
 | 
			
		||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
 | 
			
		||||
  width="120px" height="20px" viewBox="15 0 10 10" enable-background="new 0 0 270 10" xml:space="preserve"><defs><style>.cls-1{isolation:isolate;}.cls-2{fill:#000;}</style></defs><g class="cls-1"><path class="cls-2" d="M1.65,11V2.45H2.87V3a2.81,2.81,0,0,1,.47-.45A1.13,1.13,0,0,1,4,2.38,1.11,1.11,0,0,1,5.1,3a1.55,1.55,0,0,1,.16.5,5.61,5.61,0,0,1,0,.81V6.58c0,.45,0,.77,0,1a1.17,1.17,0,0,1-.55.9,1.23,1.23,0,0,1-.7.16,1.35,1.35,0,0,1-.64-.16A1.53,1.53,0,0,1,2.89,8h0v3ZM4.08,4.43a1.21,1.21,0,0,0-.14-.6.51.51,0,0,0-.46-.22A.54.54,0,0,0,3,3.82a.8.8,0,0,0-.17.54V6.73A.68.68,0,0,0,3,7.2a.6.6,0,0,0,.44.18A.53.53,0,0,0,4,7.17a1,1,0,0,0,.12-.5Z"/><path class="cls-2" d="M8.63,8.54V7.91h0a2.24,2.24,0,0,1-.48.52,1.13,1.13,0,0,1-.69.18A1.39,1.39,0,0,1,7,8.54a1.09,1.09,0,0,1-.43-.24,1.32,1.32,0,0,1-.33-.49A2.33,2.33,0,0,1,6.11,7a4.89,4.89,0,0,1,.08-.91,1.51,1.51,0,0,1,.31-.65,1.44,1.44,0,0,1,.59-.38A3.19,3.19,0,0,1,8,4.93h.59V4.33a1,1,0,0,0-.13-.52A.52.52,0,0,0,8,3.61a.71.71,0,0,0-.44.15.78.78,0,0,0-.26.46H6.13A2,2,0,0,1,6.69,2.9a1.73,1.73,0,0,1,.57-.38A2,2,0,0,1,8,2.38a2.18,2.18,0,0,1,.72.12,1.71,1.71,0,0,1,.59.36,2,2,0,0,1,.38.6,2.18,2.18,0,0,1,.14.84V8.54Zm0-2.62-.34,0a1.2,1.2,0,0,0-.67.18.76.76,0,0,0-.29.68.89.89,0,0,0,.17.56A.55.55,0,0,0,8,7.53a.63.63,0,0,0,.49-.2.91.91,0,0,0,.17-.58Z"/><path class="cls-2" d="M13,4.16a.59.59,0,0,0-.2-.47.65.65,0,0,0-.42-.16.59.59,0,0,0-.45.19.66.66,0,0,0-.15.43.8.8,0,0,0,.08.33.85.85,0,0,0,.44.29l.71.29a1.73,1.73,0,0,1,.95.72,2,2,0,0,1,.26,1,1.85,1.85,0,0,1-.52,1.3,1.56,1.56,0,0,1-.58.39,1.88,1.88,0,0,1-2-.32,1.58,1.58,0,0,1-.4-.57,1.81,1.81,0,0,1-.17-.8h1.15a1.11,1.11,0,0,0,.17.47.56.56,0,0,0,.49.22.71.71,0,0,0,.47-.18A.59.59,0,0,0,13,6.8a.69.69,0,0,0-.13-.43,1.08,1.08,0,0,0-.48-.32l-.59-.21a2.08,2.08,0,0,1-.9-.64,1.66,1.66,0,0,1-.33-1,1.89,1.89,0,0,1,.14-.72,1.78,1.78,0,0,1,.4-.57,1.5,1.5,0,0,1,.56-.36,1.82,1.82,0,0,1,.7-.13,1.93,1.93,0,0,1,.69.13,1.6,1.6,0,0,1,.54.38,1.85,1.85,0,0,1,.36.57,1.82,1.82,0,0,1,.13.7Z"/><path class="cls-2" d="M17.2,4.16a.63.63,0,0,0-.2-.47.69.69,0,0,0-.43-.16.55.55,0,0,0-.44.19.62.62,0,0,0-.16.43.68.68,0,0,0,.09.33.81.81,0,0,0,.43.29l.72.29a1.7,1.7,0,0,1,.94.72,2,2,0,0,1,.26,1,1.85,1.85,0,0,1-.52,1.3,1.61,1.61,0,0,1-.57.39,1.81,1.81,0,0,1-.74.15,1.76,1.76,0,0,1-1.24-.47,1.61,1.61,0,0,1-.41-.57,2,2,0,0,1-.17-.8h1.15a1.12,1.12,0,0,0,.18.47.53.53,0,0,0,.48.22.72.72,0,0,0,.48-.18.59.59,0,0,0,.21-.48.69.69,0,0,0-.14-.43,1,1,0,0,0-.48-.32l-.58-.21a2.06,2.06,0,0,1-.91-.64,1.66,1.66,0,0,1-.33-1A1.89,1.89,0,0,1,15,3.44a1.78,1.78,0,0,1,.4-.57,1.58,1.58,0,0,1,.56-.36,1.82,1.82,0,0,1,.7-.13,1.93,1.93,0,0,1,.69.13,1.75,1.75,0,0,1,.55.38,1.85,1.85,0,0,1,.36.57,2,2,0,0,1,.13.7Z"/><path class="cls-2" d="M19.2,8.54V0h1.22V3h0a1.53,1.53,0,0,1,.48-.47,1.39,1.39,0,0,1,.65-.16,1.26,1.26,0,0,1,.69.16,1.35,1.35,0,0,1,.4.39,1.18,1.18,0,0,1,.15.51,7.72,7.72,0,0,1,0,1V6.73a5.56,5.56,0,0,1-.05.8,1.56,1.56,0,0,1-.15.5,1.12,1.12,0,0,1-1.07.58,1.15,1.15,0,0,1-.7-.18A3.79,3.79,0,0,1,20.42,8v.55Zm2.44-4.21a1,1,0,0,0-.13-.51A.5.5,0,0,0,21,3.61a.57.57,0,0,0-.44.18.66.66,0,0,0-.18.48V6.63a.83.83,0,0,0,.17.54.52.52,0,0,0,.45.21.49.49,0,0,0,.45-.22,1.11,1.11,0,0,0,.15-.6Z"/><path class="cls-2" d="M23.76,4.49a4.83,4.83,0,0,1,0-.68A1.55,1.55,0,0,1,24,3.26a1.59,1.59,0,0,1,.62-.64,1.84,1.84,0,0,1,1-.24,1.87,1.87,0,0,1,1,.24,1.59,1.59,0,0,1,.62.64,1.55,1.55,0,0,1,.18.55,4.83,4.83,0,0,1,.05.68v2a4.72,4.72,0,0,1-.05.68,1.55,1.55,0,0,1-.18.55,1.59,1.59,0,0,1-.62.64,1.87,1.87,0,0,1-1,.24,1.84,1.84,0,0,1-1-.24A1.59,1.59,0,0,1,24,7.73a1.55,1.55,0,0,1-.18-.55,4.72,4.72,0,0,1,0-.68ZM25,6.69a.72.72,0,0,0,.17.52.53.53,0,0,0,.43.17A.55.55,0,0,0,26,7.21a.72.72,0,0,0,.16-.52V4.3A.74.74,0,0,0,26,3.78a.55.55,0,0,0-.44-.17.53.53,0,0,0-.43.17A.74.74,0,0,0,25,4.3Z"/><path class="cls-2" d="M28.2,4.49a4.83,4.83,0,0,1,.05-.68,1.55,1.55,0,0,1,.18-.55,1.59,1.59,0,0,1,.62-.64,1.84,1.84,0,0,1,1-.24,1.87,1.87,0,0,1,1,.24,1.59,1.59,0,0,1,.62.64,1.55,1.55,0,0,1,.18.55,4.83,4.83,0,0,1,.05.68v2a4.72,4.72,0,0,1-.05.68,1.55,1.55,0,0,1-.18.55,1.59,1.59,0,0,1-.62.64,1.87,1.87,0,0,1-1,.24,1.84,1.84,0,0,1-1-.24,1.59,1.59,0,0,1-.62-.64,1.55,1.55,0,0,1-.18-.55,4.72,4.72,0,0,1-.05-.68Zm1.22,2.2a.72.72,0,0,0,.17.52.53.53,0,0,0,.43.17.55.55,0,0,0,.44-.17.72.72,0,0,0,.16-.52V4.3a.74.74,0,0,0-.16-.52A.55.55,0,0,0,30,3.61a.53.53,0,0,0-.43.17.74.74,0,0,0-.17.52Z"/><path class="cls-2" d="M32.75,8.54V0H34V5.11h0l1.47-2.66H36.7L35.24,4.93,37,8.54H35.66l-1.1-2.63L34,6.83V8.54Z"/></g></svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 4.5 KiB  | 
| 
		 Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								docs/images/screen_admin.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 175 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								docs/images/screen_apps.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 160 KiB  | 
							
								
								
									
										16
									
								
								docs/index.md
									
									
									
									
									
										Executable file
									
								
							
							
						
						@ -0,0 +1,16 @@
 | 
			
		||||
#
 | 
			
		||||
{: style="height:50px"}
 | 
			
		||||
{: style="height:50px"}
 | 
			
		||||
 | 
			
		||||
## What is passbook?
 | 
			
		||||
 | 
			
		||||
passbook is an open-source Identity Provider focused on flexibility and versatility. You can use passbook in an existing environment to add support for new protocols. passbook is also a great solution for implementing signup/recovery/etc in your application, so you don't have to deal with it.
 | 
			
		||||
 | 
			
		||||
## Installation
 | 
			
		||||
 | 
			
		||||
See [Docker-compose](installation/docker-compose.md) or [Kubernetes](installation/kubernetes.md)
 | 
			
		||||
 | 
			
		||||
## Screenshots
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||

 | 
			
		||||
							
								
								
									
										26
									
								
								docs/installation/docker-compose.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,26 @@
 | 
			
		||||
# docker-compose
 | 
			
		||||
 | 
			
		||||
This installation Method is for test-setups and small-scale productive setups.
 | 
			
		||||
 | 
			
		||||
## Prerequisites
 | 
			
		||||
 | 
			
		||||
-   docker
 | 
			
		||||
-   docker-compose
 | 
			
		||||
 | 
			
		||||
## Install
 | 
			
		||||
 | 
			
		||||
Download the latest `docker-compose.yml` from [here](https://raw.githubusercontent.com/BeryJu/passbook/master/docker-compose.yml). Place it in a directory of your choice.
 | 
			
		||||
 | 
			
		||||
passbook needs to know it's primary URL to create links in E-Mails and set cookies, so you have to run the following command:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
export PASSBOOK_DOMAIN=domain.tld # this can be any domain or IP, it just needs to point to passbook.
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The compose file references the current latest version, which can be overridden with the `SERVER_TAG` Environment variable.
 | 
			
		||||
 | 
			
		||||
If you plan to use this setup for production, it is also advised to change the PostgreSQL Password by setting `PG_PASS` to a password of your choice.
 | 
			
		||||
 | 
			
		||||
Now you can pull the Docker images needed by running `docker-compose pull`. After this has finished, run `docker-compose up -d` to start passbook.
 | 
			
		||||
 | 
			
		||||
passbook will then be reachable on Port 80. You can optionally configure the packaged traefik to use Let's Encrypt for TLS Encryption.
 | 
			
		||||
							
								
								
									
										61
									
								
								docs/installation/kubernetes.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,61 @@
 | 
			
		||||
# Kubernetes
 | 
			
		||||
 | 
			
		||||
For a mid to high-load Installation, Kubernetes is recommended. passbook is installed using a helm-chart.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
# Default values for passbook.
 | 
			
		||||
# This is a YAML-formatted file.
 | 
			
		||||
# Declare variables to be passed into your templates.
 | 
			
		||||
# passbook version to use. Defaults to latest stable version
 | 
			
		||||
# image:
 | 
			
		||||
#   tag:
 | 
			
		||||
 | 
			
		||||
nameOverride: ""
 | 
			
		||||
 | 
			
		||||
config:
 | 
			
		||||
  # Optionally specify fixed secret_key, otherwise generated automatically
 | 
			
		||||
  # secret_key: _k*@6h2u2@q-dku57hhgzb7tnx*ba9wodcb^s9g0j59@=y(@_o
 | 
			
		||||
  # Enable error reporting
 | 
			
		||||
  error_reporting: false
 | 
			
		||||
  # Log level used by web and worker
 | 
			
		||||
  # Can be either debug, info, warning, error
 | 
			
		||||
  log_level: warning
 | 
			
		||||
 | 
			
		||||
# This Helm chart ships with built-in Prometheus ServiceMonitors and Rules.
 | 
			
		||||
# This requires the CoreOS Prometheus Operator.
 | 
			
		||||
monitoring:
 | 
			
		||||
  enabled: false
 | 
			
		||||
 | 
			
		||||
# Enable Database Backups to S3
 | 
			
		||||
# backup:
 | 
			
		||||
#   access_key: access-key
 | 
			
		||||
#   secret_key: secret-key
 | 
			
		||||
#   bucket: s3-bucket
 | 
			
		||||
#   host: s3-host
 | 
			
		||||
 | 
			
		||||
ingress:
 | 
			
		||||
  enabled: false
 | 
			
		||||
  annotations: {}
 | 
			
		||||
    # kubernetes.io/ingress.class: nginx
 | 
			
		||||
    # kubernetes.io/tls-acme: "true"
 | 
			
		||||
  path: /
 | 
			
		||||
  hosts:
 | 
			
		||||
    - passbook.k8s.local
 | 
			
		||||
  tls: []
 | 
			
		||||
  #  - secretName: chart-example-tls
 | 
			
		||||
  #    hosts:
 | 
			
		||||
  #      - passbook.k8s.local
 | 
			
		||||
 | 
			
		||||
# These settings configure the packaged PostgreSQL and Redis chart.
 | 
			
		||||
postgresql:
 | 
			
		||||
  postgresqlDatabase: passbook
 | 
			
		||||
 | 
			
		||||
redis:
 | 
			
		||||
  cluster:
 | 
			
		||||
    enabled: false
 | 
			
		||||
  master:
 | 
			
		||||
    persistence:
 | 
			
		||||
      enabled: false
 | 
			
		||||
    # https://stackoverflow.com/a/59189742
 | 
			
		||||
    disableCommands: []
 | 
			
		||||
```
 | 
			
		||||
							
								
								
									
										32
									
								
								docs/integrations/services/aws/index.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,32 @@
 | 
			
		||||
# Amazon Web Services Integration
 | 
			
		||||
 | 
			
		||||
## What is AWS
 | 
			
		||||
 | 
			
		||||
!!! note ""
 | 
			
		||||
    Amazon Web Services (AWS) is the world’s most comprehensive and broadly adopted cloud platform, offering over 175 fully featured services from data centers globally. Millions of customers—including the fastest-growing startups, largest enterprises, and leading government agencies—are using AWS to lower costs, become more agile, and innovate faster.
 | 
			
		||||
 | 
			
		||||
## Preparation
 | 
			
		||||
 | 
			
		||||
The following placeholders will be used:
 | 
			
		||||
 | 
			
		||||
-   `passbook.company` is the FQDN of the passbook Install
 | 
			
		||||
 | 
			
		||||
Create an application in passbook and note the slug, as this will be used later. Create a SAML Provider with the following Parameters:
 | 
			
		||||
 | 
			
		||||
-   ACS URL: `https://signin.aws.amazon.com/saml`
 | 
			
		||||
-   Audience: `urn:amazon:webservices`
 | 
			
		||||
-   Issuer: `passbook`
 | 
			
		||||
 | 
			
		||||
You can of course use a custom Signing Certificate, and adjust durations.
 | 
			
		||||
 | 
			
		||||
## AWS
 | 
			
		||||
 | 
			
		||||
Create a Role with the Permissions you desire, and note the ARN.
 | 
			
		||||
 | 
			
		||||
AWS requires two custom PropertyMappings; `Role` and `RoleSessionName`. Create them as following:
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
Afterwards export the Metadata from passbook, and create an Identity Provider [here](https://console.aws.amazon.com/iam/home#/providers).
 | 
			
		||||
| 
		 After Width: | Height: | Size: 65 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								docs/integrations/services/aws/property-mapping-role.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 66 KiB  |