fix: [reportlab] Galaxies and Clusters printing

pull/358/head
Falconieri 2019-03-01 09:06:01 +01:00
parent 24e1a1732c
commit a06c8cf5b8
16 changed files with 356 additions and 217 deletions

View File

@ -10,10 +10,9 @@ codecov = "*"
requests-mock = "*" requests-mock = "*"
[packages] [packages]
pymisp = {editable = true,extras = ["fileobjects", "neo", "openioc", "virustotal"],path = "."} pymisp = {editable = true,extras = ["fileobjects", "neo", "openioc", "virustotal", "pdfexport"],path = "."}
pydeep = {editable = true,git = "https://github.com/kbandla/pydeep.git"} pydeep = {editable = true,git = "https://github.com/kbandla/pydeep.git"}
pymispwarninglists = {editable = true,git = "https://github.com/MISP/PyMISPWarningLists.git"} pymispwarninglists = {editable = true,git = "https://github.com/MISP/PyMISPWarningLists.git"}
reportlab = "*"
[requires] [requires]
python_version = "3.6" python_version = "3.6"

218
Pipfile.lock generated
View File

@ -1,7 +1,7 @@
{ {
"_meta": { "_meta": {
"hash": { "hash": {
"sha256": "2551d32f7430eba34eac975cc1b28eca13fe9faff7197d83f312d7de8df187da" "sha256": "c95b6920af9d48d6e38e0456394f752479064c9f3091cf3e6b93e751de21cfad"
}, },
"pipfile-spec": 6, "pipfile-spec": 6,
"requires": { "requires": {
@ -23,6 +23,13 @@
], ],
"version": "==0.24.0" "version": "==0.24.0"
}, },
"attrs": {
"hashes": [
"sha256:10cbf6e27dbce8c30807caf056c8eb50917e0eaafe86347671b57254006c3e69",
"sha256:ca4be454458f9dec299268d472aaa5a11f67a4ff70093396e1ceae9c76cf4bbb"
],
"version": "==18.2.0"
},
"beautifulsoup4": { "beautifulsoup4": {
"hashes": [ "hashes": [
"sha256:034740f6cb549b4e932ae1ab975581e6103ac8f942200a0e9759065984391858", "sha256:034740f6cb549b4e932ae1ab975581e6103ac8f942200a0e9759065984391858",
@ -40,40 +47,36 @@
}, },
"cffi": { "cffi": {
"hashes": [ "hashes": [
"sha256:151b7eefd035c56b2b2e1eb9963c90c6302dc15fbd8c1c0a83a163ff2c7d7743", "sha256:00b97afa72c233495560a0793cdc86c2571721b4271c0667addc83c417f3d90f",
"sha256:1553d1e99f035ace1c0544050622b7bc963374a00c467edafac50ad7bd276aef", "sha256:0ba1b0c90f2124459f6966a10c03794082a2f3985cd699d7d63c4a8dae113e11",
"sha256:1b0493c091a1898f1136e3f4f991a784437fac3673780ff9de3bcf46c80b6b50", "sha256:0bffb69da295a4fc3349f2ec7cbe16b8ba057b0a593a92cbe8396e535244ee9d",
"sha256:2ba8a45822b7aee805ab49abfe7eec16b90587f7f26df20c71dd89e45a97076f", "sha256:21469a2b1082088d11ccd79dd84157ba42d940064abbfa59cf5f024c19cf4891",
"sha256:3bb6bd7266598f318063e584378b8e27c67de998a43362e8fce664c54ee52d30", "sha256:2e4812f7fa984bf1ab253a40f1f4391b604f7fc424a3e21f7de542a7f8f7aedf",
"sha256:3c85641778460581c42924384f5e68076d724ceac0f267d66c757f7535069c93", "sha256:2eac2cdd07b9049dd4e68449b90d3ef1adc7c759463af5beb53a84f1db62e36c",
"sha256:3eb6434197633b7748cea30bf0ba9f66727cdce45117a712b29a443943733257", "sha256:2f9089979d7456c74d21303c7851f158833d48fb265876923edcb2d0194104ed",
"sha256:495c5c2d43bf6cebe0178eb3e88f9c4aa48d8934aa6e3cddb865c058da76756b", "sha256:3dd13feff00bddb0bd2d650cdb7338f815c1789a91a6f68fdc00e5c5ed40329b",
"sha256:4c91af6e967c2015729d3e69c2e51d92f9898c330d6a851bf8f121236f3defd3", "sha256:4065c32b52f4b142f417af6f33a5024edc1336aa845b9d5a8d86071f6fcaac5a",
"sha256:57b2533356cb2d8fac1555815929f7f5f14d68ac77b085d2326b571310f34f6e", "sha256:51a4ba1256e9003a3acf508e3b4f4661bebd015b8180cc31849da222426ef585",
"sha256:770f3782b31f50b68627e22f91cb182c48c47c02eb405fd689472aa7b7aa16dc", "sha256:59888faac06403767c0cf8cfb3f4a777b2939b1fbd9f729299b5384f097f05ea",
"sha256:79f9b6f7c46ae1f8ded75f68cf8ad50e5729ed4d590c74840471fc2823457d04", "sha256:59c87886640574d8b14910840327f5cd15954e26ed0bbd4e7cef95fa5aef218f",
"sha256:7a33145e04d44ce95bcd71e522b478d282ad0eafaf34fe1ec5bbd73e662f22b6", "sha256:610fc7d6db6c56a244c2701575f6851461753c60f73f2de89c79bbf1cc807f33",
"sha256:857959354ae3a6fa3da6651b966d13b0a8bed6bbc87a0de7b38a549db1d2a359", "sha256:70aeadeecb281ea901bf4230c6222af0248c41044d6f57401a614ea59d96d145",
"sha256:87f37fe5130574ff76c17cab61e7d2538a16f843bb7bca8ebbc4b12de3078596", "sha256:71e1296d5e66c59cd2c0f2d72dc476d42afe02aeddc833d8e05630a0551dad7a",
"sha256:95d5251e4b5ca00061f9d9f3d6fe537247e145a8524ae9fd30a2f8fbce993b5b", "sha256:8fc7a49b440ea752cfdf1d51a586fd08d395ff7a5d555dc69e84b1939f7ddee3",
"sha256:9d1d3e63a4afdc29bd76ce6aa9d58c771cd1599fbba8cf5057e7860b203710dd", "sha256:9b5c2afd2d6e3771d516045a6cfa11a8da9a60e3d128746a7fe9ab36dfe7221f",
"sha256:a36c5c154f9d42ec176e6e620cb0dd275744aa1d804786a71ac37dc3661a5e95", "sha256:9c759051ebcb244d9d55ee791259ddd158188d15adee3c152502d3b69005e6bd",
"sha256:a6a5cb8809091ec9ac03edde9304b3ad82ad4466333432b16d78ef40e0cce0d5", "sha256:b4d1011fec5ec12aa7cc10c05a2f2f12dfa0adfe958e56ae38dc140614035804",
"sha256:ae5e35a2c189d397b91034642cb0eab0e346f776ec2eb44a49a459e6615d6e2e", "sha256:b4f1d6332339ecc61275bebd1f7b674098a66fea11a00c84d1c58851e618dc0d",
"sha256:b0f7d4a3df8f06cf49f9f121bead236e328074de6449866515cea4907bbc63d6", "sha256:c030cda3dc8e62b814831faa4eb93dd9a46498af8cd1d5c178c2de856972fd92",
"sha256:b75110fb114fa366b29a027d0c9be3709579602ae111ff61674d28c93606acca", "sha256:c2e1f2012e56d61390c0e668c20c4fb0ae667c44d6f6a2eeea5d7148dcd3df9f",
"sha256:ba5e697569f84b13640c9e193170e89c13c6244c24400fc57e88724ef610cd31", "sha256:c37c77d6562074452120fc6c02ad86ec928f5710fbc435a181d69334b4de1d84",
"sha256:be2a9b390f77fd7676d80bc3cdc4f8edb940d8c198ed2d8c0be1319018c778e1", "sha256:c8149780c60f8fd02752d0429246088c6c04e234b895c4a42e1ea9b4de8d27fb",
"sha256:ca1bd81f40adc59011f58159e4aa6445fc585a32bb8ac9badf7a2c1aa23822f2", "sha256:cbeeef1dc3c4299bd746b774f019de9e4672f7cc666c777cd5b409f0b746dac7",
"sha256:d5d8555d9bfc3f02385c1c37e9f998e2011f0db4f90e250e5bc0c0a85a813085", "sha256:e113878a446c6228669144ae8a56e268c91b7f1fafae927adc4879d9849e0ea7",
"sha256:e55e22ac0a30023426564b1059b035973ec82186ddddbac867078435801c7801", "sha256:e21162bf941b85c0cda08224dade5def9360f53b09f9f259adb85fc7dd0e7b35",
"sha256:e90f17980e6ab0f3c2f3730e56d1fe9bcba1891eeea58966e89d352492cc74f4", "sha256:fb6934ef4744becbda3143d30c6604718871495a5e36c408431bf33d9c146889"
"sha256:ecbb7b01409e9b782df5ded849c178a0aa7c906cf8c5a67368047daab282b184",
"sha256:ed01918d545a38998bfa5902c7c00e0fee90e957ce036a4000a88e3fe2264917",
"sha256:edabd457cd23a02965166026fd9bfd196f4324fe6032e866d0f3bd0301cd486f",
"sha256:fdf1c1dc5bafc32bc5d08b054f94d659422b05aba244d6be4ddc1c72d9aa70fb"
], ],
"version": "==1.11.5" "version": "==1.12.2"
}, },
"chardet": { "chardet": {
"hashes": [ "hashes": [
@ -98,27 +101,27 @@
}, },
"cryptography": { "cryptography": {
"hashes": [ "hashes": [
"sha256:05b3ded5e88747d28ee3ef493f2b92cbb947c1e45cf98cfef22e6d38bb67d4af", "sha256:066f815f1fe46020877c5983a7e747ae140f517f1b09030ec098503575265ce1",
"sha256:06826e7f72d1770e186e9c90e76b4f84d90cdb917b47ff88d8dc59a7b10e2b1e", "sha256:210210d9df0afba9e000636e97810117dc55b7157c903a55716bb73e3ae07705",
"sha256:08b753df3672b7066e74376f42ce8fc4683e4fd1358d34c80f502e939ee944d2", "sha256:26c821cbeb683facb966045e2064303029d572a87ee69ca5a1bf54bf55f93ca6",
"sha256:2cd29bd1911782baaee890544c653bb03ec7d95ebeb144d714b0f5c33deb55c7", "sha256:2afb83308dc5c5255149ff7d3fb9964f7c9ee3d59b603ec18ccf5b0a8852e2b1",
"sha256:31e5637e9036d966824edaa91bf0aa39dc6f525a1c599f39fd5c50340264e079", "sha256:2db34e5c45988f36f7a08a7ab2b69638994a8923853dec2d4af121f689c66dc8",
"sha256:42fad67d7072216a49e34f923d8cbda9edacbf6633b19a79655e88a1b4857063", "sha256:409c4653e0f719fa78febcb71ac417076ae5e20160aec7270c91d009837b9151",
"sha256:4946b67235b9d2ea7d31307be9d5ad5959d6c4a8f98f900157b47abddf698401", "sha256:45a4f4cf4f4e6a55c8128f8b76b4c057027b27d4c67e3fe157fa02f27e37830d",
"sha256:522fdb2809603ee97a4d0ef2f8d617bc791eb483313ba307cb9c0a773e5e5695", "sha256:48eab46ef38faf1031e58dfcc9c3e71756a1108f4c9c966150b605d4a1a7f659",
"sha256:6f841c7272645dd7c65b07b7108adfa8af0aaea57f27b7f59e01d41f75444c85", "sha256:6b9e0ae298ab20d371fc26e2129fd683cfc0cfde4d157c6341722de645146537",
"sha256:7d335e35306af5b9bc0560ca39f740dfc8def72749645e193dd35be11fb323b3", "sha256:6c4778afe50f413707f604828c1ad1ff81fadf6c110cb669579dea7e2e98a75e",
"sha256:8504661ffe324837f5c4607347eeee4cf0fcad689163c6e9c8d3b18cf1f4a4ad", "sha256:8c33fb99025d353c9520141f8bc989c2134a1f76bac6369cea060812f5b5c2bb",
"sha256:9260b201ce584d7825d900c88700aa0bd6b40d4ebac7b213857bd2babee9dbca", "sha256:9873a1760a274b620a135054b756f9f218fa61ca030e42df31b409f0fb738b6c",
"sha256:9a30384cc402eac099210ab9b8801b2ae21e591831253883decdb4513b77a3cd", "sha256:9b069768c627f3f5623b1cbd3248c5e7e92aec62f4c98827059eed7053138cc9",
"sha256:9e29af877c29338f0cab5f049ccc8bd3ead289a557f144376c4fbc7d1b98914f", "sha256:9e4ce27a507e4886efbd3c32d120db5089b906979a4debf1d5939ec01b9dd6c5",
"sha256:ab50da871bc109b2d9389259aac269dd1b7c7413ee02d06fe4e486ed26882159", "sha256:acb424eaca214cb08735f1a744eceb97d014de6530c1ea23beb86d9c6f13c2ad",
"sha256:b13c80b877e73bcb6f012813c6f4a9334fcf4b0e96681c5a15dac578f2eedfa0", "sha256:c8181c7d77388fe26ab8418bb088b1a1ef5fde058c6926790c8a0a3d94075a4a",
"sha256:bfe66b577a7118e05b04141f0f1ed0959552d45672aa7ecb3d91e319d846001e", "sha256:d4afbb0840f489b60f5a580a41a1b9c3622e08ecb5eec8614d4fb4cd914c4460",
"sha256:e091bd424567efa4b9d94287a952597c05d22155a13716bf5f9f746b9dc906d3", "sha256:d9ed28030797c00f4bc43c86bf819266c76a5ea61d006cd4078a93ebf7da6bfd",
"sha256:fa2b38c8519c5a3aa6e2b4e1cf1a549b54acda6adb25397ff542068e73d1ed00" "sha256:e603aa7bb52e4e8ed4119a58a03b60323918467ef209e6ff9db3ac382e5cf2c6"
], ],
"version": "==2.5" "version": "==2.6.1"
}, },
"decorator": { "decorator": {
"hashes": [ "hashes": [
@ -143,10 +146,10 @@
}, },
"jsonschema": { "jsonschema": {
"hashes": [ "hashes": [
"sha256:000e68abd33c972a5248544925a0cae7d1125f9bf6c58280d37546b946769a08", "sha256:acc8a90c31d11060516cfd0b414b9f8bcf4bc691b21f0f786ea57dd5255c79db",
"sha256:6ff5f3180870836cae40f06fa10419f557208175f13ad7bc26caa77beb1f6e02" "sha256:dd3f8ecb1b52d94d45eedb67cb86cac57b94ded562c5d98f63719e55ce58557b"
], ],
"version": "==2.6.0" "version": "==3.0.0"
}, },
"lief": { "lief": {
"hashes": [ "hashes": [
@ -156,9 +159,9 @@
}, },
"neobolt": { "neobolt": {
"hashes": [ "hashes": [
"sha256:f70df7422568f3f92f065482237dabe3b96cd49a921c5e17feb1c9e68fdd0357" "sha256:3324f2b319e84acb82e37a81ef75f3f7ce71c149387daf900589377db48bed2a"
], ],
"version": "==1.7.3" "version": "==1.7.4"
}, },
"neotime": { "neotime": {
"hashes": [ "hashes": [
@ -166,13 +169,48 @@
], ],
"version": "==1.7.4" "version": "==1.7.4"
}, },
"pillow": {
"hashes": [
"sha256:051de330a06c99d6f84bcf582960487835bcae3fc99365185dc2d4f65a390c0e",
"sha256:0ae5289948c5e0a16574750021bd8be921c27d4e3527800dc9c2c1d2abc81bf7",
"sha256:0b1efce03619cdbf8bcc61cfae81fcda59249a469f31c6735ea59badd4a6f58a",
"sha256:163136e09bd1d6c6c6026b0a662976e86c58b932b964f255ff384ecc8c3cefa3",
"sha256:18e912a6ccddf28defa196bd2021fe33600cbe5da1aa2f2e2c6df15f720b73d1",
"sha256:24ec3dea52339a610d34401d2d53d0fb3c7fd08e34b20c95d2ad3973193591f1",
"sha256:267f8e4c0a1d7e36e97c6a604f5b03ef58e2b81c1becb4fccecddcb37e063cc7",
"sha256:3273a28734175feebbe4d0a4cde04d4ed20f620b9b506d26f44379d3c72304e1",
"sha256:4c678e23006798fc8b6f4cef2eaad267d53ff4c1779bd1af8725cc11b72a63f3",
"sha256:4d4bc2e6bb6861103ea4655d6b6f67af8e5336e7216e20fff3e18ffa95d7a055",
"sha256:505738076350a337c1740a31646e1de09a164c62c07db3b996abdc0f9d2e50cf",
"sha256:5233664eadfa342c639b9b9977190d64ad7aca4edc51a966394d7e08e7f38a9f",
"sha256:5d95cb9f6cced2628f3e4de7e795e98b2659dfcc7176ab4a01a8b48c2c2f488f",
"sha256:7eda4c737637af74bac4b23aa82ea6fbb19002552be85f0b89bc27e3a762d239",
"sha256:801ddaa69659b36abf4694fed5aa9f61d1ecf2daaa6c92541bbbbb775d97b9fe",
"sha256:825aa6d222ce2c2b90d34a0ea31914e141a85edefc07e17342f1d2fdf121c07c",
"sha256:9c215442ff8249d41ff58700e91ef61d74f47dfd431a50253e1a1ca9436b0697",
"sha256:a3d90022f2202bbb14da991f26ca7a30b7e4c62bf0f8bf9825603b22d7e87494",
"sha256:a631fd36a9823638fe700d9225f9698fb59d049c942d322d4c09544dc2115356",
"sha256:a6523a23a205be0fe664b6b8747a5c86d55da960d9586db039eec9f5c269c0e6",
"sha256:a756ecf9f4b9b3ed49a680a649af45a8767ad038de39e6c030919c2f443eb000",
"sha256:b117287a5bdc81f1bac891187275ec7e829e961b8032c9e5ff38b70fd036c78f",
"sha256:ba04f57d1715ca5ff74bb7f8a818bf929a204b3b3c2c2826d1e1cc3b1c13398c",
"sha256:cd878195166723f30865e05d87cbaf9421614501a4bd48792c5ed28f90fd36ca",
"sha256:cee815cc62d136e96cf76771b9d3eb58e0777ec18ea50de5cfcede8a7c429aa8",
"sha256:d1722b7aa4b40cf93ac3c80d3edd48bf93b9208241d166a14ad8e7a20ee1d4f3",
"sha256:d7c1c06246b05529f9984435fc4fa5a545ea26606e7f450bdbe00c153f5aeaad",
"sha256:e9c8066249c040efdda84793a2a669076f92a301ceabe69202446abb4c5c5ef9",
"sha256:f227d7e574d050ff3996049e086e1f18c7bd2d067ef24131e50a1d3fe5831fbc",
"sha256:fc9a12aad714af36cf3ad0275a96a733526571e52710319855628f476dcb144e"
],
"version": "==5.4.1"
},
"prompt-toolkit": { "prompt-toolkit": {
"hashes": [ "hashes": [
"sha256:88002cc618cacfda8760c4539e76c3b3f148ecdb7035a3d422c7ecdc90c2a3ba", "sha256:11adf3389a996a6d45cc277580d0d53e8a5afd281d0c9ec71b28e6f121463780",
"sha256:c6655a12e9b08edb8cf5aeab4815fd1e1bdea4ad73d3bbf269cf2e0c4eb75d5e", "sha256:2519ad1d8038fd5fc8e770362237ad0364d16a7650fb5724af6997ed5515e3c1",
"sha256:df5835fb8f417aa55e5cafadbaeb0cf630a1e824aad16989f9f0493e679ec010" "sha256:977c6583ae813a37dc1c2e1b715892461fcbdaa57f6fc62f33a528c4886c8f55"
], ],
"version": "==2.0.8" "version": "==2.0.9"
}, },
"py2neo": { "py2neo": {
"hashes": [ "hashes": [
@ -204,7 +242,8 @@
"fileobjects", "fileobjects",
"neo", "neo",
"openioc", "openioc",
"virustotal" "virustotal",
"pdfexport"
], ],
"path": "." "path": "."
}, },
@ -220,6 +259,12 @@
], ],
"version": "==19.0.0" "version": "==19.0.0"
}, },
"pyrsistent": {
"hashes": [
"sha256:3ca82748918eb65e2d89f222b702277099aca77e34843c5eb9d52451173970e2"
],
"version": "==0.14.11"
},
"python-dateutil": { "python-dateutil": {
"hashes": [ "hashes": [
"sha256:7e6584c74aeed623791615e26efd690f29817a27c73085b78e4bad02493df2fb", "sha256:7e6584c74aeed623791615e26efd690f29817a27c73085b78e4bad02493df2fb",
@ -241,6 +286,39 @@
], ],
"version": "==2018.9" "version": "==2018.9"
}, },
"reportlab": {
"hashes": [
"sha256:069f684cd0aaa518a27dc9124aed29cee8998e21ddf19604e53214ec8462bdd7",
"sha256:09b68ec01d86b4b120456b3f3202570ec96f57624e3a4fc36f3829323391daa4",
"sha256:0c32be9a406172c29ea20ff55a709ccac1e7fb09f15aba67cb7b455fd1d3dbe0",
"sha256:233196cf25e97cfe7c452524ea29d9a4909f1cb66599299233be1efaaaa7a7a3",
"sha256:2b5e4533f3e5b962835a5ce44467e66d1ecc822761d1b508077b5087a06be338",
"sha256:2e860bcdace5a558356802a92ae8658d7e5fdaa00ded82e83a3f2987c562cb66",
"sha256:3546029e63a9a9dc24ee38959eb417678c2425b96cd27b31e09e216dafc94666",
"sha256:4452b93f9c73b6b70311e7d69082d64da81b38e91bfb4766397630092e6da6fd",
"sha256:528c74a1c6527d1859c2c7a64a94a1cba485b00175162ea23699ae58a1e94939",
"sha256:6116e750f98018febc08dfee6df20446cf954adbcfa378d2c703d56c8864aff3",
"sha256:6b2b3580c647d75ef129172cb3da648cdb24566987b0b59c5ebb80ab770748d6",
"sha256:727b5f2bed08552d143fc99649b1863c773729f580a416844f9d9967bb0a1ae8",
"sha256:74c24a3ec0a3d4f8acb13a07192f45bdb54a1cc3c2286241677e7e8bcd5011fa",
"sha256:98ccd2f8b4f8636db05f3f14db0b471ad6bb4b66ae0dc9052c4822b3bd5d6a7d",
"sha256:a5905aa567946bc938b489a7249c7890c3fd3c9b7b5680dece5bc551c2ddbe0d",
"sha256:acbb7f676b8586b770719e9683eda951fdb38eb7970d46fcbf3cdda88d912a64",
"sha256:b5e30f865add48cf880f1c363eb505b97f2f7baaa88c155f87a335a76515a3e5",
"sha256:be2a7c33a2c28bbd3f453ffe4f0e5200b88c803a097f4cf52d69c6b53fad7a8f",
"sha256:c356bb600f59ac64955813d6497a08bfd5d0c451cb5829b61e3913d0ac084e26",
"sha256:c7ec4ae2393beab584921b1287a04e94fd98c28315e348362d89b85f4b464546",
"sha256:d476edc831bb3e9ebd04d1403abaf3ea57b3e4c2276c91a54fdfb6efbd3f9d97",
"sha256:db059e1a0691c872784062421ec51848539eb4f5210142682e61059a5ca7cc55",
"sha256:dd423a6753509ab14a0ac1b5be39d219c8f8d3781cce3deb4f45eda31969b5e8",
"sha256:ed9b7c0d71ce6fe2b31c6cde530ad8238632b876a5d599218739bda142a77f7c",
"sha256:f0a2465af4006f97b05e1f1546d67d3a3213d414894bf28be7f87f550a7f4a55",
"sha256:f20bfe26e57e8e1f575a9e0325be04dd3562db9f247ffdd73b5d4df6dec53bc2",
"sha256:f3463f2cb40a1b515ac0133ba859eca58f53b56760da9abb27ed684c565f853c",
"sha256:facc3c9748ab1525fb8401a1223bce4f24f0d6aa1a9db86c55db75777ccf40f9"
],
"version": "==3.5.13"
},
"requests": { "requests": {
"hashes": [ "hashes": [
"sha256:502a824f31acdacb3a35b6690b5fbf0bc41d63a24a45c4004352b0242707598e", "sha256:502a824f31acdacb3a35b6690b5fbf0bc41d63a24a45c4004352b0242707598e",
@ -257,10 +335,10 @@
}, },
"soupsieve": { "soupsieve": {
"hashes": [ "hashes": [
"sha256:466910df7561796a60748826781ebe9a888f7a1668a636ae86783f44d10aae73", "sha256:afa56bf14907bb09403e5d15fbed6275caa4174d36b975226e3b67a3bb6e2c4b",
"sha256:87db12ae79194f0ff9808d2b1641c4f031ae39ffa3cab6b907ea7c1e5e5ed445" "sha256:eaed742b48b1f3e2d45ba6f79401b2ed5dc33b2123dfe216adb90d4bfa0ade26"
], ],
"version": "==1.7.3" "version": "==1.8"
}, },
"urllib3": { "urllib3": {
"extras": [ "extras": [
@ -347,11 +425,11 @@
}, },
"coveralls": { "coveralls": {
"hashes": [ "hashes": [
"sha256:ab638e88d38916a6cedbf80a9cd8992d5fa55c77ab755e262e00b36792b7cd6d", "sha256:6f213e461390973f4a97fb9e9d4ebd4956af296ff0a4d868e622108145835cb7",
"sha256:b2388747e2529fa4c669fb1e3e2756e4e07b6ee56c7d9fce05f35ccccc913aa0" "sha256:a7d0078c9e9b5692c03dcd3884647e837836c265c01e98094632feadef767d36"
], ],
"index": "pypi", "index": "pypi",
"version": "==1.5.1" "version": "==1.6.0"
}, },
"docopt": { "docopt": {
"hashes": [ "hashes": [

View File

@ -4,6 +4,8 @@ README
[![Documentation Status](https://readthedocs.org/projects/pymisp/badge/?version=latest)](http://pymisp.readthedocs.io/?badge=latest) [![Documentation Status](https://readthedocs.org/projects/pymisp/badge/?version=latest)](http://pymisp.readthedocs.io/?badge=latest)
[![Build Status](https://travis-ci.org/MISP/PyMISP.svg?branch=master)](https://travis-ci.org/MISP/PyMISP) [![Build Status](https://travis-ci.org/MISP/PyMISP.svg?branch=master)](https://travis-ci.org/MISP/PyMISP)
[![Coverage Status](https://coveralls.io/repos/github/MISP/PyMISP/badge.svg?branch=master)](https://coveralls.io/github/MISP/PyMISP?branch=master) [![Coverage Status](https://coveralls.io/repos/github/MISP/PyMISP/badge.svg?branch=master)](https://coveralls.io/github/MISP/PyMISP?branch=master)
[![Python 3.6](https://img.shields.io/badge/python-3.6+-blue.svg)](https://www.python.org/downloads/release/python-360/)
[![PyPi version](https://img.shields.io/pypi/v/pymisp.svg)](https://pypi.python.org/pypi/pymisp/)
# PyMISP - Python Library to access MISP # PyMISP - Python Library to access MISP

View File

@ -23,7 +23,7 @@
"misp_url = 'http://127.0.0.1:8080'\n", "misp_url = 'http://127.0.0.1:8080'\n",
"# Can be found in the MISP web interface under \n", "# Can be found in the MISP web interface under \n",
"# http://+MISP_URL+/users/view/me -> Authkey\n", "# http://+MISP_URL+/users/view/me -> Authkey\n",
"misp_key = 'LBelWqKY9SQyG0huZzAMqiEBl6FODxpgRRXMsZFu'\n", "misp_key = 'aJAmQQoBhVL5jqUDSucIkPrEYIbFyW0wwQnxyBfc'\n",
"# Should PyMISP verify the MISP certificate\n", "# Should PyMISP verify the MISP certificate\n",
"misp_verifycert = False" "misp_verifycert = False"
] ]
@ -87,10 +87,11 @@
}, },
"outputs": [], "outputs": [],
"source": [ "source": [
"response = misp.search(publish_timestamp='2h')\n", "response = misp.search(publish_timestamp='2d')\n",
"\n", "\n",
"print (response)\n",
"events = []\n", "events = []\n",
"for event in response['response']:\n", "for event in response:\n",
" me = MISPEvent()\n", " me = MISPEvent()\n",
" me.load(event)\n", " me.load(event)\n",
" events.append(me)\n", " events.append(me)\n",
@ -133,7 +134,7 @@
"response = misp.search(timestamp=ts-36000)\n", "response = misp.search(timestamp=ts-36000)\n",
"\n", "\n",
"events = []\n", "events = []\n",
"for event in response['response']:\n", "for event in response:\n",
" me = MISPEvent()\n", " me = MISPEvent()\n",
" me.load(event)\n", " me.load(event)\n",
" events.append(me)\n", " events.append(me)\n",
@ -179,10 +180,10 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"response = misp.search(controller='attributes', publish_timestamp='1h')\n", "response = misp.search(controller='attributes', publish_timestamp='1d')\n",
"\n", "\n",
"attributes = []\n", "attributes = []\n",
"for attribute in response['response']['Attribute']:\n", "for attribute in response['Attribute']:\n",
" ma = MISPAttribute()\n", " ma = MISPAttribute()\n",
" ma.from_dict(**attribute)\n", " ma.from_dict(**attribute)\n",
" attributes.append(ma)\n", " attributes.append(ma)\n",
@ -197,10 +198,10 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"response = misp.search(controller='attributes', publish_timestamp=['2h', '1h'])\n", "response = misp.search(controller='attributes', publish_timestamp=['2d', '1h'])\n",
"\n", "\n",
"attributes = []\n", "attributes = []\n",
"for attribute in response['response']['Attribute']:\n", "for attribute in response['Attribute']:\n",
" ma = MISPAttribute()\n", " ma = MISPAttribute()\n",
" ma.from_dict(**attribute)\n", " ma.from_dict(**attribute)\n",
" attributes.append(ma)\n", " attributes.append(ma)\n",
@ -229,7 +230,7 @@
"response = misp.search(controller='attributes', timestamp=ts - 36000)\n", "response = misp.search(controller='attributes', timestamp=ts - 36000)\n",
"\n", "\n",
"attributes = []\n", "attributes = []\n",
"for attribute in response['response']['Attribute']:\n", "for attribute in response['Attribute']:\n",
" ma = MISPAttribute()\n", " ma = MISPAttribute()\n",
" ma.from_dict(**attribute)\n", " ma.from_dict(**attribute)\n",
" attributes.append(ma)\n", " attributes.append(ma)\n",
@ -256,7 +257,7 @@
"response = misp.search_index(eventinfo='Cobalt Strike')\n", "response = misp.search_index(eventinfo='Cobalt Strike')\n",
"\n", "\n",
"events = []\n", "events = []\n",
"for event in response['response']:\n", "for event in response:\n",
" me = MISPEvent()\n", " me = MISPEvent()\n",
" me.from_dict(**event)\n", " me.from_dict(**event)\n",
" events.append(me)\n", " events.append(me)\n",
@ -280,10 +281,10 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"response = misp.search_index(tag='malware_classification:malware-category=\"Ransomware\"')\n", "response = misp.search_index(tags='malware_classification:malware-category=\"Ransomware\"')\n",
"\n", "\n",
"events = []\n", "events = []\n",
"for event in response['response']:\n", "for event in response:\n",
" me = MISPEvent()\n", " me = MISPEvent()\n",
" me.from_dict(**event)\n", " me.from_dict(**event)\n",
" events.append(me)\n", " events.append(me)\n",
@ -303,7 +304,7 @@
"response = misp.search_index(timestamp='1h')\n", "response = misp.search_index(timestamp='1h')\n",
"\n", "\n",
"events = []\n", "events = []\n",
"for event in response['response']:\n", "for event in response:\n",
" me = MISPEvent()\n", " me = MISPEvent()\n",
" me.from_dict(**event)\n", " me.from_dict(**event)\n",
" events.append(me)\n", " events.append(me)\n",
@ -328,8 +329,9 @@
"outputs": [], "outputs": [],
"source": [ "source": [
"event = MISPEvent()\n", "event = MISPEvent()\n",
"event.load(misp.get(events[0].id))\n", "#event.load(misp.get(events[0].id))\n",
"print(event.to_json())" "print (misp.get(events[0].id))\n",
"#print(event.to_json())"
] ]
}, },
{ {
@ -345,7 +347,7 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"complex_query = misp.build_complex_query(or_parameters=['59.157.4.2', 'hotfixmsupload.com'])\n", "complex_query = misp.build_complex_query(or_parameters=['59.157.4.2', 'hotfixmsupload.com', '8.8.8.8'])\n",
"events = misp.search(value=complex_query, pythonify=True)\n", "events = misp.search(value=complex_query, pythonify=True)\n",
"\n", "\n",
"for e in events:\n", "for e in events:\n",
@ -365,7 +367,7 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"misp.sighting(value=e.attributes[3].value)" "misp.sighting(value=e.attributes[1].value)"
] ]
}, },
{ {
@ -374,7 +376,7 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"misp.sighting_list(e.attributes[3].id)" "misp.sighting_list(e.attributes[1].id)"
] ]
}, },
{ {

View File

@ -42,7 +42,17 @@ try:
from .tools import openioc # noqa from .tools import openioc # noqa
from .tools import load_warninglists # noqa from .tools import load_warninglists # noqa
from .tools import ext_lookups # noqa from .tools import ext_lookups # noqa
from .tools import reportlab_generator # noqa
if sys.version_info >= (3, 4):
# Let's not bother with python 2
try:
from .tools import reportlab_generator # noqa
except ImportError:
# FIXME: The import should not raise an exception if reportlab isn't installed
pass
except NameError:
# FIXME: The import should not raise an exception if reportlab isn't installed
pass
if sys.version_info >= (3, 6): if sys.version_info >= (3, 6):
from .aping import ExpandedPyMISP # noqa from .aping import ExpandedPyMISP # noqa
logger.debug('pymisp loaded properly') logger.debug('pymisp loaded properly')

View File

@ -69,9 +69,10 @@ class PyMISP(object):
:param proxies: Proxy dict as describes here: http://docs.python-requests.org/en/master/user/advanced/#proxies :param proxies: Proxy dict as describes here: http://docs.python-requests.org/en/master/user/advanced/#proxies
:param cert: Client certificate, as described there: http://docs.python-requests.org/en/master/user/advanced/#client-side-certificates :param cert: Client certificate, as described there: http://docs.python-requests.org/en/master/user/advanced/#client-side-certificates
:param asynch: Use asynchronous processing where possible :param asynch: Use asynchronous processing where possible
:param auth: The auth parameter is passed directly to requests, as described here: http://docs.python-requests.org/en/master/user/authentication/
""" """
def __init__(self, url, key, ssl=True, out_type='json', debug=None, proxies=None, cert=None, asynch=False): def __init__(self, url, key, ssl=True, out_type='json', debug=None, proxies=None, cert=None, asynch=False, auth=None):
if not url: if not url:
raise NoURL('Please provide the URL of your MISP instance.') raise NoURL('Please provide the URL of your MISP instance.')
if not key: if not key:
@ -83,6 +84,7 @@ class PyMISP(object):
self.proxies = proxies self.proxies = proxies
self.cert = cert self.cert = cert
self.asynch = asynch self.asynch = asynch
self.auth = auth
if asynch and not ASYNC_OK: if asynch and not ASYNC_OK:
logger.critical("You turned on Async, but don't have requests_futures installed") logger.critical("You turned on Async, but don't have requests_futures installed")
self.asynch = False self.asynch = False
@ -169,6 +171,7 @@ class PyMISP(object):
else: else:
local_session = requests.Session local_session = requests.Session
with local_session() as s: with local_session() as s:
req.auth = self.auth
prepped = s.prepare_request(req) prepped = s.prepare_request(req)
prepped.headers.update( prepped.headers.update(
{'Authorization': self.key, {'Authorization': self.key,
@ -1779,7 +1782,7 @@ class PyMISP(object):
def get_roles_list(self): def get_roles_list(self):
"""Get the list of existing roles""" """Get the list of existing roles"""
url = urljoin(self.root_url, '/roles') url = urljoin(self.root_url, 'roles')
response = self._prepare_request('GET', url) response = self._prepare_request('GET', url)
return self._check_response(response) return self._check_response(response)
@ -1787,13 +1790,13 @@ class PyMISP(object):
def get_tags_list(self): def get_tags_list(self):
"""Get the list of existing tags.""" """Get the list of existing tags."""
url = urljoin(self.root_url, '/tags') url = urljoin(self.root_url, 'tags')
response = self._prepare_request('GET', url) response = self._prepare_request('GET', url)
return self._check_response(response)['Tag'] return self._check_response(response)['Tag']
def get_tag(self, tag_id): def get_tag(self, tag_id):
"""Get a tag by id.""" """Get a tag by id."""
url = urljoin(self.root_url, '/tags/view/{}'.format(tag_id)) url = urljoin(self.root_url, 'tags/view/{}'.format(tag_id))
response = self._prepare_request('GET', url) response = self._prepare_request('GET', url)
return self._check_response(response) return self._check_response(response)
@ -1827,7 +1830,7 @@ class PyMISP(object):
old_tag = self.get_tag(tag_id) old_tag = self.get_tag(tag_id)
new_tag = self._set_tag_parameters(name, colour, exportable, hide_tag, org_id, count, user_id, new_tag = self._set_tag_parameters(name, colour, exportable, hide_tag, org_id, count, user_id,
numerical_value, attribute_count, old_tag) numerical_value, attribute_count, old_tag)
url = urljoin(self.root_url, '/tags/edit/{}'.format(tag_id)) url = urljoin(self.root_url, 'tags/edit/{}'.format(tag_id))
response = self._prepare_request('POST', url, json.dumps(new_tag)) response = self._prepare_request('POST', url, json.dumps(new_tag))
return self._check_response(response) return self._check_response(response)
@ -1835,7 +1838,7 @@ class PyMISP(object):
"""Edit the tag using a json file.""" """Edit the tag using a json file."""
with open(json_file, 'rb') as f: with open(json_file, 'rb') as f:
jdata = json.load(f) jdata = json.load(f)
url = urljoin(self.root_url, '/tags/edit/{}'.format(tag_id)) url = urljoin(self.root_url, 'tags/edit/{}'.format(tag_id))
response = self._prepare_request('POST', url, json.dumps(jdata)) response = self._prepare_request('POST', url, json.dumps(jdata))
return self._check_response(response) return self._check_response(response)
@ -1853,38 +1856,38 @@ class PyMISP(object):
def get_taxonomies_list(self): def get_taxonomies_list(self):
"""Get all the taxonomies.""" """Get all the taxonomies."""
url = urljoin(self.root_url, '/taxonomies') url = urljoin(self.root_url, 'taxonomies')
response = self._prepare_request('GET', url) response = self._prepare_request('GET', url)
return self._check_response(response) return self._check_response(response)
def get_taxonomy(self, taxonomy_id): def get_taxonomy(self, taxonomy_id):
"""Get a taxonomy by id.""" """Get a taxonomy by id."""
url = urljoin(self.root_url, '/taxonomies/view/{}'.format(taxonomy_id)) url = urljoin(self.root_url, 'taxonomies/view/{}'.format(taxonomy_id))
response = self._prepare_request('GET', url) response = self._prepare_request('GET', url)
return self._check_response(response) return self._check_response(response)
def update_taxonomies(self): def update_taxonomies(self):
"""Update all the taxonomies.""" """Update all the taxonomies."""
url = urljoin(self.root_url, '/taxonomies/update') url = urljoin(self.root_url, 'taxonomies/update')
response = self._prepare_request('POST', url) response = self._prepare_request('POST', url)
return self._check_response(response) return self._check_response(response)
def enable_taxonomy(self, taxonomy_id): def enable_taxonomy(self, taxonomy_id):
"""Enable a taxonomy by id.""" """Enable a taxonomy by id."""
url = urljoin(self.root_url, '/taxonomies/enable/{}'.format(taxonomy_id)) url = urljoin(self.root_url, 'taxonomies/enable/{}'.format(taxonomy_id))
response = self._prepare_request('POST', url) response = self._prepare_request('POST', url)
return self._check_response(response) return self._check_response(response)
def disable_taxonomy(self, taxonomy_id): def disable_taxonomy(self, taxonomy_id):
"""Disable a taxonomy by id.""" """Disable a taxonomy by id."""
self.disable_taxonomy_tags(taxonomy_id) self.disable_taxonomy_tags(taxonomy_id)
url = urljoin(self.root_url, '/taxonomies/disable/{}'.format(taxonomy_id)) url = urljoin(self.root_url, 'taxonomies/disable/{}'.format(taxonomy_id))
response = self._prepare_request('POST', url) response = self._prepare_request('POST', url)
return self._check_response(response) return self._check_response(response)
def get_taxonomy_tags_list(self, taxonomy_id): def get_taxonomy_tags_list(self, taxonomy_id):
"""Get all the tags of a taxonomy by id.""" """Get all the tags of a taxonomy by id."""
url = urljoin(self.root_url, '/taxonomies/view/{}'.format(taxonomy_id)) url = urljoin(self.root_url, 'taxonomies/view/{}'.format(taxonomy_id))
response = self._prepare_request('GET', url) response = self._prepare_request('GET', url)
return self._check_response(response)["entries"] return self._check_response(response)["entries"]
@ -1892,13 +1895,13 @@ class PyMISP(object):
"""Enable all the tags of a taxonomy by id.""" """Enable all the tags of a taxonomy by id."""
enabled = self.get_taxonomy(taxonomy_id)['Taxonomy']['enabled'] enabled = self.get_taxonomy(taxonomy_id)['Taxonomy']['enabled']
if enabled: if enabled:
url = urljoin(self.root_url, '/taxonomies/addTag/{}'.format(taxonomy_id)) url = urljoin(self.root_url, 'taxonomies/addTag/{}'.format(taxonomy_id))
response = self._prepare_request('POST', url) response = self._prepare_request('POST', url)
return self._check_response(response) return self._check_response(response)
def disable_taxonomy_tags(self, taxonomy_id): def disable_taxonomy_tags(self, taxonomy_id):
"""Disable all the tags of a taxonomy by id.""" """Disable all the tags of a taxonomy by id."""
url = urljoin(self.root_url, '/taxonomies/disableTag/{}'.format(taxonomy_id)) url = urljoin(self.root_url, 'taxonomies/disableTag/{}'.format(taxonomy_id))
response = self._prepare_request('POST', url) response = self._prepare_request('POST', url)
return self._check_response(response) return self._check_response(response)
@ -1906,19 +1909,19 @@ class PyMISP(object):
def get_warninglists(self): def get_warninglists(self):
"""Get all the warninglists.""" """Get all the warninglists."""
url = urljoin(self.root_url, '/warninglists') url = urljoin(self.root_url, 'warninglists')
response = self._prepare_request('GET', url) response = self._prepare_request('GET', url)
return self._check_response(response) return self._check_response(response)
def get_warninglist(self, warninglist_id): def get_warninglist(self, warninglist_id):
"""Get a warninglist by id.""" """Get a warninglist by id."""
url = urljoin(self.root_url, '/warninglists/view/{}'.format(warninglist_id)) url = urljoin(self.root_url, 'warninglists/view/{}'.format(warninglist_id))
response = self._prepare_request('GET', url) response = self._prepare_request('GET', url)
return self._check_response(response) return self._check_response(response)
def update_warninglists(self): def update_warninglists(self):
"""Update all the warninglists.""" """Update all the warninglists."""
url = urljoin(self.root_url, '/warninglists/update') url = urljoin(self.root_url, 'warninglists/update')
response = self._prepare_request('POST', url) response = self._prepare_request('POST', url)
return self._check_response(response) return self._check_response(response)
@ -1940,7 +1943,7 @@ class PyMISP(object):
query['name'] = warninglist_name query['name'] = warninglist_name
if force_enable is not None: if force_enable is not None:
query['enabled'] = force_enable query['enabled'] = force_enable
url = urljoin(self.root_url, '/warninglists/toggleEnable') url = urljoin(self.root_url, 'warninglists/toggleEnable')
response = self._prepare_request('POST', url, json.dumps(query)) response = self._prepare_request('POST', url, json.dumps(query))
return self._check_response(response) return self._check_response(response)
@ -1954,7 +1957,7 @@ class PyMISP(object):
def check_warninglist(self, value): def check_warninglist(self, value):
"""Check if IOC values are in warninglist""" """Check if IOC values are in warninglist"""
url = urljoin(self.root_url, '/warninglists/checkValue') url = urljoin(self.root_url, 'warninglists/checkValue')
response = self._prepare_request('POST', url, json.dumps(value)) response = self._prepare_request('POST', url, json.dumps(value))
return self._check_response(response) return self._check_response(response)
@ -1962,31 +1965,31 @@ class PyMISP(object):
def get_noticelists(self): def get_noticelists(self):
"""Get all the noticelists.""" """Get all the noticelists."""
url = urljoin(self.root_url, '/noticelists') url = urljoin(self.root_url, 'noticelists')
response = self._prepare_request('GET', url) response = self._prepare_request('GET', url)
return self._check_response(response) return self._check_response(response)
def get_noticelist(self, noticelist_id): def get_noticelist(self, noticelist_id):
"""Get a noticelist by id.""" """Get a noticelist by id."""
url = urljoin(self.root_url, '/noticelists/view/{}'.format(noticelist_id)) url = urljoin(self.root_url, 'noticelists/view/{}'.format(noticelist_id))
response = self._prepare_request('GET', url) response = self._prepare_request('GET', url)
return self._check_response(response) return self._check_response(response)
def update_noticelists(self): def update_noticelists(self):
"""Update all the noticelists.""" """Update all the noticelists."""
url = urljoin(self.root_url, '/noticelists/update') url = urljoin(self.root_url, 'noticelists/update')
response = self._prepare_request('POST', url) response = self._prepare_request('POST', url)
return self._check_response(response) return self._check_response(response)
def enable_noticelist(self, noticelist_id): def enable_noticelist(self, noticelist_id):
"""Enable a noticelist by id.""" """Enable a noticelist by id."""
url = urljoin(self.root_url, '/noticelists/enableNoticelist/{}/true'.format(noticelist_id)) url = urljoin(self.root_url, 'noticelists/enableNoticelist/{}/true'.format(noticelist_id))
response = self._prepare_request('POST', url) response = self._prepare_request('POST', url)
return self._check_response(response) return self._check_response(response)
def disable_noticelist(self, noticelist_id): def disable_noticelist(self, noticelist_id):
"""Disable a noticelist by id.""" """Disable a noticelist by id."""
url = urljoin(self.root_url, '/noticelists/enableNoticelist/{}'.format(noticelist_id)) url = urljoin(self.root_url, 'noticelists/enableNoticelist/{}'.format(noticelist_id))
response = self._prepare_request('POST', url) response = self._prepare_request('POST', url)
return self._check_response(response) return self._check_response(response)
@ -1994,19 +1997,19 @@ class PyMISP(object):
def get_galaxies(self): def get_galaxies(self):
"""Get all the galaxies.""" """Get all the galaxies."""
url = urljoin(self.root_url, '/galaxies') url = urljoin(self.root_url, 'galaxies')
response = self._prepare_request('GET', url) response = self._prepare_request('GET', url)
return self._check_response(response) return self._check_response(response)
def get_galaxy(self, galaxy_id): def get_galaxy(self, galaxy_id):
"""Get a galaxy by id.""" """Get a galaxy by id."""
url = urljoin(self.root_url, '/galaxies/view/{}'.format(galaxy_id)) url = urljoin(self.root_url, 'galaxies/view/{}'.format(galaxy_id))
response = self._prepare_request('GET', url) response = self._prepare_request('GET', url)
return self._check_response(response) return self._check_response(response)
def update_galaxies(self): def update_galaxies(self):
"""Update all the galaxies.""" """Update all the galaxies."""
url = urljoin(self.root_url, '/galaxies/update') url = urljoin(self.root_url, 'galaxies/update')
response = self._prepare_request('POST', url) response = self._prepare_request('POST', url)
return self._check_response(response) return self._check_response(response)
@ -2046,7 +2049,7 @@ class PyMISP(object):
if tags: if tags:
if isinstance(tags, list): if isinstance(tags, list):
tags = "&&".join(tags) tags = "&&".join(tags)
url = urljoin(self.root_url, "/events/stix/download/{}/{}/{}/{}/{}".format( url = urljoin(self.root_url, "events/stix/download/{}/{}/{}/{}/{}".format(
event_id, with_attachments, tags, from_date, to_date)) event_id, with_attachments, tags, from_date, to_date))
logger.debug("Getting STIX event from %s", url) logger.debug("Getting STIX event from %s", url)
response = self._prepare_request('GET', url) response = self._prepare_request('GET', url)
@ -2064,7 +2067,7 @@ class PyMISP(object):
:param context: Add event level context (event_info,event_member_org,event_source_org,event_distribution,event_threat_level_id,event_analysis,event_date,event_tag) :param context: Add event level context (event_info,event_member_org,event_source_org,event_distribution,event_threat_level_id,event_analysis,event_date,event_tag)
:param ignore: Returns the attributes even if the event isn't published, or the attribute doesn't have the to_ids flag set :param ignore: Returns the attributes even if the event isn't published, or the attribute doesn't have the to_ids flag set
""" """
url = urljoin(self.root_url, '/events/csv/download') url = urljoin(self.root_url, 'events/csv/download')
to_post = {} to_post = {}
if eventid: if eventid:
to_post['eventid'] = eventid to_post['eventid'] = eventid
@ -2217,7 +2220,7 @@ class PyMISP(object):
:extend: Allow the organisation to extend the group :extend: Allow the organisation to extend the group
''' '''
to_jsonify = {'sg_id': sharing_group, 'org_id': organisation, 'extend': extend} to_jsonify = {'sg_id': sharing_group, 'org_id': organisation, 'extend': extend}
url = urljoin(self.root_url, '/sharingGroups/addOrg') url = urljoin(self.root_url, 'sharingGroups/addOrg')
response = self._prepare_request('POST', url, json.dumps(to_jsonify)) response = self._prepare_request('POST', url, json.dumps(to_jsonify))
return self._check_response(response) return self._check_response(response)
@ -2227,7 +2230,7 @@ class PyMISP(object):
:organisation: Organisation's local instance ID, or Organisation's global UUID, or Organisation's name as known to the curent instance :organisation: Organisation's local instance ID, or Organisation's global UUID, or Organisation's name as known to the curent instance
''' '''
to_jsonify = {'sg_id': sharing_group, 'org_id': organisation} to_jsonify = {'sg_id': sharing_group, 'org_id': organisation}
url = urljoin(self.root_url, '/sharingGroups/removeOrg') url = urljoin(self.root_url, 'sharingGroups/removeOrg')
response = self._prepare_request('POST', url, json.dumps(to_jsonify)) response = self._prepare_request('POST', url, json.dumps(to_jsonify))
return self._check_response(response) return self._check_response(response)
@ -2238,7 +2241,7 @@ class PyMISP(object):
:all_orgs: Add all the organisations of the server to the group :all_orgs: Add all the organisations of the server to the group
''' '''
to_jsonify = {'sg_id': sharing_group, 'server_id': server, 'all_orgs': all_orgs} to_jsonify = {'sg_id': sharing_group, 'server_id': server, 'all_orgs': all_orgs}
url = urljoin(self.root_url, '/sharingGroups/addServer') url = urljoin(self.root_url, 'sharingGroups/addServer')
response = self._prepare_request('POST', url, json.dumps(to_jsonify)) response = self._prepare_request('POST', url, json.dumps(to_jsonify))
return self._check_response(response) return self._check_response(response)
@ -2248,7 +2251,7 @@ class PyMISP(object):
:server: Server's local instance ID, or URL of the Server, or Server's name as known to the curent instance :server: Server's local instance ID, or URL of the Server, or Server's name as known to the curent instance
''' '''
to_jsonify = {'sg_id': sharing_group, 'server_id': server} to_jsonify = {'sg_id': sharing_group, 'server_id': server}
url = urljoin(self.root_url, '/sharingGroups/removeServer') url = urljoin(self.root_url, 'sharingGroups/removeServer')
response = self._prepare_request('POST', url, json.dumps(to_jsonify)) response = self._prepare_request('POST', url, json.dumps(to_jsonify))
return self._check_response(response) return self._check_response(response)
@ -2324,7 +2327,7 @@ class PyMISP(object):
return self._check_response(response) return self._check_response(response)
def update_object_templates(self): def update_object_templates(self):
url = urljoin(self.root_url, '/objectTemplates/update') url = urljoin(self.root_url, 'objectTemplates/update')
response = self._prepare_request('POST', url) response = self._prepare_request('POST', url)
return self._check_response(response) return self._check_response(response)

@ -1 +1 @@
Subproject commit 75ae30f44df997280255eec60b981b9f376c5ac4 Subproject commit d0886ba6aff1526868efcd59fccb99e920372f3b

View File

@ -34,7 +34,6 @@ try:
HAS_REPORTLAB = True HAS_REPORTLAB = True
except ImportError: except ImportError:
HAS_REPORTLAB = False HAS_REPORTLAB = False
print("ReportLab cannot be imported. Please verify that ReportLab is installed on the system.")
######################################################################## ########################################################################
@ -190,6 +189,17 @@ analysis_map = {"0": "<font color =" + HIGH_THREAT_COLOR + "> Initial (0)</fon
"1": "<font color =" + MEDIUM_THREAT_COLOR + "> Ongoing (1)</font>", "1": "<font color =" + MEDIUM_THREAT_COLOR + "> Ongoing (1)</font>",
"2": "<font color =" + LOW_THREAT_COLOR + "> Completed (2)</font>"} "2": "<font color =" + LOW_THREAT_COLOR + "> Completed (2)</font>"}
# == Parameters for Sightings ==
POSITIVE_SIGHT_COLOR = 'green'
NEGATIVE_SIGHT_COLOR = 'red'
MISC_SIGHT_COLOR = 'orange'
# == Parameters for galaxies ==
DO_SMALL_GALAXIES = True
FIRST_LEVEL_GALAXY_WIDTHS = ["15%","85%"]
SECOND_LEVEL_GALAXY_WIDTHS = ["20%","80%"]
CLUSTER_COLORS = [0] # or 1
OFFSET = 1
######################################################################## ########################################################################
# "UTILITIES" METHODS. Not meant to be used except for development purposes # "UTILITIES" METHODS. Not meant to be used except for development purposes
@ -315,6 +325,9 @@ def lines_style_generator(data, line_alternation):
# Last line # Last line
lines_list.append(('LINEBELOW', (0, len(data) - 1), (-1, len(data) - 1), LINE_THICKNESS, LINE_COLOR)) lines_list.append(('LINEBELOW', (0, len(data) - 1), (-1, len(data) - 1), LINE_THICKNESS, LINE_COLOR))
elif line_alternation == [] :
# Do nothing
return lines_list
else: else:
if data_len > len(line_alternation) : if data_len > len(line_alternation) :
logger.warning("Line alternation for PDF display isn't correctly set. Looping on given values only.") logger.warning("Line alternation for PDF display isn't correctly set. Looping on given values only.")
@ -374,6 +387,30 @@ def get_table_styles():
return custom_body_style_col_1, custom_body_style_col_2 return custom_body_style_col_1, custom_body_style_col_2
def get_clusters_table_styles():
'''
Create and returns the two mains styles for the columns of a table describing a cluster.
:return: two styles, one for each columns of the document, describing the MISP object.
'''
col1, col2 = get_table_styles()
custom_body_style_col_1 = ParagraphStyle(name='Column_1_small',
parent=col1,
fontName=FIRST_COL_FONT,
textColor=FIRST_COL_FONT_COLOR,
fontSize=TEXT_FONT_SIZE - 2,
leading=LEADING_SPACE- 1,
alignment=FIRST_COL_ALIGNEMENT)
custom_body_style_col_2 = ParagraphStyle(name='Column_2_small',
parent=col2,
fontName=SECOND_COL_FONT,
textColor=SECOND_COL_FONT_COLOR,
fontSize=TEXT_FONT_SIZE - 2,
leading=LEADING_SPACE- 1,
alignment=TA_JUSTIFY)
return custom_body_style_col_1, custom_body_style_col_2
######################################################################## ########################################################################
# Checks # Checks
@ -413,18 +450,22 @@ class Value_Formatter():
''' '''
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
def __init__(self, config, col1_style, col2_style): def __init__(self, config, col1_style, col2_style, col1_small_style, col2_small_style):
self.config = config self.config = config
self.col1_style = col1_style self.col1_style = col1_style
self.col2_style = col2_style self.col2_style = col2_style
self.col1_small_style = col1_small_style
self.col2_small_style = col2_small_style
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
######################################################################## ########################################################################
# General attribut formater # General attribut formater
def get_col1_paragraph(self, dirty_string): def get_col1_paragraph(self, dirty_string, do_small=False):
return self.get_unoverflowable_paragraph(dirty_string, self.col1_style) if do_small :
return self.get_unoverflowable_paragraph(dirty_string, self.col1_small_style, do_small=do_small)
return self.get_unoverflowable_paragraph(dirty_string, self.col1_style, do_small=do_small)
def get_unoverflowable_paragraph(self, dirty_string, curr_style=None, do_escape_string=True): def get_unoverflowable_paragraph(self, dirty_string, curr_style=None, do_escape_string=True, do_small=False):
''' '''
Create a paragraph that can fit on a cell displayed one page maximum. Create a paragraph that can fit on a cell displayed one page maximum.
This method can be improved (get the exact size of the current frame, and limit the paragraph to this size.) This method can be improved (get the exact size of the current frame, and limit the paragraph to this size.)
@ -439,8 +480,12 @@ class Value_Formatter():
else: else:
sanitized_str = dirty_string sanitized_str = dirty_string
if curr_style is None: if curr_style is None :
curr_style = self.col2_style if do_small :
curr_style = self.col2_small_style
else :
curr_style = self.col2_style
# Get the space that the paragraph needs to be printed # Get the space that the paragraph needs to be printed
w, h = Paragraph(sanitized_str, curr_style).wrap(FRAME_MAX_WIDTH, FRAME_MAX_HEIGHT) w, h = Paragraph(sanitized_str, curr_style).wrap(FRAME_MAX_WIDTH, FRAME_MAX_HEIGHT)
@ -721,10 +766,10 @@ class Value_Formatter():
if is_safe_dict_attribute(misp_galaxy, item[1]): if is_safe_dict_attribute(misp_galaxy, item[1]):
return self.get_unoverflowable_paragraph(safe_string(misp_galaxy[item[1]]) return self.get_unoverflowable_paragraph(safe_string(misp_galaxy[item[1]])
+ " <i>from</i> " + safe_string(misp_galaxy[item[3]]) + ":" + " <i>from</i> " + safe_string(misp_galaxy[item[3]]) + ":"
+ safe_string(misp_galaxy[item[4]]), do_escape_string=False) + safe_string(misp_galaxy[item[4]]), do_escape_string=False, do_small=True)
return self.get_unoverflowable_paragraph(item[2]) return self.get_unoverflowable_paragraph(item[2], do_small=True)
def get_galaxy_cluster_name_value(self, misp_cluster): def get_galaxy_cluster_name_value(self, misp_cluster, do_small=False):
item = ["Name", 'value', "None", "source", "meta", "synonyms"] item = ["Name", 'value', "None", "source", "meta", "synonyms"]
tmp_text = "" tmp_text = ""
@ -742,8 +787,8 @@ class Value_Formatter():
tmp_text += " / " tmp_text += " / "
tmp_text += safe_string(synonyme) tmp_text += safe_string(synonyme)
return self.get_unoverflowable_paragraph(tmp_text, do_escape_string=False) return self.get_unoverflowable_paragraph(tmp_text, do_escape_string=False, do_small=do_small)
return self.get_unoverflowable_paragraph(item[2]) return self.get_unoverflowable_paragraph(item[2], do_small=do_small)
class Event_Metadata(): class Event_Metadata():
@ -826,6 +871,8 @@ class Event_Metadata():
flowable_table.append(create_flowable_table_from_data(data)) flowable_table.append(create_flowable_table_from_data(data))
flowable_table.append(PageBreak())
# Galaxies # Galaxies
item = ["Related Galaxies", 'Galaxy', "None"] item = ["Related Galaxies", 'Galaxy', "None"]
curr_Galaxy = Galaxy(self.config, self.value_formatter) curr_Galaxy = Galaxy(self.config, self.value_formatter)
@ -962,7 +1009,7 @@ class Attributes():
# There is some attributes for this object # There is some attributes for this object
for item in getattr(misp_event, "Attribute"): for item in getattr(misp_event, "Attribute"):
# you can use a spacer instead of title to separate paragraph: flowable_table.append(Spacer(1, 5 * mm)) # you can use a spacer instead of title to separate paragraph: flowable_table.append(Spacer(1, 5 * mm))
flowable_table.append(Paragraph("Attribute #" + str(i), self.sample_style_sheet['Heading4'])) flowable_table.append(Paragraph("Attribute #" + str(i+OFFSET), self.sample_style_sheet['Heading4']))
flowable_table += self.create_flowable_table_from_one_attribute(item) flowable_table += self.create_flowable_table_from_one_attribute(item)
i += 1 i += 1
else: else:
@ -1036,8 +1083,9 @@ class Attributes():
# Galaxies # Galaxies
item = ["Related Galaxies", 'Galaxy', "None"] item = ["Related Galaxies", 'Galaxy', "None"]
curr_Galaxy = Galaxy(self.config, self.value_formatter) if is_safe_attribute_table(misp_attribute, item[1]) :
flowable_table += curr_Galaxy.get_galaxy_value(misp_attribute, item) curr_Galaxy = Galaxy(self.config, self.value_formatter)
flowable_table += curr_Galaxy.get_galaxy_value(misp_attribute, item)
return flowable_table return flowable_table
@ -1121,11 +1169,7 @@ class Sightings():
:return: a table of flowable to add to the pdf :return: a table of flowable to add to the pdf
''' '''
col1_style, col2_style = get_table_styles()
i = 0 i = 0
POSITIVE_SIGHT_COLOR = 'green'
NEGATIVE_SIGHT_COLOR = 'red'
MISC_SIGHT_COLOR = 'orange'
list_sighting = [0, 0, 0] list_sighting = [0, 0, 0]
if is_safe_attribute_table(misp_attribute, item[1]): if is_safe_attribute_table(misp_attribute, item[1]):
@ -1151,6 +1195,7 @@ class Sightings():
return answer_sighting return answer_sighting
class Object(): class Object():
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
@ -1161,6 +1206,7 @@ class Object():
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
def create_flowable_table_from_objects(self, misp_event, config=None): def create_flowable_table_from_objects(self, misp_event, config=None):
''' '''
Returns a list of flowables representing the list of objects of a misp event. Returns a list of flowables representing the list of objects of a misp event.
@ -1178,7 +1224,7 @@ class Object():
# There is a list of objects # There is a list of objects
for item in getattr(misp_event, "Object"): for item in getattr(misp_event, "Object"):
# you can use a spacer instead of title to separate paragraph: flowable_table.append(Spacer(1, 5 * mm)) # you can use a spacer instead of title to separate paragraph: flowable_table.append(Spacer(1, 5 * mm))
flowable_table.append(Paragraph("Object #" + str(i), self.sample_style_sheet['Heading3'])) flowable_table.append(Paragraph("Object #" + str(i+OFFSET), self.sample_style_sheet['Heading3']))
flowable_table += self.create_flowable_table_from_one_object(item, config) flowable_table += self.create_flowable_table_from_one_object(item, config)
i += 1 i += 1
else: else:
@ -1187,6 +1233,7 @@ class Object():
return flowable_table return flowable_table
def create_flowable_table_from_one_object(self, misp_object, config=None): def create_flowable_table_from_one_object(self, misp_object, config=None):
''' '''
Returns a table (flowable) representing the object Returns a table (flowable) representing the object
@ -1194,7 +1241,6 @@ class Object():
:return: a table representing this misp's object's attributes, to add to the pdf as a flowable :return: a table representing this misp's object's attributes, to add to the pdf as a flowable
''' '''
data = [] data = []
col1_style, col2_style = get_table_styles()
# To reduce code size, and automate it a bit, triplet (Displayed Name, object_attribute_name, # To reduce code size, and automate it a bit, triplet (Displayed Name, object_attribute_name,
# to_display_if_not_present) are store in the following list # to_display_if_not_present) are store in the following list
@ -1217,7 +1263,7 @@ class Object():
# Timestamp # Timestamp
item = ["Object date", 'timestamp', "None"] item = ["Object date", 'timestamp', "None"]
data.append([Paragraph(item[0], col1_style), self.value_formatter.get_timestamp_value(misp_object, item)]) data.append([self.value_formatter.get_col1_paragraph(item[0]), self.value_formatter.get_timestamp_value(misp_object, item)])
# Transform list of value in a table # Transform list of value in a table
data = [create_flowable_table_from_data(data)] data = [create_flowable_table_from_data(data)]
@ -1275,19 +1321,20 @@ class Galaxy():
:param misp_event: A misp event :param misp_event: A misp event
:return: a table of flowables to add to the pdf :return: a table of flowables to add to the pdf
''' '''
flowable_table = [] flowable_table = []
scheme_alternation = [] scheme_alternation = []
curr_color = 0 curr_color = 0
i = 0 i = 0
if is_safe_attribute_table(misp_event, "Galaxy"): if is_safe_attribute_table(misp_event, "Galaxy"):
# There is some galaxies for this object # There is some galaxies for this object
for curr_galaxy in getattr(misp_event, "Galaxy"): for curr_galaxy in getattr(misp_event, "Galaxy"):
# For each galaxy of the misp object # For each galaxy of the misp object
galaxy_title = Paragraph("Galaxy # " + str(i), self.sample_style_sheet['Heading6']) txt_title = "Galaxy #" + str(i+OFFSET) + " - " + safe_string(curr_galaxy["name"])
galaxy_title = Paragraph(txt_title, self.sample_style_sheet['Heading6'])
flowable_table.append(galaxy_title) flowable_table.append(galaxy_title)
i += 1 i += 1
@ -1298,21 +1345,12 @@ class Galaxy():
# Construct the line color scheme and line scheme # Construct the line color scheme and line scheme
scheme_alternation += [curr_color] * nb_added_item scheme_alternation += [curr_color] * nb_added_item
# Apply the scheme
# answer_tags = create_flowable_table_from_data(flowable_table)
# Add metadata about clusters # Add metadata about clusters
curr_cluster = Galaxy_cluster(self.config, self.value_formatter) curr_cluster = Galaxy_cluster(self.config, self.value_formatter)
clusters_metadata = curr_cluster.create_flowable_table_from_galaxy_clusters(curr_galaxy) clusters_metadata = curr_cluster.create_flowable_table_from_galaxy_clusters(curr_galaxy)
flowable_table += clusters_metadata flowable_table += clusters_metadata
'''
# Construct the line color scheme and line scheme
scheme_alternation += [curr_color] * nb_added_item
curr_color += 1 if curr_color == 0 else 0
'''
else: else:
# No galaxies for this object # No galaxies for this object
answer_tags = [self.value_formatter.get_unoverflowable_paragraph("No galaxies")] answer_tags = [self.value_formatter.get_unoverflowable_paragraph("No galaxies")]
@ -1332,15 +1370,15 @@ class Galaxy():
# Name # Name
item = ["Name", 'name', "None"] item = ["Name", 'name', "None"]
if is_safe_dict_attribute(misp_galaxy, item[1]): if is_safe_dict_attribute(misp_galaxy, item[1]):
data.append([self.value_formatter.get_col1_paragraph(item[0]), data.append([self.value_formatter.get_col1_paragraph(item[0], do_small=DO_SMALL_GALAXIES),
self.value_formatter.get_galaxy_name_value(misp_galaxy)]) self.value_formatter.get_galaxy_name_value(misp_galaxy)])
nb_added_item += 1 nb_added_item += 1
# Description # Description
item = ["Description", 'description', "None"] item = ["Description", 'description', "None"]
if is_safe_dict_attribute(misp_galaxy, item[1]): if is_safe_dict_attribute(misp_galaxy, item[1]):
data.append([self.value_formatter.get_col1_paragraph(item[0]), data.append([self.value_formatter.get_col1_paragraph(item[0], do_small=DO_SMALL_GALAXIES),
self.value_formatter.get_unoverflowable_paragraph(misp_galaxy[item[1]])]) self.value_formatter.get_unoverflowable_paragraph(misp_galaxy[item[1]], do_small=DO_SMALL_GALAXIES)])
nb_added_item += 1 nb_added_item += 1
flowable_table = [] flowable_table = []
@ -1349,6 +1387,7 @@ class Galaxy():
return flowable_table, nb_added_item return flowable_table, nb_added_item
class Galaxy_cluster(): class Galaxy_cluster():
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
@ -1366,37 +1405,31 @@ class Galaxy_cluster():
''' '''
data = [] data = []
i = 0
item = ["Cluster #", 'name', "None"] item = ["Cluster #", 'name', "None"]
if is_safe_dict_attribute(misp_galaxy, "GalaxyCluster"): if is_safe_dict_attribute(misp_galaxy, "GalaxyCluster"):
# There is some clusters for this object # There is some clusters for this object
for curr_cluster in misp_galaxy["GalaxyCluster"]: for i, curr_cluster in enumerate(misp_galaxy["GalaxyCluster"]):
''' # If title is needed :
galaxy_title = [Paragraph("Cluster #" + str(i), self.sample_style_sheet['Heading6'])] # galaxy_title = [Paragraph("Cluster #" + str(i), self.sample_style_sheet['Heading6'])]
data.append(galaxy_title) # data.append(galaxy_title)
i += 1
'''
item[0] = "Cluster #" + str(i + OFFSET)
# For each cluster # For each cluster
tmp_data = self.create_flowable_table_from_one_galaxy_cluster(curr_cluster) tmp_data = self.create_flowable_table_from_one_galaxy_cluster(curr_cluster)
tmp_flowable_table = [] tmp_flowable_table = []
tmp_flowable_table.append(create_flowable_table_from_data(tmp_data, color_alternation = [0], line_alternation=[0])) tmp_flowable_table.append(create_flowable_table_from_data(tmp_data, col_w=SECOND_LEVEL_GALAXY_WIDTHS, color_alternation = CLUSTER_COLORS, line_alternation=[]))
data.append([self.value_formatter.get_col1_paragraph(item[0]), tmp_flowable_table]) data.append([self.value_formatter.get_col1_paragraph(item[0], do_small=DO_SMALL_GALAXIES), tmp_flowable_table]) # Cluster #X - 3 lines
# data += tmp_data
else: else:
# No galaxies for this object # No galaxies for this object
data = [self.value_formatter.get_unoverflowable_paragraph("No galaxy cluster")] data = [self.value_formatter.get_unoverflowable_paragraph("No galaxy cluster", do_small=DO_SMALL_GALAXIES)]
flowable_table = [] flowable_table = []
flowable_table.append(create_flowable_table_from_data(data)) flowable_table.append(create_flowable_table_from_data(data, col_w=FIRST_LEVEL_GALAXY_WIDTHS, color_alternation = CLUSTER_COLORS))
return flowable_table return flowable_table
@ -1410,15 +1443,19 @@ class Galaxy_cluster():
# Name # Name
item = ["Name", 'name', "None"] item = ["Name", 'name', "None"]
data.append([self.value_formatter.get_col1_paragraph(item[0]), data.append([self.value_formatter.get_col1_paragraph(item[0], do_small=True),
self.value_formatter.get_galaxy_cluster_name_value(misp_cluster)]) self.value_formatter.get_galaxy_cluster_name_value(misp_cluster, do_small=True)])
# Description if misp_cluster['value'] != misp_cluster['description'] : # Prevent name that are same as description
item = ["Description", 'description', "None"] # Description
data.append([self.value_formatter.get_col1_paragraph(item[0]), item = ["Description", 'description', "None"]
self.value_formatter.get_unoverflowable_paragraph(misp_cluster[item[1]])]) data.append([self.value_formatter.get_col1_paragraph(item[0], do_small=True),
self.value_formatter.get_unoverflowable_paragraph(misp_cluster[item[1]], do_small=True)])
# Refs ? # Refs ?
# item = ["Description", 'description', "None"]
# data.append([self.value_formatter.get_col1_paragraph(item[0]),
# self.value_formatter.get_unoverflowable_paragraph(misp_cluster[item[1]])])
return data return data
@ -1506,7 +1543,8 @@ def collect_parts(misp_event, config=None):
# Get the list of available styles # Get the list of available styles
sample_style_sheet = getSampleStyleSheet() sample_style_sheet = getSampleStyleSheet()
col1_style, col2_style = get_table_styles() col1_style, col2_style = get_table_styles()
curr_val_f = Value_Formatter(config, col1_style, col2_style) col1_small_style, col2_small_style = get_clusters_table_styles()
curr_val_f = Value_Formatter(config, col1_style, col2_style, col1_small_style, col2_small_style)
# Create stuff # Create stuff
title_style = ParagraphStyle(name='Column_1', parent=sample_style_sheet['Heading1'], alignment=TA_CENTER) title_style = ParagraphStyle(name='Column_1', parent=sample_style_sheet['Heading1'], alignment=TA_CENTER)

View File

@ -41,12 +41,13 @@ setup(
], ],
install_requires=['six', 'requests', 'python-dateutil', 'jsonschema', install_requires=['six', 'requests', 'python-dateutil', 'jsonschema',
'python-dateutil', 'enum34;python_version<"3.4"', 'python-dateutil', 'enum34;python_version<"3.4"',
'functools32;python_version<"3.0"', 'reportlab'], 'functools32;python_version<"3.0"'],
extras_require={'fileobjects': ['lief>=0.8', 'python-magic'], extras_require={'fileobjects': ['lief>=0.8', 'python-magic'],
'neo': ['py2neo'], 'neo': ['py2neo'],
'openioc': ['beautifulsoup4'], 'openioc': ['beautifulsoup4'],
'virustotal': ['validators'], 'virustotal': ['validators'],
'docs': ['sphinx-autodoc-typehints']}, 'docs': ['sphinx-autodoc-typehints'],
'pdfexport': ['reportlab']},
tests_require=[ tests_require=[
'jsonschema', 'jsonschema',
'python-magic', 'python-magic',

View File

@ -31,7 +31,7 @@
"name": "file", "name": "file",
"sharing_group_id": "0", "sharing_group_id": "0",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215", "template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"template_version": "15", "template_version": "16",
"uuid": "a" "uuid": "a"
}, },
{ {

View File

@ -23,7 +23,7 @@
"name": "file", "name": "file",
"sharing_group_id": "0", "sharing_group_id": "0",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215", "template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"template_version": "15", "template_version": "16",
"uuid": "a" "uuid": "a"
}, },
{ {
@ -48,7 +48,7 @@
"name": "file", "name": "file",
"sharing_group_id": "0", "sharing_group_id": "0",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215", "template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"template_version": "15", "template_version": "16",
"uuid": "b" "uuid": "b"
} }
] ]

View File

@ -715,7 +715,7 @@
"meta-category": "file", "meta-category": "file",
"description": "File object describing a file with meta-information", "description": "File object describing a file with meta-information",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215", "template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"template_version": "15", "template_version": "16",
"event_id": "1203", "event_id": "1203",
"uuid": "1db36cab-7b13-4758-b16a-9e9862d0973e", "uuid": "1db36cab-7b13-4758-b16a-9e9862d0973e",
"timestamp": "1550871228", "timestamp": "1550871228",
@ -887,7 +887,7 @@
"meta-category": "file", "meta-category": "file",
"description": "File object describing a file with meta-information", "description": "File object describing a file with meta-information",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215", "template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"template_version": "15", "template_version": "16",
"event_id": "1203", "event_id": "1203",
"uuid": "3b8f6a45-0b7f-4bea-ad61-0369f01cc306", "uuid": "3b8f6a45-0b7f-4bea-ad61-0369f01cc306",
"timestamp": "1550871228", "timestamp": "1550871228",
@ -1059,7 +1059,7 @@
"meta-category": "file", "meta-category": "file",
"description": "File object describing a file with meta-information", "description": "File object describing a file with meta-information",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215", "template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"template_version": "15", "template_version": "16",
"event_id": "1203", "event_id": "1203",
"uuid": "8cc1ffb8-e4b2-4641-a536-ea843ff9bc7a", "uuid": "8cc1ffb8-e4b2-4641-a536-ea843ff9bc7a",
"timestamp": "1550871228", "timestamp": "1550871228",
@ -1231,7 +1231,7 @@
"meta-category": "file", "meta-category": "file",
"description": "File object describing a file with meta-information", "description": "File object describing a file with meta-information",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215", "template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"template_version": "15", "template_version": "16",
"event_id": "1203", "event_id": "1203",
"uuid": "89e0ad73-a186-4959-b978-2311ee49e4af", "uuid": "89e0ad73-a186-4959-b978-2311ee49e4af",
"timestamp": "1550871229", "timestamp": "1550871229",
@ -1403,7 +1403,7 @@
"meta-category": "file", "meta-category": "file",
"description": "File object describing a file with meta-information", "description": "File object describing a file with meta-information",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215", "template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"template_version": "15", "template_version": "16",
"event_id": "1203", "event_id": "1203",
"uuid": "4dbf697b-11ce-447f-85c6-cd02a2365a7f", "uuid": "4dbf697b-11ce-447f-85c6-cd02a2365a7f",
"timestamp": "1550871229", "timestamp": "1550871229",
@ -1575,7 +1575,7 @@
"meta-category": "file", "meta-category": "file",
"description": "File object describing a file with meta-information", "description": "File object describing a file with meta-information",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215", "template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"template_version": "15", "template_version": "16",
"event_id": "1203", "event_id": "1203",
"uuid": "6860e975-938c-413d-b144-74cde72c25dc", "uuid": "6860e975-938c-413d-b144-74cde72c25dc",
"timestamp": "1550871229", "timestamp": "1550871229",
@ -1747,7 +1747,7 @@
"meta-category": "file", "meta-category": "file",
"description": "File object describing a file with meta-information", "description": "File object describing a file with meta-information",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215", "template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"template_version": "15", "template_version": "16",
"event_id": "1203", "event_id": "1203",
"uuid": "df5dd372-ecd6-4595-ab34-45bff1decb63", "uuid": "df5dd372-ecd6-4595-ab34-45bff1decb63",
"timestamp": "1550871229", "timestamp": "1550871229",
@ -1919,7 +1919,7 @@
"meta-category": "file", "meta-category": "file",
"description": "File object describing a file with meta-information", "description": "File object describing a file with meta-information",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215", "template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"template_version": "15", "template_version": "16",
"event_id": "1203", "event_id": "1203",
"uuid": "3061d73f-2f4f-4c6e-8478-3d5d1e74c1bc", "uuid": "3061d73f-2f4f-4c6e-8478-3d5d1e74c1bc",
"timestamp": "1550871229", "timestamp": "1550871229",
@ -2091,7 +2091,7 @@
"meta-category": "file", "meta-category": "file",
"description": "File object describing a file with meta-information", "description": "File object describing a file with meta-information",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215", "template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"template_version": "15", "template_version": "16",
"event_id": "1203", "event_id": "1203",
"uuid": "fd57be37-61cc-4452-85b5-518d55586335", "uuid": "fd57be37-61cc-4452-85b5-518d55586335",
"timestamp": "1550871230", "timestamp": "1550871230",
@ -2263,7 +2263,7 @@
"meta-category": "file", "meta-category": "file",
"description": "File object describing a file with meta-information", "description": "File object describing a file with meta-information",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215", "template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"template_version": "15", "template_version": "16",
"event_id": "1203", "event_id": "1203",
"uuid": "56b391e4-f005-4caa-ae12-a90db6664ebd", "uuid": "56b391e4-f005-4caa-ae12-a90db6664ebd",
"timestamp": "1550871270", "timestamp": "1550871270",

View File

@ -70,7 +70,7 @@
"timestamp": "1543921748", "timestamp": "1543921748",
"description": "File object describing a file with meta-information", "description": "File object describing a file with meta-information",
"distribution": "3", "distribution": "3",
"template_version": "15", "template_version": "16",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215", "template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"comment": "", "comment": "",
"name": "file", "name": "file",
@ -114,7 +114,7 @@
"timestamp": "1543921750", "timestamp": "1543921750",
"description": "File object describing a file with meta-information", "description": "File object describing a file with meta-information",
"distribution": "3", "distribution": "3",
"template_version": "15", "template_version": "16",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215", "template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"comment": "", "comment": "",
"name": "file", "name": "file",
@ -158,7 +158,7 @@
"timestamp": "1543921751", "timestamp": "1543921751",
"description": "File object describing a file with meta-information", "description": "File object describing a file with meta-information",
"distribution": "3", "distribution": "3",
"template_version": "15", "template_version": "16",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215", "template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"comment": "", "comment": "",
"name": "file", "name": "file",
@ -482,7 +482,7 @@
"timestamp": "1543921755", "timestamp": "1543921755",
"description": "File object describing a file with meta-information", "description": "File object describing a file with meta-information",
"distribution": "3", "distribution": "3",
"template_version": "15", "template_version": "16",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215", "template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"comment": "", "comment": "",
"name": "file", "name": "file",
@ -875,7 +875,7 @@
"timestamp": "1543921759", "timestamp": "1543921759",
"description": "File object describing a file with meta-information", "description": "File object describing a file with meta-information",
"distribution": "3", "distribution": "3",
"template_version": "15", "template_version": "16",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215", "template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"comment": "", "comment": "",
"name": "file", "name": "file",
@ -988,7 +988,7 @@
"timestamp": "1543921762", "timestamp": "1543921762",
"description": "File object describing a file with meta-information", "description": "File object describing a file with meta-information",
"distribution": "3", "distribution": "3",
"template_version": "15", "template_version": "16",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215", "template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"comment": "", "comment": "",
"name": "file", "name": "file",

View File

@ -82,7 +82,7 @@
"timestamp": "1543922168", "timestamp": "1543922168",
"description": "File object describing a file with meta-information", "description": "File object describing a file with meta-information",
"distribution": "3", "distribution": "3",
"template_version": "15", "template_version": "16",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215", "template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"comment": "", "comment": "",
"name": "file", "name": "file",
@ -126,7 +126,7 @@
"timestamp": "1543922169", "timestamp": "1543922169",
"description": "File object describing a file with meta-information", "description": "File object describing a file with meta-information",
"distribution": "3", "distribution": "3",
"template_version": "15", "template_version": "16",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215", "template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"comment": "", "comment": "",
"name": "file", "name": "file",
@ -450,7 +450,7 @@
"timestamp": "1543922173", "timestamp": "1543922173",
"description": "File object describing a file with meta-information", "description": "File object describing a file with meta-information",
"distribution": "3", "distribution": "3",
"template_version": "15", "template_version": "16",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215", "template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"comment": "", "comment": "",
"name": "file", "name": "file",
@ -857,7 +857,7 @@
"timestamp": "1543922178", "timestamp": "1543922178",
"description": "File object describing a file with meta-information", "description": "File object describing a file with meta-information",
"distribution": "3", "distribution": "3",
"template_version": "15", "template_version": "16",
"template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215", "template_uuid": "688c46fb-5edb-40a3-8273-1af7923e2215",
"comment": "", "comment": "",
"name": "file", "name": "file",

View File

@ -9,8 +9,13 @@ import unittest
from pymisp import MISPEvent from pymisp import MISPEvent
from pymisp.tools import reportlab_generator from pymisp.tools import reportlab_generator
manual_testing = True manual_testing = False
if sys.version_info < (3, 6):
print('This test suite requires Python 3.6+, breaking.')
sys.exit(0)
else:
from pymisp import reportlab_generator
class TestMISPEvent(unittest.TestCase): class TestMISPEvent(unittest.TestCase):
@ -226,7 +231,6 @@ class TestMISPEvent(unittest.TestCase):
if self.check_python_2(): if self.check_python_2():
self.assertTrue(True) self.assertTrue(True)
else: else:
config = {} config = {}
config[self.moduleconfig[0]] = "http://localhost:8080" config[self.moduleconfig[0]] = "http://localhost:8080"
config[self.moduleconfig[1]] = "My Wonderful CERT" config[self.moduleconfig[1]] = "My Wonderful CERT"
@ -309,6 +313,8 @@ class TestMISPEvent(unittest.TestCase):
config[self.moduleconfig[0]] = "http://localhost:8080" config[self.moduleconfig[0]] = "http://localhost:8080"
config[self.moduleconfig[1]] = "My Wonderful CERT" config[self.moduleconfig[1]] = "My Wonderful CERT"
config[self.moduleconfig[2]] = True config[self.moduleconfig[2]] = True
config[self.moduleconfig[3]] = True
file_nb = str(len(os.listdir(self.test_batch_folder))) file_nb = str(len(os.listdir(self.test_batch_folder)))
i = 0 i = 0

View File

@ -496,7 +496,7 @@ class TestComprehensive(unittest.TestCase):
self.assertEqual(new_obj['Object']['distribution'], str(Distribution.inherit.value)) self.assertEqual(new_obj['Object']['distribution'], str(Distribution.inherit.value))
self.assertEqual(new_obj['Object']['Attribute'][0]['distribution'], str(Distribution.inherit.value)) self.assertEqual(new_obj['Object']['Attribute'][0]['distribution'], str(Distribution.inherit.value))
# Object - edit # Object - edit
clean_obj = MISPObject(**new_obj['Object']) clean_obj = MISPObject(strict=True, **new_obj['Object'])
clean_obj.from_dict(**new_obj['Object']) clean_obj.from_dict(**new_obj['Object'])
clean_obj.add_attribute('filename', value='blah.exe') clean_obj.add_attribute('filename', value='blah.exe')
new_obj = self.user_misp_connector.edit_object(clean_obj) new_obj = self.user_misp_connector.edit_object(clean_obj)