From 8bd528565b4fa920415b3453be4eb19fcaea9e16 Mon Sep 17 00:00:00 2001 From: Owen Halliday Date: Wed, 20 Nov 2024 09:42:00 -0500 Subject: [PATCH 01/14] add cognito dependency --- pyproject.toml | 1 + uv.lock | 257 ++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 211 insertions(+), 47 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 5d09c3d..708038b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,6 +8,7 @@ dependencies = [ "boto3>=1.35.50", "flask>=3.0.3", "pillow>=11.0.0", + "flask-cognito-lib>=1.9.2", ] [tool.uv] diff --git a/uv.lock b/uv.lock index 6590e15..32f691a 100644 --- a/uv.lock +++ b/uv.lock @@ -8,6 +8,7 @@ source = { virtual = "." } dependencies = [ { name = "boto3" }, { name = "flask" }, + { name = "flask-cognito-lib" }, { name = "pillow" }, ] @@ -24,6 +25,7 @@ dev = [ requires-dist = [ { name = "boto3", specifier = ">=1.35.50" }, { name = "flask", specifier = ">=3.0.3" }, + { name = "flask-cognito-lib", specifier = ">=1.9.2" }, { name = "pillow", specifier = ">=11.0.0" }, ] @@ -38,39 +40,94 @@ dev = [ [[package]] name = "blinker" -version = "1.8.2" +version = "1.9.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1e/57/a6a1721eff09598fb01f3c7cda070c1b6a0f12d63c83236edf79a440abcc/blinker-1.8.2.tar.gz", hash = "sha256:8f77b09d3bf7c795e969e9486f39c2c5e9c39d4ee07424be2bc594ece9642d83", size = 23161 } +sdist = { url = "https://files.pythonhosted.org/packages/21/28/9b3f50ce0e048515135495f198351908d99540d69bfdc8c1d15b73dc55ce/blinker-1.9.0.tar.gz", hash = "sha256:b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf", size = 22460 } wheels = [ - { url = "https://files.pythonhosted.org/packages/bb/2a/10164ed1f31196a2f7f3799368a821765c62851ead0e630ab52b8e14b4d0/blinker-1.8.2-py3-none-any.whl", hash = "sha256:1779309f71bf239144b9399d06ae925637cf6634cf6bd131104184531bf67c01", size = 9456 }, + { url = "https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl", hash = "sha256:ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc", size = 8458 }, ] [[package]] name = "boto3" -version = "1.35.50" +version = "1.35.66" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "botocore" }, { name = "jmespath" }, { name = "s3transfer" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5f/2e/553086c009b4b9975f4af9f0efaac5855f2fb69dae4b94638df477a3ff37/boto3-1.35.50.tar.gz", hash = "sha256:4f15d1ccb481d66f6925b8c91c970ce41b956b6ecf7c479f23e2159531b37eec", size = 110983 } +sdist = { url = "https://files.pythonhosted.org/packages/66/aa/5a6318f61564bd181e6c65855dc78c46139b5e8c5e301256e18eedfbb7af/boto3-1.35.66.tar.gz", hash = "sha256:c392b9168b65e9c23483eaccb5b68d1f960232d7f967a1e00a045ba065ce050d", size = 111093 } wheels = [ - { url = "https://files.pythonhosted.org/packages/c4/3e/7b8af8462e9bccb7c429933948d188c6c2c568abb1ea7df9cc7a24d84cec/boto3-1.35.50-py3-none-any.whl", hash = "sha256:14724b905fd13f26d9d8f7cdcea0fa65a9acad79f60f41f7662667f4e233d97c", size = 139157 }, + { url = "https://files.pythonhosted.org/packages/01/c8/fcf1ec25b0320af58be3a3d8c0f8ed06513133c65b318895e7eb39ef14ab/boto3-1.35.66-py3-none-any.whl", hash = "sha256:09a610f8cf4d3c22d4ca69c1f89079e3a1c82805ce94fa0eb4ecdd4d2ba6c4bc", size = 139191 }, ] [[package]] name = "botocore" -version = "1.35.50" +version = "1.35.66" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jmespath" }, { name = "python-dateutil" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ef/16/04bc1b17f085a435e28b101e8a62cfe9588d6eeeab5ffa39c07d134da512/botocore-1.35.50.tar.gz", hash = "sha256:136ecef8d5a1088f1ba485c0bbfca40abd42b9f9fe9e11d8cde4e53b4c05b188", size = 12836935 } +sdist = { url = "https://files.pythonhosted.org/packages/87/06/bd0dcda686003598530eebbd0c4d7da67c031db2059a3d51a945e6199ce5/botocore-1.35.66.tar.gz", hash = "sha256:51f43220315f384959f02ea3266740db4d421592dd87576c18824e424b349fdb", size = 13089606 } wheels = [ - { url = "https://files.pythonhosted.org/packages/81/e3/c505012734ea717f48e6b8214801bf45ec2502187afcf4a6d2d75d2e29c8/botocore-1.35.50-py3-none-any.whl", hash = "sha256:965d3b99179ac04aa98e4c4baf4a970ebce77a5e02bb2a0a21cb6304e2bc0955", size = 12624100 }, + { url = "https://files.pythonhosted.org/packages/92/f0/372c2474cd198485ac427ccdd54796b05c2e730bdff0523c26012fe40ad7/botocore-1.35.66-py3-none-any.whl", hash = "sha256:d0683e9c18bb6852f768da268086c3749d925332a664db0dd1459cfa7e96e475", size = 12882983 }, +] + +[[package]] +name = "certifi" +version = "2024.8.30" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b0/ee/9b19140fe824b367c04c5e1b369942dd754c4c5462d5674002f75c4dedc1/certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9", size = 168507 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/12/90/3c9ff0512038035f59d279fddeb79f5f1eccd8859f06d6163c58798b9487/certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8", size = 167321 }, +] + +[[package]] +name = "cffi" +version = "1.17.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pycparser" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8d/f8/dd6c246b148639254dad4d6803eb6a54e8c85c6e11ec9df2cffa87571dbe/cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e", size = 182989 }, + { url = "https://files.pythonhosted.org/packages/8b/f1/672d303ddf17c24fc83afd712316fda78dc6fce1cd53011b839483e1ecc8/cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2", size = 178802 }, + { url = "https://files.pythonhosted.org/packages/0e/2d/eab2e858a91fdff70533cab61dcff4a1f55ec60425832ddfdc9cd36bc8af/cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3", size = 454792 }, + { url = "https://files.pythonhosted.org/packages/75/b2/fbaec7c4455c604e29388d55599b99ebcc250a60050610fadde58932b7ee/cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683", size = 478893 }, + { url = "https://files.pythonhosted.org/packages/4f/b7/6e4a2162178bf1935c336d4da8a9352cccab4d3a5d7914065490f08c0690/cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5", size = 485810 }, + { url = "https://files.pythonhosted.org/packages/c7/8a/1d0e4a9c26e54746dc08c2c6c037889124d4f59dffd853a659fa545f1b40/cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4", size = 471200 }, + { url = "https://files.pythonhosted.org/packages/26/9f/1aab65a6c0db35f43c4d1b4f580e8df53914310afc10ae0397d29d697af4/cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd", size = 479447 }, + { url = "https://files.pythonhosted.org/packages/5f/e4/fb8b3dd8dc0e98edf1135ff067ae070bb32ef9d509d6cb0f538cd6f7483f/cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed", size = 484358 }, + { url = "https://files.pythonhosted.org/packages/f1/47/d7145bf2dc04684935d57d67dff9d6d795b2ba2796806bb109864be3a151/cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9", size = 488469 }, + { url = "https://files.pythonhosted.org/packages/bf/ee/f94057fa6426481d663b88637a9a10e859e492c73d0384514a17d78ee205/cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d", size = 172475 }, + { url = "https://files.pythonhosted.org/packages/7c/fc/6a8cb64e5f0324877d503c854da15d76c1e50eb722e320b15345c4d0c6de/cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", size = 182009 }, +] + +[[package]] +name = "charset-normalizer" +version = "3.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f2/4f/e1808dc01273379acc506d18f1504eb2d299bd4131743b9fc54d7be4df1e/charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e", size = 106620 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f3/89/68a4c86f1a0002810a27f12e9a7b22feb198c59b2f05231349fbce5c06f4/charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114", size = 194617 }, + { url = "https://files.pythonhosted.org/packages/4f/cd/8947fe425e2ab0aa57aceb7807af13a0e4162cd21eee42ef5b053447edf5/charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed", size = 125310 }, + { url = "https://files.pythonhosted.org/packages/5b/f0/b5263e8668a4ee9becc2b451ed909e9c27058337fda5b8c49588183c267a/charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250", size = 119126 }, + { url = "https://files.pythonhosted.org/packages/ff/6e/e445afe4f7fda27a533f3234b627b3e515a1b9429bc981c9a5e2aa5d97b6/charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920", size = 139342 }, + { url = "https://files.pythonhosted.org/packages/a1/b2/4af9993b532d93270538ad4926c8e37dc29f2111c36f9c629840c57cd9b3/charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64", size = 149383 }, + { url = "https://files.pythonhosted.org/packages/fb/6f/4e78c3b97686b871db9be6f31d64e9264e889f8c9d7ab33c771f847f79b7/charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23", size = 142214 }, + { url = "https://files.pythonhosted.org/packages/2b/c9/1c8fe3ce05d30c87eff498592c89015b19fade13df42850aafae09e94f35/charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc", size = 144104 }, + { url = "https://files.pythonhosted.org/packages/ee/68/efad5dcb306bf37db7db338338e7bb8ebd8cf38ee5bbd5ceaaaa46f257e6/charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d", size = 146255 }, + { url = "https://files.pythonhosted.org/packages/0c/75/1ed813c3ffd200b1f3e71121c95da3f79e6d2a96120163443b3ad1057505/charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88", size = 140251 }, + { url = "https://files.pythonhosted.org/packages/7d/0d/6f32255c1979653b448d3c709583557a4d24ff97ac4f3a5be156b2e6a210/charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90", size = 148474 }, + { url = "https://files.pythonhosted.org/packages/ac/a0/c1b5298de4670d997101fef95b97ac440e8c8d8b4efa5a4d1ef44af82f0d/charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b", size = 151849 }, + { url = "https://files.pythonhosted.org/packages/04/4f/b3961ba0c664989ba63e30595a3ed0875d6790ff26671e2aae2fdc28a399/charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d", size = 149781 }, + { url = "https://files.pythonhosted.org/packages/d8/90/6af4cd042066a4adad58ae25648a12c09c879efa4849c705719ba1b23d8c/charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482", size = 144970 }, + { url = "https://files.pythonhosted.org/packages/cc/67/e5e7e0cbfefc4ca79025238b43cdf8a2037854195b37d6417f3d0895c4c2/charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67", size = 94973 }, + { url = "https://files.pythonhosted.org/packages/65/97/fc9bbc54ee13d33dc54a7fcf17b26368b18505500fc01e228c27b5222d80/charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b", size = 102308 }, + { url = "https://files.pythonhosted.org/packages/bf/9b/08c0432272d77b04803958a4598a51e2a4b51c06640af8b8f0f908c18bf2/charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079", size = 49446 }, ] [[package]] @@ -94,9 +151,38 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, ] +[[package]] +name = "cryptography" +version = "43.0.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0d/05/07b55d1fa21ac18c3a8c79f764e2514e6f6a9698f1be44994f5adf0d29db/cryptography-43.0.3.tar.gz", hash = "sha256:315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805", size = 686989 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1f/f3/01fdf26701a26f4b4dbc337a26883ad5bccaa6f1bbbdd29cd89e22f18a1c/cryptography-43.0.3-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:bf7a1932ac4176486eab36a19ed4c0492da5d97123f1406cf15e41b05e787d2e", size = 6225303 }, + { url = "https://files.pythonhosted.org/packages/a3/01/4896f3d1b392025d4fcbecf40fdea92d3df8662123f6835d0af828d148fd/cryptography-43.0.3-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63efa177ff54aec6e1c0aefaa1a241232dcd37413835a9b674b6e3f0ae2bfd3e", size = 3760905 }, + { url = "https://files.pythonhosted.org/packages/0a/be/f9a1f673f0ed4b7f6c643164e513dbad28dd4f2dcdf5715004f172ef24b6/cryptography-43.0.3-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e1ce50266f4f70bf41a2c6dc4358afadae90e2a1e5342d3c08883df1675374f", size = 3977271 }, + { url = "https://files.pythonhosted.org/packages/4e/49/80c3a7b5514d1b416d7350830e8c422a4d667b6d9b16a9392ebfd4a5388a/cryptography-43.0.3-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:443c4a81bb10daed9a8f334365fe52542771f25aedaf889fd323a853ce7377d6", size = 3746606 }, + { url = "https://files.pythonhosted.org/packages/0e/16/a28ddf78ac6e7e3f25ebcef69ab15c2c6be5ff9743dd0709a69a4f968472/cryptography-43.0.3-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:74f57f24754fe349223792466a709f8e0c093205ff0dca557af51072ff47ab18", size = 3986484 }, + { url = "https://files.pythonhosted.org/packages/01/f5/69ae8da70c19864a32b0315049866c4d411cce423ec169993d0434218762/cryptography-43.0.3-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9762ea51a8fc2a88b70cf2995e5675b38d93bf36bd67d91721c309df184f49bd", size = 3852131 }, + { url = "https://files.pythonhosted.org/packages/fd/db/e74911d95c040f9afd3612b1f732e52b3e517cb80de8bf183be0b7d413c6/cryptography-43.0.3-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:81ef806b1fef6b06dcebad789f988d3b37ccaee225695cf3e07648eee0fc6b73", size = 4075647 }, + { url = "https://files.pythonhosted.org/packages/56/48/7b6b190f1462818b324e674fa20d1d5ef3e24f2328675b9b16189cbf0b3c/cryptography-43.0.3-cp37-abi3-win32.whl", hash = "sha256:cbeb489927bd7af4aa98d4b261af9a5bc025bd87f0e3547e11584be9e9427be2", size = 2623873 }, + { url = "https://files.pythonhosted.org/packages/eb/b1/0ebff61a004f7f89e7b65ca95f2f2375679d43d0290672f7713ee3162aff/cryptography-43.0.3-cp37-abi3-win_amd64.whl", hash = "sha256:f46304d6f0c6ab8e52770addfa2fc41e6629495548862279641972b6215451cd", size = 3068039 }, + { url = "https://files.pythonhosted.org/packages/30/d5/c8b32c047e2e81dd172138f772e81d852c51f0f2ad2ae8a24f1122e9e9a7/cryptography-43.0.3-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:8ac43ae87929a5982f5948ceda07001ee5e83227fd69cf55b109144938d96984", size = 6222984 }, + { url = "https://files.pythonhosted.org/packages/2f/78/55356eb9075d0be6e81b59f45c7b48df87f76a20e73893872170471f3ee8/cryptography-43.0.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:846da004a5804145a5f441b8530b4bf35afbf7da70f82409f151695b127213d5", size = 3762968 }, + { url = "https://files.pythonhosted.org/packages/2a/2c/488776a3dc843f95f86d2f957ca0fc3407d0242b50bede7fad1e339be03f/cryptography-43.0.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f996e7268af62598f2fc1204afa98a3b5712313a55c4c9d434aef49cadc91d4", size = 3977754 }, + { url = "https://files.pythonhosted.org/packages/7c/04/2345ca92f7a22f601a9c62961741ef7dd0127c39f7310dffa0041c80f16f/cryptography-43.0.3-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f7b178f11ed3664fd0e995a47ed2b5ff0a12d893e41dd0494f406d1cf555cab7", size = 3749458 }, + { url = "https://files.pythonhosted.org/packages/ac/25/e715fa0bc24ac2114ed69da33adf451a38abb6f3f24ec207908112e9ba53/cryptography-43.0.3-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:c2e6fc39c4ab499049df3bdf567f768a723a5e8464816e8f009f121a5a9f4405", size = 3988220 }, + { url = "https://files.pythonhosted.org/packages/21/ce/b9c9ff56c7164d8e2edfb6c9305045fbc0df4508ccfdb13ee66eb8c95b0e/cryptography-43.0.3-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e1be4655c7ef6e1bbe6b5d0403526601323420bcf414598955968c9ef3eb7d16", size = 3853898 }, + { url = "https://files.pythonhosted.org/packages/2a/33/b3682992ab2e9476b9c81fff22f02c8b0a1e6e1d49ee1750a67d85fd7ed2/cryptography-43.0.3-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:df6b6c6d742395dd77a23ea3728ab62f98379eff8fb61be2744d4679ab678f73", size = 4076592 }, + { url = "https://files.pythonhosted.org/packages/81/1e/ffcc41b3cebd64ca90b28fd58141c5f68c83d48563c88333ab660e002cd3/cryptography-43.0.3-cp39-abi3-win32.whl", hash = "sha256:d56e96520b1020449bbace2b78b603442e7e378a9b3bd68de65c782db1507995", size = 2623145 }, + { url = "https://files.pythonhosted.org/packages/87/5c/3dab83cc4aba1f4b0e733e3f0c3e7d4386440d660ba5b1e3ff995feb734d/cryptography-43.0.3-cp39-abi3-win_amd64.whl", hash = "sha256:0c580952eef9bf68c4747774cde7ec1d85a6e61de97281f2dba83c7d2c806362", size = 3068026 }, +] + [[package]] name = "flask" -version = "3.0.3" +version = "3.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "blinker" }, @@ -105,9 +191,25 @@ dependencies = [ { name = "jinja2" }, { name = "werkzeug" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/41/e1/d104c83026f8d35dfd2c261df7d64738341067526406b40190bc063e829a/flask-3.0.3.tar.gz", hash = "sha256:ceb27b0af3823ea2737928a4d99d125a06175b8512c445cbd9a9ce200ef76842", size = 676315 } +sdist = { url = "https://files.pythonhosted.org/packages/89/50/dff6380f1c7f84135484e176e0cac8690af72fa90e932ad2a0a60e28c69b/flask-3.1.0.tar.gz", hash = "sha256:5f873c5184c897c8d9d1b05df1e3d01b14910ce69607a117bd3277098a5836ac", size = 680824 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/af/47/93213ee66ef8fae3b93b3e29206f6b251e65c97bd91d8e1c5596ef15af0a/flask-3.1.0-py3-none-any.whl", hash = "sha256:d667207822eb83f1c4b50949b1623c8fc8d51f2341d65f72e1a1815397551136", size = 102979 }, +] + +[[package]] +name = "flask-cognito-lib" +version = "1.9.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cryptography" }, + { name = "flask" }, + { name = "pyjwt", extra = ["crypto"] }, + { name = "requests" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5d/fd/ce6489cc992379b9039821903a8a6a145309e7c88c0d0a273b61478a9910/flask_cognito_lib-1.9.2.tar.gz", hash = "sha256:a5b49f0789bedaa2bb50e38058eed8e76fc2ff3eaba22f118cca410d6365c599", size = 17800 } wheels = [ - { url = "https://files.pythonhosted.org/packages/61/80/ffe1da13ad9300f87c93af113edd0638c75138c42a0994becfacac078c06/flask-3.0.3-py3-none-any.whl", hash = "sha256:34e815dfaa43340d1d15a5c3a02b8476004037eb4840b34910c6e21679d288f3", size = 101735 }, + { url = "https://files.pythonhosted.org/packages/b8/ef/3cacc5886c40de5ab741e5b258c1062007f6de80dbd6d31702268c71bc98/flask_cognito_lib-1.9.2-py3-none-any.whl", hash = "sha256:538ae3fb6a16e858a0aa610bdcdf54e07ec41886820f9c395f5a41e299230129", size = 18148 }, ] [[package]] @@ -122,6 +224,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/cb/7d/6dac2a6e1eba33ee43f318edbed4ff29151a49b5d37f080aad1e6469bca4/gunicorn-23.0.0-py3-none-any.whl", hash = "sha256:ec400d38950de4dfd418cff8328b2c8faed0edb0d517d3394e457c317908ca4d", size = 85029 }, ] +[[package]] +name = "idna" +version = "3.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 }, +] + [[package]] name = "iniconfig" version = "2.0.0" @@ -191,25 +302,25 @@ wheels = [ [[package]] name = "mongomock" -version = "4.2.0.post1" +version = "4.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "packaging" }, { name = "pytz" }, { name = "sentinels" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/47/1d/e6eb5dee9c95e086fc1a72c3d50b71385c81ebe963cc85c2150914629c6b/mongomock-4.2.0.post1.tar.gz", hash = "sha256:9241d2cec7274b9736dbe8edacb19528ff66af3b3779b324d79ecc4201227f31", size = 134369 } +sdist = { url = "https://files.pythonhosted.org/packages/4d/a4/4a560a9f2a0bec43d5f63104f55bc48666d619ca74825c8ae156b08547cf/mongomock-4.3.0.tar.gz", hash = "sha256:32667b79066fabc12d4f17f16a8fd7361b5f4435208b3ba32c226e52212a8c30", size = 135862 } wheels = [ - { url = "https://files.pythonhosted.org/packages/d0/3c/846538689518247545758c29ef2d7587126c481118e580892ded3439dbbc/mongomock-4.2.0.post1-py2.py3-none-any.whl", hash = "sha256:ff78f1944bf0cdcfc291ece198357db805c2f0db39e814bcef8a43c9f53e8a81", size = 64551 }, + { url = "https://files.pythonhosted.org/packages/94/4d/8bea712978e3aff017a2ab50f262c620e9239cc36f348aae45e48d6a4786/mongomock-4.3.0-py2.py3-none-any.whl", hash = "sha256:5ef86bd12fc8806c6e7af32f21266c61b6c4ba96096f85129852d1c4fec1327e", size = 64891 }, ] [[package]] name = "packaging" -version = "24.1" +version = "24.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/51/65/50db4dda066951078f0a96cf12f4b9ada6e4b811516bf0262c0f4f7064d4/packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002", size = 148788 } +sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950 } wheels = [ - { url = "https://files.pythonhosted.org/packages/08/aa/cc0199a5f0ad350994d660967a8efb233fe0416e4639146c089643407ce6/packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124", size = 53985 }, + { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451 }, ] [[package]] @@ -248,6 +359,29 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556 }, ] +[[package]] +name = "pycparser" +version = "2.22" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", size = 172736 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", size = 117552 }, +] + +[[package]] +name = "pyjwt" +version = "2.10.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b5/05/324952ded002de746f87b21066b9373080bb5058f64cf01c4d62784b8186/pyjwt-2.10.0.tar.gz", hash = "sha256:7628a7eb7938959ac1b26e819a1df0fd3259505627b575e4bad6d08f76db695c", size = 87687 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6f/1d/ef9b066e7ef60494c94173dc9f0b9adf5d9ec5f888109f5c669f53d4144b/PyJWT-2.10.0-py3-none-any.whl", hash = "sha256:543b77207db656de204372350926bed5a86201c4cbff159f623f79c7bb487a15", size = 23002 }, +] + +[package.optional-dependencies] +crypto = [ + { name = "cryptography" }, +] + [[package]] name = "pytest" version = "8.3.3" @@ -284,41 +418,56 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/11/c3/005fcca25ce078d2cc29fd559379817424e94885510568bc1bc53d7d5846/pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725", size = 508002 }, ] +[[package]] +name = "requests" +version = "2.32.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928 }, +] + [[package]] name = "ruff" -version = "0.7.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a6/21/5c6e05e0fd3fbb41be4fb92edbc9a04de70baf60adb61435ce0c6b8c3d55/ruff-0.7.1.tar.gz", hash = "sha256:9d8a41d4aa2dad1575adb98a82870cf5db5f76b2938cf2206c22c940034a36f4", size = 3181670 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/65/45/8a20a9920175c9c4892b2420f80ff3cf14949cf3067118e212f9acd9c908/ruff-0.7.1-py3-none-linux_armv6l.whl", hash = "sha256:cb1bc5ed9403daa7da05475d615739cc0212e861b7306f314379d958592aaa89", size = 10389268 }, - { url = "https://files.pythonhosted.org/packages/1b/d3/2f8382db2cf4f9488e938602e33e36287f9d26cb283aa31f11c31297ce79/ruff-0.7.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:27c1c52a8d199a257ff1e5582d078eab7145129aa02721815ca8fa4f9612dc35", size = 10188348 }, - { url = "https://files.pythonhosted.org/packages/a2/31/7d14e2a88da351200f844b7be889a0845d9e797162cf76b136d21b832a23/ruff-0.7.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:588a34e1ef2ea55b4ddfec26bbe76bc866e92523d8c6cdec5e8aceefeff02d99", size = 9841448 }, - { url = "https://files.pythonhosted.org/packages/db/99/738cafdc768eceeca0bd26c6f03e213aa91203d2278e1d95b1c31c4ece41/ruff-0.7.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94fc32f9cdf72dc75c451e5f072758b118ab8100727168a3df58502b43a599ca", size = 10674864 }, - { url = "https://files.pythonhosted.org/packages/fe/12/bcf2836b50eab53c65008383e7d55201e490d75167c474f14a16e1af47d2/ruff-0.7.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:985818742b833bffa543a84d1cc11b5e6871de1b4e0ac3060a59a2bae3969250", size = 10192105 }, - { url = "https://files.pythonhosted.org/packages/2b/71/261d5d668bf98b6c44e89bfb5dfa4cb8cb6c8b490a201a3d8030e136ea4f/ruff-0.7.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32f1e8a192e261366c702c5fb2ece9f68d26625f198a25c408861c16dc2dea9c", size = 11194144 }, - { url = "https://files.pythonhosted.org/packages/90/1f/0926d18a3b566fa6e7b3b36093088e4ffef6b6ba4ea85a462d9a93f7e35c/ruff-0.7.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:699085bf05819588551b11751eff33e9ca58b1b86a6843e1b082a7de40da1565", size = 11917066 }, - { url = "https://files.pythonhosted.org/packages/cd/a8/9fac41f128b6a44ab4409c1493430b4ee4b11521e8aeeca19bfe1ce851f9/ruff-0.7.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:344cc2b0814047dc8c3a8ff2cd1f3d808bb23c6658db830d25147339d9bf9ea7", size = 11458821 }, - { url = "https://files.pythonhosted.org/packages/25/cd/59644168f086ab13fe4e02943b9489a0aa710171f66b178e179df5383554/ruff-0.7.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4316bbf69d5a859cc937890c7ac7a6551252b6a01b1d2c97e8fc96e45a7c8b4a", size = 12700379 }, - { url = "https://files.pythonhosted.org/packages/fb/30/3bac63619eb97174661829c07fc46b2055a053dee72da29d7c304c1cd2c0/ruff-0.7.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79d3af9dca4c56043e738a4d6dd1e9444b6d6c10598ac52d146e331eb155a8ad", size = 11019813 }, - { url = "https://files.pythonhosted.org/packages/4b/af/f567b885b5cb3bcdbcca3458ebf210cc8c9c7a9f61c332d3c2a050c3b21e/ruff-0.7.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:c5c121b46abde94a505175524e51891f829414e093cd8326d6e741ecfc0a9112", size = 10662146 }, - { url = "https://files.pythonhosted.org/packages/bc/ad/eb930d3ad117a9f2f7261969c21559ebd82bb13b6e8001c7caed0d44be5f/ruff-0.7.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:8422104078324ea250886954e48f1373a8fe7de59283d747c3a7eca050b4e378", size = 10256911 }, - { url = "https://files.pythonhosted.org/packages/20/d5/af292ce70a016fcec792105ca67f768b403dd480a11888bc1f418fed0dd5/ruff-0.7.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:56aad830af8a9db644e80098fe4984a948e2b6fc2e73891538f43bbe478461b8", size = 10767488 }, - { url = "https://files.pythonhosted.org/packages/24/85/cc04a3bd027f433bebd2a097e63b3167653c079f7f13d8f9a1178e693412/ruff-0.7.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:658304f02f68d3a83c998ad8bf91f9b4f53e93e5412b8f2388359d55869727fd", size = 11093368 }, - { url = "https://files.pythonhosted.org/packages/0b/fb/c39cbf32d1f3e318674b8622f989417231794926b573f76dd4d0ca49f0f1/ruff-0.7.1-py3-none-win32.whl", hash = "sha256:b517a2011333eb7ce2d402652ecaa0ac1a30c114fbbd55c6b8ee466a7f600ee9", size = 8594180 }, - { url = "https://files.pythonhosted.org/packages/5a/71/ec8cdea34ecb90c830ca60d54ac7b509a7b5eab50fae27e001d4470fe813/ruff-0.7.1-py3-none-win_amd64.whl", hash = "sha256:f38c41fcde1728736b4eb2b18850f6d1e3eedd9678c914dede554a70d5241307", size = 9419751 }, - { url = "https://files.pythonhosted.org/packages/79/7b/884553415e9f0a9bf358ed52fb68b934e67ef6c5a62397ace924a1afdf9a/ruff-0.7.1-py3-none-win_arm64.whl", hash = "sha256:19aa200ec824c0f36d0c9114c8ec0087082021732979a359d6f3c390a6ff2a37", size = 8717402 }, +version = "0.7.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0b/8b/bc4e0dfa1245b07cf14300e10319b98e958a53ff074c1dd86b35253a8c2a/ruff-0.7.4.tar.gz", hash = "sha256:cd12e35031f5af6b9b93715d8c4f40360070b2041f81273d0527683d5708fce2", size = 3275547 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e6/4b/f5094719e254829766b807dadb766841124daba75a37da83e292ae5ad12f/ruff-0.7.4-py3-none-linux_armv6l.whl", hash = "sha256:a4919925e7684a3f18e18243cd6bea7cfb8e968a6eaa8437971f681b7ec51478", size = 10447512 }, + { url = "https://files.pythonhosted.org/packages/9e/1d/3d2d2c9f601cf6044799c5349ff5267467224cefed9b35edf5f1f36486e9/ruff-0.7.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:cfb365c135b830778dda8c04fb7d4280ed0b984e1aec27f574445231e20d6c63", size = 10235436 }, + { url = "https://files.pythonhosted.org/packages/62/83/42a6ec6216ded30b354b13e0e9327ef75a3c147751aaf10443756cb690e9/ruff-0.7.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:63a569b36bc66fbadec5beaa539dd81e0527cb258b94e29e0531ce41bacc1f20", size = 9888936 }, + { url = "https://files.pythonhosted.org/packages/4d/26/e1e54893b13046a6ad05ee9b89ee6f71542ba250f72b4c7a7d17c3dbf73d/ruff-0.7.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d06218747d361d06fd2fdac734e7fa92df36df93035db3dc2ad7aa9852cb109", size = 10697353 }, + { url = "https://files.pythonhosted.org/packages/21/24/98d2e109c4efc02bfef144ec6ea2c3e1217e7ce0cfddda8361d268dfd499/ruff-0.7.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e0cea28d0944f74ebc33e9f934238f15c758841f9f5edd180b5315c203293452", size = 10228078 }, + { url = "https://files.pythonhosted.org/packages/ad/b7/964c75be9bc2945fc3172241b371197bb6d948cc69e28bc4518448c368f3/ruff-0.7.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:80094ecd4793c68b2571b128f91754d60f692d64bc0d7272ec9197fdd09bf9ea", size = 11264823 }, + { url = "https://files.pythonhosted.org/packages/12/8d/20abdbf705969914ce40988fe71a554a918deaab62c38ec07483e77866f6/ruff-0.7.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:997512325c6620d1c4c2b15db49ef59543ef9cd0f4aa8065ec2ae5103cedc7e7", size = 11951855 }, + { url = "https://files.pythonhosted.org/packages/b8/fc/6519ce58c57b4edafcdf40920b7273dfbba64fc6ebcaae7b88e4dc1bf0a8/ruff-0.7.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:00b4cf3a6b5fad6d1a66e7574d78956bbd09abfd6c8a997798f01f5da3d46a05", size = 11516580 }, + { url = "https://files.pythonhosted.org/packages/37/1a/5ec1844e993e376a86eb2456496831ed91b4398c434d8244f89094758940/ruff-0.7.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7dbdc7d8274e1422722933d1edddfdc65b4336abf0b16dfcb9dedd6e6a517d06", size = 12692057 }, + { url = "https://files.pythonhosted.org/packages/50/90/76867152b0d3c05df29a74bb028413e90f704f0f6701c4801174ba47f959/ruff-0.7.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e92dfb5f00eaedb1501b2f906ccabfd67b2355bdf117fea9719fc99ac2145bc", size = 11085137 }, + { url = "https://files.pythonhosted.org/packages/c8/eb/0a7cb6059ac3555243bd026bb21785bbc812f7bbfa95a36c101bd72b47ae/ruff-0.7.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:3bd726099f277d735dc38900b6a8d6cf070f80828877941983a57bca1cd92172", size = 10681243 }, + { url = "https://files.pythonhosted.org/packages/5e/76/2270719dbee0fd35780b05c08a07b7a726c3da9f67d9ae89ef21fc18e2e5/ruff-0.7.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:2e32829c429dd081ee5ba39aef436603e5b22335c3d3fff013cd585806a6486a", size = 10319187 }, + { url = "https://files.pythonhosted.org/packages/9f/e5/39100f72f8ba70bec1bd329efc880dea8b6c1765ea1cb9d0c1c5f18b8d7f/ruff-0.7.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:662a63b4971807623f6f90c1fb664613f67cc182dc4d991471c23c541fee62dd", size = 10803715 }, + { url = "https://files.pythonhosted.org/packages/a5/89/40e904784f305fb56850063f70a998a64ebba68796d823dde67e89a24691/ruff-0.7.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:876f5e09eaae3eb76814c1d3b68879891d6fde4824c015d48e7a7da4cf066a3a", size = 11162912 }, + { url = "https://files.pythonhosted.org/packages/8d/1b/dd77503b3875c51e3dbc053fd8367b845ab8b01c9ca6d0c237082732856c/ruff-0.7.4-py3-none-win32.whl", hash = "sha256:75c53f54904be42dd52a548728a5b572344b50d9b2873d13a3f8c5e3b91f5cac", size = 8702767 }, + { url = "https://files.pythonhosted.org/packages/63/76/253ddc3e89e70165bba952ecca424b980b8d3c2598ceb4fc47904f424953/ruff-0.7.4-py3-none-win_amd64.whl", hash = "sha256:745775c7b39f914238ed1f1b0bebed0b9155a17cd8bc0b08d3c87e4703b990d6", size = 9497534 }, + { url = "https://files.pythonhosted.org/packages/aa/70/f8724f31abc0b329ca98b33d73c14020168babcf71b0cba3cded5d9d0e66/ruff-0.7.4-py3-none-win_arm64.whl", hash = "sha256:11bff065102c3ae9d3ea4dc9ecdfe5a5171349cdd0787c1fc64761212fc9cf1f", size = 8851590 }, ] [[package]] name = "s3transfer" -version = "0.10.3" +version = "0.10.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "botocore" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a0/a8/e0a98fd7bd874914f0608ef7c90ffde17e116aefad765021de0f012690a2/s3transfer-0.10.3.tar.gz", hash = "sha256:4f50ed74ab84d474ce614475e0b8d5047ff080810aac5d01ea25231cfc944b0c", size = 144591 } +sdist = { url = "https://files.pythonhosted.org/packages/c0/0a/1cdbabf9edd0ea7747efdf6c9ab4e7061b085aa7f9bfc36bb1601563b069/s3transfer-0.10.4.tar.gz", hash = "sha256:29edc09801743c21eb5ecbc617a152df41d3c287f67b615f73e5f750583666a7", size = 145287 } wheels = [ - { url = "https://files.pythonhosted.org/packages/e5/c0/b0fba8259b61c938c9733da9346b9f93e00881a9db22aafdd72f6ae0ec05/s3transfer-0.10.3-py3-none-any.whl", hash = "sha256:263ed587a5803c6c708d3ce44dc4dfedaab4c1a32e8329bab818933d79ddcf5d", size = 82625 }, + { url = "https://files.pythonhosted.org/packages/66/05/7957af15543b8c9799209506df4660cba7afc4cf94bfb60513827e96bed6/s3transfer-0.10.4-py3-none-any.whl", hash = "sha256:244a76a24355363a68164241438de1b72f8781664920260c48465896b712a41e", size = 83175 }, ] [[package]] @@ -329,9 +478,23 @@ sdist = { url = "https://files.pythonhosted.org/packages/ac/b7/1af07a98390aba07d [[package]] name = "setproctitle" -version = "1.3.3" +version = "1.3.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ff/e1/b16b16a1aa12174349d15b73fd4b87e641a8ae3fb1163e80938dbbf6ae98/setproctitle-1.3.3.tar.gz", hash = "sha256:c913e151e7ea01567837ff037a23ca8740192880198b7fbb90b16d181607caae", size = 27253 } +sdist = { url = "https://files.pythonhosted.org/packages/ae/4e/b09341b19b9ceb8b4c67298ab4a08ef7a4abdd3016c7bb152e9b6379031d/setproctitle-1.3.4.tar.gz", hash = "sha256:3b40d32a3e1f04e94231ed6dfee0da9e43b4f9c6b5450d53e6dd7754c34e0c50", size = 26456 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d4/01/51d07ab1dbec8885ebad419d254c06b9e28f4363c163b737a89995a52b75/setproctitle-1.3.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:d6e3b177e634aa6bbbfbf66d097b6d1cdb80fc60e912c7d8bace2e45699c07dd", size = 16831 }, + { url = "https://files.pythonhosted.org/packages/30/03/deff7089b525c0d8ec047e06661d2be67c87685a99be6a6aed2890b81c8f/setproctitle-1.3.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6b17655a5f245b416e127e02087ea6347a48821cc4626bc0fd57101bfcd88afc", size = 11607 }, + { url = "https://files.pythonhosted.org/packages/ea/be/cb2950b3f6ba460f530bda2c713828236c75d982d0aa0f62b33429a9b4d0/setproctitle-1.3.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fa5057a86df920faab8ee83960b724bace01a3231eb8e3f2c93d78283504d598", size = 31881 }, + { url = "https://files.pythonhosted.org/packages/5c/b4/1f0dba7525a2fbefd08d4086e7e998d9c7581153807fb6b3083d06e0b8e2/setproctitle-1.3.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:149fdfb8a26a555780c4ce53c92e6d3c990ef7b30f90a675eca02e83c6d5f76d", size = 33290 }, + { url = "https://files.pythonhosted.org/packages/2d/a8/07a160f9dcd1a7b1cad39ce6cbaf4425837502b0592a400c38cb21f0f247/setproctitle-1.3.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ded03546938a987f463c68ab98d683af87a83db7ac8093bbc179e77680be5ba2", size = 30489 }, + { url = "https://files.pythonhosted.org/packages/83/0c/3d972d9ea4165961a9764df5324d42bf2d059cb8a6ef516c67f068ed4d92/setproctitle-1.3.4-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ab9f5b7f2bbc1754bc6292d9a7312071058e5a891b0391e6d13b226133f36aa", size = 31576 }, + { url = "https://files.pythonhosted.org/packages/7a/c0/c12bdc2c91009defdd1b207ff156ccd691f5b9a6a0aae1ed9126d4ff9a0c/setproctitle-1.3.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0b19813c852566fa031902124336fa1f080c51e262fc90266a8c3d65ca47b74c", size = 31273 }, + { url = "https://files.pythonhosted.org/packages/4f/83/8d704bee57990b27537adf7c97540f32226ffa3922fb26bdd459da8a4470/setproctitle-1.3.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:db78b645dc63c0ccffca367a498f3b13492fb106a2243a1e998303ba79c996e2", size = 30236 }, + { url = "https://files.pythonhosted.org/packages/d8/42/94e31d1f515f831e1ae43f2405794257eb940a7972b2fbb6283790db2958/setproctitle-1.3.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:b669aaac70bd9f03c070270b953f78d9ee56c4af6f0ff9f9cd3e6d1878c10b40", size = 32766 }, + { url = "https://files.pythonhosted.org/packages/83/53/01746ed8fb75239a001ee89d5eb8ad5a3022df510572d1cf60dd04567e13/setproctitle-1.3.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6dc3d656702791565994e64035a208be56b065675a5bc87b644c657d6d9e2232", size = 30812 }, + { url = "https://files.pythonhosted.org/packages/5f/ea/3ce61e70a6b898e95c0a1e393964c829103dc4ad4b0732cd70c8fc13e54c/setproctitle-1.3.4-cp313-cp313-win32.whl", hash = "sha256:091f682809a4d12291cf0205517619d2e7014986b7b00ebecfde3d76f8ae5a8f", size = 11349 }, + { url = "https://files.pythonhosted.org/packages/e7/1a/8149da1c19db6bd57164d62b1d91c188e7d77e695947cf1ac327c8aea513/setproctitle-1.3.4-cp313-cp313-win_amd64.whl", hash = "sha256:adcd6ba863a315702184d92d3d3bbff290514f24a14695d310f02ae5e28bd1f7", size = 12062 }, +] [[package]] name = "six" @@ -353,12 +516,12 @@ wheels = [ [[package]] name = "werkzeug" -version = "3.0.6" +version = "3.1.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markupsafe" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d4/f9/0ba83eaa0df9b9e9d1efeb2ea351d0677c37d41ee5d0f91e98423c7281c9/werkzeug-3.0.6.tar.gz", hash = "sha256:a8dd59d4de28ca70471a34cba79bed5f7ef2e036a76b3ab0835474246eb41f8d", size = 805170 } +sdist = { url = "https://files.pythonhosted.org/packages/9f/69/83029f1f6300c5fb2471d621ab06f6ec6b3324685a2ce0f9777fd4a8b71e/werkzeug-3.1.3.tar.gz", hash = "sha256:60723ce945c19328679790e3282cc758aa4a6040e4bb330f53d30fa546d44746", size = 806925 } wheels = [ - { url = "https://files.pythonhosted.org/packages/6c/69/05837f91dfe42109203ffa3e488214ff86a6d68b2ed6c167da6cdc42349b/werkzeug-3.0.6-py3-none-any.whl", hash = "sha256:1bc0c2310d2fbb07b1dd1105eba2f7af72f322e1e455f2f93c993bee8c8a5f17", size = 227979 }, + { url = "https://files.pythonhosted.org/packages/52/24/ab44c871b0f07f491e5d2ad12c9bd7358e527510618cb1b803a88e986db1/werkzeug-3.1.3-py3-none-any.whl", hash = "sha256:54b78bf3716d19a65be4fceccc0d1d7b89e608834989dfae50ea87564639213e", size = 224498 }, ] From 8ff09702334f6c50e34fa11d6c396dd257e3fab0 Mon Sep 17 00:00:00 2001 From: Owen Halliday Date: Wed, 20 Nov 2024 09:48:07 -0500 Subject: [PATCH 02/14] implement barebones auth flow --- src/app/app.py | 4 +++- src/app/auth_routes.py | 43 ++++++++++++++++++++++++++++++++++++++++++ src/app/config.py | 28 +++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 src/app/auth_routes.py diff --git a/src/app/app.py b/src/app/app.py index 7a69dc6..a1b7011 100644 --- a/src/app/app.py +++ b/src/app/app.py @@ -5,7 +5,7 @@ from data.persistence import TilePoolDB, tile_to_dict from game.game import Board -from . import image_routes, tilepool_routes +from . import auth_routes, image_routes, tilepool_routes from .config import Config, LocalDiskConfig @@ -13,6 +13,7 @@ def create_app(config: type[Config] = LocalDiskConfig) -> Flask: app = Flask(__name__) app.config.from_object(config) + auth_routes.cognito_app(app) @app.route("/") def index(): @@ -24,6 +25,7 @@ def tilesets(): app.register_blueprint(tilepool_routes.bp) app.register_blueprint(image_routes.bp) + app.register_blueprint(auth_routes.bp) @app.route("/bingocard/") def generate_card(tilepoolId: str): diff --git a/src/app/auth_routes.py b/src/app/auth_routes.py new file mode 100644 index 0000000..b72b6a1 --- /dev/null +++ b/src/app/auth_routes.py @@ -0,0 +1,43 @@ +from flask import Blueprint, Flask, redirect +from flask_cognito_lib import CognitoAuth +from flask_cognito_lib.decorators import ( + cognito_login, + cognito_login_callback, + cognito_logout, + cognito_refresh_callback, +) + +bp = Blueprint("auth", __name__) + + +def cognito_app(app: Flask): + return CognitoAuth(app) + + +@bp.get("/login") +@cognito_login +def login(): + pass + + +@bp.get("/postlogin") +@cognito_login_callback +def post_login(): + return redirect("/") + + +@bp.get("/logout") +@cognito_logout +def logout(): + return "Logged out" + + +@bp.get("/postlogout") +def post_logout(): + return "Logged out" + + +@bp.get("/refresh") +@cognito_refresh_callback +def refresh(): + return "Refreshed" diff --git a/src/app/config.py b/src/app/config.py index 2e9e4f7..85ee2e5 100644 --- a/src/app/config.py +++ b/src/app/config.py @@ -1,4 +1,5 @@ import os +import boto3 from data import DynamoTilePoolDB, FileTilePoolDB, MemoryTilePoolDB from images import ( @@ -12,6 +13,7 @@ class Config: TESTING = False DEBUG = False + SECRET_KEY = "07c56596b48f48b3a749a6969e64fadc" @property def DB(self): @@ -71,6 +73,14 @@ def IMAGES(self): class CloudAWSConfig(Config): + AWS_REGION = "us-east-1" + AWS_COGNITO_DOMAIN = "https://bingomaker.auth.us-east-1.amazoncognito.com" + AWS_COGNITO_REDIRECT_URL = "http://localhost:8080/postlogin" + AWS_COGNITO_LOGOUT_URL = "http://localhost:8080/postlogout" + AWS_COGNITO_REFRESH_FLOW_ENABLED = True + AWS_COGNITO_REFRESH_COOKIE_ENCRYPTED = True + AWS_COGNITO_REFRESH_COOKIE_AGE_SECONDS = 86400 + @property def DB(self): return DynamoTilePoolDB() @@ -78,3 +88,21 @@ def DB(self): @property def IMAGES(self): return S3ImageManager(os.environ["S3_BUCKET_NAME"], LocalReferenceCounts("counts")) + + @property + def AWS_COGNITO_USER_POOL_CLIENT_SECRET(self): + client = boto3.client('secretsmanager') + + return client.get_secret_value(SecretId='CognitoUserPoolClientSecret')['SecretString'] + + @property + def AWS_COGNITO_USER_POOL_CLIENT_ID(self): + client = boto3.client('secretsmanager') + + return client.get_secret_value(SecretId='CognitoUserPoolClientId')['SecretString'] + + @property + def AWS_COGNITO_USER_POOL_ID(self): + client = boto3.client('secretsmanager') + + return client.get_secret_value(SecretId='CognitoUserPoolId')['SecretString'] \ No newline at end of file From b9c7fe251a62660172f1d0811195739710a91b39 Mon Sep 17 00:00:00 2001 From: Owen Halliday Date: Thu, 21 Nov 2024 12:29:35 -0500 Subject: [PATCH 03/14] linting fix --- src/app/config.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app/config.py b/src/app/config.py index 85ee2e5..706452b 100644 --- a/src/app/config.py +++ b/src/app/config.py @@ -1,4 +1,5 @@ import os + import boto3 from data import DynamoTilePoolDB, FileTilePoolDB, MemoryTilePoolDB From 29ab2c7fd05513a390c037aa24f14ebfe50f052b Mon Sep 17 00:00:00 2001 From: Owen Halliday Date: Thu, 21 Nov 2024 13:23:19 -0500 Subject: [PATCH 04/14] add deploy and destroy scripts --- deploy/deploy.sh | 117 ++++++++++++++++++++++++++++++++++++++++++++++ deploy/destroy.sh | 86 ++++++++++++++++++++++++++++++++++ 2 files changed, 203 insertions(+) create mode 100755 deploy/deploy.sh create mode 100755 deploy/destroy.sh diff --git a/deploy/deploy.sh b/deploy/deploy.sh new file mode 100755 index 0000000..964e5d1 --- /dev/null +++ b/deploy/deploy.sh @@ -0,0 +1,117 @@ +#! /usr/bin/env bash + +# This script deploys all the components of the BingoMaker App in AWS. +export PAGER=cat + +S3_BUCKET_NAME="cs399-bingo-maker-app" +AWS_REGION="us-east-1" +COGNITO_DOMAIN_PREFIX="bingo-maker-cs399" +DYNAMODB_TABLE_NAME="BingoMaker" +COGNITO_POOL_NAME="BingoMaker" + + +#list all vpcs and select the first one +VPC_ID=$(aws ec2 describe-vpcs --query "Vpcs[0].VpcId" --output text) + +echo "VPC ID: $VPC_ID" + +echo -n "Security Group ID: " +# check if security group exists, if not create it +if aws ec2 describe-security-groups --filters Name=tag:purpose,Values=bingo-maker --query "SecurityGroups[0].GroupId" --output text | grep -q "None"; then + aws ec2 create-security-group --group-name "bingo-maker-ec2" --description "Allow http(s), ssh, and database access" \ + --vpc-id $VPC_ID \ + --query "GroupId" --output text \ + --tag-specifications '{"ResourceType":"security-group","Tags":[{"Key":"purpose","Value":"bingo-maker"},{"Key":"lifespan","Value":"indeterminate"}]}' +fi + +SECURITY_GROUP_ID=$(aws ec2 describe-security-groups --filters Name=tag:purpose,Values=bingo-maker --query "SecurityGroups[0].GroupId" --output text) + + +if ! aws ec2 authorize-security-group-ingress --group-id $SECURITY_GROUP_ID \ + --ip-permissions '{"FromPort":22,"ToPort":22,"IpProtocol":"tcp","IpRanges":[{"CidrIp":"0.0.0.0/0"}]}' '{"FromPort":80,"ToPort":80,"IpProtocol":"tcp","IpRanges":[{"CidrIp":"0.0.0.0/0"}]}' '{"FromPort":443,"ToPort":443,"IpProtocol":"tcp","IpRanges":[{"CidrIp":"0.0.0.0/0"}]}' | grep -q "already exists"; then + echo "Successfully added ingress rules to security group" +else + echo "ingress rules already exist" +fi +# allow access to port 22 (ssh), 80 (http), and 443 (https) + + +# create the ec2 instance +echo "Creating EC2 instance..." +INSTANCE_ID=$(aws ec2 run-instances --image-id "ami-06b21ccaeff8cd686" --instance-type "t2.micro" \ + --key-name "vockey" --network-interfaces "[{\"AssociatePublicIpAddress\":true,\"DeviceIndex\":0,\"Groups\":[\"$SECURITY_GROUP_ID\"]}]" \ + --tag-specifications '{"ResourceType":"instance","Tags":[{"Key":"Name","Value":"bingo-maker"}]}' \ + --private-dns-name-options '{"HostnameType":"ip-name","EnableResourceNameDnsARecord":true,"EnableResourceNameDnsAAAARecord":false}' \ + --user-data file://deploy/userdata.sh \ + --count "1" \ + --query "Instances[*].InstanceId" \ + --output text +) + +echo "EC2 instance created with ID: $INSTANCE_ID" + +INSTANCE_IP_ADDR=$(aws ec2 describe-instances --instance-ids $INSTANCE_ID --query 'Reservations[*].Instances[*].PublicIpAddress' --output text) + + + + +# make a DynamoDB table for the BingoMaker App +# if the table already exists, it will be skipped +aws dynamodb create-table --table-name $DYNAMODB_TABLE_NAME --attribute-definitions AttributeName=id,AttributeType=S --key-schema AttributeName=id,KeyType=HASH --provisioned-throughput ReadCapacityUnits=1,WriteCapacityUnits=1 --region $AWS_REGION > /dev/null + + +# create an S3 Bucket for the BingoMaker App + +aws s3api create-bucket --bucket $S3_BUCKET_NAME --region $AWS_REGION > /dev/null + +# create cognito +echo "Creating Cognito User Pool..." +USER_POOL_ID=$(aws cognito-idp create-user-pool \ + --region $AWS_REGION \ + --pool-name $COGNITO_POOL_NAME \ + --policies 'PasswordPolicy={MinimumLength=8,RequireUppercase=true,RequireLowercase=true,RequireNumbers=true,RequireSymbols=true}' \ + --auto-verified-attributes email \ + --schema '[ + {"Name":"email","AttributeDataType":"String","DeveloperOnlyAttribute":false,"Mutable":true,"Required":true}, + {"Name":"name","AttributeDataType":"String","DeveloperOnlyAttribute":false,"Mutable":true,"Required":false} + ]' \ + --alias-attributes email \ + --admin-create-user-config AllowAdminCreateUserOnly=false \ + --query 'UserPool.Id' --output text) + +echo "Creating Cognito User Pool Domain..." +aws cognito-idp create-user-pool-domain \ + --domain $COGNITO_DOMAIN_PREFIX \ + --user-pool-id $USER_POOL_ID \ + --region $AWS_REGION + + +AWS_COGNITO_REDIRECT_URL=https://bingo.drek.cloud/postlogin + +echo "Updating Cognito User Pool Client..." +OUTPUT=$(aws cognito-idp create-user-pool-client \ + --user-pool-id $USER_POOL_ID \ + --region $AWS_REGION \ + --client-name flask \ + --allowed-o-auth-flows implicit \ + --allowed-o-auth-scopes openid email profile \ + --supported-identity-providers COGNITO \ + --callback-urls $AWS_COGNITO_REDIRECT_URL \ + --generate-secret +) + +AWS_COGNITO_USER_POOL_CLIENT_ID=$(echo $OUTPUT | jq -r '.UserPoolClient.ClientId') +AWS_COGNITO_USER_POOL_CLIENT_SECRET=$(echo $OUTPUT | jq -r '.UserPoolClient.ClientSecret') + +echo "AWS_COGNITO_USER_POOL_CLIENT_ID: $AWS_COGNITO_USER_POOL_CLIENT_ID" +echo "AWS_COGNITO_USER_POOL_CLIENT_SECRET: $AWS_COGNITO_USER_POOL_CLIENT_SECRET" +echo "AWS_COGNITO_USER_POOL_ID: $USER_POOL_ID" + +# put the user_pool_id, client_id, and client_secret in secrets manager +echo "Putting Cognito User Pool Client ID and Secret in Secrets Manager..." +aws secretsmanager create-secret --name CognitoUserPoolClientSecret --secret-string $AWS_COGNITO_USER_POOL_CLIENT_SECRET +aws secretsmanager create-secret --name CognitoUserPoolClientId --secret-string $AWS_COGNITO_USER_POOL_CLIENT_ID +aws secretsmanager create-secret --name CognitoUserPoolId --secret-string $USER_POOL_ID + + +echo "EC2 instance created with IP address: $INSTANCE_IP_ADDR" \ No newline at end of file diff --git a/deploy/destroy.sh b/deploy/destroy.sh new file mode 100755 index 0000000..b0691d0 --- /dev/null +++ b/deploy/destroy.sh @@ -0,0 +1,86 @@ +#! /usr/bin/env bash +export PAGER=cat + + +# remove all the resources created by the deploy script +S3_BUCKET_NAME="cs399-bingo-maker-app" +AWS_REGION="us-east-1" +COGNITO_DOMAIN_PREFIX="bingo-maker-cs399" +DYNAMODB_TABLE_NAME="BingoMaker" +COGNITO_POOL_NAME="BingoMaker" +#get the instance id +INSTANCE_ID=$(aws ec2 describe-instances \ + --filters "Name=tag:Name,Values=bingo-maker" "Name=instance-state-name,Values=running" \ + --query "Reservations[*].Instances[*].InstanceId" \ + --output text) + +# remove the ec2 instance +echo "Terminating EC2 instance..." +aws ec2 terminate-instances --instance-ids $INSTANCE_ID + +# remove the s3 bucket +echo "Deleting S3 Bucket..." +aws s3api delete-bucket --bucket $S3_BUCKET_NAME + +# get the userpool id + +COGNITO_USER_POOL_ID=$(aws cognito-idp list-user-pools --max-results=5 --output json | \ + jq -r --arg POOL_NAME "$COGNITO_POOL_NAME" \ + '.UserPools[] | select(.Name == $POOL_NAME) | .Id') + + +#get the cognito user pool client id +COGNITO_USER_POOL_CLIENT_ID=$(aws cognito-idp list-user-pool-clients --user-pool-id $COGNITO_USER_POOL_ID --max-results=5 --output json | \ + jq -r --arg CLIENT_NAME "flask" '.UserPoolClients[] | select(.ClientName == $CLIENT_NAME) | .ClientId') + + +# remove the cognito user pool +echo "Deleting Cognito User Pool Client..." +aws cognito-idp delete-user-pool-client --user-pool-id $COGNITO_USER_POOL_ID --client-id $COGNITO_USER_POOL_CLIENT_ID +echo "Deleting Cognito User Pool Domain..." +aws cognito-idp delete-user-pool-domain --domain $COGNITO_DOMAIN_PREFIX --user-pool-id $COGNITO_USER_POOL_ID +echo "Deleting Cognito User Pool..." +aws cognito-idp delete-user-pool --user-pool-id $COGNITO_USER_POOL_ID + + +# remove the dynamodb table +echo "Deleting DynamoDB Table..." +aws dynamodb delete-table --table-name $DYNAMODB_TABLE_NAME + + + +# If INSTANCE_ID is empty, print a message and skip the loop +if [ -z "$INSTANCE_ID" ]; then + echo "No running EC2 instance found with the tag 'Name=bingo-maker'." +else + echo "Found running EC2 instance with ID: $INSTANCE_ID" + + echo "Waiting for the EC2 instance to terminate..." + while true; do + # Get the current state of the instance + INSTANCE_STATE=$(aws ec2 describe-instances --instance-ids "$INSTANCE_ID" --query "Reservations[0].Instances[0].State.Name" --output text) + + echo "Current state: $INSTANCE_STATE" + + # Check if the instance is terminated + if [ "$INSTANCE_STATE" == "terminated" ]; then + echo "EC2 instance has been terminated." + break + fi + + # Wait for 5 seconds before checking again + sleep 5 + done +fi +# get the security group id +SECURITY_GROUP_ID=$(aws ec2 describe-security-groups --filters Name=tag:purpose,Values=bingo-maker --query "SecurityGroups[0].GroupId" --output text) +echo "Deleting Security Group..." +# remove the security group +aws ec2 delete-security-group --group-id $SECURITY_GROUP_ID + + +# remove the secrets in secrets manager +echo "Deleting Secrets Manager Secrets..." +aws secretsmanager delete-secret --force-delete-without-recovery --secret-id CognitoUserPoolClientSecret +aws secretsmanager delete-secret --force-delete-without-recovery --secret-id CognitoUserPoolClientId +aws secretsmanager delete-secret --force-delete-without-recovery --secret-id CognitoUserPoolId \ No newline at end of file From dda82940cf41c80b258636d2cad023905b13ca78 Mon Sep 17 00:00:00 2001 From: Owen Halliday Date: Thu, 21 Nov 2024 16:03:40 -0500 Subject: [PATCH 05/14] remove property decorators --- src/app/config.py | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/src/app/config.py b/src/app/config.py index 706452b..00208e3 100644 --- a/src/app/config.py +++ b/src/app/config.py @@ -75,12 +75,22 @@ def IMAGES(self): class CloudAWSConfig(Config): AWS_REGION = "us-east-1" + _client = boto3.client("secretsmanager", region_name=AWS_REGION) AWS_COGNITO_DOMAIN = "https://bingomaker.auth.us-east-1.amazoncognito.com" - AWS_COGNITO_REDIRECT_URL = "http://localhost:8080/postlogin" - AWS_COGNITO_LOGOUT_URL = "http://localhost:8080/postlogout" + AWS_COGNITO_REDIRECT_URL = "https://bingo.drek.cloud/postlogin" + AWS_COGNITO_LOGOUT_URL = "https://bingo.drek.cloud/postlogout" AWS_COGNITO_REFRESH_FLOW_ENABLED = True AWS_COGNITO_REFRESH_COOKIE_ENCRYPTED = True AWS_COGNITO_REFRESH_COOKIE_AGE_SECONDS = 86400 + AWS_COGNITO_USER_POOL_CLIENT_SECRET = _client.get_secret_value( + SecretId="CognitoUserPoolClientSecret" + )["SecretString"] + AWS_COGNITO_USER_POOL_CLIENT_ID = _client.get_secret_value(SecretId="CognitoUserPoolClientId")[ + "SecretString" + ] + AWS_COGNITO_USER_POOL_ID = _client.get_secret_value(SecretId="CognitoUserPoolId")[ + "SecretString" + ] @property def DB(self): @@ -89,21 +99,3 @@ def DB(self): @property def IMAGES(self): return S3ImageManager(os.environ["S3_BUCKET_NAME"], LocalReferenceCounts("counts")) - - @property - def AWS_COGNITO_USER_POOL_CLIENT_SECRET(self): - client = boto3.client('secretsmanager') - - return client.get_secret_value(SecretId='CognitoUserPoolClientSecret')['SecretString'] - - @property - def AWS_COGNITO_USER_POOL_CLIENT_ID(self): - client = boto3.client('secretsmanager') - - return client.get_secret_value(SecretId='CognitoUserPoolClientId')['SecretString'] - - @property - def AWS_COGNITO_USER_POOL_ID(self): - client = boto3.client('secretsmanager') - - return client.get_secret_value(SecretId='CognitoUserPoolId')['SecretString'] \ No newline at end of file From bb00301cfa2a379c4957ce4dfa358f1b7d44f6c1 Mon Sep 17 00:00:00 2001 From: Owen Halliday Date: Thu, 21 Nov 2024 23:06:11 -0500 Subject: [PATCH 06/14] mangle cognito config --- src/app/app.py | 3 ++- src/app/auth_routes.py | 12 ++++++++++++ src/app/config.py | 12 ------------ tests/test_app.py | 2 +- 4 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/app/app.py b/src/app/app.py index a1b7011..9f82577 100644 --- a/src/app/app.py +++ b/src/app/app.py @@ -9,10 +9,11 @@ from .config import Config, LocalDiskConfig -def create_app(config: type[Config] = LocalDiskConfig) -> Flask: +def create_app(config: type[Config] = LocalDiskConfig, TESTING: bool = False) -> Flask: app = Flask(__name__) app.config.from_object(config) + app.config["TESTING"] = TESTING auth_routes.cognito_app(app) @app.route("/") diff --git a/src/app/auth_routes.py b/src/app/auth_routes.py index b72b6a1..c477d4d 100644 --- a/src/app/auth_routes.py +++ b/src/app/auth_routes.py @@ -1,3 +1,4 @@ +import boto3 from flask import Blueprint, Flask, redirect from flask_cognito_lib import CognitoAuth from flask_cognito_lib.decorators import ( @@ -11,6 +12,17 @@ def cognito_app(app: Flask): + if not app.config["TESTING"]: + _client = boto3.client("secretsmanager", region_name=app.config["AWS_REGION"]) + app.config["AWS_COGNITO_USER_POOL_CLIENT_SECRET"] = _client.get_secret_value( + SecretId="CognitoUserPoolClientSecret" + )["SecretString"] + app.config["AWS_COGNITO_USER_POOL_CLIENT_ID"] = _client.get_secret_value( + SecretId="CognitoUserPoolClientId" + )["SecretString"] + app.config["AWS_COGNITO_USER_POOL_ID"] = _client.get_secret_value( + SecretId="CognitoUserPoolId" + )["SecretString"] return CognitoAuth(app) diff --git a/src/app/config.py b/src/app/config.py index 00208e3..e8568f6 100644 --- a/src/app/config.py +++ b/src/app/config.py @@ -1,7 +1,5 @@ import os -import boto3 - from data import DynamoTilePoolDB, FileTilePoolDB, MemoryTilePoolDB from images import ( LocalImageManager, @@ -75,22 +73,12 @@ def IMAGES(self): class CloudAWSConfig(Config): AWS_REGION = "us-east-1" - _client = boto3.client("secretsmanager", region_name=AWS_REGION) AWS_COGNITO_DOMAIN = "https://bingomaker.auth.us-east-1.amazoncognito.com" AWS_COGNITO_REDIRECT_URL = "https://bingo.drek.cloud/postlogin" AWS_COGNITO_LOGOUT_URL = "https://bingo.drek.cloud/postlogout" AWS_COGNITO_REFRESH_FLOW_ENABLED = True AWS_COGNITO_REFRESH_COOKIE_ENCRYPTED = True AWS_COGNITO_REFRESH_COOKIE_AGE_SECONDS = 86400 - AWS_COGNITO_USER_POOL_CLIENT_SECRET = _client.get_secret_value( - SecretId="CognitoUserPoolClientSecret" - )["SecretString"] - AWS_COGNITO_USER_POOL_CLIENT_ID = _client.get_secret_value(SecretId="CognitoUserPoolClientId")[ - "SecretString" - ] - AWS_COGNITO_USER_POOL_ID = _client.get_secret_value(SecretId="CognitoUserPoolId")[ - "SecretString" - ] @property def DB(self): diff --git a/tests/test_app.py b/tests/test_app.py index 6a6e749..c85309b 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -102,7 +102,7 @@ def db_data(db: MemoryTilePoolDB): @pytest.fixture def app(db_data: TilePoolDB, image_manager: ImageManager): - app = create_app() + app = create_app(TESTING=True) app.config.update(TESTING=True, DB=db_data, IMAGES=image_manager) return app From 673efb2d5103cb55e278065c0e626529fd709e1b Mon Sep 17 00:00:00 2001 From: Owen Halliday Date: Thu, 21 Nov 2024 23:08:40 -0500 Subject: [PATCH 07/14] add more cognito parameters --- deploy/deploy.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/deploy/deploy.sh b/deploy/deploy.sh index 964e5d1..d916077 100755 --- a/deploy/deploy.sh +++ b/deploy/deploy.sh @@ -44,10 +44,14 @@ INSTANCE_ID=$(aws ec2 run-instances --image-id "ami-06b21ccaeff8cd686" --instanc --private-dns-name-options '{"HostnameType":"ip-name","EnableResourceNameDnsARecord":true,"EnableResourceNameDnsAAAARecord":false}' \ --user-data file://deploy/userdata.sh \ --count "1" \ + --iam-instance-profile '{"Arn": "arn:aws:iam::620401114971:instance-profile/LabInstanceProfile" }' \ --query "Instances[*].InstanceId" \ --output text ) +# echo "Associating IAM Instance Profile..." +# aws ec2 associate-iam-instance-profile --instance-id $INSTANCE_ID --iam-instance-profile '{"Name": "LabRole" }' + echo "EC2 instance created with ID: $INSTANCE_ID" INSTANCE_IP_ADDR=$(aws ec2 describe-instances --instance-ids $INSTANCE_ID --query 'Reservations[*].Instances[*].PublicIpAddress' --output text) @@ -76,6 +80,7 @@ USER_POOL_ID=$(aws cognito-idp create-user-pool \ {"Name":"name","AttributeDataType":"String","DeveloperOnlyAttribute":false,"Mutable":true,"Required":false} ]' \ --alias-attributes email \ + --username-configuration "CaseSensitive=false" \ --admin-create-user-config AllowAdminCreateUserOnly=false \ --query 'UserPool.Id' --output text) @@ -96,6 +101,13 @@ OUTPUT=$(aws cognito-idp create-user-pool-client \ --allowed-o-auth-flows implicit \ --allowed-o-auth-scopes openid email profile \ --supported-identity-providers COGNITO \ + --token-validity-units AccessToken=minutes,IdToken=minutes,RefreshToken=days \ + --read-attributes email name \ + --write-attributes email name \ + --prevent-user-existence-errors ENABLED \ + --explicit-auth-flows ALLOW_REFRESH_TOKEN_AUTH ALLOW_USER_SRP_AUTH \ + --allowed-o-auth-flows code \ + --allowed-o-auth-flows-user-pool-client \ --callback-urls $AWS_COGNITO_REDIRECT_URL \ --generate-secret ) From 106d0f7d7b388476fab5eb48e750d7259f2f23f2 Mon Sep 17 00:00:00 2001 From: Owen Halliday Date: Thu, 21 Nov 2024 23:09:30 -0500 Subject: [PATCH 08/14] move cognito params to base class --- src/app/config.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/app/config.py b/src/app/config.py index e8568f6..8d82074 100644 --- a/src/app/config.py +++ b/src/app/config.py @@ -13,6 +13,13 @@ class Config: TESTING = False DEBUG = False SECRET_KEY = "07c56596b48f48b3a749a6969e64fadc" + AWS_REGION = "us-east-1" + AWS_COGNITO_DOMAIN = "https://bingomaker.auth.us-east-1.amazoncognito.com" + AWS_COGNITO_REDIRECT_URL = "https://bingo.drek.cloud/postlogin" + AWS_COGNITO_LOGOUT_URL = "https://bingo.drek.cloud/postlogout" + AWS_COGNITO_REFRESH_FLOW_ENABLED = True + AWS_COGNITO_REFRESH_COOKIE_ENCRYPTED = True + AWS_COGNITO_REFRESH_COOKIE_AGE_SECONDS = 86400 @property def DB(self): @@ -72,13 +79,6 @@ def IMAGES(self): class CloudAWSConfig(Config): - AWS_REGION = "us-east-1" - AWS_COGNITO_DOMAIN = "https://bingomaker.auth.us-east-1.amazoncognito.com" - AWS_COGNITO_REDIRECT_URL = "https://bingo.drek.cloud/postlogin" - AWS_COGNITO_LOGOUT_URL = "https://bingo.drek.cloud/postlogout" - AWS_COGNITO_REFRESH_FLOW_ENABLED = True - AWS_COGNITO_REFRESH_COOKIE_ENCRYPTED = True - AWS_COGNITO_REFRESH_COOKIE_AGE_SECONDS = 86400 @property def DB(self): From b137cf19ab870141da07e3f0411007bc3743020f Mon Sep 17 00:00:00 2001 From: JP Appel Date: Thu, 21 Nov 2024 23:17:03 -0500 Subject: [PATCH 09/14] Add app factory for aws config --- src/app/app.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/app/app.py b/src/app/app.py index 9f82577..78dd057 100644 --- a/src/app/app.py +++ b/src/app/app.py @@ -6,7 +6,11 @@ from game.game import Board from . import auth_routes, image_routes, tilepool_routes -from .config import Config, LocalDiskConfig +from .config import CloudAWSConfig, Config, LocalDiskConfig + + +def aws_create_app() -> Flask: + return create_app(CloudAWSConfig) def create_app(config: type[Config] = LocalDiskConfig, TESTING: bool = False) -> Flask: From a39c0cba4ff207cb0d1be2182a27bd906e1ca1a9 Mon Sep 17 00:00:00 2001 From: Owen Halliday Date: Thu, 21 Nov 2024 23:58:03 -0500 Subject: [PATCH 10/14] add aws create app --- Makefile | 2 +- src/app/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 08d44b3..73069c0 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,7 @@ deploy: --workers $(DEPLOY_WORKERS) \ --log-syslog \ -p /tmp/BingoMaker.pid -n $(DEPLOY_NAME) \ - "app:create_app()" + "app:aws_create_app()" test: @uv run pytest -m "not localstack" diff --git a/src/app/__init__.py b/src/app/__init__.py index f841c05..8455dcf 100644 --- a/src/app/__init__.py +++ b/src/app/__init__.py @@ -1,4 +1,4 @@ -from .app import create_app +from .app import aws_create_app, create_app # noqa: F401 if __name__ == "__main__": create_app().run(port=8080) From 867781d633cc2c29f4a5965d996778e0575383a7 Mon Sep 17 00:00:00 2001 From: JP Appel Date: Fri, 22 Nov 2024 08:28:14 -0500 Subject: [PATCH 11/14] Fix config classes --- src/app/app.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/app/app.py b/src/app/app.py index 78dd057..728f92f 100644 --- a/src/app/app.py +++ b/src/app/app.py @@ -13,9 +13,10 @@ def aws_create_app() -> Flask: return create_app(CloudAWSConfig) -def create_app(config: type[Config] = LocalDiskConfig, TESTING: bool = False) -> Flask: +def create_app(config_class: type[Config] = LocalDiskConfig, TESTING: bool = False) -> Flask: app = Flask(__name__) + config = config_class() app.config.from_object(config) app.config["TESTING"] = TESTING auth_routes.cognito_app(app) @@ -23,7 +24,7 @@ def create_app(config: type[Config] = LocalDiskConfig, TESTING: bool = False) -> @app.route("/") def index(): return render_template("index.html") - + @app.route("/tilesets") def tilesets(): return render_template("tilesets.html") @@ -58,4 +59,5 @@ def generate_card(tilepoolId: str): "grid": [tile_to_dict(tile) for row in board.board for tile in row], } - return app \ No newline at end of file + return app + From 106414d41951f761ed5c200d2bfd83f3e14cb244 Mon Sep 17 00:00:00 2001 From: JP Appel Date: Fri, 22 Nov 2024 10:01:59 -0500 Subject: [PATCH 12/14] Change lazy evaluation of CloudAWSConfig --- src/app/app.py | 4 +--- src/app/auth_routes.py | 11 --------- src/app/config.py | 54 +++++++++++++++++++++++++++++++++++++++--- 3 files changed, 52 insertions(+), 17 deletions(-) diff --git a/src/app/app.py b/src/app/app.py index 728f92f..6205aac 100644 --- a/src/app/app.py +++ b/src/app/app.py @@ -16,8 +16,7 @@ def aws_create_app() -> Flask: def create_app(config_class: type[Config] = LocalDiskConfig, TESTING: bool = False) -> Flask: app = Flask(__name__) - config = config_class() - app.config.from_object(config) + app.config.from_object(config_class()) app.config["TESTING"] = TESTING auth_routes.cognito_app(app) @@ -60,4 +59,3 @@ def generate_card(tilepoolId: str): } return app - diff --git a/src/app/auth_routes.py b/src/app/auth_routes.py index c477d4d..82bfc08 100644 --- a/src/app/auth_routes.py +++ b/src/app/auth_routes.py @@ -12,17 +12,6 @@ def cognito_app(app: Flask): - if not app.config["TESTING"]: - _client = boto3.client("secretsmanager", region_name=app.config["AWS_REGION"]) - app.config["AWS_COGNITO_USER_POOL_CLIENT_SECRET"] = _client.get_secret_value( - SecretId="CognitoUserPoolClientSecret" - )["SecretString"] - app.config["AWS_COGNITO_USER_POOL_CLIENT_ID"] = _client.get_secret_value( - SecretId="CognitoUserPoolClientId" - )["SecretString"] - app.config["AWS_COGNITO_USER_POOL_ID"] = _client.get_secret_value( - SecretId="CognitoUserPoolId" - )["SecretString"] return CognitoAuth(app) diff --git a/src/app/config.py b/src/app/config.py index 8d82074..d2f481c 100644 --- a/src/app/config.py +++ b/src/app/config.py @@ -1,4 +1,4 @@ -import os +import boto3 from data import DynamoTilePoolDB, FileTilePoolDB, MemoryTilePoolDB from images import ( @@ -79,11 +79,59 @@ def IMAGES(self): class CloudAWSConfig(Config): + def __init__(self): + self.client = boto3.client("secretsmanager", region_name=self.AWS_REGION) + self._DB = None + self._IMAGES = None + self._AWS_COGNITO_USER_POOL_CLIENT_SECRET = "" + self._AWS_COGNITO_USER_POOL_CLIENT_ID = "" + self._AWS_COGNITO_USER_POOL_ID = "" + self._S3_BUCKET_NAME = "" @property def DB(self): - return DynamoTilePoolDB() + if self._DB is None: + self._DB = DynamoTilePoolDB() + return self._DB + + @property + def S3_BUCKET_NAME(self) -> str: + if not self._S3_BUCKET_NAME: + self._S3_BUCKET_NAME = self.client.get_secret_value(SecretId="S3BucketName")[ + "SecretString" + ] + + return self._S3_BUCKET_NAME @property def IMAGES(self): - return S3ImageManager(os.environ["S3_BUCKET_NAME"], LocalReferenceCounts("counts")) + if self._IMAGES is None: + self._IMAGES = S3ImageManager(self.S3_BUCKET_NAME, LocalReferenceCounts("counts")) + return self._IMAGES + + @property + def AWS_COGNITO_USER_POOL_CLIENT_SECRET(self): + if not self._AWS_COGNITO_USER_POOL_CLIENT_SECRET: + self._AWS_COGNITO_USER_POOL_CLIENT_SECRET = self.client.get_secret_value( + SecretId="CognitoUserPoolClientSecret" + )["SecretString"] + + return self._AWS_COGNITO_USER_POOL_CLIENT_SECRET + + @property + def AWS_COGNITO_USER_POOL_CLIENT_ID(self): + if not self._AWS_COGNITO_USER_POOL_CLIENT_ID: + self._AWS_COGNITO_USER_POOL_CLIENT_ID = self.client.get_secret_value( + SecretId="CognitoUserPoolClientId" + )["SecretString"] + + return self._AWS_COGNITO_USER_POOL_CLIENT_ID + + @property + def AWS_COGNITO_USER_POOL_ID(self): + if not self._AWS_COGNITO_USER_POOL_ID: + self._AWS_COGNITO_USER_POOL_ID = self.client.get_secret_value( + SecretId="CognitoUserPoolId" + )["SecretString"] + + return self._AWS_COGNITO_USER_POOL_ID From 0311e63937ff63e2a5bc57474147ba916e38178c Mon Sep 17 00:00:00 2001 From: JP Appel Date: Fri, 22 Nov 2024 10:03:53 -0500 Subject: [PATCH 13/14] Fix linter error --- src/app/auth_routes.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/app/auth_routes.py b/src/app/auth_routes.py index 82bfc08..b72b6a1 100644 --- a/src/app/auth_routes.py +++ b/src/app/auth_routes.py @@ -1,4 +1,3 @@ -import boto3 from flask import Blueprint, Flask, redirect from flask_cognito_lib import CognitoAuth from flask_cognito_lib.decorators import ( From 5021afa2c816275955019cddd30358f02b0b1bc6 Mon Sep 17 00:00:00 2001 From: Owen Halliday Date: Sun, 24 Nov 2024 21:29:04 -0500 Subject: [PATCH 14/14] removed deploy scripts --- deploy/deploy.sh | 129 ---------------------------------------------- deploy/destroy.sh | 86 ------------------------------- 2 files changed, 215 deletions(-) delete mode 100755 deploy/deploy.sh delete mode 100755 deploy/destroy.sh diff --git a/deploy/deploy.sh b/deploy/deploy.sh deleted file mode 100755 index d916077..0000000 --- a/deploy/deploy.sh +++ /dev/null @@ -1,129 +0,0 @@ -#! /usr/bin/env bash - -# This script deploys all the components of the BingoMaker App in AWS. -export PAGER=cat - -S3_BUCKET_NAME="cs399-bingo-maker-app" -AWS_REGION="us-east-1" -COGNITO_DOMAIN_PREFIX="bingo-maker-cs399" -DYNAMODB_TABLE_NAME="BingoMaker" -COGNITO_POOL_NAME="BingoMaker" - - -#list all vpcs and select the first one -VPC_ID=$(aws ec2 describe-vpcs --query "Vpcs[0].VpcId" --output text) - -echo "VPC ID: $VPC_ID" - -echo -n "Security Group ID: " -# check if security group exists, if not create it -if aws ec2 describe-security-groups --filters Name=tag:purpose,Values=bingo-maker --query "SecurityGroups[0].GroupId" --output text | grep -q "None"; then - aws ec2 create-security-group --group-name "bingo-maker-ec2" --description "Allow http(s), ssh, and database access" \ - --vpc-id $VPC_ID \ - --query "GroupId" --output text \ - --tag-specifications '{"ResourceType":"security-group","Tags":[{"Key":"purpose","Value":"bingo-maker"},{"Key":"lifespan","Value":"indeterminate"}]}' -fi - -SECURITY_GROUP_ID=$(aws ec2 describe-security-groups --filters Name=tag:purpose,Values=bingo-maker --query "SecurityGroups[0].GroupId" --output text) - - -if ! aws ec2 authorize-security-group-ingress --group-id $SECURITY_GROUP_ID \ - --ip-permissions '{"FromPort":22,"ToPort":22,"IpProtocol":"tcp","IpRanges":[{"CidrIp":"0.0.0.0/0"}]}' '{"FromPort":80,"ToPort":80,"IpProtocol":"tcp","IpRanges":[{"CidrIp":"0.0.0.0/0"}]}' '{"FromPort":443,"ToPort":443,"IpProtocol":"tcp","IpRanges":[{"CidrIp":"0.0.0.0/0"}]}' | grep -q "already exists"; then - echo "Successfully added ingress rules to security group" -else - echo "ingress rules already exist" -fi -# allow access to port 22 (ssh), 80 (http), and 443 (https) - - -# create the ec2 instance -echo "Creating EC2 instance..." -INSTANCE_ID=$(aws ec2 run-instances --image-id "ami-06b21ccaeff8cd686" --instance-type "t2.micro" \ - --key-name "vockey" --network-interfaces "[{\"AssociatePublicIpAddress\":true,\"DeviceIndex\":0,\"Groups\":[\"$SECURITY_GROUP_ID\"]}]" \ - --tag-specifications '{"ResourceType":"instance","Tags":[{"Key":"Name","Value":"bingo-maker"}]}' \ - --private-dns-name-options '{"HostnameType":"ip-name","EnableResourceNameDnsARecord":true,"EnableResourceNameDnsAAAARecord":false}' \ - --user-data file://deploy/userdata.sh \ - --count "1" \ - --iam-instance-profile '{"Arn": "arn:aws:iam::620401114971:instance-profile/LabInstanceProfile" }' \ - --query "Instances[*].InstanceId" \ - --output text -) - -# echo "Associating IAM Instance Profile..." -# aws ec2 associate-iam-instance-profile --instance-id $INSTANCE_ID --iam-instance-profile '{"Name": "LabRole" }' - -echo "EC2 instance created with ID: $INSTANCE_ID" - -INSTANCE_IP_ADDR=$(aws ec2 describe-instances --instance-ids $INSTANCE_ID --query 'Reservations[*].Instances[*].PublicIpAddress' --output text) - - - - -# make a DynamoDB table for the BingoMaker App -# if the table already exists, it will be skipped -aws dynamodb create-table --table-name $DYNAMODB_TABLE_NAME --attribute-definitions AttributeName=id,AttributeType=S --key-schema AttributeName=id,KeyType=HASH --provisioned-throughput ReadCapacityUnits=1,WriteCapacityUnits=1 --region $AWS_REGION > /dev/null - - -# create an S3 Bucket for the BingoMaker App - -aws s3api create-bucket --bucket $S3_BUCKET_NAME --region $AWS_REGION > /dev/null - -# create cognito -echo "Creating Cognito User Pool..." -USER_POOL_ID=$(aws cognito-idp create-user-pool \ - --region $AWS_REGION \ - --pool-name $COGNITO_POOL_NAME \ - --policies 'PasswordPolicy={MinimumLength=8,RequireUppercase=true,RequireLowercase=true,RequireNumbers=true,RequireSymbols=true}' \ - --auto-verified-attributes email \ - --schema '[ - {"Name":"email","AttributeDataType":"String","DeveloperOnlyAttribute":false,"Mutable":true,"Required":true}, - {"Name":"name","AttributeDataType":"String","DeveloperOnlyAttribute":false,"Mutable":true,"Required":false} - ]' \ - --alias-attributes email \ - --username-configuration "CaseSensitive=false" \ - --admin-create-user-config AllowAdminCreateUserOnly=false \ - --query 'UserPool.Id' --output text) - -echo "Creating Cognito User Pool Domain..." -aws cognito-idp create-user-pool-domain \ - --domain $COGNITO_DOMAIN_PREFIX \ - --user-pool-id $USER_POOL_ID \ - --region $AWS_REGION - - -AWS_COGNITO_REDIRECT_URL=https://bingo.drek.cloud/postlogin - -echo "Updating Cognito User Pool Client..." -OUTPUT=$(aws cognito-idp create-user-pool-client \ - --user-pool-id $USER_POOL_ID \ - --region $AWS_REGION \ - --client-name flask \ - --allowed-o-auth-flows implicit \ - --allowed-o-auth-scopes openid email profile \ - --supported-identity-providers COGNITO \ - --token-validity-units AccessToken=minutes,IdToken=minutes,RefreshToken=days \ - --read-attributes email name \ - --write-attributes email name \ - --prevent-user-existence-errors ENABLED \ - --explicit-auth-flows ALLOW_REFRESH_TOKEN_AUTH ALLOW_USER_SRP_AUTH \ - --allowed-o-auth-flows code \ - --allowed-o-auth-flows-user-pool-client \ - --callback-urls $AWS_COGNITO_REDIRECT_URL \ - --generate-secret -) - -AWS_COGNITO_USER_POOL_CLIENT_ID=$(echo $OUTPUT | jq -r '.UserPoolClient.ClientId') -AWS_COGNITO_USER_POOL_CLIENT_SECRET=$(echo $OUTPUT | jq -r '.UserPoolClient.ClientSecret') - -echo "AWS_COGNITO_USER_POOL_CLIENT_ID: $AWS_COGNITO_USER_POOL_CLIENT_ID" -echo "AWS_COGNITO_USER_POOL_CLIENT_SECRET: $AWS_COGNITO_USER_POOL_CLIENT_SECRET" -echo "AWS_COGNITO_USER_POOL_ID: $USER_POOL_ID" - -# put the user_pool_id, client_id, and client_secret in secrets manager -echo "Putting Cognito User Pool Client ID and Secret in Secrets Manager..." -aws secretsmanager create-secret --name CognitoUserPoolClientSecret --secret-string $AWS_COGNITO_USER_POOL_CLIENT_SECRET -aws secretsmanager create-secret --name CognitoUserPoolClientId --secret-string $AWS_COGNITO_USER_POOL_CLIENT_ID -aws secretsmanager create-secret --name CognitoUserPoolId --secret-string $USER_POOL_ID - - -echo "EC2 instance created with IP address: $INSTANCE_IP_ADDR" \ No newline at end of file diff --git a/deploy/destroy.sh b/deploy/destroy.sh deleted file mode 100755 index b0691d0..0000000 --- a/deploy/destroy.sh +++ /dev/null @@ -1,86 +0,0 @@ -#! /usr/bin/env bash -export PAGER=cat - - -# remove all the resources created by the deploy script -S3_BUCKET_NAME="cs399-bingo-maker-app" -AWS_REGION="us-east-1" -COGNITO_DOMAIN_PREFIX="bingo-maker-cs399" -DYNAMODB_TABLE_NAME="BingoMaker" -COGNITO_POOL_NAME="BingoMaker" -#get the instance id -INSTANCE_ID=$(aws ec2 describe-instances \ - --filters "Name=tag:Name,Values=bingo-maker" "Name=instance-state-name,Values=running" \ - --query "Reservations[*].Instances[*].InstanceId" \ - --output text) - -# remove the ec2 instance -echo "Terminating EC2 instance..." -aws ec2 terminate-instances --instance-ids $INSTANCE_ID - -# remove the s3 bucket -echo "Deleting S3 Bucket..." -aws s3api delete-bucket --bucket $S3_BUCKET_NAME - -# get the userpool id - -COGNITO_USER_POOL_ID=$(aws cognito-idp list-user-pools --max-results=5 --output json | \ - jq -r --arg POOL_NAME "$COGNITO_POOL_NAME" \ - '.UserPools[] | select(.Name == $POOL_NAME) | .Id') - - -#get the cognito user pool client id -COGNITO_USER_POOL_CLIENT_ID=$(aws cognito-idp list-user-pool-clients --user-pool-id $COGNITO_USER_POOL_ID --max-results=5 --output json | \ - jq -r --arg CLIENT_NAME "flask" '.UserPoolClients[] | select(.ClientName == $CLIENT_NAME) | .ClientId') - - -# remove the cognito user pool -echo "Deleting Cognito User Pool Client..." -aws cognito-idp delete-user-pool-client --user-pool-id $COGNITO_USER_POOL_ID --client-id $COGNITO_USER_POOL_CLIENT_ID -echo "Deleting Cognito User Pool Domain..." -aws cognito-idp delete-user-pool-domain --domain $COGNITO_DOMAIN_PREFIX --user-pool-id $COGNITO_USER_POOL_ID -echo "Deleting Cognito User Pool..." -aws cognito-idp delete-user-pool --user-pool-id $COGNITO_USER_POOL_ID - - -# remove the dynamodb table -echo "Deleting DynamoDB Table..." -aws dynamodb delete-table --table-name $DYNAMODB_TABLE_NAME - - - -# If INSTANCE_ID is empty, print a message and skip the loop -if [ -z "$INSTANCE_ID" ]; then - echo "No running EC2 instance found with the tag 'Name=bingo-maker'." -else - echo "Found running EC2 instance with ID: $INSTANCE_ID" - - echo "Waiting for the EC2 instance to terminate..." - while true; do - # Get the current state of the instance - INSTANCE_STATE=$(aws ec2 describe-instances --instance-ids "$INSTANCE_ID" --query "Reservations[0].Instances[0].State.Name" --output text) - - echo "Current state: $INSTANCE_STATE" - - # Check if the instance is terminated - if [ "$INSTANCE_STATE" == "terminated" ]; then - echo "EC2 instance has been terminated." - break - fi - - # Wait for 5 seconds before checking again - sleep 5 - done -fi -# get the security group id -SECURITY_GROUP_ID=$(aws ec2 describe-security-groups --filters Name=tag:purpose,Values=bingo-maker --query "SecurityGroups[0].GroupId" --output text) -echo "Deleting Security Group..." -# remove the security group -aws ec2 delete-security-group --group-id $SECURITY_GROUP_ID - - -# remove the secrets in secrets manager -echo "Deleting Secrets Manager Secrets..." -aws secretsmanager delete-secret --force-delete-without-recovery --secret-id CognitoUserPoolClientSecret -aws secretsmanager delete-secret --force-delete-without-recovery --secret-id CognitoUserPoolClientId -aws secretsmanager delete-secret --force-delete-without-recovery --secret-id CognitoUserPoolId \ No newline at end of file