diff --git a/Pipfile b/Pipfile index 9a810480c37..5d1ff352a0f 100644 --- a/Pipfile +++ b/Pipfile @@ -89,6 +89,7 @@ yarl = "*" openai = "*" spdx-tools = ">=0.8.0,<0.9.0" license-expression = "*" +pydantic = "*" [requires] python_version = "3.8" diff --git a/Pipfile.lock b/Pipfile.lock index 7691cc1b626..3557fa34db9 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "e0ea76e9bcacf1083c0a593b9f9ef0a05a5ab57c5f682fff2a026bde0ce67c44" + "sha256": "0c8a2a2091c2b988809544b7873a34b624e5152af508929c1b69ed449bd16684" }, "pipfile-spec": 6, "requires": { @@ -133,13 +133,21 @@ "markers": "python_version >= '3.7'", "version": "==1.3.1" }, + "annotated-types": { + "hashes": [ + "sha256:47cdc3490d9ac1506ce92c7aaa76c579dc3509ff11e098fc867e5130ab7be802", + "sha256:58da39888f92c276ad970249761ebea80ba544b77acddaa1a4d6cf78287d45fd" + ], + "markers": "python_version >= '3.7'", + "version": "==0.5.0" + }, "argcomplete": { "hashes": [ - "sha256:35fa893a88deea85ea7b20d241100e64516d6af6d7b0ae2bed1d263d26f70948", - "sha256:6c4c563f14f01440aaffa3eae13441c5db2357b5eec639abe7c0b15334627dff" + "sha256:d5d1e5efd41435260b8f85673b74ea2e883affcbec9f4230c582689e8e78251b", + "sha256:d97c036d12a752d1079f190bc1521c545b941fda89ad85d15afa909b4d1b9a99" ], "index": "pypi", - "version": "==3.1.1" + "version": "==3.1.2" }, "async-timeout": { "hashes": [ @@ -183,11 +191,11 @@ }, "beartype": { "hashes": [ - "sha256:231379a056da2fc1811a2e1324d5c3d0fa2082e305bfa15cb3acb9b7ce9df516", - "sha256:f0aa0f09468f732c9c4d07c024d3d69cff64cb07fd81e8ab52962e1db16ff04a" + "sha256:b3bfb911ed6af91aeada851a44b4d564c23662869b5391d71fe3648f2c643b6d", + "sha256:d86f5472e5e6ff8f643da28ff537469d57b01505ad211aee007c49c5a7de2a05" ], "markers": "python_full_version >= '3.8.0'", - "version": "==0.16.0" + "version": "==0.16.1" }, "beautifulsoup4": { "hashes": [ @@ -206,19 +214,19 @@ }, "boto3": { "hashes": [ - "sha256:519639859a3c829ccf7073a58b3716cb26cb5906e306fe63eb4beab68bf9bfab", - "sha256:c9fad1b01a1d7e7bd51150b3175b4c32b79d699ce94708082611f59fde2e097a" + "sha256:33062ab3801029ab7b2cb35b6bf4768715d13c5f9ea7d5dce22ace6219c1dc7a", + "sha256:cda98a2952cccb1db4208c53a1bba6585620fffa0ca05244827ca65884856d1f" ], "index": "pypi", - "version": "==1.28.49" + "version": "==1.28.50" }, "botocore": { "hashes": [ - "sha256:7d64cb45154e4f34f3a45f551e118caad7379ae831565639e0afe5b2af126c61", - "sha256:95e9716f27f67d4207f260ab0ea157603ca544d3b82c5f21728b1c732bec1817" + "sha256:5038a407783ea394aaf0671d1086cf55cc1e7c303e1fac244b76adc78cc7ef07", + "sha256:a1343f2e38ea86e11247d61bd37a9d5656c16186f4a21b482c713589a054c605" ], "markers": "python_version >= '3.7'", - "version": "==1.31.49" + "version": "==1.31.50" }, "cached-property": { "hashes": [ @@ -1012,6 +1020,126 @@ ], "version": "==2.21" }, + "pydantic": { + "hashes": [ + "sha256:1607cc106602284cd4a00882986570472f193fde9cb1259bceeaedb26aa79a6d", + "sha256:45b5e446c6dfaad9444819a293b921a40e1db1aa61ea08aede0522529ce90e81" + ], + "index": "pypi", + "version": "==2.3.0" + }, + "pydantic-core": { + "hashes": [ + "sha256:002d0ea50e17ed982c2d65b480bd975fc41086a5a2f9c924ef8fc54419d1dea3", + "sha256:02e1c385095efbd997311d85c6021d32369675c09bcbfff3b69d84e59dc103f6", + "sha256:046af9cfb5384f3684eeb3f58a48698ddab8dd870b4b3f67f825353a14441418", + "sha256:04fe5c0a43dec39aedba0ec9579001061d4653a9b53a1366b113aca4a3c05ca7", + "sha256:07a1aec07333bf5adebd8264047d3dc518563d92aca6f2f5b36f505132399efc", + "sha256:1480fa4682e8202b560dcdc9eeec1005f62a15742b813c88cdc01d44e85308e5", + "sha256:1508f37ba9e3ddc0189e6ff4e2228bd2d3c3a4641cbe8c07177162f76ed696c7", + "sha256:171a4718860790f66d6c2eda1d95dd1edf64f864d2e9f9115840840cf5b5713f", + "sha256:19e20f8baedd7d987bd3f8005c146e6bcbda7cdeefc36fad50c66adb2dd2da48", + "sha256:1a0ddaa723c48af27d19f27f1c73bdc615c73686d763388c8683fe34ae777bad", + "sha256:1aa712ba150d5105814e53cb141412217146fedc22621e9acff9236d77d2a5ef", + "sha256:1ac1750df1b4339b543531ce793b8fd5c16660a95d13aecaab26b44ce11775e9", + "sha256:1c721bfc575d57305dd922e6a40a8fe3f762905851d694245807a351ad255c58", + "sha256:1ce8c84051fa292a5dc54018a40e2a1926fd17980a9422c973e3ebea017aa8da", + "sha256:1fa1f6312fb84e8c281f32b39affe81984ccd484da6e9d65b3d18c202c666149", + "sha256:22134a4453bd59b7d1e895c455fe277af9d9d9fbbcb9dc3f4a97b8693e7e2c9b", + "sha256:23470a23614c701b37252618e7851e595060a96a23016f9a084f3f92f5ed5881", + "sha256:240a015102a0c0cc8114f1cba6444499a8a4d0333e178bc504a5c2196defd456", + "sha256:252851b38bad3bfda47b104ffd077d4f9604a10cb06fe09d020016a25107bf98", + "sha256:2a20c533cb80466c1d42a43a4521669ccad7cf2967830ac62c2c2f9cece63e7e", + "sha256:2dd50d6a1aef0426a1d0199190c6c43ec89812b1f409e7fe44cb0fbf6dfa733c", + "sha256:340e96c08de1069f3d022a85c2a8c63529fd88709468373b418f4cf2c949fb0e", + "sha256:3796a6152c545339d3b1652183e786df648ecdf7c4f9347e1d30e6750907f5bb", + "sha256:37a822f630712817b6ecc09ccc378192ef5ff12e2c9bae97eb5968a6cdf3b862", + "sha256:3a750a83b2728299ca12e003d73d1264ad0440f60f4fc9cee54acc489249b728", + "sha256:3c8945a105f1589ce8a693753b908815e0748f6279959a4530f6742e1994dcb6", + "sha256:3ccc13afee44b9006a73d2046068d4df96dc5b333bf3509d9a06d1b42db6d8bf", + "sha256:3f90e5e3afb11268628c89f378f7a1ea3f2fe502a28af4192e30a6cdea1e7d5e", + "sha256:4292ca56751aebbe63a84bbfc3b5717abb09b14d4b4442cc43fd7c49a1529efd", + "sha256:430ddd965ffd068dd70ef4e4d74f2c489c3a313adc28e829dd7262cc0d2dd1e8", + "sha256:439a0de139556745ae53f9cc9668c6c2053444af940d3ef3ecad95b079bc9987", + "sha256:44b4f937b992394a2e81a5c5ce716f3dcc1237281e81b80c748b2da6dd5cf29a", + "sha256:48c1ed8b02ffea4d5c9c220eda27af02b8149fe58526359b3c07eb391cb353a2", + "sha256:4ef724a059396751aef71e847178d66ad7fc3fc969a1a40c29f5aac1aa5f8784", + "sha256:50555ba3cb58f9861b7a48c493636b996a617db1a72c18da4d7f16d7b1b9952b", + "sha256:522a9c4a4d1924facce7270c84b5134c5cabcb01513213662a2e89cf28c1d309", + "sha256:5493a7027bfc6b108e17c3383959485087d5942e87eb62bbac69829eae9bc1f7", + "sha256:56ea80269077003eaa59723bac1d8bacd2cd15ae30456f2890811efc1e3d4413", + "sha256:5a2a3c9ef904dcdadb550eedf3291ec3f229431b0084666e2c2aa8ff99a103a2", + "sha256:5cfde4fab34dd1e3a3f7f3db38182ab6c95e4ea91cf322242ee0be5c2f7e3d2f", + "sha256:5e4a2cf8c4543f37f5dc881de6c190de08096c53986381daebb56a355be5dfe6", + "sha256:5e9c068f36b9f396399d43bfb6defd4cc99c36215f6ff33ac8b9c14ba15bdf6b", + "sha256:5ed7ceca6aba5331ece96c0e328cd52f0dcf942b8895a1ed2642de50800b79d3", + "sha256:5fa159b902d22b283b680ef52b532b29554ea2a7fc39bf354064751369e9dbd7", + "sha256:615a31b1629e12445c0e9fc8339b41aaa6cc60bd53bf802d5fe3d2c0cda2ae8d", + "sha256:621afe25cc2b3c4ba05fff53525156d5100eb35c6e5a7cf31d66cc9e1963e378", + "sha256:6656a0ae383d8cd7cc94e91de4e526407b3726049ce8d7939049cbfa426518c8", + "sha256:672174480a85386dd2e681cadd7d951471ad0bb028ed744c895f11f9d51b9ebe", + "sha256:692b4ff5c4e828a38716cfa92667661a39886e71136c97b7dac26edef18767f7", + "sha256:6bcc1ad776fffe25ea5c187a028991c031a00ff92d012ca1cc4714087e575973", + "sha256:6bf7d610ac8f0065a286002a23bcce241ea8248c71988bda538edcc90e0c39ad", + "sha256:75c0ebbebae71ed1e385f7dfd9b74c1cff09fed24a6df43d326dd7f12339ec34", + "sha256:788be9844a6e5c4612b74512a76b2153f1877cd845410d756841f6c3420230eb", + "sha256:7dc2ce039c7290b4ef64334ec7e6ca6494de6eecc81e21cb4f73b9b39991408c", + "sha256:813aab5bfb19c98ae370952b6f7190f1e28e565909bfc219a0909db168783465", + "sha256:8421cf496e746cf8d6b677502ed9a0d1e4e956586cd8b221e1312e0841c002d5", + "sha256:84e87c16f582f5c753b7f39a71bd6647255512191be2d2dbf49458c4ef024588", + "sha256:84f8bb34fe76c68c9d96b77c60cef093f5e660ef8e43a6cbfcd991017d375950", + "sha256:85cc4d105747d2aa3c5cf3e37dac50141bff779545ba59a095f4a96b0a460e70", + "sha256:883daa467865e5766931e07eb20f3e8152324f0adf52658f4d302242c12e2c32", + "sha256:8b2b1bfed698fa410ab81982f681f5b1996d3d994ae8073286515ac4d165c2e7", + "sha256:8ecbac050856eb6c3046dea655b39216597e373aa8e50e134c0e202f9c47efec", + "sha256:930bfe73e665ebce3f0da2c6d64455098aaa67e1a00323c74dc752627879fc67", + "sha256:9616567800bdc83ce136e5847d41008a1d602213d024207b0ff6cab6753fe645", + "sha256:9680dd23055dd874173a3a63a44e7f5a13885a4cfd7e84814be71be24fba83db", + "sha256:99faba727727b2e59129c59542284efebbddade4f0ae6a29c8b8d3e1f437beb7", + "sha256:9a718d56c4d55efcfc63f680f207c9f19c8376e5a8a67773535e6f7e80e93170", + "sha256:9b33bf9658cb29ac1a517c11e865112316d09687d767d7a0e4a63d5c640d1b17", + "sha256:9e8b374ef41ad5c461efb7a140ce4730661aadf85958b5c6a3e9cf4e040ff4bb", + "sha256:9e9b65a55bbabda7fccd3500192a79f6e474d8d36e78d1685496aad5f9dbd92c", + "sha256:a0b7486d85293f7f0bbc39b34e1d8aa26210b450bbd3d245ec3d732864009819", + "sha256:a53e3195f134bde03620d87a7e2b2f2046e0e5a8195e66d0f244d6d5b2f6d31b", + "sha256:a87c54e72aa2ef30189dc74427421e074ab4561cf2bf314589f6af5b37f45e6d", + "sha256:a892b5b1871b301ce20d40b037ffbe33d1407a39639c2b05356acfef5536d26a", + "sha256:a8acc9dedd304da161eb071cc7ff1326aa5b66aadec9622b2574ad3ffe225525", + "sha256:aaafc776e5edc72b3cad1ccedb5fd869cc5c9a591f1213aa9eba31a781be9ac1", + "sha256:acafc4368b289a9f291e204d2c4c75908557d4f36bd3ae937914d4529bf62a76", + "sha256:b0a5d7edb76c1c57b95df719af703e796fc8e796447a1da939f97bfa8a918d60", + "sha256:b25afe9d5c4f60dcbbe2b277a79be114e2e65a16598db8abee2a2dcde24f162b", + "sha256:b44c42edc07a50a081672e25dfe6022554b47f91e793066a7b601ca290f71e42", + "sha256:b594b64e8568cf09ee5c9501ede37066b9fc41d83d58f55b9952e32141256acd", + "sha256:b962700962f6e7a6bd77e5f37320cabac24b4c0f76afeac05e9f93cf0c620014", + "sha256:bb128c30cf1df0ab78166ded1ecf876620fb9aac84d2413e8ea1594b588c735d", + "sha256:bf9d42a71a4d7a7c1f14f629e5c30eac451a6fc81827d2beefd57d014c006c4a", + "sha256:c6595b0d8c8711e8e1dc389d52648b923b809f68ac1c6f0baa525c6440aa0daa", + "sha256:c8c6660089a25d45333cb9db56bb9e347241a6d7509838dbbd1931d0e19dbc7f", + "sha256:c9d469204abcca28926cbc28ce98f28e50e488767b084fb3fbdf21af11d3de26", + "sha256:d38bbcef58220f9c81e42c255ef0bf99735d8f11edef69ab0b499da77105158a", + "sha256:d4eb77df2964b64ba190eee00b2312a1fd7a862af8918ec70fc2d6308f76ac64", + "sha256:d63b7545d489422d417a0cae6f9898618669608750fc5e62156957e609e728a5", + "sha256:d7050899026e708fb185e174c63ebc2c4ee7a0c17b0a96ebc50e1f76a231c057", + "sha256:d79f1f2f7ebdb9b741296b69049ff44aedd95976bfee38eb4848820628a99b50", + "sha256:d85463560c67fc65cd86153a4975d0b720b6d7725cf7ee0b2d291288433fc21b", + "sha256:d9140ded382a5b04a1c030b593ed9bf3088243a0a8b7fa9f071a5736498c5483", + "sha256:d9b4916b21931b08096efed090327f8fe78e09ae8f5ad44e07f5c72a7eedb51b", + "sha256:df14f6332834444b4a37685810216cc8fe1fe91f447332cd56294c984ecbff1c", + "sha256:e49ce7dc9f925e1fb010fc3d555250139df61fa6e5a0a95ce356329602c11ea9", + "sha256:e61eae9b31799c32c5f9b7be906be3380e699e74b2db26c227c50a5fc7988698", + "sha256:ea053cefa008fda40f92aab937fb9f183cf8752e41dbc7bc68917884454c6362", + "sha256:f06e21ad0b504658a3a9edd3d8530e8cea5723f6ea5d280e8db8efc625b47e49", + "sha256:f14546403c2a1d11a130b537dda28f07eb6c1805a43dae4617448074fd49c282", + "sha256:f1a5d8f18877474c80b7711d870db0eeef9442691fcdb00adabfc97e183ee0b0", + "sha256:f2969e8f72c6236c51f91fbb79c33821d12a811e2a94b7aa59c65f8dbdfad34a", + "sha256:f468d520f47807d1eb5d27648393519655eadc578d5dd862d06873cce04c4d1b", + "sha256:f70dc00a91311a1aea124e5f64569ea44c011b58433981313202c46bccbec0e1", + "sha256:f93255b3e4d64785554e544c1c76cd32f4a354fa79e2eeca5d16ac2e7fdd57aa" + ], + "markers": "python_version >= '3.7'", + "version": "==2.6.3" + }, "pyparsing": { "hashes": [ "sha256:32c7c0b711493c72ff18a981d24f28aaf9c1fb7ed5e9667c9e84e3db623bdbfb", @@ -1391,11 +1519,11 @@ }, "smmap": { "hashes": [ - "sha256:2aba19d6a040e78d8b09de5c57e96207b09ed71d8e55ce0959eeee6c8e190d94", - "sha256:c840e62059cd3be204b0c9c9f74be2c09d5648eddd4580d9314c3ecde0b30936" + "sha256:dceeb6c0028fdb6734471eb07c0cd2aae706ccaecab45965ee83f11c8d3b1f62", + "sha256:e6d8668fa5f93e706934a62d7b4db19c8d9eb8cf2adbb75ef1b675aa332b69da" ], - "markers": "python_version >= '3.6'", - "version": "==5.0.0" + "markers": "python_version >= '3.7'", + "version": "==5.0.1" }, "sortedcontainers": { "hashes": [ @@ -1461,11 +1589,11 @@ }, "typing-extensions": { "hashes": [ - "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36", - "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2" + "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0", + "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef" ], "index": "pypi", - "version": "==4.7.1" + "version": "==4.8.0" }, "unidiff": { "hashes": [ @@ -1603,11 +1731,11 @@ }, "zipp": { "hashes": [ - "sha256:679e51dd4403591b2d6838a48de3d283f3d188412a9782faadf845f298736ba0", - "sha256:ebc15946aa78bd63458992fc81ec3b6f7b1e92d51c35e6de1c3804e73b799147" + "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31", + "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0" ], "markers": "python_version >= '3.8'", - "version": "==3.16.2" + "version": "==3.17.0" } }, "develop": { @@ -1720,6 +1848,14 @@ "markers": "python_version >= '3.7'", "version": "==1.3.1" }, + "annotated-types": { + "hashes": [ + "sha256:47cdc3490d9ac1506ce92c7aaa76c579dc3509ff11e098fc867e5130ab7be802", + "sha256:58da39888f92c276ad970249761ebea80ba544b77acddaa1a4d6cf78287d45fd" + ], + "markers": "python_version >= '3.7'", + "version": "==0.5.0" + }, "async-timeout": { "hashes": [ "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f", @@ -1749,19 +1885,19 @@ "s3" ], "hashes": [ - "sha256:348deff669e69421779d98d3f543fa724459ea818db48e19362012c43a40e192", - "sha256:cb69a4903742bbec3c66daa8cd8803844a8b43a99e09f1d71f0b9278d5a62ced" + "sha256:d734730a5ba3ab7a8f8bf61feaaf16fcd2f7084be2f1d2e54576daf023528330", + "sha256:ff00eb158f7825f850df9d1b97433c41297141726058ac2a4f8270c7224160a7" ], "index": "pypi", - "version": "==1.28.49" + "version": "==1.28.50" }, "botocore-stubs": { "hashes": [ - "sha256:2e005b032feeba93f74511027338a6266b4d7f582e31a56a67ac728a3b5f5b83", - "sha256:4807bbb65680ff4546d60a76879d83af6d314d0952413d347a8c784eef37c482" + "sha256:b0ba8d9fa627c8e06c7b76c5c91cd0b1e529042805dab86ca6b47674162251db", + "sha256:ed728773c01ab93f1c0ee9bb47742d58e1bdf89b0806b0e2a4fbd99fc9979d27" ], "markers": "python_version >= '3.7' and python_version < '4.0'", - "version": "==1.31.49" + "version": "==1.31.50" }, "certifi": { "hashes": [ @@ -2351,6 +2487,126 @@ "markers": "python_version >= '3.8'", "version": "==2.11.0" }, + "pydantic": { + "hashes": [ + "sha256:1607cc106602284cd4a00882986570472f193fde9cb1259bceeaedb26aa79a6d", + "sha256:45b5e446c6dfaad9444819a293b921a40e1db1aa61ea08aede0522529ce90e81" + ], + "index": "pypi", + "version": "==2.3.0" + }, + "pydantic-core": { + "hashes": [ + "sha256:002d0ea50e17ed982c2d65b480bd975fc41086a5a2f9c924ef8fc54419d1dea3", + "sha256:02e1c385095efbd997311d85c6021d32369675c09bcbfff3b69d84e59dc103f6", + "sha256:046af9cfb5384f3684eeb3f58a48698ddab8dd870b4b3f67f825353a14441418", + "sha256:04fe5c0a43dec39aedba0ec9579001061d4653a9b53a1366b113aca4a3c05ca7", + "sha256:07a1aec07333bf5adebd8264047d3dc518563d92aca6f2f5b36f505132399efc", + "sha256:1480fa4682e8202b560dcdc9eeec1005f62a15742b813c88cdc01d44e85308e5", + "sha256:1508f37ba9e3ddc0189e6ff4e2228bd2d3c3a4641cbe8c07177162f76ed696c7", + "sha256:171a4718860790f66d6c2eda1d95dd1edf64f864d2e9f9115840840cf5b5713f", + "sha256:19e20f8baedd7d987bd3f8005c146e6bcbda7cdeefc36fad50c66adb2dd2da48", + "sha256:1a0ddaa723c48af27d19f27f1c73bdc615c73686d763388c8683fe34ae777bad", + "sha256:1aa712ba150d5105814e53cb141412217146fedc22621e9acff9236d77d2a5ef", + "sha256:1ac1750df1b4339b543531ce793b8fd5c16660a95d13aecaab26b44ce11775e9", + "sha256:1c721bfc575d57305dd922e6a40a8fe3f762905851d694245807a351ad255c58", + "sha256:1ce8c84051fa292a5dc54018a40e2a1926fd17980a9422c973e3ebea017aa8da", + "sha256:1fa1f6312fb84e8c281f32b39affe81984ccd484da6e9d65b3d18c202c666149", + "sha256:22134a4453bd59b7d1e895c455fe277af9d9d9fbbcb9dc3f4a97b8693e7e2c9b", + "sha256:23470a23614c701b37252618e7851e595060a96a23016f9a084f3f92f5ed5881", + "sha256:240a015102a0c0cc8114f1cba6444499a8a4d0333e178bc504a5c2196defd456", + "sha256:252851b38bad3bfda47b104ffd077d4f9604a10cb06fe09d020016a25107bf98", + "sha256:2a20c533cb80466c1d42a43a4521669ccad7cf2967830ac62c2c2f9cece63e7e", + "sha256:2dd50d6a1aef0426a1d0199190c6c43ec89812b1f409e7fe44cb0fbf6dfa733c", + "sha256:340e96c08de1069f3d022a85c2a8c63529fd88709468373b418f4cf2c949fb0e", + "sha256:3796a6152c545339d3b1652183e786df648ecdf7c4f9347e1d30e6750907f5bb", + "sha256:37a822f630712817b6ecc09ccc378192ef5ff12e2c9bae97eb5968a6cdf3b862", + "sha256:3a750a83b2728299ca12e003d73d1264ad0440f60f4fc9cee54acc489249b728", + "sha256:3c8945a105f1589ce8a693753b908815e0748f6279959a4530f6742e1994dcb6", + "sha256:3ccc13afee44b9006a73d2046068d4df96dc5b333bf3509d9a06d1b42db6d8bf", + "sha256:3f90e5e3afb11268628c89f378f7a1ea3f2fe502a28af4192e30a6cdea1e7d5e", + "sha256:4292ca56751aebbe63a84bbfc3b5717abb09b14d4b4442cc43fd7c49a1529efd", + "sha256:430ddd965ffd068dd70ef4e4d74f2c489c3a313adc28e829dd7262cc0d2dd1e8", + "sha256:439a0de139556745ae53f9cc9668c6c2053444af940d3ef3ecad95b079bc9987", + "sha256:44b4f937b992394a2e81a5c5ce716f3dcc1237281e81b80c748b2da6dd5cf29a", + "sha256:48c1ed8b02ffea4d5c9c220eda27af02b8149fe58526359b3c07eb391cb353a2", + "sha256:4ef724a059396751aef71e847178d66ad7fc3fc969a1a40c29f5aac1aa5f8784", + "sha256:50555ba3cb58f9861b7a48c493636b996a617db1a72c18da4d7f16d7b1b9952b", + "sha256:522a9c4a4d1924facce7270c84b5134c5cabcb01513213662a2e89cf28c1d309", + "sha256:5493a7027bfc6b108e17c3383959485087d5942e87eb62bbac69829eae9bc1f7", + "sha256:56ea80269077003eaa59723bac1d8bacd2cd15ae30456f2890811efc1e3d4413", + "sha256:5a2a3c9ef904dcdadb550eedf3291ec3f229431b0084666e2c2aa8ff99a103a2", + "sha256:5cfde4fab34dd1e3a3f7f3db38182ab6c95e4ea91cf322242ee0be5c2f7e3d2f", + "sha256:5e4a2cf8c4543f37f5dc881de6c190de08096c53986381daebb56a355be5dfe6", + "sha256:5e9c068f36b9f396399d43bfb6defd4cc99c36215f6ff33ac8b9c14ba15bdf6b", + "sha256:5ed7ceca6aba5331ece96c0e328cd52f0dcf942b8895a1ed2642de50800b79d3", + "sha256:5fa159b902d22b283b680ef52b532b29554ea2a7fc39bf354064751369e9dbd7", + "sha256:615a31b1629e12445c0e9fc8339b41aaa6cc60bd53bf802d5fe3d2c0cda2ae8d", + "sha256:621afe25cc2b3c4ba05fff53525156d5100eb35c6e5a7cf31d66cc9e1963e378", + "sha256:6656a0ae383d8cd7cc94e91de4e526407b3726049ce8d7939049cbfa426518c8", + "sha256:672174480a85386dd2e681cadd7d951471ad0bb028ed744c895f11f9d51b9ebe", + "sha256:692b4ff5c4e828a38716cfa92667661a39886e71136c97b7dac26edef18767f7", + "sha256:6bcc1ad776fffe25ea5c187a028991c031a00ff92d012ca1cc4714087e575973", + "sha256:6bf7d610ac8f0065a286002a23bcce241ea8248c71988bda538edcc90e0c39ad", + "sha256:75c0ebbebae71ed1e385f7dfd9b74c1cff09fed24a6df43d326dd7f12339ec34", + "sha256:788be9844a6e5c4612b74512a76b2153f1877cd845410d756841f6c3420230eb", + "sha256:7dc2ce039c7290b4ef64334ec7e6ca6494de6eecc81e21cb4f73b9b39991408c", + "sha256:813aab5bfb19c98ae370952b6f7190f1e28e565909bfc219a0909db168783465", + "sha256:8421cf496e746cf8d6b677502ed9a0d1e4e956586cd8b221e1312e0841c002d5", + "sha256:84e87c16f582f5c753b7f39a71bd6647255512191be2d2dbf49458c4ef024588", + "sha256:84f8bb34fe76c68c9d96b77c60cef093f5e660ef8e43a6cbfcd991017d375950", + "sha256:85cc4d105747d2aa3c5cf3e37dac50141bff779545ba59a095f4a96b0a460e70", + "sha256:883daa467865e5766931e07eb20f3e8152324f0adf52658f4d302242c12e2c32", + "sha256:8b2b1bfed698fa410ab81982f681f5b1996d3d994ae8073286515ac4d165c2e7", + "sha256:8ecbac050856eb6c3046dea655b39216597e373aa8e50e134c0e202f9c47efec", + "sha256:930bfe73e665ebce3f0da2c6d64455098aaa67e1a00323c74dc752627879fc67", + "sha256:9616567800bdc83ce136e5847d41008a1d602213d024207b0ff6cab6753fe645", + "sha256:9680dd23055dd874173a3a63a44e7f5a13885a4cfd7e84814be71be24fba83db", + "sha256:99faba727727b2e59129c59542284efebbddade4f0ae6a29c8b8d3e1f437beb7", + "sha256:9a718d56c4d55efcfc63f680f207c9f19c8376e5a8a67773535e6f7e80e93170", + "sha256:9b33bf9658cb29ac1a517c11e865112316d09687d767d7a0e4a63d5c640d1b17", + "sha256:9e8b374ef41ad5c461efb7a140ce4730661aadf85958b5c6a3e9cf4e040ff4bb", + "sha256:9e9b65a55bbabda7fccd3500192a79f6e474d8d36e78d1685496aad5f9dbd92c", + "sha256:a0b7486d85293f7f0bbc39b34e1d8aa26210b450bbd3d245ec3d732864009819", + "sha256:a53e3195f134bde03620d87a7e2b2f2046e0e5a8195e66d0f244d6d5b2f6d31b", + "sha256:a87c54e72aa2ef30189dc74427421e074ab4561cf2bf314589f6af5b37f45e6d", + "sha256:a892b5b1871b301ce20d40b037ffbe33d1407a39639c2b05356acfef5536d26a", + "sha256:a8acc9dedd304da161eb071cc7ff1326aa5b66aadec9622b2574ad3ffe225525", + "sha256:aaafc776e5edc72b3cad1ccedb5fd869cc5c9a591f1213aa9eba31a781be9ac1", + "sha256:acafc4368b289a9f291e204d2c4c75908557d4f36bd3ae937914d4529bf62a76", + "sha256:b0a5d7edb76c1c57b95df719af703e796fc8e796447a1da939f97bfa8a918d60", + "sha256:b25afe9d5c4f60dcbbe2b277a79be114e2e65a16598db8abee2a2dcde24f162b", + "sha256:b44c42edc07a50a081672e25dfe6022554b47f91e793066a7b601ca290f71e42", + "sha256:b594b64e8568cf09ee5c9501ede37066b9fc41d83d58f55b9952e32141256acd", + "sha256:b962700962f6e7a6bd77e5f37320cabac24b4c0f76afeac05e9f93cf0c620014", + "sha256:bb128c30cf1df0ab78166ded1ecf876620fb9aac84d2413e8ea1594b588c735d", + "sha256:bf9d42a71a4d7a7c1f14f629e5c30eac451a6fc81827d2beefd57d014c006c4a", + "sha256:c6595b0d8c8711e8e1dc389d52648b923b809f68ac1c6f0baa525c6440aa0daa", + "sha256:c8c6660089a25d45333cb9db56bb9e347241a6d7509838dbbd1931d0e19dbc7f", + "sha256:c9d469204abcca28926cbc28ce98f28e50e488767b084fb3fbdf21af11d3de26", + "sha256:d38bbcef58220f9c81e42c255ef0bf99735d8f11edef69ab0b499da77105158a", + "sha256:d4eb77df2964b64ba190eee00b2312a1fd7a862af8918ec70fc2d6308f76ac64", + "sha256:d63b7545d489422d417a0cae6f9898618669608750fc5e62156957e609e728a5", + "sha256:d7050899026e708fb185e174c63ebc2c4ee7a0c17b0a96ebc50e1f76a231c057", + "sha256:d79f1f2f7ebdb9b741296b69049ff44aedd95976bfee38eb4848820628a99b50", + "sha256:d85463560c67fc65cd86153a4975d0b720b6d7725cf7ee0b2d291288433fc21b", + "sha256:d9140ded382a5b04a1c030b593ed9bf3088243a0a8b7fa9f071a5736498c5483", + "sha256:d9b4916b21931b08096efed090327f8fe78e09ae8f5ad44e07f5c72a7eedb51b", + "sha256:df14f6332834444b4a37685810216cc8fe1fe91f447332cd56294c984ecbff1c", + "sha256:e49ce7dc9f925e1fb010fc3d555250139df61fa6e5a0a95ce356329602c11ea9", + "sha256:e61eae9b31799c32c5f9b7be906be3380e699e74b2db26c227c50a5fc7988698", + "sha256:ea053cefa008fda40f92aab937fb9f183cf8752e41dbc7bc68917884454c6362", + "sha256:f06e21ad0b504658a3a9edd3d8530e8cea5723f6ea5d280e8db8efc625b47e49", + "sha256:f14546403c2a1d11a130b537dda28f07eb6c1805a43dae4617448074fd49c282", + "sha256:f1a5d8f18877474c80b7711d870db0eeef9442691fcdb00adabfc97e183ee0b0", + "sha256:f2969e8f72c6236c51f91fbb79c33821d12a811e2a94b7aa59c65f8dbdfad34a", + "sha256:f468d520f47807d1eb5d27648393519655eadc578d5dd862d06873cce04c4d1b", + "sha256:f70dc00a91311a1aea124e5f64569ea44c011b58433981313202c46bccbec0e1", + "sha256:f93255b3e4d64785554e544c1c76cd32f4a354fa79e2eeca5d16ac2e7fdd57aa" + ], + "markers": "python_version >= '3.7'", + "version": "==2.6.3" + }, "pyflakes": { "hashes": [ "sha256:4132f6d49cb4dae6819e5379898f2b8cce3c5f23994194c24b77d5da2e36f774", @@ -2497,11 +2753,11 @@ }, "rich": { "hashes": [ - "sha256:146a90b3b6b47cac4a73c12866a499e9817426423f57c5a66949c086191a8808", - "sha256:fb9d6c0a0f643c99eed3875b5377a184132ba9be4d61516a55273d3554d75a39" + "sha256:87b43e0543149efa1253f485cd845bb7ee54df16c9617b8a893650ab84b4acb6", + "sha256:9257b468badc3d347e146a4faa268ff229039d4c2d176ab0cffb4c4fbc73d5d9" ], "markers": "python_full_version >= '3.7.0'", - "version": "==13.5.2" + "version": "==13.5.3" }, "rpds-py": { "hashes": [ @@ -2624,11 +2880,11 @@ }, "smmap": { "hashes": [ - "sha256:2aba19d6a040e78d8b09de5c57e96207b09ed71d8e55ce0959eeee6c8e190d94", - "sha256:c840e62059cd3be204b0c9c9f74be2c09d5648eddd4580d9314c3ecde0b30936" + "sha256:dceeb6c0028fdb6734471eb07c0cd2aae706ccaecab45965ee83f11c8d3b1f62", + "sha256:e6d8668fa5f93e706934a62d7b4db19c8d9eb8cf2adbb75ef1b675aa332b69da" ], - "markers": "python_version >= '3.6'", - "version": "==5.0.0" + "markers": "python_version >= '3.7'", + "version": "==5.0.1" }, "stevedore": { "hashes": [ @@ -2744,11 +3000,11 @@ }, "typing-extensions": { "hashes": [ - "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36", - "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2" + "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0", + "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef" ], "index": "pypi", - "version": "==4.7.1" + "version": "==4.8.0" }, "urllib3": { "hashes": [ @@ -2856,11 +3112,11 @@ }, "zipp": { "hashes": [ - "sha256:679e51dd4403591b2d6838a48de3d283f3d188412a9782faadf845f298736ba0", - "sha256:ebc15946aa78bd63458992fc81ec3b6f7b1e92d51c35e6de1c3804e73b799147" + "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31", + "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0" ], "markers": "python_version >= '3.8'", - "version": "==3.16.2" + "version": "==3.17.0" } } } diff --git a/checkov/common/sca/reachability/__init__.py b/checkov/common/sca/reachability/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/checkov/common/sca/reachability/abstract_alias_mapping_strategy.py b/checkov/common/sca/reachability/abstract_alias_mapping_strategy.py new file mode 100644 index 00000000000..31a1b7db135 --- /dev/null +++ b/checkov/common/sca/reachability/abstract_alias_mapping_strategy.py @@ -0,0 +1,53 @@ +from abc import ABC, abstractmethod +from typing import List, Dict, Set, Callable +import logging +import os + +from checkov.common.sca.reachability.typing import AliasMappingObject, LanguageObject, \ + RepositoryObject, FileObject, PackageAliasesObject + + +class AbstractAliasMappingStrategy(ABC): + @abstractmethod + def get_language(self) -> str: + pass + + @abstractmethod + def get_file_name_to_parser_map(self) -> Dict[str, Callable[[str, Set[str]], FileObject]]: + pass + + @staticmethod + def _add_package_aliases(alias_mapping: AliasMappingObject, language: str, repository_name: str, + file_relative_path: str, package_name: str, package_aliases: List[str]) -> None: + package_aliases_for_file = alias_mapping.languages.setdefault(language, LanguageObject()).repositories \ + .setdefault(repository_name, RepositoryObject()).files \ + .setdefault(file_relative_path, FileObject()).packageAliases + if package_name in package_aliases_for_file: + raise Exception(f"aliases for \'{package_name}\' in the file \'{file_relative_path}\' in the repository " + f"\'{repository_name}\' already were set") + package_aliases_for_file[package_name] = PackageAliasesObject(packageAliases=package_aliases) + + def update_alias_mapping(self, alias_mapping: AliasMappingObject, repository_name: str, root_dir: str, relevant_packages: Set[str])\ + -> None: + logging.debug("[AbstractAliasMappingStrategy](create_alias_mapping) - starting") + file_name_to_parser_map = self.get_file_name_to_parser_map() + for curr_root, _, f_names in os.walk(root_dir): + for file_name in f_names: + if file_name in file_name_to_parser_map: + logging.debug(f"[AbstractAliasMappingStrategy](create_alias_mapping) - starting parsing ${file_name}") + file_absolute_path = os.path.join(curr_root, file_name) + file_relative_path = os.path.relpath(file_absolute_path, root_dir) + with open(file_absolute_path) as f: + file_content = f.read() + try: + output = file_name_to_parser_map[file_name](file_content, relevant_packages) + for package_name in output.packageAliases: + self._add_package_aliases(alias_mapping, self.get_language(), repository_name, + file_relative_path, package_name, + output.packageAliases[package_name].packageAliases) + logging.debug( + f"[AbstractAliasMappingStrategy](create_alias_mapping) - done parsing for ${file_name}") + except Exception: + logging.error(f"[AbstractAliasMappingStrategy](create_alias_mapping) - failure when " + f"parsing the file '${file_name}'. file content:\n{file_content}.\n", + exc_info=True) diff --git a/checkov/common/sca/reachability/alias_mapping_creator.py b/checkov/common/sca/reachability/alias_mapping_creator.py new file mode 100644 index 00000000000..f269576b272 --- /dev/null +++ b/checkov/common/sca/reachability/alias_mapping_creator.py @@ -0,0 +1,28 @@ +from __future__ import annotations + +from typing import Dict, Set + +from checkov.common.sca.reachability.abstract_alias_mapping_strategy import AbstractAliasMappingStrategy +from checkov.common.sca.reachability.nodejs.nodejs_alias_mapping_strategy import NodejsAliasMappingStrategy +from checkov.common.sca.reachability.typing import AliasMappingObject + +language_to_strategy: Dict[str, AbstractAliasMappingStrategy] = { + "nodejs": NodejsAliasMappingStrategy() +} + + +class AliasMappingCreator: + def __init__(self) -> None: + self._alias_mapping: AliasMappingObject = AliasMappingObject() + + def update_alias_mapping_for_repository( + self, + repository_name: str, + repository_root_dir: str, + relevant_packages: Set[str] + ) -> None: + for lang in language_to_strategy: + language_to_strategy[lang].update_alias_mapping(self._alias_mapping, repository_name, repository_root_dir, relevant_packages) + + def get_alias_mapping(self) -> AliasMappingObject: + return self._alias_mapping diff --git a/checkov/common/sca/reachability/nodejs/__init__.py b/checkov/common/sca/reachability/nodejs/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/checkov/common/sca/reachability/nodejs/nodejs_alias_mapping_strategy.py b/checkov/common/sca/reachability/nodejs/nodejs_alias_mapping_strategy.py new file mode 100644 index 00000000000..5c8b5d13894 --- /dev/null +++ b/checkov/common/sca/reachability/nodejs/nodejs_alias_mapping_strategy.py @@ -0,0 +1,25 @@ +from __future__ import annotations + +from typing import Dict, Set, Callable + +from checkov.common.sca.reachability.typing import FileObject +from checkov.common.sca.reachability.abstract_alias_mapping_strategy import AbstractAliasMappingStrategy +from checkov.common.sca.reachability.nodejs.utils import parse_webpack_file, parse_tsconfig_file, parse_babel_file, \ + parse_rollup_file, parse_package_json_file, parse_snowpack_file, parse_vite_file + + +class NodejsAliasMappingStrategy(AbstractAliasMappingStrategy): + def get_language(self) -> str: + return "nodejs" + + def get_file_name_to_parser_map(self) -> Dict[str, Callable[[str, Set[str]], FileObject]]: + return { + "webpack.config.js": parse_webpack_file, + "tsconfig.json": parse_tsconfig_file, + ".babelrc": parse_babel_file, + "babel.config.js": parse_babel_file, + "rollup.config.js": parse_rollup_file, + "package.json": parse_package_json_file, + "snowpack.config.js": parse_snowpack_file, + "vite.config.js": parse_vite_file + } diff --git a/checkov/common/sca/reachability/nodejs/utils.py b/checkov/common/sca/reachability/nodejs/utils.py new file mode 100644 index 00000000000..484c2ffc047 --- /dev/null +++ b/checkov/common/sca/reachability/nodejs/utils.py @@ -0,0 +1,125 @@ +from __future__ import annotations + +import os.path +from typing import Dict, Set, Any +import re +import json +import os + +from checkov.common.sca.reachability.typing import FileObject, PackageAliasesObject + + +MODULE_EXPORTS_PATTERN = r'module\.exports\s*=\s*({.*?});' +EXPORT_DEFAULT_PATTERN = r'export\s*default\s*({.*?});' + + +def _parse_export(file_content: str, pattern: str) -> Dict[str, Any] | None: + module_export_match = re.search(pattern, file_content, re.DOTALL) + + if module_export_match: + module_exports_str = module_export_match.group(1) + # for having for all the keys and values double quotes and removing spaces + module_exports_str = re.sub(r'\s+', '', re.sub(r'([{\s,])(\w+):', r'\1"\2":', module_exports_str) + .replace("'", "\"")) + module_exports: Dict[str, Any] = json.loads(module_exports_str) + return module_exports + return None + + +def parse_webpack_file(file_content: str, relevant_packages: Set[str]) -> FileObject: + output: FileObject = FileObject() + module_exports_json = _parse_export(file_content, MODULE_EXPORTS_PATTERN) + if module_exports_json: + aliases = module_exports_json.get("resolve", {}).get("alias", {}) + for imported_name in aliases: + package_name = aliases[imported_name] + if package_name in relevant_packages: + output.packageAliases.setdefault(package_name, PackageAliasesObject()).packageAliases.append(imported_name) + return output + + +def parse_tsconfig_file(file_content: str, relevant_packages: Set[str]) -> FileObject: + output: FileObject = FileObject() + tsconfig_json = json.loads(file_content) + paths = tsconfig_json.get("compilerOptions", {}).get("paths", {}) + for imported_name in paths: + for package_relative_path in paths[imported_name]: + package_name = os.path.basename(package_relative_path) + if package_name in relevant_packages: + output.packageAliases.setdefault(package_name, PackageAliasesObject()).packageAliases.append(imported_name) + return output + + +def parse_babel_file(file_content: str, relevant_packages: Set[str]) -> FileObject: + output: FileObject = FileObject() + babelrc_json = json.loads(file_content) + plugins = babelrc_json.get("plugins", {}) + for plugin in plugins: + if len(plugin) > 1: + plugin_object = plugin[1] + aliases = plugin_object.get("alias", {}) + for imported_name in aliases: + package_name = aliases[imported_name] + if package_name in relevant_packages: + output.packageAliases.setdefault(package_name, PackageAliasesObject()).packageAliases.append(imported_name) + return output + + +def parse_rollup_file(file_content: str, relevant_packages: Set[str]) -> FileObject: + output: FileObject = FileObject() + export_default_match = re.search(EXPORT_DEFAULT_PATTERN, file_content, re.DOTALL) + if export_default_match: + export_default_str = export_default_match.group(1) + # for having for all the keys and values doube quotes and removing spaces + export_default_str = re.sub(r'\s+', '', re.sub(r'([{\s,])(\w+):', r'\1"\2":', export_default_str) + .replace("'", "\"")) + + # Defining a regular expression pattern to match the elements within the "plugins" list + pattern = r'alias\(\{[^)]*\}\)' + matches = re.findall(pattern, export_default_str) + + for alias_object_str in matches: + alias_object = json.loads(alias_object_str[6:-1]) # removing 'alias(' and ')' + for entry in alias_object.get("entries", []): + if entry["replacement"] in relevant_packages: + output.packageAliases.setdefault(entry["replacement"], PackageAliasesObject()).packageAliases.append(entry["find"]) + return output + + +def parse_package_json_file(file_content: str, relevant_packages: Set[str]) -> FileObject: + output: FileObject = FileObject() + package_json = json.loads(file_content) + aliases: Dict[str, str] = dict() + if "alias" in package_json: + aliases.update(package_json["alias"]) + if package_json.get("aliasify", {}).get("aliases"): + aliases.update(package_json["aliasify"]["aliases"]) + for imported_name in aliases: + if aliases[imported_name] in relevant_packages: + output.packageAliases.setdefault(aliases[imported_name], PackageAliasesObject()).packageAliases.append(imported_name) + return output + + +def parse_snowpack_file(file_content: str, relevant_packages: Set[str]) -> FileObject: + output: FileObject = FileObject() + module_exports_json = _parse_export(file_content, MODULE_EXPORTS_PATTERN) + if module_exports_json: + aliases = module_exports_json.get("alias", {}) + for imported_name in aliases: + package_name = aliases[imported_name] + if package_name in relevant_packages: + if package_name in relevant_packages: + output.packageAliases.setdefault(package_name, PackageAliasesObject()).packageAliases.append(imported_name) + return output + + +def parse_vite_file(file_content: str, relevant_packages: Set[str]) -> FileObject: + output: FileObject = FileObject() + export_default_match = _parse_export(file_content, EXPORT_DEFAULT_PATTERN) + if export_default_match: + aliases = export_default_match.get("resolve", {}).get("alias", {}) + for imported_name in aliases: + package_name = aliases[imported_name] + if package_name in relevant_packages: + output.packageAliases.setdefault(package_name, PackageAliasesObject()).packageAliases.append(imported_name) + return output diff --git a/checkov/common/sca/reachability/typing.py b/checkov/common/sca/reachability/typing.py new file mode 100644 index 00000000000..7db9644b54e --- /dev/null +++ b/checkov/common/sca/reachability/typing.py @@ -0,0 +1,24 @@ +from __future__ import annotations + +from typing import List, Dict +from pydantic import BaseModel + + +class PackageAliasesObject(BaseModel): + packageAliases: List[str] = list() # noqa: CCE003 # a default value for initialization + + +class FileObject(BaseModel): + packageAliases: Dict[str, PackageAliasesObject] = dict() # noqa: CCE003 # a default value for initialization + + +class RepositoryObject(BaseModel): + files: Dict[str, FileObject] = dict() # noqa: CCE003 # a default value for initialization + + +class LanguageObject(BaseModel): + repositories: Dict[str, RepositoryObject] = dict() # noqa: CCE003 # a default value for initialization + + +class AliasMappingObject(BaseModel): + languages: Dict[str, LanguageObject] = dict() # noqa: CCE003 # a default value for initialization diff --git a/setup.py b/setup.py index 462ea220e3a..0477c6bec57 100644 --- a/setup.py +++ b/setup.py @@ -111,6 +111,7 @@ def run(self) -> None: "openai", "spdx-tools>=0.8.0,<0.9.0", "license-expression", + "pydantic", ], dependency_links=[], # keep it empty, needed for pipenv-setup license="Apache License 2.0", diff --git a/tests/common/sca/reachability/__init__.py b/tests/common/sca/reachability/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/common/sca/reachability/example_repo/tsconfig.json b/tests/common/sca/reachability/example_repo/tsconfig.json new file mode 100644 index 00000000000..69fbc006431 --- /dev/null +++ b/tests/common/sca/reachability/example_repo/tsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "ax": ["node_modules/axios"] + } + } +} \ No newline at end of file diff --git a/tests/common/sca/reachability/nodejs/__init__.py b/tests/common/sca/reachability/nodejs/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/common/sca/reachability/nodejs/examples/babel/babel_config/babel.config.js b/tests/common/sca/reachability/nodejs/examples/babel/babel_config/babel.config.js new file mode 100644 index 00000000000..f21cd124ab3 --- /dev/null +++ b/tests/common/sca/reachability/nodejs/examples/babel/babel_config/babel.config.js @@ -0,0 +1,9 @@ +{ + "plugins": [ + ["module-resolver", { + "alias": { + "ax": "axios" + } + }] + ] +} \ No newline at end of file diff --git a/tests/common/sca/reachability/nodejs/examples/babel/babelrc/.babelrc b/tests/common/sca/reachability/nodejs/examples/babel/babelrc/.babelrc new file mode 100644 index 00000000000..f21cd124ab3 --- /dev/null +++ b/tests/common/sca/reachability/nodejs/examples/babel/babelrc/.babelrc @@ -0,0 +1,9 @@ +{ + "plugins": [ + ["module-resolver", { + "alias": { + "ax": "axios" + } + }] + ] +} \ No newline at end of file diff --git a/tests/common/sca/reachability/nodejs/examples/fake_file/fake.babel.config.js b/tests/common/sca/reachability/nodejs/examples/fake_file/fake.babel.config.js new file mode 100644 index 00000000000..f21cd124ab3 --- /dev/null +++ b/tests/common/sca/reachability/nodejs/examples/fake_file/fake.babel.config.js @@ -0,0 +1,9 @@ +{ + "plugins": [ + ["module-resolver", { + "alias": { + "ax": "axios" + } + }] + ] +} \ No newline at end of file diff --git a/tests/common/sca/reachability/nodejs/examples/mix/package_json_with_alias/package.json b/tests/common/sca/reachability/nodejs/examples/mix/package_json_with_alias/package.json new file mode 100644 index 00000000000..d2f5026ef39 --- /dev/null +++ b/tests/common/sca/reachability/nodejs/examples/mix/package_json_with_alias/package.json @@ -0,0 +1,5 @@ +{ + "alias": { + "ax": "axios" + } +} \ No newline at end of file diff --git a/tests/common/sca/reachability/nodejs/examples/mix/vite.config.js b/tests/common/sca/reachability/nodejs/examples/mix/vite.config.js new file mode 100644 index 00000000000..b542651f912 --- /dev/null +++ b/tests/common/sca/reachability/nodejs/examples/mix/vite.config.js @@ -0,0 +1,7 @@ +export default { + resolve: { + alias: { + "ax": "axios" + } + } +}; \ No newline at end of file diff --git a/tests/common/sca/reachability/nodejs/examples/package_json/package_json_with_alias/package.json b/tests/common/sca/reachability/nodejs/examples/package_json/package_json_with_alias/package.json new file mode 100644 index 00000000000..d2f5026ef39 --- /dev/null +++ b/tests/common/sca/reachability/nodejs/examples/package_json/package_json_with_alias/package.json @@ -0,0 +1,5 @@ +{ + "alias": { + "ax": "axios" + } +} \ No newline at end of file diff --git a/tests/common/sca/reachability/nodejs/examples/package_json/package_json_with_aliasify/package.json b/tests/common/sca/reachability/nodejs/examples/package_json/package_json_with_aliasify/package.json new file mode 100644 index 00000000000..a2511b86d47 --- /dev/null +++ b/tests/common/sca/reachability/nodejs/examples/package_json/package_json_with_aliasify/package.json @@ -0,0 +1,7 @@ +{ + "aliasify": { + "aliases": { + "ax": "axios" + } + } +} \ No newline at end of file diff --git a/tests/common/sca/reachability/nodejs/examples/rollup/rollup.config.js b/tests/common/sca/reachability/nodejs/examples/rollup/rollup.config.js new file mode 100644 index 00000000000..2aea10b8e49 --- /dev/null +++ b/tests/common/sca/reachability/nodejs/examples/rollup/rollup.config.js @@ -0,0 +1,11 @@ +import alias from '@rollup/plugin-alias'; + +export default { + plugins: [ + alias({ + entries: [ + { find: 'ax', replacement: 'axios' } + ] + }) + ] +}; \ No newline at end of file diff --git a/tests/common/sca/reachability/nodejs/examples/snowpack/snowpack.config.js b/tests/common/sca/reachability/nodejs/examples/snowpack/snowpack.config.js new file mode 100644 index 00000000000..160e53671cb --- /dev/null +++ b/tests/common/sca/reachability/nodejs/examples/snowpack/snowpack.config.js @@ -0,0 +1,5 @@ +module.exports = { + alias: { + "ax": "axios" + } +}; \ No newline at end of file diff --git a/tests/common/sca/reachability/nodejs/examples/tsconfig/tsconfig.json b/tests/common/sca/reachability/nodejs/examples/tsconfig/tsconfig.json new file mode 100644 index 00000000000..69fbc006431 --- /dev/null +++ b/tests/common/sca/reachability/nodejs/examples/tsconfig/tsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "ax": ["node_modules/axios"] + } + } +} \ No newline at end of file diff --git a/tests/common/sca/reachability/nodejs/examples/vite/vite.config.js b/tests/common/sca/reachability/nodejs/examples/vite/vite.config.js new file mode 100644 index 00000000000..b542651f912 --- /dev/null +++ b/tests/common/sca/reachability/nodejs/examples/vite/vite.config.js @@ -0,0 +1,7 @@ +export default { + resolve: { + alias: { + "ax": "axios" + } + } +}; \ No newline at end of file diff --git a/tests/common/sca/reachability/nodejs/examples/webpack/webpack.config.js b/tests/common/sca/reachability/nodejs/examples/webpack/webpack.config.js new file mode 100644 index 00000000000..4344076893f --- /dev/null +++ b/tests/common/sca/reachability/nodejs/examples/webpack/webpack.config.js @@ -0,0 +1,7 @@ +module.exports = { + resolve: { + alias: { + ax: 'axios' + } + } +}; \ No newline at end of file diff --git a/tests/common/sca/reachability/nodejs/test_javascript_alias_mapping_strategy.py b/tests/common/sca/reachability/nodejs/test_javascript_alias_mapping_strategy.py new file mode 100644 index 00000000000..b786300bea5 --- /dev/null +++ b/tests/common/sca/reachability/nodejs/test_javascript_alias_mapping_strategy.py @@ -0,0 +1,86 @@ +import os +from typing import Dict, Any +from checkov.common.sca.reachability.nodejs.nodejs_alias_mapping_strategy import NodejsAliasMappingStrategy +from checkov.common.sca.reachability.typing import AliasMappingObject + +current_dir = os.path.dirname(os.path.realpath(__file__)) + + +def test_create_alias_mapping_from_webpack_file(): + strategy_object = NodejsAliasMappingStrategy() + root_dir = os.path.join(current_dir, "examples", "webpack") + alias_mapping: AliasMappingObject = AliasMappingObject() + strategy_object.update_alias_mapping(alias_mapping, "supplygoat", root_dir, {'axios'}) + assert alias_mapping.model_dump() == {'languages': {'nodejs': {'repositories': {'supplygoat': {'files': {'webpack.config.js': {'packageAliases': {'axios': {'packageAliases': ['ax']}}}}}}}}} + + +def test_create_alias_mapping_from_babelrc_file(): + strategy_object = NodejsAliasMappingStrategy() + root_dir = os.path.join(current_dir, "examples", "babel", "babelrc") + alias_mapping: AliasMappingObject = AliasMappingObject() + strategy_object.update_alias_mapping(alias_mapping, "supplygoat", root_dir, {'axios'}) + assert alias_mapping.model_dump() == {'languages': {'nodejs': {'repositories': {'supplygoat': {'files': {'.babelrc': {'packageAliases': {'axios': {'packageAliases': ['ax']}}}}}}}}} + + +def test_create_alias_mapping_from_babel_config_file(): + strategy_object = NodejsAliasMappingStrategy() + root_dir = os.path.join(current_dir, "examples", "babel", "babel_config") + alias_mapping: AliasMappingObject = AliasMappingObject() + strategy_object.update_alias_mapping(alias_mapping, "supplygoat", root_dir, {'axios'}) + assert alias_mapping.model_dump() == {'languages': {'nodejs': {'repositories': {'supplygoat': {'files': {'babel.config.js': {'packageAliases': {'axios': {'packageAliases': ['ax']}}}}}}}}} + + +def test_create_alias_mapping_from_rollup_file(): + strategy_object = NodejsAliasMappingStrategy() + root_dir = os.path.join(current_dir, "examples", "rollup") + alias_mapping: AliasMappingObject = AliasMappingObject() + strategy_object.update_alias_mapping(alias_mapping, "supplygoat", root_dir, {'axios'}) + assert alias_mapping.model_dump() == {'languages': {'nodejs': {'repositories': {'supplygoat': {'files': {'rollup.config.js': {'packageAliases': {'axios': {'packageAliases': ['ax']}}}}}}}}} + + +def test_create_alias_mapping_from_package_json_alias(): + strategy_object = NodejsAliasMappingStrategy() + root_dir = os.path.join(current_dir, "examples", "package_json", "package_json_with_alias") + alias_mapping: AliasMappingObject = AliasMappingObject() + strategy_object.update_alias_mapping(alias_mapping, "supplygoat", root_dir, {'axios'}) + assert alias_mapping.model_dump() == {'languages': {'nodejs': {'repositories': {'supplygoat': {'files': {'package.json': {'packageAliases': {'axios': {'packageAliases': ['ax']}}}}}}}}} + + +def test_create_alias_mapping_from_package_json_aliasify(): + strategy_object = NodejsAliasMappingStrategy() + root_dir = os.path.join(current_dir, "examples", "package_json", "package_json_with_aliasify") + alias_mapping: AliasMappingObject = AliasMappingObject() + strategy_object.update_alias_mapping(alias_mapping, "supplygoat", root_dir, {'axios'}) + assert alias_mapping.model_dump() == {'languages': {'nodejs': {'repositories': {'supplygoat': {'files': {'package.json': {'packageAliases': {'axios': {'packageAliases': ['ax']}}}}}}}}} + + +def test_create_alias_mapping_from_snowpack(): + strategy_object = NodejsAliasMappingStrategy() + root_dir = os.path.join(current_dir, "examples", "snowpack") + alias_mapping: AliasMappingObject = AliasMappingObject() + strategy_object.update_alias_mapping(alias_mapping, "supplygoat", root_dir, {'axios'}) + assert alias_mapping.model_dump() == {'languages': {'nodejs': {'repositories': {'supplygoat': {'files': {'snowpack.config.js': {'packageAliases': {'axios': {'packageAliases': ['ax']}}}}}}}}} + + +def test_create_alias_mapping_from_vite(): + strategy_object = NodejsAliasMappingStrategy() + root_dir = os.path.join(current_dir, "examples", "vite") + alias_mapping: AliasMappingObject = AliasMappingObject() + strategy_object.update_alias_mapping(alias_mapping, "supplygoat", root_dir, {'axios'}) + assert alias_mapping.model_dump() == {'languages': {'nodejs': {'repositories': {'supplygoat': {'files': {'vite.config.js': {'packageAliases': {'axios': {'packageAliases': ['ax']}}}}}}}}} + + +def test_create_alias_mapping_mix(): + strategy_object = NodejsAliasMappingStrategy() + root_dir = os.path.join(current_dir, "examples", "mix") + alias_mapping: AliasMappingObject = AliasMappingObject() + strategy_object.update_alias_mapping(alias_mapping, "supplygoat", root_dir, {'axios'}) + assert alias_mapping.model_dump() == {'languages': {'nodejs': {'repositories': {'supplygoat': {'files': {'vite.config.js': {'packageAliases': {'axios': {'packageAliases': ['ax']}}}, 'package_json_with_alias/package.json': {'packageAliases': {'axios': {'packageAliases': ['ax']}}}}}}}}} + + +def test_create_alias_mapping_from_fake(): + strategy_object = NodejsAliasMappingStrategy() + root_dir = os.path.join(current_dir, "examples", "fake_file") + alias_mapping: AliasMappingObject = AliasMappingObject() + strategy_object.update_alias_mapping(alias_mapping, "supplygoat", root_dir, {'axios'}) + assert alias_mapping.model_dump() == {'languages': {}} diff --git a/tests/common/sca/reachability/test_alias_mapping_creator.py b/tests/common/sca/reachability/test_alias_mapping_creator.py new file mode 100644 index 00000000000..a487b599a1f --- /dev/null +++ b/tests/common/sca/reachability/test_alias_mapping_creator.py @@ -0,0 +1,29 @@ +import os +from checkov.common.sca.reachability.alias_mapping_creator import AliasMappingCreator + +current_dir = os.path.dirname(os.path.realpath(__file__)) + + +def test_alias_mapping_creator(): + alias_mapping_creator = AliasMappingCreator() + alias_mapping_creator.update_alias_mapping_for_repository("example_repo", os.path.join(current_dir, "example_repo"), {'axios'}) + alias_mapping = alias_mapping_creator.get_alias_mapping() + assert alias_mapping.model_dump() == { + "languages": { + "nodejs": { + "repositories": { + "example_repo": { + "files": { + "tsconfig.json": { + "packageAliases": { + "axios": { + "packageAliases":["ax"] + } + } + } + } + } + } + } + } + }