mirror of
https://github.com/absmach/magistrala.git
synced 2026-08-07 15:25:48 +00:00
Compare commits
938 Commits
v0.14.1-dave
...
edge
| Author | SHA1 | Date | |
|---|---|---|---|
| 7f372910dc | |||
| e8cf13c7f3 | |||
| 10791c1e28 | |||
| d63bbe1f93 | |||
| f8fab301de | |||
| 135490f680 | |||
| dcd6e85afd | |||
| 0ba7994db9 | |||
| 880634e009 | |||
| 168e8b90cb | |||
| 6429f16233 | |||
| d40757f36f | |||
| c09020a29c | |||
| 2320ec96c0 | |||
| 14d6db9684 | |||
| 513a84361b | |||
| 6ed7ca6a42 | |||
| 52645e2c39 | |||
| e078e00f73 | |||
| c3b9c20cc0 | |||
| 36fb079563 | |||
| 4d20126e75 | |||
| 09a56575c1 | |||
| 3b5f646719 | |||
| ededf5308c | |||
| bc7c9096f9 | |||
| c405028fc5 | |||
| cdc065a7b2 | |||
| 3cf6b2f0f4 | |||
| afd2665c9c | |||
| 45c426c8bf | |||
| 16ba29cf4a | |||
| 19ed0de788 | |||
| 7efeb875de | |||
| 935a0950f9 | |||
| d4f0d8fdef | |||
| aaa718bdf6 | |||
| 91e010128d | |||
| 5d7d3d412b | |||
| cb364d0426 | |||
| b68c9fe79e | |||
| 0d5048941e | |||
| 24edbe6ad8 | |||
| 610da72779 | |||
| 90672e5fc7 | |||
| 5821d2a513 | |||
| 49488738df | |||
| 493073ae49 | |||
| 5a528dd138 | |||
| 377b8dfc08 | |||
| 03b33fee9e | |||
| af75ac730c | |||
| 70d879275a | |||
| 353e050a39 | |||
| 683809dc6b | |||
| f380c8d360 | |||
| 78804278d4 | |||
| 426532099a | |||
| 7f03134d8e | |||
| f736bca7c1 | |||
| d840aeb1b9 | |||
| a0bc7c2108 | |||
| df242f6179 | |||
| 3f256ddcf6 | |||
| e294963450 | |||
| 12180707d2 | |||
| 68befa023c | |||
| dc72811048 | |||
| 92b2993366 | |||
| f3a7230cc0 | |||
| ac8dadefc6 | |||
| 3541ea8678 | |||
| 125e311eda | |||
| c9bf5beba2 | |||
| c5fc0b64d4 | |||
| 6c7e5d893d | |||
| 69d02ed58e | |||
| 3f329eb3c2 | |||
| b753294101 | |||
| 6dd470a41e | |||
| 61d0427898 | |||
| fc679e9982 | |||
| 791e084de6 | |||
| 6a3319828e | |||
| 5f230f9446 | |||
| 03893cf9e5 | |||
| 560e90aa96 | |||
| 2687a31ac2 | |||
| b70004500e | |||
| c336bf2bb6 | |||
| 74832cc081 | |||
| 468457c303 | |||
| b062fb22ee | |||
| fad25c9092 | |||
| 8e774b3398 | |||
| cc84466e7d | |||
| 351b25cd85 | |||
| ef5c253c51 | |||
| 08249c045b | |||
| e3be8d5f91 | |||
| cf7cd15a14 | |||
| 8f1ae9fd03 | |||
| 0f7ad10534 | |||
| fade98b84e | |||
| 492965d379 | |||
| 6969fd2ce8 | |||
| 9c6ad9744e | |||
| df2446c2cc | |||
| 28ae84286e | |||
| 487dbbb44c | |||
| ea3925e3e2 | |||
| 3fc2dabf8a | |||
| e3902256ef | |||
| 215218495d | |||
| ff581b8736 | |||
| 4bd1694cd5 | |||
| efba921328 | |||
| 373aab73ae | |||
| abd669c610 | |||
| cef4b1d14d | |||
| f8410b8940 | |||
| 2260293dfc | |||
| c9f34e3759 | |||
| aeb1d9d0a1 | |||
| 03a8feb679 | |||
| 9c2608659f | |||
| 2c476c17ee | |||
| 3b2dd09ab4 | |||
| 5255d887ef | |||
| bb8917cc34 | |||
| 4792a99c9a | |||
| fe49305238 | |||
| 03143d4142 | |||
| 15a6c026e9 | |||
| 175f0e08ab | |||
| 41526634f8 | |||
| 73a640e646 | |||
| 6ca535155a | |||
| 4a449629b3 | |||
| 1cd00fbd83 | |||
| a871fa926e | |||
| c7fad0d2ca | |||
| 51e782693d | |||
| e3a3e052d2 | |||
| 1e8437cfc2 | |||
| f8f4ccac79 | |||
| 56bb07273d | |||
| aba4d6a0b7 | |||
| b948edc573 | |||
| 20bafe0077 | |||
| 4e77ae65e2 | |||
| 61c120f947 | |||
| 0d4f4c9266 | |||
| 668338dfa2 | |||
| 38ea004e30 | |||
| 7b99baeb02 | |||
| cd31b1c6bd | |||
| 1a348b11dd | |||
| f552e08661 | |||
| 5606cdbe47 | |||
| 59d9f91813 | |||
| 5b913dd46b | |||
| 9293de7636 | |||
| 2dd8c44aa3 | |||
| 28fc9738df | |||
| ad1d67a678 | |||
| 1086f3e208 | |||
| b896c03f5f | |||
| d78c1e8d20 | |||
| 551d44d58e | |||
| 927230dbb4 | |||
| c7996ce6cf | |||
| bf7a965195 | |||
| 67c28ff134 | |||
| a526a2ccd5 | |||
| c679224596 | |||
| e1c881d2ad | |||
| 9a0d8062be | |||
| 25d8b86f2b | |||
| 24ca513eff | |||
| 52510d8c62 | |||
| 6b6bab79c6 | |||
| 6a5d28c65a | |||
| 59f8d4e4d7 | |||
| e23555ee2a | |||
| cb337a38fd | |||
| f9b503f1d6 | |||
| 0fe5a6d6e8 | |||
| f612109f24 | |||
| 3fcf2e5369 | |||
| 1355bc8bb7 | |||
| 1e7e65d642 | |||
| 3a5c1e12df | |||
| 61b95a28c2 | |||
| 4c40b8b82c | |||
| 955c556fe6 | |||
| dc437a8296 | |||
| 314537f7c5 | |||
| 7e5fd0cfa8 | |||
| 6a2c8a3ca6 | |||
| 2bea4412d8 | |||
| c8cb0daa6c | |||
| f8017c8b9f | |||
| 27fc32c153 | |||
| 9aa9487207 | |||
| 1292095cdb | |||
| 856ef1ba49 | |||
| 146028fb98 | |||
| 6cb3e635c9 | |||
| 175d27c4b6 | |||
| eec6b8be07 | |||
| e48e5dee1f | |||
| 0df8e8451c | |||
| e77e3a3bb6 | |||
| 3e6b771850 | |||
| 15e756a5a3 | |||
| c5a4336d43 | |||
| b05ae65e24 | |||
| 1a8d11acdd | |||
| 27b72db52e | |||
| e75ce59998 | |||
| cd281c2589 | |||
| 9d13d5b528 | |||
| f7dcaa949b | |||
| fa080ab0f8 | |||
| 5807cf1754 | |||
| f96ddab9dd | |||
| 914d491a13 | |||
| 843a0cae1f | |||
| 9ba9a12084 | |||
| 5ed6b258a0 | |||
| eb83edbcde | |||
| 5c12bc8c91 | |||
| 589209eae2 | |||
| a2e660b8a1 | |||
| 21731aef37 | |||
| 2f55947305 | |||
| 80806c4745 | |||
| 1947f6e78e | |||
| 5b0c556b60 | |||
| 5891e4bb75 | |||
| 299742096a | |||
| 27c57b192b | |||
| 8083cec373 | |||
| e2d9b1ddf9 | |||
| 6092bc2cf0 | |||
| 071d23a5f0 | |||
| 7bb4b298c5 | |||
| cac6c648d3 | |||
| 4ee7736b32 | |||
| 8ed8915e4f | |||
| 65c6a4d8f4 | |||
| ec223e7467 | |||
| aa3cc3d7ee | |||
| 9650dde716 | |||
| d02747a56f | |||
| dc0df1c955 | |||
| 64b4497ad4 | |||
| 1b26264495 | |||
| 69366d77cc | |||
| fa8862cbc8 | |||
| 15b8901853 | |||
| 9258237cb6 | |||
| 2adeecd9ec | |||
| c5eee6d8fd | |||
| 648edbd386 | |||
| 35fb296318 | |||
| a98777b191 | |||
| 3c693a7b41 | |||
| c230a24b7d | |||
| 42b2a8c166 | |||
| 6468ebe749 | |||
| 1adbe1ff24 | |||
| 27995cb093 | |||
| 5833bafbee | |||
| 6394908b2c | |||
| 0e0598c6d8 | |||
| 3e400da5ad | |||
| 2112281171 | |||
| 6f40c7fa1e | |||
| b0e9e43b9e | |||
| bc7727c275 | |||
| 8d1c3c41b5 | |||
| d84df8604f | |||
| d4d8bc5351 | |||
| ac9bc9aad6 | |||
| 4b83301f69 | |||
| b746a8679f | |||
| e6022542b9 | |||
| 6c77e1b738 | |||
| 04774ae972 | |||
| ae7c93020a | |||
| b031dc08b8 | |||
| 0465ceb7a3 | |||
| af424ee2cb | |||
| 96a15b32dd | |||
| 61f1e9aca2 | |||
| 29f7063c15 | |||
| 1f48a73677 | |||
| cd9cb9e1d5 | |||
| 8d9e92f228 | |||
| ad685c27ad | |||
| 44485cacec | |||
| 7fac6ff4c4 | |||
| 1930a0c8f2 | |||
| 9eac9366ba | |||
| ad191c4609 | |||
| 1d935f0519 | |||
| bc1ccace4a | |||
| 89fdb4e6c7 | |||
| 44e44639aa | |||
| d31c66174e | |||
| e6d7a07277 | |||
| a2ea92a5ba | |||
| 3320a716f3 | |||
| a70b838f1c | |||
| c50221a042 | |||
| 1efa8b5bce | |||
| e57ad79cd4 | |||
| 22616911d2 | |||
| 766bb5519a | |||
| fbcdef9693 | |||
| 9aacde7c5b | |||
| cdf26051f6 | |||
| a9a412e909 | |||
| 0754fa1126 | |||
| ec75f4eadb | |||
| af35396601 | |||
| 6a27594751 | |||
| 555d89d358 | |||
| c3c9dcf318 | |||
| 5a75772f62 | |||
| b9ac94f058 | |||
| 8ab1f4c408 | |||
| e842bfaab6 | |||
| 886cd63415 | |||
| 9cd22910d8 | |||
| 906e365adf | |||
| 8e7e897906 | |||
| 4b50ef93a2 | |||
| 73c2d76b58 | |||
| 473338527a | |||
| 12d1a0de32 | |||
| b4e0e89c38 | |||
| 6f5e535b30 | |||
| fb1062a98a | |||
| c56a5ae577 | |||
| a19cd9c97b | |||
| 0e1a090f16 | |||
| ef712443e1 | |||
| 248b708909 | |||
| c63c936b36 | |||
| 4927333691 | |||
| 5acc8f96a6 | |||
| 9d91740063 | |||
| 1951f206cb | |||
| 441feb8578 | |||
| 7d11f16988 | |||
| 2e3f52fdbf | |||
| b942a42271 | |||
| 0178594c25 | |||
| 3dbd617ed0 | |||
| 8188da16b3 | |||
| bc7b988098 | |||
| a0b3970ad6 | |||
| 0f20663cfb | |||
| 4dc98763a6 | |||
| 230be1d13b | |||
| 99493d86ff | |||
| 4ffb1fe422 | |||
| f4417ecb78 | |||
| 9b77130f6e | |||
| 71ea84c3ec | |||
| 36c138688d | |||
| 86afe1736f | |||
| 8e70e1113e | |||
| a379d11035 | |||
| 45a5c42ea4 | |||
| 99a55a6e24 | |||
| 6e404caa32 | |||
| 898048cb8b | |||
| 0794c2828e | |||
| 7be4ec6890 | |||
| 5669e8a76e | |||
| d4dc7ffe35 | |||
| b6080bc42b | |||
| 0dea465fb3 | |||
| 879225f7a8 | |||
| f8a7a75486 | |||
| fb0b188d4e | |||
| 376bc8b9c4 | |||
| da319a1aa9 | |||
| 2ab3db79e5 | |||
| 33e8d4f47e | |||
| 902e85e648 | |||
| afb28667c4 | |||
| 26feb34f8d | |||
| bdfdb67998 | |||
| 1c0400d3a5 | |||
| fa5b6b86c6 | |||
| 16f1b411ec | |||
| be66701b15 | |||
| 0a18a580eb | |||
| a0044c51be | |||
| 788d8334f7 | |||
| 7ecdd7ebe3 | |||
| dda01ff4a1 | |||
| 5d04de4ffa | |||
| f6e8db4c09 | |||
| 0f9ae05615 | |||
| bcba9e962e | |||
| 191f8a1e0f | |||
| 0d1aafcbbf | |||
| 9a194a86df | |||
| 668013cbad | |||
| d83f0b8559 | |||
| c198e8093b | |||
| 12a562284e | |||
| 54c1ff0587 | |||
| d9cf3851a1 | |||
| 9abdf39fd6 | |||
| d8e895970c | |||
| f7f399a5a5 | |||
| 3a1b9ce20b | |||
| 8d04e7adbe | |||
| 707ca54ef9 | |||
| ca93b8865a | |||
| 86dd4ede3a | |||
| 5b7b759131 | |||
| 2aa247b3c3 | |||
| ec126a5976 | |||
| c8814237cf | |||
| e98b6576f1 | |||
| c429b1d5ff | |||
| 09de0cf2f5 | |||
| a01d933218 | |||
| d8b7af424e | |||
| 798ed3a2dd | |||
| d3c9e0bbcd | |||
| b69947fc57 | |||
| e4553f27d1 | |||
| cf68a07b00 | |||
| c691fb779a | |||
| a93fccc234 | |||
| 4bea349b04 | |||
| ab41689a9b | |||
| 921e5111b5 | |||
| 21c7b1019e | |||
| d64a74b1be | |||
| 343a771c4f | |||
| 5e96516bf6 | |||
| 582b764679 | |||
| 56528ee68a | |||
| 8856a26869 | |||
| b2eb51c155 | |||
| a95d1bb672 | |||
| 5b572cd5fc | |||
| 8fce6fc8d4 | |||
| d2eabd1836 | |||
| 8c3f621e21 | |||
| 0275c8a5c4 | |||
| 0dd25d7140 | |||
| 079749b3e8 | |||
| c0fd0f410f | |||
| 58753f60d8 | |||
| 04f6117e36 | |||
| 7f4633a3d1 | |||
| d6c260b803 | |||
| 2dba6e644f | |||
| a7d2acb591 | |||
| 2b5a670bef | |||
| 16eff6bebb | |||
| c7c224b5f1 | |||
| 86a8f49e82 | |||
| 9a9e22fbce | |||
| d7d059767b | |||
| 3b38863b61 | |||
| c092e4c888 | |||
| 17a884f7e9 | |||
| 920d775965 | |||
| 7a3c598fb9 | |||
| 8b185cf48c | |||
| 0c7ec7c197 | |||
| 7b13473af8 | |||
| b586d988e6 | |||
| 16ac66c35f | |||
| ecf78a36ba | |||
| 39bb9f5240 | |||
| f76332ef71 | |||
| ed367fb1e5 | |||
| b04fb5cd97 | |||
| 5ea3cbd014 | |||
| cc9fc70d6d | |||
| 8aa5668a73 | |||
| bd9e0c9b5a | |||
| f79cce34fa | |||
| fc02c26a84 | |||
| c14bb6e18a | |||
| 62f4599140 | |||
| 56fa8aee84 | |||
| 6d7100b8ec | |||
| 602025b48b | |||
| 0e571d1905 | |||
| 757ad31f92 | |||
| 01f20a29d2 | |||
| 5fd1d9b431 | |||
| 6151be72ce | |||
| 299cee7771 | |||
| a01d2571de | |||
| 1c3ffba300 | |||
| ba9d65898f | |||
| 814f19390d | |||
| af8caa4cc8 | |||
| ff55a7625a | |||
| 8e5daf735d | |||
| f2006ae97a | |||
| efb392f77b | |||
| 739730efe5 | |||
| 05e72a5932 | |||
| a1e4b51d55 | |||
| 006a1fb0f4 | |||
| e14eee0ac5 | |||
| 49fd8448c0 | |||
| b79fdb1534 | |||
| 3931ecabdb | |||
| 7a3a55d399 | |||
| 340098cec3 | |||
| 12b41e3ab0 | |||
| ce570be40e | |||
| 5e77512009 | |||
| 321e38590c | |||
| 7ae2f7de00 | |||
| 056dd34f9b | |||
| 623b9910d5 | |||
| 6011cad546 | |||
| e56b86823e | |||
| 878860d249 | |||
| 3ff3469455 | |||
| cca5e27de7 | |||
| 7e1b53bf3e | |||
| ddb3f9ba6d | |||
| 3b675a7ab3 | |||
| f6b3938f96 | |||
| b0493e03af | |||
| 1ad754d933 | |||
| 001c8255eb | |||
| 1e4341a6ec | |||
| 2bee2efae5 | |||
| 065e764387 | |||
| e7032a6313 | |||
| b23a8c20eb | |||
| 5cc3c1b4fa | |||
| 88f7172fb4 | |||
| fd76a03257 | |||
| adf94adc7b | |||
| 98bc206169 | |||
| 17b5224090 | |||
| 56829c15d8 | |||
| df0f9068d6 | |||
| de05aa7f88 | |||
| 9997d0c77f | |||
| d4c8383266 | |||
| 986bc38a19 | |||
| f96876fe04 | |||
| a5bf63c2c6 | |||
| a4e4527b04 | |||
| 506f67f222 | |||
| 5c0a0237d7 | |||
| 2a86caeb3d | |||
| eaaba5beeb | |||
| 72c762f9cb | |||
| 972fa0b25b | |||
| da6e3e17a6 | |||
| db553d328a | |||
| 3fc7868759 | |||
| 62a3578e0d | |||
| 42f48b41ba | |||
| 7667eee725 | |||
| 597ad23ba1 | |||
| 838cfd59a6 | |||
| 984d67eaa1 | |||
| 6121c18088 | |||
| 392940cfa8 | |||
| 118d85f1e8 | |||
| 236b841182 | |||
| da17597121 | |||
| bd44d1e95a | |||
| 67ab52db90 | |||
| cff6e7f085 | |||
| 7c6bc9cd7e | |||
| 484de372ec | |||
| 07dbb86203 | |||
| 53cb10bb89 | |||
| e69730d9d6 | |||
| ef328369b8 | |||
| e5b2fa2ec7 | |||
| 97f8092868 | |||
| d2dbc4c44c | |||
| d77d005659 | |||
| 104c5b3da4 | |||
| 53e39a1dc6 | |||
| 3cb41fa6e7 | |||
| 88d583bfb1 | |||
| a8b12e4461 | |||
| bc6339bf52 | |||
| 15d8e94678 | |||
| 250070dc15 | |||
| f7ee4f103c | |||
| fbbe5ff767 | |||
| 5d755990b7 | |||
| fdea1a753e | |||
| d02d63d1eb | |||
| 153d230907 | |||
| 3a11b54394 | |||
| 6fd7e3de63 | |||
| 33407fad16 | |||
| a9169276e5 | |||
| df5d752c4b | |||
| cd73d36bdf | |||
| 2b2d8b8a5c | |||
| a052559983 | |||
| 8de72f88f4 | |||
| d89c199f3a | |||
| 378da932b5 | |||
| c89cb41c5b | |||
| ca0f7ca3e8 | |||
| 6abc52d074 | |||
| f12aacd1da | |||
| c32d40636d | |||
| 6b16535958 | |||
| 58ba597c62 | |||
| 8e552d0a96 | |||
| 4f73a52192 | |||
| 7486317363 | |||
| 7ac7b1f9c6 | |||
| 10c6140e3c | |||
| c50bf5bebf | |||
| 0e2ae5e5e1 | |||
| 1474da8b2e | |||
| e95d1bfbcf | |||
| f0d014eba2 | |||
| 9e6da193c8 | |||
| e8e17f5530 | |||
| 0d126c3be0 | |||
| d46c8d71a0 | |||
| 99b3e67918 | |||
| d6aa51bf24 | |||
| f288c77893 | |||
| f7d0513ad5 | |||
| 8c93dae2ba | |||
| 42802703d4 | |||
| e8e8a4bd8a | |||
| e8d77679e4 | |||
| 901ed73fc9 | |||
| b444046661 | |||
| cff356461d | |||
| adfb2f4143 | |||
| 4a24edc9ea | |||
| 48e4c12187 | |||
| 559e05f0f4 | |||
| 1e77579b33 | |||
| ed7f818514 | |||
| 8b732db931 | |||
| 922de4abaa | |||
| c401324667 | |||
| fed25100d4 | |||
| 51d2c37458 | |||
| 9630595333 | |||
| 178aa46ad4 | |||
| 10bc218dee | |||
| 243ccade0b | |||
| e29b54c54d | |||
| 3b937c284c | |||
| 5b2c1bab8e | |||
| ba556e1e0d | |||
| 8d4e752274 | |||
| b20b45023d | |||
| f42f45e305 | |||
| aa5a2bffe8 | |||
| 73138d83bd | |||
| 92e84c05ce | |||
| eb49015dce | |||
| d9f3bca478 | |||
| c039b0a45d | |||
| ccf4ab934f | |||
| 317a7e4ac4 | |||
| 41ff500ccf | |||
| c5fb31fbe5 | |||
| 54a134e72f | |||
| 8b9ec40abc | |||
| 6d305286df | |||
| e8d69e67be | |||
| 31342746a0 | |||
| b11cf10622 | |||
| cacec3adaa | |||
| cd945419c4 | |||
| 3a02788e3a | |||
| a5059a7946 | |||
| a596afb498 | |||
| 87c390da4c | |||
| ef8631bd1f | |||
| e271d0ff29 | |||
| 233bbf9861 | |||
| 0019f71b46 | |||
| 077882f672 | |||
| db7a9ce0ac | |||
| 50de747792 | |||
| f88e11bdb2 | |||
| ca8ed3b006 | |||
| 0a1ac0183c | |||
| 52c0f26c08 | |||
| ea42694dc8 | |||
| 225b10e866 | |||
| eb881690c7 | |||
| eb513e19df | |||
| f305f40acb | |||
| a457601d77 | |||
| 61eca8a371 | |||
| e5765c6a9b | |||
| 957fd786f8 | |||
| e66eaae328 | |||
| f40ef0b0a3 | |||
| 858045bb18 | |||
| 95c174c094 | |||
| 4552b7c7ab | |||
| d454db70e8 | |||
| db0183b5b3 | |||
| b45ee62e3d | |||
| 5f0235ce67 | |||
| 9f1aa4aef9 | |||
| 85bcb4e70c | |||
| b9cf48d9c8 | |||
| e611165fc8 | |||
| 67aee00dc4 | |||
| c32b802a07 | |||
| 2098c85287 | |||
| 2bc851c38b | |||
| fdaecf54e5 | |||
| 1ce5952d1a | |||
| 44e9c4e819 | |||
| 16820d1da2 | |||
| 8fb2b052e4 | |||
| a8e25b16ec | |||
| 48c4a7e7d4 | |||
| 529d81739c | |||
| 81c1ccf2ed | |||
| b992f45bdd | |||
| 092e679103 | |||
| 2eccae8097 | |||
| 6d9f08622b | |||
| cb186979d5 | |||
| 6c95a0505a | |||
| 81d56b5cb9 | |||
| fa3c084d86 | |||
| c077a03d54 | |||
| f5cc255caa | |||
| 871998c529 | |||
| 612f0a82a7 | |||
| c156aed68d | |||
| 8015b40980 | |||
| a97155d8fb | |||
| d23e005618 | |||
| 3ae864d39e | |||
| 4697ad4415 | |||
| 7aef267fdd | |||
| e3f5f6e720 | |||
| 6a41ea10a3 | |||
| 03065369a7 | |||
| 38386a3d96 | |||
| 06cb004a9b | |||
| dcc8a831f9 | |||
| b97b1398f7 | |||
| c3e7159cb7 | |||
| 0e3dbf6e38 | |||
| c398908d50 | |||
| c4c037f839 | |||
| 66fe5f1483 | |||
| 8440affe5f | |||
| 6c54214732 | |||
| 78cd5a88bd | |||
| 5faf15723d | |||
| 395a97b0fc | |||
| df698e9560 | |||
| 862cdc8aa7 | |||
| f50cc5b80d | |||
| 5412bddfcf | |||
| ffba4ebb8e | |||
| 468362aac4 | |||
| 04c3594627 | |||
| b49a2cd012 | |||
| c0b9017679 | |||
| e315d05355 | |||
| 573fefc86d | |||
| ccb4827c52 | |||
| b8a1fe1af6 | |||
| 083e655bde | |||
| 8596b73375 | |||
| c518c0bcd6 | |||
| 13024417ca | |||
| e86eda5f54 | |||
| 9d982c466b | |||
| a82413c32a | |||
| e48a52c023 | |||
| d9cd733c90 | |||
| 4e2ae73fb0 | |||
| 86d896dd44 | |||
| 6d11c54874 | |||
| 1a817f6684 | |||
| ee3716623c | |||
| 2fe2f850c2 | |||
| 0794363a3c | |||
| b0e37dacf4 | |||
| 1893107b07 | |||
| 50b374bd3e | |||
| be9bc22df4 | |||
| d19a2e4337 | |||
| 288f94de35 | |||
| 709b670819 | |||
| 9cfa7134b0 | |||
| 4d6f523260 | |||
| be69946036 | |||
| fdb8aa216e | |||
| 4ae799ec39 | |||
| 6ea6d6756b | |||
| 3c33961395 | |||
| 94053f37ee | |||
| 424aa7cf80 | |||
| ef1322be57 | |||
| 95badeee62 | |||
| d9bd5a465b | |||
| 8ac4f0122b | |||
| b49a5ca04f | |||
| fdc9450f8c | |||
| 3528163175 | |||
| c47bfb4fcd | |||
| 3355332ebd | |||
| 27f5fb8688 | |||
| 6cabc23dad | |||
| 487dcc643c | |||
| 75a66a4f9b | |||
| ce02e30587 | |||
| 20f8c084c1 | |||
| 222c8a8252 | |||
| 052128a395 | |||
| cb00f3a5db | |||
| 7c7d0265d1 | |||
| 2b7ec78797 | |||
| b795213649 | |||
| 36a7e81f1b | |||
| 931583693d | |||
| 3e23807623 | |||
| 31d0e8c452 | |||
| 42be65a3d2 | |||
| e9172f7e5f | |||
| 5dada0d584 | |||
| b212d8afbb | |||
| 7ed7c66015 | |||
| dba14f8c74 | |||
| d62982b4b6 | |||
| 3e70fedb14 | |||
| cbb97c1d2e | |||
| 3bd5984480 | |||
| 894a4ab118 | |||
| 5b32305f43 | |||
| 965dd986f2 | |||
| 8eb8ed873c | |||
| 4d18c8b21d | |||
| 75db28c522 | |||
| 551d5cf4ca | |||
| 3e63dfb696 | |||
| c164253474 | |||
| 7746b65f9a | |||
| bb77ef8e4d | |||
| afe0f2d449 | |||
| e343b1d38c | |||
| 19c1261e81 | |||
| 2040d2b34a | |||
| d7d5911b93 | |||
| 8915b73953 | |||
| 07635ad828 | |||
| 3aa674fca0 | |||
| cf832af14b | |||
| 49028e2950 | |||
| 539be0f011 | |||
| 66c737a22d | |||
| 24b5ea14b1 | |||
| 3cfcf14a50 | |||
| 28b4087b69 | |||
| 1ca5b87db4 | |||
| 469466d3c9 | |||
| 9474830136 | |||
| 54e322ee3e | |||
| 853dab3f5c | |||
| f334ee2606 | |||
| f6477ed868 | |||
| 4935ae867d | |||
| 2246d790a4 | |||
| 1f9f8f5e30 | |||
| c10c453eac | |||
| 3d0678725e | |||
| cdf18dc972 | |||
| 76788d3ae2 | |||
| 658003080e | |||
| e803f36f78 | |||
| 9742d5bf07 | |||
| 3fe9b5273c | |||
| 3b1b038b51 | |||
| b27d924d82 | |||
| 24b3b485b7 | |||
| 467c22fcd3 | |||
| 1571119e0f | |||
| 634e68de5a | |||
| ab77d93950 | |||
| ddb90a046a | |||
| 33704abc0c | |||
| 5c62e339c1 | |||
| 9b188b4520 | |||
| 36944c1941 | |||
| 987c853448 | |||
| 8b930e81e9 | |||
| eb6b201a2a | |||
| a39d46238b | |||
| 65941368b8 | |||
| ed4824d959 | |||
| 9e0be76911 | |||
| 70c3d65863 | |||
| f733147517 | |||
| ec7b4b45ec | |||
| 7a2f71a6c1 | |||
| 22a3c2962d | |||
| 364749f281 | |||
| fbec74bd94 | |||
| 3bf59689fb | |||
| cd1c88b4d4 | |||
| 0affd8b619 | |||
| 163ccbbe59 | |||
| 42d433a92f | |||
| 2be34c42f4 |
@@ -0,0 +1,15 @@
|
||||
# Copyright (c) Abstract Machines
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# CoAP is temporarily ignored since we don't have tests for it yet.
|
||||
coverage:
|
||||
ignore:
|
||||
- "tools/*"
|
||||
- "api/grpc/**"
|
||||
- "cmd/*"
|
||||
- "coap/**"
|
||||
- "**/mocks/*"
|
||||
- "*/middleware/*"
|
||||
- "pkg/sid/mock.go"
|
||||
- "pkg/tracing/utils.go"
|
||||
- "pkg/prometheus/*"
|
||||
@@ -5,7 +5,7 @@ blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Google group
|
||||
url: https://groups.google.com/forum/#!forum/mainflux
|
||||
about: Join the Mainflux community on Google group.
|
||||
about: Join the Magistrala community on Google group.
|
||||
- name: Gitter
|
||||
url: https://gitter.im/mainflux/mainflux
|
||||
about: Join the Mainflux community on Gitter.
|
||||
about: Join the Magistrala community on Gitter.
|
||||
@@ -4,7 +4,7 @@ SPDX-License-Identifier: Apache-2.0 -->
|
||||
<!--
|
||||
|
||||
Pull request title should be `MG-XXX - description` or `NOISSUE - description` where XXX is ID of the issue that this PR relate to.
|
||||
Please review the [CONTRIBUTING.md](https://github.com/absmach/magistrala/blob/master/CONTRIBUTING.md) file for detailed contributing guidelines.
|
||||
Please review the [CONTRIBUTING.md](https://github.com/absmach/magistrala/blob/main/CONTRIBUTING.md) file for detailed contributing guidelines.
|
||||
|
||||
For Work In Progress Pull Requests, please use the Draft PR feature, see https://github.blog/2019-02-14-introducing-draft-pull-requests/ for further details.
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
# Copyright (c) Abstract Machines
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "./.github/workflows"
|
||||
target-branch: "main"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
day: "monday"
|
||||
time: "06:00"
|
||||
timezone: "Europe/Paris"
|
||||
groups:
|
||||
gh-dependency:
|
||||
patterns:
|
||||
- "*"
|
||||
|
||||
- package-ecosystem: "gomod"
|
||||
directory: "/"
|
||||
target-branch: "main"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
day: "monday"
|
||||
time: "06:15"
|
||||
timezone: "Europe/Paris"
|
||||
groups:
|
||||
go-dependency:
|
||||
patterns:
|
||||
- "*"
|
||||
|
||||
- package-ecosystem: "docker"
|
||||
directory: "/docker"
|
||||
target-branch: "main"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
day: "monday"
|
||||
time: "06:30"
|
||||
timezone: "Europe/Paris"
|
||||
groups:
|
||||
docker-dependency:
|
||||
patterns:
|
||||
- "*"
|
||||
@@ -1,19 +0,0 @@
|
||||
# Copyright (c) Abstract Machines
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
|
||||
- package-ecosystem: "gomod"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
|
||||
- package-ecosystem: "docker"
|
||||
directory: "./docker"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
@@ -0,0 +1,181 @@
|
||||
<!--
|
||||
Copyright (c) Abstract Machines
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Magistrala API Documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5.30.3/swagger-ui.css">
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.topbar {
|
||||
display: none;
|
||||
}
|
||||
.service-selector {
|
||||
background: #1b1b1b;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
.service-selector h1 {
|
||||
color: #fff;
|
||||
margin: 0 0 15px 0;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
.service-dropdown-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
.service-dropdown-container label {
|
||||
color: #fff;
|
||||
font-family: sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
}
|
||||
.service-dropdown {
|
||||
background: #2d2d2d;
|
||||
color: white;
|
||||
border: 1px solid #4990e2;
|
||||
padding: 10px 40px 10px 15px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
min-width: 200px;
|
||||
appearance: none;
|
||||
background-image: url('data:image/svg+xml;charset=UTF-8,<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"><path fill="%23ffffff" d="M6 9L1 4h10z"/></svg>');
|
||||
background-repeat: no-repeat;
|
||||
background-position: right 12px center;
|
||||
}
|
||||
.service-dropdown:hover {
|
||||
background-color: #3a3a3a;
|
||||
border-color: #357abd;
|
||||
}
|
||||
.service-dropdown:focus {
|
||||
outline: none;
|
||||
border-color: #4990e2;
|
||||
box-shadow: 0 0 0 2px rgba(73, 144, 226, 0.3);
|
||||
}
|
||||
|
||||
/* Responsive styles for mobile */
|
||||
@media (max-width: 768px) {
|
||||
.service-selector {
|
||||
padding: 15px 10px;
|
||||
}
|
||||
.service-selector h1 {
|
||||
font-size: 1.5rem;
|
||||
margin: 0 0 12px 0;
|
||||
}
|
||||
.service-dropdown-container {
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
.service-dropdown-container label {
|
||||
font-size: 13px;
|
||||
}
|
||||
.service-dropdown {
|
||||
width: 100%;
|
||||
max-width: 300px;
|
||||
min-width: auto;
|
||||
font-size: 13px;
|
||||
padding: 8px 35px 8px 12px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.service-selector h1 {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
.service-dropdown {
|
||||
max-width: 250px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="service-selector">
|
||||
<h1>Magistrala API Documentation</h1>
|
||||
<div class="service-dropdown-container">
|
||||
<label for="serviceDropdown">Select Service:</label>
|
||||
<select id="serviceDropdown" class="service-dropdown"></select>
|
||||
</div>
|
||||
</div>
|
||||
<div id="swagger-ui"></div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5.30.3/swagger-ui-bundle.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5.30.3/swagger-ui-standalone-preset.js"></script>
|
||||
<script>
|
||||
// Available API specifications
|
||||
const APIs = APIS_PLACEHOLDER;
|
||||
|
||||
// Get the service from URL query parameter, default to first service
|
||||
function getServiceFromURL() {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const service = params.get('service');
|
||||
return service && APIs.includes(service) ? service : APIs[0];
|
||||
}
|
||||
|
||||
// Update URL with selected service
|
||||
function updateURL(service) {
|
||||
const url = new URL(window.location);
|
||||
url.searchParams.set('service', service);
|
||||
window.history.pushState({}, '', url);
|
||||
}
|
||||
|
||||
// Create service selector dropdown
|
||||
function createServiceDropdown() {
|
||||
const dropdown = document.getElementById('serviceDropdown');
|
||||
const currentService = getServiceFromURL();
|
||||
|
||||
APIs.forEach(api => {
|
||||
const option = document.createElement('option');
|
||||
option.value = api;
|
||||
let serviceName = api.replace('.yaml', '').replace(/^\w/, c => c.toUpperCase());
|
||||
if (serviceName.toLowerCase() === 'http') {
|
||||
serviceName = 'HTTP';
|
||||
}
|
||||
option.textContent = serviceName;
|
||||
if (api === currentService) {
|
||||
option.selected = true;
|
||||
}
|
||||
dropdown.appendChild(option);
|
||||
});
|
||||
|
||||
// Handle dropdown change
|
||||
dropdown.addEventListener('change', (e) => {
|
||||
const selectedApi = e.target.value;
|
||||
loadSwaggerUI(selectedApi);
|
||||
updateURL(selectedApi);
|
||||
});
|
||||
}
|
||||
|
||||
// Load Swagger UI with specified API spec
|
||||
function loadSwaggerUI(apiSpec) {
|
||||
SwaggerUIBundle({
|
||||
url: apiSpec,
|
||||
dom_id: '#swagger-ui',
|
||||
deepLinking: true,
|
||||
presets: [
|
||||
SwaggerUIBundle.presets.apis,
|
||||
SwaggerUIStandalonePreset
|
||||
],
|
||||
plugins: [
|
||||
SwaggerUIBundle.plugins.DownloadUrl
|
||||
],
|
||||
layout: "StandaloneLayout"
|
||||
});
|
||||
}
|
||||
|
||||
// Initialize
|
||||
createServiceDropdown();
|
||||
loadSwaggerUI(getServiceFromURL());
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,244 @@
|
||||
# Copyright (c) Abstract Machines
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: Property Based Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- ".github/workflows/api-tests.yaml"
|
||||
- "api/**"
|
||||
- "internal/atom/**"
|
||||
- "channels/api/http/**"
|
||||
- "clients/api/http/**"
|
||||
- "domains/api/http/**"
|
||||
- "groups/api/http/**"
|
||||
- "users/api/**"
|
||||
- "bootstrap/api/**"
|
||||
- "certs/api/http/**"
|
||||
- "readers/api/http/**"
|
||||
- "apidocs/openapi/**"
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- ".github/workflows/api-tests.yaml"
|
||||
- "api/**"
|
||||
- "internal/atom/**"
|
||||
- "channels/api/http/**"
|
||||
- "clients/api/http/**"
|
||||
- "domains/api/http/**"
|
||||
- "groups/api/http/**"
|
||||
- "users/api/**"
|
||||
- "bootstrap/api/**"
|
||||
- "certs/api/http/**"
|
||||
- "readers/api/http/**"
|
||||
- "apidocs/openapi/**"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
ATOM_LOGIN_URL: http://localhost/auth/login
|
||||
USER_IDENTITY: admin
|
||||
USER_SECRET: 12345678
|
||||
DOMAIN_NAME: demo-test
|
||||
USERS_URL: http://localhost
|
||||
DOMAIN_URL: http://localhost
|
||||
CLIENTS_URL: http://localhost
|
||||
CHANNELS_URL: http://localhost
|
||||
GROUPS_URL: http://localhost
|
||||
BOOTSTRAP_URL: http://localhost:9013
|
||||
CERTS_URL: http://localhost:9019
|
||||
READERS_URL: http://localhost:9011
|
||||
|
||||
jobs:
|
||||
api-test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v7
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
cache-dependency-path: "go.sum"
|
||||
|
||||
- name: Check for changes in specific paths
|
||||
uses: dorny/paths-filter@v4
|
||||
id: changes
|
||||
with:
|
||||
filters: |
|
||||
workflow:
|
||||
- ".github/workflows/api-tests.yaml"
|
||||
|
||||
domains:
|
||||
- "apidocs/openapi/domains.yaml"
|
||||
- "internal/atom/**"
|
||||
- "domains/api/http/**"
|
||||
|
||||
clients:
|
||||
- "apidocs/openapi/clients.yaml"
|
||||
- "internal/atom/**"
|
||||
- "clients/api/http/**"
|
||||
|
||||
channels:
|
||||
- "apidocs/openapi/channels.yaml"
|
||||
- "internal/atom/**"
|
||||
- "channels/api/http/**"
|
||||
|
||||
groups:
|
||||
- "apidocs/openapi/groups.yaml"
|
||||
- "internal/atom/**"
|
||||
- "groups/api/http/**"
|
||||
|
||||
users:
|
||||
- "apidocs/openapi/users.yaml"
|
||||
- "internal/atom/**"
|
||||
- "users/api/**"
|
||||
|
||||
bootstrap:
|
||||
- "apidocs/openapi/bootstrap.yaml"
|
||||
- "bootstrap/api/**"
|
||||
|
||||
certs:
|
||||
- "apidocs/openapi/certs.yaml"
|
||||
- "certs/api/http/**"
|
||||
|
||||
readers:
|
||||
- "apidocs/openapi/readers.yaml"
|
||||
- "readers/api/http/**"
|
||||
|
||||
- name: Build images
|
||||
run: make all -j $(nproc) && make dockers_dev -j $(nproc)
|
||||
|
||||
- name: Provision Atom service tokens
|
||||
run: make provision_atom_tokens
|
||||
|
||||
- name: Start containers
|
||||
run: make run_latest_ci up args="-d" && make run_addons up args="-d"
|
||||
|
||||
- name: Wait for services to be ready
|
||||
run: |
|
||||
echo "Waiting for services to start..."
|
||||
sleep 15
|
||||
|
||||
# Check if services are responding
|
||||
for i in {1..30}; do
|
||||
if curl -f -s http://localhost/health > /dev/null 2>&1; then
|
||||
echo "Services are ready!"
|
||||
exit 0
|
||||
fi
|
||||
echo "Waiting for services... ($i/30)"
|
||||
sleep 2
|
||||
done
|
||||
|
||||
echo "Services failed to become ready" >&2
|
||||
docker compose -f docker/docker-compose.yaml -f docker/docker-compose-ci.yaml --env-file docker/.env --env-file docker/.env.tokens -p "${USER_REPO:-absmach_magistrala}" ps || true
|
||||
docker logs --tail 100 magistrala-nginx || true
|
||||
docker logs --tail 100 magistrala-atom || true
|
||||
docker logs --tail 100 magistrala-atom-bootstrap || true
|
||||
exit 1
|
||||
|
||||
- name: Set access token
|
||||
run: |
|
||||
export USER_TOKEN=$(curl -fsS -X POST "$ATOM_LOGIN_URL" -H "Content-Type: application/json" -d "{\"identifier\":\"$USER_IDENTITY\",\"secret\":\"$USER_SECRET\",\"kind\":\"password\"}" | jq -er .token)
|
||||
echo "USER_TOKEN=$USER_TOKEN" >> $GITHUB_ENV
|
||||
|
||||
- name: Run Users API tests
|
||||
if: (steps.changes.outputs.users == 'true' || steps.changes.outputs.workflow == 'true') && hashFiles('users/api/**') != ''
|
||||
uses: schemathesis/action@v3.0.0
|
||||
with:
|
||||
schema: apidocs/openapi/users.yaml
|
||||
base-url: ${{ env.USERS_URL }}
|
||||
checks: all
|
||||
args: '--header "Authorization: Bearer ${{ env.USER_TOKEN }}" --suppress-health-check=filter_too_much --exclude-checks=positive_data_acceptance --exclude-operation-id=requestPasswordReset --phases=examples'
|
||||
coverage-artifact-name: schema-coverage-users
|
||||
coverage-pr-comment: false
|
||||
|
||||
- name: Run Groups API tests
|
||||
if: (steps.changes.outputs.groups == 'true' || steps.changes.outputs.workflow == 'true') && hashFiles('groups/api/http/**') != ''
|
||||
uses: schemathesis/action@v3.0.0
|
||||
with:
|
||||
schema: apidocs/openapi/groups.yaml
|
||||
base-url: ${{ env.GROUPS_URL }}
|
||||
checks: all
|
||||
args: '--header "Authorization: Bearer ${{ env.USER_TOKEN }}" --suppress-health-check=filter_too_much --exclude-checks=positive_data_acceptance --phases=examples'
|
||||
coverage-artifact-name: schema-coverage-groups
|
||||
coverage-pr-comment: false
|
||||
|
||||
- name: Run Clients API tests
|
||||
if: (steps.changes.outputs.clients == 'true' || steps.changes.outputs.workflow == 'true') && hashFiles('clients/api/http/**') != ''
|
||||
uses: schemathesis/action@v3.0.0
|
||||
with:
|
||||
schema: apidocs/openapi/clients.yaml
|
||||
base-url: ${{ env.CLIENTS_URL }}
|
||||
checks: all
|
||||
args: '--header "Authorization: Bearer ${{ env.USER_TOKEN }}" --suppress-health-check=filter_too_much --exclude-checks=positive_data_acceptance --phases=examples'
|
||||
coverage-artifact-name: schema-coverage-clients
|
||||
coverage-pr-comment: false
|
||||
|
||||
- name: Run Channels API tests
|
||||
if: (steps.changes.outputs.channels == 'true' || steps.changes.outputs.workflow == 'true') && hashFiles('channels/api/http/**') != ''
|
||||
uses: schemathesis/action@v3.0.0
|
||||
with:
|
||||
schema: apidocs/openapi/channels.yaml
|
||||
base-url: ${{ env.CHANNELS_URL }}
|
||||
checks: all
|
||||
args: '--header "Authorization: Bearer ${{ env.USER_TOKEN }}" --suppress-health-check=filter_too_much --exclude-checks=positive_data_acceptance --phases=examples'
|
||||
coverage-artifact-name: schema-coverage-channels
|
||||
coverage-pr-comment: false
|
||||
|
||||
- name: Run Domains API tests
|
||||
if: (steps.changes.outputs.domains == 'true' || steps.changes.outputs.workflow == 'true') && hashFiles('domains/api/http/**') != ''
|
||||
uses: schemathesis/action@v3.0.0
|
||||
with:
|
||||
schema: apidocs/openapi/domains.yaml
|
||||
base-url: ${{ env.DOMAIN_URL }}
|
||||
checks: all
|
||||
args: '--header "Authorization: Bearer ${{ env.USER_TOKEN }}" --suppress-health-check=filter_too_much --exclude-checks=positive_data_acceptance --phases=examples'
|
||||
coverage-artifact-name: schema-coverage-domains
|
||||
coverage-pr-comment: false
|
||||
|
||||
- name: Run Bootstrap API tests
|
||||
if: (steps.changes.outputs.bootstrap == 'true' || steps.changes.outputs.workflow == 'true') && hashFiles('bootstrap/api/**') != ''
|
||||
uses: schemathesis/action@v3.0.0
|
||||
with:
|
||||
schema: apidocs/openapi/bootstrap.yaml
|
||||
base-url: ${{ env.BOOTSTRAP_URL }}
|
||||
checks: all
|
||||
args: '--header "Authorization: Bearer ${{ env.USER_TOKEN }}" --suppress-health-check=filter_too_much --exclude-checks=positive_data_acceptance --phases=examples'
|
||||
coverage-artifact-name: schema-coverage-bootstrap
|
||||
coverage-pr-comment: false
|
||||
|
||||
- name: Run Certs API tests
|
||||
if: (steps.changes.outputs.certs == 'true' || steps.changes.outputs.workflow == 'true') && hashFiles('docker/addons/certs/docker-compose.yaml') != ''
|
||||
uses: schemathesis/action@v3.0.0
|
||||
with:
|
||||
schema: apidocs/openapi/certs.yaml
|
||||
base-url: ${{ env.CERTS_URL }}
|
||||
checks: all
|
||||
args: '--header "Authorization: Bearer ${{ env.USER_TOKEN }}" --suppress-health-check=filter_too_much --exclude-checks=positive_data_acceptance --phases=examples'
|
||||
coverage-artifact-name: schema-coverage-certs
|
||||
coverage-pr-comment: false
|
||||
|
||||
- name: Run Readers API tests
|
||||
if: steps.changes.outputs.readers == 'true' || steps.changes.outputs.workflow == 'true'
|
||||
uses: schemathesis/action@v3.0.0
|
||||
with:
|
||||
schema: apidocs/openapi/readers.yaml
|
||||
base-url: ${{ env.READERS_URL }}
|
||||
checks: all
|
||||
args: '--header "Authorization: Bearer ${{ env.USER_TOKEN }}" --suppress-health-check=filter_too_much --exclude-checks=positive_data_acceptance --phases=examples'
|
||||
coverage-artifact-name: schema-coverage-readers
|
||||
coverage-pr-comment: false
|
||||
|
||||
- name: Stop containers
|
||||
if: always()
|
||||
run: make run_latest_ci down args="-v" && make run_addons down args="-v"
|
||||
@@ -0,0 +1,59 @@
|
||||
# Copyright (c) Abstract Machines
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: Continuous Delivery
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths-ignore:
|
||||
- "**/*.md"
|
||||
- "docs/**"
|
||||
- ".github/workflows/**"
|
||||
- "LICENSE"
|
||||
- "MAINTAINERS"
|
||||
- "CODEOWNERS"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
lint-and-build:
|
||||
uses: ./.github/workflows/lint-and-build.yaml
|
||||
|
||||
build-and-push:
|
||||
name: Build and Push Docker Images
|
||||
runs-on: ubuntu-latest
|
||||
needs: [lint-and-build]
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-tags: true
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v7
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
cache-dependency-path: "go.sum"
|
||||
|
||||
- name: Set up Docker Build
|
||||
uses: docker/setup-buildx-action@v4
|
||||
|
||||
- name: Login to GHCR
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push Docker images
|
||||
run: |
|
||||
make latest -j $(nproc)
|
||||
@@ -1,58 +0,0 @@
|
||||
# Copyright (c) Abstract Machines
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: Continuous Delivery
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
build-and-push:
|
||||
name: Build and Push
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: 1.21.x
|
||||
cache-dependency-path: "go.sum"
|
||||
|
||||
- name: Run tests
|
||||
run: |
|
||||
make test
|
||||
|
||||
- name: Upload coverage
|
||||
uses: codecov/codecov-action@v3
|
||||
with:
|
||||
token: ${{ secrets.CODECOV }}
|
||||
directory: ./coverage/
|
||||
name: codecov-umbrella
|
||||
verbose: true
|
||||
|
||||
- name: Set up Docker Build
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: docker.io
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_TOKEN }}
|
||||
|
||||
- name: Compile check for rabbitmq
|
||||
run: |
|
||||
MG_MESSAGE_BROKER_TYPE=rabbitmq make mqtt
|
||||
|
||||
- name: Compile check for redis
|
||||
run: |
|
||||
MG_ES_TYPE=redis make mqtt
|
||||
|
||||
- name: Build and push Dockers
|
||||
run: |
|
||||
make latest -j $(nproc)
|
||||
@@ -0,0 +1,128 @@
|
||||
# Copyright (c) Abstract Machines
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: Check the consistency of generated files
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
check-generated-files:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
PROTOC_VERSION: "35.1"
|
||||
PROTOC_GEN_GO_VERSION: "v1.36.11"
|
||||
PROTOC_GEN_GO_GRPC_VERSION: "v1.6.2"
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v7
|
||||
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v7
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
cache-dependency-path: "go.sum"
|
||||
|
||||
- name: Set GOBIN
|
||||
run: echo "GOBIN=$HOME/.local/bin" >> $GITHUB_ENV
|
||||
|
||||
- name: Add GOBIN to PATH
|
||||
run: echo "$HOME/.local/bin" >> $GITHUB_PATH
|
||||
|
||||
- name: Check for changes in go.mod
|
||||
run: |
|
||||
go mod tidy
|
||||
git diff --exit-code
|
||||
|
||||
- name: Check for changes in specific paths
|
||||
uses: dorny/paths-filter@v4
|
||||
id: changes
|
||||
with:
|
||||
base: main
|
||||
filters: |
|
||||
proto:
|
||||
- ".github/workflows/check-generated-files.yaml"
|
||||
- "auth.proto"
|
||||
- "auth/*.pb.go"
|
||||
- "pkg/messaging/message.proto"
|
||||
- "pkg/messaging/*.pb.go"
|
||||
|
||||
mocks:
|
||||
- "tools/config/.mockery.yaml"
|
||||
- ".github/workflows/check-generated-files.yaml"
|
||||
- "pkg/sdk/sdk.go"
|
||||
- "users/postgres/clients.go"
|
||||
- "users/clients.go"
|
||||
- "pkg/clients/clients.go"
|
||||
- "pkg/messaging/pubsub.go"
|
||||
- "clients/postgres/clients.go"
|
||||
- "clients/clients.go"
|
||||
- "pkg/authz.go"
|
||||
- "pkg/authn.go"
|
||||
- "auth/domains.go"
|
||||
- "auth/keys.go"
|
||||
- "auth/service.go"
|
||||
- "pkg/events/events.go"
|
||||
- "pkg/groups/groups.go"
|
||||
- "users/emailer.go"
|
||||
- "users/hasher.go"
|
||||
- "consumers/notifier.go"
|
||||
|
||||
- name: Install Protoc
|
||||
if: steps.changes.outputs.proto == 'true'
|
||||
uses: arduino/setup-protoc@v3
|
||||
with:
|
||||
version: ${{ env.PROTOC_VERSION }}
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Install Go Protobuf Plugins
|
||||
if: steps.changes.outputs.proto == 'true'
|
||||
run: |
|
||||
go install google.golang.org/protobuf/cmd/protoc-gen-go@$PROTOC_GEN_GO_VERSION
|
||||
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@$PROTOC_GEN_GO_GRPC_VERSION
|
||||
|
||||
- name: Check Protobuf is up to Date
|
||||
if: steps.changes.outputs.proto == 'true'
|
||||
run: |
|
||||
for p in $(find . -name "*.pb.go"); do
|
||||
mv $p $p.tmp
|
||||
done
|
||||
|
||||
make proto
|
||||
|
||||
for p in $(find . -name "*.pb.go"); do
|
||||
if ! cmp -s $p $p.tmp; then
|
||||
echo "Error: Proto file and generated Go file $p are out of sync!"
|
||||
echo "Here is the difference:"
|
||||
diff $p $p.tmp || true
|
||||
echo "Please run 'make proto' with protoc version $PROTOC_VERSION, protoc-gen-go version $PROTOC_GEN_GO_VERSION and protoc-gen-go-grpc version $PROTOC_GEN_GO_GRPC_VERSION and commit the changes."
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
- name: Check Mocks are up to Date
|
||||
if: steps.changes.outputs.mocks == 'true'
|
||||
run: |
|
||||
for f in $(find . -type f -path '*/mocks/*.go' ! -name 'doc.go'); do
|
||||
mv $f $f.tmp
|
||||
done
|
||||
|
||||
make mocks
|
||||
|
||||
check_mock_changes() {
|
||||
local file_path=$1
|
||||
local tmp_file_path=$1.tmp
|
||||
local entity_name=$2
|
||||
|
||||
if ! cmp -s "$file_path" "$tmp_file_path"; then
|
||||
echo "Error: Generated mocks for $entity_name are out of sync!"
|
||||
echo "Please run 'make mocks' with mockery version $MOCKERY_VERSION and commit the changes."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
for f in $(find . -type f -path '*/mocks/*.go' ! -name 'doc.go'); do
|
||||
check_mock_changes $f "$f"
|
||||
done
|
||||
@@ -1,155 +0,0 @@
|
||||
# Copyright (c) Abstract Machines
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: Check the consistency of generated files
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
check-generated-files:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: 1.21.x
|
||||
cache-dependency-path: "go.sum"
|
||||
|
||||
- name: Check for changes in go.mod
|
||||
run: |
|
||||
go mod tidy
|
||||
git diff --exit-code
|
||||
|
||||
- name: Check for changes in specific paths
|
||||
uses: dorny/paths-filter@v2
|
||||
id: changes
|
||||
with:
|
||||
base: main
|
||||
filters: |
|
||||
proto:
|
||||
- ".github/workflows/check-generated-files.yml"
|
||||
- "auth.proto"
|
||||
- "auth/*.pb.go"
|
||||
- "pkg/messaging/message.proto"
|
||||
- "pkg/messaging/*.pb.go"
|
||||
|
||||
mocks:
|
||||
- ".github/workflows/check-generated-files.yml"
|
||||
- "pkg/sdk/go/sdk.go"
|
||||
- "users/postgres/clients.go"
|
||||
- "users/clients.go"
|
||||
- "pkg/clients/clients.go"
|
||||
- "pkg/messaging/pubsub.go"
|
||||
- "things/postgres/clients.go"
|
||||
- "things/things.go"
|
||||
- "auth/domains.go"
|
||||
- "auth/keys.go"
|
||||
- "auth/policies.go"
|
||||
- "auth/service.go"
|
||||
- "pkg/events/events.go"
|
||||
- "provision/service.go"
|
||||
- "pkg/groups/groups.go"
|
||||
|
||||
- name: Set up protoc
|
||||
if: steps.changes.outputs.proto == 'true'
|
||||
run: |
|
||||
PROTOC_VERSION=25.3
|
||||
PROTOC_GEN_VERSION=v1.32.0
|
||||
PROTOC_GRPC_VERSION=v1.3.0
|
||||
|
||||
# Download and install protoc
|
||||
PROTOC_ZIP=protoc-$PROTOC_VERSION-linux-x86_64.zip
|
||||
curl -0L -o $PROTOC_ZIP https://github.com/protocolbuffers/protobuf/releases/download/v$PROTOC_VERSION/$PROTOC_ZIP
|
||||
unzip -o $PROTOC_ZIP -d protoc3
|
||||
sudo mv protoc3/bin/* /usr/local/bin/
|
||||
sudo mv protoc3/include/* /usr/local/include/
|
||||
rm -rf $PROTOC_ZIP protoc3
|
||||
|
||||
# Install protoc-gen-go and protoc-gen-go-grpc
|
||||
go install google.golang.org/protobuf/cmd/protoc-gen-go@$PROTOC_GEN_VERSION
|
||||
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@$PROTOC_GRPC_VERSION
|
||||
|
||||
# Add protoc to the PATH
|
||||
export PATH=$PATH:/usr/local/bin/protoc
|
||||
|
||||
- name: Check Protobuf is up to Date
|
||||
if: steps.changes.outputs.proto == 'true'
|
||||
run: |
|
||||
for p in $(find . -name "*.pb.go"); do
|
||||
mv $p $p.tmp
|
||||
done
|
||||
|
||||
make proto
|
||||
|
||||
for p in $(find . -name "*.pb.go"); do
|
||||
if ! cmp -s $p $p.tmp; then
|
||||
echo "Error: Proto file and generated Go file $p are out of sync!"
|
||||
echo "Please run 'make proto' with protoc version $PROTOC_VERSION, protoc-gen-go version $PROTOC_GEN_VERSION and protoc-gen-go-grpc version $PROTOC_GRPC_VERSION and commit the changes."
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
- name: Check Mocks are up to Date
|
||||
if: steps.changes.outputs.mocks == 'true'
|
||||
run: |
|
||||
MOCKERY_VERSION=v2.38.0
|
||||
go install github.com/vektra/mockery/v2@$MOCKERY_VERSION
|
||||
|
||||
mv ./pkg/sdk/mocks/sdk.go ./pkg/sdk/mocks/sdk.go.tmp
|
||||
mv ./users/mocks/repository.go ./users/mocks/repository.go.tmp
|
||||
mv ./users/mocks/service.go ./users/mocks/service.go.tmp
|
||||
mv ./pkg/messaging/mocks/pubsub.go ./pkg/messaging/mocks/pubsub.go.tmp
|
||||
mv ./things/mocks/repository.go ./things/mocks/repository.go.tmp
|
||||
mv ./things/mocks/service.go ./things/mocks/service.go.tmp
|
||||
mv ./things/mocks/cache.go ./things/mocks/cache.go.tmp
|
||||
mv ./auth/mocks/agent.go ./auth/mocks/agent.go.tmp
|
||||
mv ./auth/mocks/authz.go ./auth/mocks/authz.go.tmp
|
||||
mv ./auth/mocks/domains.go ./auth/mocks/domains.go.tmp
|
||||
mv ./auth/mocks/keys.go ./auth/mocks/keys.go.tmp
|
||||
mv ./auth/mocks/service.go ./auth/mocks/service.go.tmp
|
||||
mv ./pkg/events/mocks/publisher.go ./pkg/events/mocks/publisher.go.tmp
|
||||
mv ./pkg/events/mocks/subscriber.go ./pkg/events/mocks/subscriber.go.tmp
|
||||
mv ./provision/mocks/service.go ./provision/mocks/service.go.tmp
|
||||
mv ./pkg/groups/mocks/repository.go ./pkg/groups/mocks/repository.go.tmp
|
||||
mv ./pkg/groups/mocks/service.go ./pkg/groups/mocks/service.go.tmp
|
||||
|
||||
make mocks
|
||||
|
||||
check_mock_changes() {
|
||||
local file_path=$1
|
||||
local tmp_file_path=$1.tmp
|
||||
local entity_name=$2
|
||||
|
||||
if ! cmp -s "$file_path" "$tmp_file_path"; then
|
||||
echo "Error: Generated mocks for $entity_name are out of sync!"
|
||||
echo "Please run 'make mocks' with mockery version $MOCKERY_VERSION and commit the changes."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
check_mock_changes ./pkg/sdk/mocks/sdk.go "SDK ./pkg/sdk/mocks/sdk.go"
|
||||
check_mock_changes ./users/mocks/repository.go "Users Repository ./users/mocks/repository.go"
|
||||
check_mock_changes ./users/mocks/service.go "Users Service ./users/mocks/service.go"
|
||||
check_mock_changes ./pkg/messaging/mocks/pubsub.go "PubSub ./pkg/messaging/mocks/pubsub.go"
|
||||
check_mock_changes ./things/mocks/repository.go "Things Repository ./things/mocks/repository.go"
|
||||
check_mock_changes ./things/mocks/service.go "Things Service ./things/mocks/service.go"
|
||||
check_mock_changes ./things/mocks/cache.go "Things Cache ./things/mocks/cache.go"
|
||||
check_mock_changes ./auth/mocks/agent.go "Auth Agent ./auth/mocks/agent.go"
|
||||
check_mock_changes ./auth/mocks/authz.go "Auth Authz ./auth/mocks/authz.go"
|
||||
check_mock_changes ./auth/mocks/domains.go "Auth Domains ./auth/mocks/domains.go"
|
||||
check_mock_changes ./auth/mocks/keys.go "Auth Keys ./auth/mocks/keys.go"
|
||||
check_mock_changes ./auth/mocks/service.go "Auth Service ./auth/mocks/service.go"
|
||||
check_mock_changes ./pkg/events/mocks/publisher.go "ES Publisher ./pkg/events/mocks/publisher.go"
|
||||
check_mock_changes ./pkg/events/mocks/subscriber.go "EE Subscriber ./pkg/events/mocks/subscriber.go"
|
||||
check_mock_changes ./provision/mocks/service.go "Provision Service ./provision/mocks/service.go"
|
||||
check_mock_changes ./pkg/groups/mocks/repository.go "Groups Repository ./pkg/groups/mocks/repository.go"
|
||||
check_mock_changes ./pkg/groups/mocks/service.go "Groups Service ./pkg/groups/mocks/service.go"
|
||||
@@ -4,9 +4,6 @@
|
||||
name: Check License Header
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
@@ -16,16 +13,25 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v7
|
||||
|
||||
- name: Check License Header
|
||||
run: |
|
||||
CHECK=$(grep -rcL --exclude-dir={.git,build,**vernemq**} \
|
||||
CHECK=""
|
||||
for file in $(grep -rl --exclude-dir={.git,build} \
|
||||
--exclude=\*.{crt,key,pem,zed,hcl,md,json,csv,mod,sum,tmpl,args} \
|
||||
--exclude={CODEOWNERS,LICENSE,MAINTAINERS} \
|
||||
--regexp "Copyright (c) Abstract Machines" .)
|
||||
--exclude={CODEOWNERS,LICENSE,MAINTAINERS,enabled_plugins,rabbitmq.conf} \
|
||||
.); do
|
||||
|
||||
if ! head -n 5 "$file" | grep -q "Copyright (c) Abstract Machines"; then
|
||||
CHECK="$CHECK $file"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$CHECK" ]; then
|
||||
echo "License header check failed. Fix the following files:"
|
||||
echo "$CHECK"
|
||||
exit 1
|
||||
else
|
||||
echo "All files have the correct license header!"
|
||||
fi
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
# Copyright (c) Abstract Machines
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: Lint and Build
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
name: Lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v7
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v7
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
cache-dependency-path: "go.sum"
|
||||
|
||||
- name: Run linters
|
||||
uses: golangci/golangci-lint-action@v9.3.0
|
||||
with:
|
||||
version: v2.10.1
|
||||
args: --config ./tools/config/.golangci.yaml
|
||||
|
||||
build:
|
||||
name: Build All Binaries
|
||||
runs-on: ubuntu-latest
|
||||
needs: lint
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v7
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v7
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
cache-dependency-path: "go.sum"
|
||||
|
||||
- name: Build all binaries
|
||||
run: |
|
||||
make all -j $(nproc)
|
||||
|
||||
compile-check:
|
||||
name: Compile Check Redis Event Store
|
||||
runs-on: ubuntu-latest
|
||||
needs: lint
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v7
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v7
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
cache-dependency-path: "go.sum"
|
||||
|
||||
- name: Compile check
|
||||
run: |
|
||||
MG_ES_TYPE=es_redis make all -j $(nproc)
|
||||
@@ -8,24 +8,38 @@ on:
|
||||
branches:
|
||||
- main
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
swagger-ui:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v7
|
||||
|
||||
- name: Swagger UI action
|
||||
id: swagger-ui-action
|
||||
uses: blokovi/swagger-ui-action@main
|
||||
with:
|
||||
dir: "./api/openapi"
|
||||
pattern: "*.yml"
|
||||
debug: "true"
|
||||
- name: Build Swagger UI
|
||||
run: |
|
||||
# Create output directory
|
||||
mkdir -p swagger-ui
|
||||
|
||||
# Copy OpenAPI YAML files and schemas directory
|
||||
cp apidocs/openapi/*.yaml swagger-ui/
|
||||
cp -r apidocs/openapi/schemas swagger-ui/
|
||||
|
||||
# Get list of YAML files
|
||||
cd apidocs/openapi
|
||||
YAML_FILES=$(ls *.yaml | jq -R -s -c 'split("\n")[:-1]')
|
||||
cd ../..
|
||||
|
||||
# Generate index.html from template
|
||||
sed "s|APIS_PLACEHOLDER|$YAML_FILES|g" .github/swagger-ui-template.html > swagger-ui/index.html
|
||||
|
||||
echo "Generated Swagger UI with APIs: $YAML_FILES"
|
||||
|
||||
- name: Deploy to GitHub Pages
|
||||
uses: peaceiris/actions-gh-pages@v3
|
||||
uses: peaceiris/actions-gh-pages@v4
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
publish_dir: swagger-ui
|
||||
cname: api.mainflux.io
|
||||
publish_dir: ./swagger-ui
|
||||
cname: docs.api.magistrala.absmach.eu
|
||||
|
||||
@@ -0,0 +1,306 @@
|
||||
# Copyright (c) Abstract Machines
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: CI Pipeline
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths-ignore:
|
||||
- '**/*.md'
|
||||
- 'docs/**'
|
||||
- 'LICENSE'
|
||||
- 'MAINTAINERS'
|
||||
- 'CODEOWNERS'
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
lint-proto:
|
||||
name: Lint Proto
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v7
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v7
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
cache-dependency-path: "go.sum"
|
||||
|
||||
- name: Install protolint
|
||||
run: |
|
||||
go install github.com/yoheimuta/protolint/cmd/protolint@latest
|
||||
|
||||
- name: Lint Protobuf Files
|
||||
run: |
|
||||
protolint .
|
||||
|
||||
lint-and-build:
|
||||
needs: [lint-proto]
|
||||
uses: ./.github/workflows/lint-and-build.yaml
|
||||
|
||||
detect-changes:
|
||||
name: Detect Changes
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
modules: ${{ steps.set-matrix.outputs.modules }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Check for changes in specific paths
|
||||
uses: dorny/paths-filter@v4
|
||||
id: changes
|
||||
with:
|
||||
filters: |
|
||||
workflow:
|
||||
- ".github/workflows/tests.yaml"
|
||||
|
||||
channels:
|
||||
- "channels/**"
|
||||
- "pkg/sdk/**"
|
||||
- "clients/api/grpc/**"
|
||||
- "groups/api/grpc/**"
|
||||
- "domains/api/grpc/**"
|
||||
- "internal/grpc/**"
|
||||
|
||||
cli:
|
||||
- "cli/**"
|
||||
- "cmd/cli/**"
|
||||
- "pkg/sdk/**"
|
||||
|
||||
clients:
|
||||
- "clients/**"
|
||||
- "pkg/ulid/**"
|
||||
- "pkg/uuid/**"
|
||||
- "pkg/events/**"
|
||||
- "groups/api/grpc/**"
|
||||
- "channels/api/grpc/**"
|
||||
- "domains/api/grpc/**"
|
||||
- "internal/grpc/**"
|
||||
|
||||
domains:
|
||||
- "domains/**"
|
||||
- "internal/grpc/**"
|
||||
|
||||
groups:
|
||||
- "groups/**"
|
||||
- "pkg/ulid/**"
|
||||
- "pkg/uuid/**"
|
||||
- "clients/api/grpc/**"
|
||||
- "channels/api/grpc/**"
|
||||
- "domains/api/grpc/**"
|
||||
- "internal/grpc/**"
|
||||
|
||||
internal:
|
||||
- "internal/**"
|
||||
|
||||
logger:
|
||||
- "logger/**"
|
||||
|
||||
pkg-atom:
|
||||
- "pkg/atom/**"
|
||||
|
||||
pkg-email:
|
||||
- "pkg/email/**"
|
||||
- "pkg/emailer/**"
|
||||
|
||||
pkg-readersclient:
|
||||
- "pkg/readersclient/**"
|
||||
|
||||
pkg-testsutil:
|
||||
- "pkg/testsutil/**"
|
||||
|
||||
pkg-errors:
|
||||
- "pkg/errors/**"
|
||||
|
||||
pkg-events:
|
||||
- "pkg/events/**"
|
||||
- "pkg/messaging/**"
|
||||
|
||||
pkg-grpcclient:
|
||||
- "pkg/grpcclient/**"
|
||||
|
||||
pkg-messaging:
|
||||
- "pkg/messaging/**"
|
||||
|
||||
pkg-sdk:
|
||||
- "pkg/sdk/**"
|
||||
- "pkg/errors/**"
|
||||
- "pkg/groups/**"
|
||||
- "internal/*"
|
||||
- "clients/**"
|
||||
- "users/**"
|
||||
- "channels/**"
|
||||
- "domains/**"
|
||||
- "groups/**"
|
||||
- "api/http/**"
|
||||
|
||||
pkg-transformers:
|
||||
- "pkg/transformers/**"
|
||||
|
||||
pkg-ulid:
|
||||
- "pkg/ulid/**"
|
||||
|
||||
pkg-uuid:
|
||||
- "pkg/uuid/**"
|
||||
|
||||
users:
|
||||
- "users/**"
|
||||
- "pkg/ulid/**"
|
||||
- "pkg/uuid/**"
|
||||
- "pkg/events/**"
|
||||
|
||||
api:
|
||||
- "api/**"
|
||||
|
||||
consumers:
|
||||
- "consumers/**"
|
||||
- "cmd/postgres-writer/**"
|
||||
- "cmd/timescale-writer/**"
|
||||
- "cmd/smpp-notifier/**"
|
||||
- "cmd/smtp-notifier/**"
|
||||
|
||||
readers:
|
||||
- "readers/**"
|
||||
- "cmd/postgres-reader/**"
|
||||
- "cmd/timescale-reader/**"
|
||||
|
||||
- name: Set matrix for changed modules
|
||||
id: set-matrix
|
||||
run: |
|
||||
modules=()
|
||||
|
||||
if [[ "${{ steps.changes.outputs.workflow }}" == "true" || "${{ steps.changes.outputs.pkg-errors }}" == "true" || "${{ steps.changes.outputs.pkg-testsutil }}" == "true" ]]; then
|
||||
# If workflow, shared errors, or test utilities changed, test everything
|
||||
modules=("auth" "channels" "cli" "clients" "domains" "groups" "internal" "logger" "pkg-atom" "pkg-email" "pkg-errors" "pkg-events" "pkg-grpcclient" "pkg-messaging" "pkg-readersclient" "pkg-sdk" "pkg-testsutil" "pkg-transformers" "pkg-ulid" "pkg-uuid" "users" "api" "consumers" "readers")
|
||||
else
|
||||
# Add only changed modules
|
||||
[[ "${{ steps.changes.outputs.auth }}" == "true" ]] && modules+=("auth")
|
||||
[[ "${{ steps.changes.outputs.channels }}" == "true" ]] && modules+=("channels")
|
||||
[[ "${{ steps.changes.outputs.cli }}" == "true" ]] && modules+=("cli")
|
||||
[[ "${{ steps.changes.outputs.clients }}" == "true" ]] && modules+=("clients")
|
||||
[[ "${{ steps.changes.outputs.domains }}" == "true" ]] && modules+=("domains")
|
||||
[[ "${{ steps.changes.outputs.groups }}" == "true" ]] && modules+=("groups")
|
||||
[[ "${{ steps.changes.outputs.internal }}" == "true" ]] && modules+=("internal")
|
||||
[[ "${{ steps.changes.outputs.logger }}" == "true" ]] && modules+=("logger")
|
||||
[[ "${{ steps.changes.outputs.pkg-atom }}" == "true" ]] && modules+=("pkg-atom")
|
||||
[[ "${{ steps.changes.outputs.pkg-email }}" == "true" ]] && modules+=("pkg-email")
|
||||
[[ "${{ steps.changes.outputs.pkg-errors }}" == "true" ]] && modules+=("pkg-errors")
|
||||
[[ "${{ steps.changes.outputs.pkg-events }}" == "true" ]] && modules+=("pkg-events")
|
||||
[[ "${{ steps.changes.outputs.pkg-grpcclient }}" == "true" ]] && modules+=("pkg-grpcclient")
|
||||
[[ "${{ steps.changes.outputs.pkg-messaging }}" == "true" ]] && modules+=("pkg-messaging")
|
||||
[[ "${{ steps.changes.outputs.pkg-readersclient }}" == "true" ]] && modules+=("pkg-readersclient")
|
||||
[[ "${{ steps.changes.outputs.pkg-sdk }}" == "true" ]] && modules+=("pkg-sdk")
|
||||
[[ "${{ steps.changes.outputs.pkg-transformers }}" == "true" ]] && modules+=("pkg-transformers")
|
||||
[[ "${{ steps.changes.outputs.pkg-ulid }}" == "true" ]] && modules+=("pkg-ulid")
|
||||
[[ "${{ steps.changes.outputs.pkg-uuid }}" == "true" ]] && modules+=("pkg-uuid")
|
||||
[[ "${{ steps.changes.outputs.users }}" == "true" ]] && modules+=("users")
|
||||
[[ "${{ steps.changes.outputs.api }}" == "true" ]] && modules+=("api")
|
||||
[[ "${{ steps.changes.outputs.consumers }}" == "true" ]] && modules+=("consumers")
|
||||
[[ "${{ steps.changes.outputs.readers }}" == "true" ]] && modules+=("readers")
|
||||
fi
|
||||
|
||||
# Convert to JSON array
|
||||
json_modules=$(printf '%s\n' "${modules[@]}" | jq -R . | jq -s -c .)
|
||||
echo "modules=$json_modules" >> $GITHUB_OUTPUT
|
||||
echo "Testing modules: $json_modules"
|
||||
|
||||
run-tests:
|
||||
name: Test ${{ matrix.module }}
|
||||
runs-on: ubuntu-latest
|
||||
needs: [lint-and-build, detect-changes]
|
||||
if: needs.detect-changes.outputs.modules != '[]'
|
||||
strategy:
|
||||
fail-fast: true
|
||||
max-parallel: 20
|
||||
matrix:
|
||||
module: ${{ fromJSON(needs.detect-changes.outputs.modules) }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v7
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
cache-dependency-path: "go.sum"
|
||||
|
||||
- name: Verify dependencies
|
||||
run: |
|
||||
go mod download
|
||||
go mod verify
|
||||
|
||||
- name: Run ${{ matrix.module }} tests
|
||||
run: |
|
||||
# Map module names to directories
|
||||
case "${{ matrix.module }}" in
|
||||
pkg-atom) dir="pkg/atom" ;;
|
||||
pkg-email) dir="pkg/email" ;;
|
||||
pkg-errors) dir="pkg/errors" ;;
|
||||
pkg-events) dir="pkg/events" ;;
|
||||
pkg-grpcclient) dir="pkg/grpcclient" ;;
|
||||
pkg-messaging) dir="pkg/messaging" ;;
|
||||
pkg-readersclient) dir="pkg/readersclient" ;;
|
||||
pkg-sdk) dir="pkg/sdk" ;;
|
||||
pkg-testsutil) dir="pkg/testsutil" ;;
|
||||
pkg-transformers) dir="pkg/transformers" ;;
|
||||
pkg-ulid) dir="pkg/ulid" ;;
|
||||
pkg-uuid) dir="pkg/uuid" ;;
|
||||
channels) dir="pkg/channels" ;;
|
||||
clients) dir="pkg/clients" ;;
|
||||
domains) dir="pkg/domains" ;;
|
||||
groups) dir="pkg/groups" ;;
|
||||
*) dir="${{ matrix.module }}" ;;
|
||||
esac
|
||||
|
||||
if [[ ! -d "$dir" ]]; then
|
||||
echo "Skipping ${{ matrix.module }}; ./$dir is not present in this branch"
|
||||
echo "mode: atomic" > coverage-${{ matrix.module }}.out
|
||||
exit 0
|
||||
fi
|
||||
|
||||
go test -mod=readonly --race -v -count=1 -failfast -coverprofile=coverage-${{ matrix.module }}.out ./$dir/...
|
||||
|
||||
- name: Upload coverage
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: coverage-${{ matrix.module }}
|
||||
path: coverage-${{ matrix.module }}.out
|
||||
retention-days: 1
|
||||
|
||||
upload-coverage:
|
||||
name: Upload Coverage
|
||||
runs-on: ubuntu-latest
|
||||
needs: run-tests
|
||||
if: always() && needs.run-tests.result != 'cancelled'
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
|
||||
- name: Download all coverage artifacts
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
pattern: coverage-*
|
||||
path: coverage
|
||||
merge-multiple: true
|
||||
|
||||
- name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@v7
|
||||
with:
|
||||
token: ${{ secrets.CODECOV }}
|
||||
directory: ./coverage
|
||||
files: ./coverage/*.out
|
||||
fail_ci_if_error: false
|
||||
verbose: true
|
||||
@@ -1,407 +0,0 @@
|
||||
# Copyright (c) Abstract Machines
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: CI Pipeline
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
lint-and-build: # Linting and building are combined to save time for setting up Go
|
||||
name: Lint and Build
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: 1.21.x
|
||||
cache-dependency-path: "go.sum"
|
||||
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@v4
|
||||
with:
|
||||
version: v1.56.1
|
||||
|
||||
- name: Build all Binaries
|
||||
run: |
|
||||
make all -j $(nproc)
|
||||
|
||||
- name: Compile check for rabbitmq
|
||||
run: |
|
||||
MG_MESSAGE_BROKER_TYPE=rabbitmq make mqtt
|
||||
|
||||
- name: Compile check for redis
|
||||
run: |
|
||||
MG_ES_TYPE=redis make mqtt
|
||||
|
||||
run-tests:
|
||||
name: Run tests
|
||||
runs-on: ubuntu-latest
|
||||
needs: lint-and-build
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: 1.21.x
|
||||
cache-dependency-path: "go.sum"
|
||||
|
||||
- name: Check for changes in specific paths
|
||||
uses: dorny/paths-filter@v2
|
||||
id: changes
|
||||
with:
|
||||
base: main
|
||||
filters: |
|
||||
workflow:
|
||||
- ".github/workflows/tests.yml"
|
||||
|
||||
auth:
|
||||
- "auth/**"
|
||||
- "cmd/auth/**"
|
||||
- "auth.proto"
|
||||
- "auth.pb.go"
|
||||
- "auth_grpc.pb.go"
|
||||
- "pkg/ulid/**"
|
||||
- "pkg/uuid/**"
|
||||
|
||||
bootstrap:
|
||||
- "bootstrap/**"
|
||||
- "cmd/bootstrap/**"
|
||||
- "auth.pb.go"
|
||||
- "auth_grpc.pb.go"
|
||||
- "auth/**"
|
||||
- "pkg/sdk/**"
|
||||
- "pkg/events/**"
|
||||
|
||||
certs:
|
||||
- "certs/**"
|
||||
- "cmd/certs/**"
|
||||
- "auth.pb.go"
|
||||
- "auth_grpc.pb.go"
|
||||
- "auth/**"
|
||||
- "pkg/sdk/**"
|
||||
|
||||
coap:
|
||||
- "coap/**"
|
||||
- "cmd/coap/**"
|
||||
- "auth.pb.go"
|
||||
- "auth_grpc.pb.go"
|
||||
- "things/**"
|
||||
- "pkg/messaging/**"
|
||||
|
||||
consumers:
|
||||
- "consumers/**"
|
||||
- "cmd/cassandra-writer/**"
|
||||
- "cmd/influxdb-writer/**"
|
||||
- "cmd/mongodb-writer/**"
|
||||
- "cmd/postgres-writer/**"
|
||||
- "cmd/timescale-writer/**"
|
||||
- "cmd/smpp-notifier/**"
|
||||
- "cmd/smtp-notifier/**"
|
||||
- "auth.pb.go"
|
||||
- "auth_grpc.pb.go"
|
||||
- "auth/**"
|
||||
- "pkg/ulid/**"
|
||||
- "pkg/uuid/**"
|
||||
- "pkg/messaging/**"
|
||||
|
||||
http:
|
||||
- "http/**"
|
||||
- "cmd/http/**"
|
||||
- "auth.pb.go"
|
||||
- "auth_grpc.pb.go"
|
||||
- "things/**"
|
||||
- "pkg/messaging/**"
|
||||
- "logger/**"
|
||||
|
||||
internal:
|
||||
- "internal/**"
|
||||
|
||||
invitations:
|
||||
- "invitations/**"
|
||||
- "cmd/invitations/**"
|
||||
- "auth.pb.go"
|
||||
- "auth_grpc.pb.go"
|
||||
- "auth/**"
|
||||
- "pkg/sdk/**"
|
||||
|
||||
lora:
|
||||
- "lora/**"
|
||||
- "cmd/lora/**"
|
||||
- "pkg/messaging/**"
|
||||
|
||||
logger:
|
||||
- "logger/**"
|
||||
|
||||
mqtt:
|
||||
- "mqtt/**"
|
||||
- "cmd/mqtt/**"
|
||||
- "auth.pb.go"
|
||||
- "auth_grpc.pb.go"
|
||||
- "things/**"
|
||||
- "pkg/messaging/**"
|
||||
- "logger/**"
|
||||
- "pkg/events/**"
|
||||
|
||||
opcua:
|
||||
- "opcua/**"
|
||||
- "cmd/opcua/**"
|
||||
- "logger/**"
|
||||
|
||||
pkg-auth:
|
||||
- "pkg/auth/**"
|
||||
|
||||
pkg-clients:
|
||||
- "pkg/clients/**"
|
||||
|
||||
pkg-errors:
|
||||
- "pkg/errors/**"
|
||||
|
||||
pkg-events:
|
||||
- "pkg/events/**"
|
||||
- "pkg/messaging/**"
|
||||
|
||||
pkg-messaging:
|
||||
- "pkg/messaging/**"
|
||||
|
||||
pkg-sdk:
|
||||
- "pkg/sdk/**"
|
||||
- "pkg/clients/**"
|
||||
- "pkg/errors/**"
|
||||
- "auth/**"
|
||||
- "bootstrap/**"
|
||||
- "certs/**"
|
||||
- "consumers/**"
|
||||
- "http/**"
|
||||
- "invitations/**"
|
||||
- "provision/**"
|
||||
- "readers/**"
|
||||
- "things/**"
|
||||
- "twins/**"
|
||||
- "users/**"
|
||||
|
||||
pkg-transformers:
|
||||
- "pkg/transformers/**"
|
||||
|
||||
pkg-ulid:
|
||||
- "pkg/ulid/**"
|
||||
|
||||
pkg-uuid:
|
||||
- "pkg/uuid/**"
|
||||
|
||||
provision:
|
||||
- "provision/**"
|
||||
- "cmd/provision/**"
|
||||
- "logger/**"
|
||||
- "pkg/sdk/**"
|
||||
|
||||
readers:
|
||||
- "readers/**"
|
||||
- "cmd/cassandra-reader/**"
|
||||
- "cmd/influxdb-reader/**"
|
||||
- "cmd/mongodb-reader/**"
|
||||
- "cmd/postgres-reader/**"
|
||||
- "cmd/timescale-reader/**"
|
||||
- "auth.pb.go"
|
||||
- "auth_grpc.pb.go"
|
||||
- "things/**"
|
||||
- "auth/**"
|
||||
|
||||
things:
|
||||
- "things/**"
|
||||
- "cmd/things/**"
|
||||
- "auth.pb.go"
|
||||
- "auth_grpc.pb.go"
|
||||
- "auth/**"
|
||||
- "pkg/clients/**"
|
||||
- "pkg/ulid/**"
|
||||
- "pkg/uuid/**"
|
||||
- "pkg/events/**"
|
||||
|
||||
twins:
|
||||
- "twins/**"
|
||||
- "cmd/twins/**"
|
||||
- "auth.pb.go"
|
||||
- "auth_grpc.pb.go"
|
||||
- "auth/**"
|
||||
- "pkg/messaging/**"
|
||||
- "pkg/ulid/**"
|
||||
- "pkg/uuid/**"
|
||||
- "logger/**"
|
||||
|
||||
users:
|
||||
- "users/**"
|
||||
- "cmd/users/**"
|
||||
- "auth.pb.go"
|
||||
- "auth_grpc.pb.go"
|
||||
- "auth/**"
|
||||
- "pkg/clients/**"
|
||||
- "pkg/ulid/**"
|
||||
- "pkg/uuid/**"
|
||||
- "pkg/events/**"
|
||||
|
||||
ws:
|
||||
- "ws/**"
|
||||
- "cmd/ws/**"
|
||||
- "auth.pb.go"
|
||||
- "auth_grpc.pb.go"
|
||||
- "things/**"
|
||||
- "pkg/messaging/**"
|
||||
|
||||
- name: Create coverage directory
|
||||
run: |
|
||||
mkdir coverage
|
||||
|
||||
- name: Run auth tests
|
||||
if: steps.changes.outputs.auth == 'true' || steps.changes.outputs.workflow == 'true'
|
||||
run: |
|
||||
go test --race -v -count=1 -coverprofile=coverage/auth.out ./auth/...
|
||||
|
||||
- name: Run bootstrap tests
|
||||
if: steps.changes.outputs.bootstrap == 'true' || steps.changes.outputs.workflow == 'true'
|
||||
run: |
|
||||
go test --race -v -count=1 -coverprofile=coverage/bootstrap.out ./bootstrap/...
|
||||
|
||||
- name: Run certs tests
|
||||
if: steps.changes.outputs.certs == 'true' || steps.changes.outputs.workflow == 'true'
|
||||
run: |
|
||||
go test --race -v -count=1 -coverprofile=coverage/certs.out ./certs/...
|
||||
|
||||
- name: Run CoAP tests
|
||||
if: steps.changes.outputs.coap == 'true' || steps.changes.outputs.workflow == 'true'
|
||||
run: |
|
||||
go test --race -v -count=1 -coverprofile=coverage/coap.out ./coap/...
|
||||
|
||||
- name: Run consumers tests
|
||||
if: steps.changes.outputs.consumers == 'true' || steps.changes.outputs.workflow == 'true'
|
||||
run: |
|
||||
go test --race -v -count=1 -coverprofile=coverage/consumers.out ./consumers/...
|
||||
|
||||
- name: Run HTTP tests
|
||||
if: steps.changes.outputs.http == 'true' || steps.changes.outputs.workflow == 'true'
|
||||
run: |
|
||||
go test --race -v -count=1 -coverprofile=coverage/http.out ./http/...
|
||||
|
||||
- name: Run internal tests
|
||||
if: steps.changes.outputs.internal == 'true' || steps.changes.outputs.workflow == 'true'
|
||||
run: |
|
||||
go test --race -v -count=1 -coverprofile=coverage/internal.out ./internal/...
|
||||
|
||||
- name: Run invitations tests
|
||||
if: steps.changes.outputs.invitations == 'true' || steps.changes.outputs.workflow == 'true'
|
||||
run: |
|
||||
go test --race -v -count=1 -coverprofile=coverage/invitations.out ./invitations/...
|
||||
|
||||
- name: Run logger tests
|
||||
if: steps.changes.outputs.logger == 'true' || steps.changes.outputs.workflow == 'true'
|
||||
run: |
|
||||
go test --race -v -count=1 -coverprofile=coverage/logger.out ./logger/...
|
||||
|
||||
- name: Run LoRa tests
|
||||
if: steps.changes.outputs.lora == 'true' || steps.changes.outputs.workflow == 'true'
|
||||
run: |
|
||||
go test --race -v -count=1 -coverprofile=coverage/lora.out ./lora/...
|
||||
|
||||
- name: Run MQTT tests
|
||||
if: steps.changes.outputs.mqtt == 'true' || steps.changes.outputs.workflow == 'true'
|
||||
run: |
|
||||
go test --race -v -count=1 -coverprofile=coverage/mqtt.out ./mqtt/...
|
||||
|
||||
- name: Run OPC-UA tests
|
||||
if: steps.changes.outputs.opcua == 'true' || steps.changes.outputs.workflow == 'true'
|
||||
run: |
|
||||
go test --race -v -count=1 -coverprofile=coverage/opcua.out ./opcua/...
|
||||
|
||||
- name: Run pkg auth tests
|
||||
if: steps.changes.outputs.pkg-auth == 'true' || steps.changes.outputs.workflow == 'true'
|
||||
run: |
|
||||
go test --race -v -count=1 -coverprofile=coverage/pkg-auth.out ./pkg/auth/...
|
||||
|
||||
- name: Run pkg clients tests
|
||||
if: steps.changes.outputs.pkg-clients == 'true' || steps.changes.outputs.workflow == 'true'
|
||||
run: |
|
||||
go test --race -v -count=1 -coverprofile=coverage/pkg-clients.out ./pkg/clients/...
|
||||
|
||||
- name: Run pkg errors tests
|
||||
if: steps.changes.outputs.pkg-errors == 'true' || steps.changes.outputs.workflow == 'true'
|
||||
run: |
|
||||
go test --race -v -count=1 -coverprofile=coverage/pkg-errors.out ./pkg/errors/...
|
||||
|
||||
- name: Run pkg events tests
|
||||
if: steps.changes.outputs.pkg-events == 'true' || steps.changes.outputs.workflow == 'true'
|
||||
run: |
|
||||
go test --race -v -count=1 -coverprofile=coverage/pkg-events.out ./pkg/events/...
|
||||
|
||||
- name: Run pkg messaging tests
|
||||
if: steps.changes.outputs.pkg-messaging == 'true' || steps.changes.outputs.workflow == 'true'
|
||||
run: |
|
||||
go test --race -v -count=1 -coverprofile=coverage/pkg-messaging.out ./pkg/messaging/...
|
||||
|
||||
- name: Run pkg sdk tests
|
||||
if: steps.changes.outputs.pkg-sdk == 'true' || steps.changes.outputs.workflow == 'true'
|
||||
run: |
|
||||
go test --race -v -count=1 -coverprofile=coverage/pkg-sdk.out ./pkg/sdk/...
|
||||
|
||||
- name: Run pkg transformers tests
|
||||
if: steps.changes.outputs.pkg-transformers == 'true' || steps.changes.outputs.workflow == 'true'
|
||||
run: |
|
||||
go test --race -v -count=1 -coverprofile=coverage/pkg-transformers.out ./pkg/transformers/...
|
||||
|
||||
- name: Run pkg ulid tests
|
||||
if: steps.changes.outputs.pkg-ulid == 'true' || steps.changes.outputs.workflow == 'true'
|
||||
run: |
|
||||
go test --race -v -count=1 -coverprofile=coverage/pkg-ulid.out ./pkg/ulid/...
|
||||
|
||||
- name: Run pkg uuid tests
|
||||
if: steps.changes.outputs.pkg-uuid == 'true' || steps.changes.outputs.workflow == 'true'
|
||||
run: |
|
||||
go test --race -v -count=1 -coverprofile=coverage/pkg-uuid.out ./pkg/uuid/...
|
||||
|
||||
- name: Run provision tests
|
||||
if: steps.changes.outputs.provision == 'true' || steps.changes.outputs.workflow == 'true'
|
||||
run: |
|
||||
go test --race -v -count=1 -coverprofile=coverage/provision.out ./provision/...
|
||||
|
||||
- name: Run readers tests
|
||||
if: steps.changes.outputs.readers == 'true' || steps.changes.outputs.workflow == 'true'
|
||||
run: |
|
||||
go test --race -v -count=1 -coverprofile=coverage/readers.out ./readers/...
|
||||
|
||||
- name: Run things tests
|
||||
if: steps.changes.outputs.things == 'true' || steps.changes.outputs.workflow == 'true'
|
||||
run: |
|
||||
go test --race -v -count=1 -coverprofile=coverage/things.out ./things/...
|
||||
|
||||
- name: Run twins tests
|
||||
if: steps.changes.outputs.twins == 'true' || steps.changes.outputs.workflow == 'true'
|
||||
run: |
|
||||
go test --race -v -count=1 -coverprofile=coverage/twins.out ./twins/...
|
||||
|
||||
- name: Run users tests
|
||||
if: steps.changes.outputs.users == 'true' || steps.changes.outputs.workflow == 'true'
|
||||
run: |
|
||||
go test --race -v -count=1 -coverprofile=coverage/users.out ./users/...
|
||||
|
||||
- name: Run WebSocket tests
|
||||
if: steps.changes.outputs.ws == 'true' || steps.changes.outputs.workflow == 'true'
|
||||
run: |
|
||||
go test --race -v -count=1 -coverprofile=coverage/ws.out ./ws/...
|
||||
|
||||
- name: Upload coverage
|
||||
uses: codecov/codecov-action@v3
|
||||
with:
|
||||
token: ${{ secrets.CODECOV }}
|
||||
directory: ./coverage/
|
||||
name: codecov-umbrella
|
||||
verbose: true
|
||||
+15
@@ -12,3 +12,18 @@ tools/provision/mgconn.toml
|
||||
|
||||
# coverage files
|
||||
coverage
|
||||
|
||||
# Schemathesis
|
||||
.hypothesis
|
||||
|
||||
# Ignore Openbao data directory as it contains runtime-generated data
|
||||
docker/addons/certs/openbao/
|
||||
|
||||
# Ignore generated local Atom service tokens.
|
||||
docker/.env.tokens
|
||||
|
||||
# Ignore SeaweedFS data directory as it contains runtime-generated data
|
||||
docker/data/*
|
||||
|
||||
demo-ui
|
||||
node_modules
|
||||
|
||||
-100
@@ -1,100 +0,0 @@
|
||||
# Copyright (c) Abstract Machines
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
run:
|
||||
timeout: 10m
|
||||
build-tags:
|
||||
- "nats"
|
||||
|
||||
issues:
|
||||
max-issues-per-linter: 100
|
||||
max-same-issues: 100
|
||||
exclude:
|
||||
- "string `Usage:\n` has (\\d+) occurrences, make it a constant"
|
||||
- "string `For example:\n` has (\\d+) occurrences, make it a constant"
|
||||
|
||||
linters-settings:
|
||||
importas:
|
||||
no-unaliased: true
|
||||
no-extra-aliases: false
|
||||
alias:
|
||||
- pkg: github.com/absmach/callhome/pkg/client
|
||||
alias: chclient
|
||||
- pkg: github.com/absmach/magistrala/logger
|
||||
alias: mglog
|
||||
- pkg: github.com/absmach/magistrala/pkg/errors/service
|
||||
alias: svcerr
|
||||
- pkg: github.com/absmach/magistrala/pkg/errors/repository
|
||||
alias: repoerr
|
||||
- pkg: github.com/absmach/magistrala/pkg/sdk/mocks
|
||||
alias: sdkmocks
|
||||
|
||||
gocritic:
|
||||
enabled-checks:
|
||||
- captLocal
|
||||
- singleCaseSwitch
|
||||
- switchTrue
|
||||
- importShadow
|
||||
- httpNoBody
|
||||
- paramTypeCombine
|
||||
- emptyStringTest
|
||||
- builtinShadow
|
||||
- exposedSyncMutex
|
||||
disabled-checks:
|
||||
- appendAssign
|
||||
enabled-tags:
|
||||
- diagnostic
|
||||
disabled-tags:
|
||||
- performance
|
||||
- style
|
||||
- experimental
|
||||
- opinionated
|
||||
misspell:
|
||||
ignore-words:
|
||||
- "mosquitto"
|
||||
stylecheck:
|
||||
checks: ["-ST1000", "-ST1003", "-ST1020", "-ST1021", "-ST1022"]
|
||||
goheader:
|
||||
template: |-
|
||||
Copyright (c) Abstract Machines
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
linters:
|
||||
disable-all: true
|
||||
enable:
|
||||
- gocritic
|
||||
- gosimple
|
||||
- errcheck
|
||||
- govet
|
||||
- unused
|
||||
- goconst
|
||||
- godot
|
||||
- godox
|
||||
- ineffassign
|
||||
- misspell
|
||||
- stylecheck
|
||||
- whitespace
|
||||
- gci
|
||||
- gofmt
|
||||
- goimports
|
||||
- loggercheck
|
||||
- goheader
|
||||
- asasalint
|
||||
- asciicheck
|
||||
- bidichk
|
||||
- contextcheck
|
||||
- decorder
|
||||
- dogsled
|
||||
- errchkjson
|
||||
- errname
|
||||
- execinquery
|
||||
- exportloopref
|
||||
- ginkgolinter
|
||||
- gocheckcompilerdirectives
|
||||
- gofumpt
|
||||
- goprintffuncname
|
||||
- importas
|
||||
- makezero
|
||||
- mirror
|
||||
- nakedret
|
||||
- dupword
|
||||
+1
-1
@@ -33,4 +33,4 @@ Pull request commit must be [signed](https://docs.github.com/en/github/authentic
|
||||
## Adopters list (alphabetical)
|
||||
|
||||
|
||||
**Note:** The list is maintained by the users themselves. If you find yourself on this list, and you think it's inappropriate. Please contact [project maintainers](https://github.com/absmach/magistrala/blob/master/MAINTAINERS) and you will be permanently removed from the list.
|
||||
**Note:** The list is maintained by the users themselves. If you find yourself on this list, and you think it's inappropriate. Please contact [project maintainers](https://github.com/absmach/magistrala/blob/main/MAINTAINERS) and you will be permanently removed from the list.
|
||||
|
||||
+3
-3
@@ -5,7 +5,7 @@ hosted on the [Abstract Machines Organization](https://github.com/absmach) on Gi
|
||||
|
||||
This project adheres to the [Contributor Covenant 1.2](http://contributor-covenant.org/version/1/2/0).
|
||||
By participating, you are expected to uphold this code. Please report unacceptable behavior to
|
||||
[abuse@magistrala.com](mailto:abuse@magistrala.com).
|
||||
[abuse@absmach.eu](mailto:abuse@absmach.eu).
|
||||
|
||||
## Reporting issues
|
||||
|
||||
@@ -49,11 +49,11 @@ git remote add upstream https://github.com/absmach/magistrala.git
|
||||
If your cloned repository is behind the upstream commits, then get the latest changes from upstream:
|
||||
|
||||
```
|
||||
git checkout master
|
||||
git checkout main
|
||||
git pull --rebase upstream main
|
||||
```
|
||||
|
||||
Create a new topic branch from `master` using the naming convention `MG-[issue-number]`
|
||||
Create a new topic branch from `main` using the naming convention `MG-[issue-number]`
|
||||
to help us keep track of your contribution scope:
|
||||
|
||||
```
|
||||
|
||||
@@ -176,7 +176,7 @@
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Copyright 2015-2020 Magistrala
|
||||
Copyright 2015-2026 Magistrala
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
+11
-26
@@ -1,30 +1,15 @@
|
||||
# Magistrala follows the timeless, highly efficient and totally unfair system
|
||||
# known as [Benevolent dictator for
|
||||
# life](https://en.wikipedia.org/wiki/Benevolent_Dictator_for_Life), with
|
||||
# Drasko DRASKOVIC in the role of BDFL.
|
||||
# Magistrala Maintainers
|
||||
|
||||
[bdfl]
|
||||
|
||||
[[drasko]]
|
||||
Name = "Drasko Draskovic"
|
||||
Email = "draasko.draskovic@abstractmachines.fr"
|
||||
GitHub = "drasko"
|
||||
Magistrala follows a BDFL model for dead-lock situations; day-to-day decisions happen through discussion and pull requests.
|
||||
|
||||
# However, this role serves only in dead-lock events, or in a special and very rare cases
|
||||
# when BDFL completely disagrees with the decisions made.
|
||||
# In the normal flow of events, decisions on the project design are made through discussions,
|
||||
# most often on the Pull Requests.
|
||||
#
|
||||
# Maintainers have the special role in the project in managing and accepting PRs,
|
||||
# overall leading the project and making design decisions on the maintained subsystems.
|
||||
#
|
||||
# A reference list of all maintainers of the Magistrala project.
|
||||
## BDFL
|
||||
|
||||
# ADD YOURSELF HERE IN ALPHABETICAL ORDER
|
||||
- **Drasko Draskovic** — [drasko@absmach.eu](mailto:drasko@absmach.eu) — [GitHub: drasko](https://github.com/drasko)
|
||||
|
||||
[maintainers]
|
||||
|
||||
[[dusan]]
|
||||
Name = "Dusan Borovcanin"
|
||||
Email = "dusan.borovcanin@abstractmachines.fr"
|
||||
GitHub = "dborovcanin"
|
||||
## Maintainers
|
||||
|
||||
Add yourself below in alphabetical order.
|
||||
|
||||
| Name | Email | GitHub |
|
||||
| --- | --- | --- |
|
||||
| Dusan Borovcanin | [dusan.borovcanin@absmach.eu](mailto:dusan.borovcanin@absmach.eu) | [dborovcanin](https://github.com/dborovcanin) |
|
||||
|
||||
@@ -1,42 +1,61 @@
|
||||
# Copyright (c) Abstract Machines
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
MG_DOCKER_IMAGE_NAME_PREFIX ?= magistrala
|
||||
BUILD_DIR = build
|
||||
SERVICES = auth users things http coap ws lora influxdb-writer influxdb-reader mongodb-writer \
|
||||
mongodb-reader cassandra-writer cassandra-reader postgres-writer postgres-reader timescale-writer timescale-reader cli \
|
||||
bootstrap opcua twins mqtt provision certs smtp-notifier smpp-notifier invitations
|
||||
override MG_DOCKER_IMAGE_NAME_PREFIX := ghcr.io/absmach/magistrala
|
||||
MG_DOCKER_VOLUME_NAME_PREFIX ?= magistrala
|
||||
BUILD_DIR ?= build
|
||||
SERVICES = atom-bootstrap certs postgres-writer postgres-reader timescale-writer timescale-reader fluxmq
|
||||
TEST_API_SERVICES = certs clients users channels groups domains
|
||||
TEST_API = $(addprefix test_api_,$(TEST_API_SERVICES))
|
||||
DOCKERS = $(addprefix docker_,$(SERVICES))
|
||||
DOCKERS_DEV = $(addprefix docker_dev_,$(SERVICES))
|
||||
CGO_ENABLED ?= 0
|
||||
GOARCH ?= amd64
|
||||
VERSION ?= $(shell git describe --abbrev=0 --tags)
|
||||
GOOS ?= linux
|
||||
DETECTED_ARCH := $(shell uname -m)
|
||||
VERSION ?= $(shell git describe --abbrev=0 --tags 2>/dev/null || echo 'unknown')
|
||||
COMMIT ?= $(shell git rev-parse HEAD)
|
||||
TIME ?= $(shell date +%F_%T)
|
||||
USER_REPO ?= $(shell git remote get-url origin | sed -e 's/.*\/\([^/]*\)\/\([^/]*\).*/\1_\2/' )
|
||||
USER_REPO ?= $(shell git remote get-url origin | sed -E 's@.*/([^/]+)/([^/.]+)(\.git)?@\1_\2@')
|
||||
empty:=
|
||||
space:= $(empty) $(empty)
|
||||
# Docker compose project name should follow this guidelines: https://docs.docker.com/compose/reference/#use--p-to-specify-a-project-name
|
||||
DOCKER_PROJECT ?= $(shell echo $(subst $(space),,$(USER_REPO)) | tr -c -s '[:alnum:][=-=]' '_' | tr '[:upper:]' '[:lower:]')
|
||||
DOCKER_COMPOSE_COMMANDS_SUPPORTED := up down config
|
||||
DOCKER_PROJECT ?= $(shell echo $(subst $(space),,$(USER_REPO)) | sed -E 's/[^a-zA-Z0-9]/_/g' | tr '[:upper:]' '[:lower:]')
|
||||
DOCKER_COMPOSE_COMMANDS_SUPPORTED := up down config restart
|
||||
DEFAULT_DOCKER_COMPOSE_COMMAND := up
|
||||
ATOM_TOKENS_ENV ?= docker/.env.tokens
|
||||
REQUIRED_ATOM_TOKEN_ENVS := MG_ATOM_TOKEN_FLUXMQ_AUTH MG_ATOM_TOKEN_FLUXMQ_NODE1 MG_ATOM_TOKEN_FLUXMQ_NODE2 MG_ATOM_TOKEN_FLUXMQ_NODE3 MG_ATOM_TOKEN_TIMESCALE_READER MG_ATOM_TOKEN_RE MG_ATOM_TOKEN_ALARMS MG_ATOM_TOKEN_REPORTS MG_ATOM_TOKEN_POSTGRES_READER
|
||||
PROVISION_ATOM_TOKENS ?= false
|
||||
PROVISION_ATOM_TOKEN_GOALS := provision-atom-tokens
|
||||
DOCKER_BASE_ENV_FILES := --env-file docker/.env
|
||||
DOCKER_ENV_FILES = $(if $(filter down,$(DOCKER_COMPOSE_COMMAND)),$(DOCKER_BASE_ENV_FILES),$(DOCKER_BASE_ENV_FILES) --env-file $(ATOM_TOKENS_ENV))
|
||||
DOCKER_PROVISION_ENV_FILES = $(DOCKER_BASE_ENV_FILES) $(if $(wildcard $(ATOM_TOKENS_ENV)),--env-file $(ATOM_TOKENS_ENV))
|
||||
HOST_UID := $(shell id -u)
|
||||
HOST_GID := $(shell id -g)
|
||||
GRPC_MTLS_CERT_FILES_EXISTS = 0
|
||||
MOCKERY_VERSION=v2.38.0
|
||||
MOCKERY = $(GOBIN)/mockery
|
||||
MOCKERY_VERSION=3.6.4
|
||||
PKG_PROTO_GEN_OUT_DIR=api/grpc
|
||||
INTERNAL_PROTO_DIR=internal/proto
|
||||
INTERNAL_PROTO_FILES := $(shell find $(INTERNAL_PROTO_DIR) -name "*.proto" | sed 's|$(INTERNAL_PROTO_DIR)/||')
|
||||
|
||||
ifneq ($(MG_MESSAGE_BROKER_TYPE),)
|
||||
MG_MESSAGE_BROKER_TYPE := $(MG_MESSAGE_BROKER_TYPE)
|
||||
MG_MESSAGE_BROKER_TYPE := $(MG_MESSAGE_BROKER_TYPE)
|
||||
else
|
||||
MG_MESSAGE_BROKER_TYPE=nats
|
||||
MG_MESSAGE_BROKER_TYPE=msg_fluxmq
|
||||
endif
|
||||
|
||||
ifneq ($(MG_ES_TYPE),)
|
||||
MG_ES_TYPE := $(MG_ES_TYPE)
|
||||
MG_ES_TYPE := $(MG_ES_TYPE)
|
||||
else
|
||||
MG_ES_TYPE=nats
|
||||
MG_ES_TYPE=es_fluxmq
|
||||
endif
|
||||
|
||||
BUILD_TAGS := $(strip $(MG_MESSAGE_BROKER_TYPE) $(MG_ES_TYPE))
|
||||
|
||||
define compile_service
|
||||
CGO_ENABLED=$(CGO_ENABLED) GOOS=$(GOOS) GOARCH=$(GOARCH) GOARM=$(GOARM) \
|
||||
go build -tags $(MG_MESSAGE_BROKER_TYPE) --tags $(MG_ES_TYPE) -ldflags "-s -w \
|
||||
go build -tags "$(BUILD_TAGS)" -ldflags "-s -w \
|
||||
-X 'github.com/absmach/magistrala.BuildTime=$(TIME)' \
|
||||
-X 'github.com/absmach/magistrala.Version=$(VERSION)' \
|
||||
-X 'github.com/absmach/magistrala.Commit=$(COMMIT)'" \
|
||||
@@ -54,6 +73,7 @@ define make_docker
|
||||
--build-arg VERSION=$(VERSION) \
|
||||
--build-arg COMMIT=$(COMMIT) \
|
||||
--build-arg TIME=$(TIME) \
|
||||
--build-arg BUILD_TAGS="$(BUILD_TAGS)" \
|
||||
--tag=$(MG_DOCKER_IMAGE_NAME_PREFIX)/$(svc) \
|
||||
-f docker/Dockerfile .
|
||||
endef
|
||||
@@ -68,16 +88,96 @@ define make_docker_dev
|
||||
-f docker/Dockerfile.dev ./build
|
||||
endef
|
||||
|
||||
ADDON_SERVICES = bootstrap cassandra-reader cassandra-writer certs \
|
||||
influxdb-reader influxdb-writer lora-adapter mongodb-reader mongodb-writer \
|
||||
opcua-adapter postgres-reader postgres-writer provision smpp-notifier smtp-notifier \
|
||||
timescale-reader timescale-writer twins
|
||||
define require_atom_tokens_env
|
||||
@if [ -z "$(filter down,$(DOCKER_COMPOSE_COMMAND))" ]; then \
|
||||
if [ ! -f "$(ATOM_TOKENS_ENV)" ]; then \
|
||||
echo "Missing $(ATOM_TOKENS_ENV). Run 'make provision_atom_tokens' before starting the Docker Compose stack."; \
|
||||
exit 2; \
|
||||
fi; \
|
||||
missing=""; \
|
||||
for env_name in $(REQUIRED_ATOM_TOKEN_ENVS); do \
|
||||
if ! grep -q "^$${env_name}=" "$(ATOM_TOKENS_ENV)"; then \
|
||||
missing="$${missing} $${env_name}"; \
|
||||
fi; \
|
||||
done; \
|
||||
if [ -n "$${missing}" ]; then \
|
||||
echo "Missing Atom service token(s) in $(ATOM_TOKENS_ENV):$${missing}. Run 'make provision_atom_tokens' before starting the Docker Compose stack."; \
|
||||
exit 2; \
|
||||
fi; \
|
||||
fi
|
||||
endef
|
||||
|
||||
EXTERNAL_SERVICES = vault prometheus
|
||||
define ensure_atom_tokens_env
|
||||
@if [ "$(PROVISION_ATOM_TOKENS)" = "true" ] && [ -z "$(filter down,$(DOCKER_COMPOSE_COMMAND))" ]; then \
|
||||
$(MAKE) provision_atom_tokens; \
|
||||
elif [ -z "$(filter down,$(DOCKER_COMPOSE_COMMAND))" ]; then \
|
||||
if [ ! -f "$(ATOM_TOKENS_ENV)" ]; then \
|
||||
echo "Missing $(ATOM_TOKENS_ENV). Run 'make provision_atom_tokens' before starting the Docker Compose stack."; \
|
||||
exit 2; \
|
||||
fi; \
|
||||
missing=""; \
|
||||
for env_name in $(REQUIRED_ATOM_TOKEN_ENVS); do \
|
||||
if ! grep -q "^$${env_name}=" "$(ATOM_TOKENS_ENV)"; then \
|
||||
missing="$${missing} $${env_name}"; \
|
||||
fi; \
|
||||
done; \
|
||||
if [ -n "$${missing}" ]; then \
|
||||
echo "Missing Atom service token(s) in $(ATOM_TOKENS_ENV):$${missing}. Run 'make provision_atom_tokens' before starting the Docker Compose stack."; \
|
||||
exit 2; \
|
||||
fi; \
|
||||
fi
|
||||
endef
|
||||
|
||||
define run_with_arch_detection
|
||||
$(call require_atom_tokens_env)
|
||||
@echo "Detecting architecture..."
|
||||
@if [ "$(DETECTED_ARCH)" = "arm64" ] || [ "$(DETECTED_ARCH)" = "aarch64" ]; then \
|
||||
echo "ARM64 architecture detected."; \
|
||||
git checkout $(1); \
|
||||
GOARCH=arm64 $(MAKE) dockers; \
|
||||
for svc in $(SERVICES); do \
|
||||
docker tag $(MG_DOCKER_IMAGE_NAME_PREFIX)/$$svc $(MG_DOCKER_IMAGE_NAME_PREFIX)/$$svc:latest; \
|
||||
done; \
|
||||
sed -i.bak 's/^MG_RELEASE_TAG=.*/MG_RELEASE_TAG=latest/' docker/.env && rm -f docker/.env.bak; \
|
||||
docker compose -f docker/docker-compose.yaml $(DOCKER_ENV_FILES) -p $(DOCKER_PROJECT) $(DOCKER_COMPOSE_COMMAND) $(args); \
|
||||
else \
|
||||
echo "x86_64 architecture detected."; \
|
||||
git checkout $(1); \
|
||||
sed -i.bak 's/^MG_RELEASE_TAG=.*/MG_RELEASE_TAG=$(2)/' docker/.env && rm -f docker/.env.bak; \
|
||||
docker compose -f docker/docker-compose.yaml $(DOCKER_ENV_FILES) -p $(DOCKER_PROJECT) $(DOCKER_COMPOSE_COMMAND) $(args); \
|
||||
fi
|
||||
endef
|
||||
|
||||
ADDON_SERVICES = bootstrap provision postgres-writer postgres-reader
|
||||
|
||||
EXTERNAL_SERVICES = prometheus
|
||||
|
||||
# Detect OS and architecture for cross-platform compatibility
|
||||
UNAME_S := $(shell uname -s)
|
||||
UNAME_M := $(shell uname -m)
|
||||
|
||||
# macOS BSD sed vs GNU sed compatibility
|
||||
ifeq ($(UNAME_S),Darwin)
|
||||
SED_INPLACE := sed -i ''
|
||||
else
|
||||
SED_INPLACE := sed -i
|
||||
endif
|
||||
|
||||
# Apple Silicon (arm64) Docker platform compatibility
|
||||
# Pre-built images are amd64 only, so we need to use emulation on Apple Silicon
|
||||
ifeq ($(UNAME_S),Darwin)
|
||||
ifeq ($(UNAME_M),arm64)
|
||||
DOCKER_PLATFORM := DOCKER_DEFAULT_PLATFORM=linux/amd64
|
||||
endif
|
||||
endif
|
||||
DOCKER_PLATFORM ?=
|
||||
|
||||
ifneq ($(filter run%,$(firstword $(MAKECMDGOALS))),)
|
||||
temp_args := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))
|
||||
DOCKER_COMPOSE_COMMAND := $(if $(filter $(DOCKER_COMPOSE_COMMANDS_SUPPORTED),$(temp_args)), $(filter $(DOCKER_COMPOSE_COMMANDS_SUPPORTED),$(temp_args)), $(DEFAULT_DOCKER_COMPOSE_COMMAND))
|
||||
ifneq ($(filter $(PROVISION_ATOM_TOKEN_GOALS),$(temp_args)),)
|
||||
override PROVISION_ATOM_TOKENS := true
|
||||
endif
|
||||
$(eval $(DOCKER_COMPOSE_COMMAND):;@)
|
||||
endif
|
||||
|
||||
@@ -97,18 +197,25 @@ FILTERED_SERVICES = $(filter-out $(RUN_ADDON_ARGS), $(SERVICES))
|
||||
|
||||
all: $(SERVICES)
|
||||
|
||||
.PHONY: all $(SERVICES) dockers dockers_dev latest release run run_addons grpc_mtls_certs check_mtls check_certs
|
||||
.PHONY: all help $(SERVICES) dockers dockers_dev latest release provision_atom_tokens provision-atom-tokens migrate_atom run_latest run_latest_ci run_tls run_stable run_addons grpc_mtls_certs check_mtls check_certs check_fluxmq_service_certs check_re_trace_key test_api mocks
|
||||
|
||||
help:
|
||||
@printf 'Usage:\n make <target> [VARIABLE=value ...]\n\nAvailable targets:\n'
|
||||
@$(MAKE) -qpRr : 2>/dev/null | \
|
||||
awk -F: '/^[[:alnum:]_][^$$#\/\t=]*:([^=]|$$)/ { split($$1, targets, /[[:space:]]+/); for (i in targets) if (targets[i] != "") print targets[i] }' | \
|
||||
LC_ALL=C sort -u | \
|
||||
awk '$$0 != "Makefile" { printf " make %s\n", $$0 }'
|
||||
|
||||
clean:
|
||||
rm -rf ${BUILD_DIR}
|
||||
|
||||
cleandocker:
|
||||
# Stops containers and removes containers, networks, volumes, and images created by up
|
||||
docker compose -f docker/docker-compose.yml -p $(DOCKER_PROJECT) down --rmi all -v --remove-orphans
|
||||
docker compose -f docker/docker-compose.yaml -p $(DOCKER_PROJECT) down --rmi all -v --remove-orphans
|
||||
|
||||
ifdef pv
|
||||
# Remove unused volumes
|
||||
docker volume ls -f name=$(MG_DOCKER_IMAGE_NAME_PREFIX) -f dangling=true -q | xargs -r docker volume rm
|
||||
docker volume ls -f name=$(MG_DOCKER_VOLUME_NAME_PREFIX) -f dangling=true -q | xargs -r docker volume rm
|
||||
endif
|
||||
|
||||
install:
|
||||
@@ -116,22 +223,56 @@ install:
|
||||
cp $$file $(GOBIN)/magistrala-`basename $$file`; \
|
||||
done
|
||||
|
||||
mocks:
|
||||
@which mockery > /dev/null || go install github.com/vektra/mockery/v2@$(MOCKERY_VERSION)
|
||||
@unset MOCKERY_VERSION && go generate ./...
|
||||
mocks: $(MOCKERY)
|
||||
@$(MOCKERY) --config ./tools/config/.mockery.yaml
|
||||
|
||||
$(MOCKERY):
|
||||
@mkdir -p $(GOBIN)
|
||||
@echo ">> installing mockery $(MOCKERY_VERSION)..."
|
||||
@go install github.com/vektra/mockery/v3@v$(MOCKERY_VERSION)
|
||||
|
||||
DIRS = consumers readers postgres internal opcua
|
||||
DIRS = consumers readers postgres internal
|
||||
test: mocks
|
||||
mkdir -p coverage
|
||||
@for dir in $(DIRS); do \
|
||||
go test -v --race -count 1 -tags test -coverprofile=coverage/$$dir.out $$(go list ./... | grep $$dir | grep -v 'cmd'); \
|
||||
done
|
||||
go test -v --race -count 1 -tags test -coverprofile=coverage/coverage.out $$(go list ./... | grep -v 'consumers\|readers\|postgres\|internal\|opcua\|cmd')
|
||||
go test -v --race -failfast -count 1 -tags test -coverprofile=coverage/$$dir.out $$(go list ./... | grep $$dir | grep -v 'cmd'); \
|
||||
done
|
||||
go test -v --race -failfast -count 1 -tags test -coverprofile=coverage/coverage.out $$(go list ./... | grep -v 'consumers\|readers\|postgres\|internal\|cmd\|middleware')
|
||||
|
||||
define test_api_service
|
||||
$(eval svc=$(subst test_api_,,$(1)))
|
||||
@which uv > /dev/null || (echo "uv not found, please install it from https://github.com/astral-sh/uv" && exit 1)
|
||||
|
||||
@if [ -z "$(USER_TOKEN)" ]; then \
|
||||
echo "USER_TOKEN is not set"; \
|
||||
echo "Please set it to a valid token"; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
@uvx schemathesis run apidocs/openapi/$(svc).yaml \
|
||||
--checks all \
|
||||
--url $(2) \
|
||||
--header "Authorization: Bearer $(USER_TOKEN)" \
|
||||
--suppress-health-check=filter_too_much \
|
||||
--exclude-checks=positive_data_acceptance \
|
||||
--exclude-operation-id=requestPasswordReset \
|
||||
--phases=examples,stateful
|
||||
endef
|
||||
|
||||
test_api_users: TEST_API_URL := http://localhost:9000
|
||||
test_api_clients: TEST_API_URL := http://localhost:9000
|
||||
test_api_domains: TEST_API_URL := http://localhost:9000
|
||||
test_api_channels: TEST_API_URL := http://localhost:9000
|
||||
test_api_groups: TEST_API_URL := http://localhost:9000
|
||||
test_api_certs: TEST_API_URL := http://localhost:9019
|
||||
|
||||
$(TEST_API):
|
||||
$(call test_api_service,$(@),$(TEST_API_URL))
|
||||
|
||||
proto:
|
||||
protoc -I. --go_out=. --go_opt=paths=source_relative pkg/messaging/*.proto
|
||||
protoc -I. --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative ./*.proto
|
||||
mkdir -p $(PKG_PROTO_GEN_OUT_DIR)
|
||||
protoc -I $(INTERNAL_PROTO_DIR) --go_out=$(PKG_PROTO_GEN_OUT_DIR) --go_opt=paths=source_relative --go-grpc_out=$(PKG_PROTO_GEN_OUT_DIR) --go-grpc_opt=paths=source_relative $(INTERNAL_PROTO_FILES)
|
||||
|
||||
$(FILTERED_SERVICES):
|
||||
$(call compile_service,$(@))
|
||||
@@ -157,6 +298,15 @@ changelog:
|
||||
latest: dockers
|
||||
$(call docker_push,latest)
|
||||
|
||||
publish_arch:
|
||||
$(MAKE) dockers GOOS=$(GOOS) GOARCH=$(GOARCH) GOARM=$(GOARM)
|
||||
for svc in $(SERVICES); do \
|
||||
docker tag $(MG_DOCKER_IMAGE_NAME_PREFIX)/$$svc $(MG_DOCKER_IMAGE_NAME_PREFIX)/$$svc:$(VERSION)-$(GOARCH); \
|
||||
docker tag $(MG_DOCKER_IMAGE_NAME_PREFIX)/$$svc $(MG_DOCKER_IMAGE_NAME_PREFIX)/$$svc:latest-$(GOARCH); \
|
||||
docker push $(MG_DOCKER_IMAGE_NAME_PREFIX)/$$svc:$(VERSION)-$(GOARCH); \
|
||||
docker push $(MG_DOCKER_IMAGE_NAME_PREFIX)/$$svc:latest-$(GOARCH); \
|
||||
done
|
||||
|
||||
release:
|
||||
$(eval version = $(shell git describe --abbrev=0 --tags))
|
||||
git checkout $(version)
|
||||
@@ -170,42 +320,121 @@ rundev:
|
||||
cd scripts && ./run.sh
|
||||
|
||||
grpc_mtls_certs:
|
||||
$(MAKE) -C docker/ssl auth_grpc_certs things_grpc_certs
|
||||
$(MAKE) -C docker/ssl clients_grpc_certs
|
||||
|
||||
provision_atom_tokens:
|
||||
$(DOCKER_PLATFORM) docker compose -f docker/docker-compose.yaml $(DOCKER_PROVISION_ENV_FILES) -p $(DOCKER_PROJECT) up -d --wait --wait-timeout 120 atom
|
||||
$(MAKE) docker_atom-bootstrap
|
||||
$(DOCKER_PLATFORM) docker compose -f docker/docker-compose.yaml $(DOCKER_PROVISION_ENV_FILES) -p $(DOCKER_PROJECT) run --rm --no-deps --user "$(HOST_UID):$(HOST_GID)" -v "$(PWD)/docker:/host/docker" atom-bootstrap provision-tokens --output /host/docker/.env.tokens
|
||||
|
||||
provision-atom-tokens:
|
||||
@:
|
||||
|
||||
# Migrate an old Magistrala (v0.30.0 / pre-Atom) deployment into Atom. Runs an
|
||||
# isolated, collision-free stack, seeds the Atom schema into the run_latest Atom
|
||||
# volume and loads the data. Default is a dry-run; pass args="--apply" to load,
|
||||
# args="--verify" to reconcile afterwards.
|
||||
# make migrate_atom # dry-run
|
||||
# make migrate_atom args="--apply" # perform the migration
|
||||
# make migrate_atom args="--apply --fresh-atom" # rebuild Atom schema first
|
||||
migrate_atom:
|
||||
DOCKER_PROJECT="$(DOCKER_PROJECT)" tools/atom-migration/migrate.sh $(args)
|
||||
|
||||
check_tls:
|
||||
ifeq ($(GRPC_TLS),true)
|
||||
@unset GRPC_MTLS
|
||||
@echo "gRPC TLS is enabled"
|
||||
GRPC_MTLS=
|
||||
$(eval GRPC_MTLS :=)
|
||||
else
|
||||
@unset GRPC_TLS
|
||||
GRPC_TLS=
|
||||
$(eval GRPC_TLS :=)
|
||||
endif
|
||||
|
||||
check_mtls:
|
||||
ifeq ($(GRPC_MTLS),true)
|
||||
@unset GRPC_TLS
|
||||
@echo "gRPC MTLS is enabled"
|
||||
GRPC_TLS=
|
||||
$(eval GRPC_TLS :=)
|
||||
else
|
||||
@unset GRPC_MTLS
|
||||
GRPC_MTLS=
|
||||
$(eval GRPC_MTLS :=)
|
||||
endif
|
||||
|
||||
check_certs: check_mtls check_tls
|
||||
# Internal services reach FluxMQ on the mTLS local listener, and Compose mounts
|
||||
# both sides of those connections. Certificates and principal secrets are
|
||||
# generated rather than committed, so make them before anything binds them.
|
||||
check_fluxmq_service_certs:
|
||||
ifeq ("$(wildcard docker/ssl/certs/re-fluxmq-client.crt)","")
|
||||
$(MAKE) -C docker/ssl fluxmq_service_certs
|
||||
endif
|
||||
ifeq ("$(wildcard docker/ssl/certs/timescale-writer-fluxmq-client.crt)","")
|
||||
$(MAKE) -C docker/ssl timescale_writer_fluxmq_client_cert
|
||||
endif
|
||||
ifeq ("$(wildcard docker/ssl/certs/postgres-writer-fluxmq-client.crt)","")
|
||||
$(MAKE) -C docker/ssl postgres_writer_fluxmq_client_cert
|
||||
endif
|
||||
ifeq ("$(wildcard docker/ssl/certs/fluxmq-auth-fluxmq-client.crt)","")
|
||||
$(MAKE) -C docker/ssl fluxmq_auth_fluxmq_client_cert
|
||||
endif
|
||||
ifeq ("$(wildcard docker/fluxmq/secrets/re-current)","")
|
||||
$(MAKE) -C docker/ssl fluxmq_service_secret
|
||||
endif
|
||||
ifeq ("$(wildcard docker/fluxmq/secrets/timescale-writer-current)","")
|
||||
$(MAKE) -C docker/ssl timescale_writer_fluxmq_service_secret
|
||||
endif
|
||||
ifeq ("$(wildcard docker/fluxmq/secrets/postgres-writer-current)","")
|
||||
$(MAKE) -C docker/ssl postgres_writer_fluxmq_service_secret
|
||||
endif
|
||||
ifeq ("$(wildcard docker/fluxmq/secrets/fluxmq-auth-current)","")
|
||||
$(MAKE) -C docker/ssl fluxmq_auth_fluxmq_service_secret
|
||||
endif
|
||||
|
||||
check_re_trace_key:
|
||||
ifeq ("$(wildcard docker/re/secrets/trace.key)","")
|
||||
$(MAKE) -C docker/ssl re_trace_key
|
||||
endif
|
||||
|
||||
check_certs: check_mtls check_tls check_fluxmq_service_certs check_re_trace_key
|
||||
ifeq ($(GRPC_MTLS_CERT_FILES_EXISTS),0)
|
||||
ifeq ($(filter true,$(GRPC_MTLS) $(GRPC_TLS)),true)
|
||||
ifeq ($(filter $(DEFAULT_DOCKER_COMPOSE_COMMAND),$(DOCKER_COMPOSE_COMMAND)),$(DEFAULT_DOCKER_COMPOSE_COMMAND))
|
||||
$(MAKE) -C docker/ssl auth_grpc_certs things_grpc_certs
|
||||
$(MAKE) -C docker/ssl clients_grpc_certs
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
run: check_certs
|
||||
docker compose -f docker/docker-compose.yml --env-file docker/.env -p $(DOCKER_PROJECT) $(DOCKER_COMPOSE_COMMAND) $(args)
|
||||
run_latest: check_certs
|
||||
$(SED_INPLACE) 's/^MG_RELEASE_TAG=.*/MG_RELEASE_TAG=latest/' docker/.env
|
||||
$(call ensure_atom_tokens_env)
|
||||
$(DOCKER_PLATFORM) docker compose -f docker/docker-compose.yaml $(DOCKER_ENV_FILES) -p $(DOCKER_PROJECT) $(DOCKER_COMPOSE_COMMAND) $(args)
|
||||
|
||||
run_latest_ci: check_certs
|
||||
$(call require_atom_tokens_env)
|
||||
$(SED_INPLACE) 's/^MG_RELEASE_TAG=.*/MG_RELEASE_TAG=latest/' docker/.env
|
||||
$(DOCKER_PLATFORM) docker compose -f docker/docker-compose.yaml -f docker/docker-compose-ci.yaml $(DOCKER_ENV_FILES) -p $(DOCKER_PROJECT) $(DOCKER_COMPOSE_COMMAND) $(args)
|
||||
|
||||
run_tls: check_certs
|
||||
@test -n "$(host)" || (echo "Usage: make run_tls host=example.com [email=admin@example.com] [letsencrypt=false] [staging=true] [force=true]" && exit 2)
|
||||
@if [ "$(or $(letsencrypt),true)" != "false" ] && [ -z "$(email)" ]; then echo "Usage: make run_tls host=example.com email=admin@example.com [letsencrypt=false] [staging=true] [force=true]"; exit 2; fi
|
||||
MG_PUBLIC_HOST="$(host)" \
|
||||
MG_LETSENCRYPT_ENABLED="$(or $(letsencrypt),true)" \
|
||||
MG_LETSENCRYPT_EMAIL="$(email)" \
|
||||
MG_LETSENCRYPT_STAGING="$(or $(staging),false)" \
|
||||
MG_LETSENCRYPT_FORCE_RENEWAL="$(or $(force),false)" \
|
||||
DOCKER_PROJECT="$(DOCKER_PROJECT)" \
|
||||
./docker/setup-tls.sh
|
||||
|
||||
run_stable: check_certs
|
||||
$(call require_atom_tokens_env)
|
||||
$(eval version = $(shell git describe --abbrev=0 --tags))
|
||||
git checkout $(version)
|
||||
$(SED_INPLACE) 's/^MG_RELEASE_TAG=.*/MG_RELEASE_TAG=$(version)/' docker/.env
|
||||
$(DOCKER_PLATFORM) docker compose -f docker/docker-compose.yaml $(DOCKER_ENV_FILES) -p $(DOCKER_PROJECT) $(DOCKER_COMPOSE_COMMAND) $(args)
|
||||
|
||||
run_addons: check_certs
|
||||
$(call require_atom_tokens_env)
|
||||
$(foreach SVC,$(RUN_ADDON_ARGS),$(if $(filter $(SVC),$(ADDON_SERVICES) $(EXTERNAL_SERVICES)),,$(error Invalid Service $(SVC))))
|
||||
@$(DOCKER_PLATFORM) docker compose -f docker/docker-compose.yaml $(DOCKER_ENV_FILES) -p $(DOCKER_PROJECT) up -d atom jaeger
|
||||
@for SVC in $(RUN_ADDON_ARGS); do \
|
||||
MG_ADDONS_CERTS_PATH_PREFIX="../." docker compose -f docker/addons/$$SVC/docker-compose.yml -p $(DOCKER_PROJECT) --env-file ./docker/.env $(DOCKER_COMPOSE_COMMAND) $(args) & \
|
||||
MG_ADDONS_CERTS_PATH_PREFIX="../" $(DOCKER_PLATFORM) docker compose -f docker/addons/$$SVC/docker-compose.yaml -p $(DOCKER_PROJECT) $(DOCKER_ENV_FILES) $(DOCKER_COMPOSE_COMMAND) $(args) & \
|
||||
done
|
||||
|
||||
run_live: check_certs
|
||||
$(call require_atom_tokens_env)
|
||||
GOPATH=$(go env GOPATH) $(DOCKER_PLATFORM) docker compose -f docker/docker-compose.yaml -f docker/docker-compose-live.yaml $(DOCKER_ENV_FILES) -p $(DOCKER_PROJECT) $(DOCKER_COMPOSE_COMMAND) $(args)
|
||||
|
||||
@@ -1,193 +1,412 @@
|
||||
<div align="center">
|
||||
|
||||
# Magistrala
|
||||
|
||||
### A Modern IoT Platform Framework for Scalable IoT
|
||||
|
||||
**Made with ❤ by [Abstract Machines](https://absmach.eu/)**
|
||||
|
||||
[](https://github.com/absmach/magistrala/actions/workflows/build.yaml)
|
||||
[](https://goreportcard.com/report/github.com/absmach/magistrala)
|
||||
[](https://deepwiki.com/absmach/magistrala)
|
||||
[](https://github.com/absmach/magistrala/actions/workflows/check-license.yaml)
|
||||
[](https://github.com/absmach/magistrala/actions/workflows/check-generated-files.yml)
|
||||
[](https://github.com/absmach/magistrala/actions/workflows/build.yml)
|
||||
[![go report card][grc-badge]][grc-url]
|
||||
[![coverage][cov-badge]][cov-url]
|
||||
[![license][license]](LICENSE)
|
||||
[![chat][gitter-badge]][gitter]
|
||||
[](https://github.com/absmach/magistrala/actions/workflows/check-generated-files.yaml)
|
||||
[](https://codecov.io/gh/absmach/magistrala)
|
||||
[](LICENSE)
|
||||
[](https://matrix.to/#/#supermq:matrix.org)
|
||||
|
||||
![banner][banner]
|
||||
[Guide](https://magistrala.absmach.eu/docs/) | [Contributing](CONTRIBUTING.md) | [Website](https://absmach.eu/) | [Chat](https://matrix.to/#/#supermq:matrix.org)
|
||||
</div>
|
||||
|
||||
Magistrala is modern, scalable, secure, open-source, and patent-free IoT cloud platform written in Go.
|
||||
## Introduction 🌍
|
||||
|
||||
It accepts user and thing (sensor, actuator, application) connections over various network protocols (i.e. HTTP, MQTT, WebSocket, CoAP), thus making a seamless bridge between them. It is used as the IoT middleware for building complex IoT solutions.
|
||||
Magistrala is an open-source IoT platform built for engineers who need full control over their messaging, device management, and data pipelines.
|
||||
|
||||
For more details, check out the [official documentation][docs].
|
||||
It is built on top of [FluxMQ](https://github.com/absmach/fluxmq), a modern message broker designed for both messaging and event streams. Magistrala provides everything around it: identity, access control, device provisioning, data processing, and observability.
|
||||
|
||||
## Features
|
||||
IoT systems usually involve brokers, databases, rule engines, and custom services. Magistrala does not pretend those pieces disappear. It provides a coherent framework for integrating them into a single system with a consistent model for identity, access control, messaging, and observability.
|
||||
|
||||
- Multi-protocol connectivity and bridging (HTTP, MQTT, WebSocket and CoAP)
|
||||
- Device management and provisioning (Zero Touch provisioning)
|
||||
- Mutual TLS Authentication (mTLS) using X.509 Certificates
|
||||
- Fine-grained access control (policies, ABAC/RBAC)
|
||||
- Message persistence (Cassandra, InfluxDB, MongoDB and PostgresSQL)
|
||||
- Platform logging and instrumentation support (Prometheus and OpenTelemetry)
|
||||
- Event sourcing
|
||||
- Container-based deployment using [Docker][docker] and [Kubernetes][kubernetes]
|
||||
- [LoRaWAN][lora] network integration
|
||||
- [OPC UA][opcua] integration
|
||||
- Edge [Agent][agent] and [Export][export] services for remote IoT gateway management and edge computing
|
||||
- SDK
|
||||
- CLI
|
||||
- Small memory footprint and fast execution
|
||||
- Domain-driven design architecture, high-quality code and test coverage
|
||||
**What it is:**
|
||||
- An event-driven IoT middleware platform
|
||||
- A unified control plane for devices, users, and data
|
||||
- A foundation for building scalable IoT systems
|
||||
|
||||
## Prerequisites
|
||||
**What it is not:**
|
||||
- Not just an MQTT broker
|
||||
- Not a black-box SaaS
|
||||
- Not tied to a single cloud or vendor
|
||||
|
||||
The following are needed to run Magistrala:
|
||||
---
|
||||
|
||||
- [Docker](https://docs.docker.com/install/) (version 24.0.7)
|
||||
- [Docker compose](https://docs.docker.com/compose/install/) (version 2.24.0)
|
||||
## 🧩 IoT Platform Framework
|
||||
|
||||
Developing Magistrala will also require:
|
||||
We call Magistrala a **framework**, not just a platform.
|
||||
|
||||
- [Go](https://golang.org/doc/install) (version 1.21)
|
||||
- [Protobuf](https://github.com/protocolbuffers/protobuf#protocol-compiler-installation) (version 25.1)
|
||||
It is extremely flexible and lets you build systems the way you want — from simple prototypes to complex, large-scale deployments — without forcing you into rigid patterns.
|
||||
|
||||
## Install
|
||||
At the same time, it avoids the typical complexity of many IoT platforms, where you need to learn an entirely new set of concepts before you can even get started.
|
||||
|
||||
Once the prerequisites are installed, execute the following commands from the project's root:
|
||||
Magistrala is built around a small number of main concepts:
|
||||
- users
|
||||
- clients (devices)
|
||||
- channels
|
||||
- messages
|
||||
- policies
|
||||
|
||||
```bash
|
||||
docker compose -f docker/docker-compose.yml --env-file docker/.env -p git_github_com_absmach_magistrala_git_ up
|
||||
Most engineers are already familiar with these ideas, so you can start building immediately.
|
||||
|
||||
You can keep things simple:
|
||||
- connect devices
|
||||
- send messages
|
||||
- store data
|
||||
|
||||
Or you can go deeper:
|
||||
- define complex access control policies
|
||||
- build event-driven pipelines
|
||||
- integrate custom processing and automation
|
||||
|
||||
Magistrala scales with your needs — simple when you want it, powerful when you need it.
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Key Benefits
|
||||
|
||||
- **A Coherent System, Not a Mess of Integrations**
|
||||
Build IoT systems from multiple components without ending up with fragmented security, messaging, and operations.
|
||||
|
||||
- **Event-Driven at the Core**
|
||||
Everything is built around events — enabling real-time processing, streaming, and scalable data flows.
|
||||
|
||||
- **Protocol-Native, Not Forced Abstractions**
|
||||
MQTT, HTTP, WebSocket, and CoAP are treated as first-class citizens, each with their own semantics.
|
||||
|
||||
- **Security Built Into the Model**
|
||||
Identity, authentication, and authorization are part of the system design — not bolted on later.
|
||||
|
||||
- **Flexible by Design**
|
||||
Start simple or build complex systems — without changing platforms or rewriting your architecture.
|
||||
|
||||
- **Runs Where You Need It**
|
||||
Cloud, edge, or hybrid — no vendor lock-in, no hidden dependencies.
|
||||
---
|
||||
## ✨ Features
|
||||
|
||||
Magistrala provides a complete set of building blocks for IoT systems — from device connectivity to data processing and observability — without forcing a rigid architecture.
|
||||
|
||||
### 🔐 Identity & Access
|
||||
|
||||
- Multi-tenant domains for isolating environments
|
||||
- Users, roles, and organizational hierarchies
|
||||
- Fine-grained access control (ABAC + RBAC)
|
||||
- Mutual TLS (X.509) and JWT-based authentication
|
||||
- Personal Access Tokens (PATs) with scoping and revocation
|
||||
|
||||
### 🔌 Connectivity
|
||||
|
||||
- Native support for MQTT, HTTP, WebSocket, and CoAP
|
||||
- Consistent authentication and authorization across protocols
|
||||
- Designed for both cloud services and constrained devices
|
||||
|
||||
### 📦 Device & Application Model
|
||||
|
||||
- Device (client) provisioning and lifecycle management
|
||||
- Channels for grouping and controlling message flow
|
||||
- Application-level grouping and sharing of clients
|
||||
- Simple but flexible communication model
|
||||
|
||||
### ⚙️ Processing & Automation
|
||||
|
||||
- Rules engine for message processing and routing (Enterprise Edition)
|
||||
- Alarms and triggers for reacting to events (Enterprise Edition)
|
||||
- Scheduled actions for time-based workflows
|
||||
- Event-driven architecture as the foundation
|
||||
|
||||
### 📊 Observability
|
||||
|
||||
- Audit logs for tracking system activity (Enterprise Edition)
|
||||
- Metrics and tracing via Prometheus and OpenTelemetry
|
||||
- Built-in visibility into system behavior and data flows
|
||||
|
||||
### 🚀 Deployment & Operations
|
||||
|
||||
- Container-native (Docker, Kubernetes)
|
||||
- Designed for cloud, edge, and hybrid deployments
|
||||
- Works with external storage and processing systems
|
||||
- Scales from small setups to production environments
|
||||
|
||||
### 🧑💻 Developer Experience
|
||||
|
||||
- CLI and SDKs for fast integration
|
||||
- Straightforward APIs and concepts
|
||||
- Documentation focused on getting you running quickly
|
||||
---
|
||||
|
||||
## Atom Integration Model
|
||||
|
||||
Magistrala uses **Atom** as the backend for identity, authorization, and the catalog.
|
||||
|
||||
Atom is the source of truth for:
|
||||
- domains
|
||||
- users
|
||||
- clients
|
||||
- channels
|
||||
- groups
|
||||
- roles
|
||||
- access policies
|
||||
|
||||
Magistrala services such as rules, alarms, and reports remain Magistrala services, but they use Atom for identity and authorization.
|
||||
|
||||
Current Docker deployments use the Atom image configured by `ATOM_IMAGE` in `docker/.env`. For compatibility with the current Magistrala integration, the generated `MG_ATOM_TOKEN_*` service credentials are unscoped Atom access tokens. Scoped Atom access tokens should not be used for these service env vars until Magistrala stops using owner-wide Atom listing APIs such as `authorizedObjectIds` in service policy paths.
|
||||
|
||||
### Core Entity Mapping
|
||||
|
||||
| Magistrala concept | Atom concept | Meaning |
|
||||
| ------------------ | ---------------------------- | ------------------------------------------------------------------ |
|
||||
| Domain | Tenant | Isolation boundary for one organization, project, or environment |
|
||||
| User | Entity with kind `human` | A person who logs in and uses the UI/API |
|
||||
| Client | Entity with kind `device` | A device or application that sends/receives data |
|
||||
| Channel | Resource with kind `channel` | A messaging/data path that clients can publish or subscribe to |
|
||||
| Group | Group | A collection of users, clients, channels, or other grouped objects |
|
||||
|
||||
In simple terms:
|
||||
|
||||
```text
|
||||
MG Domain = Atom Tenant
|
||||
MG User = Atom Human Entity
|
||||
MG Client = Atom Device Entity
|
||||
MG Channel = Atom Channel Resource
|
||||
MG Group = Atom Group
|
||||
```
|
||||
|
||||
This will bring up the Magistrala docker services and interconnect them. This command can also be executed using the project's included Makefile:
|
||||
### Actions, Permission Blocks, Roles, and Assignments
|
||||
|
||||
```bash
|
||||
make run
|
||||
Atom access control has these basic parts:
|
||||
|
||||
| Atom word | Simple meaning | Example |
|
||||
| ---------------- | ----------------------------- | --------------------------------------------------------- |
|
||||
| Action | One permission verb | `read`, `write`, `delete`, `role.manage`, `policy.manage` |
|
||||
| Permission Block | Where actions apply | all channels in domain `d1` can `read`, `publish` |
|
||||
| Role | A bundle of permission blocks | `tenant-admin` bundles domain, role, and member access |
|
||||
| Role Assignment | Who gets a role | give `user1` the `tenant-admin` role |
|
||||
|
||||
Read an assignment like this:
|
||||
|
||||
```text
|
||||
Give <who> this <role>.
|
||||
The role contains permission blocks that say where and what.
|
||||
```
|
||||
|
||||
If you want to run services from specific release checkout code from github and make sure that
|
||||
`MG_RELEASE_TAG` in [.env](.env) is being set to match the release version
|
||||
Example:
|
||||
|
||||
```bash
|
||||
git checkout tags/<release_number> -b <release_number>
|
||||
# e.g. `git checkout tags/0.13.0 -b 0.13.0`
|
||||
```text
|
||||
Give user1 the tenant-admin role on domain d1.
|
||||
```
|
||||
|
||||
Check that `.env` file contains:
|
||||
That means:
|
||||
|
||||
```bash
|
||||
MG_RELEASE_TAG=<release_number>
|
||||
```text
|
||||
user1 can use the tenant-admin permissions inside domain d1.
|
||||
```
|
||||
|
||||
> `docker-compose` should be used for development and testing deployments. For production we suggest using [Kubernetes](https://docs.mainflux.io/kubernetes).
|
||||
### How MG Roles Work With Atom
|
||||
|
||||
MG UI shows actions such as:
|
||||
- read
|
||||
- update
|
||||
- delete
|
||||
- manage roles
|
||||
- add/remove members
|
||||
- publish
|
||||
- subscribe
|
||||
|
||||
These are mapped to Atom actions:
|
||||
|
||||
| MG action | Atom action |
|
||||
| ---------------------------- | --------------- |
|
||||
| view/read | `read` |
|
||||
| create/update/edit/connect | `write` |
|
||||
| delete/remove | `delete` |
|
||||
| manage roles | `role.manage` |
|
||||
| add/remove members or access | `policy.manage` |
|
||||
| channel publish | `publish` |
|
||||
| channel subscribe | `subscribe` |
|
||||
|
||||
So when MG UI checks:
|
||||
|
||||
```text
|
||||
Can user1 manage roles for client1?
|
||||
```
|
||||
|
||||
Atom checks:
|
||||
|
||||
```text
|
||||
Does user1 have role.manage on client1, or on the domain that contains client1?
|
||||
```
|
||||
|
||||
When MG UI checks:
|
||||
|
||||
```text
|
||||
Can user1 add a member to channel1?
|
||||
```
|
||||
|
||||
Atom checks:
|
||||
|
||||
```text
|
||||
Does user1 have policy.manage on channel1, or on the domain that contains channel1?
|
||||
```
|
||||
|
||||
### Practical Rule
|
||||
|
||||
If a user is domain admin, they usually receive a tenant-scoped role in Atom.
|
||||
|
||||
That tenant-scoped role can allow them to manage objects inside the domain:
|
||||
- clients
|
||||
- channels
|
||||
- groups
|
||||
- rules
|
||||
- alarms
|
||||
- reports
|
||||
|
||||
For narrower access, create object-scoped roles. For example:
|
||||
|
||||
```text
|
||||
Give user2 a reader role only on channel1.
|
||||
```
|
||||
|
||||
Then user2 can read only that channel, not the whole domain.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
git clone https://github.com/absmach/magistrala.git
|
||||
cd magistrala
|
||||
make provision_atom_tokens
|
||||
make run_latest
|
||||
```
|
||||
|
||||
A fresh clone carries no generated secrets. Two sets have to exist before the
|
||||
stack can start — certificates and keys the internal services authenticate
|
||||
with, and the Atom service tokens each service presents to Atom. `make
|
||||
run_latest` produces the first set itself but expects the second to be there
|
||||
already, which is why the token step comes first above.
|
||||
|
||||
### Certificates, broker secret and trace key
|
||||
|
||||
Generated by `make run_latest`, or on demand:
|
||||
|
||||
```bash
|
||||
make check_certs
|
||||
```
|
||||
|
||||
This creates whatever is missing and leaves anything already present alone:
|
||||
|
||||
| Path | What it is |
|
||||
| ----------------------------------------------------------- | ------------------------------------------------------------------------- |
|
||||
| `docker/ssl/certs/fluxmq-service-server.{crt,key}` | Server certificate for FluxMQ's mTLS service listener |
|
||||
| `docker/ssl/certs/re-fluxmq-client.{crt,key}` | Client certificate whose URI SAN identifies the Rules Engine |
|
||||
| `docker/ssl/certs/timescale-writer-fluxmq-client.{crt,key}` | Client certificate whose URI SAN identifies the Timescale writer |
|
||||
| `docker/ssl/certs/postgres-writer-fluxmq-client.{crt,key}` | Client certificate whose URI SAN identifies the Postgres writer |
|
||||
| `docker/ssl/certs/fluxmq-auth-fluxmq-client.{crt,key}` | Client certificate whose URI SAN identifies the publish proxy |
|
||||
| `docker/fluxmq/secrets/re-current` | Rules Engine principal secret, from `MG_RE_BROKER_SECRET` |
|
||||
| `docker/fluxmq/secrets/timescale-writer-current` | Timescale writer secret, from `MG_TIMESCALE_WRITER_BROKER_SECRET` |
|
||||
| `docker/fluxmq/secrets/postgres-writer-current` | Postgres writer secret, from `MG_POSTGRES_WRITER_BROKER_SECRET` |
|
||||
| `docker/fluxmq/secrets/fluxmq-auth-current` | Publish proxy secret, from `MG_FLUXMQ_BROKER_SECRET` |
|
||||
| `docker/re/secrets/trace.key` | HMAC key the Rules Engine signs its loop-detection traces with |
|
||||
|
||||
Internal services reach the broker as *local principals* rather than as ordinary
|
||||
clients: each presents a client certificate whose URI SAN names it, plus a SASL
|
||||
secret, and the broker grants it only what it needs — the Rules Engine consumes
|
||||
`m`, republishes under it, and feeds the `writers` and `alarms` streams; the
|
||||
writers only subscribe to `writers`; the publish proxy that serves the UI's
|
||||
HTTP publish endpoint only publishes under `m.`. The principals are declared in
|
||||
`docker/fluxmq/node{1,2,3}.yaml`, and adding a service means adding an entry
|
||||
there alongside its certificate and secret.
|
||||
|
||||
Being a local principal is also what preserves a message's origin. The broker
|
||||
stamps its own transport protocol and identity on anything published over a
|
||||
connection it does not trust, so a message relayed to the writers over the plain
|
||||
AMQP listener would be stored as `protocol: amqp` with the relaying service as
|
||||
its publisher. A `service`-role principal on the mTLS listener may state the
|
||||
origin instead, and the protocol the device actually published with survives to
|
||||
the database.
|
||||
|
||||
The certificates are issued by the development CA committed at
|
||||
`docker/ssl/certs/ca.crt`, so no extra setup is needed for a local run. The
|
||||
generated material is gitignored.
|
||||
|
||||
The server certificate is issued for `fluxmq` and `fluxmq-node{1,2,3}`, which
|
||||
covers both this Compose stack and a single-node deployment. Point any
|
||||
`MG_*_BROKER_URL` at a host outside that set and the service fails its TLS
|
||||
verification with `certificate is valid for ...`; add the name to
|
||||
`FLUXMQ_SERVICE_SERVER_CERT_CONFIG` in `docker/ssl/Makefile` and reissue:
|
||||
|
||||
```bash
|
||||
rm -f docker/ssl/certs/fluxmq-service-server.* \
|
||||
docker/ssl/certs/re-fluxmq-client.* \
|
||||
docker/ssl/certs/timescale-writer-fluxmq-client.* \
|
||||
docker/ssl/certs/postgres-writer-fluxmq-client.*
|
||||
make -C docker/ssl fluxmq_service_certs
|
||||
```
|
||||
|
||||
`make check_certs` skips certificates that already exist, so stale certificates
|
||||
have to be removed rather than merely re-running the target.
|
||||
|
||||
Each local-principal secret must stay equal to the corresponding value in
|
||||
`docker/.env`; a mismatch fails that service's broker authentication. After
|
||||
changing one, re-run its target:
|
||||
|
||||
| Variable | Target |
|
||||
| ----------------------------------- | ----------------------------------------- |
|
||||
| `MG_RE_BROKER_SECRET` | `fluxmq_service_secret` |
|
||||
| `MG_TIMESCALE_WRITER_BROKER_SECRET` | `timescale_writer_fluxmq_service_secret` |
|
||||
| `MG_POSTGRES_WRITER_BROKER_SECRET` | `postgres_writer_fluxmq_service_secret` |
|
||||
| `MG_FLUXMQ_BROKER_SECRET` | `fluxmq_auth_fluxmq_service_secret` |
|
||||
|
||||
`trace.key` is created once and preserved on later runs — replacing it while
|
||||
messages are in flight would invalidate the rule traces they already carry, so
|
||||
delete it only deliberately. Every Rules Engine replica must read the same key.
|
||||
|
||||
Start the stack through `make run_latest` rather than calling `docker compose
|
||||
up` directly. Compose creates a missing bind-mount source as an empty
|
||||
*directory*, so bringing up `re` or `fluxmq` before these files exist leaves the
|
||||
containers failing against a directory where they expect a key.
|
||||
|
||||
### Atom service tokens
|
||||
|
||||
Not generated automatically, because provisioning them starts Atom and runs a
|
||||
bootstrap job against it:
|
||||
|
||||
```bash
|
||||
make provision_atom_tokens
|
||||
```
|
||||
|
||||
This brings up Atom, runs `atom-bootstrap`, and writes the gitignored
|
||||
`docker/.env.tokens` with one service token per consumer —
|
||||
`MG_ATOM_TOKEN_FLUXMQ_AUTH`, `MG_ATOM_TOKEN_FLUXMQ_NODE{1,2,3}`,
|
||||
`MG_ATOM_TOKEN_RE`, `MG_ATOM_TOKEN_ALARMS`, `MG_ATOM_TOKEN_REPORTS`,
|
||||
`MG_ATOM_TOKEN_TIMESCALE_READER`, and `MG_ATOM_TOKEN_POSTGRES_READER`.
|
||||
|
||||
`make run_latest` refuses to start when that file is absent or short of any of
|
||||
those variables, and names what is missing. To fold the step into the run:
|
||||
|
||||
```bash
|
||||
make run_latest PROVISION_ATOM_TOKENS=true
|
||||
```
|
||||
|
||||
Re-run `provision_atom_tokens` after anything that resets Atom's database; the
|
||||
old tokens do not survive it.
|
||||
|
||||
---
|
||||
|
||||
## Usage
|
||||
|
||||
The quickest way to start using Magistrala is via the CLI. The latest version can be downloaded from the [official releases page][releases].
|
||||
|
||||
It can also be built and used from the project's root directory:
|
||||
|
||||
```bash
|
||||
make cli
|
||||
./build/cli version
|
||||
./build/cli health <service>
|
||||
```
|
||||
|
||||
Additional details on using the CLI can be found in the [CLI documentation](https://docs.mainflux.io/cli).
|
||||
|
||||
## Documentation
|
||||
|
||||
Official documentation is hosted at [Magistrala official docs page][docs]. Documentation is auto-generated, checkout the instructions on [official docs repository](https://github.com/mainflux/docs):
|
||||
|
||||
If you spot an error or a need for corrections, please let us know - or even better: send us a PR.
|
||||
|
||||
## Authors
|
||||
|
||||
Main architect and BDFL of Magistrala project is [@drasko][drasko].
|
||||
|
||||
Additionally, [@nmarcetic][nikola] and [@janko-isidorovic][janko] assured overall architecture and design, while [@manuio][manu] and [@darkodraskovic][darko] helped with crafting initial implementation and continuously worked on the project evolutions.
|
||||
|
||||
Besides them, Magistrala is constantly improved and actively developed by [@anovakovic01][alex], [@dusanb94][dusan], [@srados][sava], [@gsaleh][george], [@blokovi][iva], [@chombium][kole], [@mteodor][mirko], [@rodneyosodo][rodneyosodo] and a large set of contributors.
|
||||
|
||||
Maintainers are listed in [MAINTAINERS](MAINTAINERS) file.
|
||||
|
||||
The Magistrala team would like to give special thanks to [@mijicd][dejan] for his monumental work on designing and implementing a highly improved and optimized version of the platform, and [@malidukica][dusanm] for his effort on implementing the initial user interface.
|
||||
|
||||
## Professional Support
|
||||
|
||||
There are many companies offering professional support for the Magistrala system.
|
||||
|
||||
If you need this kind of support, best is to reach out to [@drasko][drasko] directly, and he will point you out to the best-matching support team.
|
||||
|
||||
## Contributing
|
||||
|
||||
Thank you for your interest in Magistrala and the desire to contribute!
|
||||
|
||||
1. Take a look at our [open issues](https://github.com/absmach/magistrala/issues). The [good-first-issue](https://github.com/absmach/magistrala/labels/good-first-issue) label is specifically for issues that are great for getting started.
|
||||
2. Checkout the [contribution guide](CONTRIBUTING.md) to learn more about our style and conventions.
|
||||
3. Make your changes compatible to our workflow.
|
||||
|
||||
### We're Hiring
|
||||
|
||||
You like Magistrala and you would like to make it your day job? We're always looking for talented engineers interested in open-source, IoT and distributed systems. If you recognize yourself, reach out to [@drasko][drasko] - he will contact you back.
|
||||
|
||||
> The best way to grab our attention is, of course, by sending PRs :sunglasses:.
|
||||
|
||||
## Community
|
||||
|
||||
- [Google group][forum]
|
||||
- [Gitter][gitter]
|
||||
- [Twitter][twitter]
|
||||
---
|
||||
|
||||
## License
|
||||
|
||||
[Apache-2.0](LICENSE)
|
||||
|
||||
[](https://app.fossa.com/projects/git%2Bgithub.com%2Fmainflux%2Fmainflux?ref=badge_large)
|
||||
|
||||
## Data Collection for Magistrala
|
||||
|
||||
Magistrala is committed to continuously improving its services and ensuring a seamless experience for its users. To achieve this, we collect certain data from your deployments. Rest assured, this data is collected solely for the purpose of enhancing Magistrala and is not used with any malicious intent. The deployment summary can be found on our [website][callhome].
|
||||
|
||||
The collected data includes:
|
||||
|
||||
- **IP Address** - Used for approximate location information on deployments.
|
||||
- **Services Used** - To understand which features are popular and prioritize future developments.
|
||||
- **Last Seen Time** - To ensure the stability and availability of Magistrala.
|
||||
- **Magistrala Version** - To track the software version and deliver relevant updates.
|
||||
|
||||
We take your privacy and data security seriously. All data collected is handled in accordance with our stringent privacy policies and industry best practices.
|
||||
|
||||
Data collection is on by default and can be disabled by setting the env variable:
|
||||
`MG_SEND_TELEMETRY=false`
|
||||
|
||||
By utilizing Magistrala, you actively contribute to its improvement. Together, we can build a more robust and efficient IoT platform. Thank you for your trust in Magistrala!
|
||||
|
||||
[banner]: https://github.com/mainflux/docs/blob/master/docs/img/gopherBanner.jpg
|
||||
[docs]: https://docs.mainflux.io
|
||||
[docker]: https://www.docker.com
|
||||
[forum]: https://groups.google.com/forum/#!forum/mainflux
|
||||
[gitter]: https://gitter.im/absmach/magistrala?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
|
||||
[gitter-badge]: https://badges.gitter.im/Join%20Chat.svg
|
||||
[grc-badge]: https://goreportcard.com/badge/github.com/absmach/magistrala
|
||||
[grc-url]: https://goreportcard.com/report/github.com/absmach/magistrala
|
||||
[cov-badge]: https://codecov.io/gh/absmach/magistrala/graph/badge.svg?token=SEMDAO3L09
|
||||
[cov-url]: https://codecov.io/gh/absmach/magistrala
|
||||
[license]: https://img.shields.io/badge/license-Apache%20v2.0-blue.svg
|
||||
[twitter]: https://twitter.com/mainflux
|
||||
[lora]: https://lora-alliance.org/
|
||||
[opcua]: https://opcfoundation.org/about/opc-technologies/opc-ua/
|
||||
[agent]: https://github.com/mainflux/agent
|
||||
[export]: https://github.com/mainflux/export
|
||||
[kubernetes]: https://kubernetes.io/
|
||||
[releases]: https://github.com/absmach/magistrala/releases
|
||||
[drasko]: https://github.com/drasko
|
||||
[nikola]: https://github.com/nmarcetic
|
||||
[dejan]: https://github.com/mijicd
|
||||
[manu]: https://github.com/manuIO
|
||||
[darko]: https://github.com/darkodraskovic
|
||||
[janko]: https://github.com/janko-isidorovic
|
||||
[alex]: https://github.com/anovakovic01
|
||||
[dusan]: https://github.com/dborovcanin
|
||||
[sava]: https://github.com/srados
|
||||
[george]: https://github.com/gesaleh
|
||||
[iva]: https://github.com/blokovi
|
||||
[kole]: https://github.com/chombium
|
||||
[dusanm]: https://github.com/malidukica
|
||||
[mirko]: https://github.com/mteodor
|
||||
[rodneyosodo]: https://github.com/rodneyosodo
|
||||
[callhome]: https://deployments.mainflux.io
|
||||
Apache-2.0
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Package api contains commonly used constants and functions
|
||||
// for the HTTP endpoints.
|
||||
// for the HTTP and gRPC API.
|
||||
package api
|
||||
@@ -0,0 +1,551 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.11
|
||||
// protoc v7.35.1
|
||||
// source: auth/v1/auth.proto
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type AuthNReq struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *AuthNReq) Reset() {
|
||||
*x = AuthNReq{}
|
||||
mi := &file_auth_v1_auth_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *AuthNReq) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*AuthNReq) ProtoMessage() {}
|
||||
|
||||
func (x *AuthNReq) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_auth_v1_auth_proto_msgTypes[0]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use AuthNReq.ProtoReflect.Descriptor instead.
|
||||
func (*AuthNReq) Descriptor() ([]byte, []int) {
|
||||
return file_auth_v1_auth_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *AuthNReq) GetToken() string {
|
||||
if x != nil {
|
||||
return x.Token
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type AuthNRes struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
UserId string `protobuf:"bytes,2,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
|
||||
UserRole uint32 `protobuf:"varint,3,opt,name=user_role,json=userRole,proto3" json:"user_role,omitempty"`
|
||||
Verified bool `protobuf:"varint,4,opt,name=verified,proto3" json:"verified,omitempty"`
|
||||
TokenType uint32 `protobuf:"varint,5,opt,name=token_type,json=tokenType,proto3" json:"token_type,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *AuthNRes) Reset() {
|
||||
*x = AuthNRes{}
|
||||
mi := &file_auth_v1_auth_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *AuthNRes) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*AuthNRes) ProtoMessage() {}
|
||||
|
||||
func (x *AuthNRes) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_auth_v1_auth_proto_msgTypes[1]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use AuthNRes.ProtoReflect.Descriptor instead.
|
||||
func (*AuthNRes) Descriptor() ([]byte, []int) {
|
||||
return file_auth_v1_auth_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *AuthNRes) GetId() string {
|
||||
if x != nil {
|
||||
return x.Id
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AuthNRes) GetUserId() string {
|
||||
if x != nil {
|
||||
return x.UserId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AuthNRes) GetUserRole() uint32 {
|
||||
if x != nil {
|
||||
return x.UserRole
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *AuthNRes) GetVerified() bool {
|
||||
if x != nil {
|
||||
return x.Verified
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *AuthNRes) GetTokenType() uint32 {
|
||||
if x != nil {
|
||||
return x.TokenType
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type PolicyReq struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Domain string `protobuf:"bytes,1,opt,name=domain,proto3" json:"domain,omitempty"`
|
||||
SubjectType string `protobuf:"bytes,2,opt,name=subject_type,json=subjectType,proto3" json:"subject_type,omitempty"`
|
||||
SubjectKind string `protobuf:"bytes,3,opt,name=subject_kind,json=subjectKind,proto3" json:"subject_kind,omitempty"`
|
||||
SubjectRelation string `protobuf:"bytes,4,opt,name=subject_relation,json=subjectRelation,proto3" json:"subject_relation,omitempty"`
|
||||
Subject string `protobuf:"bytes,5,opt,name=subject,proto3" json:"subject,omitempty"`
|
||||
Relation string `protobuf:"bytes,6,opt,name=relation,proto3" json:"relation,omitempty"`
|
||||
Permission string `protobuf:"bytes,7,opt,name=permission,proto3" json:"permission,omitempty"`
|
||||
Object string `protobuf:"bytes,8,opt,name=object,proto3" json:"object,omitempty"`
|
||||
ObjectType string `protobuf:"bytes,9,opt,name=object_type,json=objectType,proto3" json:"object_type,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *PolicyReq) Reset() {
|
||||
*x = PolicyReq{}
|
||||
mi := &file_auth_v1_auth_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *PolicyReq) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*PolicyReq) ProtoMessage() {}
|
||||
|
||||
func (x *PolicyReq) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_auth_v1_auth_proto_msgTypes[2]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use PolicyReq.ProtoReflect.Descriptor instead.
|
||||
func (*PolicyReq) Descriptor() ([]byte, []int) {
|
||||
return file_auth_v1_auth_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *PolicyReq) GetDomain() string {
|
||||
if x != nil {
|
||||
return x.Domain
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PolicyReq) GetSubjectType() string {
|
||||
if x != nil {
|
||||
return x.SubjectType
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PolicyReq) GetSubjectKind() string {
|
||||
if x != nil {
|
||||
return x.SubjectKind
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PolicyReq) GetSubjectRelation() string {
|
||||
if x != nil {
|
||||
return x.SubjectRelation
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PolicyReq) GetSubject() string {
|
||||
if x != nil {
|
||||
return x.Subject
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PolicyReq) GetRelation() string {
|
||||
if x != nil {
|
||||
return x.Relation
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PolicyReq) GetPermission() string {
|
||||
if x != nil {
|
||||
return x.Permission
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PolicyReq) GetObject() string {
|
||||
if x != nil {
|
||||
return x.Object
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PolicyReq) GetObjectType() string {
|
||||
if x != nil {
|
||||
return x.ObjectType
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type PATReq struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
PatId string `protobuf:"bytes,1,opt,name=pat_id,json=patId,proto3" json:"pat_id,omitempty"`
|
||||
Domain string `protobuf:"bytes,2,opt,name=domain,proto3" json:"domain,omitempty"`
|
||||
Operation string `protobuf:"bytes,3,opt,name=operation,proto3" json:"operation,omitempty"`
|
||||
UserId string `protobuf:"bytes,4,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
|
||||
EntityId string `protobuf:"bytes,5,opt,name=entity_id,json=entityId,proto3" json:"entity_id,omitempty"`
|
||||
EntityType string `protobuf:"bytes,6,opt,name=entity_type,json=entityType,proto3" json:"entity_type,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *PATReq) Reset() {
|
||||
*x = PATReq{}
|
||||
mi := &file_auth_v1_auth_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *PATReq) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*PATReq) ProtoMessage() {}
|
||||
|
||||
func (x *PATReq) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_auth_v1_auth_proto_msgTypes[3]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use PATReq.ProtoReflect.Descriptor instead.
|
||||
func (*PATReq) Descriptor() ([]byte, []int) {
|
||||
return file_auth_v1_auth_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *PATReq) GetPatId() string {
|
||||
if x != nil {
|
||||
return x.PatId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PATReq) GetDomain() string {
|
||||
if x != nil {
|
||||
return x.Domain
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PATReq) GetOperation() string {
|
||||
if x != nil {
|
||||
return x.Operation
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PATReq) GetUserId() string {
|
||||
if x != nil {
|
||||
return x.UserId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PATReq) GetEntityId() string {
|
||||
if x != nil {
|
||||
return x.EntityId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PATReq) GetEntityType() string {
|
||||
if x != nil {
|
||||
return x.EntityType
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type AuthZReq struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
PolicyReq *PolicyReq `protobuf:"bytes,1,opt,name=policy_req,json=policyReq,proto3" json:"policy_req,omitempty"`
|
||||
PatReq *PATReq `protobuf:"bytes,2,opt,name=pat_req,json=patReq,proto3,oneof" json:"pat_req,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *AuthZReq) Reset() {
|
||||
*x = AuthZReq{}
|
||||
mi := &file_auth_v1_auth_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *AuthZReq) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*AuthZReq) ProtoMessage() {}
|
||||
|
||||
func (x *AuthZReq) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_auth_v1_auth_proto_msgTypes[4]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use AuthZReq.ProtoReflect.Descriptor instead.
|
||||
func (*AuthZReq) Descriptor() ([]byte, []int) {
|
||||
return file_auth_v1_auth_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *AuthZReq) GetPolicyReq() *PolicyReq {
|
||||
if x != nil {
|
||||
return x.PolicyReq
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *AuthZReq) GetPatReq() *PATReq {
|
||||
if x != nil {
|
||||
return x.PatReq
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type AuthZRes struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Authorized bool `protobuf:"varint,1,opt,name=authorized,proto3" json:"authorized,omitempty"`
|
||||
Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *AuthZRes) Reset() {
|
||||
*x = AuthZRes{}
|
||||
mi := &file_auth_v1_auth_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *AuthZRes) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*AuthZRes) ProtoMessage() {}
|
||||
|
||||
func (x *AuthZRes) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_auth_v1_auth_proto_msgTypes[5]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use AuthZRes.ProtoReflect.Descriptor instead.
|
||||
func (*AuthZRes) Descriptor() ([]byte, []int) {
|
||||
return file_auth_v1_auth_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
func (x *AuthZRes) GetAuthorized() bool {
|
||||
if x != nil {
|
||||
return x.Authorized
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *AuthZRes) GetId() string {
|
||||
if x != nil {
|
||||
return x.Id
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var File_auth_v1_auth_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_auth_v1_auth_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x12auth/v1/auth.proto\x12\aauth.v1\" \n" +
|
||||
"\bAuthNReq\x12\x14\n" +
|
||||
"\x05token\x18\x01 \x01(\tR\x05token\"\x8b\x01\n" +
|
||||
"\bAuthNRes\x12\x0e\n" +
|
||||
"\x02id\x18\x01 \x01(\tR\x02id\x12\x17\n" +
|
||||
"\auser_id\x18\x02 \x01(\tR\x06userId\x12\x1b\n" +
|
||||
"\tuser_role\x18\x03 \x01(\rR\buserRole\x12\x1a\n" +
|
||||
"\bverified\x18\x04 \x01(\bR\bverified\x12\x1d\n" +
|
||||
"\n" +
|
||||
"token_type\x18\x05 \x01(\rR\ttokenType\"\xa3\x02\n" +
|
||||
"\tPolicyReq\x12\x16\n" +
|
||||
"\x06domain\x18\x01 \x01(\tR\x06domain\x12!\n" +
|
||||
"\fsubject_type\x18\x02 \x01(\tR\vsubjectType\x12!\n" +
|
||||
"\fsubject_kind\x18\x03 \x01(\tR\vsubjectKind\x12)\n" +
|
||||
"\x10subject_relation\x18\x04 \x01(\tR\x0fsubjectRelation\x12\x18\n" +
|
||||
"\asubject\x18\x05 \x01(\tR\asubject\x12\x1a\n" +
|
||||
"\brelation\x18\x06 \x01(\tR\brelation\x12\x1e\n" +
|
||||
"\n" +
|
||||
"permission\x18\a \x01(\tR\n" +
|
||||
"permission\x12\x16\n" +
|
||||
"\x06object\x18\b \x01(\tR\x06object\x12\x1f\n" +
|
||||
"\vobject_type\x18\t \x01(\tR\n" +
|
||||
"objectType\"\xac\x01\n" +
|
||||
"\x06PATReq\x12\x15\n" +
|
||||
"\x06pat_id\x18\x01 \x01(\tR\x05patId\x12\x16\n" +
|
||||
"\x06domain\x18\x02 \x01(\tR\x06domain\x12\x1c\n" +
|
||||
"\toperation\x18\x03 \x01(\tR\toperation\x12\x17\n" +
|
||||
"\auser_id\x18\x04 \x01(\tR\x06userId\x12\x1b\n" +
|
||||
"\tentity_id\x18\x05 \x01(\tR\bentityId\x12\x1f\n" +
|
||||
"\ventity_type\x18\x06 \x01(\tR\n" +
|
||||
"entityType\"x\n" +
|
||||
"\bAuthZReq\x121\n" +
|
||||
"\n" +
|
||||
"policy_req\x18\x01 \x01(\v2\x12.auth.v1.PolicyReqR\tpolicyReq\x12-\n" +
|
||||
"\apat_req\x18\x02 \x01(\v2\x0f.auth.v1.PATReqH\x00R\x06patReq\x88\x01\x01B\n" +
|
||||
"\n" +
|
||||
"\b_pat_req\":\n" +
|
||||
"\bAuthZRes\x12\x1e\n" +
|
||||
"\n" +
|
||||
"authorized\x18\x01 \x01(\bR\n" +
|
||||
"authorized\x12\x0e\n" +
|
||||
"\x02id\x18\x02 \x01(\tR\x02id2z\n" +
|
||||
"\vAuthService\x123\n" +
|
||||
"\tAuthorize\x12\x11.auth.v1.AuthZReq\x1a\x11.auth.v1.AuthZRes\"\x00\x126\n" +
|
||||
"\fAuthenticate\x12\x11.auth.v1.AuthNReq\x1a\x11.auth.v1.AuthNRes\"\x00B0Z.github.com/absmach/magistrala/api/grpc/auth/v1b\x06proto3"
|
||||
|
||||
var (
|
||||
file_auth_v1_auth_proto_rawDescOnce sync.Once
|
||||
file_auth_v1_auth_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_auth_v1_auth_proto_rawDescGZIP() []byte {
|
||||
file_auth_v1_auth_proto_rawDescOnce.Do(func() {
|
||||
file_auth_v1_auth_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_auth_v1_auth_proto_rawDesc), len(file_auth_v1_auth_proto_rawDesc)))
|
||||
})
|
||||
return file_auth_v1_auth_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_auth_v1_auth_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
|
||||
var file_auth_v1_auth_proto_goTypes = []any{
|
||||
(*AuthNReq)(nil), // 0: auth.v1.AuthNReq
|
||||
(*AuthNRes)(nil), // 1: auth.v1.AuthNRes
|
||||
(*PolicyReq)(nil), // 2: auth.v1.PolicyReq
|
||||
(*PATReq)(nil), // 3: auth.v1.PATReq
|
||||
(*AuthZReq)(nil), // 4: auth.v1.AuthZReq
|
||||
(*AuthZRes)(nil), // 5: auth.v1.AuthZRes
|
||||
}
|
||||
var file_auth_v1_auth_proto_depIdxs = []int32{
|
||||
2, // 0: auth.v1.AuthZReq.policy_req:type_name -> auth.v1.PolicyReq
|
||||
3, // 1: auth.v1.AuthZReq.pat_req:type_name -> auth.v1.PATReq
|
||||
4, // 2: auth.v1.AuthService.Authorize:input_type -> auth.v1.AuthZReq
|
||||
0, // 3: auth.v1.AuthService.Authenticate:input_type -> auth.v1.AuthNReq
|
||||
5, // 4: auth.v1.AuthService.Authorize:output_type -> auth.v1.AuthZRes
|
||||
1, // 5: auth.v1.AuthService.Authenticate:output_type -> auth.v1.AuthNRes
|
||||
4, // [4:6] is the sub-list for method output_type
|
||||
2, // [2:4] is the sub-list for method input_type
|
||||
2, // [2:2] is the sub-list for extension type_name
|
||||
2, // [2:2] is the sub-list for extension extendee
|
||||
0, // [0:2] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_auth_v1_auth_proto_init() }
|
||||
func file_auth_v1_auth_proto_init() {
|
||||
if File_auth_v1_auth_proto != nil {
|
||||
return
|
||||
}
|
||||
file_auth_v1_auth_proto_msgTypes[4].OneofWrappers = []any{}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_auth_v1_auth_proto_rawDesc), len(file_auth_v1_auth_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 6,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_auth_v1_auth_proto_goTypes,
|
||||
DependencyIndexes: file_auth_v1_auth_proto_depIdxs,
|
||||
MessageInfos: file_auth_v1_auth_proto_msgTypes,
|
||||
}.Build()
|
||||
File_auth_v1_auth_proto = out.File
|
||||
file_auth_v1_auth_proto_goTypes = nil
|
||||
file_auth_v1_auth_proto_depIdxs = nil
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.6.2
|
||||
// - protoc v7.35.1
|
||||
// source: auth/v1/auth.proto
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
context "context"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.64.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion9
|
||||
|
||||
const (
|
||||
AuthService_Authorize_FullMethodName = "/auth.v1.AuthService/Authorize"
|
||||
AuthService_Authenticate_FullMethodName = "/auth.v1.AuthService/Authenticate"
|
||||
)
|
||||
|
||||
// AuthServiceClient is the client API for AuthService service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
//
|
||||
// AuthService is a service that provides authentication
|
||||
// and authorization functionalities for Magistrala services.
|
||||
type AuthServiceClient interface {
|
||||
Authorize(ctx context.Context, in *AuthZReq, opts ...grpc.CallOption) (*AuthZRes, error)
|
||||
Authenticate(ctx context.Context, in *AuthNReq, opts ...grpc.CallOption) (*AuthNRes, error)
|
||||
}
|
||||
|
||||
type authServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewAuthServiceClient(cc grpc.ClientConnInterface) AuthServiceClient {
|
||||
return &authServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *authServiceClient) Authorize(ctx context.Context, in *AuthZReq, opts ...grpc.CallOption) (*AuthZRes, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(AuthZRes)
|
||||
err := c.cc.Invoke(ctx, AuthService_Authorize_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *authServiceClient) Authenticate(ctx context.Context, in *AuthNReq, opts ...grpc.CallOption) (*AuthNRes, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(AuthNRes)
|
||||
err := c.cc.Invoke(ctx, AuthService_Authenticate_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// AuthServiceServer is the server API for AuthService service.
|
||||
// All implementations must embed UnimplementedAuthServiceServer
|
||||
// for forward compatibility.
|
||||
//
|
||||
// AuthService is a service that provides authentication
|
||||
// and authorization functionalities for Magistrala services.
|
||||
type AuthServiceServer interface {
|
||||
Authorize(context.Context, *AuthZReq) (*AuthZRes, error)
|
||||
Authenticate(context.Context, *AuthNReq) (*AuthNRes, error)
|
||||
mustEmbedUnimplementedAuthServiceServer()
|
||||
}
|
||||
|
||||
// UnimplementedAuthServiceServer must be embedded to have
|
||||
// forward compatible implementations.
|
||||
//
|
||||
// NOTE: this should be embedded by value instead of pointer to avoid a nil
|
||||
// pointer dereference when methods are called.
|
||||
type UnimplementedAuthServiceServer struct{}
|
||||
|
||||
func (UnimplementedAuthServiceServer) Authorize(context.Context, *AuthZReq) (*AuthZRes, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method Authorize not implemented")
|
||||
}
|
||||
func (UnimplementedAuthServiceServer) Authenticate(context.Context, *AuthNReq) (*AuthNRes, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method Authenticate not implemented")
|
||||
}
|
||||
func (UnimplementedAuthServiceServer) mustEmbedUnimplementedAuthServiceServer() {}
|
||||
func (UnimplementedAuthServiceServer) testEmbeddedByValue() {}
|
||||
|
||||
// UnsafeAuthServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to AuthServiceServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeAuthServiceServer interface {
|
||||
mustEmbedUnimplementedAuthServiceServer()
|
||||
}
|
||||
|
||||
func RegisterAuthServiceServer(s grpc.ServiceRegistrar, srv AuthServiceServer) {
|
||||
// If the following call panics, it indicates UnimplementedAuthServiceServer was
|
||||
// embedded by pointer and is nil. This will cause panics if an
|
||||
// unimplemented method is ever invoked, so we test this at initialization
|
||||
// time to prevent it from happening at runtime later due to I/O.
|
||||
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
|
||||
t.testEmbeddedByValue()
|
||||
}
|
||||
s.RegisterService(&AuthService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _AuthService_Authorize_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(AuthZReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(AuthServiceServer).Authorize(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: AuthService_Authorize_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(AuthServiceServer).Authorize(ctx, req.(*AuthZReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _AuthService_Authenticate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(AuthNReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(AuthServiceServer).Authenticate(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: AuthService_Authenticate_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(AuthServiceServer).Authenticate(ctx, req.(*AuthNReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// AuthService_ServiceDesc is the grpc.ServiceDesc for AuthService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var AuthService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "auth.v1.AuthService",
|
||||
HandlerType: (*AuthServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "Authorize",
|
||||
Handler: _AuthService_Authorize_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Authenticate",
|
||||
Handler: _AuthService_Authenticate_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "auth/v1/auth.proto",
|
||||
}
|
||||
@@ -0,0 +1,228 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.11
|
||||
// protoc v7.35.1
|
||||
// source: certs/v1/certs.proto
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
emptypb "google.golang.org/protobuf/types/known/emptypb"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type EntityReq struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
SerialNumber string `protobuf:"bytes,1,opt,name=serial_number,json=serialNumber,proto3" json:"serial_number,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *EntityReq) Reset() {
|
||||
*x = EntityReq{}
|
||||
mi := &file_certs_v1_certs_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *EntityReq) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*EntityReq) ProtoMessage() {}
|
||||
|
||||
func (x *EntityReq) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_certs_v1_certs_proto_msgTypes[0]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use EntityReq.ProtoReflect.Descriptor instead.
|
||||
func (*EntityReq) Descriptor() ([]byte, []int) {
|
||||
return file_certs_v1_certs_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *EntityReq) GetSerialNumber() string {
|
||||
if x != nil {
|
||||
return x.SerialNumber
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type EntityRes struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
EntityId string `protobuf:"bytes,1,opt,name=entity_id,json=entityId,proto3" json:"entity_id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *EntityRes) Reset() {
|
||||
*x = EntityRes{}
|
||||
mi := &file_certs_v1_certs_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *EntityRes) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*EntityRes) ProtoMessage() {}
|
||||
|
||||
func (x *EntityRes) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_certs_v1_certs_proto_msgTypes[1]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use EntityRes.ProtoReflect.Descriptor instead.
|
||||
func (*EntityRes) Descriptor() ([]byte, []int) {
|
||||
return file_certs_v1_certs_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *EntityRes) GetEntityId() string {
|
||||
if x != nil {
|
||||
return x.EntityId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type RevokeReq struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
EntityId string `protobuf:"bytes,1,opt,name=entity_id,json=entityId,proto3" json:"entity_id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *RevokeReq) Reset() {
|
||||
*x = RevokeReq{}
|
||||
mi := &file_certs_v1_certs_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *RevokeReq) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*RevokeReq) ProtoMessage() {}
|
||||
|
||||
func (x *RevokeReq) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_certs_v1_certs_proto_msgTypes[2]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use RevokeReq.ProtoReflect.Descriptor instead.
|
||||
func (*RevokeReq) Descriptor() ([]byte, []int) {
|
||||
return file_certs_v1_certs_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *RevokeReq) GetEntityId() string {
|
||||
if x != nil {
|
||||
return x.EntityId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var File_certs_v1_certs_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_certs_v1_certs_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x14certs/v1/certs.proto\x12\rabsmach.certs\x1a\x1bgoogle/protobuf/empty.proto\"0\n" +
|
||||
"\tEntityReq\x12#\n" +
|
||||
"\rserial_number\x18\x01 \x01(\tR\fserialNumber\"(\n" +
|
||||
"\tEntityRes\x12\x1b\n" +
|
||||
"\tentity_id\x18\x01 \x01(\tR\bentityId\"(\n" +
|
||||
"\tRevokeReq\x12\x1b\n" +
|
||||
"\tentity_id\x18\x01 \x01(\tR\bentityId2\x96\x01\n" +
|
||||
"\fCertsService\x12C\n" +
|
||||
"\vGetEntityID\x12\x18.absmach.certs.EntityReq\x1a\x18.absmach.certs.EntityRes\"\x00\x12A\n" +
|
||||
"\vRevokeCerts\x12\x18.absmach.certs.RevokeReq\x1a\x16.google.protobuf.Empty\"\x00B1Z/github.com/absmach/magistrala/api/grpc/certs/v1b\x06proto3"
|
||||
|
||||
var (
|
||||
file_certs_v1_certs_proto_rawDescOnce sync.Once
|
||||
file_certs_v1_certs_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_certs_v1_certs_proto_rawDescGZIP() []byte {
|
||||
file_certs_v1_certs_proto_rawDescOnce.Do(func() {
|
||||
file_certs_v1_certs_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_certs_v1_certs_proto_rawDesc), len(file_certs_v1_certs_proto_rawDesc)))
|
||||
})
|
||||
return file_certs_v1_certs_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_certs_v1_certs_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
|
||||
var file_certs_v1_certs_proto_goTypes = []any{
|
||||
(*EntityReq)(nil), // 0: absmach.certs.EntityReq
|
||||
(*EntityRes)(nil), // 1: absmach.certs.EntityRes
|
||||
(*RevokeReq)(nil), // 2: absmach.certs.RevokeReq
|
||||
(*emptypb.Empty)(nil), // 3: google.protobuf.Empty
|
||||
}
|
||||
var file_certs_v1_certs_proto_depIdxs = []int32{
|
||||
0, // 0: absmach.certs.CertsService.GetEntityID:input_type -> absmach.certs.EntityReq
|
||||
2, // 1: absmach.certs.CertsService.RevokeCerts:input_type -> absmach.certs.RevokeReq
|
||||
1, // 2: absmach.certs.CertsService.GetEntityID:output_type -> absmach.certs.EntityRes
|
||||
3, // 3: absmach.certs.CertsService.RevokeCerts:output_type -> google.protobuf.Empty
|
||||
2, // [2:4] is the sub-list for method output_type
|
||||
0, // [0:2] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
0, // [0:0] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_certs_v1_certs_proto_init() }
|
||||
func file_certs_v1_certs_proto_init() {
|
||||
if File_certs_v1_certs_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_certs_v1_certs_proto_rawDesc), len(file_certs_v1_certs_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 3,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_certs_v1_certs_proto_goTypes,
|
||||
DependencyIndexes: file_certs_v1_certs_proto_depIdxs,
|
||||
MessageInfos: file_certs_v1_certs_proto_msgTypes,
|
||||
}.Build()
|
||||
File_certs_v1_certs_proto = out.File
|
||||
file_certs_v1_certs_proto_goTypes = nil
|
||||
file_certs_v1_certs_proto_depIdxs = nil
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.6.2
|
||||
// - protoc v7.35.1
|
||||
// source: certs/v1/certs.proto
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
context "context"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
emptypb "google.golang.org/protobuf/types/known/emptypb"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.64.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion9
|
||||
|
||||
const (
|
||||
CertsService_GetEntityID_FullMethodName = "/absmach.certs.CertsService/GetEntityID"
|
||||
CertsService_RevokeCerts_FullMethodName = "/absmach.certs.CertsService/RevokeCerts"
|
||||
)
|
||||
|
||||
// CertsServiceClient is the client API for CertsService service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type CertsServiceClient interface {
|
||||
GetEntityID(ctx context.Context, in *EntityReq, opts ...grpc.CallOption) (*EntityRes, error)
|
||||
RevokeCerts(ctx context.Context, in *RevokeReq, opts ...grpc.CallOption) (*emptypb.Empty, error)
|
||||
}
|
||||
|
||||
type certsServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewCertsServiceClient(cc grpc.ClientConnInterface) CertsServiceClient {
|
||||
return &certsServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *certsServiceClient) GetEntityID(ctx context.Context, in *EntityReq, opts ...grpc.CallOption) (*EntityRes, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(EntityRes)
|
||||
err := c.cc.Invoke(ctx, CertsService_GetEntityID_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *certsServiceClient) RevokeCerts(ctx context.Context, in *RevokeReq, opts ...grpc.CallOption) (*emptypb.Empty, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(emptypb.Empty)
|
||||
err := c.cc.Invoke(ctx, CertsService_RevokeCerts_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// CertsServiceServer is the server API for CertsService service.
|
||||
// All implementations must embed UnimplementedCertsServiceServer
|
||||
// for forward compatibility.
|
||||
type CertsServiceServer interface {
|
||||
GetEntityID(context.Context, *EntityReq) (*EntityRes, error)
|
||||
RevokeCerts(context.Context, *RevokeReq) (*emptypb.Empty, error)
|
||||
mustEmbedUnimplementedCertsServiceServer()
|
||||
}
|
||||
|
||||
// UnimplementedCertsServiceServer must be embedded to have
|
||||
// forward compatible implementations.
|
||||
//
|
||||
// NOTE: this should be embedded by value instead of pointer to avoid a nil
|
||||
// pointer dereference when methods are called.
|
||||
type UnimplementedCertsServiceServer struct{}
|
||||
|
||||
func (UnimplementedCertsServiceServer) GetEntityID(context.Context, *EntityReq) (*EntityRes, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method GetEntityID not implemented")
|
||||
}
|
||||
func (UnimplementedCertsServiceServer) RevokeCerts(context.Context, *RevokeReq) (*emptypb.Empty, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method RevokeCerts not implemented")
|
||||
}
|
||||
func (UnimplementedCertsServiceServer) mustEmbedUnimplementedCertsServiceServer() {}
|
||||
func (UnimplementedCertsServiceServer) testEmbeddedByValue() {}
|
||||
|
||||
// UnsafeCertsServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to CertsServiceServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeCertsServiceServer interface {
|
||||
mustEmbedUnimplementedCertsServiceServer()
|
||||
}
|
||||
|
||||
func RegisterCertsServiceServer(s grpc.ServiceRegistrar, srv CertsServiceServer) {
|
||||
// If the following call panics, it indicates UnimplementedCertsServiceServer was
|
||||
// embedded by pointer and is nil. This will cause panics if an
|
||||
// unimplemented method is ever invoked, so we test this at initialization
|
||||
// time to prevent it from happening at runtime later due to I/O.
|
||||
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
|
||||
t.testEmbeddedByValue()
|
||||
}
|
||||
s.RegisterService(&CertsService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _CertsService_GetEntityID_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(EntityReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(CertsServiceServer).GetEntityID(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: CertsService_GetEntityID_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(CertsServiceServer).GetEntityID(ctx, req.(*EntityReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _CertsService_RevokeCerts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(RevokeReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(CertsServiceServer).RevokeCerts(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: CertsService_RevokeCerts_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(CertsServiceServer).RevokeCerts(ctx, req.(*RevokeReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// CertsService_ServiceDesc is the grpc.ServiceDesc for CertsService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var CertsService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "absmach.certs.CertsService",
|
||||
HandlerType: (*CertsServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "GetEntityID",
|
||||
Handler: _CertsService_GetEntityID_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "RevokeCerts",
|
||||
Handler: _CertsService_RevokeCerts_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "certs/v1/certs.proto",
|
||||
}
|
||||
@@ -0,0 +1,402 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.11
|
||||
// protoc v7.35.1
|
||||
// source: channels/v1/channels.proto
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
v1 "github.com/absmach/magistrala/api/grpc/common/v1"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type RemoveClientConnectionsReq struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
ClientId string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *RemoveClientConnectionsReq) Reset() {
|
||||
*x = RemoveClientConnectionsReq{}
|
||||
mi := &file_channels_v1_channels_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *RemoveClientConnectionsReq) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*RemoveClientConnectionsReq) ProtoMessage() {}
|
||||
|
||||
func (x *RemoveClientConnectionsReq) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_channels_v1_channels_proto_msgTypes[0]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use RemoveClientConnectionsReq.ProtoReflect.Descriptor instead.
|
||||
func (*RemoveClientConnectionsReq) Descriptor() ([]byte, []int) {
|
||||
return file_channels_v1_channels_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *RemoveClientConnectionsReq) GetClientId() string {
|
||||
if x != nil {
|
||||
return x.ClientId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type RemoveClientConnectionsRes struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *RemoveClientConnectionsRes) Reset() {
|
||||
*x = RemoveClientConnectionsRes{}
|
||||
mi := &file_channels_v1_channels_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *RemoveClientConnectionsRes) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*RemoveClientConnectionsRes) ProtoMessage() {}
|
||||
|
||||
func (x *RemoveClientConnectionsRes) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_channels_v1_channels_proto_msgTypes[1]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use RemoveClientConnectionsRes.ProtoReflect.Descriptor instead.
|
||||
func (*RemoveClientConnectionsRes) Descriptor() ([]byte, []int) {
|
||||
return file_channels_v1_channels_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
type UnsetParentGroupFromChannelsReq struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
ParentGroupId string `protobuf:"bytes,1,opt,name=parent_group_id,json=parentGroupId,proto3" json:"parent_group_id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *UnsetParentGroupFromChannelsReq) Reset() {
|
||||
*x = UnsetParentGroupFromChannelsReq{}
|
||||
mi := &file_channels_v1_channels_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *UnsetParentGroupFromChannelsReq) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*UnsetParentGroupFromChannelsReq) ProtoMessage() {}
|
||||
|
||||
func (x *UnsetParentGroupFromChannelsReq) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_channels_v1_channels_proto_msgTypes[2]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use UnsetParentGroupFromChannelsReq.ProtoReflect.Descriptor instead.
|
||||
func (*UnsetParentGroupFromChannelsReq) Descriptor() ([]byte, []int) {
|
||||
return file_channels_v1_channels_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *UnsetParentGroupFromChannelsReq) GetParentGroupId() string {
|
||||
if x != nil {
|
||||
return x.ParentGroupId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type UnsetParentGroupFromChannelsRes struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *UnsetParentGroupFromChannelsRes) Reset() {
|
||||
*x = UnsetParentGroupFromChannelsRes{}
|
||||
mi := &file_channels_v1_channels_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *UnsetParentGroupFromChannelsRes) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*UnsetParentGroupFromChannelsRes) ProtoMessage() {}
|
||||
|
||||
func (x *UnsetParentGroupFromChannelsRes) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_channels_v1_channels_proto_msgTypes[3]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use UnsetParentGroupFromChannelsRes.ProtoReflect.Descriptor instead.
|
||||
func (*UnsetParentGroupFromChannelsRes) Descriptor() ([]byte, []int) {
|
||||
return file_channels_v1_channels_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
type AuthzReq struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
DomainId string `protobuf:"bytes,1,opt,name=domain_id,json=domainId,proto3" json:"domain_id,omitempty"`
|
||||
ClientId string `protobuf:"bytes,2,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"`
|
||||
ClientType string `protobuf:"bytes,3,opt,name=client_type,json=clientType,proto3" json:"client_type,omitempty"`
|
||||
ChannelId string `protobuf:"bytes,4,opt,name=channel_id,json=channelId,proto3" json:"channel_id,omitempty"`
|
||||
Type uint32 `protobuf:"varint,5,opt,name=type,proto3" json:"type,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *AuthzReq) Reset() {
|
||||
*x = AuthzReq{}
|
||||
mi := &file_channels_v1_channels_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *AuthzReq) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*AuthzReq) ProtoMessage() {}
|
||||
|
||||
func (x *AuthzReq) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_channels_v1_channels_proto_msgTypes[4]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use AuthzReq.ProtoReflect.Descriptor instead.
|
||||
func (*AuthzReq) Descriptor() ([]byte, []int) {
|
||||
return file_channels_v1_channels_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *AuthzReq) GetDomainId() string {
|
||||
if x != nil {
|
||||
return x.DomainId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AuthzReq) GetClientId() string {
|
||||
if x != nil {
|
||||
return x.ClientId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AuthzReq) GetClientType() string {
|
||||
if x != nil {
|
||||
return x.ClientType
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AuthzReq) GetChannelId() string {
|
||||
if x != nil {
|
||||
return x.ChannelId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AuthzReq) GetType() uint32 {
|
||||
if x != nil {
|
||||
return x.Type
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type AuthzRes struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Authorized bool `protobuf:"varint,1,opt,name=authorized,proto3" json:"authorized,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *AuthzRes) Reset() {
|
||||
*x = AuthzRes{}
|
||||
mi := &file_channels_v1_channels_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *AuthzRes) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*AuthzRes) ProtoMessage() {}
|
||||
|
||||
func (x *AuthzRes) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_channels_v1_channels_proto_msgTypes[5]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use AuthzRes.ProtoReflect.Descriptor instead.
|
||||
func (*AuthzRes) Descriptor() ([]byte, []int) {
|
||||
return file_channels_v1_channels_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
func (x *AuthzRes) GetAuthorized() bool {
|
||||
if x != nil {
|
||||
return x.Authorized
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var File_channels_v1_channels_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_channels_v1_channels_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x1achannels/v1/channels.proto\x12\vchannels.v1\x1a\x16common/v1/common.proto\"9\n" +
|
||||
"\x1aRemoveClientConnectionsReq\x12\x1b\n" +
|
||||
"\tclient_id\x18\x01 \x01(\tR\bclientId\"\x1c\n" +
|
||||
"\x1aRemoveClientConnectionsRes\"I\n" +
|
||||
"\x1fUnsetParentGroupFromChannelsReq\x12&\n" +
|
||||
"\x0fparent_group_id\x18\x01 \x01(\tR\rparentGroupId\"!\n" +
|
||||
"\x1fUnsetParentGroupFromChannelsRes\"\x98\x01\n" +
|
||||
"\bAuthzReq\x12\x1b\n" +
|
||||
"\tdomain_id\x18\x01 \x01(\tR\bdomainId\x12\x1b\n" +
|
||||
"\tclient_id\x18\x02 \x01(\tR\bclientId\x12\x1f\n" +
|
||||
"\vclient_type\x18\x03 \x01(\tR\n" +
|
||||
"clientType\x12\x1d\n" +
|
||||
"\n" +
|
||||
"channel_id\x18\x04 \x01(\tR\tchannelId\x12\x12\n" +
|
||||
"\x04type\x18\x05 \x01(\rR\x04type\"*\n" +
|
||||
"\bAuthzRes\x12\x1e\n" +
|
||||
"\n" +
|
||||
"authorized\x18\x01 \x01(\bR\n" +
|
||||
"authorized2\xe1\x03\n" +
|
||||
"\x0fChannelsService\x12;\n" +
|
||||
"\tAuthorize\x12\x15.channels.v1.AuthzReq\x1a\x15.channels.v1.AuthzRes\"\x00\x12m\n" +
|
||||
"\x17RemoveClientConnections\x12'.channels.v1.RemoveClientConnectionsReq\x1a'.channels.v1.RemoveClientConnectionsRes\"\x00\x12|\n" +
|
||||
"\x1cUnsetParentGroupFromChannels\x12,.channels.v1.UnsetParentGroupFromChannelsReq\x1a,.channels.v1.UnsetParentGroupFromChannelsRes\"\x00\x12N\n" +
|
||||
"\x0eRetrieveEntity\x12\x1c.common.v1.RetrieveEntityReq\x1a\x1c.common.v1.RetrieveEntityRes\"\x00\x12T\n" +
|
||||
"\x11RetrieveIDByRoute\x12\x1f.common.v1.RetrieveIDByRouteReq\x1a\x1c.common.v1.RetrieveEntityRes\"\x00B4Z2github.com/absmach/magistrala/api/grpc/channels/v1b\x06proto3"
|
||||
|
||||
var (
|
||||
file_channels_v1_channels_proto_rawDescOnce sync.Once
|
||||
file_channels_v1_channels_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_channels_v1_channels_proto_rawDescGZIP() []byte {
|
||||
file_channels_v1_channels_proto_rawDescOnce.Do(func() {
|
||||
file_channels_v1_channels_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_channels_v1_channels_proto_rawDesc), len(file_channels_v1_channels_proto_rawDesc)))
|
||||
})
|
||||
return file_channels_v1_channels_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_channels_v1_channels_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
|
||||
var file_channels_v1_channels_proto_goTypes = []any{
|
||||
(*RemoveClientConnectionsReq)(nil), // 0: channels.v1.RemoveClientConnectionsReq
|
||||
(*RemoveClientConnectionsRes)(nil), // 1: channels.v1.RemoveClientConnectionsRes
|
||||
(*UnsetParentGroupFromChannelsReq)(nil), // 2: channels.v1.UnsetParentGroupFromChannelsReq
|
||||
(*UnsetParentGroupFromChannelsRes)(nil), // 3: channels.v1.UnsetParentGroupFromChannelsRes
|
||||
(*AuthzReq)(nil), // 4: channels.v1.AuthzReq
|
||||
(*AuthzRes)(nil), // 5: channels.v1.AuthzRes
|
||||
(*v1.RetrieveEntityReq)(nil), // 6: common.v1.RetrieveEntityReq
|
||||
(*v1.RetrieveIDByRouteReq)(nil), // 7: common.v1.RetrieveIDByRouteReq
|
||||
(*v1.RetrieveEntityRes)(nil), // 8: common.v1.RetrieveEntityRes
|
||||
}
|
||||
var file_channels_v1_channels_proto_depIdxs = []int32{
|
||||
4, // 0: channels.v1.ChannelsService.Authorize:input_type -> channels.v1.AuthzReq
|
||||
0, // 1: channels.v1.ChannelsService.RemoveClientConnections:input_type -> channels.v1.RemoveClientConnectionsReq
|
||||
2, // 2: channels.v1.ChannelsService.UnsetParentGroupFromChannels:input_type -> channels.v1.UnsetParentGroupFromChannelsReq
|
||||
6, // 3: channels.v1.ChannelsService.RetrieveEntity:input_type -> common.v1.RetrieveEntityReq
|
||||
7, // 4: channels.v1.ChannelsService.RetrieveIDByRoute:input_type -> common.v1.RetrieveIDByRouteReq
|
||||
5, // 5: channels.v1.ChannelsService.Authorize:output_type -> channels.v1.AuthzRes
|
||||
1, // 6: channels.v1.ChannelsService.RemoveClientConnections:output_type -> channels.v1.RemoveClientConnectionsRes
|
||||
3, // 7: channels.v1.ChannelsService.UnsetParentGroupFromChannels:output_type -> channels.v1.UnsetParentGroupFromChannelsRes
|
||||
8, // 8: channels.v1.ChannelsService.RetrieveEntity:output_type -> common.v1.RetrieveEntityRes
|
||||
8, // 9: channels.v1.ChannelsService.RetrieveIDByRoute:output_type -> common.v1.RetrieveEntityRes
|
||||
5, // [5:10] is the sub-list for method output_type
|
||||
0, // [0:5] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
0, // [0:0] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_channels_v1_channels_proto_init() }
|
||||
func file_channels_v1_channels_proto_init() {
|
||||
if File_channels_v1_channels_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_channels_v1_channels_proto_rawDesc), len(file_channels_v1_channels_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 6,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_channels_v1_channels_proto_goTypes,
|
||||
DependencyIndexes: file_channels_v1_channels_proto_depIdxs,
|
||||
MessageInfos: file_channels_v1_channels_proto_msgTypes,
|
||||
}.Build()
|
||||
File_channels_v1_channels_proto = out.File
|
||||
file_channels_v1_channels_proto_goTypes = nil
|
||||
file_channels_v1_channels_proto_depIdxs = nil
|
||||
}
|
||||
@@ -0,0 +1,277 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.6.2
|
||||
// - protoc v7.35.1
|
||||
// source: channels/v1/channels.proto
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
context "context"
|
||||
v1 "github.com/absmach/magistrala/api/grpc/common/v1"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.64.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion9
|
||||
|
||||
const (
|
||||
ChannelsService_Authorize_FullMethodName = "/channels.v1.ChannelsService/Authorize"
|
||||
ChannelsService_RemoveClientConnections_FullMethodName = "/channels.v1.ChannelsService/RemoveClientConnections"
|
||||
ChannelsService_UnsetParentGroupFromChannels_FullMethodName = "/channels.v1.ChannelsService/UnsetParentGroupFromChannels"
|
||||
ChannelsService_RetrieveEntity_FullMethodName = "/channels.v1.ChannelsService/RetrieveEntity"
|
||||
ChannelsService_RetrieveIDByRoute_FullMethodName = "/channels.v1.ChannelsService/RetrieveIDByRoute"
|
||||
)
|
||||
|
||||
// ChannelsServiceClient is the client API for ChannelsService service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type ChannelsServiceClient interface {
|
||||
Authorize(ctx context.Context, in *AuthzReq, opts ...grpc.CallOption) (*AuthzRes, error)
|
||||
RemoveClientConnections(ctx context.Context, in *RemoveClientConnectionsReq, opts ...grpc.CallOption) (*RemoveClientConnectionsRes, error)
|
||||
UnsetParentGroupFromChannels(ctx context.Context, in *UnsetParentGroupFromChannelsReq, opts ...grpc.CallOption) (*UnsetParentGroupFromChannelsRes, error)
|
||||
RetrieveEntity(ctx context.Context, in *v1.RetrieveEntityReq, opts ...grpc.CallOption) (*v1.RetrieveEntityRes, error)
|
||||
RetrieveIDByRoute(ctx context.Context, in *v1.RetrieveIDByRouteReq, opts ...grpc.CallOption) (*v1.RetrieveEntityRes, error)
|
||||
}
|
||||
|
||||
type channelsServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewChannelsServiceClient(cc grpc.ClientConnInterface) ChannelsServiceClient {
|
||||
return &channelsServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *channelsServiceClient) Authorize(ctx context.Context, in *AuthzReq, opts ...grpc.CallOption) (*AuthzRes, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(AuthzRes)
|
||||
err := c.cc.Invoke(ctx, ChannelsService_Authorize_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *channelsServiceClient) RemoveClientConnections(ctx context.Context, in *RemoveClientConnectionsReq, opts ...grpc.CallOption) (*RemoveClientConnectionsRes, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(RemoveClientConnectionsRes)
|
||||
err := c.cc.Invoke(ctx, ChannelsService_RemoveClientConnections_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *channelsServiceClient) UnsetParentGroupFromChannels(ctx context.Context, in *UnsetParentGroupFromChannelsReq, opts ...grpc.CallOption) (*UnsetParentGroupFromChannelsRes, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(UnsetParentGroupFromChannelsRes)
|
||||
err := c.cc.Invoke(ctx, ChannelsService_UnsetParentGroupFromChannels_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *channelsServiceClient) RetrieveEntity(ctx context.Context, in *v1.RetrieveEntityReq, opts ...grpc.CallOption) (*v1.RetrieveEntityRes, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(v1.RetrieveEntityRes)
|
||||
err := c.cc.Invoke(ctx, ChannelsService_RetrieveEntity_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *channelsServiceClient) RetrieveIDByRoute(ctx context.Context, in *v1.RetrieveIDByRouteReq, opts ...grpc.CallOption) (*v1.RetrieveEntityRes, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(v1.RetrieveEntityRes)
|
||||
err := c.cc.Invoke(ctx, ChannelsService_RetrieveIDByRoute_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// ChannelsServiceServer is the server API for ChannelsService service.
|
||||
// All implementations must embed UnimplementedChannelsServiceServer
|
||||
// for forward compatibility.
|
||||
type ChannelsServiceServer interface {
|
||||
Authorize(context.Context, *AuthzReq) (*AuthzRes, error)
|
||||
RemoveClientConnections(context.Context, *RemoveClientConnectionsReq) (*RemoveClientConnectionsRes, error)
|
||||
UnsetParentGroupFromChannels(context.Context, *UnsetParentGroupFromChannelsReq) (*UnsetParentGroupFromChannelsRes, error)
|
||||
RetrieveEntity(context.Context, *v1.RetrieveEntityReq) (*v1.RetrieveEntityRes, error)
|
||||
RetrieveIDByRoute(context.Context, *v1.RetrieveIDByRouteReq) (*v1.RetrieveEntityRes, error)
|
||||
mustEmbedUnimplementedChannelsServiceServer()
|
||||
}
|
||||
|
||||
// UnimplementedChannelsServiceServer must be embedded to have
|
||||
// forward compatible implementations.
|
||||
//
|
||||
// NOTE: this should be embedded by value instead of pointer to avoid a nil
|
||||
// pointer dereference when methods are called.
|
||||
type UnimplementedChannelsServiceServer struct{}
|
||||
|
||||
func (UnimplementedChannelsServiceServer) Authorize(context.Context, *AuthzReq) (*AuthzRes, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method Authorize not implemented")
|
||||
}
|
||||
func (UnimplementedChannelsServiceServer) RemoveClientConnections(context.Context, *RemoveClientConnectionsReq) (*RemoveClientConnectionsRes, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method RemoveClientConnections not implemented")
|
||||
}
|
||||
func (UnimplementedChannelsServiceServer) UnsetParentGroupFromChannels(context.Context, *UnsetParentGroupFromChannelsReq) (*UnsetParentGroupFromChannelsRes, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method UnsetParentGroupFromChannels not implemented")
|
||||
}
|
||||
func (UnimplementedChannelsServiceServer) RetrieveEntity(context.Context, *v1.RetrieveEntityReq) (*v1.RetrieveEntityRes, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method RetrieveEntity not implemented")
|
||||
}
|
||||
func (UnimplementedChannelsServiceServer) RetrieveIDByRoute(context.Context, *v1.RetrieveIDByRouteReq) (*v1.RetrieveEntityRes, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method RetrieveIDByRoute not implemented")
|
||||
}
|
||||
func (UnimplementedChannelsServiceServer) mustEmbedUnimplementedChannelsServiceServer() {}
|
||||
func (UnimplementedChannelsServiceServer) testEmbeddedByValue() {}
|
||||
|
||||
// UnsafeChannelsServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to ChannelsServiceServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeChannelsServiceServer interface {
|
||||
mustEmbedUnimplementedChannelsServiceServer()
|
||||
}
|
||||
|
||||
func RegisterChannelsServiceServer(s grpc.ServiceRegistrar, srv ChannelsServiceServer) {
|
||||
// If the following call panics, it indicates UnimplementedChannelsServiceServer was
|
||||
// embedded by pointer and is nil. This will cause panics if an
|
||||
// unimplemented method is ever invoked, so we test this at initialization
|
||||
// time to prevent it from happening at runtime later due to I/O.
|
||||
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
|
||||
t.testEmbeddedByValue()
|
||||
}
|
||||
s.RegisterService(&ChannelsService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _ChannelsService_Authorize_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(AuthzReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ChannelsServiceServer).Authorize(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ChannelsService_Authorize_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ChannelsServiceServer).Authorize(ctx, req.(*AuthzReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ChannelsService_RemoveClientConnections_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(RemoveClientConnectionsReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ChannelsServiceServer).RemoveClientConnections(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ChannelsService_RemoveClientConnections_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ChannelsServiceServer).RemoveClientConnections(ctx, req.(*RemoveClientConnectionsReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ChannelsService_UnsetParentGroupFromChannels_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(UnsetParentGroupFromChannelsReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ChannelsServiceServer).UnsetParentGroupFromChannels(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ChannelsService_UnsetParentGroupFromChannels_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ChannelsServiceServer).UnsetParentGroupFromChannels(ctx, req.(*UnsetParentGroupFromChannelsReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ChannelsService_RetrieveEntity_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(v1.RetrieveEntityReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ChannelsServiceServer).RetrieveEntity(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ChannelsService_RetrieveEntity_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ChannelsServiceServer).RetrieveEntity(ctx, req.(*v1.RetrieveEntityReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ChannelsService_RetrieveIDByRoute_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(v1.RetrieveIDByRouteReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ChannelsServiceServer).RetrieveIDByRoute(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ChannelsService_RetrieveIDByRoute_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ChannelsServiceServer).RetrieveIDByRoute(ctx, req.(*v1.RetrieveIDByRouteReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// ChannelsService_ServiceDesc is the grpc.ServiceDesc for ChannelsService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var ChannelsService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "channels.v1.ChannelsService",
|
||||
HandlerType: (*ChannelsServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "Authorize",
|
||||
Handler: _ChannelsService_Authorize_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "RemoveClientConnections",
|
||||
Handler: _ChannelsService_RemoveClientConnections_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "UnsetParentGroupFromChannels",
|
||||
Handler: _ChannelsService_UnsetParentGroupFromChannels_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "RetrieveEntity",
|
||||
Handler: _ChannelsService_RetrieveEntity_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "RetrieveIDByRoute",
|
||||
Handler: _ChannelsService_RetrieveIDByRoute_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "channels/v1/channels.proto",
|
||||
}
|
||||
@@ -0,0 +1,384 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.11
|
||||
// protoc v7.35.1
|
||||
// source: clients/v1/clients.proto
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
v1 "github.com/absmach/magistrala/api/grpc/common/v1"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type AuthnReq struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *AuthnReq) Reset() {
|
||||
*x = AuthnReq{}
|
||||
mi := &file_clients_v1_clients_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *AuthnReq) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*AuthnReq) ProtoMessage() {}
|
||||
|
||||
func (x *AuthnReq) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_clients_v1_clients_proto_msgTypes[0]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use AuthnReq.ProtoReflect.Descriptor instead.
|
||||
func (*AuthnReq) Descriptor() ([]byte, []int) {
|
||||
return file_clients_v1_clients_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *AuthnReq) GetToken() string {
|
||||
if x != nil {
|
||||
return x.Token
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type AuthnRes struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Authenticated bool `protobuf:"varint,1,opt,name=authenticated,proto3" json:"authenticated,omitempty"`
|
||||
Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *AuthnRes) Reset() {
|
||||
*x = AuthnRes{}
|
||||
mi := &file_clients_v1_clients_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *AuthnRes) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*AuthnRes) ProtoMessage() {}
|
||||
|
||||
func (x *AuthnRes) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_clients_v1_clients_proto_msgTypes[1]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use AuthnRes.ProtoReflect.Descriptor instead.
|
||||
func (*AuthnRes) Descriptor() ([]byte, []int) {
|
||||
return file_clients_v1_clients_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *AuthnRes) GetAuthenticated() bool {
|
||||
if x != nil {
|
||||
return x.Authenticated
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *AuthnRes) GetId() string {
|
||||
if x != nil {
|
||||
return x.Id
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type RemoveChannelConnectionsReq struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
ChannelId string `protobuf:"bytes,1,opt,name=channel_id,json=channelId,proto3" json:"channel_id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *RemoveChannelConnectionsReq) Reset() {
|
||||
*x = RemoveChannelConnectionsReq{}
|
||||
mi := &file_clients_v1_clients_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *RemoveChannelConnectionsReq) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*RemoveChannelConnectionsReq) ProtoMessage() {}
|
||||
|
||||
func (x *RemoveChannelConnectionsReq) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_clients_v1_clients_proto_msgTypes[2]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use RemoveChannelConnectionsReq.ProtoReflect.Descriptor instead.
|
||||
func (*RemoveChannelConnectionsReq) Descriptor() ([]byte, []int) {
|
||||
return file_clients_v1_clients_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *RemoveChannelConnectionsReq) GetChannelId() string {
|
||||
if x != nil {
|
||||
return x.ChannelId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type RemoveChannelConnectionsRes struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *RemoveChannelConnectionsRes) Reset() {
|
||||
*x = RemoveChannelConnectionsRes{}
|
||||
mi := &file_clients_v1_clients_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *RemoveChannelConnectionsRes) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*RemoveChannelConnectionsRes) ProtoMessage() {}
|
||||
|
||||
func (x *RemoveChannelConnectionsRes) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_clients_v1_clients_proto_msgTypes[3]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use RemoveChannelConnectionsRes.ProtoReflect.Descriptor instead.
|
||||
func (*RemoveChannelConnectionsRes) Descriptor() ([]byte, []int) {
|
||||
return file_clients_v1_clients_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
type UnsetParentGroupFromClientReq struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
ParentGroupId string `protobuf:"bytes,1,opt,name=parent_group_id,json=parentGroupId,proto3" json:"parent_group_id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *UnsetParentGroupFromClientReq) Reset() {
|
||||
*x = UnsetParentGroupFromClientReq{}
|
||||
mi := &file_clients_v1_clients_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *UnsetParentGroupFromClientReq) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*UnsetParentGroupFromClientReq) ProtoMessage() {}
|
||||
|
||||
func (x *UnsetParentGroupFromClientReq) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_clients_v1_clients_proto_msgTypes[4]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use UnsetParentGroupFromClientReq.ProtoReflect.Descriptor instead.
|
||||
func (*UnsetParentGroupFromClientReq) Descriptor() ([]byte, []int) {
|
||||
return file_clients_v1_clients_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *UnsetParentGroupFromClientReq) GetParentGroupId() string {
|
||||
if x != nil {
|
||||
return x.ParentGroupId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type UnsetParentGroupFromClientRes struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *UnsetParentGroupFromClientRes) Reset() {
|
||||
*x = UnsetParentGroupFromClientRes{}
|
||||
mi := &file_clients_v1_clients_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *UnsetParentGroupFromClientRes) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*UnsetParentGroupFromClientRes) ProtoMessage() {}
|
||||
|
||||
func (x *UnsetParentGroupFromClientRes) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_clients_v1_clients_proto_msgTypes[5]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use UnsetParentGroupFromClientRes.ProtoReflect.Descriptor instead.
|
||||
func (*UnsetParentGroupFromClientRes) Descriptor() ([]byte, []int) {
|
||||
return file_clients_v1_clients_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
var File_clients_v1_clients_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_clients_v1_clients_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x18clients/v1/clients.proto\x12\n" +
|
||||
"clients.v1\x1a\x16common/v1/common.proto\" \n" +
|
||||
"\bAuthnReq\x12\x14\n" +
|
||||
"\x05token\x18\x01 \x01(\tR\x05token\"@\n" +
|
||||
"\bAuthnRes\x12$\n" +
|
||||
"\rauthenticated\x18\x01 \x01(\bR\rauthenticated\x12\x0e\n" +
|
||||
"\x02id\x18\x02 \x01(\tR\x02id\"<\n" +
|
||||
"\x1bRemoveChannelConnectionsReq\x12\x1d\n" +
|
||||
"\n" +
|
||||
"channel_id\x18\x01 \x01(\tR\tchannelId\"\x1d\n" +
|
||||
"\x1bRemoveChannelConnectionsRes\"G\n" +
|
||||
"\x1dUnsetParentGroupFromClientReq\x12&\n" +
|
||||
"\x0fparent_group_id\x18\x01 \x01(\tR\rparentGroupId\"\x1f\n" +
|
||||
"\x1dUnsetParentGroupFromClientRes2\x83\x05\n" +
|
||||
"\x0eClientsService\x12<\n" +
|
||||
"\fAuthenticate\x12\x14.clients.v1.AuthnReq\x1a\x14.clients.v1.AuthnRes\"\x00\x12N\n" +
|
||||
"\x0eRetrieveEntity\x12\x1c.common.v1.RetrieveEntityReq\x1a\x1c.common.v1.RetrieveEntityRes\"\x00\x12T\n" +
|
||||
"\x10RetrieveEntities\x12\x1e.common.v1.RetrieveEntitiesReq\x1a\x1e.common.v1.RetrieveEntitiesRes\"\x00\x12N\n" +
|
||||
"\x0eAddConnections\x12\x1c.common.v1.AddConnectionsReq\x1a\x1c.common.v1.AddConnectionsRes\"\x00\x12W\n" +
|
||||
"\x11RemoveConnections\x12\x1f.common.v1.RemoveConnectionsReq\x1a\x1f.common.v1.RemoveConnectionsRes\"\x00\x12n\n" +
|
||||
"\x18RemoveChannelConnections\x12'.clients.v1.RemoveChannelConnectionsReq\x1a'.clients.v1.RemoveChannelConnectionsRes\"\x00\x12t\n" +
|
||||
"\x1aUnsetParentGroupFromClient\x12).clients.v1.UnsetParentGroupFromClientReq\x1a).clients.v1.UnsetParentGroupFromClientRes\"\x00B3Z1github.com/absmach/magistrala/api/grpc/clients/v1b\x06proto3"
|
||||
|
||||
var (
|
||||
file_clients_v1_clients_proto_rawDescOnce sync.Once
|
||||
file_clients_v1_clients_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_clients_v1_clients_proto_rawDescGZIP() []byte {
|
||||
file_clients_v1_clients_proto_rawDescOnce.Do(func() {
|
||||
file_clients_v1_clients_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_clients_v1_clients_proto_rawDesc), len(file_clients_v1_clients_proto_rawDesc)))
|
||||
})
|
||||
return file_clients_v1_clients_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_clients_v1_clients_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
|
||||
var file_clients_v1_clients_proto_goTypes = []any{
|
||||
(*AuthnReq)(nil), // 0: clients.v1.AuthnReq
|
||||
(*AuthnRes)(nil), // 1: clients.v1.AuthnRes
|
||||
(*RemoveChannelConnectionsReq)(nil), // 2: clients.v1.RemoveChannelConnectionsReq
|
||||
(*RemoveChannelConnectionsRes)(nil), // 3: clients.v1.RemoveChannelConnectionsRes
|
||||
(*UnsetParentGroupFromClientReq)(nil), // 4: clients.v1.UnsetParentGroupFromClientReq
|
||||
(*UnsetParentGroupFromClientRes)(nil), // 5: clients.v1.UnsetParentGroupFromClientRes
|
||||
(*v1.RetrieveEntityReq)(nil), // 6: common.v1.RetrieveEntityReq
|
||||
(*v1.RetrieveEntitiesReq)(nil), // 7: common.v1.RetrieveEntitiesReq
|
||||
(*v1.AddConnectionsReq)(nil), // 8: common.v1.AddConnectionsReq
|
||||
(*v1.RemoveConnectionsReq)(nil), // 9: common.v1.RemoveConnectionsReq
|
||||
(*v1.RetrieveEntityRes)(nil), // 10: common.v1.RetrieveEntityRes
|
||||
(*v1.RetrieveEntitiesRes)(nil), // 11: common.v1.RetrieveEntitiesRes
|
||||
(*v1.AddConnectionsRes)(nil), // 12: common.v1.AddConnectionsRes
|
||||
(*v1.RemoveConnectionsRes)(nil), // 13: common.v1.RemoveConnectionsRes
|
||||
}
|
||||
var file_clients_v1_clients_proto_depIdxs = []int32{
|
||||
0, // 0: clients.v1.ClientsService.Authenticate:input_type -> clients.v1.AuthnReq
|
||||
6, // 1: clients.v1.ClientsService.RetrieveEntity:input_type -> common.v1.RetrieveEntityReq
|
||||
7, // 2: clients.v1.ClientsService.RetrieveEntities:input_type -> common.v1.RetrieveEntitiesReq
|
||||
8, // 3: clients.v1.ClientsService.AddConnections:input_type -> common.v1.AddConnectionsReq
|
||||
9, // 4: clients.v1.ClientsService.RemoveConnections:input_type -> common.v1.RemoveConnectionsReq
|
||||
2, // 5: clients.v1.ClientsService.RemoveChannelConnections:input_type -> clients.v1.RemoveChannelConnectionsReq
|
||||
4, // 6: clients.v1.ClientsService.UnsetParentGroupFromClient:input_type -> clients.v1.UnsetParentGroupFromClientReq
|
||||
1, // 7: clients.v1.ClientsService.Authenticate:output_type -> clients.v1.AuthnRes
|
||||
10, // 8: clients.v1.ClientsService.RetrieveEntity:output_type -> common.v1.RetrieveEntityRes
|
||||
11, // 9: clients.v1.ClientsService.RetrieveEntities:output_type -> common.v1.RetrieveEntitiesRes
|
||||
12, // 10: clients.v1.ClientsService.AddConnections:output_type -> common.v1.AddConnectionsRes
|
||||
13, // 11: clients.v1.ClientsService.RemoveConnections:output_type -> common.v1.RemoveConnectionsRes
|
||||
3, // 12: clients.v1.ClientsService.RemoveChannelConnections:output_type -> clients.v1.RemoveChannelConnectionsRes
|
||||
5, // 13: clients.v1.ClientsService.UnsetParentGroupFromClient:output_type -> clients.v1.UnsetParentGroupFromClientRes
|
||||
7, // [7:14] is the sub-list for method output_type
|
||||
0, // [0:7] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
0, // [0:0] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_clients_v1_clients_proto_init() }
|
||||
func file_clients_v1_clients_proto_init() {
|
||||
if File_clients_v1_clients_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_clients_v1_clients_proto_rawDesc), len(file_clients_v1_clients_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 6,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_clients_v1_clients_proto_goTypes,
|
||||
DependencyIndexes: file_clients_v1_clients_proto_depIdxs,
|
||||
MessageInfos: file_clients_v1_clients_proto_msgTypes,
|
||||
}.Build()
|
||||
File_clients_v1_clients_proto = out.File
|
||||
file_clients_v1_clients_proto_goTypes = nil
|
||||
file_clients_v1_clients_proto_depIdxs = nil
|
||||
}
|
||||
@@ -0,0 +1,361 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.6.2
|
||||
// - protoc v7.35.1
|
||||
// source: clients/v1/clients.proto
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
context "context"
|
||||
v1 "github.com/absmach/magistrala/api/grpc/common/v1"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.64.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion9
|
||||
|
||||
const (
|
||||
ClientsService_Authenticate_FullMethodName = "/clients.v1.ClientsService/Authenticate"
|
||||
ClientsService_RetrieveEntity_FullMethodName = "/clients.v1.ClientsService/RetrieveEntity"
|
||||
ClientsService_RetrieveEntities_FullMethodName = "/clients.v1.ClientsService/RetrieveEntities"
|
||||
ClientsService_AddConnections_FullMethodName = "/clients.v1.ClientsService/AddConnections"
|
||||
ClientsService_RemoveConnections_FullMethodName = "/clients.v1.ClientsService/RemoveConnections"
|
||||
ClientsService_RemoveChannelConnections_FullMethodName = "/clients.v1.ClientsService/RemoveChannelConnections"
|
||||
ClientsService_UnsetParentGroupFromClient_FullMethodName = "/clients.v1.ClientsService/UnsetParentGroupFromClient"
|
||||
)
|
||||
|
||||
// ClientsServiceClient is the client API for ClientsService service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
//
|
||||
// ClientsService is a service that provides clients
|
||||
// authorization functionalities for Magistrala services.
|
||||
type ClientsServiceClient interface {
|
||||
// Authorize checks if the client is authorized to perform
|
||||
Authenticate(ctx context.Context, in *AuthnReq, opts ...grpc.CallOption) (*AuthnRes, error)
|
||||
RetrieveEntity(ctx context.Context, in *v1.RetrieveEntityReq, opts ...grpc.CallOption) (*v1.RetrieveEntityRes, error)
|
||||
RetrieveEntities(ctx context.Context, in *v1.RetrieveEntitiesReq, opts ...grpc.CallOption) (*v1.RetrieveEntitiesRes, error)
|
||||
AddConnections(ctx context.Context, in *v1.AddConnectionsReq, opts ...grpc.CallOption) (*v1.AddConnectionsRes, error)
|
||||
RemoveConnections(ctx context.Context, in *v1.RemoveConnectionsReq, opts ...grpc.CallOption) (*v1.RemoveConnectionsRes, error)
|
||||
RemoveChannelConnections(ctx context.Context, in *RemoveChannelConnectionsReq, opts ...grpc.CallOption) (*RemoveChannelConnectionsRes, error)
|
||||
UnsetParentGroupFromClient(ctx context.Context, in *UnsetParentGroupFromClientReq, opts ...grpc.CallOption) (*UnsetParentGroupFromClientRes, error)
|
||||
}
|
||||
|
||||
type clientsServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewClientsServiceClient(cc grpc.ClientConnInterface) ClientsServiceClient {
|
||||
return &clientsServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *clientsServiceClient) Authenticate(ctx context.Context, in *AuthnReq, opts ...grpc.CallOption) (*AuthnRes, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(AuthnRes)
|
||||
err := c.cc.Invoke(ctx, ClientsService_Authenticate_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *clientsServiceClient) RetrieveEntity(ctx context.Context, in *v1.RetrieveEntityReq, opts ...grpc.CallOption) (*v1.RetrieveEntityRes, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(v1.RetrieveEntityRes)
|
||||
err := c.cc.Invoke(ctx, ClientsService_RetrieveEntity_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *clientsServiceClient) RetrieveEntities(ctx context.Context, in *v1.RetrieveEntitiesReq, opts ...grpc.CallOption) (*v1.RetrieveEntitiesRes, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(v1.RetrieveEntitiesRes)
|
||||
err := c.cc.Invoke(ctx, ClientsService_RetrieveEntities_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *clientsServiceClient) AddConnections(ctx context.Context, in *v1.AddConnectionsReq, opts ...grpc.CallOption) (*v1.AddConnectionsRes, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(v1.AddConnectionsRes)
|
||||
err := c.cc.Invoke(ctx, ClientsService_AddConnections_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *clientsServiceClient) RemoveConnections(ctx context.Context, in *v1.RemoveConnectionsReq, opts ...grpc.CallOption) (*v1.RemoveConnectionsRes, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(v1.RemoveConnectionsRes)
|
||||
err := c.cc.Invoke(ctx, ClientsService_RemoveConnections_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *clientsServiceClient) RemoveChannelConnections(ctx context.Context, in *RemoveChannelConnectionsReq, opts ...grpc.CallOption) (*RemoveChannelConnectionsRes, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(RemoveChannelConnectionsRes)
|
||||
err := c.cc.Invoke(ctx, ClientsService_RemoveChannelConnections_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *clientsServiceClient) UnsetParentGroupFromClient(ctx context.Context, in *UnsetParentGroupFromClientReq, opts ...grpc.CallOption) (*UnsetParentGroupFromClientRes, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(UnsetParentGroupFromClientRes)
|
||||
err := c.cc.Invoke(ctx, ClientsService_UnsetParentGroupFromClient_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// ClientsServiceServer is the server API for ClientsService service.
|
||||
// All implementations must embed UnimplementedClientsServiceServer
|
||||
// for forward compatibility.
|
||||
//
|
||||
// ClientsService is a service that provides clients
|
||||
// authorization functionalities for Magistrala services.
|
||||
type ClientsServiceServer interface {
|
||||
// Authorize checks if the client is authorized to perform
|
||||
Authenticate(context.Context, *AuthnReq) (*AuthnRes, error)
|
||||
RetrieveEntity(context.Context, *v1.RetrieveEntityReq) (*v1.RetrieveEntityRes, error)
|
||||
RetrieveEntities(context.Context, *v1.RetrieveEntitiesReq) (*v1.RetrieveEntitiesRes, error)
|
||||
AddConnections(context.Context, *v1.AddConnectionsReq) (*v1.AddConnectionsRes, error)
|
||||
RemoveConnections(context.Context, *v1.RemoveConnectionsReq) (*v1.RemoveConnectionsRes, error)
|
||||
RemoveChannelConnections(context.Context, *RemoveChannelConnectionsReq) (*RemoveChannelConnectionsRes, error)
|
||||
UnsetParentGroupFromClient(context.Context, *UnsetParentGroupFromClientReq) (*UnsetParentGroupFromClientRes, error)
|
||||
mustEmbedUnimplementedClientsServiceServer()
|
||||
}
|
||||
|
||||
// UnimplementedClientsServiceServer must be embedded to have
|
||||
// forward compatible implementations.
|
||||
//
|
||||
// NOTE: this should be embedded by value instead of pointer to avoid a nil
|
||||
// pointer dereference when methods are called.
|
||||
type UnimplementedClientsServiceServer struct{}
|
||||
|
||||
func (UnimplementedClientsServiceServer) Authenticate(context.Context, *AuthnReq) (*AuthnRes, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method Authenticate not implemented")
|
||||
}
|
||||
func (UnimplementedClientsServiceServer) RetrieveEntity(context.Context, *v1.RetrieveEntityReq) (*v1.RetrieveEntityRes, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method RetrieveEntity not implemented")
|
||||
}
|
||||
func (UnimplementedClientsServiceServer) RetrieveEntities(context.Context, *v1.RetrieveEntitiesReq) (*v1.RetrieveEntitiesRes, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method RetrieveEntities not implemented")
|
||||
}
|
||||
func (UnimplementedClientsServiceServer) AddConnections(context.Context, *v1.AddConnectionsReq) (*v1.AddConnectionsRes, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method AddConnections not implemented")
|
||||
}
|
||||
func (UnimplementedClientsServiceServer) RemoveConnections(context.Context, *v1.RemoveConnectionsReq) (*v1.RemoveConnectionsRes, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method RemoveConnections not implemented")
|
||||
}
|
||||
func (UnimplementedClientsServiceServer) RemoveChannelConnections(context.Context, *RemoveChannelConnectionsReq) (*RemoveChannelConnectionsRes, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method RemoveChannelConnections not implemented")
|
||||
}
|
||||
func (UnimplementedClientsServiceServer) UnsetParentGroupFromClient(context.Context, *UnsetParentGroupFromClientReq) (*UnsetParentGroupFromClientRes, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method UnsetParentGroupFromClient not implemented")
|
||||
}
|
||||
func (UnimplementedClientsServiceServer) mustEmbedUnimplementedClientsServiceServer() {}
|
||||
func (UnimplementedClientsServiceServer) testEmbeddedByValue() {}
|
||||
|
||||
// UnsafeClientsServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to ClientsServiceServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeClientsServiceServer interface {
|
||||
mustEmbedUnimplementedClientsServiceServer()
|
||||
}
|
||||
|
||||
func RegisterClientsServiceServer(s grpc.ServiceRegistrar, srv ClientsServiceServer) {
|
||||
// If the following call panics, it indicates UnimplementedClientsServiceServer was
|
||||
// embedded by pointer and is nil. This will cause panics if an
|
||||
// unimplemented method is ever invoked, so we test this at initialization
|
||||
// time to prevent it from happening at runtime later due to I/O.
|
||||
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
|
||||
t.testEmbeddedByValue()
|
||||
}
|
||||
s.RegisterService(&ClientsService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _ClientsService_Authenticate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(AuthnReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ClientsServiceServer).Authenticate(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ClientsService_Authenticate_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ClientsServiceServer).Authenticate(ctx, req.(*AuthnReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ClientsService_RetrieveEntity_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(v1.RetrieveEntityReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ClientsServiceServer).RetrieveEntity(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ClientsService_RetrieveEntity_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ClientsServiceServer).RetrieveEntity(ctx, req.(*v1.RetrieveEntityReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ClientsService_RetrieveEntities_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(v1.RetrieveEntitiesReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ClientsServiceServer).RetrieveEntities(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ClientsService_RetrieveEntities_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ClientsServiceServer).RetrieveEntities(ctx, req.(*v1.RetrieveEntitiesReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ClientsService_AddConnections_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(v1.AddConnectionsReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ClientsServiceServer).AddConnections(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ClientsService_AddConnections_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ClientsServiceServer).AddConnections(ctx, req.(*v1.AddConnectionsReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ClientsService_RemoveConnections_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(v1.RemoveConnectionsReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ClientsServiceServer).RemoveConnections(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ClientsService_RemoveConnections_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ClientsServiceServer).RemoveConnections(ctx, req.(*v1.RemoveConnectionsReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ClientsService_RemoveChannelConnections_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(RemoveChannelConnectionsReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ClientsServiceServer).RemoveChannelConnections(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ClientsService_RemoveChannelConnections_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ClientsServiceServer).RemoveChannelConnections(ctx, req.(*RemoveChannelConnectionsReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ClientsService_UnsetParentGroupFromClient_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(UnsetParentGroupFromClientReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ClientsServiceServer).UnsetParentGroupFromClient(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ClientsService_UnsetParentGroupFromClient_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ClientsServiceServer).UnsetParentGroupFromClient(ctx, req.(*UnsetParentGroupFromClientReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// ClientsService_ServiceDesc is the grpc.ServiceDesc for ClientsService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var ClientsService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "clients.v1.ClientsService",
|
||||
HandlerType: (*ClientsServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "Authenticate",
|
||||
Handler: _ClientsService_Authenticate_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "RetrieveEntity",
|
||||
Handler: _ClientsService_RetrieveEntity_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "RetrieveEntities",
|
||||
Handler: _ClientsService_RetrieveEntities_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "AddConnections",
|
||||
Handler: _ClientsService_AddConnections_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "RemoveConnections",
|
||||
Handler: _ClientsService_RemoveConnections_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "RemoveChannelConnections",
|
||||
Handler: _ClientsService_RemoveChannelConnections_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "UnsetParentGroupFromClient",
|
||||
Handler: _ClientsService_UnsetParentGroupFromClient_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "clients/v1/clients.proto",
|
||||
}
|
||||
@@ -0,0 +1,691 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.11
|
||||
// protoc v7.35.1
|
||||
// source: common/v1/common.proto
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type RetrieveEntitiesReq struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Ids []string `protobuf:"bytes,1,rep,name=ids,proto3" json:"ids,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *RetrieveEntitiesReq) Reset() {
|
||||
*x = RetrieveEntitiesReq{}
|
||||
mi := &file_common_v1_common_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *RetrieveEntitiesReq) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*RetrieveEntitiesReq) ProtoMessage() {}
|
||||
|
||||
func (x *RetrieveEntitiesReq) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_common_v1_common_proto_msgTypes[0]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use RetrieveEntitiesReq.ProtoReflect.Descriptor instead.
|
||||
func (*RetrieveEntitiesReq) Descriptor() ([]byte, []int) {
|
||||
return file_common_v1_common_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *RetrieveEntitiesReq) GetIds() []string {
|
||||
if x != nil {
|
||||
return x.Ids
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type RetrieveEntitiesRes struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Total uint64 `protobuf:"varint,1,opt,name=total,proto3" json:"total,omitempty"`
|
||||
Limit uint64 `protobuf:"varint,2,opt,name=limit,proto3" json:"limit,omitempty"`
|
||||
Offset uint64 `protobuf:"varint,3,opt,name=offset,proto3" json:"offset,omitempty"`
|
||||
Entities []*EntityBasic `protobuf:"bytes,4,rep,name=entities,proto3" json:"entities,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *RetrieveEntitiesRes) Reset() {
|
||||
*x = RetrieveEntitiesRes{}
|
||||
mi := &file_common_v1_common_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *RetrieveEntitiesRes) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*RetrieveEntitiesRes) ProtoMessage() {}
|
||||
|
||||
func (x *RetrieveEntitiesRes) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_common_v1_common_proto_msgTypes[1]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use RetrieveEntitiesRes.ProtoReflect.Descriptor instead.
|
||||
func (*RetrieveEntitiesRes) Descriptor() ([]byte, []int) {
|
||||
return file_common_v1_common_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *RetrieveEntitiesRes) GetTotal() uint64 {
|
||||
if x != nil {
|
||||
return x.Total
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *RetrieveEntitiesRes) GetLimit() uint64 {
|
||||
if x != nil {
|
||||
return x.Limit
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *RetrieveEntitiesRes) GetOffset() uint64 {
|
||||
if x != nil {
|
||||
return x.Offset
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *RetrieveEntitiesRes) GetEntities() []*EntityBasic {
|
||||
if x != nil {
|
||||
return x.Entities
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type RetrieveEntityReq struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *RetrieveEntityReq) Reset() {
|
||||
*x = RetrieveEntityReq{}
|
||||
mi := &file_common_v1_common_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *RetrieveEntityReq) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*RetrieveEntityReq) ProtoMessage() {}
|
||||
|
||||
func (x *RetrieveEntityReq) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_common_v1_common_proto_msgTypes[2]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use RetrieveEntityReq.ProtoReflect.Descriptor instead.
|
||||
func (*RetrieveEntityReq) Descriptor() ([]byte, []int) {
|
||||
return file_common_v1_common_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *RetrieveEntityReq) GetId() string {
|
||||
if x != nil {
|
||||
return x.Id
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type RetrieveEntityRes struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Entity *EntityBasic `protobuf:"bytes,1,opt,name=entity,proto3" json:"entity,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *RetrieveEntityRes) Reset() {
|
||||
*x = RetrieveEntityRes{}
|
||||
mi := &file_common_v1_common_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *RetrieveEntityRes) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*RetrieveEntityRes) ProtoMessage() {}
|
||||
|
||||
func (x *RetrieveEntityRes) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_common_v1_common_proto_msgTypes[3]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use RetrieveEntityRes.ProtoReflect.Descriptor instead.
|
||||
func (*RetrieveEntityRes) Descriptor() ([]byte, []int) {
|
||||
return file_common_v1_common_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *RetrieveEntityRes) GetEntity() *EntityBasic {
|
||||
if x != nil {
|
||||
return x.Entity
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type EntityBasic struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
DomainId string `protobuf:"bytes,2,opt,name=domain_id,json=domainId,proto3" json:"domain_id,omitempty"`
|
||||
ParentGroupId string `protobuf:"bytes,3,opt,name=parent_group_id,json=parentGroupId,proto3" json:"parent_group_id,omitempty"`
|
||||
Status uint32 `protobuf:"varint,4,opt,name=status,proto3" json:"status,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *EntityBasic) Reset() {
|
||||
*x = EntityBasic{}
|
||||
mi := &file_common_v1_common_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *EntityBasic) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*EntityBasic) ProtoMessage() {}
|
||||
|
||||
func (x *EntityBasic) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_common_v1_common_proto_msgTypes[4]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use EntityBasic.ProtoReflect.Descriptor instead.
|
||||
func (*EntityBasic) Descriptor() ([]byte, []int) {
|
||||
return file_common_v1_common_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *EntityBasic) GetId() string {
|
||||
if x != nil {
|
||||
return x.Id
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *EntityBasic) GetDomainId() string {
|
||||
if x != nil {
|
||||
return x.DomainId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *EntityBasic) GetParentGroupId() string {
|
||||
if x != nil {
|
||||
return x.ParentGroupId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *EntityBasic) GetStatus() uint32 {
|
||||
if x != nil {
|
||||
return x.Status
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type AddConnectionsReq struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Connections []*Connection `protobuf:"bytes,1,rep,name=connections,proto3" json:"connections,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *AddConnectionsReq) Reset() {
|
||||
*x = AddConnectionsReq{}
|
||||
mi := &file_common_v1_common_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *AddConnectionsReq) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*AddConnectionsReq) ProtoMessage() {}
|
||||
|
||||
func (x *AddConnectionsReq) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_common_v1_common_proto_msgTypes[5]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use AddConnectionsReq.ProtoReflect.Descriptor instead.
|
||||
func (*AddConnectionsReq) Descriptor() ([]byte, []int) {
|
||||
return file_common_v1_common_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
func (x *AddConnectionsReq) GetConnections() []*Connection {
|
||||
if x != nil {
|
||||
return x.Connections
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type AddConnectionsRes struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Ok bool `protobuf:"varint,1,opt,name=ok,proto3" json:"ok,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *AddConnectionsRes) Reset() {
|
||||
*x = AddConnectionsRes{}
|
||||
mi := &file_common_v1_common_proto_msgTypes[6]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *AddConnectionsRes) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*AddConnectionsRes) ProtoMessage() {}
|
||||
|
||||
func (x *AddConnectionsRes) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_common_v1_common_proto_msgTypes[6]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use AddConnectionsRes.ProtoReflect.Descriptor instead.
|
||||
func (*AddConnectionsRes) Descriptor() ([]byte, []int) {
|
||||
return file_common_v1_common_proto_rawDescGZIP(), []int{6}
|
||||
}
|
||||
|
||||
func (x *AddConnectionsRes) GetOk() bool {
|
||||
if x != nil {
|
||||
return x.Ok
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type RemoveConnectionsReq struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Connections []*Connection `protobuf:"bytes,1,rep,name=connections,proto3" json:"connections,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *RemoveConnectionsReq) Reset() {
|
||||
*x = RemoveConnectionsReq{}
|
||||
mi := &file_common_v1_common_proto_msgTypes[7]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *RemoveConnectionsReq) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*RemoveConnectionsReq) ProtoMessage() {}
|
||||
|
||||
func (x *RemoveConnectionsReq) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_common_v1_common_proto_msgTypes[7]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use RemoveConnectionsReq.ProtoReflect.Descriptor instead.
|
||||
func (*RemoveConnectionsReq) Descriptor() ([]byte, []int) {
|
||||
return file_common_v1_common_proto_rawDescGZIP(), []int{7}
|
||||
}
|
||||
|
||||
func (x *RemoveConnectionsReq) GetConnections() []*Connection {
|
||||
if x != nil {
|
||||
return x.Connections
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type RemoveConnectionsRes struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Ok bool `protobuf:"varint,1,opt,name=ok,proto3" json:"ok,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *RemoveConnectionsRes) Reset() {
|
||||
*x = RemoveConnectionsRes{}
|
||||
mi := &file_common_v1_common_proto_msgTypes[8]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *RemoveConnectionsRes) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*RemoveConnectionsRes) ProtoMessage() {}
|
||||
|
||||
func (x *RemoveConnectionsRes) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_common_v1_common_proto_msgTypes[8]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use RemoveConnectionsRes.ProtoReflect.Descriptor instead.
|
||||
func (*RemoveConnectionsRes) Descriptor() ([]byte, []int) {
|
||||
return file_common_v1_common_proto_rawDescGZIP(), []int{8}
|
||||
}
|
||||
|
||||
func (x *RemoveConnectionsRes) GetOk() bool {
|
||||
if x != nil {
|
||||
return x.Ok
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type Connection struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
ClientId string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"`
|
||||
ChannelId string `protobuf:"bytes,2,opt,name=channel_id,json=channelId,proto3" json:"channel_id,omitempty"`
|
||||
DomainId string `protobuf:"bytes,3,opt,name=domain_id,json=domainId,proto3" json:"domain_id,omitempty"`
|
||||
Type uint32 `protobuf:"varint,4,opt,name=type,proto3" json:"type,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *Connection) Reset() {
|
||||
*x = Connection{}
|
||||
mi := &file_common_v1_common_proto_msgTypes[9]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *Connection) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Connection) ProtoMessage() {}
|
||||
|
||||
func (x *Connection) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_common_v1_common_proto_msgTypes[9]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Connection.ProtoReflect.Descriptor instead.
|
||||
func (*Connection) Descriptor() ([]byte, []int) {
|
||||
return file_common_v1_common_proto_rawDescGZIP(), []int{9}
|
||||
}
|
||||
|
||||
func (x *Connection) GetClientId() string {
|
||||
if x != nil {
|
||||
return x.ClientId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Connection) GetChannelId() string {
|
||||
if x != nil {
|
||||
return x.ChannelId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Connection) GetDomainId() string {
|
||||
if x != nil {
|
||||
return x.DomainId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Connection) GetType() uint32 {
|
||||
if x != nil {
|
||||
return x.Type
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type RetrieveIDByRouteReq struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Route string `protobuf:"bytes,1,opt,name=route,proto3" json:"route,omitempty"`
|
||||
DomainId string `protobuf:"bytes,2,opt,name=domain_id,json=domainId,proto3" json:"domain_id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *RetrieveIDByRouteReq) Reset() {
|
||||
*x = RetrieveIDByRouteReq{}
|
||||
mi := &file_common_v1_common_proto_msgTypes[10]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *RetrieveIDByRouteReq) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*RetrieveIDByRouteReq) ProtoMessage() {}
|
||||
|
||||
func (x *RetrieveIDByRouteReq) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_common_v1_common_proto_msgTypes[10]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use RetrieveIDByRouteReq.ProtoReflect.Descriptor instead.
|
||||
func (*RetrieveIDByRouteReq) Descriptor() ([]byte, []int) {
|
||||
return file_common_v1_common_proto_rawDescGZIP(), []int{10}
|
||||
}
|
||||
|
||||
func (x *RetrieveIDByRouteReq) GetRoute() string {
|
||||
if x != nil {
|
||||
return x.Route
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *RetrieveIDByRouteReq) GetDomainId() string {
|
||||
if x != nil {
|
||||
return x.DomainId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var File_common_v1_common_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_common_v1_common_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x16common/v1/common.proto\x12\tcommon.v1\"'\n" +
|
||||
"\x13RetrieveEntitiesReq\x12\x10\n" +
|
||||
"\x03ids\x18\x01 \x03(\tR\x03ids\"\x8d\x01\n" +
|
||||
"\x13RetrieveEntitiesRes\x12\x14\n" +
|
||||
"\x05total\x18\x01 \x01(\x04R\x05total\x12\x14\n" +
|
||||
"\x05limit\x18\x02 \x01(\x04R\x05limit\x12\x16\n" +
|
||||
"\x06offset\x18\x03 \x01(\x04R\x06offset\x122\n" +
|
||||
"\bentities\x18\x04 \x03(\v2\x16.common.v1.EntityBasicR\bentities\"#\n" +
|
||||
"\x11RetrieveEntityReq\x12\x0e\n" +
|
||||
"\x02id\x18\x01 \x01(\tR\x02id\"C\n" +
|
||||
"\x11RetrieveEntityRes\x12.\n" +
|
||||
"\x06entity\x18\x01 \x01(\v2\x16.common.v1.EntityBasicR\x06entity\"z\n" +
|
||||
"\vEntityBasic\x12\x0e\n" +
|
||||
"\x02id\x18\x01 \x01(\tR\x02id\x12\x1b\n" +
|
||||
"\tdomain_id\x18\x02 \x01(\tR\bdomainId\x12&\n" +
|
||||
"\x0fparent_group_id\x18\x03 \x01(\tR\rparentGroupId\x12\x16\n" +
|
||||
"\x06status\x18\x04 \x01(\rR\x06status\"L\n" +
|
||||
"\x11AddConnectionsReq\x127\n" +
|
||||
"\vconnections\x18\x01 \x03(\v2\x15.common.v1.ConnectionR\vconnections\"#\n" +
|
||||
"\x11AddConnectionsRes\x12\x0e\n" +
|
||||
"\x02ok\x18\x01 \x01(\bR\x02ok\"O\n" +
|
||||
"\x14RemoveConnectionsReq\x127\n" +
|
||||
"\vconnections\x18\x01 \x03(\v2\x15.common.v1.ConnectionR\vconnections\"&\n" +
|
||||
"\x14RemoveConnectionsRes\x12\x0e\n" +
|
||||
"\x02ok\x18\x01 \x01(\bR\x02ok\"y\n" +
|
||||
"\n" +
|
||||
"Connection\x12\x1b\n" +
|
||||
"\tclient_id\x18\x01 \x01(\tR\bclientId\x12\x1d\n" +
|
||||
"\n" +
|
||||
"channel_id\x18\x02 \x01(\tR\tchannelId\x12\x1b\n" +
|
||||
"\tdomain_id\x18\x03 \x01(\tR\bdomainId\x12\x12\n" +
|
||||
"\x04type\x18\x04 \x01(\rR\x04type\"I\n" +
|
||||
"\x14RetrieveIDByRouteReq\x12\x14\n" +
|
||||
"\x05route\x18\x01 \x01(\tR\x05route\x12\x1b\n" +
|
||||
"\tdomain_id\x18\x02 \x01(\tR\bdomainIdB2Z0github.com/absmach/magistrala/api/grpc/common/v1b\x06proto3"
|
||||
|
||||
var (
|
||||
file_common_v1_common_proto_rawDescOnce sync.Once
|
||||
file_common_v1_common_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_common_v1_common_proto_rawDescGZIP() []byte {
|
||||
file_common_v1_common_proto_rawDescOnce.Do(func() {
|
||||
file_common_v1_common_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_common_v1_common_proto_rawDesc), len(file_common_v1_common_proto_rawDesc)))
|
||||
})
|
||||
return file_common_v1_common_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_common_v1_common_proto_msgTypes = make([]protoimpl.MessageInfo, 11)
|
||||
var file_common_v1_common_proto_goTypes = []any{
|
||||
(*RetrieveEntitiesReq)(nil), // 0: common.v1.RetrieveEntitiesReq
|
||||
(*RetrieveEntitiesRes)(nil), // 1: common.v1.RetrieveEntitiesRes
|
||||
(*RetrieveEntityReq)(nil), // 2: common.v1.RetrieveEntityReq
|
||||
(*RetrieveEntityRes)(nil), // 3: common.v1.RetrieveEntityRes
|
||||
(*EntityBasic)(nil), // 4: common.v1.EntityBasic
|
||||
(*AddConnectionsReq)(nil), // 5: common.v1.AddConnectionsReq
|
||||
(*AddConnectionsRes)(nil), // 6: common.v1.AddConnectionsRes
|
||||
(*RemoveConnectionsReq)(nil), // 7: common.v1.RemoveConnectionsReq
|
||||
(*RemoveConnectionsRes)(nil), // 8: common.v1.RemoveConnectionsRes
|
||||
(*Connection)(nil), // 9: common.v1.Connection
|
||||
(*RetrieveIDByRouteReq)(nil), // 10: common.v1.RetrieveIDByRouteReq
|
||||
}
|
||||
var file_common_v1_common_proto_depIdxs = []int32{
|
||||
4, // 0: common.v1.RetrieveEntitiesRes.entities:type_name -> common.v1.EntityBasic
|
||||
4, // 1: common.v1.RetrieveEntityRes.entity:type_name -> common.v1.EntityBasic
|
||||
9, // 2: common.v1.AddConnectionsReq.connections:type_name -> common.v1.Connection
|
||||
9, // 3: common.v1.RemoveConnectionsReq.connections:type_name -> common.v1.Connection
|
||||
4, // [4:4] is the sub-list for method output_type
|
||||
4, // [4:4] is the sub-list for method input_type
|
||||
4, // [4:4] is the sub-list for extension type_name
|
||||
4, // [4:4] is the sub-list for extension extendee
|
||||
0, // [0:4] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_common_v1_common_proto_init() }
|
||||
func file_common_v1_common_proto_init() {
|
||||
if File_common_v1_common_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_common_v1_common_proto_rawDesc), len(file_common_v1_common_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 11,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_common_v1_common_proto_goTypes,
|
||||
DependencyIndexes: file_common_v1_common_proto_depIdxs,
|
||||
MessageInfos: file_common_v1_common_proto_msgTypes,
|
||||
}.Build()
|
||||
File_common_v1_common_proto = out.File
|
||||
file_common_v1_common_proto_goTypes = nil
|
||||
file_common_v1_common_proto_depIdxs = nil
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.11
|
||||
// protoc v7.35.1
|
||||
// source: domains/v1/domains.proto
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
v1 "github.com/absmach/magistrala/api/grpc/common/v1"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type DeleteUserRes struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Deleted bool `protobuf:"varint,1,opt,name=deleted,proto3" json:"deleted,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *DeleteUserRes) Reset() {
|
||||
*x = DeleteUserRes{}
|
||||
mi := &file_domains_v1_domains_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *DeleteUserRes) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*DeleteUserRes) ProtoMessage() {}
|
||||
|
||||
func (x *DeleteUserRes) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_domains_v1_domains_proto_msgTypes[0]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use DeleteUserRes.ProtoReflect.Descriptor instead.
|
||||
func (*DeleteUserRes) Descriptor() ([]byte, []int) {
|
||||
return file_domains_v1_domains_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *DeleteUserRes) GetDeleted() bool {
|
||||
if x != nil {
|
||||
return x.Deleted
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type DeleteUserReq struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *DeleteUserReq) Reset() {
|
||||
*x = DeleteUserReq{}
|
||||
mi := &file_domains_v1_domains_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *DeleteUserReq) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*DeleteUserReq) ProtoMessage() {}
|
||||
|
||||
func (x *DeleteUserReq) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_domains_v1_domains_proto_msgTypes[1]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use DeleteUserReq.ProtoReflect.Descriptor instead.
|
||||
func (*DeleteUserReq) Descriptor() ([]byte, []int) {
|
||||
return file_domains_v1_domains_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *DeleteUserReq) GetId() string {
|
||||
if x != nil {
|
||||
return x.Id
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var File_domains_v1_domains_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_domains_v1_domains_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x18domains/v1/domains.proto\x12\n" +
|
||||
"domains.v1\x1a\x16common/v1/common.proto\")\n" +
|
||||
"\rDeleteUserRes\x12\x18\n" +
|
||||
"\adeleted\x18\x01 \x01(\bR\adeleted\"\x1f\n" +
|
||||
"\rDeleteUserReq\x12\x0e\n" +
|
||||
"\x02id\x18\x01 \x01(\tR\x02id2\x87\x02\n" +
|
||||
"\x0eDomainsService\x12O\n" +
|
||||
"\x15DeleteUserFromDomains\x12\x19.domains.v1.DeleteUserReq\x1a\x19.domains.v1.DeleteUserRes\"\x00\x12N\n" +
|
||||
"\x0eRetrieveStatus\x12\x1c.common.v1.RetrieveEntityReq\x1a\x1c.common.v1.RetrieveEntityRes\"\x00\x12T\n" +
|
||||
"\x11RetrieveIDByRoute\x12\x1f.common.v1.RetrieveIDByRouteReq\x1a\x1c.common.v1.RetrieveEntityRes\"\x00B8Z6github.com/absmach/magistrala/internal/grpc/domains/v1b\x06proto3"
|
||||
|
||||
var (
|
||||
file_domains_v1_domains_proto_rawDescOnce sync.Once
|
||||
file_domains_v1_domains_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_domains_v1_domains_proto_rawDescGZIP() []byte {
|
||||
file_domains_v1_domains_proto_rawDescOnce.Do(func() {
|
||||
file_domains_v1_domains_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_domains_v1_domains_proto_rawDesc), len(file_domains_v1_domains_proto_rawDesc)))
|
||||
})
|
||||
return file_domains_v1_domains_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_domains_v1_domains_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
|
||||
var file_domains_v1_domains_proto_goTypes = []any{
|
||||
(*DeleteUserRes)(nil), // 0: domains.v1.DeleteUserRes
|
||||
(*DeleteUserReq)(nil), // 1: domains.v1.DeleteUserReq
|
||||
(*v1.RetrieveEntityReq)(nil), // 2: common.v1.RetrieveEntityReq
|
||||
(*v1.RetrieveIDByRouteReq)(nil), // 3: common.v1.RetrieveIDByRouteReq
|
||||
(*v1.RetrieveEntityRes)(nil), // 4: common.v1.RetrieveEntityRes
|
||||
}
|
||||
var file_domains_v1_domains_proto_depIdxs = []int32{
|
||||
1, // 0: domains.v1.DomainsService.DeleteUserFromDomains:input_type -> domains.v1.DeleteUserReq
|
||||
2, // 1: domains.v1.DomainsService.RetrieveStatus:input_type -> common.v1.RetrieveEntityReq
|
||||
3, // 2: domains.v1.DomainsService.RetrieveIDByRoute:input_type -> common.v1.RetrieveIDByRouteReq
|
||||
0, // 3: domains.v1.DomainsService.DeleteUserFromDomains:output_type -> domains.v1.DeleteUserRes
|
||||
4, // 4: domains.v1.DomainsService.RetrieveStatus:output_type -> common.v1.RetrieveEntityRes
|
||||
4, // 5: domains.v1.DomainsService.RetrieveIDByRoute:output_type -> common.v1.RetrieveEntityRes
|
||||
3, // [3:6] is the sub-list for method output_type
|
||||
0, // [0:3] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
0, // [0:0] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_domains_v1_domains_proto_init() }
|
||||
func file_domains_v1_domains_proto_init() {
|
||||
if File_domains_v1_domains_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_domains_v1_domains_proto_rawDesc), len(file_domains_v1_domains_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 2,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_domains_v1_domains_proto_goTypes,
|
||||
DependencyIndexes: file_domains_v1_domains_proto_depIdxs,
|
||||
MessageInfos: file_domains_v1_domains_proto_msgTypes,
|
||||
}.Build()
|
||||
File_domains_v1_domains_proto = out.File
|
||||
file_domains_v1_domains_proto_goTypes = nil
|
||||
file_domains_v1_domains_proto_depIdxs = nil
|
||||
}
|
||||
@@ -0,0 +1,207 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.6.2
|
||||
// - protoc v7.35.1
|
||||
// source: domains/v1/domains.proto
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
context "context"
|
||||
v1 "github.com/absmach/magistrala/api/grpc/common/v1"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.64.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion9
|
||||
|
||||
const (
|
||||
DomainsService_DeleteUserFromDomains_FullMethodName = "/domains.v1.DomainsService/DeleteUserFromDomains"
|
||||
DomainsService_RetrieveStatus_FullMethodName = "/domains.v1.DomainsService/RetrieveStatus"
|
||||
DomainsService_RetrieveIDByRoute_FullMethodName = "/domains.v1.DomainsService/RetrieveIDByRoute"
|
||||
)
|
||||
|
||||
// DomainsServiceClient is the client API for DomainsService service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
//
|
||||
// DomainsService is a service that provides access to
|
||||
// domains functionalities for Magistrala services.
|
||||
type DomainsServiceClient interface {
|
||||
DeleteUserFromDomains(ctx context.Context, in *DeleteUserReq, opts ...grpc.CallOption) (*DeleteUserRes, error)
|
||||
RetrieveStatus(ctx context.Context, in *v1.RetrieveEntityReq, opts ...grpc.CallOption) (*v1.RetrieveEntityRes, error)
|
||||
RetrieveIDByRoute(ctx context.Context, in *v1.RetrieveIDByRouteReq, opts ...grpc.CallOption) (*v1.RetrieveEntityRes, error)
|
||||
}
|
||||
|
||||
type domainsServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewDomainsServiceClient(cc grpc.ClientConnInterface) DomainsServiceClient {
|
||||
return &domainsServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *domainsServiceClient) DeleteUserFromDomains(ctx context.Context, in *DeleteUserReq, opts ...grpc.CallOption) (*DeleteUserRes, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(DeleteUserRes)
|
||||
err := c.cc.Invoke(ctx, DomainsService_DeleteUserFromDomains_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *domainsServiceClient) RetrieveStatus(ctx context.Context, in *v1.RetrieveEntityReq, opts ...grpc.CallOption) (*v1.RetrieveEntityRes, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(v1.RetrieveEntityRes)
|
||||
err := c.cc.Invoke(ctx, DomainsService_RetrieveStatus_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *domainsServiceClient) RetrieveIDByRoute(ctx context.Context, in *v1.RetrieveIDByRouteReq, opts ...grpc.CallOption) (*v1.RetrieveEntityRes, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(v1.RetrieveEntityRes)
|
||||
err := c.cc.Invoke(ctx, DomainsService_RetrieveIDByRoute_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// DomainsServiceServer is the server API for DomainsService service.
|
||||
// All implementations must embed UnimplementedDomainsServiceServer
|
||||
// for forward compatibility.
|
||||
//
|
||||
// DomainsService is a service that provides access to
|
||||
// domains functionalities for Magistrala services.
|
||||
type DomainsServiceServer interface {
|
||||
DeleteUserFromDomains(context.Context, *DeleteUserReq) (*DeleteUserRes, error)
|
||||
RetrieveStatus(context.Context, *v1.RetrieveEntityReq) (*v1.RetrieveEntityRes, error)
|
||||
RetrieveIDByRoute(context.Context, *v1.RetrieveIDByRouteReq) (*v1.RetrieveEntityRes, error)
|
||||
mustEmbedUnimplementedDomainsServiceServer()
|
||||
}
|
||||
|
||||
// UnimplementedDomainsServiceServer must be embedded to have
|
||||
// forward compatible implementations.
|
||||
//
|
||||
// NOTE: this should be embedded by value instead of pointer to avoid a nil
|
||||
// pointer dereference when methods are called.
|
||||
type UnimplementedDomainsServiceServer struct{}
|
||||
|
||||
func (UnimplementedDomainsServiceServer) DeleteUserFromDomains(context.Context, *DeleteUserReq) (*DeleteUserRes, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method DeleteUserFromDomains not implemented")
|
||||
}
|
||||
func (UnimplementedDomainsServiceServer) RetrieveStatus(context.Context, *v1.RetrieveEntityReq) (*v1.RetrieveEntityRes, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method RetrieveStatus not implemented")
|
||||
}
|
||||
func (UnimplementedDomainsServiceServer) RetrieveIDByRoute(context.Context, *v1.RetrieveIDByRouteReq) (*v1.RetrieveEntityRes, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method RetrieveIDByRoute not implemented")
|
||||
}
|
||||
func (UnimplementedDomainsServiceServer) mustEmbedUnimplementedDomainsServiceServer() {}
|
||||
func (UnimplementedDomainsServiceServer) testEmbeddedByValue() {}
|
||||
|
||||
// UnsafeDomainsServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to DomainsServiceServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeDomainsServiceServer interface {
|
||||
mustEmbedUnimplementedDomainsServiceServer()
|
||||
}
|
||||
|
||||
func RegisterDomainsServiceServer(s grpc.ServiceRegistrar, srv DomainsServiceServer) {
|
||||
// If the following call panics, it indicates UnimplementedDomainsServiceServer was
|
||||
// embedded by pointer and is nil. This will cause panics if an
|
||||
// unimplemented method is ever invoked, so we test this at initialization
|
||||
// time to prevent it from happening at runtime later due to I/O.
|
||||
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
|
||||
t.testEmbeddedByValue()
|
||||
}
|
||||
s.RegisterService(&DomainsService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _DomainsService_DeleteUserFromDomains_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(DeleteUserReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(DomainsServiceServer).DeleteUserFromDomains(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: DomainsService_DeleteUserFromDomains_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(DomainsServiceServer).DeleteUserFromDomains(ctx, req.(*DeleteUserReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _DomainsService_RetrieveStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(v1.RetrieveEntityReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(DomainsServiceServer).RetrieveStatus(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: DomainsService_RetrieveStatus_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(DomainsServiceServer).RetrieveStatus(ctx, req.(*v1.RetrieveEntityReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _DomainsService_RetrieveIDByRoute_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(v1.RetrieveIDByRouteReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(DomainsServiceServer).RetrieveIDByRoute(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: DomainsService_RetrieveIDByRoute_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(DomainsServiceServer).RetrieveIDByRoute(ctx, req.(*v1.RetrieveIDByRouteReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// DomainsService_ServiceDesc is the grpc.ServiceDesc for DomainsService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var DomainsService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "domains.v1.DomainsService",
|
||||
HandlerType: (*DomainsServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "DeleteUserFromDomains",
|
||||
Handler: _DomainsService_DeleteUserFromDomains_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "RetrieveStatus",
|
||||
Handler: _DomainsService_RetrieveStatus_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "RetrieveIDByRoute",
|
||||
Handler: _DomainsService_RetrieveIDByRoute_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "domains/v1/domains.proto",
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.11
|
||||
// protoc v7.35.1
|
||||
// source: groups/v1/groups.proto
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
v1 "github.com/absmach/magistrala/api/grpc/common/v1"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
var File_groups_v1_groups_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_groups_v1_groups_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x16groups/v1/groups.proto\x12\tgroups.v1\x1a\x16common/v1/common.proto2_\n" +
|
||||
"\rGroupsService\x12N\n" +
|
||||
"\x0eRetrieveEntity\x12\x1c.common.v1.RetrieveEntityReq\x1a\x1c.common.v1.RetrieveEntityRes\"\x00B2Z0github.com/absmach/magistrala/api/grpc/groups/v1b\x06proto3"
|
||||
|
||||
var file_groups_v1_groups_proto_goTypes = []any{
|
||||
(*v1.RetrieveEntityReq)(nil), // 0: common.v1.RetrieveEntityReq
|
||||
(*v1.RetrieveEntityRes)(nil), // 1: common.v1.RetrieveEntityRes
|
||||
}
|
||||
var file_groups_v1_groups_proto_depIdxs = []int32{
|
||||
0, // 0: groups.v1.GroupsService.RetrieveEntity:input_type -> common.v1.RetrieveEntityReq
|
||||
1, // 1: groups.v1.GroupsService.RetrieveEntity:output_type -> common.v1.RetrieveEntityRes
|
||||
1, // [1:2] is the sub-list for method output_type
|
||||
0, // [0:1] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
0, // [0:0] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_groups_v1_groups_proto_init() }
|
||||
func file_groups_v1_groups_proto_init() {
|
||||
if File_groups_v1_groups_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_groups_v1_groups_proto_rawDesc), len(file_groups_v1_groups_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 0,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_groups_v1_groups_proto_goTypes,
|
||||
DependencyIndexes: file_groups_v1_groups_proto_depIdxs,
|
||||
}.Build()
|
||||
File_groups_v1_groups_proto = out.File
|
||||
file_groups_v1_groups_proto_goTypes = nil
|
||||
file_groups_v1_groups_proto_depIdxs = nil
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.6.2
|
||||
// - protoc v7.35.1
|
||||
// source: groups/v1/groups.proto
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
context "context"
|
||||
v1 "github.com/absmach/magistrala/api/grpc/common/v1"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.64.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion9
|
||||
|
||||
const (
|
||||
GroupsService_RetrieveEntity_FullMethodName = "/groups.v1.GroupsService/RetrieveEntity"
|
||||
)
|
||||
|
||||
// GroupsServiceClient is the client API for GroupsService service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
//
|
||||
// GroupssService is a service that provides groups
|
||||
// functionalities for Magistrala services.
|
||||
type GroupsServiceClient interface {
|
||||
RetrieveEntity(ctx context.Context, in *v1.RetrieveEntityReq, opts ...grpc.CallOption) (*v1.RetrieveEntityRes, error)
|
||||
}
|
||||
|
||||
type groupsServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewGroupsServiceClient(cc grpc.ClientConnInterface) GroupsServiceClient {
|
||||
return &groupsServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *groupsServiceClient) RetrieveEntity(ctx context.Context, in *v1.RetrieveEntityReq, opts ...grpc.CallOption) (*v1.RetrieveEntityRes, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(v1.RetrieveEntityRes)
|
||||
err := c.cc.Invoke(ctx, GroupsService_RetrieveEntity_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// GroupsServiceServer is the server API for GroupsService service.
|
||||
// All implementations must embed UnimplementedGroupsServiceServer
|
||||
// for forward compatibility.
|
||||
//
|
||||
// GroupssService is a service that provides groups
|
||||
// functionalities for Magistrala services.
|
||||
type GroupsServiceServer interface {
|
||||
RetrieveEntity(context.Context, *v1.RetrieveEntityReq) (*v1.RetrieveEntityRes, error)
|
||||
mustEmbedUnimplementedGroupsServiceServer()
|
||||
}
|
||||
|
||||
// UnimplementedGroupsServiceServer must be embedded to have
|
||||
// forward compatible implementations.
|
||||
//
|
||||
// NOTE: this should be embedded by value instead of pointer to avoid a nil
|
||||
// pointer dereference when methods are called.
|
||||
type UnimplementedGroupsServiceServer struct{}
|
||||
|
||||
func (UnimplementedGroupsServiceServer) RetrieveEntity(context.Context, *v1.RetrieveEntityReq) (*v1.RetrieveEntityRes, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method RetrieveEntity not implemented")
|
||||
}
|
||||
func (UnimplementedGroupsServiceServer) mustEmbedUnimplementedGroupsServiceServer() {}
|
||||
func (UnimplementedGroupsServiceServer) testEmbeddedByValue() {}
|
||||
|
||||
// UnsafeGroupsServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to GroupsServiceServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeGroupsServiceServer interface {
|
||||
mustEmbedUnimplementedGroupsServiceServer()
|
||||
}
|
||||
|
||||
func RegisterGroupsServiceServer(s grpc.ServiceRegistrar, srv GroupsServiceServer) {
|
||||
// If the following call panics, it indicates UnimplementedGroupsServiceServer was
|
||||
// embedded by pointer and is nil. This will cause panics if an
|
||||
// unimplemented method is ever invoked, so we test this at initialization
|
||||
// time to prevent it from happening at runtime later due to I/O.
|
||||
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
|
||||
t.testEmbeddedByValue()
|
||||
}
|
||||
s.RegisterService(&GroupsService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _GroupsService_RetrieveEntity_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(v1.RetrieveEntityReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(GroupsServiceServer).RetrieveEntity(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: GroupsService_RetrieveEntity_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(GroupsServiceServer).RetrieveEntity(ctx, req.(*v1.RetrieveEntityReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// GroupsService_ServiceDesc is the grpc.ServiceDesc for GroupsService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var GroupsService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "groups.v1.GroupsService",
|
||||
HandlerType: (*GroupsServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "RetrieveEntity",
|
||||
Handler: _GroupsService_RetrieveEntity_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "groups/v1/groups.proto",
|
||||
}
|
||||
@@ -0,0 +1,884 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.11
|
||||
// protoc v7.35.1
|
||||
// source: readers/v1/readers.proto
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// Aggregation defines supported data aggregations.
|
||||
type Aggregation int32
|
||||
|
||||
const (
|
||||
Aggregation_AGGREGATION_UNSPECIFIED Aggregation = 0
|
||||
Aggregation_AGGREGATION_MAX Aggregation = 1
|
||||
Aggregation_AGGREGATION_MIN Aggregation = 2
|
||||
Aggregation_AGGREGATION_SUM Aggregation = 3
|
||||
Aggregation_AGGREGATION_COUNT Aggregation = 4
|
||||
Aggregation_AGGREGATION_AVG Aggregation = 5
|
||||
)
|
||||
|
||||
// Enum value maps for Aggregation.
|
||||
var (
|
||||
Aggregation_name = map[int32]string{
|
||||
0: "AGGREGATION_UNSPECIFIED",
|
||||
1: "AGGREGATION_MAX",
|
||||
2: "AGGREGATION_MIN",
|
||||
3: "AGGREGATION_SUM",
|
||||
4: "AGGREGATION_COUNT",
|
||||
5: "AGGREGATION_AVG",
|
||||
}
|
||||
Aggregation_value = map[string]int32{
|
||||
"AGGREGATION_UNSPECIFIED": 0,
|
||||
"AGGREGATION_MAX": 1,
|
||||
"AGGREGATION_MIN": 2,
|
||||
"AGGREGATION_SUM": 3,
|
||||
"AGGREGATION_COUNT": 4,
|
||||
"AGGREGATION_AVG": 5,
|
||||
}
|
||||
)
|
||||
|
||||
func (x Aggregation) Enum() *Aggregation {
|
||||
p := new(Aggregation)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x Aggregation) String() string {
|
||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||
}
|
||||
|
||||
func (Aggregation) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_readers_v1_readers_proto_enumTypes[0].Descriptor()
|
||||
}
|
||||
|
||||
func (Aggregation) Type() protoreflect.EnumType {
|
||||
return &file_readers_v1_readers_proto_enumTypes[0]
|
||||
}
|
||||
|
||||
func (x Aggregation) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Aggregation.Descriptor instead.
|
||||
func (Aggregation) EnumDescriptor() ([]byte, []int) {
|
||||
return file_readers_v1_readers_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
type PageMetadata struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Limit uint64 `protobuf:"varint,1,opt,name=limit,proto3" json:"limit,omitempty"`
|
||||
Offset uint64 `protobuf:"varint,2,opt,name=offset,proto3" json:"offset,omitempty"`
|
||||
Protocol string `protobuf:"bytes,3,opt,name=protocol,proto3" json:"protocol,omitempty"`
|
||||
Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Value float64 `protobuf:"fixed64,5,opt,name=value,proto3" json:"value,omitempty"`
|
||||
Publisher string `protobuf:"bytes,6,opt,name=publisher,proto3" json:"publisher,omitempty"`
|
||||
BoolValue bool `protobuf:"varint,7,opt,name=bool_value,json=boolValue,proto3" json:"bool_value,omitempty"`
|
||||
StringValue string `protobuf:"bytes,8,opt,name=string_value,json=stringValue,proto3" json:"string_value,omitempty"`
|
||||
DataValue string `protobuf:"bytes,9,opt,name=data_value,json=dataValue,proto3" json:"data_value,omitempty"`
|
||||
From float64 `protobuf:"fixed64,10,opt,name=from,proto3" json:"from,omitempty"`
|
||||
To float64 `protobuf:"fixed64,11,opt,name=to,proto3" json:"to,omitempty"`
|
||||
Subtopic string `protobuf:"bytes,12,opt,name=subtopic,proto3" json:"subtopic,omitempty"`
|
||||
Interval string `protobuf:"bytes,13,opt,name=interval,proto3" json:"interval,omitempty"`
|
||||
Read bool `protobuf:"varint,14,opt,name=read,proto3" json:"read,omitempty"`
|
||||
Aggregation Aggregation `protobuf:"varint,15,opt,name=aggregation,proto3,enum=readers.v1.Aggregation" json:"aggregation,omitempty"`
|
||||
Comparator string `protobuf:"bytes,16,opt,name=comparator,proto3" json:"comparator,omitempty"`
|
||||
Format string `protobuf:"bytes,17,opt,name=format,proto3" json:"format,omitempty"`
|
||||
Order string `protobuf:"bytes,18,opt,name=order,proto3" json:"order,omitempty"`
|
||||
Dir string `protobuf:"bytes,19,opt,name=dir,proto3" json:"dir,omitempty"`
|
||||
Publishers []string `protobuf:"bytes,20,rep,name=publishers,proto3" json:"publishers,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *PageMetadata) Reset() {
|
||||
*x = PageMetadata{}
|
||||
mi := &file_readers_v1_readers_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *PageMetadata) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*PageMetadata) ProtoMessage() {}
|
||||
|
||||
func (x *PageMetadata) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_readers_v1_readers_proto_msgTypes[0]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use PageMetadata.ProtoReflect.Descriptor instead.
|
||||
func (*PageMetadata) Descriptor() ([]byte, []int) {
|
||||
return file_readers_v1_readers_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *PageMetadata) GetLimit() uint64 {
|
||||
if x != nil {
|
||||
return x.Limit
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *PageMetadata) GetOffset() uint64 {
|
||||
if x != nil {
|
||||
return x.Offset
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *PageMetadata) GetProtocol() string {
|
||||
if x != nil {
|
||||
return x.Protocol
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PageMetadata) GetName() string {
|
||||
if x != nil {
|
||||
return x.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PageMetadata) GetValue() float64 {
|
||||
if x != nil {
|
||||
return x.Value
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *PageMetadata) GetPublisher() string {
|
||||
if x != nil {
|
||||
return x.Publisher
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PageMetadata) GetBoolValue() bool {
|
||||
if x != nil {
|
||||
return x.BoolValue
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *PageMetadata) GetStringValue() string {
|
||||
if x != nil {
|
||||
return x.StringValue
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PageMetadata) GetDataValue() string {
|
||||
if x != nil {
|
||||
return x.DataValue
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PageMetadata) GetFrom() float64 {
|
||||
if x != nil {
|
||||
return x.From
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *PageMetadata) GetTo() float64 {
|
||||
if x != nil {
|
||||
return x.To
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *PageMetadata) GetSubtopic() string {
|
||||
if x != nil {
|
||||
return x.Subtopic
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PageMetadata) GetInterval() string {
|
||||
if x != nil {
|
||||
return x.Interval
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PageMetadata) GetRead() bool {
|
||||
if x != nil {
|
||||
return x.Read
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *PageMetadata) GetAggregation() Aggregation {
|
||||
if x != nil {
|
||||
return x.Aggregation
|
||||
}
|
||||
return Aggregation_AGGREGATION_UNSPECIFIED
|
||||
}
|
||||
|
||||
func (x *PageMetadata) GetComparator() string {
|
||||
if x != nil {
|
||||
return x.Comparator
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PageMetadata) GetFormat() string {
|
||||
if x != nil {
|
||||
return x.Format
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PageMetadata) GetOrder() string {
|
||||
if x != nil {
|
||||
return x.Order
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PageMetadata) GetDir() string {
|
||||
if x != nil {
|
||||
return x.Dir
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PageMetadata) GetPublishers() []string {
|
||||
if x != nil {
|
||||
return x.Publishers
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ReadMessagesRes struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Total uint64 `protobuf:"varint,1,opt,name=total,proto3" json:"total,omitempty"`
|
||||
PageMetadata *PageMetadata `protobuf:"bytes,2,opt,name=page_metadata,json=pageMetadata,proto3" json:"page_metadata,omitempty"`
|
||||
Messages []*Message `protobuf:"bytes,3,rep,name=messages,proto3" json:"messages,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ReadMessagesRes) Reset() {
|
||||
*x = ReadMessagesRes{}
|
||||
mi := &file_readers_v1_readers_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *ReadMessagesRes) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ReadMessagesRes) ProtoMessage() {}
|
||||
|
||||
func (x *ReadMessagesRes) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_readers_v1_readers_proto_msgTypes[1]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ReadMessagesRes.ProtoReflect.Descriptor instead.
|
||||
func (*ReadMessagesRes) Descriptor() ([]byte, []int) {
|
||||
return file_readers_v1_readers_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *ReadMessagesRes) GetTotal() uint64 {
|
||||
if x != nil {
|
||||
return x.Total
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *ReadMessagesRes) GetPageMetadata() *PageMetadata {
|
||||
if x != nil {
|
||||
return x.PageMetadata
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ReadMessagesRes) GetMessages() []*Message {
|
||||
if x != nil {
|
||||
return x.Messages
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Message struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
// Types that are valid to be assigned to Payload:
|
||||
//
|
||||
// *Message_Senml
|
||||
// *Message_Json
|
||||
Payload isMessage_Payload `protobuf_oneof:"payload"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *Message) Reset() {
|
||||
*x = Message{}
|
||||
mi := &file_readers_v1_readers_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *Message) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Message) ProtoMessage() {}
|
||||
|
||||
func (x *Message) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_readers_v1_readers_proto_msgTypes[2]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Message.ProtoReflect.Descriptor instead.
|
||||
func (*Message) Descriptor() ([]byte, []int) {
|
||||
return file_readers_v1_readers_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *Message) GetPayload() isMessage_Payload {
|
||||
if x != nil {
|
||||
return x.Payload
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Message) GetSenml() *SenMLMessage {
|
||||
if x != nil {
|
||||
if x, ok := x.Payload.(*Message_Senml); ok {
|
||||
return x.Senml
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Message) GetJson() *JsonMessage {
|
||||
if x != nil {
|
||||
if x, ok := x.Payload.(*Message_Json); ok {
|
||||
return x.Json
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type isMessage_Payload interface {
|
||||
isMessage_Payload()
|
||||
}
|
||||
|
||||
type Message_Senml struct {
|
||||
Senml *SenMLMessage `protobuf:"bytes,1,opt,name=senml,proto3,oneof"`
|
||||
}
|
||||
|
||||
type Message_Json struct {
|
||||
Json *JsonMessage `protobuf:"bytes,2,opt,name=json,proto3,oneof"`
|
||||
}
|
||||
|
||||
func (*Message_Senml) isMessage_Payload() {}
|
||||
|
||||
func (*Message_Json) isMessage_Payload() {}
|
||||
|
||||
type BaseMessage struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Channel string `protobuf:"bytes,1,opt,name=channel,proto3" json:"channel,omitempty"`
|
||||
Subtopic string `protobuf:"bytes,2,opt,name=subtopic,proto3" json:"subtopic,omitempty"`
|
||||
Publisher string `protobuf:"bytes,3,opt,name=publisher,proto3" json:"publisher,omitempty"`
|
||||
Protocol string `protobuf:"bytes,4,opt,name=protocol,proto3" json:"protocol,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *BaseMessage) Reset() {
|
||||
*x = BaseMessage{}
|
||||
mi := &file_readers_v1_readers_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *BaseMessage) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*BaseMessage) ProtoMessage() {}
|
||||
|
||||
func (x *BaseMessage) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_readers_v1_readers_proto_msgTypes[3]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use BaseMessage.ProtoReflect.Descriptor instead.
|
||||
func (*BaseMessage) Descriptor() ([]byte, []int) {
|
||||
return file_readers_v1_readers_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *BaseMessage) GetChannel() string {
|
||||
if x != nil {
|
||||
return x.Channel
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *BaseMessage) GetSubtopic() string {
|
||||
if x != nil {
|
||||
return x.Subtopic
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *BaseMessage) GetPublisher() string {
|
||||
if x != nil {
|
||||
return x.Publisher
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *BaseMessage) GetProtocol() string {
|
||||
if x != nil {
|
||||
return x.Protocol
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type SenMLMessage struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Base *BaseMessage `protobuf:"bytes,1,opt,name=base,proto3" json:"base,omitempty"`
|
||||
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Unit string `protobuf:"bytes,3,opt,name=unit,proto3" json:"unit,omitempty"`
|
||||
Time float64 `protobuf:"fixed64,4,opt,name=time,proto3" json:"time,omitempty"`
|
||||
UpdateTime float64 `protobuf:"fixed64,5,opt,name=update_time,json=updateTime,proto3" json:"update_time,omitempty"`
|
||||
Value *float64 `protobuf:"fixed64,6,opt,name=value,proto3,oneof" json:"value,omitempty"`
|
||||
StringValue *string `protobuf:"bytes,7,opt,name=string_value,json=stringValue,proto3,oneof" json:"string_value,omitempty"`
|
||||
DataValue *string `protobuf:"bytes,8,opt,name=data_value,json=dataValue,proto3,oneof" json:"data_value,omitempty"`
|
||||
BoolValue *bool `protobuf:"varint,9,opt,name=bool_value,json=boolValue,proto3,oneof" json:"bool_value,omitempty"`
|
||||
Sum *float64 `protobuf:"fixed64,10,opt,name=sum,proto3,oneof" json:"sum,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *SenMLMessage) Reset() {
|
||||
*x = SenMLMessage{}
|
||||
mi := &file_readers_v1_readers_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *SenMLMessage) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*SenMLMessage) ProtoMessage() {}
|
||||
|
||||
func (x *SenMLMessage) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_readers_v1_readers_proto_msgTypes[4]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use SenMLMessage.ProtoReflect.Descriptor instead.
|
||||
func (*SenMLMessage) Descriptor() ([]byte, []int) {
|
||||
return file_readers_v1_readers_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *SenMLMessage) GetBase() *BaseMessage {
|
||||
if x != nil {
|
||||
return x.Base
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *SenMLMessage) GetName() string {
|
||||
if x != nil {
|
||||
return x.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *SenMLMessage) GetUnit() string {
|
||||
if x != nil {
|
||||
return x.Unit
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *SenMLMessage) GetTime() float64 {
|
||||
if x != nil {
|
||||
return x.Time
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *SenMLMessage) GetUpdateTime() float64 {
|
||||
if x != nil {
|
||||
return x.UpdateTime
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *SenMLMessage) GetValue() float64 {
|
||||
if x != nil && x.Value != nil {
|
||||
return *x.Value
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *SenMLMessage) GetStringValue() string {
|
||||
if x != nil && x.StringValue != nil {
|
||||
return *x.StringValue
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *SenMLMessage) GetDataValue() string {
|
||||
if x != nil && x.DataValue != nil {
|
||||
return *x.DataValue
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *SenMLMessage) GetBoolValue() bool {
|
||||
if x != nil && x.BoolValue != nil {
|
||||
return *x.BoolValue
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *SenMLMessage) GetSum() float64 {
|
||||
if x != nil && x.Sum != nil {
|
||||
return *x.Sum
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type JsonMessage struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Base *BaseMessage `protobuf:"bytes,1,opt,name=base,proto3" json:"base,omitempty"`
|
||||
Created int64 `protobuf:"varint,2,opt,name=created,proto3" json:"created,omitempty"`
|
||||
Payload []byte `protobuf:"bytes,3,opt,name=payload,proto3" json:"payload,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *JsonMessage) Reset() {
|
||||
*x = JsonMessage{}
|
||||
mi := &file_readers_v1_readers_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *JsonMessage) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*JsonMessage) ProtoMessage() {}
|
||||
|
||||
func (x *JsonMessage) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_readers_v1_readers_proto_msgTypes[5]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use JsonMessage.ProtoReflect.Descriptor instead.
|
||||
func (*JsonMessage) Descriptor() ([]byte, []int) {
|
||||
return file_readers_v1_readers_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
func (x *JsonMessage) GetBase() *BaseMessage {
|
||||
if x != nil {
|
||||
return x.Base
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *JsonMessage) GetCreated() int64 {
|
||||
if x != nil {
|
||||
return x.Created
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *JsonMessage) GetPayload() []byte {
|
||||
if x != nil {
|
||||
return x.Payload
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ReadMessagesReq struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
ChannelId string `protobuf:"bytes,1,opt,name=channel_id,json=channelId,proto3" json:"channel_id,omitempty"`
|
||||
DomainId string `protobuf:"bytes,2,opt,name=domain_id,json=domainId,proto3" json:"domain_id,omitempty"`
|
||||
PageMetadata *PageMetadata `protobuf:"bytes,3,opt,name=page_metadata,json=pageMetadata,proto3" json:"page_metadata,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ReadMessagesReq) Reset() {
|
||||
*x = ReadMessagesReq{}
|
||||
mi := &file_readers_v1_readers_proto_msgTypes[6]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *ReadMessagesReq) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ReadMessagesReq) ProtoMessage() {}
|
||||
|
||||
func (x *ReadMessagesReq) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_readers_v1_readers_proto_msgTypes[6]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ReadMessagesReq.ProtoReflect.Descriptor instead.
|
||||
func (*ReadMessagesReq) Descriptor() ([]byte, []int) {
|
||||
return file_readers_v1_readers_proto_rawDescGZIP(), []int{6}
|
||||
}
|
||||
|
||||
func (x *ReadMessagesReq) GetChannelId() string {
|
||||
if x != nil {
|
||||
return x.ChannelId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ReadMessagesReq) GetDomainId() string {
|
||||
if x != nil {
|
||||
return x.DomainId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ReadMessagesReq) GetPageMetadata() *PageMetadata {
|
||||
if x != nil {
|
||||
return x.PageMetadata
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_readers_v1_readers_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_readers_v1_readers_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x18readers/v1/readers.proto\x12\n" +
|
||||
"readers.v1\"\xac\x04\n" +
|
||||
"\fPageMetadata\x12\x14\n" +
|
||||
"\x05limit\x18\x01 \x01(\x04R\x05limit\x12\x16\n" +
|
||||
"\x06offset\x18\x02 \x01(\x04R\x06offset\x12\x1a\n" +
|
||||
"\bprotocol\x18\x03 \x01(\tR\bprotocol\x12\x12\n" +
|
||||
"\x04name\x18\x04 \x01(\tR\x04name\x12\x14\n" +
|
||||
"\x05value\x18\x05 \x01(\x01R\x05value\x12\x1c\n" +
|
||||
"\tpublisher\x18\x06 \x01(\tR\tpublisher\x12\x1d\n" +
|
||||
"\n" +
|
||||
"bool_value\x18\a \x01(\bR\tboolValue\x12!\n" +
|
||||
"\fstring_value\x18\b \x01(\tR\vstringValue\x12\x1d\n" +
|
||||
"\n" +
|
||||
"data_value\x18\t \x01(\tR\tdataValue\x12\x12\n" +
|
||||
"\x04from\x18\n" +
|
||||
" \x01(\x01R\x04from\x12\x0e\n" +
|
||||
"\x02to\x18\v \x01(\x01R\x02to\x12\x1a\n" +
|
||||
"\bsubtopic\x18\f \x01(\tR\bsubtopic\x12\x1a\n" +
|
||||
"\binterval\x18\r \x01(\tR\binterval\x12\x12\n" +
|
||||
"\x04read\x18\x0e \x01(\bR\x04read\x129\n" +
|
||||
"\vaggregation\x18\x0f \x01(\x0e2\x17.readers.v1.AggregationR\vaggregation\x12\x1e\n" +
|
||||
"\n" +
|
||||
"comparator\x18\x10 \x01(\tR\n" +
|
||||
"comparator\x12\x16\n" +
|
||||
"\x06format\x18\x11 \x01(\tR\x06format\x12\x14\n" +
|
||||
"\x05order\x18\x12 \x01(\tR\x05order\x12\x10\n" +
|
||||
"\x03dir\x18\x13 \x01(\tR\x03dir\x12\x1e\n" +
|
||||
"\n" +
|
||||
"publishers\x18\x14 \x03(\tR\n" +
|
||||
"publishers\"\x97\x01\n" +
|
||||
"\x0fReadMessagesRes\x12\x14\n" +
|
||||
"\x05total\x18\x01 \x01(\x04R\x05total\x12=\n" +
|
||||
"\rpage_metadata\x18\x02 \x01(\v2\x18.readers.v1.PageMetadataR\fpageMetadata\x12/\n" +
|
||||
"\bmessages\x18\x03 \x03(\v2\x13.readers.v1.MessageR\bmessages\"u\n" +
|
||||
"\aMessage\x120\n" +
|
||||
"\x05senml\x18\x01 \x01(\v2\x18.readers.v1.SenMLMessageH\x00R\x05senml\x12-\n" +
|
||||
"\x04json\x18\x02 \x01(\v2\x17.readers.v1.JsonMessageH\x00R\x04jsonB\t\n" +
|
||||
"\apayload\"}\n" +
|
||||
"\vBaseMessage\x12\x18\n" +
|
||||
"\achannel\x18\x01 \x01(\tR\achannel\x12\x1a\n" +
|
||||
"\bsubtopic\x18\x02 \x01(\tR\bsubtopic\x12\x1c\n" +
|
||||
"\tpublisher\x18\x03 \x01(\tR\tpublisher\x12\x1a\n" +
|
||||
"\bprotocol\x18\x04 \x01(\tR\bprotocol\"\xfb\x02\n" +
|
||||
"\fSenMLMessage\x12+\n" +
|
||||
"\x04base\x18\x01 \x01(\v2\x17.readers.v1.BaseMessageR\x04base\x12\x12\n" +
|
||||
"\x04name\x18\x02 \x01(\tR\x04name\x12\x12\n" +
|
||||
"\x04unit\x18\x03 \x01(\tR\x04unit\x12\x12\n" +
|
||||
"\x04time\x18\x04 \x01(\x01R\x04time\x12\x1f\n" +
|
||||
"\vupdate_time\x18\x05 \x01(\x01R\n" +
|
||||
"updateTime\x12\x19\n" +
|
||||
"\x05value\x18\x06 \x01(\x01H\x00R\x05value\x88\x01\x01\x12&\n" +
|
||||
"\fstring_value\x18\a \x01(\tH\x01R\vstringValue\x88\x01\x01\x12\"\n" +
|
||||
"\n" +
|
||||
"data_value\x18\b \x01(\tH\x02R\tdataValue\x88\x01\x01\x12\"\n" +
|
||||
"\n" +
|
||||
"bool_value\x18\t \x01(\bH\x03R\tboolValue\x88\x01\x01\x12\x15\n" +
|
||||
"\x03sum\x18\n" +
|
||||
" \x01(\x01H\x04R\x03sum\x88\x01\x01B\b\n" +
|
||||
"\x06_valueB\x0f\n" +
|
||||
"\r_string_valueB\r\n" +
|
||||
"\v_data_valueB\r\n" +
|
||||
"\v_bool_valueB\x06\n" +
|
||||
"\x04_sum\"n\n" +
|
||||
"\vJsonMessage\x12+\n" +
|
||||
"\x04base\x18\x01 \x01(\v2\x17.readers.v1.BaseMessageR\x04base\x12\x18\n" +
|
||||
"\acreated\x18\x02 \x01(\x03R\acreated\x12\x18\n" +
|
||||
"\apayload\x18\x03 \x01(\fR\apayload\"\x8c\x01\n" +
|
||||
"\x0fReadMessagesReq\x12\x1d\n" +
|
||||
"\n" +
|
||||
"channel_id\x18\x01 \x01(\tR\tchannelId\x12\x1b\n" +
|
||||
"\tdomain_id\x18\x02 \x01(\tR\bdomainId\x12=\n" +
|
||||
"\rpage_metadata\x18\x03 \x01(\v2\x18.readers.v1.PageMetadataR\fpageMetadata*\x95\x01\n" +
|
||||
"\vAggregation\x12\x1b\n" +
|
||||
"\x17AGGREGATION_UNSPECIFIED\x10\x00\x12\x13\n" +
|
||||
"\x0fAGGREGATION_MAX\x10\x01\x12\x13\n" +
|
||||
"\x0fAGGREGATION_MIN\x10\x02\x12\x13\n" +
|
||||
"\x0fAGGREGATION_SUM\x10\x03\x12\x15\n" +
|
||||
"\x11AGGREGATION_COUNT\x10\x04\x12\x13\n" +
|
||||
"\x0fAGGREGATION_AVG\x10\x052\\\n" +
|
||||
"\x0eReadersService\x12J\n" +
|
||||
"\fReadMessages\x12\x1b.readers.v1.ReadMessagesReq\x1a\x1b.readers.v1.ReadMessagesRes\"\x00B3Z1github.com/absmach/magistrala/api/grpc/readers/v1b\x06proto3"
|
||||
|
||||
var (
|
||||
file_readers_v1_readers_proto_rawDescOnce sync.Once
|
||||
file_readers_v1_readers_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_readers_v1_readers_proto_rawDescGZIP() []byte {
|
||||
file_readers_v1_readers_proto_rawDescOnce.Do(func() {
|
||||
file_readers_v1_readers_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_readers_v1_readers_proto_rawDesc), len(file_readers_v1_readers_proto_rawDesc)))
|
||||
})
|
||||
return file_readers_v1_readers_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_readers_v1_readers_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
|
||||
var file_readers_v1_readers_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
|
||||
var file_readers_v1_readers_proto_goTypes = []any{
|
||||
(Aggregation)(0), // 0: readers.v1.Aggregation
|
||||
(*PageMetadata)(nil), // 1: readers.v1.PageMetadata
|
||||
(*ReadMessagesRes)(nil), // 2: readers.v1.ReadMessagesRes
|
||||
(*Message)(nil), // 3: readers.v1.Message
|
||||
(*BaseMessage)(nil), // 4: readers.v1.BaseMessage
|
||||
(*SenMLMessage)(nil), // 5: readers.v1.SenMLMessage
|
||||
(*JsonMessage)(nil), // 6: readers.v1.JsonMessage
|
||||
(*ReadMessagesReq)(nil), // 7: readers.v1.ReadMessagesReq
|
||||
}
|
||||
var file_readers_v1_readers_proto_depIdxs = []int32{
|
||||
0, // 0: readers.v1.PageMetadata.aggregation:type_name -> readers.v1.Aggregation
|
||||
1, // 1: readers.v1.ReadMessagesRes.page_metadata:type_name -> readers.v1.PageMetadata
|
||||
3, // 2: readers.v1.ReadMessagesRes.messages:type_name -> readers.v1.Message
|
||||
5, // 3: readers.v1.Message.senml:type_name -> readers.v1.SenMLMessage
|
||||
6, // 4: readers.v1.Message.json:type_name -> readers.v1.JsonMessage
|
||||
4, // 5: readers.v1.SenMLMessage.base:type_name -> readers.v1.BaseMessage
|
||||
4, // 6: readers.v1.JsonMessage.base:type_name -> readers.v1.BaseMessage
|
||||
1, // 7: readers.v1.ReadMessagesReq.page_metadata:type_name -> readers.v1.PageMetadata
|
||||
7, // 8: readers.v1.ReadersService.ReadMessages:input_type -> readers.v1.ReadMessagesReq
|
||||
2, // 9: readers.v1.ReadersService.ReadMessages:output_type -> readers.v1.ReadMessagesRes
|
||||
9, // [9:10] is the sub-list for method output_type
|
||||
8, // [8:9] is the sub-list for method input_type
|
||||
8, // [8:8] is the sub-list for extension type_name
|
||||
8, // [8:8] is the sub-list for extension extendee
|
||||
0, // [0:8] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_readers_v1_readers_proto_init() }
|
||||
func file_readers_v1_readers_proto_init() {
|
||||
if File_readers_v1_readers_proto != nil {
|
||||
return
|
||||
}
|
||||
file_readers_v1_readers_proto_msgTypes[2].OneofWrappers = []any{
|
||||
(*Message_Senml)(nil),
|
||||
(*Message_Json)(nil),
|
||||
}
|
||||
file_readers_v1_readers_proto_msgTypes[4].OneofWrappers = []any{}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_readers_v1_readers_proto_rawDesc), len(file_readers_v1_readers_proto_rawDesc)),
|
||||
NumEnums: 1,
|
||||
NumMessages: 7,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_readers_v1_readers_proto_goTypes,
|
||||
DependencyIndexes: file_readers_v1_readers_proto_depIdxs,
|
||||
EnumInfos: file_readers_v1_readers_proto_enumTypes,
|
||||
MessageInfos: file_readers_v1_readers_proto_msgTypes,
|
||||
}.Build()
|
||||
File_readers_v1_readers_proto = out.File
|
||||
file_readers_v1_readers_proto_goTypes = nil
|
||||
file_readers_v1_readers_proto_depIdxs = nil
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.6.2
|
||||
// - protoc v7.35.1
|
||||
// source: readers/v1/readers.proto
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
context "context"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.64.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion9
|
||||
|
||||
const (
|
||||
ReadersService_ReadMessages_FullMethodName = "/readers.v1.ReadersService/ReadMessages"
|
||||
)
|
||||
|
||||
// ReadersServiceClient is the client API for ReadersService service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
//
|
||||
// ReadersService is a service that provides access to
|
||||
// readers functionalities for Magistrala services.
|
||||
type ReadersServiceClient interface {
|
||||
ReadMessages(ctx context.Context, in *ReadMessagesReq, opts ...grpc.CallOption) (*ReadMessagesRes, error)
|
||||
}
|
||||
|
||||
type readersServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewReadersServiceClient(cc grpc.ClientConnInterface) ReadersServiceClient {
|
||||
return &readersServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *readersServiceClient) ReadMessages(ctx context.Context, in *ReadMessagesReq, opts ...grpc.CallOption) (*ReadMessagesRes, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(ReadMessagesRes)
|
||||
err := c.cc.Invoke(ctx, ReadersService_ReadMessages_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// ReadersServiceServer is the server API for ReadersService service.
|
||||
// All implementations must embed UnimplementedReadersServiceServer
|
||||
// for forward compatibility.
|
||||
//
|
||||
// ReadersService is a service that provides access to
|
||||
// readers functionalities for Magistrala services.
|
||||
type ReadersServiceServer interface {
|
||||
ReadMessages(context.Context, *ReadMessagesReq) (*ReadMessagesRes, error)
|
||||
mustEmbedUnimplementedReadersServiceServer()
|
||||
}
|
||||
|
||||
// UnimplementedReadersServiceServer must be embedded to have
|
||||
// forward compatible implementations.
|
||||
//
|
||||
// NOTE: this should be embedded by value instead of pointer to avoid a nil
|
||||
// pointer dereference when methods are called.
|
||||
type UnimplementedReadersServiceServer struct{}
|
||||
|
||||
func (UnimplementedReadersServiceServer) ReadMessages(context.Context, *ReadMessagesReq) (*ReadMessagesRes, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method ReadMessages not implemented")
|
||||
}
|
||||
func (UnimplementedReadersServiceServer) mustEmbedUnimplementedReadersServiceServer() {}
|
||||
func (UnimplementedReadersServiceServer) testEmbeddedByValue() {}
|
||||
|
||||
// UnsafeReadersServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to ReadersServiceServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeReadersServiceServer interface {
|
||||
mustEmbedUnimplementedReadersServiceServer()
|
||||
}
|
||||
|
||||
func RegisterReadersServiceServer(s grpc.ServiceRegistrar, srv ReadersServiceServer) {
|
||||
// If the following call panics, it indicates UnimplementedReadersServiceServer was
|
||||
// embedded by pointer and is nil. This will cause panics if an
|
||||
// unimplemented method is ever invoked, so we test this at initialization
|
||||
// time to prevent it from happening at runtime later due to I/O.
|
||||
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
|
||||
t.testEmbeddedByValue()
|
||||
}
|
||||
s.RegisterService(&ReadersService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _ReadersService_ReadMessages_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ReadMessagesReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ReadersServiceServer).ReadMessages(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ReadersService_ReadMessages_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ReadersServiceServer).ReadMessages(ctx, req.(*ReadMessagesReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// ReadersService_ServiceDesc is the grpc.ServiceDesc for ReadersService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var ReadersService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "readers.v1.ReadersService",
|
||||
HandlerType: (*ReadersServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "ReadMessages",
|
||||
Handler: _ReadersService_ReadMessages_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "readers/v1/readers.proto",
|
||||
}
|
||||
@@ -0,0 +1,547 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.11
|
||||
// protoc v7.35.1
|
||||
// source: token/v1/token.proto
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type IssueReq struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
|
||||
UserRole uint32 `protobuf:"varint,2,opt,name=user_role,json=userRole,proto3" json:"user_role,omitempty"`
|
||||
Type uint32 `protobuf:"varint,3,opt,name=type,proto3" json:"type,omitempty"`
|
||||
Verified bool `protobuf:"varint,4,opt,name=verified,proto3" json:"verified,omitempty"`
|
||||
Description string `protobuf:"bytes,5,opt,name=description,proto3" json:"description,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *IssueReq) Reset() {
|
||||
*x = IssueReq{}
|
||||
mi := &file_token_v1_token_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *IssueReq) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*IssueReq) ProtoMessage() {}
|
||||
|
||||
func (x *IssueReq) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_token_v1_token_proto_msgTypes[0]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use IssueReq.ProtoReflect.Descriptor instead.
|
||||
func (*IssueReq) Descriptor() ([]byte, []int) {
|
||||
return file_token_v1_token_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *IssueReq) GetUserId() string {
|
||||
if x != nil {
|
||||
return x.UserId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *IssueReq) GetUserRole() uint32 {
|
||||
if x != nil {
|
||||
return x.UserRole
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *IssueReq) GetType() uint32 {
|
||||
if x != nil {
|
||||
return x.Type
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *IssueReq) GetVerified() bool {
|
||||
if x != nil {
|
||||
return x.Verified
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *IssueReq) GetDescription() string {
|
||||
if x != nil {
|
||||
return x.Description
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type RefreshReq struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
RefreshToken string `protobuf:"bytes,1,opt,name=refresh_token,json=refreshToken,proto3" json:"refresh_token,omitempty"`
|
||||
Verified bool `protobuf:"varint,2,opt,name=verified,proto3" json:"verified,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *RefreshReq) Reset() {
|
||||
*x = RefreshReq{}
|
||||
mi := &file_token_v1_token_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *RefreshReq) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*RefreshReq) ProtoMessage() {}
|
||||
|
||||
func (x *RefreshReq) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_token_v1_token_proto_msgTypes[1]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use RefreshReq.ProtoReflect.Descriptor instead.
|
||||
func (*RefreshReq) Descriptor() ([]byte, []int) {
|
||||
return file_token_v1_token_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *RefreshReq) GetRefreshToken() string {
|
||||
if x != nil {
|
||||
return x.RefreshToken
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *RefreshReq) GetVerified() bool {
|
||||
if x != nil {
|
||||
return x.Verified
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type RevokeReq struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
TokenId string `protobuf:"bytes,1,opt,name=token_id,json=tokenId,proto3" json:"token_id,omitempty"`
|
||||
UserId string `protobuf:"bytes,2,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *RevokeReq) Reset() {
|
||||
*x = RevokeReq{}
|
||||
mi := &file_token_v1_token_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *RevokeReq) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*RevokeReq) ProtoMessage() {}
|
||||
|
||||
func (x *RevokeReq) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_token_v1_token_proto_msgTypes[2]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use RevokeReq.ProtoReflect.Descriptor instead.
|
||||
func (*RevokeReq) Descriptor() ([]byte, []int) {
|
||||
return file_token_v1_token_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *RevokeReq) GetTokenId() string {
|
||||
if x != nil {
|
||||
return x.TokenId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *RevokeReq) GetUserId() string {
|
||||
if x != nil {
|
||||
return x.UserId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// If a token is not carrying any information itself, the type
|
||||
// field can be used to determine how to validate the token.
|
||||
// Also, different tokens can be encoded in different ways.
|
||||
type Token struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
AccessToken string `protobuf:"bytes,1,opt,name=access_token,json=accessToken,proto3" json:"access_token,omitempty"`
|
||||
RefreshToken *string `protobuf:"bytes,2,opt,name=refresh_token,json=refreshToken,proto3,oneof" json:"refresh_token,omitempty"`
|
||||
AccessType string `protobuf:"bytes,3,opt,name=access_type,json=accessType,proto3" json:"access_type,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *Token) Reset() {
|
||||
*x = Token{}
|
||||
mi := &file_token_v1_token_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *Token) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Token) ProtoMessage() {}
|
||||
|
||||
func (x *Token) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_token_v1_token_proto_msgTypes[3]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Token.ProtoReflect.Descriptor instead.
|
||||
func (*Token) Descriptor() ([]byte, []int) {
|
||||
return file_token_v1_token_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *Token) GetAccessToken() string {
|
||||
if x != nil {
|
||||
return x.AccessToken
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Token) GetRefreshToken() string {
|
||||
if x != nil && x.RefreshToken != nil {
|
||||
return *x.RefreshToken
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Token) GetAccessType() string {
|
||||
if x != nil {
|
||||
return x.AccessType
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type RevokeRes struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *RevokeRes) Reset() {
|
||||
*x = RevokeRes{}
|
||||
mi := &file_token_v1_token_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *RevokeRes) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*RevokeRes) ProtoMessage() {}
|
||||
|
||||
func (x *RevokeRes) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_token_v1_token_proto_msgTypes[4]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use RevokeRes.ProtoReflect.Descriptor instead.
|
||||
func (*RevokeRes) Descriptor() ([]byte, []int) {
|
||||
return file_token_v1_token_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
type ListUserRefreshTokensReq struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ListUserRefreshTokensReq) Reset() {
|
||||
*x = ListUserRefreshTokensReq{}
|
||||
mi := &file_token_v1_token_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *ListUserRefreshTokensReq) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ListUserRefreshTokensReq) ProtoMessage() {}
|
||||
|
||||
func (x *ListUserRefreshTokensReq) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_token_v1_token_proto_msgTypes[5]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ListUserRefreshTokensReq.ProtoReflect.Descriptor instead.
|
||||
func (*ListUserRefreshTokensReq) Descriptor() ([]byte, []int) {
|
||||
return file_token_v1_token_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
func (x *ListUserRefreshTokensReq) GetUserId() string {
|
||||
if x != nil {
|
||||
return x.UserId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type ListUserRefreshTokensRes struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
RefreshTokens []*RefreshToken `protobuf:"bytes,1,rep,name=refresh_tokens,json=refreshTokens,proto3" json:"refresh_tokens,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ListUserRefreshTokensRes) Reset() {
|
||||
*x = ListUserRefreshTokensRes{}
|
||||
mi := &file_token_v1_token_proto_msgTypes[6]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *ListUserRefreshTokensRes) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ListUserRefreshTokensRes) ProtoMessage() {}
|
||||
|
||||
func (x *ListUserRefreshTokensRes) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_token_v1_token_proto_msgTypes[6]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ListUserRefreshTokensRes.ProtoReflect.Descriptor instead.
|
||||
func (*ListUserRefreshTokensRes) Descriptor() ([]byte, []int) {
|
||||
return file_token_v1_token_proto_rawDescGZIP(), []int{6}
|
||||
}
|
||||
|
||||
func (x *ListUserRefreshTokensRes) GetRefreshTokens() []*RefreshToken {
|
||||
if x != nil {
|
||||
return x.RefreshTokens
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type RefreshToken struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *RefreshToken) Reset() {
|
||||
*x = RefreshToken{}
|
||||
mi := &file_token_v1_token_proto_msgTypes[7]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *RefreshToken) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*RefreshToken) ProtoMessage() {}
|
||||
|
||||
func (x *RefreshToken) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_token_v1_token_proto_msgTypes[7]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use RefreshToken.ProtoReflect.Descriptor instead.
|
||||
func (*RefreshToken) Descriptor() ([]byte, []int) {
|
||||
return file_token_v1_token_proto_rawDescGZIP(), []int{7}
|
||||
}
|
||||
|
||||
func (x *RefreshToken) GetId() string {
|
||||
if x != nil {
|
||||
return x.Id
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *RefreshToken) GetDescription() string {
|
||||
if x != nil {
|
||||
return x.Description
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var File_token_v1_token_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_token_v1_token_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x14token/v1/token.proto\x12\btoken.v1\"\x92\x01\n" +
|
||||
"\bIssueReq\x12\x17\n" +
|
||||
"\auser_id\x18\x01 \x01(\tR\x06userId\x12\x1b\n" +
|
||||
"\tuser_role\x18\x02 \x01(\rR\buserRole\x12\x12\n" +
|
||||
"\x04type\x18\x03 \x01(\rR\x04type\x12\x1a\n" +
|
||||
"\bverified\x18\x04 \x01(\bR\bverified\x12 \n" +
|
||||
"\vdescription\x18\x05 \x01(\tR\vdescription\"M\n" +
|
||||
"\n" +
|
||||
"RefreshReq\x12#\n" +
|
||||
"\rrefresh_token\x18\x01 \x01(\tR\frefreshToken\x12\x1a\n" +
|
||||
"\bverified\x18\x02 \x01(\bR\bverified\"?\n" +
|
||||
"\tRevokeReq\x12\x19\n" +
|
||||
"\btoken_id\x18\x01 \x01(\tR\atokenId\x12\x17\n" +
|
||||
"\auser_id\x18\x02 \x01(\tR\x06userId\"\x87\x01\n" +
|
||||
"\x05Token\x12!\n" +
|
||||
"\faccess_token\x18\x01 \x01(\tR\vaccessToken\x12(\n" +
|
||||
"\rrefresh_token\x18\x02 \x01(\tH\x00R\frefreshToken\x88\x01\x01\x12\x1f\n" +
|
||||
"\vaccess_type\x18\x03 \x01(\tR\n" +
|
||||
"accessTypeB\x10\n" +
|
||||
"\x0e_refresh_token\"\v\n" +
|
||||
"\tRevokeRes\"3\n" +
|
||||
"\x18ListUserRefreshTokensReq\x12\x17\n" +
|
||||
"\auser_id\x18\x01 \x01(\tR\x06userId\"Y\n" +
|
||||
"\x18ListUserRefreshTokensRes\x12=\n" +
|
||||
"\x0erefresh_tokens\x18\x01 \x03(\v2\x16.token.v1.RefreshTokenR\rrefreshTokens\"@\n" +
|
||||
"\fRefreshToken\x12\x0e\n" +
|
||||
"\x02id\x18\x01 \x01(\tR\x02id\x12 \n" +
|
||||
"\vdescription\x18\x02 \x01(\tR\vdescription2\x8b\x02\n" +
|
||||
"\fTokenService\x12.\n" +
|
||||
"\x05Issue\x12\x12.token.v1.IssueReq\x1a\x0f.token.v1.Token\"\x00\x122\n" +
|
||||
"\aRefresh\x12\x14.token.v1.RefreshReq\x1a\x0f.token.v1.Token\"\x00\x124\n" +
|
||||
"\x06Revoke\x12\x13.token.v1.RevokeReq\x1a\x13.token.v1.RevokeRes\"\x00\x12a\n" +
|
||||
"\x15ListUserRefreshTokens\x12\".token.v1.ListUserRefreshTokensReq\x1a\".token.v1.ListUserRefreshTokensRes\"\x00B1Z/github.com/absmach/magistrala/api/grpc/token/v1b\x06proto3"
|
||||
|
||||
var (
|
||||
file_token_v1_token_proto_rawDescOnce sync.Once
|
||||
file_token_v1_token_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_token_v1_token_proto_rawDescGZIP() []byte {
|
||||
file_token_v1_token_proto_rawDescOnce.Do(func() {
|
||||
file_token_v1_token_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_token_v1_token_proto_rawDesc), len(file_token_v1_token_proto_rawDesc)))
|
||||
})
|
||||
return file_token_v1_token_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_token_v1_token_proto_msgTypes = make([]protoimpl.MessageInfo, 8)
|
||||
var file_token_v1_token_proto_goTypes = []any{
|
||||
(*IssueReq)(nil), // 0: token.v1.IssueReq
|
||||
(*RefreshReq)(nil), // 1: token.v1.RefreshReq
|
||||
(*RevokeReq)(nil), // 2: token.v1.RevokeReq
|
||||
(*Token)(nil), // 3: token.v1.Token
|
||||
(*RevokeRes)(nil), // 4: token.v1.RevokeRes
|
||||
(*ListUserRefreshTokensReq)(nil), // 5: token.v1.ListUserRefreshTokensReq
|
||||
(*ListUserRefreshTokensRes)(nil), // 6: token.v1.ListUserRefreshTokensRes
|
||||
(*RefreshToken)(nil), // 7: token.v1.RefreshToken
|
||||
}
|
||||
var file_token_v1_token_proto_depIdxs = []int32{
|
||||
7, // 0: token.v1.ListUserRefreshTokensRes.refresh_tokens:type_name -> token.v1.RefreshToken
|
||||
0, // 1: token.v1.TokenService.Issue:input_type -> token.v1.IssueReq
|
||||
1, // 2: token.v1.TokenService.Refresh:input_type -> token.v1.RefreshReq
|
||||
2, // 3: token.v1.TokenService.Revoke:input_type -> token.v1.RevokeReq
|
||||
5, // 4: token.v1.TokenService.ListUserRefreshTokens:input_type -> token.v1.ListUserRefreshTokensReq
|
||||
3, // 5: token.v1.TokenService.Issue:output_type -> token.v1.Token
|
||||
3, // 6: token.v1.TokenService.Refresh:output_type -> token.v1.Token
|
||||
4, // 7: token.v1.TokenService.Revoke:output_type -> token.v1.RevokeRes
|
||||
6, // 8: token.v1.TokenService.ListUserRefreshTokens:output_type -> token.v1.ListUserRefreshTokensRes
|
||||
5, // [5:9] is the sub-list for method output_type
|
||||
1, // [1:5] is the sub-list for method input_type
|
||||
1, // [1:1] is the sub-list for extension type_name
|
||||
1, // [1:1] is the sub-list for extension extendee
|
||||
0, // [0:1] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_token_v1_token_proto_init() }
|
||||
func file_token_v1_token_proto_init() {
|
||||
if File_token_v1_token_proto != nil {
|
||||
return
|
||||
}
|
||||
file_token_v1_token_proto_msgTypes[3].OneofWrappers = []any{}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_token_v1_token_proto_rawDesc), len(file_token_v1_token_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 8,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_token_v1_token_proto_goTypes,
|
||||
DependencyIndexes: file_token_v1_token_proto_depIdxs,
|
||||
MessageInfos: file_token_v1_token_proto_msgTypes,
|
||||
}.Build()
|
||||
File_token_v1_token_proto = out.File
|
||||
file_token_v1_token_proto_goTypes = nil
|
||||
file_token_v1_token_proto_depIdxs = nil
|
||||
}
|
||||
@@ -0,0 +1,238 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.6.2
|
||||
// - protoc v7.35.1
|
||||
// source: token/v1/token.proto
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
context "context"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.64.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion9
|
||||
|
||||
const (
|
||||
TokenService_Issue_FullMethodName = "/token.v1.TokenService/Issue"
|
||||
TokenService_Refresh_FullMethodName = "/token.v1.TokenService/Refresh"
|
||||
TokenService_Revoke_FullMethodName = "/token.v1.TokenService/Revoke"
|
||||
TokenService_ListUserRefreshTokens_FullMethodName = "/token.v1.TokenService/ListUserRefreshTokens"
|
||||
)
|
||||
|
||||
// TokenServiceClient is the client API for TokenService service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type TokenServiceClient interface {
|
||||
Issue(ctx context.Context, in *IssueReq, opts ...grpc.CallOption) (*Token, error)
|
||||
Refresh(ctx context.Context, in *RefreshReq, opts ...grpc.CallOption) (*Token, error)
|
||||
Revoke(ctx context.Context, in *RevokeReq, opts ...grpc.CallOption) (*RevokeRes, error)
|
||||
ListUserRefreshTokens(ctx context.Context, in *ListUserRefreshTokensReq, opts ...grpc.CallOption) (*ListUserRefreshTokensRes, error)
|
||||
}
|
||||
|
||||
type tokenServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewTokenServiceClient(cc grpc.ClientConnInterface) TokenServiceClient {
|
||||
return &tokenServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *tokenServiceClient) Issue(ctx context.Context, in *IssueReq, opts ...grpc.CallOption) (*Token, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(Token)
|
||||
err := c.cc.Invoke(ctx, TokenService_Issue_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *tokenServiceClient) Refresh(ctx context.Context, in *RefreshReq, opts ...grpc.CallOption) (*Token, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(Token)
|
||||
err := c.cc.Invoke(ctx, TokenService_Refresh_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *tokenServiceClient) Revoke(ctx context.Context, in *RevokeReq, opts ...grpc.CallOption) (*RevokeRes, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(RevokeRes)
|
||||
err := c.cc.Invoke(ctx, TokenService_Revoke_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *tokenServiceClient) ListUserRefreshTokens(ctx context.Context, in *ListUserRefreshTokensReq, opts ...grpc.CallOption) (*ListUserRefreshTokensRes, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(ListUserRefreshTokensRes)
|
||||
err := c.cc.Invoke(ctx, TokenService_ListUserRefreshTokens_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// TokenServiceServer is the server API for TokenService service.
|
||||
// All implementations must embed UnimplementedTokenServiceServer
|
||||
// for forward compatibility.
|
||||
type TokenServiceServer interface {
|
||||
Issue(context.Context, *IssueReq) (*Token, error)
|
||||
Refresh(context.Context, *RefreshReq) (*Token, error)
|
||||
Revoke(context.Context, *RevokeReq) (*RevokeRes, error)
|
||||
ListUserRefreshTokens(context.Context, *ListUserRefreshTokensReq) (*ListUserRefreshTokensRes, error)
|
||||
mustEmbedUnimplementedTokenServiceServer()
|
||||
}
|
||||
|
||||
// UnimplementedTokenServiceServer must be embedded to have
|
||||
// forward compatible implementations.
|
||||
//
|
||||
// NOTE: this should be embedded by value instead of pointer to avoid a nil
|
||||
// pointer dereference when methods are called.
|
||||
type UnimplementedTokenServiceServer struct{}
|
||||
|
||||
func (UnimplementedTokenServiceServer) Issue(context.Context, *IssueReq) (*Token, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method Issue not implemented")
|
||||
}
|
||||
func (UnimplementedTokenServiceServer) Refresh(context.Context, *RefreshReq) (*Token, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method Refresh not implemented")
|
||||
}
|
||||
func (UnimplementedTokenServiceServer) Revoke(context.Context, *RevokeReq) (*RevokeRes, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method Revoke not implemented")
|
||||
}
|
||||
func (UnimplementedTokenServiceServer) ListUserRefreshTokens(context.Context, *ListUserRefreshTokensReq) (*ListUserRefreshTokensRes, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method ListUserRefreshTokens not implemented")
|
||||
}
|
||||
func (UnimplementedTokenServiceServer) mustEmbedUnimplementedTokenServiceServer() {}
|
||||
func (UnimplementedTokenServiceServer) testEmbeddedByValue() {}
|
||||
|
||||
// UnsafeTokenServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to TokenServiceServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeTokenServiceServer interface {
|
||||
mustEmbedUnimplementedTokenServiceServer()
|
||||
}
|
||||
|
||||
func RegisterTokenServiceServer(s grpc.ServiceRegistrar, srv TokenServiceServer) {
|
||||
// If the following call panics, it indicates UnimplementedTokenServiceServer was
|
||||
// embedded by pointer and is nil. This will cause panics if an
|
||||
// unimplemented method is ever invoked, so we test this at initialization
|
||||
// time to prevent it from happening at runtime later due to I/O.
|
||||
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
|
||||
t.testEmbeddedByValue()
|
||||
}
|
||||
s.RegisterService(&TokenService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _TokenService_Issue_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(IssueReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(TokenServiceServer).Issue(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: TokenService_Issue_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(TokenServiceServer).Issue(ctx, req.(*IssueReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _TokenService_Refresh_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(RefreshReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(TokenServiceServer).Refresh(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: TokenService_Refresh_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(TokenServiceServer).Refresh(ctx, req.(*RefreshReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _TokenService_Revoke_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(RevokeReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(TokenServiceServer).Revoke(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: TokenService_Revoke_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(TokenServiceServer).Revoke(ctx, req.(*RevokeReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _TokenService_ListUserRefreshTokens_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ListUserRefreshTokensReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(TokenServiceServer).ListUserRefreshTokens(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: TokenService_ListUserRefreshTokens_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(TokenServiceServer).ListUserRefreshTokens(ctx, req.(*ListUserRefreshTokensReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// TokenService_ServiceDesc is the grpc.ServiceDesc for TokenService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var TokenService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "token.v1.TokenService",
|
||||
HandlerType: (*TokenServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "Issue",
|
||||
Handler: _TokenService_Issue_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Refresh",
|
||||
Handler: _TokenService_Refresh_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Revoke",
|
||||
Handler: _TokenService_Revoke_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "ListUserRefreshTokens",
|
||||
Handler: _TokenService_ListUserRefreshTokens_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "token/v1/token.proto",
|
||||
}
|
||||
@@ -0,0 +1,428 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.11
|
||||
// protoc v7.35.1
|
||||
// source: users/v1/users.proto
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
structpb "google.golang.org/protobuf/types/known/structpb"
|
||||
timestamppb "google.golang.org/protobuf/types/known/timestamppb"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type RetrieveUsersReq struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Ids []string `protobuf:"bytes,1,rep,name=ids,proto3" json:"ids,omitempty"`
|
||||
Offset uint64 `protobuf:"varint,2,opt,name=offset,proto3" json:"offset,omitempty"`
|
||||
Limit uint64 `protobuf:"varint,3,opt,name=limit,proto3" json:"limit,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *RetrieveUsersReq) Reset() {
|
||||
*x = RetrieveUsersReq{}
|
||||
mi := &file_users_v1_users_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *RetrieveUsersReq) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*RetrieveUsersReq) ProtoMessage() {}
|
||||
|
||||
func (x *RetrieveUsersReq) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_users_v1_users_proto_msgTypes[0]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use RetrieveUsersReq.ProtoReflect.Descriptor instead.
|
||||
func (*RetrieveUsersReq) Descriptor() ([]byte, []int) {
|
||||
return file_users_v1_users_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *RetrieveUsersReq) GetIds() []string {
|
||||
if x != nil {
|
||||
return x.Ids
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *RetrieveUsersReq) GetOffset() uint64 {
|
||||
if x != nil {
|
||||
return x.Offset
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *RetrieveUsersReq) GetLimit() uint64 {
|
||||
if x != nil {
|
||||
return x.Limit
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type RetrieveUsersRes struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Total uint64 `protobuf:"varint,1,opt,name=total,proto3" json:"total,omitempty"`
|
||||
Limit uint64 `protobuf:"varint,2,opt,name=limit,proto3" json:"limit,omitempty"`
|
||||
Offset uint64 `protobuf:"varint,3,opt,name=offset,proto3" json:"offset,omitempty"`
|
||||
Users []*User `protobuf:"bytes,4,rep,name=users,proto3" json:"users,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *RetrieveUsersRes) Reset() {
|
||||
*x = RetrieveUsersRes{}
|
||||
mi := &file_users_v1_users_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *RetrieveUsersRes) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*RetrieveUsersRes) ProtoMessage() {}
|
||||
|
||||
func (x *RetrieveUsersRes) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_users_v1_users_proto_msgTypes[1]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use RetrieveUsersRes.ProtoReflect.Descriptor instead.
|
||||
func (*RetrieveUsersRes) Descriptor() ([]byte, []int) {
|
||||
return file_users_v1_users_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *RetrieveUsersRes) GetTotal() uint64 {
|
||||
if x != nil {
|
||||
return x.Total
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *RetrieveUsersRes) GetLimit() uint64 {
|
||||
if x != nil {
|
||||
return x.Limit
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *RetrieveUsersRes) GetOffset() uint64 {
|
||||
if x != nil {
|
||||
return x.Offset
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *RetrieveUsersRes) GetUsers() []*User {
|
||||
if x != nil {
|
||||
return x.Users
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type User struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
FirstName string `protobuf:"bytes,2,opt,name=first_name,json=firstName,proto3" json:"first_name,omitempty"`
|
||||
LastName string `protobuf:"bytes,3,opt,name=last_name,json=lastName,proto3" json:"last_name,omitempty"`
|
||||
Tags []string `protobuf:"bytes,4,rep,name=tags,proto3" json:"tags,omitempty"`
|
||||
Metadata *structpb.Struct `protobuf:"bytes,5,opt,name=metadata,proto3" json:"metadata,omitempty"`
|
||||
PrivateMetadata *structpb.Struct `protobuf:"bytes,6,opt,name=private_metadata,json=privateMetadata,proto3" json:"private_metadata,omitempty"`
|
||||
Status uint32 `protobuf:"varint,7,opt,name=status,proto3" json:"status,omitempty"`
|
||||
Role uint32 `protobuf:"varint,8,opt,name=role,proto3" json:"role,omitempty"`
|
||||
ProfilePicture string `protobuf:"bytes,9,opt,name=profile_picture,json=profilePicture,proto3" json:"profile_picture,omitempty"`
|
||||
Username string `protobuf:"bytes,10,opt,name=username,proto3" json:"username,omitempty"`
|
||||
Email string `protobuf:"bytes,11,opt,name=email,proto3" json:"email,omitempty"`
|
||||
CreatedAt *timestamppb.Timestamp `protobuf:"bytes,12,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
|
||||
UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,13,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"`
|
||||
UpdatedBy string `protobuf:"bytes,14,opt,name=updated_by,json=updatedBy,proto3" json:"updated_by,omitempty"`
|
||||
VerifiedAt *timestamppb.Timestamp `protobuf:"bytes,15,opt,name=verified_at,json=verifiedAt,proto3" json:"verified_at,omitempty"`
|
||||
AuthProvider string `protobuf:"bytes,16,opt,name=auth_provider,json=authProvider,proto3" json:"auth_provider,omitempty"`
|
||||
Permissions []string `protobuf:"bytes,17,rep,name=permissions,proto3" json:"permissions,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *User) Reset() {
|
||||
*x = User{}
|
||||
mi := &file_users_v1_users_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *User) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*User) ProtoMessage() {}
|
||||
|
||||
func (x *User) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_users_v1_users_proto_msgTypes[2]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use User.ProtoReflect.Descriptor instead.
|
||||
func (*User) Descriptor() ([]byte, []int) {
|
||||
return file_users_v1_users_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *User) GetId() string {
|
||||
if x != nil {
|
||||
return x.Id
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *User) GetFirstName() string {
|
||||
if x != nil {
|
||||
return x.FirstName
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *User) GetLastName() string {
|
||||
if x != nil {
|
||||
return x.LastName
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *User) GetTags() []string {
|
||||
if x != nil {
|
||||
return x.Tags
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *User) GetMetadata() *structpb.Struct {
|
||||
if x != nil {
|
||||
return x.Metadata
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *User) GetPrivateMetadata() *structpb.Struct {
|
||||
if x != nil {
|
||||
return x.PrivateMetadata
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *User) GetStatus() uint32 {
|
||||
if x != nil {
|
||||
return x.Status
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *User) GetRole() uint32 {
|
||||
if x != nil {
|
||||
return x.Role
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *User) GetProfilePicture() string {
|
||||
if x != nil {
|
||||
return x.ProfilePicture
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *User) GetUsername() string {
|
||||
if x != nil {
|
||||
return x.Username
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *User) GetEmail() string {
|
||||
if x != nil {
|
||||
return x.Email
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *User) GetCreatedAt() *timestamppb.Timestamp {
|
||||
if x != nil {
|
||||
return x.CreatedAt
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *User) GetUpdatedAt() *timestamppb.Timestamp {
|
||||
if x != nil {
|
||||
return x.UpdatedAt
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *User) GetUpdatedBy() string {
|
||||
if x != nil {
|
||||
return x.UpdatedBy
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *User) GetVerifiedAt() *timestamppb.Timestamp {
|
||||
if x != nil {
|
||||
return x.VerifiedAt
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *User) GetAuthProvider() string {
|
||||
if x != nil {
|
||||
return x.AuthProvider
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *User) GetPermissions() []string {
|
||||
if x != nil {
|
||||
return x.Permissions
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_users_v1_users_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_users_v1_users_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x14users/v1/users.proto\x12\busers.v1\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"R\n" +
|
||||
"\x10RetrieveUsersReq\x12\x10\n" +
|
||||
"\x03ids\x18\x01 \x03(\tR\x03ids\x12\x16\n" +
|
||||
"\x06offset\x18\x02 \x01(\x04R\x06offset\x12\x14\n" +
|
||||
"\x05limit\x18\x03 \x01(\x04R\x05limit\"|\n" +
|
||||
"\x10RetrieveUsersRes\x12\x14\n" +
|
||||
"\x05total\x18\x01 \x01(\x04R\x05total\x12\x14\n" +
|
||||
"\x05limit\x18\x02 \x01(\x04R\x05limit\x12\x16\n" +
|
||||
"\x06offset\x18\x03 \x01(\x04R\x06offset\x12$\n" +
|
||||
"\x05users\x18\x04 \x03(\v2\x0e.users.v1.UserR\x05users\"\xff\x04\n" +
|
||||
"\x04User\x12\x0e\n" +
|
||||
"\x02id\x18\x01 \x01(\tR\x02id\x12\x1d\n" +
|
||||
"\n" +
|
||||
"first_name\x18\x02 \x01(\tR\tfirstName\x12\x1b\n" +
|
||||
"\tlast_name\x18\x03 \x01(\tR\blastName\x12\x12\n" +
|
||||
"\x04tags\x18\x04 \x03(\tR\x04tags\x123\n" +
|
||||
"\bmetadata\x18\x05 \x01(\v2\x17.google.protobuf.StructR\bmetadata\x12B\n" +
|
||||
"\x10private_metadata\x18\x06 \x01(\v2\x17.google.protobuf.StructR\x0fprivateMetadata\x12\x16\n" +
|
||||
"\x06status\x18\a \x01(\rR\x06status\x12\x12\n" +
|
||||
"\x04role\x18\b \x01(\rR\x04role\x12'\n" +
|
||||
"\x0fprofile_picture\x18\t \x01(\tR\x0eprofilePicture\x12\x1a\n" +
|
||||
"\busername\x18\n" +
|
||||
" \x01(\tR\busername\x12\x14\n" +
|
||||
"\x05email\x18\v \x01(\tR\x05email\x129\n" +
|
||||
"\n" +
|
||||
"created_at\x18\f \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\x129\n" +
|
||||
"\n" +
|
||||
"updated_at\x18\r \x01(\v2\x1a.google.protobuf.TimestampR\tupdatedAt\x12\x1d\n" +
|
||||
"\n" +
|
||||
"updated_by\x18\x0e \x01(\tR\tupdatedBy\x12;\n" +
|
||||
"\vverified_at\x18\x0f \x01(\v2\x1a.google.protobuf.TimestampR\n" +
|
||||
"verifiedAt\x12#\n" +
|
||||
"\rauth_provider\x18\x10 \x01(\tR\fauthProvider\x12 \n" +
|
||||
"\vpermissions\x18\x11 \x03(\tR\vpermissions2Y\n" +
|
||||
"\fUsersService\x12I\n" +
|
||||
"\rRetrieveUsers\x12\x1a.users.v1.RetrieveUsersReq\x1a\x1a.users.v1.RetrieveUsersRes\"\x00B1Z/github.com/absmach/magistrala/api/grpc/users/v1b\x06proto3"
|
||||
|
||||
var (
|
||||
file_users_v1_users_proto_rawDescOnce sync.Once
|
||||
file_users_v1_users_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_users_v1_users_proto_rawDescGZIP() []byte {
|
||||
file_users_v1_users_proto_rawDescOnce.Do(func() {
|
||||
file_users_v1_users_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_users_v1_users_proto_rawDesc), len(file_users_v1_users_proto_rawDesc)))
|
||||
})
|
||||
return file_users_v1_users_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_users_v1_users_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
|
||||
var file_users_v1_users_proto_goTypes = []any{
|
||||
(*RetrieveUsersReq)(nil), // 0: users.v1.RetrieveUsersReq
|
||||
(*RetrieveUsersRes)(nil), // 1: users.v1.RetrieveUsersRes
|
||||
(*User)(nil), // 2: users.v1.User
|
||||
(*structpb.Struct)(nil), // 3: google.protobuf.Struct
|
||||
(*timestamppb.Timestamp)(nil), // 4: google.protobuf.Timestamp
|
||||
}
|
||||
var file_users_v1_users_proto_depIdxs = []int32{
|
||||
2, // 0: users.v1.RetrieveUsersRes.users:type_name -> users.v1.User
|
||||
3, // 1: users.v1.User.metadata:type_name -> google.protobuf.Struct
|
||||
3, // 2: users.v1.User.private_metadata:type_name -> google.protobuf.Struct
|
||||
4, // 3: users.v1.User.created_at:type_name -> google.protobuf.Timestamp
|
||||
4, // 4: users.v1.User.updated_at:type_name -> google.protobuf.Timestamp
|
||||
4, // 5: users.v1.User.verified_at:type_name -> google.protobuf.Timestamp
|
||||
0, // 6: users.v1.UsersService.RetrieveUsers:input_type -> users.v1.RetrieveUsersReq
|
||||
1, // 7: users.v1.UsersService.RetrieveUsers:output_type -> users.v1.RetrieveUsersRes
|
||||
7, // [7:8] is the sub-list for method output_type
|
||||
6, // [6:7] is the sub-list for method input_type
|
||||
6, // [6:6] is the sub-list for extension type_name
|
||||
6, // [6:6] is the sub-list for extension extendee
|
||||
0, // [0:6] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_users_v1_users_proto_init() }
|
||||
func file_users_v1_users_proto_init() {
|
||||
if File_users_v1_users_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_users_v1_users_proto_rawDesc), len(file_users_v1_users_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 3,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_users_v1_users_proto_goTypes,
|
||||
DependencyIndexes: file_users_v1_users_proto_depIdxs,
|
||||
MessageInfos: file_users_v1_users_proto_msgTypes,
|
||||
}.Build()
|
||||
File_users_v1_users_proto = out.File
|
||||
file_users_v1_users_proto_goTypes = nil
|
||||
file_users_v1_users_proto_depIdxs = nil
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.6.2
|
||||
// - protoc v7.35.1
|
||||
// source: users/v1/users.proto
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
context "context"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.64.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion9
|
||||
|
||||
const (
|
||||
UsersService_RetrieveUsers_FullMethodName = "/users.v1.UsersService/RetrieveUsers"
|
||||
)
|
||||
|
||||
// UsersServiceClient is the client API for UsersService service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
//
|
||||
// UsersService exposes user-related functionality over gRPC.
|
||||
type UsersServiceClient interface {
|
||||
// RetrieveUsers fetches users for the provided IDs.
|
||||
RetrieveUsers(ctx context.Context, in *RetrieveUsersReq, opts ...grpc.CallOption) (*RetrieveUsersRes, error)
|
||||
}
|
||||
|
||||
type usersServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewUsersServiceClient(cc grpc.ClientConnInterface) UsersServiceClient {
|
||||
return &usersServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *usersServiceClient) RetrieveUsers(ctx context.Context, in *RetrieveUsersReq, opts ...grpc.CallOption) (*RetrieveUsersRes, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(RetrieveUsersRes)
|
||||
err := c.cc.Invoke(ctx, UsersService_RetrieveUsers_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// UsersServiceServer is the server API for UsersService service.
|
||||
// All implementations must embed UnimplementedUsersServiceServer
|
||||
// for forward compatibility.
|
||||
//
|
||||
// UsersService exposes user-related functionality over gRPC.
|
||||
type UsersServiceServer interface {
|
||||
// RetrieveUsers fetches users for the provided IDs.
|
||||
RetrieveUsers(context.Context, *RetrieveUsersReq) (*RetrieveUsersRes, error)
|
||||
mustEmbedUnimplementedUsersServiceServer()
|
||||
}
|
||||
|
||||
// UnimplementedUsersServiceServer must be embedded to have
|
||||
// forward compatible implementations.
|
||||
//
|
||||
// NOTE: this should be embedded by value instead of pointer to avoid a nil
|
||||
// pointer dereference when methods are called.
|
||||
type UnimplementedUsersServiceServer struct{}
|
||||
|
||||
func (UnimplementedUsersServiceServer) RetrieveUsers(context.Context, *RetrieveUsersReq) (*RetrieveUsersRes, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method RetrieveUsers not implemented")
|
||||
}
|
||||
func (UnimplementedUsersServiceServer) mustEmbedUnimplementedUsersServiceServer() {}
|
||||
func (UnimplementedUsersServiceServer) testEmbeddedByValue() {}
|
||||
|
||||
// UnsafeUsersServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to UsersServiceServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeUsersServiceServer interface {
|
||||
mustEmbedUnimplementedUsersServiceServer()
|
||||
}
|
||||
|
||||
func RegisterUsersServiceServer(s grpc.ServiceRegistrar, srv UsersServiceServer) {
|
||||
// If the following call panics, it indicates UnimplementedUsersServiceServer was
|
||||
// embedded by pointer and is nil. This will cause panics if an
|
||||
// unimplemented method is ever invoked, so we test this at initialization
|
||||
// time to prevent it from happening at runtime later due to I/O.
|
||||
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
|
||||
t.testEmbeddedByValue()
|
||||
}
|
||||
s.RegisterService(&UsersService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _UsersService_RetrieveUsers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(RetrieveUsersReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(UsersServiceServer).RetrieveUsers(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: UsersService_RetrieveUsers_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(UsersServiceServer).RetrieveUsers(ctx, req.(*RetrieveUsersReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// UsersService_ServiceDesc is the grpc.ServiceDesc for UsersService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var UsersService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "users.v1.UsersService",
|
||||
HandlerType: (*UsersServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "RetrieveUsers",
|
||||
Handler: _UsersService_RetrieveUsers_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "users/v1/users.proto",
|
||||
}
|
||||
@@ -0,0 +1,242 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package http
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/mail"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/absmach/magistrala"
|
||||
apiutil "github.com/absmach/magistrala/api/http/util"
|
||||
"github.com/absmach/magistrala/pkg/errors"
|
||||
"github.com/gofrs/uuid/v5"
|
||||
)
|
||||
|
||||
const (
|
||||
OffsetKey = "offset"
|
||||
DirKey = "dir"
|
||||
OrderKey = "order"
|
||||
LimitKey = "limit"
|
||||
OnlyTotal = "only_total"
|
||||
|
||||
NameOrder = "name"
|
||||
IDOrder = "id"
|
||||
AscDir = "asc"
|
||||
DescDir = "desc"
|
||||
UpdatedAtOrder = "updated_at"
|
||||
CreatedAtOrder = "created_at"
|
||||
|
||||
MetadataKey = "metadata"
|
||||
NameKey = "name"
|
||||
TagKey = "tag"
|
||||
TagsKey = "tags"
|
||||
StatusKey = "status"
|
||||
|
||||
ClientKey = "client"
|
||||
ChannelKey = "channel"
|
||||
ConnTypeKey = "connection_type"
|
||||
GroupKey = "group"
|
||||
DomainKey = "domain"
|
||||
|
||||
StartLevelKey = "start_level"
|
||||
EndLevelKey = "end_level"
|
||||
TreeKey = "tree"
|
||||
ParentKey = "parent_id"
|
||||
LevelKey = "level"
|
||||
RootGroupKey = "root_group"
|
||||
|
||||
TokenKey = "token"
|
||||
SubjectKey = "subject"
|
||||
ObjectKey = "object"
|
||||
|
||||
RolesKey = "roles"
|
||||
ActionKey = "action"
|
||||
ActionsKey = "actions"
|
||||
RoleIDKey = "role_id"
|
||||
RoleNameKey = "role_name"
|
||||
AccessProviderIDKey = "access_provider_id"
|
||||
AccessTypeKey = "access_type"
|
||||
|
||||
UsernameKey = "username"
|
||||
UserKey = "user"
|
||||
EmailKey = "email"
|
||||
FirstNameKey = "first_name"
|
||||
LastNameKey = "last_name"
|
||||
|
||||
DefTotal = uint64(100)
|
||||
DefOffset = 0
|
||||
DefOrder = "updated_at"
|
||||
DefDir = "desc"
|
||||
DefLimit = 10
|
||||
DefLevel = 0
|
||||
DefStartLevel = 1
|
||||
DefEndLevel = 0
|
||||
DefStatus = "enabled"
|
||||
DefClientStatus = "enabled"
|
||||
DefUserStatus = "enabled"
|
||||
DefGroupStatus = "enabled"
|
||||
|
||||
// ContentType represents JSON content type.
|
||||
ContentType = "application/json"
|
||||
|
||||
// MaxNameSize limits name size to prevent making them too complex.
|
||||
MaxLimitSize = 100
|
||||
MaxNameSize = 1024
|
||||
MaxIDSize = 36
|
||||
)
|
||||
|
||||
var (
|
||||
nameRegExp = regexp.MustCompile(`^[a-z0-9][a-z0-9_-]{34}[a-z0-9]$`)
|
||||
routeRegExp = regexp.MustCompile(`^[a-zA-Z][a-zA-Z0-9_-]{0,35}$`)
|
||||
userNameRegExp = regexp.MustCompile(`^[a-zA-Z0-9][a-zA-Z0-9_-]{0,31}$`)
|
||||
errUnreadableName = errors.New("name containing double underscores or double dashes not allowed")
|
||||
)
|
||||
|
||||
// ValidateUUID validates UUID format.
|
||||
func ValidateUUID(extID string) (err error) {
|
||||
id, err := uuid.FromString(extID)
|
||||
if id.String() != extID || err != nil {
|
||||
return apiutil.ErrInvalidIDFormat
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func ValidateEmail(email string) (err error) {
|
||||
if _, err := mail.ParseAddress(email); err != nil {
|
||||
return apiutil.ErrInvalidEmail
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ValidateName validates name format.
|
||||
func ValidateName(id string) error {
|
||||
if !nameRegExp.MatchString(id) {
|
||||
return apiutil.ErrInvalidNameFormat
|
||||
}
|
||||
// Names containing double underscores or double dashes are invalid due to similarity concerns.
|
||||
if strings.Contains(id, "__") || strings.Contains(id, "--") {
|
||||
return errors.Wrap(apiutil.ErrInvalidNameFormat, errUnreadableName)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ValidateRoute validates route format.
|
||||
func ValidateRoute(route string) error {
|
||||
if !routeRegExp.MatchString(route) {
|
||||
return apiutil.ErrInvalidRouteFormat
|
||||
}
|
||||
|
||||
if strings.Contains(route, "__") || strings.Contains(route, "--") {
|
||||
return errors.Wrap(apiutil.ErrInvalidRouteFormat, errUnreadableName)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ValidateUserName validates user name format.
|
||||
func ValidateUserName(name string) error {
|
||||
if !userNameRegExp.MatchString(name) {
|
||||
return apiutil.ErrInvalidUsername
|
||||
}
|
||||
|
||||
if strings.Contains(name, "__") || strings.Contains(name, "--") {
|
||||
return errors.Wrap(apiutil.ErrInvalidUsername, errUnreadableName)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// EncodeResponse encodes successful response.
|
||||
func EncodeResponse(_ context.Context, w http.ResponseWriter, response any) error {
|
||||
if ar, ok := response.(magistrala.Response); ok {
|
||||
for k, v := range ar.Headers() {
|
||||
w.Header().Set(k, v)
|
||||
}
|
||||
w.Header().Set("Content-Type", ContentType)
|
||||
w.WriteHeader(ar.Code())
|
||||
|
||||
if ar.Empty() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return json.NewEncoder(w).Encode(response)
|
||||
}
|
||||
|
||||
// EncodeError encodes an error response.
|
||||
func EncodeError(_ context.Context, err error, w http.ResponseWriter) {
|
||||
w.Header().Set("Content-Type", ContentType)
|
||||
if sdkErr, ok := err.(errors.SDKError); ok {
|
||||
w.WriteHeader(sdkErr.StatusCode())
|
||||
if err := json.NewEncoder(w).Encode(sdkErr); err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if errors.Contains(err, errors.ErrAuthentication) {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
if err := json.NewEncoder(w).Encode(err); err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
}
|
||||
return
|
||||
}
|
||||
if errors.Contains(err, errors.ErrAuthorization) {
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
if err := json.NewEncoder(w).Encode(err); err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
switch retErr := err.(type) {
|
||||
case *errors.RequestError:
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
if err := json.NewEncoder(w).Encode(retErr); err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
}
|
||||
return
|
||||
case *errors.AuthNError:
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
if err := json.NewEncoder(w).Encode(retErr); err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
}
|
||||
return
|
||||
case *errors.AuthZError:
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
if err := json.NewEncoder(w).Encode(retErr); err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
}
|
||||
return
|
||||
case *errors.MediaTypeError:
|
||||
w.WriteHeader(http.StatusUnsupportedMediaType)
|
||||
if err := json.NewEncoder(w).Encode(retErr); err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
}
|
||||
return
|
||||
case *errors.ServiceError:
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
if err := json.NewEncoder(w).Encode(retErr); err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
}
|
||||
return
|
||||
case *errors.NotFoundError:
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
if err := json.NewEncoder(w).Encode(retErr); err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
}
|
||||
return
|
||||
case *errors.InternalError:
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
default:
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package api_test
|
||||
package http_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -11,11 +11,11 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/absmach/magistrala"
|
||||
"github.com/absmach/magistrala/internal/api"
|
||||
"github.com/absmach/magistrala/internal/apiutil"
|
||||
"github.com/absmach/magistrala/internal/testsutil"
|
||||
api "github.com/absmach/magistrala/api/http"
|
||||
apiutil "github.com/absmach/magistrala/api/http/util"
|
||||
"github.com/absmach/magistrala/pkg/errors"
|
||||
svcerr "github.com/absmach/magistrala/pkg/errors/service"
|
||||
"github.com/absmach/magistrala/pkg/testsutil"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@@ -115,7 +115,7 @@ func TestEncodeResponse(t *testing.T) {
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
resp interface{}
|
||||
resp any
|
||||
header http.Header
|
||||
code int
|
||||
body []byte
|
||||
@@ -218,121 +218,116 @@ func TestEncodeResponse(t *testing.T) {
|
||||
|
||||
func TestEncodeError(t *testing.T) {
|
||||
cases := []struct {
|
||||
desc string
|
||||
errs []error
|
||||
code int
|
||||
desc string
|
||||
err error
|
||||
code int
|
||||
hasBody bool
|
||||
checkError bool
|
||||
}{
|
||||
{
|
||||
desc: "BadRequest",
|
||||
errs: []error{
|
||||
apiutil.ErrInvalidSecret,
|
||||
svcerr.ErrMalformedEntity,
|
||||
errors.ErrMalformedEntity,
|
||||
apiutil.ErrMissingID,
|
||||
apiutil.ErrEmptyList,
|
||||
apiutil.ErrMissingMemberType,
|
||||
apiutil.ErrMissingMemberKind,
|
||||
apiutil.ErrLimitSize,
|
||||
apiutil.ErrNameSize,
|
||||
},
|
||||
code: http.StatusBadRequest,
|
||||
desc: "RequestError - Missing Secret",
|
||||
err: apiutil.ErrMissingSecret,
|
||||
code: http.StatusBadRequest,
|
||||
hasBody: true,
|
||||
},
|
||||
{
|
||||
desc: "BadRequest with validation error",
|
||||
errs: []error{
|
||||
errors.Wrap(apiutil.ErrValidation, apiutil.ErrInvalidSecret),
|
||||
errors.Wrap(apiutil.ErrValidation, svcerr.ErrMalformedEntity),
|
||||
errors.Wrap(apiutil.ErrValidation, errors.ErrMalformedEntity),
|
||||
errors.Wrap(apiutil.ErrValidation, apiutil.ErrMissingID),
|
||||
errors.Wrap(apiutil.ErrValidation, apiutil.ErrEmptyList),
|
||||
errors.Wrap(apiutil.ErrValidation, apiutil.ErrMissingMemberType),
|
||||
errors.Wrap(apiutil.ErrValidation, apiutil.ErrMissingMemberKind),
|
||||
errors.Wrap(apiutil.ErrValidation, apiutil.ErrLimitSize),
|
||||
errors.Wrap(apiutil.ErrValidation, apiutil.ErrNameSize),
|
||||
},
|
||||
code: http.StatusBadRequest,
|
||||
desc: "RequestError - Missing ID",
|
||||
err: apiutil.ErrMissingID,
|
||||
code: http.StatusBadRequest,
|
||||
hasBody: true,
|
||||
},
|
||||
{
|
||||
desc: "Unauthorized",
|
||||
errs: []error{
|
||||
svcerr.ErrAuthentication,
|
||||
svcerr.ErrAuthentication,
|
||||
apiutil.ErrBearerToken,
|
||||
},
|
||||
code: http.StatusUnauthorized,
|
||||
},
|
||||
|
||||
{
|
||||
desc: "NotFound",
|
||||
errs: []error{
|
||||
svcerr.ErrNotFound,
|
||||
},
|
||||
code: http.StatusNotFound,
|
||||
desc: "RequestError - Empty List",
|
||||
err: apiutil.ErrEmptyList,
|
||||
code: http.StatusBadRequest,
|
||||
hasBody: true,
|
||||
},
|
||||
{
|
||||
desc: "Conflict",
|
||||
errs: []error{
|
||||
svcerr.ErrConflict,
|
||||
svcerr.ErrConflict,
|
||||
},
|
||||
code: http.StatusConflict,
|
||||
desc: "RequestError - Conflict",
|
||||
err: svcerr.ErrConflict,
|
||||
code: http.StatusBadRequest,
|
||||
hasBody: true,
|
||||
},
|
||||
{
|
||||
desc: "Forbidden",
|
||||
errs: []error{
|
||||
svcerr.ErrAuthorization,
|
||||
svcerr.ErrAuthorization,
|
||||
svcerr.ErrDomainAuthorization,
|
||||
},
|
||||
code: http.StatusForbidden,
|
||||
desc: "NotFoundError - Not Found",
|
||||
err: svcerr.ErrNotFound,
|
||||
code: http.StatusNotFound,
|
||||
hasBody: true,
|
||||
},
|
||||
{
|
||||
desc: "UnsupportedMediaType",
|
||||
errs: []error{
|
||||
apiutil.ErrUnsupportedContentType,
|
||||
},
|
||||
code: http.StatusUnsupportedMediaType,
|
||||
desc: "AuthNError - Authentication Failed",
|
||||
err: svcerr.ErrAuthentication,
|
||||
code: http.StatusUnauthorized,
|
||||
hasBody: true,
|
||||
},
|
||||
{
|
||||
desc: "InternalServerError",
|
||||
errs: []error{
|
||||
svcerr.ErrCreateEntity,
|
||||
svcerr.ErrUpdateEntity,
|
||||
svcerr.ErrViewEntity,
|
||||
svcerr.ErrRemoveEntity,
|
||||
},
|
||||
code: http.StatusInternalServerError,
|
||||
desc: "Generic Authentication Failed",
|
||||
err: errors.ErrAuthentication,
|
||||
code: http.StatusUnauthorized,
|
||||
hasBody: true,
|
||||
},
|
||||
{
|
||||
desc: "InternalServerError",
|
||||
errs: []error{
|
||||
errors.New("test"),
|
||||
},
|
||||
code: http.StatusInternalServerError,
|
||||
desc: "AuthZError - Authorization Failed",
|
||||
err: svcerr.ErrAuthorization,
|
||||
code: http.StatusForbidden,
|
||||
hasBody: true,
|
||||
},
|
||||
{
|
||||
desc: "Generic Authorization Failed",
|
||||
err: errors.Wrap(errors.New("not authorized"), errors.ErrAuthorization),
|
||||
code: http.StatusForbidden,
|
||||
hasBody: true,
|
||||
},
|
||||
{
|
||||
desc: "AuthZError - Domain Authorization Failed",
|
||||
err: svcerr.ErrDomainAuthorization,
|
||||
code: http.StatusForbidden,
|
||||
hasBody: true,
|
||||
},
|
||||
{
|
||||
desc: "MediaTypeError - Unsupported Content Type",
|
||||
err: apiutil.ErrUnsupportedContentType,
|
||||
code: http.StatusUnsupportedMediaType,
|
||||
hasBody: true,
|
||||
},
|
||||
{
|
||||
desc: "ServiceError - Create Entity Failed",
|
||||
err: svcerr.ErrCreateEntity,
|
||||
code: http.StatusUnprocessableEntity,
|
||||
hasBody: true,
|
||||
},
|
||||
{
|
||||
desc: "ServiceError - Update Entity Failed",
|
||||
err: svcerr.ErrUpdateEntity,
|
||||
code: http.StatusUnprocessableEntity,
|
||||
hasBody: true,
|
||||
},
|
||||
{
|
||||
desc: "ServiceError - Remove Entity Failed",
|
||||
err: svcerr.ErrRemoveEntity,
|
||||
code: http.StatusUnprocessableEntity,
|
||||
hasBody: true,
|
||||
},
|
||||
{
|
||||
desc: "InternalError",
|
||||
err: errors.NewInternalError(),
|
||||
code: http.StatusInternalServerError,
|
||||
hasBody: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.desc, func(t *testing.T) {
|
||||
responseWriter := newResponseWriter()
|
||||
for _, err := range c.errs {
|
||||
api.EncodeError(context.Background(), err, responseWriter)
|
||||
assert.Equal(t, c.code, responseWriter.StatusCode())
|
||||
|
||||
message := body{}
|
||||
jerr := json.Unmarshal(responseWriter.Body(), &message)
|
||||
assert.NoError(t, jerr)
|
||||
|
||||
var wrapper error
|
||||
switch errors.Contains(err, apiutil.ErrValidation) {
|
||||
case true:
|
||||
wrapper, err = errors.Unwrap(err)
|
||||
assert.Equal(t, err.Error(), message.Error)
|
||||
assert.Equal(t, wrapper.Error(), message.Message)
|
||||
case false:
|
||||
assert.Equal(t, err.Error(), message.Message)
|
||||
}
|
||||
api.EncodeError(context.Background(), c.err, responseWriter)
|
||||
assert.Equal(t, c.code, responseWriter.StatusCode())
|
||||
if !c.hasBody {
|
||||
return
|
||||
}
|
||||
message := body{}
|
||||
jerr := json.Unmarshal(responseWriter.Body(), &message)
|
||||
assert.NoError(t, jerr)
|
||||
assert.NotEmpty(t, message.Message)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Package http contains implementation of kit service HTTP API.
|
||||
// Package api contains commonly used constants and functions
|
||||
// for the HTTP API.
|
||||
package http
|
||||
@@ -0,0 +1,27 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package http
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/absmach/magistrala"
|
||||
"github.com/go-chi/chi/v5/middleware"
|
||||
)
|
||||
|
||||
func RequestIDMiddleware(idp magistrala.IDProvider) func(http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
requestID, err := idp.ID()
|
||||
if err != nil {
|
||||
EncodeError(r.Context(), err, w)
|
||||
return
|
||||
}
|
||||
|
||||
ctx := context.WithValue(r.Context(), middleware.RequestIDKey, requestID)
|
||||
next.ServeHTTP(w, r.WithContext(ctx))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,280 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package util
|
||||
|
||||
import "github.com/absmach/magistrala/pkg/errors"
|
||||
|
||||
// Errors defined in this file are used by the LoggingErrorEncoder decorator
|
||||
// to distinguish and log API request validation errors and avoid that service
|
||||
// errors are logged twice.
|
||||
var (
|
||||
// ErrValidation indicates that an error was returned by the API.
|
||||
ErrValidation = errors.NewRequestError("something went wrong with the request")
|
||||
|
||||
// ErrBearerToken indicates missing or invalid bearer user token.
|
||||
ErrBearerToken = errors.NewAuthNError("missing or invalid bearer user token")
|
||||
|
||||
// ErrBearerKey indicates missing or invalid bearer entity key.
|
||||
ErrBearerKey = errors.NewAuthNError("missing or invalid bearer entity key")
|
||||
|
||||
// ErrMissingID indicates missing entity ID.
|
||||
ErrMissingID = errors.NewRequestError("missing entity id")
|
||||
|
||||
// ErrMissingEntityID indicates missing entity ID.
|
||||
ErrMissingEntityID = errors.NewRequestError("missing entity id")
|
||||
|
||||
// ErrMissingClientID indicates missing client ID.
|
||||
ErrMissingClientID = errors.NewRequestError("missing client id")
|
||||
|
||||
// ErrMissingChannelID indicates missing client ID.
|
||||
ErrMissingChannelID = errors.NewRequestError("missing channel id")
|
||||
|
||||
// ErrMissingConnectionType indicates missing connection tpye.
|
||||
ErrMissingConnectionType = errors.NewRequestError("missing connection type")
|
||||
|
||||
// ErrMissingParentGroupID indicates missing parent group ID.
|
||||
ErrMissingParentGroupID = errors.NewRequestError("missing parent group id")
|
||||
|
||||
// ErrMissingChildrenGroupIDs indicates missing children group IDs.
|
||||
ErrMissingChildrenGroupIDs = errors.NewRequestError("missing children group ids")
|
||||
|
||||
// ErrSelfParentingNotAllowed indicates child id is same as parent id.
|
||||
ErrSelfParentingNotAllowed = errors.NewRequestError("self parenting not allowed")
|
||||
|
||||
// ErrInvalidChildGroupID indicates invalid child group ID.
|
||||
ErrInvalidChildGroupID = errors.NewRequestError("invalid child group id")
|
||||
|
||||
// ErrInvalidAuthKey indicates invalid auth key.
|
||||
ErrInvalidAuthKey = errors.New("invalid auth key")
|
||||
|
||||
// ErrInvalidIDFormat indicates an invalid ID format.
|
||||
ErrInvalidIDFormat = errors.NewRequestError("invalid id format provided")
|
||||
|
||||
// ErrNameSize indicates that name size exceeds the max.
|
||||
ErrNameSize = errors.NewRequestError("invalid name size")
|
||||
|
||||
// ErrEmailSize indicates that email size exceeds the max.
|
||||
ErrEmailSize = errors.NewRequestError("invalid email size")
|
||||
|
||||
// ErrInvalidRole indicates that an invalid role.
|
||||
ErrInvalidRole = errors.NewRequestError("invalid client role")
|
||||
|
||||
// ErrLimitSize indicates that an invalid limit.
|
||||
ErrLimitSize = errors.NewRequestError("invalid limit size")
|
||||
|
||||
// ErrLevel indicates that an invalid level.
|
||||
ErrLevel = errors.NewRequestError("invalid level")
|
||||
|
||||
// ErrOffsetSize indicates an invalid offset.
|
||||
ErrOffsetSize = errors.NewRequestError("invalid offset size")
|
||||
|
||||
// ErrInvalidOrder indicates an invalid list order.
|
||||
ErrInvalidOrder = errors.NewRequestError("invalid list order provided")
|
||||
|
||||
// ErrInvalidDirection indicates an invalid list direction.
|
||||
ErrInvalidDirection = errors.NewRequestError("invalid list direction provided")
|
||||
|
||||
// ErrInvalidMemberKind indicates an invalid member kind.
|
||||
ErrInvalidMemberKind = errors.NewRequestError("invalid member kind")
|
||||
|
||||
// ErrEmptyList indicates that entity data is empty.
|
||||
ErrEmptyList = errors.NewRequestError("empty list provided")
|
||||
|
||||
// ErrMissingRoleName indicates that role name is empty.
|
||||
ErrMissingRoleName = errors.NewRequestError("empty role name")
|
||||
|
||||
// ErrMissingRoleID indicates that role id is empty.
|
||||
ErrMissingRoleID = errors.NewRequestError("empty role id")
|
||||
|
||||
// ErrMissingRoleOperations indicates that role operations are empty.
|
||||
ErrMissingRoleOperations = errors.NewRequestError("empty role operations")
|
||||
|
||||
// ErrMissingRoleMembers indicates that role members are empty.
|
||||
ErrMissingRoleMembers = errors.NewRequestError("empty role members")
|
||||
|
||||
// ErrMalformedPolicy indicates that policies are malformed.
|
||||
ErrMalformedPolicy = errors.NewRequestError("malformed policy")
|
||||
|
||||
// ErrMissingPolicySub indicates that policies are subject.
|
||||
ErrMissingPolicySub = errors.NewRequestError("malformed policy subject")
|
||||
|
||||
// ErrMissingPolicyObj indicates missing policies object.
|
||||
ErrMissingPolicyObj = errors.NewRequestError("malformed policy object")
|
||||
|
||||
// ErrMalformedPolicyAct indicates missing policies action.
|
||||
ErrMalformedPolicyAct = errors.NewRequestError("malformed policy action")
|
||||
|
||||
// ErrMissingPolicyEntityType indicates missing policies entity type.
|
||||
ErrMissingPolicyEntityType = errors.NewRequestError("missing policy entity type")
|
||||
|
||||
// ErrMalformedPolicyPer indicates missing policies relation.
|
||||
ErrMalformedPolicyPer = errors.NewRequestError("malformed policy permission")
|
||||
|
||||
// ErrMissingCertData indicates missing cert data (ttl).
|
||||
ErrMissingCertData = errors.NewRequestError("missing certificate data")
|
||||
|
||||
// ErrInvalidCertData indicates invalid cert data (ttl).
|
||||
ErrInvalidCertData = errors.NewRequestError("invalid certificate data")
|
||||
|
||||
// ErrInvalidTopic indicates an invalid subscription topic.
|
||||
ErrInvalidTopic = errors.NewRequestError("invalid Subscription topic")
|
||||
|
||||
// ErrInvalidContact indicates an invalid subscription contract.
|
||||
ErrInvalidContact = errors.NewRequestError("invalid Subscription contact")
|
||||
|
||||
// ErrMissingEmail indicates missing email.
|
||||
ErrMissingEmail = errors.NewRequestError("missing email")
|
||||
|
||||
// ErrInvalidEmail indicates missing email.
|
||||
ErrInvalidEmail = errors.NewRequestError("invalid email")
|
||||
|
||||
// ErrMissingHost indicates missing host.
|
||||
ErrMissingHost = errors.NewRequestError("missing host")
|
||||
|
||||
// ErrMissingPass indicates missing password.
|
||||
ErrMissingPass = errors.NewRequestError("missing password")
|
||||
|
||||
// ErrMissingConfPass indicates missing conf password.
|
||||
ErrMissingConfPass = errors.NewRequestError("missing conf password")
|
||||
|
||||
// ErrInvalidResetPass indicates an invalid reset password.
|
||||
ErrInvalidResetPass = errors.NewRequestError("invalid reset password")
|
||||
|
||||
// ErrInvalidComparator indicates an invalid comparator.
|
||||
ErrInvalidComparator = errors.NewRequestError("invalid comparator")
|
||||
|
||||
// ErrMissingMemberIDs indicates missing member ids.
|
||||
ErrMissingMemberIDs = errors.NewRequestError("missing member ids")
|
||||
|
||||
// ErrMissingMemberType indicates missing group member type.
|
||||
ErrMissingMemberType = errors.NewRequestError("missing group member type")
|
||||
|
||||
// ErrMissingMemberKind indicates missing group member kind.
|
||||
ErrMissingMemberKind = errors.NewRequestError("missing group member kind")
|
||||
|
||||
// ErrMissingRelation indicates missing relation.
|
||||
ErrMissingRelation = errors.NewRequestError("missing relation")
|
||||
|
||||
// ErrInvalidRelation indicates an invalid relation.
|
||||
ErrInvalidRelation = errors.NewRequestError("invalid relation")
|
||||
|
||||
// ErrInvalidAPIKey indicates an invalid API key type.
|
||||
ErrInvalidAPIKey = errors.NewRequestError("invalid api key type")
|
||||
|
||||
// ErrInvitationState indicates an invalid invitation state.
|
||||
ErrInvitationState = errors.NewRequestError("invalid invitation state")
|
||||
|
||||
// ErrMissingIdentity indicates missing entity Identity.
|
||||
ErrMissingIdentity = errors.NewRequestError("missing entity identity")
|
||||
|
||||
// ErrMissingSecret indicates missing secret.
|
||||
ErrMissingSecret = errors.NewRequestError("missing secret")
|
||||
|
||||
// ErrPasswordFormat indicates weak password.
|
||||
ErrPasswordFormat = errors.NewRequestError("password does not meet the requirements")
|
||||
|
||||
// ErrMissingName indicates missing identity name.
|
||||
ErrMissingName = errors.NewRequestError("missing identity name")
|
||||
|
||||
// ErrMissingRoute indicates missing route.
|
||||
ErrMissingRoute = errors.NewRequestError("missing route")
|
||||
|
||||
// ErrInvalidLevel indicates an invalid group level.
|
||||
ErrInvalidLevel = errors.NewRequestError("invalid group level (should be between 0 and 5)")
|
||||
|
||||
// ErrNotFoundParam indicates that the parameter was not found in the query.
|
||||
ErrNotFoundParam = errors.NewRequestError("parameter not found in the query")
|
||||
|
||||
// ErrInvalidQueryParams indicates invalid query parameters.
|
||||
ErrInvalidQueryParams = errors.NewRequestError("invalid query parameters")
|
||||
|
||||
// ErrInvalidVisibilityType indicates invalid visibility type.
|
||||
ErrInvalidVisibilityType = errors.NewRequestError("invalid visibility type")
|
||||
|
||||
// ErrUnsupportedContentType indicates unacceptable or lack of Content-Type.
|
||||
ErrUnsupportedContentType = errors.NewMediaTypeError("unsupported content type")
|
||||
|
||||
// ErrRollbackTx indicates failed to rollback transaction.
|
||||
ErrRollbackTx = errors.NewRequestError("failed to rollback transaction")
|
||||
|
||||
// ErrInvalidAggregation indicates invalid aggregation value.
|
||||
ErrInvalidAggregation = errors.NewRequestError("invalid aggregation value")
|
||||
|
||||
// ErrInvalidInterval indicates invalid interval value.
|
||||
ErrInvalidInterval = errors.NewRequestError("invalid interval value")
|
||||
|
||||
// ErrMissingFrom indicates missing from value.
|
||||
ErrMissingFrom = errors.NewRequestError("missing from time value")
|
||||
|
||||
// ErrMissingTo indicates missing to value.
|
||||
ErrMissingTo = errors.NewRequestError("missing to time value")
|
||||
|
||||
// ErrEmptyMessage indicates empty message.
|
||||
ErrEmptyMessage = errors.NewRequestError("empty message")
|
||||
|
||||
// ErrMissingEntityType indicates missing entity type.
|
||||
ErrMissingEntityType = errors.NewRequestError("missing entity type")
|
||||
|
||||
// ErrInvalidEntityType indicates invalid entity type.
|
||||
ErrInvalidEntityType = errors.NewRequestError("invalid entity type")
|
||||
|
||||
// ErrInvalidTimeFormat indicates invalid time format i.e not unix time.
|
||||
ErrInvalidTimeFormat = errors.NewRequestError("invalid time format use unix time")
|
||||
|
||||
// ErrEmptySearchQuery indicates search query should not be empty.
|
||||
ErrEmptySearchQuery = errors.NewRequestError("search query must not be empty")
|
||||
|
||||
// ErrLenSearchQuery indicates search query length.
|
||||
ErrLenSearchQuery = errors.NewRequestError("search query must be at least 3 characters")
|
||||
|
||||
// ErrMissingDomainID indicates missing domainID.
|
||||
ErrMissingDomainID = errors.NewRequestError("missing domainID")
|
||||
|
||||
// ErrMissingUsername indicates missing user name.
|
||||
ErrMissingUsername = errors.NewRequestError("missing username")
|
||||
|
||||
// ErrInvalidUsername indicates invalid user name.
|
||||
ErrInvalidUsername = errors.NewRequestError("invalid username")
|
||||
|
||||
// ErrMissingFirstName indicates missing first name.
|
||||
ErrMissingFirstName = errors.NewRequestError("missing first name")
|
||||
|
||||
// ErrMissingLastName indicates missing last name.
|
||||
ErrMissingLastName = errors.NewRequestError("missing last name")
|
||||
|
||||
// ErrInvalidProfilePictureURL indicates that the profile picture url is invalid.
|
||||
ErrInvalidProfilePictureURL = errors.NewRequestError("invalid profile picture url")
|
||||
|
||||
ErrMultipleEntitiesFilter = errors.NewRequestError("multiple entities are provided in filter are not supported")
|
||||
|
||||
// ErrMissingDescription indicates missing description.
|
||||
ErrMissingDescription = errors.NewRequestError("missing description")
|
||||
|
||||
// ErrUnsupportedTokenType indicates that this type of token is not supported.
|
||||
ErrUnsupportedTokenType = errors.NewRequestError("unsupported content token type")
|
||||
|
||||
// ErrMissingUserID indicates missing user ID.
|
||||
ErrMissingUserID = errors.NewRequestError("missing user id")
|
||||
|
||||
// ErrMissingPATID indicates missing pat ID.
|
||||
ErrMissingPATID = errors.NewRequestError("missing pat id")
|
||||
|
||||
// ErrInvalidNameFormat indicates invalid name format.
|
||||
ErrInvalidNameFormat = errors.NewRequestError("invalid name format")
|
||||
|
||||
// ErrInvalidRouteFormat indicates invalid route format.
|
||||
ErrInvalidRouteFormat = errors.NewRequestError("invalid route format")
|
||||
|
||||
// ErrMissingUsernameEmail indicates missing user name / email.
|
||||
ErrMissingUsernameEmail = errors.NewRequestError("missing username / email")
|
||||
|
||||
// ErrInvalidVerification indicates invalid email verification.
|
||||
ErrInvalidVerification = errors.NewRequestError("invalid verification")
|
||||
|
||||
// ErrEmailNotVerified indicates invalid email not verified.
|
||||
ErrEmailNotVerified = errors.NewRequestError("email not verified")
|
||||
|
||||
// ErrMalformedRequest indicates malformed request body.
|
||||
ErrMalformedRequestBody = errors.NewRequestError("request body is not a valid JSON, expecting a valid JSON")
|
||||
)
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package apiutil
|
||||
package util
|
||||
|
||||
// ErrorRes represents the HTTP error response body.
|
||||
type ErrorRes struct {
|
||||
@@ -0,0 +1,42 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package util
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
// BearerPrefix represents the token prefix for Bearer authentication scheme.
|
||||
BearerPrefix = "Bearer "
|
||||
|
||||
// ClientPrefix represents the key prefix for Client authentication scheme.
|
||||
ClientPrefix = "Client "
|
||||
|
||||
// BasicAuthPrefix represents the prefix for Basic authentication scheme.
|
||||
BasicAuthPrefix = "Basic "
|
||||
)
|
||||
|
||||
// ExtractBearerToken returns value of the bearer token. If there is no bearer token - an empty value is returned.
|
||||
func ExtractBearerToken(r *http.Request) string {
|
||||
token := r.Header.Get("Authorization")
|
||||
|
||||
if !strings.HasPrefix(token, BearerPrefix) {
|
||||
return ""
|
||||
}
|
||||
|
||||
return strings.TrimPrefix(token, BearerPrefix)
|
||||
}
|
||||
|
||||
// ExtractClientSecret returns value of the client secret. If it's not present - an empty value is returned.
|
||||
func ExtractClientSecret(r *http.Request) string {
|
||||
token := r.Header.Get("Authorization")
|
||||
|
||||
if !strings.HasPrefix(token, ClientPrefix) {
|
||||
return ""
|
||||
}
|
||||
|
||||
return strings.TrimPrefix(token, ClientPrefix)
|
||||
}
|
||||
@@ -1,13 +1,13 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package apiutil_test
|
||||
package util_test
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/absmach/magistrala/internal/apiutil"
|
||||
apiutil "github.com/absmach/magistrala/api/http/util"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@@ -61,7 +61,7 @@ func TestExtractBearerToken(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtractThingKey(t *testing.T) {
|
||||
func TestExtractClientSecret(t *testing.T) {
|
||||
cases := []struct {
|
||||
desc string
|
||||
request *http.Request
|
||||
@@ -71,7 +71,7 @@ func TestExtractThingKey(t *testing.T) {
|
||||
desc: "valid bearer token",
|
||||
request: &http.Request{
|
||||
Header: map[string][]string{
|
||||
"Authorization": {"Thing 123"},
|
||||
"Authorization": {"Client 123"},
|
||||
},
|
||||
},
|
||||
token: "123",
|
||||
@@ -105,7 +105,7 @@ func TestExtractThingKey(t *testing.T) {
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.desc, func(t *testing.T) {
|
||||
token := apiutil.ExtractThingKey(c.request)
|
||||
token := apiutil.ExtractClientSecret(c.request)
|
||||
assert.Equal(t, c.token, token)
|
||||
})
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package apiutil
|
||||
package util
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -39,7 +39,7 @@ func ReadStringQuery(r *http.Request, key, def string) (string, error) {
|
||||
}
|
||||
|
||||
// ReadMetadataQuery reads the value of json http query parameters for a given key.
|
||||
func ReadMetadataQuery(r *http.Request, key string, def map[string]interface{}) (map[string]interface{}, error) {
|
||||
func ReadMetadataQuery(r *http.Request, key string, def map[string]any) (map[string]any, error) {
|
||||
vals := r.URL.Query()[key]
|
||||
if len(vals) > 1 {
|
||||
return nil, ErrInvalidQueryParams
|
||||
@@ -49,7 +49,7 @@ func ReadMetadataQuery(r *http.Request, key string, def map[string]interface{})
|
||||
return def, nil
|
||||
}
|
||||
|
||||
m := make(map[string]interface{})
|
||||
m := make(map[string]any)
|
||||
err := json.Unmarshal([]byte(vals[0]), &m)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ErrInvalidQueryParams, err)
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package apiutil_test
|
||||
package util_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"github.com/absmach/magistrala/internal/apiutil"
|
||||
apiutil "github.com/absmach/magistrala/api/http/util"
|
||||
mglog "github.com/absmach/magistrala/logger"
|
||||
"github.com/absmach/magistrala/pkg/errors"
|
||||
svcerr "github.com/absmach/magistrala/pkg/errors/service"
|
||||
@@ -67,14 +67,14 @@ func TestReadMetadataQuery(t *testing.T) {
|
||||
desc string
|
||||
url string
|
||||
key string
|
||||
ret map[string]interface{}
|
||||
ret map[string]any
|
||||
err error
|
||||
}{
|
||||
{
|
||||
desc: "valid metadata query",
|
||||
url: "http://localhost:8080/?key={\"test\":\"test\"}",
|
||||
key: "key",
|
||||
ret: map[string]interface{}{"test": "test"},
|
||||
ret: map[string]any{"test": "test"},
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
@@ -177,7 +177,7 @@ func TestReadNumQuery(t *testing.T) {
|
||||
url string
|
||||
key string
|
||||
numType string
|
||||
ret interface{}
|
||||
ret any
|
||||
err error
|
||||
}{
|
||||
{
|
||||
@@ -316,7 +316,7 @@ func TestReadNumQuery(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
|
||||
r := &http.Request{URL: parsedURL}
|
||||
var ret interface{}
|
||||
var ret any
|
||||
switch c.numType {
|
||||
case "int64":
|
||||
ret, err = apiutil.ReadNumQuery[int64](r, c.key, 0)
|
||||
@@ -1,5 +0,0 @@
|
||||
# Magistrala OpenAPI Specification
|
||||
|
||||
This folder contains an OpenAPI specifications for Magistrala API.
|
||||
|
||||
View specification in Swagger UI at [api.mainflux.io](https://api.mainflux.io)
|
||||
@@ -1,887 +0,0 @@
|
||||
# Copyright (c) Abstract Machines
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: Magistrala Auth Service
|
||||
description: |
|
||||
This is the Auth Server based on the OpenAPI 3.0 specification. It is the HTTP API for managing platform users. You can now help us improve the API whether it's by making changes to the definition itself or to the code.
|
||||
Some useful links:
|
||||
- [The Magistrala repository](https://github.com/absmach/magistrala)
|
||||
contact:
|
||||
email: info@mainflux.com
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: https://github.com/absmach/magistrala/blob/master/LICENSE
|
||||
version: 0.14.0
|
||||
|
||||
servers:
|
||||
- url: http://localhost:8180
|
||||
- url: https://localhost:8180
|
||||
|
||||
tags:
|
||||
- name: Auth
|
||||
description: Everything about your Authentication and Authorization.
|
||||
externalDocs:
|
||||
description: Find out more about auth
|
||||
url: https://docs.magistrala.abstractmachines.fr/
|
||||
- name: Keys
|
||||
description: Everything about your Keys.
|
||||
externalDocs:
|
||||
description: Find out more about keys
|
||||
url: https://docs.magistrala.abstractmachines.fr/
|
||||
|
||||
paths:
|
||||
/domains:
|
||||
post:
|
||||
tags:
|
||||
- Domains
|
||||
summary: Adds new domain
|
||||
description: |
|
||||
Adds new domain.
|
||||
requestBody:
|
||||
$ref: "#/components/requestBodies/DomainCreateReq"
|
||||
responses:
|
||||
"201":
|
||||
$ref: "#/components/responses/DomainCreateRes"
|
||||
"400":
|
||||
description: Failed due to malformed JSON.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"409":
|
||||
description: Failed due to using an existing alias.
|
||||
"415":
|
||||
description: Missing or invalid content type.
|
||||
"422":
|
||||
description: Database can't process request.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
get:
|
||||
summary: Retrieves list of domains.
|
||||
description: |
|
||||
Retrieves list of domains that the user have access.
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/Limit"
|
||||
- $ref: "#/components/parameters/Offset"
|
||||
- $ref: "#/components/parameters/Metadata"
|
||||
- $ref: "#/components/parameters/Status"
|
||||
- $ref: "#/components/parameters/DomainName"
|
||||
- $ref: "#/components/parameters/Permission"
|
||||
tags:
|
||||
- Domains
|
||||
security:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
"200":
|
||||
$ref: "#/components/responses/DomainsPageRes"
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"404":
|
||||
description: A non-existent entity request.
|
||||
"422":
|
||||
description: Database can't process request.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
/domains/{domainID}:
|
||||
get:
|
||||
summary: Retrieves domain information
|
||||
description: |
|
||||
Retrieves a specific domain that is identified by the domain ID.
|
||||
tags:
|
||||
- Domains
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/DomainID"
|
||||
security:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
"200":
|
||||
$ref: "#/components/responses/DomainRes"
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"404":
|
||||
description: A non-existent entity request.
|
||||
"422":
|
||||
description: Database can't process request.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
patch:
|
||||
summary: Updates name, metadata, tags and alias of the domain.
|
||||
description: |
|
||||
Updates name, metadata, tags and alias of the domain.
|
||||
tags:
|
||||
- Domains
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/DomainID"
|
||||
requestBody:
|
||||
$ref: "#/components/requestBodies/DomainUpdateReq"
|
||||
security:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
"200":
|
||||
$ref: "#/components/responses/DomainRes"
|
||||
"400":
|
||||
description: Failed due to malformed JSON.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"403":
|
||||
description: Unauthorized access to domain id.
|
||||
"404":
|
||||
description: Failed due to non existing domain.
|
||||
"415":
|
||||
description: Missing or invalid content type.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
delete:
|
||||
summary: Delete domain for a domain with the given id.
|
||||
description: |
|
||||
Delete domain removes a domain with the given id from repo
|
||||
and removes all the things, channels, assigned users, policies related to this domain.
|
||||
tags:
|
||||
- Domains
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/DomainID"
|
||||
security:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
"204":
|
||||
description: Domain deleted.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"403":
|
||||
description: Unauthorized access to domain id.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
/domains/{domainID}/permissions:
|
||||
get:
|
||||
summary: Retrieves user permissions on domain.
|
||||
description: |
|
||||
Retrieves user permissions on domain that is identified by the domain ID.
|
||||
tags:
|
||||
- Domains
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/DomainID"
|
||||
security:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
"200":
|
||||
$ref: "#/components/responses/DomainPermissionRes"
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"404":
|
||||
description: A non-existent entity request.
|
||||
"422":
|
||||
description: Database can't process request.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
/domains/{domainID}/enable:
|
||||
post:
|
||||
summary: Enables a domain
|
||||
description: |
|
||||
Enables a specific domain that is identified by the domain ID.
|
||||
tags:
|
||||
- Domains
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/DomainID"
|
||||
security:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
"200":
|
||||
description: Successfully enabled domain.
|
||||
"400":
|
||||
description: Failed due to malformed domain's ID.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"403":
|
||||
description: Unauthorized access the domain ID.
|
||||
"404":
|
||||
description: A non-existent entity request.
|
||||
"422":
|
||||
description: Database can't process request.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
/domains/{domainID}/disable:
|
||||
post:
|
||||
summary: Disable a domain
|
||||
description: |
|
||||
Disable a specific domain that is identified by the domain ID.
|
||||
tags:
|
||||
- Domains
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/DomainID"
|
||||
security:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
"200":
|
||||
description: Successfully disabled domain.
|
||||
"400":
|
||||
description: Failed due to malformed domain's ID.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"403":
|
||||
description: Unauthorized access the domain ID.
|
||||
"404":
|
||||
description: A non-existent entity request.
|
||||
"422":
|
||||
description: Database can't process request.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
/domains/{domainID}/freeze:
|
||||
post:
|
||||
summary: Freeze a domain
|
||||
description: |
|
||||
Freeze a specific domain that is identified by the domain ID.
|
||||
tags:
|
||||
- Domains
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/DomainID"
|
||||
security:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
"200":
|
||||
description: Successfully freezed domain.
|
||||
"400":
|
||||
description: Failed due to malformed domain's ID.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"403":
|
||||
description: Unauthorized access the domain ID.
|
||||
"404":
|
||||
description: A non-existent entity request.
|
||||
"422":
|
||||
description: Database can't process request.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
/domains/{domainID}/users/assign:
|
||||
post:
|
||||
summary: Assign users to domain
|
||||
description: |
|
||||
Assign users to domain that is identified by the domain ID.
|
||||
tags:
|
||||
- Domains
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/DomainID"
|
||||
requestBody:
|
||||
$ref: "#/components/requestBodies/AssignUserReq"
|
||||
security:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
"200":
|
||||
description: Users successfully assigned to domain.
|
||||
"400":
|
||||
description: Failed due to malformed domain's ID.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"403":
|
||||
description: Unauthorized access the domain ID.
|
||||
"404":
|
||||
description: A non-existent entity request.
|
||||
"409":
|
||||
description: Conflict of data.
|
||||
"422":
|
||||
description: Database can't process request.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
/domains/{domainID}/users/unassign:
|
||||
post:
|
||||
summary: Unassign users from domain
|
||||
description: |
|
||||
Unassign users from domain that is identified by the domain ID.
|
||||
tags:
|
||||
- Domains
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/DomainID"
|
||||
requestBody:
|
||||
$ref: "#/components/requestBodies/UnassignUsersReq"
|
||||
security:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
"200":
|
||||
description: Users successfully unassigned from domain.
|
||||
"400":
|
||||
description: Failed due to malformed domain's ID.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"403":
|
||||
description: Unauthorized access the domain ID.
|
||||
"404":
|
||||
description: A non-existent entity request.
|
||||
"409":
|
||||
description: Conflict of data.
|
||||
"422":
|
||||
description: Database can't process request.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
/keys:
|
||||
post:
|
||||
tags:
|
||||
- Keys
|
||||
summary: Issue API key
|
||||
description: |
|
||||
Generates a new API key. Thew new API key will
|
||||
be uniquely identified by its ID.
|
||||
requestBody:
|
||||
$ref: "#/components/requestBodies/KeyRequest"
|
||||
responses:
|
||||
"201":
|
||||
description: Issued new key.
|
||||
"400":
|
||||
description: Failed due to malformed JSON.
|
||||
"409":
|
||||
description: Failed due to using already existing ID.
|
||||
"415":
|
||||
description: Missing or invalid content type.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
/keys/{keyID}:
|
||||
get:
|
||||
summary: Gets API key details.
|
||||
description: |
|
||||
Gets API key details for the given key.
|
||||
tags:
|
||||
- Keys
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/ApiKeyId"
|
||||
responses:
|
||||
"200":
|
||||
$ref: "#/components/responses/KeyRes"
|
||||
"400":
|
||||
description: Failed due to malformed query parameters.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
delete:
|
||||
summary: Revoke API key
|
||||
description: |
|
||||
Revoke API key identified by the given ID.
|
||||
tags:
|
||||
- Keys
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/ApiKeyId"
|
||||
responses:
|
||||
"204":
|
||||
description: Key revoked.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
/policies:
|
||||
post:
|
||||
summary: Creates new policies.
|
||||
description: |
|
||||
Creates new policies. Only admin can use this endpoint. Therefore, you need an authentication token for the admin.
|
||||
Also, only policies defined on the system are allowed to add. For more details, please see the docs for Authorization.
|
||||
tags:
|
||||
- Auth
|
||||
requestBody:
|
||||
$ref: "#/components/requestBodies/PoliciesReq"
|
||||
responses:
|
||||
"201":
|
||||
description: Policies created.
|
||||
"400":
|
||||
description: Failed due to malformed JSON.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"403":
|
||||
description: Unauthorized access token provided.
|
||||
"409":
|
||||
description: Failed due to using an existing email address.
|
||||
"415":
|
||||
description: Missing or invalid content type.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
/policies/delete:
|
||||
post:
|
||||
summary: Deletes policies.
|
||||
description: |
|
||||
Deletes policies. Only admin can use this endpoint. Therefore, you need an authentication token for the admin.
|
||||
Also, only policies defined on the system are allowed to delete. For more details, please see the docs for Authorization.
|
||||
tags:
|
||||
- Auth
|
||||
requestBody:
|
||||
$ref: "#/components/requestBodies/PoliciesReq"
|
||||
responses:
|
||||
"204":
|
||||
description: Policies deleted.
|
||||
"400":
|
||||
description: Failed due to malformed JSON.
|
||||
"409":
|
||||
description: Failed due to using an existing email address.
|
||||
"415":
|
||||
description: Missing or invalid content type.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
/users/{memberID}/domains:
|
||||
get:
|
||||
tags:
|
||||
- Domains
|
||||
summary: List users in a group
|
||||
description: |
|
||||
Retrieves a list of users in a domain. Due to performance concerns, data
|
||||
is retrieved in subsets. The API must ensure that the entire
|
||||
dataset is consumed either by making subsequent requests, or by
|
||||
increasing the subset size of the initial request.
|
||||
parameters:
|
||||
- $ref: "users.yml#/components/parameters/MemberID"
|
||||
- $ref: "#/components/parameters/Limit"
|
||||
- $ref: "#/components/parameters/Offset"
|
||||
- $ref: "#/components/parameters/Metadata"
|
||||
- $ref: "#/components/parameters/Status"
|
||||
security:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
"200":
|
||||
$ref: "users.yml#/components/responses/UserPageRes"
|
||||
"400":
|
||||
description: Failed due to malformed query parameters.
|
||||
"401":
|
||||
description: |
|
||||
Missing or invalid access token provided.
|
||||
This endpoint is available only for administrators.
|
||||
"404":
|
||||
description: A non-existent entity request.
|
||||
"422":
|
||||
description: Database can't process request.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
/health:
|
||||
get:
|
||||
summary: Retrieves service health check info.
|
||||
tags:
|
||||
- health
|
||||
responses:
|
||||
"200":
|
||||
$ref: "#/components/responses/HealthRes"
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
components:
|
||||
schemas:
|
||||
DomainReqObj:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
example: domainName
|
||||
description: Domain name.
|
||||
tags:
|
||||
type: array
|
||||
minItems: 0
|
||||
items:
|
||||
type: string
|
||||
example: ["tag1", "tag2"]
|
||||
description: domain tags.
|
||||
metadata:
|
||||
type: object
|
||||
example: { "domain": "example.com" }
|
||||
description: Arbitrary, object-encoded domain's data.
|
||||
alias:
|
||||
type: string
|
||||
example: domain alias
|
||||
description: Domain alias.
|
||||
required:
|
||||
- name
|
||||
- alias
|
||||
Domain:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
example: bb7edb32-2eac-4aad-aebe-ed96fe073879
|
||||
description: Domain unique identifier.
|
||||
name:
|
||||
type: string
|
||||
example: domainName
|
||||
description: Domain name.
|
||||
tags:
|
||||
type: array
|
||||
minItems: 0
|
||||
items:
|
||||
type: string
|
||||
example: ["tag1", "tag2"]
|
||||
description: domain tags.
|
||||
metadata:
|
||||
type: object
|
||||
example: { "domain": "example.com" }
|
||||
description: Arbitrary, object-encoded domain's data.
|
||||
alias:
|
||||
type: string
|
||||
example: domain alias
|
||||
description: Domain alias.
|
||||
status:
|
||||
type: string
|
||||
description: Domain Status
|
||||
format: string
|
||||
example: enabled
|
||||
created_by:
|
||||
type: string
|
||||
format: uuid
|
||||
example: "0d837f56-3f8a-4e2a-9359-6347d0fc9f06 "
|
||||
description: User ID of the user who created the domain.
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
example: "2019-11-26 13:31:52"
|
||||
description: Time when the domain was created.
|
||||
updated_by:
|
||||
type: string
|
||||
format: uuid
|
||||
example: "80f66b77-ed74-4e74-9f88-6cce9a0a3049"
|
||||
description: User ID of the user who last updated the domain.
|
||||
updated_at:
|
||||
type: string
|
||||
format: date-time
|
||||
example: "2019-11-26 13:31:52"
|
||||
description: Time when the domain was last updated.
|
||||
xml:
|
||||
name: domain
|
||||
|
||||
DomainsPage:
|
||||
type: object
|
||||
properties:
|
||||
domains:
|
||||
type: array
|
||||
minItems: 0
|
||||
uniqueItems: true
|
||||
items:
|
||||
$ref: "#/components/schemas/Domain"
|
||||
total:
|
||||
type: integer
|
||||
example: 1
|
||||
description: Total number of items.
|
||||
offset:
|
||||
type: integer
|
||||
description: Number of items to skip during retrieval.
|
||||
limit:
|
||||
type: integer
|
||||
example: 10
|
||||
description: Maximum number of items to return in one page.
|
||||
required:
|
||||
- domain
|
||||
- total
|
||||
- offset
|
||||
DomainUpdate:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
example: domainName
|
||||
description: Domain name.
|
||||
tags:
|
||||
type: array
|
||||
minItems: 0
|
||||
items:
|
||||
type: string
|
||||
example: ["tag1", "tag2"]
|
||||
description: domain tags.
|
||||
metadata:
|
||||
type: object
|
||||
example: { "domain": "example.com" }
|
||||
description: Arbitrary, object-encoded thing's data.
|
||||
alias:
|
||||
type: string
|
||||
example: domain alias
|
||||
description: Domain alias.
|
||||
Permissions:
|
||||
type: object
|
||||
properties:
|
||||
permissions:
|
||||
type: array
|
||||
minItems: 0
|
||||
items:
|
||||
type: string
|
||||
description: Permissions
|
||||
|
||||
UserDomainRelationReq:
|
||||
type: object
|
||||
properties:
|
||||
users_ids:
|
||||
type: array
|
||||
minItems: 1
|
||||
items:
|
||||
type: string
|
||||
description: Users IDs
|
||||
example:
|
||||
[
|
||||
"5dc1ce4b-7cc9-4f12-98a6-9d74cc4980bb",
|
||||
"c01ed106-e52d-4aa4-bed3-39f360177cfa",
|
||||
]
|
||||
relation:
|
||||
type: string
|
||||
enum: ["administrator", "editor","viewer","member"]
|
||||
example: "administrator"
|
||||
description: Policy relations.
|
||||
required:
|
||||
- users_ids
|
||||
- relation
|
||||
Key:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
example: "c5747f2f-2a7c-4fe1-b41a-51a5ae290945"
|
||||
description: API key unique identifier
|
||||
issuer_id:
|
||||
type: string
|
||||
format: uuid
|
||||
example: "9118de62-c680-46b7-ad0a-21748a52833a"
|
||||
description: In ID of the entity that issued the token.
|
||||
type:
|
||||
type: integer
|
||||
example: 0
|
||||
description: API key type. Keys of different type are processed differently.
|
||||
subject:
|
||||
type: string
|
||||
format: string
|
||||
example: "test@example.com"
|
||||
description: User's email or service identifier of API key subject.
|
||||
issued_at:
|
||||
type: string
|
||||
format: date-time
|
||||
example: "2019-11-26 13:31:52"
|
||||
description: Time when the key is generated.
|
||||
expires_at:
|
||||
type: string
|
||||
format: date-time
|
||||
example: "2019-11-26 13:31:52"
|
||||
description: Time when the Key expires. If this field is missing,
|
||||
that means that Key is valid indefinitely.
|
||||
|
||||
PoliciesReqSchema:
|
||||
type: object
|
||||
properties:
|
||||
object:
|
||||
type: string
|
||||
description: |
|
||||
Specifies an object field for the field.
|
||||
Object indicates application objects such as ThingID.
|
||||
subjects:
|
||||
type: array
|
||||
minItems: 1
|
||||
uniqueItems: true
|
||||
items:
|
||||
type: string
|
||||
policies:
|
||||
type: array
|
||||
minItems: 1
|
||||
uniqueItems: true
|
||||
items:
|
||||
type: string
|
||||
|
||||
parameters:
|
||||
DomainID:
|
||||
name: domainID
|
||||
description: Unique domain identifier.
|
||||
in: path
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
required: true
|
||||
example: bb7edb32-2eac-4aad-aebe-ed96fe073879
|
||||
Status:
|
||||
name: status
|
||||
description: Domain status.
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
default: enabled
|
||||
required: false
|
||||
example: enabled
|
||||
DomainName:
|
||||
name: name
|
||||
description: Domain's name.
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
required: false
|
||||
example: "domainName"
|
||||
Permission:
|
||||
name: permission
|
||||
description: permission.
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
required: false
|
||||
example: "edit"
|
||||
ApiKeyId:
|
||||
name: keyID
|
||||
description: API Key ID.
|
||||
in: path
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
required: true
|
||||
Limit:
|
||||
name: limit
|
||||
description: Size of the subset to retrieve.
|
||||
in: query
|
||||
schema:
|
||||
type: integer
|
||||
default: 10
|
||||
maximum: 100
|
||||
minimum: 1
|
||||
required: false
|
||||
Offset:
|
||||
name: offset
|
||||
description: Number of items to skip during retrieval.
|
||||
in: query
|
||||
schema:
|
||||
type: integer
|
||||
default: 0
|
||||
minimum: 0
|
||||
required: false
|
||||
Metadata:
|
||||
name: metadata
|
||||
description: Metadata filter. Filtering is performed matching the parameter with metadata on top level. Parameter is json.
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
type: object
|
||||
additionalProperties: {}
|
||||
Type:
|
||||
name: type
|
||||
description: The type of the API Key.
|
||||
in: query
|
||||
schema:
|
||||
type: integer
|
||||
default: 0
|
||||
minimum: 0
|
||||
required: false
|
||||
Subject:
|
||||
name: subject
|
||||
description: The subject of an API Key
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
required: false
|
||||
|
||||
requestBodies:
|
||||
DomainCreateReq:
|
||||
description: JSON-formatted document describing the new domain to be registered
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/DomainReqObj"
|
||||
DomainUpdateReq:
|
||||
description: JSON-formated document describing the name, alias, tags, and metadata of the domain to be updated
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/DomainUpdate"
|
||||
AssignUserReq:
|
||||
description: JSON-formated document describing the policy related to assigning users to a domain
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/UserDomainRelationReq"
|
||||
|
||||
UnassignUsersReq:
|
||||
description: JSON-formated document describing the policy related to unassigning users to a domain
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/UserDomainRelationReq"
|
||||
|
||||
KeyRequest:
|
||||
description: JSON-formatted document describing key request.
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
type:
|
||||
type: integer
|
||||
example: 0
|
||||
description: API key type. Keys of different type are processed differently.
|
||||
duration:
|
||||
type: number
|
||||
format: integer
|
||||
example: 23456
|
||||
description: Number of seconds issued token is valid for.
|
||||
|
||||
PoliciesReq:
|
||||
description: JSON-formatted document describing adding policies request.
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/PoliciesReqSchema"
|
||||
|
||||
responses:
|
||||
ServiceError:
|
||||
description: Unexpected server-side error occurred.
|
||||
|
||||
DomainCreateRes:
|
||||
description: Create new domain.
|
||||
headers:
|
||||
Location:
|
||||
schema:
|
||||
type: string
|
||||
format: url
|
||||
description: Registered domain relative URL in the format `/domains/<domainID_id>`
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Domain"
|
||||
|
||||
DomainRes:
|
||||
description: Data retrieved.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Domain"
|
||||
DomainPermissionRes:
|
||||
description: Data retrieved.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Permissions"
|
||||
DomainsPageRes:
|
||||
description: Data retrieved.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/DomainsPage"
|
||||
|
||||
KeyRes:
|
||||
description: Data retrieved.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Key"
|
||||
|
||||
HealthRes:
|
||||
description: Service Health Check.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "./schemas/HealthInfo.yml"
|
||||
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
description: |
|
||||
* Users access: "Authorization: Bearer <user_token>"
|
||||
|
||||
security:
|
||||
- bearerAuth: []
|
||||
@@ -1,597 +0,0 @@
|
||||
# Copyright (c) Abstract Machines
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
openapi: 3.0.1
|
||||
info:
|
||||
title: Magistrala Bootstrap service
|
||||
description: |
|
||||
HTTP API for managing platform things configuration.
|
||||
Some useful links:
|
||||
- [The Magistrala repository](https://github.com/absmach/magistrala)
|
||||
contact:
|
||||
email: info@mainflux.com
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: https://github.com/absmach/magistrala/blob/master/LICENSE
|
||||
version: 0.14.0
|
||||
|
||||
servers:
|
||||
- url: http://localhost:9013
|
||||
- url: https://localhost:9013
|
||||
|
||||
tags:
|
||||
- name: configs
|
||||
description: Everything about your Configs
|
||||
externalDocs:
|
||||
description: Find out more about Configs
|
||||
url: https://docs.magistrala.abstractmachines.fr/
|
||||
|
||||
paths:
|
||||
/things/configs:
|
||||
post:
|
||||
summary: Adds new config
|
||||
description: |
|
||||
Adds new config to the list of config owned by user identified using
|
||||
the provided access token.
|
||||
tags:
|
||||
- configs
|
||||
requestBody:
|
||||
$ref: "#/components/requestBodies/ConfigCreateReq"
|
||||
responses:
|
||||
'201':
|
||||
$ref: "#/components/responses/ConfigCreateRes"
|
||||
'400':
|
||||
description: Failed due to malformed JSON.
|
||||
'401':
|
||||
description: Missing or invalid access token provided.
|
||||
'415':
|
||||
description: Missing or invalid content type.
|
||||
'500':
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
get:
|
||||
summary: Retrieves managed configs
|
||||
description: |
|
||||
Retrieves a list of managed configs. Due to performance concerns, data
|
||||
is retrieved in subsets. The API configs must ensure that the entire
|
||||
dataset is consumed either by making subsequent requests, or by
|
||||
increasing the subset size of the initial request.
|
||||
tags:
|
||||
- configs
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/Limit"
|
||||
- $ref: "#/components/parameters/Offset"
|
||||
- $ref: "#/components/parameters/State"
|
||||
- $ref: "#/components/parameters/Name"
|
||||
responses:
|
||||
'200':
|
||||
$ref: "#/components/responses/ConfigListRes"
|
||||
'400':
|
||||
description: Failed due to malformed query parameters.
|
||||
'401':
|
||||
description: Missing or invalid access token provided.
|
||||
'500':
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
/things/configs/{configId}:
|
||||
get:
|
||||
summary: Retrieves config info (with channels).
|
||||
tags:
|
||||
- configs
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/ConfigId"
|
||||
responses:
|
||||
'200':
|
||||
$ref: "#/components/responses/ConfigRes"
|
||||
'401':
|
||||
description: Missing or invalid access token provided.
|
||||
'404':
|
||||
description: Config does not exist.
|
||||
'500':
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
put:
|
||||
summary: Updates config info
|
||||
description: |
|
||||
Update is performed by replacing the current resource data with values
|
||||
provided in a request payload. Note that the owner, ID, external ID,
|
||||
external key, Magistrala Thing ID and key cannot be changed.
|
||||
tags:
|
||||
- configs
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/ConfigId"
|
||||
requestBody:
|
||||
$ref: "#/components/requestBodies/ConfigUpdateReq"
|
||||
responses:
|
||||
'200':
|
||||
description: Config updated.
|
||||
'400':
|
||||
description: Failed due to malformed JSON.
|
||||
'401':
|
||||
description: Missing or invalid access token provided.
|
||||
'404':
|
||||
description: Config does not exist.
|
||||
'415':
|
||||
description: Missing or invalid content type.
|
||||
'500':
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
delete:
|
||||
summary: Removes a Config
|
||||
description: |
|
||||
Removes a Config. In case of successful removal the service will ensure
|
||||
that the removed config is disconnected from all of the Magistrala channels.
|
||||
tags:
|
||||
- configs
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/ConfigId"
|
||||
responses:
|
||||
'204':
|
||||
description: Config removed.
|
||||
'400':
|
||||
description: Failed due to malformed config ID.
|
||||
'401':
|
||||
description: Missing or invalid access token provided.
|
||||
'500':
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
/things/configs/certs/{configId}:
|
||||
patch:
|
||||
summary: Updates certs
|
||||
description: |
|
||||
Update is performed by replacing the current certificate data with values
|
||||
provided in a request payload.
|
||||
tags:
|
||||
- configs
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/ConfigId"
|
||||
requestBody:
|
||||
$ref: "#/components/requestBodies/ConfigCertUpdateReq"
|
||||
responses:
|
||||
'200':
|
||||
description: Config updated.
|
||||
$ref: "#/components/responses/ConfigUpdateCertsRes"
|
||||
'400':
|
||||
description: Failed due to malformed JSON.
|
||||
'401':
|
||||
description: Missing or invalid access token provided.
|
||||
'404':
|
||||
description: Config does not exist.
|
||||
'415':
|
||||
description: Missing or invalid content type.
|
||||
'500':
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
/things/configs/connections/{configId}:
|
||||
put:
|
||||
summary: Updates channels the thing is connected to
|
||||
description: |
|
||||
Update connections performs update of the channel list corresponding
|
||||
Thing is connected to.
|
||||
tags:
|
||||
- configs
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/ConfigId"
|
||||
requestBody:
|
||||
$ref: "#/components/requestBodies/ConfigConnUpdateReq"
|
||||
responses:
|
||||
'200':
|
||||
description: Config updated.
|
||||
'400':
|
||||
description: Failed due to malformed JSON.
|
||||
'401':
|
||||
description: Missing or invalid access token provided.
|
||||
'404':
|
||||
description: Config does not exist.
|
||||
'415':
|
||||
description: Missing or invalid content type.
|
||||
'500':
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
/things/bootstrap/{externalId}:
|
||||
get:
|
||||
summary: Retrieves configuration.
|
||||
description: |
|
||||
Retrieves a configuration with given external ID and external key.
|
||||
tags:
|
||||
- configs
|
||||
security:
|
||||
- bootstrapAuth: []
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/ExternalId"
|
||||
responses:
|
||||
'200':
|
||||
$ref: "#/components/responses/BootstrapConfigRes"
|
||||
'400':
|
||||
description: Failed due to malformed JSON.
|
||||
'401':
|
||||
description: Missing or invalid external key provided.
|
||||
'404':
|
||||
description: Failed to retrieve corresponding config.
|
||||
'500':
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
/things/bootstrap/secure/{externalId}:
|
||||
get:
|
||||
summary: Retrieves configuration.
|
||||
description: |
|
||||
Retrieves a configuration with given external ID and encrypted external key.
|
||||
tags:
|
||||
- configs
|
||||
security:
|
||||
- bootstrapEncAuth: []
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/ExternalId"
|
||||
responses:
|
||||
'200':
|
||||
$ref: "#/components/responses/BootstrapConfigRes"
|
||||
'404':
|
||||
description: |
|
||||
Failed to retrieve corresponding config.
|
||||
'500':
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
/things/state/{configId}:
|
||||
put:
|
||||
summary: Updates Config state.
|
||||
description: |
|
||||
Updating state represents enabling/disabling Config, i.e. connecting
|
||||
and disconnecting corresponding Magistrala Thing to the list of Channels.
|
||||
tags:
|
||||
- configs
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/ConfigId"
|
||||
requestBody:
|
||||
$ref: '#/components/requestBodies/ConfigStateUpdateReq'
|
||||
responses:
|
||||
'204':
|
||||
description: Config removed.
|
||||
'400':
|
||||
description: Failed due to malformed config's ID.
|
||||
'401':
|
||||
description: Missing or invalid access token provided.
|
||||
'500':
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
/health:
|
||||
get:
|
||||
summary: Retrieves service health check info.
|
||||
tags:
|
||||
- health
|
||||
responses:
|
||||
'200':
|
||||
$ref: "#/components/responses/HealthRes"
|
||||
'500':
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
components:
|
||||
schemas:
|
||||
State:
|
||||
type: integer
|
||||
enum: [0, 1]
|
||||
Config:
|
||||
type: object
|
||||
properties:
|
||||
thing_id:
|
||||
type: string
|
||||
format: uuid
|
||||
description: Corresponding Magistrala Thing ID.
|
||||
magistrala_key:
|
||||
type: string
|
||||
format: uuid
|
||||
description: Corresponding Magistrala Thing key.
|
||||
channels:
|
||||
type: array
|
||||
minItems: 0
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
description: Channel unique identifier.
|
||||
name:
|
||||
type: string
|
||||
description: Name of the Channel.
|
||||
metadata:
|
||||
type: object
|
||||
description: Custom metadata related to the Channel.
|
||||
external_id:
|
||||
type: string
|
||||
description: External ID (MAC address or some unique identifier).
|
||||
external_key:
|
||||
type: string
|
||||
description: External key.
|
||||
content:
|
||||
type: string
|
||||
description: Free-form custom configuration.
|
||||
state:
|
||||
$ref: "#/components/schemas/State"
|
||||
client_cert:
|
||||
type: string
|
||||
description: Client certificate.
|
||||
ca_cert:
|
||||
type: string
|
||||
description: Issuing CA certificate.
|
||||
required:
|
||||
- external_id
|
||||
- external_key
|
||||
ConfigList:
|
||||
type: object
|
||||
properties:
|
||||
total:
|
||||
type: integer
|
||||
description: Total number of results.
|
||||
minimum: 0
|
||||
offset:
|
||||
type: integer
|
||||
description: Number of items to skip during retrieval.
|
||||
minimum: 0
|
||||
default: 0
|
||||
limit:
|
||||
type: integer
|
||||
description: Size of the subset to retrieve.
|
||||
maximum: 100
|
||||
default: 10
|
||||
configs:
|
||||
type: array
|
||||
minItems: 0
|
||||
uniqueItems: true
|
||||
items:
|
||||
$ref: "#/components/schemas/Config"
|
||||
required:
|
||||
- configs
|
||||
BootstrapConfig:
|
||||
type: object
|
||||
properties:
|
||||
thing_id:
|
||||
type: string
|
||||
format: uuid
|
||||
description: Corresponding Magistrala Thing ID.
|
||||
thing_key:
|
||||
type: string
|
||||
format: uuid
|
||||
description: Corresponding Magistrala Thing key.
|
||||
channels:
|
||||
type: array
|
||||
minItems: 0
|
||||
items:
|
||||
type: string
|
||||
content:
|
||||
type: string
|
||||
description: Free-form custom configuration.
|
||||
client_cert:
|
||||
type: string
|
||||
description: Client certificate.
|
||||
client_key:
|
||||
type: string
|
||||
description: Key for the client_cert.
|
||||
ca_cert:
|
||||
type: string
|
||||
description: Issuing CA certificate.
|
||||
required:
|
||||
- thing_id
|
||||
- thing_key
|
||||
- channels
|
||||
- content
|
||||
ConfigUpdateCerts:
|
||||
type: object
|
||||
properties:
|
||||
thing_id:
|
||||
type: string
|
||||
format: uuid
|
||||
description: Corresponding Magistrala Thing ID.
|
||||
client_cert:
|
||||
type: string
|
||||
description: Client certificate.
|
||||
client_key:
|
||||
type: string
|
||||
description: Key for the client_cert.
|
||||
ca_cert:
|
||||
type: string
|
||||
description: Issuing CA certificate.
|
||||
required:
|
||||
- thing_id
|
||||
- thing_key
|
||||
- channels
|
||||
- content
|
||||
|
||||
parameters:
|
||||
ConfigId:
|
||||
name: configId
|
||||
description: Unique Config identifier. It's the ID of the corresponding Thing.
|
||||
in: path
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
required: true
|
||||
ExternalId:
|
||||
name: externalId
|
||||
description: Unique Config identifier provided by external entity.
|
||||
in: path
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
Limit:
|
||||
name: limit
|
||||
description: Size of the subset to retrieve.
|
||||
in: query
|
||||
schema:
|
||||
type: integer
|
||||
default: 10
|
||||
maximum: 100
|
||||
minimum: 1
|
||||
required: false
|
||||
Offset:
|
||||
name: offset
|
||||
description: Number of items to skip during retrieval.
|
||||
in: query
|
||||
schema:
|
||||
type: integer
|
||||
default: 0
|
||||
minimum: 0
|
||||
required: false
|
||||
State:
|
||||
name: state
|
||||
description: A state of items
|
||||
in: query
|
||||
schema:
|
||||
$ref: "#/components/schemas/State"
|
||||
required: false
|
||||
Name:
|
||||
name: name
|
||||
description: Name of the config. Search by name is partial-match and case-insensitive.
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
required: false
|
||||
|
||||
requestBodies:
|
||||
ConfigCreateReq:
|
||||
description: JSON-formatted document describing the new config.
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
external_id:
|
||||
type: string
|
||||
description: External ID (MAC address or some unique identifier).
|
||||
external_key:
|
||||
type: string
|
||||
description: External key.
|
||||
thing_id:
|
||||
type: string
|
||||
description: ID of the corresponding Magistrala Thing.
|
||||
channels:
|
||||
type: array
|
||||
minItems: 0
|
||||
items:
|
||||
type: string
|
||||
content:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
client_cert:
|
||||
type: string
|
||||
description: Thing Certificate.
|
||||
client_key:
|
||||
type: string
|
||||
description: Thing Private Key.
|
||||
ca_cert:
|
||||
type: string
|
||||
required:
|
||||
- external_id
|
||||
- external_key
|
||||
ConfigUpdateReq:
|
||||
description: JSON-formatted document describing the updated thing.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
content:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
required:
|
||||
- content
|
||||
- name
|
||||
ConfigCertUpdateReq:
|
||||
description: JSON-formatted document describing the updated thing.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
client_cert:
|
||||
type: string
|
||||
client_key:
|
||||
type: string
|
||||
ca_cert:
|
||||
type: string
|
||||
ConfigConnUpdateReq:
|
||||
description: Array if IDs the thing is be connected to.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
channels:
|
||||
type: array
|
||||
minItems: 0
|
||||
items:
|
||||
type: string
|
||||
ConfigStateUpdateReq:
|
||||
description: Update the state of the Config.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
state:
|
||||
$ref: "#/components/schemas/State"
|
||||
|
||||
responses:
|
||||
ConfigCreateRes:
|
||||
description: Config registered.
|
||||
headers:
|
||||
Location:
|
||||
content:
|
||||
text/plain:
|
||||
schema:
|
||||
type: string
|
||||
description: Created configuration's relative URL (i.e. /things/configs/{configId}).
|
||||
ConfigListRes:
|
||||
description: Data retrieved. Configs from this list don't contain channels.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ConfigList"
|
||||
ConfigRes:
|
||||
description: Data retrieved.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Config"
|
||||
BootstrapConfigRes:
|
||||
description: |
|
||||
Data retrieved. If secure, a response is encrypted using
|
||||
the secret key, so the response is in the binary form.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/BootstrapConfig"
|
||||
ServiceError:
|
||||
description: Unexpected server-side error occurred.
|
||||
HealthRes:
|
||||
description: Service Health Check.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "./schemas/HealthInfo.yml"
|
||||
ConfigUpdateCertsRes:
|
||||
description: Data retrieved. Config certs updated.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ConfigUpdateCerts"
|
||||
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
description: |
|
||||
* Users access: "Authorization: Bearer <user_token>"
|
||||
|
||||
bootstrapAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: string
|
||||
description: |
|
||||
* Things access: "Authorization: Thing <external_key>"
|
||||
|
||||
bootstrapEncAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: aes-sha256-uuid
|
||||
description: |
|
||||
* Things access: "Authorization: Thing <external_enc_key>"
|
||||
Hex-encoded configuration external key encrypted using
|
||||
the AES algorithm and SHA256 sum of the external key
|
||||
itself as an encryption key.
|
||||
|
||||
security:
|
||||
- bearerAuth: []
|
||||
@@ -1,274 +0,0 @@
|
||||
# Copyright (c) Abstract Machines
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
openapi: 3.0.1
|
||||
info:
|
||||
title: Magistrala Certs service
|
||||
description: |
|
||||
HTTP API for Certs service
|
||||
Some useful links:
|
||||
- [The Magistrala repository](https://github.com/absmach/magistrala)
|
||||
contact:
|
||||
email: info@mainflux.com
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: https://github.com/absmach/magistrala/blob/master/LICENSE
|
||||
version: 0.14.0
|
||||
|
||||
servers:
|
||||
- url: http://localhost:9019
|
||||
- url: https://localhost:9019
|
||||
|
||||
tags:
|
||||
- name: certs
|
||||
description: Everything about your Certs
|
||||
externalDocs:
|
||||
description: Find out more about certs
|
||||
url: https://docs.magistrala.abstractmachines.fr/
|
||||
|
||||
paths:
|
||||
/certs:
|
||||
post:
|
||||
summary: Creates a certificate for thing
|
||||
description: Creates a certificate for thing
|
||||
tags:
|
||||
- certs
|
||||
requestBody:
|
||||
$ref: "#/components/requestBodies/CertReq"
|
||||
responses:
|
||||
'201':
|
||||
description: Created
|
||||
'400':
|
||||
description: Failed due to malformed JSON.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
'500':
|
||||
description: Unexpected server-side error ocurred.
|
||||
/certs/{certID}:
|
||||
get:
|
||||
summary: Retrieves a certificate
|
||||
description: |
|
||||
Retrieves a certificate for a given cert ID.
|
||||
tags:
|
||||
- certs
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/CertID"
|
||||
responses:
|
||||
'200':
|
||||
$ref: "#/components/responses/CertRes"
|
||||
'400':
|
||||
description: Failed due to malformed query parameters.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
'404':
|
||||
description: |
|
||||
Failed to retrieve corresponding certificate.
|
||||
'500':
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
delete:
|
||||
summary: Revokes a certificate
|
||||
description: |
|
||||
Revokes a certificate for a given cert ID.
|
||||
tags:
|
||||
- certs
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/CertID"
|
||||
responses:
|
||||
'200':
|
||||
$ref: "#/components/responses/RevokeRes"
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
'404':
|
||||
description: |
|
||||
Failed to revoke corresponding certificate.
|
||||
'500':
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
/serials/{thingID}:
|
||||
get:
|
||||
summary: Retrieves certificates' serial IDs
|
||||
description: |
|
||||
Retrieves a list of certificates' serial IDs for a given thing ID.
|
||||
tags:
|
||||
- certs
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/ThingID"
|
||||
responses:
|
||||
'200':
|
||||
$ref: "#/components/responses/SerialsPageRes"
|
||||
'400':
|
||||
description: Failed due to malformed query parameters.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
'404':
|
||||
description: |
|
||||
Failed to retrieve corresponding certificates.
|
||||
'500':
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
/health:
|
||||
get:
|
||||
summary: Retrieves service health check info.
|
||||
tags:
|
||||
- health
|
||||
responses:
|
||||
'200':
|
||||
$ref: "#/components/responses/HealthRes"
|
||||
'500':
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
components:
|
||||
parameters:
|
||||
ThingID:
|
||||
name: thingID
|
||||
description: Thing ID
|
||||
in: path
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
required: true
|
||||
CertID:
|
||||
name: certID
|
||||
description: Serial of certificate
|
||||
in: path
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
required: true
|
||||
|
||||
schemas:
|
||||
Cert:
|
||||
type: object
|
||||
properties:
|
||||
thing_id:
|
||||
type: string
|
||||
format: uuid
|
||||
description: Corresponding Magistrala Thing ID.
|
||||
client_cert:
|
||||
type: string
|
||||
description: Client Certificate.
|
||||
client_key:
|
||||
type: string
|
||||
description: Key for the client_cert.
|
||||
issuing_ca:
|
||||
type: string
|
||||
description: CA Certificate that is used to issue client certs, usually intermediate.
|
||||
serial:
|
||||
type: string
|
||||
description: Certificate serial
|
||||
expire:
|
||||
type: string
|
||||
description: Certificate expiry date
|
||||
Serial:
|
||||
type: object
|
||||
properties:
|
||||
serial:
|
||||
type: string
|
||||
description: Certificate serial
|
||||
CertsPage:
|
||||
type: object
|
||||
properties:
|
||||
certs:
|
||||
type: array
|
||||
minItems: 0
|
||||
uniqueItems: true
|
||||
items:
|
||||
$ref: "#/components/schemas/Cert"
|
||||
total:
|
||||
type: integer
|
||||
description: Total number of items.
|
||||
offset:
|
||||
type: integer
|
||||
description: Number of items to skip during retrieval.
|
||||
limit:
|
||||
type: integer
|
||||
description: Maximum number of items to return in one page.
|
||||
SerialsPage:
|
||||
type: object
|
||||
properties:
|
||||
serials:
|
||||
type: array
|
||||
description: Certificate serials IDs.
|
||||
minItems: 0
|
||||
uniqueItems: true
|
||||
items:
|
||||
type: string
|
||||
total:
|
||||
type: integer
|
||||
description: Total number of items.
|
||||
offset:
|
||||
type: integer
|
||||
description: Number of items to skip during retrieval.
|
||||
limit:
|
||||
type: integer
|
||||
description: Maximum number of items to return in one page.
|
||||
Revoke:
|
||||
type: object
|
||||
properties:
|
||||
revocation_time:
|
||||
type: string
|
||||
description: Certificate revocation time
|
||||
|
||||
requestBodies:
|
||||
CertReq:
|
||||
description: |
|
||||
Issues a certificate that is required for mTLS. To create a certificate for a thing
|
||||
provide a thing id, data identifying particular thing will be embedded into the Certificate.
|
||||
x509 and ECC certificates are supported when using when Vault is used as PKI.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required:
|
||||
- thing_id
|
||||
- ttl
|
||||
properties:
|
||||
thing_id:
|
||||
type: string
|
||||
format: uuid
|
||||
ttl:
|
||||
type: string
|
||||
example: "10h"
|
||||
|
||||
responses:
|
||||
ServiceError:
|
||||
description: Unexpected server-side error occurred.
|
||||
CertRes:
|
||||
description: Certificate data.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Cert"
|
||||
CertsPageRes:
|
||||
description: Certificates page.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/CertsPage"
|
||||
SerialsPageRes:
|
||||
description: Serials page.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/SerialsPage"
|
||||
RevokeRes:
|
||||
description: Certificate revoked.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Revoke"
|
||||
HealthRes:
|
||||
description: Service Health Check.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "./schemas/HealthInfo.yml"
|
||||
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
description: |
|
||||
* Users access: "Authorization: Bearer <user_token>"
|
||||
|
||||
security:
|
||||
- bearerAuth: []
|
||||
@@ -1,486 +0,0 @@
|
||||
# Copyright (c) Abstract Machines
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: Magistrala Invitations Service
|
||||
description: |
|
||||
This is the Invitations Server based on the OpenAPI 3.0 specification. It is the HTTP API for managing platform invitations. You can now help us improve the API whether it's by making changes to the definition itself or to the code.
|
||||
Some useful links:
|
||||
- [The Magistrala repository](https://github.com/absmach/magistrala)
|
||||
contact:
|
||||
email: info@mainflux.com
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: https://github.com/absmach/magistrala/blob/master/LICENSE
|
||||
version: 0.14.0
|
||||
|
||||
servers:
|
||||
- url: http://localhost:9020
|
||||
- url: https://localhost:9020
|
||||
|
||||
tags:
|
||||
- name: Invitations
|
||||
description: Everything about your Invitations
|
||||
externalDocs:
|
||||
description: Find out more about Invitations
|
||||
url: https://docs.magistrala.abstractmachines.fr/
|
||||
|
||||
paths:
|
||||
/invitations:
|
||||
post:
|
||||
tags:
|
||||
- Invitations
|
||||
summary: Send invitation
|
||||
description: |
|
||||
Send invitation to user to join domain.
|
||||
requestBody:
|
||||
$ref: "#/components/requestBodies/SendInvitationReq"
|
||||
security:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
"201":
|
||||
description: Invitation sent.
|
||||
"400":
|
||||
description: Failed due to malformed JSON.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"409":
|
||||
description: Failed due to using an existing identity.
|
||||
"415":
|
||||
description: Missing or invalid content type.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
get:
|
||||
tags:
|
||||
- Invitations
|
||||
summary: List invitations
|
||||
description: |
|
||||
Retrieves a list of invitations. Due to performance concerns, data
|
||||
is retrieved in subsets. The API must ensure that the entire
|
||||
dataset is consumed either by making subsequent requests, or by
|
||||
increasing the subset size of the initial request.
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/Limit"
|
||||
- $ref: "#/components/parameters/Offset"
|
||||
- $ref: "#/components/parameters/UserID"
|
||||
- $ref: "#/components/parameters/InvitedBy"
|
||||
- $ref: "#/components/parameters/DomainID"
|
||||
- $ref: "#/components/parameters/Relation"
|
||||
- $ref: "#/components/parameters/State"
|
||||
security:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
"200":
|
||||
$ref: "#/components/responses/InvitationPageRes"
|
||||
"400":
|
||||
description: Failed due to malformed query parameters.
|
||||
"401":
|
||||
description: |
|
||||
Missing or invalid access token provided.
|
||||
This endpoint is available only for administrators.
|
||||
"404":
|
||||
description: A non-existent entity request.
|
||||
"422":
|
||||
description: Database can't process request.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
/invitations/accept:
|
||||
post:
|
||||
summary: Accept invitation
|
||||
description: |
|
||||
Current logged in user accepts invitation to join domain.
|
||||
tags:
|
||||
- Invitations
|
||||
security:
|
||||
- bearerAuth: []
|
||||
requestBody:
|
||||
$ref: "#/components/requestBodies/AcceptInvitationReq"
|
||||
responses:
|
||||
"200":
|
||||
description: Invitation accepted.
|
||||
"400":
|
||||
description: Failed due to malformed query parameters.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
/invitations/{user_id}/{domain_id}:
|
||||
get:
|
||||
summary: Retrieves a specific invitation
|
||||
description: |
|
||||
Retrieves a specific invitation that is identifier by the user ID and domain ID.
|
||||
tags:
|
||||
- Invitations
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/user_id"
|
||||
- $ref: "#/components/parameters/domain_id"
|
||||
security:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
"200":
|
||||
$ref: "#/components/responses/InvitationRes"
|
||||
"400":
|
||||
description: Failed due to malformed query parameters.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"404":
|
||||
description: A non-existent entity request.
|
||||
"422":
|
||||
description: Database can't process request.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
delete:
|
||||
summary: Deletes a specific invitation
|
||||
description: |
|
||||
Deletes a specific invitation that is identifier by the user ID and domain ID.
|
||||
tags:
|
||||
- Invitations
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/user_id"
|
||||
- $ref: "#/components/parameters/domain_id"
|
||||
security:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
"204":
|
||||
description: Invitation deleted.
|
||||
"400":
|
||||
description: Failed due to malformed JSON.
|
||||
"404":
|
||||
description: Failed due to non existing user.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
/health:
|
||||
get:
|
||||
summary: Retrieves service health check info.
|
||||
tags:
|
||||
- health
|
||||
responses:
|
||||
"200":
|
||||
$ref: "#/components/responses/HealthRes"
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
components:
|
||||
schemas:
|
||||
SendInvitationReqObj:
|
||||
type: object
|
||||
properties:
|
||||
user_id:
|
||||
type: string
|
||||
format: uuid
|
||||
example: bb7edb32-2eac-4aad-aebe-ed96fe073879
|
||||
description: User unique identifier.
|
||||
domain_id:
|
||||
type: string
|
||||
format: uuid
|
||||
example: bb7edb32-2eac-4aad-aebe-ed96fe073879
|
||||
description: Domain unique identifier.
|
||||
relation:
|
||||
type: string
|
||||
enum:
|
||||
- administrator
|
||||
- editor
|
||||
- viewer
|
||||
- member
|
||||
- domain
|
||||
- parent_group
|
||||
- role_group
|
||||
- group
|
||||
- platform
|
||||
example: editor
|
||||
description: Relation between user and domain.
|
||||
resend:
|
||||
type: boolean
|
||||
example: true
|
||||
description: Resend invitation.
|
||||
required:
|
||||
- user_id
|
||||
- domain_id
|
||||
- relation
|
||||
|
||||
Invitation:
|
||||
type: object
|
||||
properties:
|
||||
invited_by:
|
||||
type: string
|
||||
format: uuid
|
||||
example: bb7edb32-2eac-4aad-aebe-ed96fe073879
|
||||
description: User unique identifier.
|
||||
user_id:
|
||||
type: string
|
||||
format: uuid
|
||||
example: bb7edb32-2eac-4aad-aebe-ed96fe073879
|
||||
description: User unique identifier.
|
||||
domain_id:
|
||||
type: string
|
||||
format: uuid
|
||||
example: bb7edb32-2eac-4aad-aebe-ed96fe073879
|
||||
description: Domain unique identifier.
|
||||
relation:
|
||||
type: string
|
||||
enum:
|
||||
- administrator
|
||||
- editor
|
||||
- viewer
|
||||
- member
|
||||
- domain
|
||||
- parent_group
|
||||
- role_group
|
||||
- group
|
||||
- platform
|
||||
example: editor
|
||||
description: Relation between user and domain.
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
example: "2019-11-26 13:31:52"
|
||||
description: Time when the group was created.
|
||||
updated_at:
|
||||
type: string
|
||||
format: date-time
|
||||
example: "2019-11-26 13:31:52"
|
||||
description: Time when the group was created.
|
||||
confirmed_at:
|
||||
type: string
|
||||
format: date-time
|
||||
example: "2019-11-26 13:31:52"
|
||||
description: Time when the group was created.
|
||||
xml:
|
||||
name: invitation
|
||||
|
||||
InvitationPage:
|
||||
type: object
|
||||
properties:
|
||||
invitations:
|
||||
type: array
|
||||
minItems: 0
|
||||
uniqueItems: true
|
||||
items:
|
||||
$ref: "#/components/schemas/Invitation"
|
||||
total:
|
||||
type: integer
|
||||
example: 1
|
||||
description: Total number of items.
|
||||
offset:
|
||||
type: integer
|
||||
description: Number of items to skip during retrieval.
|
||||
limit:
|
||||
type: integer
|
||||
example: 10
|
||||
description: Maximum number of items to return in one page.
|
||||
required:
|
||||
- invitations
|
||||
- total
|
||||
- offset
|
||||
|
||||
Error:
|
||||
type: object
|
||||
properties:
|
||||
error:
|
||||
type: string
|
||||
description: Error message
|
||||
example: { "error": "malformed entity specification" }
|
||||
|
||||
HealthRes:
|
||||
type: object
|
||||
properties:
|
||||
status:
|
||||
type: string
|
||||
description: Service status.
|
||||
enum:
|
||||
- pass
|
||||
version:
|
||||
type: string
|
||||
description: Service version.
|
||||
example: 0.14.0
|
||||
commit:
|
||||
type: string
|
||||
description: Service commit hash.
|
||||
example: 7d6f4dc4f7f0c1fa3dc24eddfb18bb5073ff4f62
|
||||
description:
|
||||
type: string
|
||||
description: Service description.
|
||||
example: <service_name> service
|
||||
build_time:
|
||||
type: string
|
||||
description: Service build time.
|
||||
example: 1970-01-01_00:00:00
|
||||
|
||||
parameters:
|
||||
Offset:
|
||||
name: offset
|
||||
description: Number of items to skip during retrieval.
|
||||
in: query
|
||||
schema:
|
||||
type: integer
|
||||
default: 0
|
||||
minimum: 0
|
||||
required: false
|
||||
example: "0"
|
||||
|
||||
Limit:
|
||||
name: limit
|
||||
description: Size of the subset to retrieve.
|
||||
in: query
|
||||
schema:
|
||||
type: integer
|
||||
default: 10
|
||||
maximum: 10
|
||||
minimum: 1
|
||||
required: false
|
||||
example: "10"
|
||||
|
||||
UserID:
|
||||
name: user_id
|
||||
description: Unique user identifier.
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
required: true
|
||||
example: bb7edb32-2eac-4aad-aebe-ed96fe073879
|
||||
|
||||
user_id:
|
||||
name: user_id
|
||||
description: Unique user identifier.
|
||||
in: path
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
required: true
|
||||
example: bb7edb32-2eac-4aad-aebe-ed96fe073879
|
||||
|
||||
DomainID:
|
||||
name: domain_id
|
||||
description: Unique identifier for a domain.
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
required: false
|
||||
example: bb7edb32-2eac-4aad-aebe-ed96fe073879
|
||||
|
||||
domain_id:
|
||||
name: domain_id
|
||||
description: Unique identifier for a domain.
|
||||
in: path
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
required: true
|
||||
example: bb7edb32-2eac-4aad-aebe-ed96fe073879
|
||||
|
||||
InvitedBy:
|
||||
name: invited_by
|
||||
description: Unique identifier for a user that invited the user.
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
required: false
|
||||
example: bb7edb32-2eac-4aad-aebe-ed96fe073879
|
||||
|
||||
Relation:
|
||||
name: relation
|
||||
description: Relation between user and domain.
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
enum:
|
||||
- administrator
|
||||
- editor
|
||||
- viewer
|
||||
- member
|
||||
- domain
|
||||
- parent_group
|
||||
- role_group
|
||||
- group
|
||||
- platform
|
||||
required: false
|
||||
example: editor
|
||||
|
||||
State:
|
||||
name: state
|
||||
description: Invitation state.
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
enum:
|
||||
- pending
|
||||
- accepted
|
||||
- all
|
||||
required: false
|
||||
example: accepted
|
||||
|
||||
requestBodies:
|
||||
SendInvitationReq:
|
||||
description: JSON-formatted document describing request for sending invitation
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/SendInvitationReqObj"
|
||||
|
||||
AcceptInvitationReq:
|
||||
description: JSON-formatted document describing request for accepting invitation
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
domain_id:
|
||||
type: string
|
||||
format: uuid
|
||||
example: bb7edb32-2eac-4aad-aebe-ed96fe073879
|
||||
description: Domain unique identifier.
|
||||
required:
|
||||
- domain_id
|
||||
|
||||
responses:
|
||||
InvitationRes:
|
||||
description: Data retrieved.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Invitation"
|
||||
|
||||
InvitationPageRes:
|
||||
description: Data retrieved.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/InvitationPage"
|
||||
|
||||
HealthRes:
|
||||
description: Service Health Check.
|
||||
content:
|
||||
application/health+json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/HealthRes"
|
||||
|
||||
ServiceError:
|
||||
description: Unexpected server-side error occurred.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
description: |
|
||||
* User access: "Authorization: Bearer <user_access_token>"
|
||||
|
||||
security:
|
||||
- bearerAuth: []
|
||||
@@ -1,116 +0,0 @@
|
||||
# Copyright (c) Abstract Machines
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
openapi: 3.0.1
|
||||
info:
|
||||
title: Magistrala Provision service
|
||||
description: |
|
||||
HTTP API for Provision service
|
||||
Some useful links:
|
||||
- [The Magistrala repository](https://github.com/absmach/magistrala)
|
||||
contact:
|
||||
email: info@mainflux.com
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: https://github.com/absmach/magistrala/blob/master/LICENSE
|
||||
version: 0.14.0
|
||||
|
||||
servers:
|
||||
- url: http://localhost:9016
|
||||
- url: https://localhost:9016
|
||||
|
||||
tags:
|
||||
- name: provision
|
||||
description: Everything about your Provision
|
||||
externalDocs:
|
||||
description: Find out more about provision
|
||||
url: https://docs.magistrala.abstractmachines.fr/
|
||||
|
||||
paths:
|
||||
/mapping:
|
||||
post:
|
||||
summary: Adds new device to proxy
|
||||
description: Adds new device to proxy
|
||||
tags:
|
||||
- provision
|
||||
requestBody:
|
||||
$ref: "#/components/requestBodies/ProvisionReq"
|
||||
responses:
|
||||
'201':
|
||||
description: Created
|
||||
'400':
|
||||
description: Failed due to malformed JSON.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
'500':
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
get:
|
||||
summary: Gets current mapping.
|
||||
description: Gets current mapping. This can be used in UI
|
||||
so that when bootstrap config is created from UI matches
|
||||
configuration created with provision service.
|
||||
tags:
|
||||
- provision
|
||||
responses:
|
||||
'200':
|
||||
$ref: "#/components/responses/ProvisionRes"
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
'500':
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
/health:
|
||||
get:
|
||||
summary: Retrieves service health check info.
|
||||
tags:
|
||||
- health
|
||||
responses:
|
||||
'200':
|
||||
$ref: "#/components/responses/HealthRes"
|
||||
'500':
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
components:
|
||||
requestBodies:
|
||||
ProvisionReq:
|
||||
description: MAC address of device or other identifier
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required:
|
||||
- external_id
|
||||
- external_key
|
||||
properties:
|
||||
external_id:
|
||||
type: string
|
||||
external_key:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
|
||||
responses:
|
||||
ServiceError:
|
||||
description: Unexpected server-side error occurred.
|
||||
ProvisionRes:
|
||||
description: Current mapping JSON representation.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
HealthRes:
|
||||
description: Service Health Check.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "./schemas/HealthInfo.yml"
|
||||
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
description: |
|
||||
* Users access: "Authorization: Bearer <user_token>"
|
||||
|
||||
security:
|
||||
- bearerAuth: []
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,402 +0,0 @@
|
||||
# Copyright (c) Abstract Machines
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
openapi: 3.0.1
|
||||
info:
|
||||
title: Magistrala twins service
|
||||
description: |
|
||||
HTTP API for managing digital twins and their states.
|
||||
Some useful links:
|
||||
- [The Magistrala repository](https://github.com/absmach/magistrala)
|
||||
contact:
|
||||
email: info@mainflux.com
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: https://github.com/absmach/magistrala/blob/master/LICENSE
|
||||
version: 0.14.0
|
||||
|
||||
servers:
|
||||
- url: http://localhost:9018
|
||||
- url: https://localhost:9018
|
||||
|
||||
tags:
|
||||
- name: twins
|
||||
description: Everything about your Twins
|
||||
externalDocs:
|
||||
description: Find out more about twins
|
||||
url: https://docs.magistrala.abstractmachines.fr/
|
||||
|
||||
|
||||
paths:
|
||||
/twins:
|
||||
post:
|
||||
summary: Adds new twin
|
||||
description: |
|
||||
Adds new twin to the list of twins owned by user identified using
|
||||
the provided access token.
|
||||
tags:
|
||||
- twins
|
||||
requestBody:
|
||||
$ref: "#/components/requestBodies/TwinReq"
|
||||
responses:
|
||||
'201':
|
||||
$ref: "#/components/responses/TwinCreateRes"
|
||||
'400':
|
||||
description: Failed due to malformed JSON.
|
||||
'401':
|
||||
description: Missing or invalid access token provided.
|
||||
'415':
|
||||
description: Missing or invalid content type.
|
||||
'500':
|
||||
$ref: '#/components/responses/ServiceError'
|
||||
|
||||
get:
|
||||
summary: Retrieves twins
|
||||
description: |
|
||||
Retrieves a list of twins. Due to performance concerns, data
|
||||
is retrieved in subsets.
|
||||
tags:
|
||||
- twins
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/Limit'
|
||||
- $ref: '#/components/parameters/Offset'
|
||||
- $ref: '#/components/parameters/Name'
|
||||
- $ref: '#/components/parameters/Metadata'
|
||||
responses:
|
||||
'200':
|
||||
$ref: '#/components/responses/TwinsPageRes'
|
||||
'400':
|
||||
description: Failed due to malformed query parameters.
|
||||
'401':
|
||||
description: Missing or invalid access token provided.
|
||||
'500':
|
||||
$ref: '#/components/responses/ServiceError'
|
||||
|
||||
/twins/{twinID}:
|
||||
get:
|
||||
summary: Retrieves twin info
|
||||
tags:
|
||||
- twins
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/TwinID'
|
||||
responses:
|
||||
'200':
|
||||
$ref: '#/components/responses/TwinRes'
|
||||
'400':
|
||||
description: Failed due to malformed twin's ID.
|
||||
'401':
|
||||
description: Missing or invalid access token provided.
|
||||
'404':
|
||||
description: Twin does not exist.
|
||||
'500':
|
||||
$ref: '#/components/responses/ServiceError'
|
||||
put:
|
||||
summary: Updates twin info
|
||||
description: |
|
||||
Update is performed by replacing the current resource data with values
|
||||
provided in a request payload. Note that the twin's ID cannot be changed.
|
||||
tags:
|
||||
- twins
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/TwinID'
|
||||
requestBody:
|
||||
$ref: '#/components/requestBodies/TwinReq'
|
||||
responses:
|
||||
'200':
|
||||
description: Twin updated.
|
||||
'400':
|
||||
description: Failed due to malformed twin's ID or malformed JSON.
|
||||
'401':
|
||||
description: Missing or invalid access token provided.
|
||||
'404':
|
||||
description: Twin does not exist.
|
||||
'415':
|
||||
description: Missing or invalid content type.
|
||||
'500':
|
||||
$ref: '#/components/responses/ServiceError'
|
||||
delete:
|
||||
summary: Removes a twin
|
||||
description: Removes a twin.
|
||||
tags:
|
||||
- twins
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/TwinID'
|
||||
responses:
|
||||
'204':
|
||||
description: Twin removed.
|
||||
'400':
|
||||
description: Failed due to malformed twin's ID.
|
||||
'401':
|
||||
description: Missing or invalid access token provided
|
||||
'404':
|
||||
description: Twin does not exist.
|
||||
'500':
|
||||
$ref: '#/components/responses/ServiceError'
|
||||
|
||||
/states/{twinID}:
|
||||
get:
|
||||
summary: Retrieves states of twin with id twinID
|
||||
description: |
|
||||
Retrieves a list of states. Due to performance concerns, data
|
||||
is retrieved in subsets.
|
||||
tags:
|
||||
- states
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/TwinID'
|
||||
- $ref: '#/components/parameters/Limit'
|
||||
- $ref: '#/components/parameters/Offset'
|
||||
responses:
|
||||
'200':
|
||||
$ref: '#/components/responses/StatesPageRes'
|
||||
'400':
|
||||
description: Failed due to malformed query parameters.
|
||||
'401':
|
||||
description: Missing or invalid access token provided.
|
||||
'404':
|
||||
description: Twin does not exist.
|
||||
'500':
|
||||
$ref: '#/components/responses/ServiceError'
|
||||
/health:
|
||||
get:
|
||||
summary: Retrieves service health check info.
|
||||
tags:
|
||||
- health
|
||||
responses:
|
||||
'200':
|
||||
$ref: "#/components/responses/HealthRes"
|
||||
'500':
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
components:
|
||||
parameters:
|
||||
Limit:
|
||||
name: limit
|
||||
description: Size of the subset to retrieve.
|
||||
in: query
|
||||
schema:
|
||||
type: integer
|
||||
default: 10
|
||||
maximum: 100
|
||||
minimum: 1
|
||||
required: false
|
||||
Offset:
|
||||
name: offset
|
||||
description: Number of items to skip during retrieval.
|
||||
in: query
|
||||
schema:
|
||||
type: integer
|
||||
default: 0
|
||||
minimum: 0
|
||||
required: false
|
||||
Name:
|
||||
name: name
|
||||
description: Twin name
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
required: false
|
||||
Metadata:
|
||||
name: metadata
|
||||
description: |
|
||||
Metadata filter. Filtering is performed matching the parameter with
|
||||
metadata on top level. Parameter is json.
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
minimum: 0
|
||||
required: false
|
||||
TwinID:
|
||||
name: twinID
|
||||
description: Unique twin identifier.
|
||||
in: path
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
minimum: 1
|
||||
required: true
|
||||
|
||||
schemas:
|
||||
Attribute:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: Name of the attribute.
|
||||
channel:
|
||||
type: string
|
||||
description: Magistrala channel used by attribute.
|
||||
subtopic:
|
||||
type: string
|
||||
description: Subtopic used by attribute.
|
||||
persist_state:
|
||||
type: boolean
|
||||
description: Trigger state creation based on the attribute.
|
||||
Definition:
|
||||
type: object
|
||||
properties:
|
||||
delta:
|
||||
type: number
|
||||
description: Minimal time delay before new state creation.
|
||||
attributes:
|
||||
type: array
|
||||
minItems: 0
|
||||
uniqueItems: true
|
||||
items:
|
||||
$ref: '#/components/schemas/Attribute'
|
||||
TwinReqObj:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: Free-form twin name.
|
||||
metadata:
|
||||
type: object
|
||||
description: Arbitrary, object-encoded twin's data.
|
||||
definition:
|
||||
$ref: '#/components/schemas/Definition'
|
||||
TwinResObj:
|
||||
type: object
|
||||
properties:
|
||||
owner:
|
||||
type: string
|
||||
description: Email address of Magistrala user that owns twin.
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
description: Unique twin identifier generated by the service.
|
||||
name:
|
||||
type: string
|
||||
description: Free-form twin name.
|
||||
revision:
|
||||
type: number
|
||||
description: Oridnal revision number of twin.
|
||||
created:
|
||||
type: string
|
||||
format: date
|
||||
description: Twin creation date and time.
|
||||
updated:
|
||||
type: string
|
||||
format: date
|
||||
description: Twin update date and time.
|
||||
definitions:
|
||||
type: array
|
||||
minItems: 0
|
||||
uniqueItems: true
|
||||
items:
|
||||
$ref: '#/components/schemas/Definition'
|
||||
metadata:
|
||||
type: object
|
||||
description: Arbitrary, object-encoded twin's data.
|
||||
TwinsPage:
|
||||
type: object
|
||||
properties:
|
||||
twins:
|
||||
type: array
|
||||
minItems: 0
|
||||
uniqueItems: true
|
||||
items:
|
||||
$ref: '#/components/schemas/TwinResObj'
|
||||
total:
|
||||
type: integer
|
||||
description: Total number of items.
|
||||
offset:
|
||||
type: integer
|
||||
description: Number of items to skip during retrieval.
|
||||
limit:
|
||||
type: integer
|
||||
description: Maximum number of items to return in one page.
|
||||
required:
|
||||
- twins
|
||||
State:
|
||||
type: object
|
||||
properties:
|
||||
twin_id:
|
||||
type: string
|
||||
format: uuid
|
||||
description: ID of twin state belongs to.
|
||||
id:
|
||||
type: number
|
||||
description: State position in a time row of states.
|
||||
created:
|
||||
type: string
|
||||
format: date
|
||||
description: State creation date.
|
||||
payload:
|
||||
type: object
|
||||
description: Object-encoded states's payload.
|
||||
StatesPage:
|
||||
type: object
|
||||
properties:
|
||||
twins:
|
||||
type: array
|
||||
minItems: 0
|
||||
uniqueItems: true
|
||||
items:
|
||||
$ref: '#/components/schemas/State'
|
||||
total:
|
||||
type: integer
|
||||
description: Total number of items.
|
||||
offset:
|
||||
type: integer
|
||||
description: Number of items to skip during retrieval.
|
||||
limit:
|
||||
type: integer
|
||||
description: Maximum number of items to return in one page.
|
||||
required:
|
||||
- twins
|
||||
|
||||
requestBodies:
|
||||
TwinReq:
|
||||
description: JSON-formatted document describing the twin to create or update.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/TwinReqObj'
|
||||
required: true
|
||||
|
||||
responses:
|
||||
TwinCreateRes:
|
||||
description: Created twin's relative URL (i.e. /twins/{twinID}).
|
||||
headers:
|
||||
Location:
|
||||
content:
|
||||
text/plain:
|
||||
schema:
|
||||
type: string
|
||||
TwinRes:
|
||||
description: Data retrieved.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/TwinResObj'
|
||||
TwinsPageRes:
|
||||
description: Data retrieved.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/TwinsPage'
|
||||
StatesPageRes:
|
||||
description: Data retrieved.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/StatesPage'
|
||||
ServiceError:
|
||||
description: Unexpected server-side error occurred.
|
||||
HealthRes:
|
||||
description: Service Health Check.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "./schemas/HealthInfo.yml"
|
||||
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
description: |
|
||||
* Users access: "Authorization: Bearer <user_token>"
|
||||
|
||||
security:
|
||||
- bearerAuth: []
|
||||
@@ -2,23 +2,23 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
asyncapi: '2.6.0'
|
||||
id: 'https://github.com/absmach/magistrala/blob/master/api/asyncapi/mqtt.yml'
|
||||
id: 'https://github.com/absmach/magistrala/blob/main/api/asyncapi/mqtt.yaml'
|
||||
info:
|
||||
title: Magistrala MQTT Adapter
|
||||
version: '1.0.0'
|
||||
version: '0.18.0'
|
||||
contact:
|
||||
name: Magistrala Team
|
||||
url: 'https://github.com/absmach/magistrala'
|
||||
email: info@mainflux.com
|
||||
email: info@absmach.eu
|
||||
description: |
|
||||
MQTT adapter provides an MQTT API for sending messages through the platform. MQTT adapter uses [mProxy](https://github.com/absmach/mproxy) for proxying traffic between client and MQTT broker.
|
||||
Additionally, the MQTT adapter and the message broker are replicating the traffic between brokers.
|
||||
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: 'https://github.com/absmach/magistrala/blob/master/LICENSE'
|
||||
|
||||
|
||||
url: 'https://github.com/absmach/magistrala/blob/main/LICENSE'
|
||||
|
||||
|
||||
defaultContentType: application/json
|
||||
|
||||
servers:
|
||||
@@ -33,19 +33,23 @@ servers:
|
||||
enum:
|
||||
- '1883'
|
||||
- '8883'
|
||||
security:
|
||||
security:
|
||||
- user-password: []
|
||||
|
||||
channels:
|
||||
channels/{channelID}/messages/{subtopic}:
|
||||
/m/{domainPrefix}/c/{channelPrefix}/{subtopic}:
|
||||
parameters:
|
||||
channelID:
|
||||
$ref: '#/components/parameters/channelID'
|
||||
domainPrefix:
|
||||
$ref: '#/components/parameters/domainPrefix'
|
||||
in: path
|
||||
required: true
|
||||
channelPrefix:
|
||||
$ref: '#/components/parameters/channelPrefix'
|
||||
in: path
|
||||
required: true
|
||||
subtopic:
|
||||
$ref: '#/components/parameters/subtopic'
|
||||
in: path
|
||||
in: path
|
||||
required: false
|
||||
|
||||
publish:
|
||||
@@ -87,23 +91,26 @@ components:
|
||||
```
|
||||
|
||||
parameters:
|
||||
channelID:
|
||||
description: Channel ID connected to the Thing ID defined in the username.
|
||||
domainPrefix:
|
||||
description: ID or route of the domain associated with the channel and client.
|
||||
schema:
|
||||
type: string
|
||||
channelPrefix:
|
||||
description: ID or route of the channel connected to the Client ID defined in the username.
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
subtopic:
|
||||
description: Arbitrary message subtopic.
|
||||
schema:
|
||||
type: string
|
||||
default: ''
|
||||
|
||||
|
||||
securitySchemes:
|
||||
user-password:
|
||||
type: userPassword
|
||||
description: |
|
||||
username is thing ID connected to the channel defined in the mqtt topic and
|
||||
password is thing key corresponding to the thing ID
|
||||
username is client ID connected to the channel defined in the mqtt topic and
|
||||
password is client secret corresponding to the client ID
|
||||
|
||||
operationTraits:
|
||||
mqtt:
|
||||
@@ -2,18 +2,18 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
asyncapi: 2.6.0
|
||||
id: 'https://github.com/absmach/magistrala/blob/master/api/asyncapi/websocket.yml'
|
||||
id: 'https://github.com/absmach/magistrala/blob/main/api/asyncapi/websocket.yaml'
|
||||
info:
|
||||
title: Magistrala WebSocket adapter
|
||||
description: WebSocket adapter provides a WebSocket API for sending messages through communication channels. WebSocket adapter uses [mProxy](https://github.com/absmach/mproxy) for proxying traffic between client and MQTT broker.
|
||||
version: '1.0.0'
|
||||
version: '0.18.0'
|
||||
contact:
|
||||
name: Magistrala Team
|
||||
url: 'https://github.com/absmach/magistrala'
|
||||
email: info@mainflux.com
|
||||
email: info@absmach.eu
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: 'https://github.com/absmach/magistrala/blob/master/LICENSE'
|
||||
url: 'https://github.com/absmach/magistrala/blob/main/LICENSE'
|
||||
tags:
|
||||
- name: WebSocket
|
||||
defaultContentType: application/json
|
||||
@@ -29,13 +29,17 @@ servers:
|
||||
default: localhost
|
||||
port:
|
||||
description: Magistrala WebSocket Adapter port
|
||||
default: '8186'
|
||||
default: '8008'
|
||||
|
||||
channels:
|
||||
'channels/{channelID}/messages/{subtopic}':
|
||||
'm/{domainPrefix}/c/{channelPrefix}/{subtopic}':
|
||||
parameters:
|
||||
channelID:
|
||||
$ref: '#/components/parameters/channelID'
|
||||
domainPrefix:
|
||||
$ref: '#/components/parameters/domainPrefix'
|
||||
in: path
|
||||
required: true
|
||||
channelPrefix:
|
||||
$ref: '#/components/parameters/channelPrefix'
|
||||
in: path
|
||||
required: true
|
||||
subtopic:
|
||||
@@ -125,11 +129,14 @@ components:
|
||||
|
||||
```
|
||||
parameters:
|
||||
channelID:
|
||||
description: Channel ID connected to the Thing ID defined in the username.
|
||||
domainPrefix:
|
||||
description: ID or route of the domain associated with the channel and client.
|
||||
schema:
|
||||
type: string
|
||||
channelPrefix:
|
||||
description: ID or route of the channel connected to the Client ID defined in the username.
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
subtopic:
|
||||
description: Arbitrary message subtopic.
|
||||
schema:
|
||||
@@ -141,4 +148,4 @@ components:
|
||||
scheme: bearer
|
||||
bearerFormat: uuid
|
||||
description: |
|
||||
* Thing access: "Authorization: Thing <thing_key>"
|
||||
* Client access: "Authorization: Client <client_key>"
|
||||
@@ -0,0 +1,5 @@
|
||||
# Magistrala OpenAPI Specification
|
||||
|
||||
This folder contains an OpenAPI specifications for Magistrala API.
|
||||
|
||||
View specification in Swagger UI at [docs.api.magistrala.absmach.eu](https://docs.api.magistrala.absmach.eu)
|
||||
@@ -0,0 +1,508 @@
|
||||
# Copyright (c) Abstract Machines
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
openapi: 3.0.1
|
||||
info:
|
||||
title: Magistrala Alarms API
|
||||
description: |
|
||||
HTTP API for managing alarms service.
|
||||
Some useful links:
|
||||
- [The Magistrala repository](https://github.com/absmach/magistrala)
|
||||
contact:
|
||||
email: info@absmach.eu
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: https://github.com/absmach/magistrala/blob/main/LICENSE
|
||||
version: 0.18.5
|
||||
|
||||
servers:
|
||||
- url: http://localhost:8050
|
||||
- url: https://localhost:8050
|
||||
|
||||
tags:
|
||||
- name: alarms
|
||||
description: Everything about your Alarms
|
||||
externalDocs:
|
||||
description: Find out more about alarms
|
||||
url: https://magistrala.absmach.eu/docs/
|
||||
|
||||
paths:
|
||||
/{domainID}/alarms:
|
||||
get:
|
||||
operationId: listAlarms
|
||||
summary: List Alarms
|
||||
description: |
|
||||
Retrieves a list of alarms with optional filtering
|
||||
tags:
|
||||
- alarms
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/DomainID'
|
||||
- $ref: '#/components/parameters/Offset'
|
||||
- $ref: '#/components/parameters/Limit'
|
||||
- $ref: '#/components/parameters/Order'
|
||||
- $ref: '#/components/parameters/Dir'
|
||||
- $ref: '#/components/parameters/ChannelID'
|
||||
- $ref: '#/components/parameters/ClientID'
|
||||
- $ref: '#/components/parameters/Subtopic'
|
||||
- $ref: '#/components/parameters/RuleID'
|
||||
- $ref: '#/components/parameters/Status'
|
||||
- $ref: '#/components/parameters/AssigneeID'
|
||||
- $ref: '#/components/parameters/Severity'
|
||||
- $ref: '#/components/parameters/UpdatedBy'
|
||||
- $ref: '#/components/parameters/AssignedBy'
|
||||
- $ref: '#/components/parameters/AcknowledgedBy'
|
||||
- $ref: '#/components/parameters/ResolvedBy'
|
||||
- $ref: '#/components/parameters/CreatedFrom'
|
||||
- $ref: '#/components/parameters/CreatedTo'
|
||||
security:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
'200':
|
||||
$ref: '#/components/responses/AlarmsPageRes'
|
||||
'400':
|
||||
description: Failed due to malformed query parameters
|
||||
'401':
|
||||
description: Missing or invalid access token
|
||||
'422':
|
||||
description: Database can't process request
|
||||
'500':
|
||||
$ref: '#/components/responses/ServiceError'
|
||||
|
||||
/{domainID}/alarms/{alarmID}:
|
||||
get:
|
||||
operationId: viewAlarm
|
||||
summary: View Alarm
|
||||
description: Retrieves an alarm by ID
|
||||
tags:
|
||||
- alarms
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/DomainID'
|
||||
- $ref: '#/components/parameters/AlarmID'
|
||||
security:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
'200':
|
||||
$ref: '#/components/responses/AlarmRes'
|
||||
'400':
|
||||
description: Missing or invalid alarm ID
|
||||
'401':
|
||||
description: Missing or invalid access token
|
||||
'403':
|
||||
description: Failed to perform authorization over the entity
|
||||
'404':
|
||||
description: Alarm does not exist
|
||||
'422':
|
||||
description: Database can't process request
|
||||
'500':
|
||||
$ref: '#/components/responses/ServiceError'
|
||||
put:
|
||||
operationId: updateAlarm
|
||||
summary: Update Alarm
|
||||
description: Updates an existing alarm
|
||||
tags:
|
||||
- alarms
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/DomainID'
|
||||
- $ref: '#/components/parameters/AlarmID'
|
||||
security:
|
||||
- bearerAuth: []
|
||||
requestBody:
|
||||
$ref: '#/components/requestBodies/AlarmUpdateReq'
|
||||
responses:
|
||||
'200':
|
||||
$ref: '#/components/responses/AlarmRes'
|
||||
'400':
|
||||
description: Failed due to malformed JSON
|
||||
'401':
|
||||
description: Missing or invalid access token
|
||||
'403':
|
||||
description: Failed to perform authorization over the entity
|
||||
'404':
|
||||
description: Alarm does not exist
|
||||
'415':
|
||||
description: Missing or invalid content type
|
||||
'422':
|
||||
description: Database can't process request
|
||||
'500':
|
||||
$ref: '#/components/responses/ServiceError'
|
||||
delete:
|
||||
operationId: deleteAlarm
|
||||
summary: Delete Alarm
|
||||
description: Deletes an alarm
|
||||
tags:
|
||||
- alarms
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/DomainID'
|
||||
- $ref: '#/components/parameters/AlarmID'
|
||||
security:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
'204':
|
||||
description: Alarm deleted successfully
|
||||
'400':
|
||||
description: Failed due to malformed alarm ID
|
||||
'401':
|
||||
description: Missing or invalid access token
|
||||
'403':
|
||||
description: Failed to perform authorization over the entity
|
||||
'404':
|
||||
description: Alarm does not exist
|
||||
'422':
|
||||
description: Database can't process request
|
||||
'500':
|
||||
$ref: '#/components/responses/ServiceError'
|
||||
|
||||
/health:
|
||||
get:
|
||||
summary: Retrieves service health check info
|
||||
tags:
|
||||
- health
|
||||
security: []
|
||||
responses:
|
||||
'200':
|
||||
$ref: '#/components/responses/HealthRes'
|
||||
'500':
|
||||
$ref: '#/components/responses/ServiceError'
|
||||
|
||||
components:
|
||||
schemas:
|
||||
Alarm:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
description: Unique alarm identifier
|
||||
readOnly: true
|
||||
rule_id:
|
||||
type: string
|
||||
description: Rule ID that triggered this alarm
|
||||
domain_id:
|
||||
type: string
|
||||
description: Domain ID this alarm belongs to
|
||||
channel_id:
|
||||
type: string
|
||||
description: Channel ID where the alarm was triggered
|
||||
client_id:
|
||||
type: string
|
||||
description: Client ID that triggered the alarm
|
||||
subtopic:
|
||||
type: string
|
||||
description: Subtopic associated with the alarm
|
||||
status:
|
||||
type: string
|
||||
description: Alarm status
|
||||
enum: [active, cleared]
|
||||
measurement:
|
||||
type: string
|
||||
description: Measurement that triggered the alarm
|
||||
value:
|
||||
type: string
|
||||
description: Value that triggered the alarm
|
||||
unit:
|
||||
type: string
|
||||
description: Unit of measurement
|
||||
threshold:
|
||||
type: string
|
||||
description: Threshold value that was exceeded
|
||||
cause:
|
||||
type: string
|
||||
description: Cause or description of the alarm
|
||||
severity:
|
||||
type: integer
|
||||
description: Severity level (0-100)
|
||||
minimum: 0
|
||||
maximum: 100
|
||||
assignee_id:
|
||||
type: string
|
||||
description: ID of the user assigned to this alarm
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
description: Creation timestamp
|
||||
readOnly: true
|
||||
updated_at:
|
||||
type: string
|
||||
format: date-time
|
||||
description: Last update timestamp
|
||||
readOnly: true
|
||||
updated_by:
|
||||
type: string
|
||||
description: User who last updated the alarm
|
||||
readOnly: true
|
||||
assigned_at:
|
||||
type: string
|
||||
format: date-time
|
||||
description: When the alarm was assigned
|
||||
readOnly: true
|
||||
assigned_by:
|
||||
type: string
|
||||
description: User who assigned the alarm
|
||||
readOnly: true
|
||||
acknowledged_at:
|
||||
type: string
|
||||
format: date-time
|
||||
description: When the alarm was acknowledged
|
||||
readOnly: true
|
||||
acknowledged_by:
|
||||
type: string
|
||||
description: User who acknowledged the alarm
|
||||
readOnly: true
|
||||
resolved_at:
|
||||
type: string
|
||||
format: date-time
|
||||
description: When the alarm was resolved
|
||||
readOnly: true
|
||||
resolved_by:
|
||||
type: string
|
||||
description: User who resolved the alarm
|
||||
readOnly: true
|
||||
metadata:
|
||||
type: object
|
||||
description: Custom metadata
|
||||
additionalProperties: true
|
||||
|
||||
AlarmsPage:
|
||||
type: object
|
||||
properties:
|
||||
offset:
|
||||
type: integer
|
||||
description: Number of items to skip during retrieval
|
||||
minimum: 0
|
||||
default: 0
|
||||
limit:
|
||||
type: integer
|
||||
description: Size of the subset to retrieve
|
||||
minimum: 1
|
||||
maximum: 1000
|
||||
default: 10
|
||||
total:
|
||||
type: integer
|
||||
description: Total number of results
|
||||
minimum: 0
|
||||
alarms:
|
||||
type: array
|
||||
minItems: 0
|
||||
items:
|
||||
$ref: '#/components/schemas/Alarm'
|
||||
required:
|
||||
- alarms
|
||||
- total
|
||||
- offset
|
||||
- limit
|
||||
|
||||
parameters:
|
||||
DomainID:
|
||||
name: domainID
|
||||
description: Domain ID
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
AlarmID:
|
||||
name: alarmID
|
||||
description: Alarm ID
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
Offset:
|
||||
name: offset
|
||||
description: Number of items to skip
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
default: 0
|
||||
minimum: 0
|
||||
Limit:
|
||||
name: limit
|
||||
description: Size of the subset to retrieve
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
default: 10
|
||||
minimum: 1
|
||||
maximum: 1000
|
||||
Order:
|
||||
name: order
|
||||
description: Order by field
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
enum: [created_at, updated_at]
|
||||
default: created_at
|
||||
Dir:
|
||||
name: dir
|
||||
description: Sort direction
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
enum: [asc, desc]
|
||||
default: desc
|
||||
ChannelID:
|
||||
name: channel_id
|
||||
description: Filter by channel ID
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
ClientID:
|
||||
name: client_id
|
||||
description: Filter by client ID
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
Subtopic:
|
||||
name: subtopic
|
||||
description: Filter by subtopic
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
RuleID:
|
||||
name: rule_id
|
||||
description: Filter by rule ID
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
Status:
|
||||
name: status
|
||||
description: Filter by alarm status
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
enum: [active, cleared, all]
|
||||
default: all
|
||||
AssigneeID:
|
||||
name: assignee_id
|
||||
description: Filter by assignee ID
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
Severity:
|
||||
name: severity
|
||||
description: Filter by severity level
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
minimum: 0
|
||||
maximum: 100
|
||||
UpdatedBy:
|
||||
name: updated_by
|
||||
description: Filter by user who updated
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
AssignedBy:
|
||||
name: assigned_by
|
||||
description: Filter by user who assigned
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
AcknowledgedBy:
|
||||
name: acknowledged_by
|
||||
description: Filter by user who acknowledged
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
ResolvedBy:
|
||||
name: resolved_by
|
||||
description: Filter by user who resolved
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
CreatedFrom:
|
||||
name: created_from
|
||||
description: Filter alarms created after this time (RFC3339 format)
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
format: date-time
|
||||
CreatedTo:
|
||||
name: created_to
|
||||
description: Filter alarms created before this time (RFC3339 format)
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
format: date-time
|
||||
|
||||
requestBodies:
|
||||
AlarmUpdateReq:
|
||||
description: JSON-formatted document describing the alarm update
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
status:
|
||||
type: string
|
||||
description: Alarm status
|
||||
enum: [active, cleared]
|
||||
assignee_id:
|
||||
type: string
|
||||
description: ID of the user assigned to this alarm
|
||||
severity:
|
||||
type: integer
|
||||
description: Severity level (0-100)
|
||||
minimum: 0
|
||||
maximum: 100
|
||||
metadata:
|
||||
type: object
|
||||
description: Custom metadata
|
||||
additionalProperties: true
|
||||
|
||||
responses:
|
||||
AlarmRes:
|
||||
description: Alarm data retrieved
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Alarm'
|
||||
links:
|
||||
update:
|
||||
operationId: updateAlarm
|
||||
parameters:
|
||||
alarmID: $response.body#/id
|
||||
domainID: $response.body#/domain_id
|
||||
delete:
|
||||
operationId: deleteAlarm
|
||||
parameters:
|
||||
alarmID: $response.body#/id
|
||||
domainID: $response.body#/domain_id
|
||||
AlarmsPageRes:
|
||||
description: Alarms page retrieved
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/AlarmsPage'
|
||||
ServiceError:
|
||||
description: Unexpected server-side error occurred
|
||||
HealthRes:
|
||||
description: Service Health Check
|
||||
content:
|
||||
application/health+json:
|
||||
schema:
|
||||
$ref: "./schemas/health_info.yaml"
|
||||
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
description: |
|
||||
* Users access: "Authorization: Bearer <user_token>"
|
||||
@@ -0,0 +1,851 @@
|
||||
# Copyright (c) Abstract Machines
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: Magistrala Auth Service
|
||||
description: |
|
||||
This is the Auth Server based on the OpenAPI 3.0 specification. It is the HTTP API for managing platform users. You can now help us improve the API whether it's by making changes to the definition itself or to the code.
|
||||
Some useful links:
|
||||
- [The Magistrala repository](https://github.com/absmach/magistrala)
|
||||
contact:
|
||||
email: info@absmach.eu
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: https://github.com/absmach/magistrala/blob/main/LICENSE
|
||||
version: 0.18.0
|
||||
|
||||
servers:
|
||||
- url: http://localhost:9001
|
||||
- url: https://localhost:9001
|
||||
|
||||
tags:
|
||||
- name: Keys
|
||||
description: Everything about your Keys.
|
||||
externalDocs:
|
||||
description: Find out more about keys
|
||||
url: https://magistrala.absmach.eu/docs/
|
||||
- name: PATs
|
||||
description: Everything about your Personal Access Tokens.
|
||||
externalDocs:
|
||||
description: Find out more about Personal Access Tokens
|
||||
url: https://magistrala.absmach.eu/docs/
|
||||
- name: Health
|
||||
description: Service health check endpoint.
|
||||
externalDocs:
|
||||
description: Find out more about health check
|
||||
url: https://magistrala.absmach.eu/docs/
|
||||
|
||||
paths:
|
||||
/keys:
|
||||
post:
|
||||
operationId: issueKey
|
||||
tags:
|
||||
- Keys
|
||||
summary: Issue API key
|
||||
description: |
|
||||
Generates a new API key. Thew new API key will
|
||||
be uniquely identified by its ID.
|
||||
requestBody:
|
||||
$ref: "#/components/requestBodies/KeyRequest"
|
||||
responses:
|
||||
"201":
|
||||
description: Issued new key.
|
||||
"400":
|
||||
description: Failed due to malformed JSON.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"409":
|
||||
description: Failed due to using already existing ID.
|
||||
"415":
|
||||
description: Missing or invalid content type.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
/keys/{keyID}:
|
||||
get:
|
||||
operationId: getKey
|
||||
summary: Gets API key details.
|
||||
description: |
|
||||
Gets API key details for the given key.
|
||||
tags:
|
||||
- Keys
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/ApiKeyId"
|
||||
responses:
|
||||
"200":
|
||||
$ref: "#/components/responses/KeyRes"
|
||||
"400":
|
||||
description: Failed due to malformed query parameters.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"404":
|
||||
description: A non-existent entity request.
|
||||
"422":
|
||||
description: Service can't process request.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
delete:
|
||||
operationId: revokeKey
|
||||
summary: Revoke API key
|
||||
description: |
|
||||
Revoke API key identified by the given ID.
|
||||
tags:
|
||||
- Keys
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/ApiKeyId"
|
||||
responses:
|
||||
"204":
|
||||
description: Key revoked.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"404":
|
||||
description: A non-existent entity request.
|
||||
"422":
|
||||
description: Service can't process request.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
/pats:
|
||||
post:
|
||||
operationId: createPAT
|
||||
tags:
|
||||
- PATs
|
||||
summary: Create a new Personal Access Token
|
||||
description: |
|
||||
Creates a new Personal Access Token (PAT) for the authenticated user.
|
||||
requestBody:
|
||||
$ref: "#/components/requestBodies/CreatePATRequest"
|
||||
responses:
|
||||
"201":
|
||||
$ref: "#/components/responses/PATRes"
|
||||
"400":
|
||||
description: Failed due to malformed JSON or validation errors.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"415":
|
||||
description: Missing or invalid content type.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
get:
|
||||
operationId: listPATs
|
||||
tags:
|
||||
- PATs
|
||||
summary: List all Personal Access Tokens
|
||||
description: |
|
||||
Lists all Personal Access Tokens (PATs) for the authenticated user.
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/Limit"
|
||||
- $ref: "#/components/parameters/Offset"
|
||||
responses:
|
||||
"200":
|
||||
$ref: "#/components/responses/PATsPageRes"
|
||||
"400":
|
||||
description: Failed due to malformed query parameters.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
delete:
|
||||
operationId: clearAllPATs
|
||||
tags:
|
||||
- PATs
|
||||
summary: Remove all Personal Access Tokens
|
||||
description: |
|
||||
Removes all Personal Access Tokens (PATs) for the authenticated user.
|
||||
responses:
|
||||
"200":
|
||||
description: All PATs removed successfully.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
/pats/{patID}:
|
||||
get:
|
||||
operationId: retrievePAT
|
||||
tags:
|
||||
- PATs
|
||||
summary: Retrieve a Personal Access Token
|
||||
description: |
|
||||
Retrieves details of a specific Personal Access Token (PAT).
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/PatID"
|
||||
responses:
|
||||
"200":
|
||||
$ref: "#/components/responses/PATRes"
|
||||
"400":
|
||||
description: Failed due to malformed query parameters.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"404":
|
||||
description: PAT not found.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
delete:
|
||||
operationId: deletePAT
|
||||
tags:
|
||||
- PATs
|
||||
summary: Delete a Personal Access Token
|
||||
description: |
|
||||
Deletes a specific Personal Access Token (PAT).
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/PatID"
|
||||
responses:
|
||||
"204":
|
||||
description: PAT deleted successfully.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"404":
|
||||
description: PAT not found.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
/pats/{patID}/name:
|
||||
patch:
|
||||
operationId: updatePATName
|
||||
tags:
|
||||
- PATs
|
||||
summary: Update Personal Access Token name
|
||||
description: |
|
||||
Updates the name of a specific Personal Access Token (PAT).
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/PatID"
|
||||
requestBody:
|
||||
$ref: "#/components/requestBodies/UpdatePATNameRequest"
|
||||
responses:
|
||||
"202":
|
||||
$ref: "#/components/responses/PATRes"
|
||||
"400":
|
||||
description: Failed due to malformed JSON or validation errors.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"404":
|
||||
description: PAT not found.
|
||||
"415":
|
||||
description: Missing or invalid content type.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
/pats/{patID}/description:
|
||||
patch:
|
||||
operationId: updatePATDescription
|
||||
tags:
|
||||
- PATs
|
||||
summary: Update Personal Access Token description
|
||||
description: |
|
||||
Updates the description of a specific Personal Access Token (PAT).
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/PatID"
|
||||
requestBody:
|
||||
$ref: "#/components/requestBodies/UpdatePATDescriptionRequest"
|
||||
responses:
|
||||
"202":
|
||||
$ref: "#/components/responses/PATRes"
|
||||
"400":
|
||||
description: Failed due to malformed JSON or validation errors.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"404":
|
||||
description: PAT not found.
|
||||
"415":
|
||||
description: Missing or invalid content type.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
/pats/{patID}/secret/reset:
|
||||
patch:
|
||||
operationId: resetPATSecret
|
||||
tags:
|
||||
- PATs
|
||||
summary: Reset Personal Access Token secret
|
||||
description: |
|
||||
Resets the secret of a specific Personal Access Token (PAT).
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/PatID"
|
||||
requestBody:
|
||||
$ref: "#/components/requestBodies/ResetPATSecretRequest"
|
||||
responses:
|
||||
"200":
|
||||
$ref: "#/components/responses/PATRes"
|
||||
"400":
|
||||
description: Failed due to malformed JSON or validation errors.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"404":
|
||||
description: PAT not found.
|
||||
"415":
|
||||
description: Missing or invalid content type.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
/pats/{patID}/secret/revoke:
|
||||
patch:
|
||||
operationId: revokePATSecret
|
||||
tags:
|
||||
- PATs
|
||||
summary: Revoke Personal Access Token secret
|
||||
description: |
|
||||
Revokes the secret of a specific Personal Access Token (PAT).
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/PatID"
|
||||
responses:
|
||||
"204":
|
||||
description: PAT secret revoked successfully.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"404":
|
||||
description: PAT not found.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
/pats/{patID}/scope:
|
||||
get:
|
||||
operationId: listScopes
|
||||
tags:
|
||||
- PATs
|
||||
summary: List scopes for a Personal Access Token
|
||||
description: |
|
||||
Lists all scopes for a specific Personal Access Token (PAT).
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/PatID"
|
||||
- $ref: "#/components/parameters/Limit"
|
||||
- $ref: "#/components/parameters/Offset"
|
||||
responses:
|
||||
"200":
|
||||
$ref: "#/components/responses/ScopesPageRes"
|
||||
"400":
|
||||
description: Failed due to malformed query parameters.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"404":
|
||||
description: PAT not found.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
delete:
|
||||
operationId: clearAllScopes
|
||||
tags:
|
||||
- PATs
|
||||
summary: Remove all scopes from a Personal Access Token
|
||||
description: |
|
||||
Removes all scopes from a specific Personal Access Token (PAT).
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/PatID"
|
||||
responses:
|
||||
"200":
|
||||
description: All scopes removed successfully.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"404":
|
||||
description: PAT not found.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
/pats/{patID}/scope/add:
|
||||
patch:
|
||||
operationId: addScope
|
||||
tags:
|
||||
- PATs
|
||||
summary: Add scope to a Personal Access Token
|
||||
description: |
|
||||
Adds a scope to a specific Personal Access Token (PAT).
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/PatID"
|
||||
requestBody:
|
||||
$ref: "#/components/requestBodies/AddScopeRequest"
|
||||
responses:
|
||||
"200":
|
||||
description: Scope added successfully.
|
||||
"400":
|
||||
description: Failed due to malformed JSON or validation errors.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"404":
|
||||
description: PAT not found.
|
||||
"415":
|
||||
description: Missing or invalid content type.
|
||||
"422":
|
||||
description: Database cannot process the request.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
/pats/{patID}/scope/remove:
|
||||
patch:
|
||||
operationId: removeScope
|
||||
tags:
|
||||
- PATs
|
||||
summary: Remove scope from a Personal Access Token
|
||||
description: |
|
||||
Removes a scope from a specific Personal Access Token (PAT).
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/PatID"
|
||||
requestBody:
|
||||
$ref: "#/components/requestBodies/RemoveScopeRequest"
|
||||
responses:
|
||||
"200":
|
||||
description: Scope removed successfully.
|
||||
"400":
|
||||
description: Failed due to malformed JSON or validation errors.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"404":
|
||||
description: PAT not found.
|
||||
"415":
|
||||
description: Missing or invalid content type.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
/health:
|
||||
get:
|
||||
summary: Retrieves service health check info.
|
||||
tags:
|
||||
- Health
|
||||
security: []
|
||||
responses:
|
||||
"200":
|
||||
$ref: "#/components/responses/HealthRes"
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
components:
|
||||
schemas:
|
||||
PAT:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
example: "c5747f2f-2a7c-4fe1-b41a-51a5ae290945"
|
||||
description: Personal Access Token unique identifier
|
||||
user_id:
|
||||
type: string
|
||||
format: uuid
|
||||
example: "9118de62-c680-46b7-ad0a-21748a52833a"
|
||||
description: User ID of the PAT owner
|
||||
name:
|
||||
type: string
|
||||
example: "My PAT"
|
||||
description: Name of the Personal Access Token
|
||||
description:
|
||||
type: string
|
||||
example: "Token for automation"
|
||||
description: Description of the Personal Access Token
|
||||
secret:
|
||||
type: string
|
||||
example: "pat_1234567890abcdef"
|
||||
description: Secret value of the Personal Access Token
|
||||
issued_at:
|
||||
type: string
|
||||
format: date-time
|
||||
example: "2019-11-26T13:31:52Z"
|
||||
description: Time when the PAT was issued
|
||||
expires_at:
|
||||
type: string
|
||||
format: date-time
|
||||
example: "2020-11-26T13:31:52Z"
|
||||
description: Time when the PAT expires
|
||||
updated_at:
|
||||
type: string
|
||||
format: date-time
|
||||
example: "2019-11-26T13:31:52Z"
|
||||
description: Time when the PAT was last updated
|
||||
last_used_at:
|
||||
type: string
|
||||
format: date-time
|
||||
example: "2019-11-26T13:31:52Z"
|
||||
description: Time when the PAT was last used
|
||||
revoked:
|
||||
type: boolean
|
||||
example: false
|
||||
description: Whether the PAT is revoked
|
||||
revoked_at:
|
||||
type: string
|
||||
format: date-time
|
||||
example: "2019-11-26T13:31:52Z"
|
||||
description: Time when the PAT was revoked
|
||||
|
||||
PATsPage:
|
||||
type: object
|
||||
properties:
|
||||
total:
|
||||
type: integer
|
||||
example: 10
|
||||
description: Total number of PATs
|
||||
offset:
|
||||
type: integer
|
||||
example: 0
|
||||
description: Number of items to skip during retrieval
|
||||
limit:
|
||||
type: integer
|
||||
example: 10
|
||||
description: Size of the subset to retrieve
|
||||
pats:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/PAT"
|
||||
description: List of Personal Access Tokens
|
||||
|
||||
Scope:
|
||||
type: object
|
||||
properties:
|
||||
optional_domain_id:
|
||||
type: string
|
||||
format: uuid
|
||||
example: "bb7edb32-2eac-4aad-aebe-ed96fe073879"
|
||||
description: Optional domain ID for the scope
|
||||
entity_type:
|
||||
type: string
|
||||
enum:
|
||||
[groups, channels, clients, domains, users, dashboards, messages]
|
||||
example: "groups"
|
||||
description: Type of entity the scope applies to
|
||||
entity_id:
|
||||
type: string
|
||||
example: "*"
|
||||
description: ID of the entity the scope applies to. '*' means all entities of the specified type.
|
||||
operation:
|
||||
type: string
|
||||
enum:
|
||||
[
|
||||
create,
|
||||
read,
|
||||
list,
|
||||
update,
|
||||
delete,
|
||||
share,
|
||||
unshare,
|
||||
publish,
|
||||
subscribe,
|
||||
]
|
||||
example: "read"
|
||||
description: Operation allowed by this scope
|
||||
|
||||
ScopesPage:
|
||||
type: object
|
||||
properties:
|
||||
total:
|
||||
type: integer
|
||||
example: 10
|
||||
description: Total number of scopes
|
||||
offset:
|
||||
type: integer
|
||||
example: 0
|
||||
description: Number of items to skip during retrieval
|
||||
limit:
|
||||
type: integer
|
||||
example: 10
|
||||
description: Size of the subset to retrieve
|
||||
scopes:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/Scope"
|
||||
description: List of scopes
|
||||
Key:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
example: "c5747f2f-2a7c-4fe1-b41a-51a5ae290945"
|
||||
description: API key unique identifier
|
||||
issuer_id:
|
||||
type: string
|
||||
format: uuid
|
||||
example: "9118de62-c680-46b7-ad0a-21748a52833a"
|
||||
description: In ID of the entity that issued the token.
|
||||
type:
|
||||
type: integer
|
||||
example: 0
|
||||
description: API key type. Keys of different type are processed differently.
|
||||
subject:
|
||||
type: string
|
||||
format: string
|
||||
example: "test@example.com"
|
||||
description: User's email or service identifier of API key subject.
|
||||
issued_at:
|
||||
type: string
|
||||
format: date-time
|
||||
example: "2019-11-26 13:31:52"
|
||||
description: Time when the key is generated.
|
||||
expires_at:
|
||||
type: string
|
||||
format: date-time
|
||||
example: "2019-11-26 13:31:52"
|
||||
description: Time when the Key expires. If this field is missing,
|
||||
that means that Key is valid indefinitely.
|
||||
|
||||
parameters:
|
||||
PatID:
|
||||
name: patID
|
||||
description: Personal Access Token ID.
|
||||
in: path
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
required: true
|
||||
DomainID:
|
||||
name: domainID
|
||||
description: Unique domain identifier.
|
||||
in: path
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
required: true
|
||||
example: bb7edb32-2eac-4aad-aebe-ed96fe073879
|
||||
Status:
|
||||
name: status
|
||||
description: Domain status.
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
default: enabled
|
||||
required: false
|
||||
example: enabled
|
||||
DomainName:
|
||||
name: name
|
||||
description: Domain's name.
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
required: false
|
||||
example: "domainName"
|
||||
Permission:
|
||||
name: permission
|
||||
description: permission.
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
required: false
|
||||
example: "edit"
|
||||
ApiKeyId:
|
||||
name: keyID
|
||||
description: API Key ID.
|
||||
in: path
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
required: true
|
||||
Limit:
|
||||
name: limit
|
||||
description: Size of the subset to retrieve.
|
||||
in: query
|
||||
schema:
|
||||
type: integer
|
||||
default: 10
|
||||
maximum: 100
|
||||
minimum: 1
|
||||
required: false
|
||||
Offset:
|
||||
name: offset
|
||||
description: Number of items to skip during retrieval.
|
||||
in: query
|
||||
schema:
|
||||
type: integer
|
||||
default: 0
|
||||
minimum: 0
|
||||
required: false
|
||||
Metadata:
|
||||
name: metadata
|
||||
description: Metadata filter. Filtering is performed matching the parameter with metadata on top level. Parameter is json.
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
type: object
|
||||
additionalProperties: {}
|
||||
Type:
|
||||
name: type
|
||||
description: The type of the API Key.
|
||||
in: query
|
||||
schema:
|
||||
type: integer
|
||||
default: 0
|
||||
minimum: 0
|
||||
required: false
|
||||
Subject:
|
||||
name: subject
|
||||
description: The subject of an API Key
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
required: false
|
||||
|
||||
requestBodies:
|
||||
CreatePATRequest:
|
||||
description: JSON-formatted document describing PAT creation request.
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
- duration
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
minLength: 1
|
||||
example: "My PAT"
|
||||
description: Name of the Personal Access Token
|
||||
description:
|
||||
type: string
|
||||
example: "Token for automation"
|
||||
description: Description of the Personal Access Token
|
||||
duration:
|
||||
type: string
|
||||
pattern: "^[0-9]+(ns|us|µs|ms|s|m|h|d|w|y)$"
|
||||
example: "30d"
|
||||
description: Duration for which the PAT is valid. Format is a duration string (e.g. "30d", "24h", "1y").
|
||||
|
||||
UpdatePATNameRequest:
|
||||
description: JSON-formatted document describing PAT name update request.
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
example: "New PAT Name"
|
||||
description: New name for the Personal Access Token
|
||||
|
||||
UpdatePATDescriptionRequest:
|
||||
description: JSON-formatted document describing PAT description update request.
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required:
|
||||
- description
|
||||
properties:
|
||||
description:
|
||||
type: string
|
||||
example: "New PAT Description"
|
||||
description: New description for the Personal Access Token
|
||||
|
||||
ResetPATSecretRequest:
|
||||
description: JSON-formatted document describing PAT secret reset request.
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required:
|
||||
- duration
|
||||
properties:
|
||||
duration:
|
||||
type: string
|
||||
pattern: "^[0-9]+(ns|us|µs|ms|s|m|h|d|w|y)$"
|
||||
example: "30d"
|
||||
description: Duration for which the new PAT secret is valid. Format is a duration string (e.g. "30d", "24h", "1y").
|
||||
|
||||
AddScopeRequest:
|
||||
description: JSON-formatted document describing add scope request.
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required:
|
||||
- scopes
|
||||
properties:
|
||||
scopes:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/Scope"
|
||||
description: List of scopes to add
|
||||
|
||||
RemoveScopeRequest:
|
||||
description: JSON-formatted document describing remove scope request.
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required:
|
||||
- scopes_id
|
||||
properties:
|
||||
scopes_id:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
format: uuid
|
||||
description: List of scope IDs to remove
|
||||
KeyRequest:
|
||||
description: JSON-formatted document describing key request.
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
type:
|
||||
type: integer
|
||||
example: 0
|
||||
description: API key type. Keys of different type are processed differently.
|
||||
duration:
|
||||
type: number
|
||||
format: integer
|
||||
example: 23456
|
||||
description: Number of seconds issued token is valid for.
|
||||
|
||||
responses:
|
||||
PATRes:
|
||||
description: Personal Access Token data.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/PAT"
|
||||
|
||||
PATsPageRes:
|
||||
description: Page of Personal Access Tokens.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/PATsPage"
|
||||
|
||||
ScopesPageRes:
|
||||
description: Page of scopes.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ScopesPage"
|
||||
ServiceError:
|
||||
description: Unexpected server-side error occurred.
|
||||
KeyRes:
|
||||
description: Data retrieved.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Key"
|
||||
links:
|
||||
revoke:
|
||||
operationId: revokeKey
|
||||
parameters:
|
||||
keyID: $response.body#/id
|
||||
|
||||
HealthRes:
|
||||
description: Service Health Check.
|
||||
content:
|
||||
application/health+json:
|
||||
schema:
|
||||
$ref: "./schemas/health_info.yaml"
|
||||
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
description: |
|
||||
* Users access: "Authorization: Bearer <user_token>"
|
||||
|
||||
security:
|
||||
- bearerAuth: []
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,722 @@
|
||||
# Copyright (c) Abstract Machines
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: Certs Service API
|
||||
description: |
|
||||
Certificate management service for issuing, renewing, revoking, and managing X.509 certificates.
|
||||
This service provides PKI functionality including certificate lifecycle management, OCSP responder,
|
||||
and CRL generation.
|
||||
version: 1.0.0
|
||||
contact:
|
||||
name: Abstract Machines
|
||||
license:
|
||||
name: Apache-2.0
|
||||
url: https://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
servers:
|
||||
- url: http://localhost:9019
|
||||
description: Development server
|
||||
|
||||
tags:
|
||||
- name: certificates
|
||||
description: Certificate lifecycle management operations
|
||||
- name: pki
|
||||
description: PKI infrastructure operations (OCSP, CRL, CA)
|
||||
- name: health
|
||||
description: Service health and monitoring
|
||||
|
||||
security:
|
||||
- BearerAuth: []
|
||||
|
||||
paths:
|
||||
/{domainID}/certs/issue/{entityID}:
|
||||
post:
|
||||
tags:
|
||||
- certificates
|
||||
summary: Issue a new certificate
|
||||
description: Issues a new X.509 certificate for the specified entity with custom subject options
|
||||
operationId: issueCert
|
||||
security:
|
||||
- BearerAuth: []
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/DomainID'
|
||||
- $ref: '#/components/parameters/EntityID'
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/IssueCertRequest'
|
||||
responses:
|
||||
'201':
|
||||
description: Certificate successfully issued
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/CertificateResponse'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
|
||||
/{domainID}/certs/{id}/renew:
|
||||
patch:
|
||||
tags:
|
||||
- certificates
|
||||
summary: Renew a certificate
|
||||
description: Renews an existing certificate with extended TTL and new serial number
|
||||
operationId: renewCert
|
||||
security:
|
||||
- BearerAuth: []
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/DomainID'
|
||||
- $ref: '#/components/parameters/CertID'
|
||||
responses:
|
||||
'200':
|
||||
description: Certificate successfully renewed
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenewCertResponse'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
|
||||
/{domainID}/certs/{id}/revoke:
|
||||
patch:
|
||||
tags:
|
||||
- certificates
|
||||
summary: Revoke a certificate
|
||||
description: Revokes a certificate by its serial number
|
||||
operationId: revokeCert
|
||||
security:
|
||||
- BearerAuth: []
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/DomainID'
|
||||
- $ref: '#/components/parameters/CertID'
|
||||
responses:
|
||||
'204':
|
||||
description: Certificate successfully revoked
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
'422':
|
||||
$ref: '#/components/responses/UnprocessableEntity'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
|
||||
/{domainID}/certs/{entityID}/delete:
|
||||
delete:
|
||||
tags:
|
||||
- certificates
|
||||
summary: Delete certificates for an entity
|
||||
description: Deletes all certificates associated with the specified entity
|
||||
operationId: deleteCert
|
||||
security:
|
||||
- BearerAuth: []
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/DomainID'
|
||||
- $ref: '#/components/parameters/EntityID'
|
||||
responses:
|
||||
'204':
|
||||
description: Certificates successfully deleted
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'422':
|
||||
$ref: '#/components/responses/UnprocessableEntity'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
|
||||
/{domainID}/certs:
|
||||
get:
|
||||
tags:
|
||||
- certificates
|
||||
summary: List certificates
|
||||
description: Retrieves a paginated list of certificates with optional filtering by entity ID
|
||||
operationId: listCerts
|
||||
security:
|
||||
- BearerAuth: []
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/DomainID'
|
||||
- $ref: '#/components/parameters/Offset'
|
||||
- $ref: '#/components/parameters/Limit'
|
||||
- $ref: '#/components/parameters/EntityIDFilter'
|
||||
responses:
|
||||
'200':
|
||||
description: Certificates successfully retrieved
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/CertificateListResponse'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
|
||||
/{domainID}/certs/{id}:
|
||||
get:
|
||||
tags:
|
||||
- certificates
|
||||
summary: View certificate details
|
||||
description: Retrieves detailed information about a specific certificate by serial number
|
||||
operationId: viewCert
|
||||
security:
|
||||
- BearerAuth: []
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/DomainID'
|
||||
- $ref: '#/components/parameters/CertID'
|
||||
responses:
|
||||
'200':
|
||||
description: Certificate details successfully retrieved
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ViewCertResponse'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
|
||||
/{domainID}/certs/csrs/{entityID}:
|
||||
post:
|
||||
tags:
|
||||
- certificates
|
||||
summary: Issue certificate from CSR
|
||||
description: Issues a certificate from a Certificate Signing Request (CSR)
|
||||
operationId: issueFromCSR
|
||||
security:
|
||||
- BearerAuth: []
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/DomainID'
|
||||
- $ref: '#/components/parameters/EntityID'
|
||||
- $ref: '#/components/parameters/TTL'
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/IssueFromCSRRequest'
|
||||
responses:
|
||||
'200':
|
||||
description: Certificate successfully issued from CSR
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/IssueFromCSRResponse'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
|
||||
/certs/csrs/{entityID}:
|
||||
post:
|
||||
tags:
|
||||
- certificates
|
||||
summary: Issue certificate from CSR (Internal)
|
||||
description: Issues a certificate from a CSR using internal agent authentication
|
||||
operationId: issueFromCSRInternal
|
||||
security:
|
||||
- AgentAuth: []
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/EntityID'
|
||||
- $ref: '#/components/parameters/TTL'
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/IssueFromCSRRequest'
|
||||
responses:
|
||||
'200':
|
||||
description: Certificate successfully issued from CSR
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/IssueFromCSRResponse'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
|
||||
/certs/ocsp:
|
||||
post:
|
||||
tags:
|
||||
- pki
|
||||
summary: OCSP responder
|
||||
description: |
|
||||
Online Certificate Status Protocol (OCSP) responder endpoint.
|
||||
Accepts both binary OCSP requests and JSON format requests.
|
||||
operationId: ocsp
|
||||
security: []
|
||||
parameters:
|
||||
- name: force_status
|
||||
in: query
|
||||
description: Force a specific OCSP status for testing
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/ocsp-request:
|
||||
schema:
|
||||
type: string
|
||||
format: binary
|
||||
description: DER-encoded OCSP request
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/OCSPRequest'
|
||||
responses:
|
||||
'200':
|
||||
description: OCSP response
|
||||
content:
|
||||
application/ocsp-response:
|
||||
schema:
|
||||
type: string
|
||||
format: binary
|
||||
description: DER-encoded OCSP response
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
|
||||
/certs/crl:
|
||||
get:
|
||||
tags:
|
||||
- pki
|
||||
summary: Generate Certificate Revocation List
|
||||
description: Generates and returns the current Certificate Revocation List (CRL)
|
||||
operationId: generateCRL
|
||||
security: []
|
||||
responses:
|
||||
'200':
|
||||
description: CRL successfully generated
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/CRLResponse'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
|
||||
/certs/view-ca:
|
||||
get:
|
||||
tags:
|
||||
- pki
|
||||
summary: View CA certificate
|
||||
description: Retrieves the CA certificate chain (root and intermediate certificates)
|
||||
operationId: viewCA
|
||||
security: []
|
||||
responses:
|
||||
'200':
|
||||
description: CA certificate successfully retrieved
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ViewCertResponse'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
|
||||
/certs/download-ca:
|
||||
get:
|
||||
tags:
|
||||
- pki
|
||||
summary: Download CA certificate
|
||||
description: Downloads the CA certificate as a ZIP file
|
||||
operationId: downloadCA
|
||||
security: []
|
||||
responses:
|
||||
'200':
|
||||
description: CA certificate ZIP file
|
||||
content:
|
||||
application/zip:
|
||||
schema:
|
||||
type: string
|
||||
format: binary
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
|
||||
/health:
|
||||
get:
|
||||
summary: Retrieves service health check info.
|
||||
tags:
|
||||
- health
|
||||
security: []
|
||||
responses:
|
||||
'200':
|
||||
$ref: '#/components/responses/HealthRes'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
|
||||
/metrics:
|
||||
get:
|
||||
tags:
|
||||
- health
|
||||
summary: Prometheus metrics
|
||||
description: Returns Prometheus metrics for monitoring
|
||||
operationId: metrics
|
||||
security: []
|
||||
responses:
|
||||
'200':
|
||||
description: Metrics successfully retrieved
|
||||
content:
|
||||
text/plain:
|
||||
schema:
|
||||
type: string
|
||||
|
||||
components:
|
||||
securitySchemes:
|
||||
BearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
description: User authentication token
|
||||
AgentAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
description: Agent authentication token for internal operations
|
||||
|
||||
parameters:
|
||||
DomainID:
|
||||
name: domainID
|
||||
in: path
|
||||
required: true
|
||||
description: Domain identifier
|
||||
schema:
|
||||
type: string
|
||||
EntityID:
|
||||
name: entityID
|
||||
in: path
|
||||
required: true
|
||||
description: Entity identifier for the certificate
|
||||
schema:
|
||||
type: string
|
||||
CertID:
|
||||
name: id
|
||||
in: path
|
||||
required: true
|
||||
description: Certificate serial number
|
||||
schema:
|
||||
type: string
|
||||
Offset:
|
||||
name: offset
|
||||
in: query
|
||||
description: Number of items to skip
|
||||
schema:
|
||||
type: integer
|
||||
minimum: 0
|
||||
default: 0
|
||||
Limit:
|
||||
name: limit
|
||||
in: query
|
||||
description: Maximum number of items to return
|
||||
schema:
|
||||
type: integer
|
||||
minimum: 1
|
||||
maximum: 100
|
||||
default: 10
|
||||
EntityIDFilter:
|
||||
name: entity_id
|
||||
in: query
|
||||
description: Filter certificates by entity ID
|
||||
schema:
|
||||
type: string
|
||||
TTL:
|
||||
name: ttl
|
||||
in: query
|
||||
description: Time to live for the certificate (e.g., "8760h", "365d")
|
||||
schema:
|
||||
type: string
|
||||
|
||||
schemas:
|
||||
IssueCertRequest:
|
||||
type: object
|
||||
required:
|
||||
- options
|
||||
properties:
|
||||
ttl:
|
||||
type: string
|
||||
description: Time to live for the certificate (e.g., "8760h" for 1 year)
|
||||
example: "8760h"
|
||||
ip_addresses:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
description: IP addresses to include in the certificate
|
||||
example: ["192.168.1.1", "10.0.0.1"]
|
||||
options:
|
||||
$ref: '#/components/schemas/SubjectOptions'
|
||||
|
||||
SubjectOptions:
|
||||
type: object
|
||||
required:
|
||||
- common_name
|
||||
properties:
|
||||
common_name:
|
||||
type: string
|
||||
description: Common Name (CN) for the certificate subject
|
||||
example: "example.com"
|
||||
organization:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
description: Organization (O)
|
||||
example: ["Abstract Machines"]
|
||||
organizational_unit:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
description: Organizational Unit (OU)
|
||||
example: ["Engineering"]
|
||||
country:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
description: Country (C)
|
||||
example: ["US"]
|
||||
province:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
description: Province or State (ST)
|
||||
example: ["California"]
|
||||
locality:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
description: Locality or City (L)
|
||||
example: ["San Francisco"]
|
||||
street_address:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
description: Street Address
|
||||
example: ["123 Main St"]
|
||||
postal_code:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
description: Postal Code
|
||||
example: ["94105"]
|
||||
dns_names:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
description: DNS names for Subject Alternative Names
|
||||
example: ["example.com", "www.example.com"]
|
||||
ip_addresses:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
description: IP addresses for Subject Alternative Names
|
||||
example: ["192.168.1.1"]
|
||||
|
||||
CertificateResponse:
|
||||
type: object
|
||||
properties:
|
||||
serial_number:
|
||||
type: string
|
||||
description: Unique serial number of the certificate
|
||||
example: "4a:3f:5e:2c:1b:8d:9e:7f"
|
||||
certificate:
|
||||
type: string
|
||||
description: PEM-encoded certificate
|
||||
example: "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----"
|
||||
key:
|
||||
type: string
|
||||
description: PEM-encoded private key
|
||||
example: "-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----"
|
||||
revoked:
|
||||
type: boolean
|
||||
description: Whether the certificate is revoked
|
||||
example: false
|
||||
expiry_time:
|
||||
type: string
|
||||
format: date-time
|
||||
description: Certificate expiration time
|
||||
example: "2026-11-05T12:00:00Z"
|
||||
entity_id:
|
||||
type: string
|
||||
description: Entity identifier associated with the certificate
|
||||
example: "entity-123"
|
||||
|
||||
RenewCertResponse:
|
||||
type: object
|
||||
properties:
|
||||
certificate:
|
||||
$ref: '#/components/schemas/ViewCertResponse'
|
||||
|
||||
ViewCertResponse:
|
||||
type: object
|
||||
properties:
|
||||
serial_number:
|
||||
type: string
|
||||
description: Certificate serial number
|
||||
example: "4a:3f:5e:2c:1b:8d:9e:7f"
|
||||
certificate:
|
||||
type: string
|
||||
description: PEM-encoded certificate
|
||||
example: "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----"
|
||||
key:
|
||||
type: string
|
||||
description: PEM-encoded private key
|
||||
example: "-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----"
|
||||
revoked:
|
||||
type: boolean
|
||||
description: Revocation status
|
||||
example: false
|
||||
expiry_time:
|
||||
type: string
|
||||
format: date-time
|
||||
description: Expiration timestamp
|
||||
example: "2026-11-05T12:00:00Z"
|
||||
entity_id:
|
||||
type: string
|
||||
description: Associated entity identifier
|
||||
example: "entity-123"
|
||||
|
||||
CertificateListResponse:
|
||||
type: object
|
||||
properties:
|
||||
total:
|
||||
type: integer
|
||||
format: uint64
|
||||
description: Total number of certificates
|
||||
example: 100
|
||||
offset:
|
||||
type: integer
|
||||
format: uint64
|
||||
description: Current offset
|
||||
example: 0
|
||||
limit:
|
||||
type: integer
|
||||
format: uint64
|
||||
description: Current limit
|
||||
example: 10
|
||||
certificates:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/ViewCertResponse'
|
||||
|
||||
IssueFromCSRRequest:
|
||||
type: object
|
||||
required:
|
||||
- csr
|
||||
properties:
|
||||
csr:
|
||||
type: string
|
||||
format: byte
|
||||
description: PEM-encoded Certificate Signing Request
|
||||
example: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0K..."
|
||||
|
||||
IssueFromCSRResponse:
|
||||
type: object
|
||||
properties:
|
||||
serial_number:
|
||||
type: string
|
||||
description: Serial number of the issued certificate
|
||||
example: "4a:3f:5e:2c:1b:8d:9e:7f"
|
||||
certificate:
|
||||
type: string
|
||||
description: PEM-encoded certificate
|
||||
example: "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----"
|
||||
revoked:
|
||||
type: boolean
|
||||
description: Revocation status
|
||||
example: false
|
||||
expiry_time:
|
||||
type: string
|
||||
format: date-time
|
||||
description: Expiration timestamp
|
||||
example: "2026-11-05T12:00:00Z"
|
||||
entity_id:
|
||||
type: string
|
||||
description: Associated entity identifier
|
||||
example: "entity-123"
|
||||
|
||||
OCSPRequest:
|
||||
type: object
|
||||
properties:
|
||||
serial_number:
|
||||
type: string
|
||||
description: Certificate serial number to check
|
||||
example: "4a:3f:5e:2c:1b:8d:9e:7f"
|
||||
certificate:
|
||||
type: string
|
||||
description: PEM-encoded certificate to check
|
||||
example: "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----"
|
||||
status:
|
||||
type: string
|
||||
description: Force a specific status (for testing)
|
||||
enum: [good, revoked, unknown]
|
||||
|
||||
CRLResponse:
|
||||
type: object
|
||||
properties:
|
||||
crl:
|
||||
type: string
|
||||
format: byte
|
||||
description: DER-encoded Certificate Revocation List
|
||||
|
||||
Error:
|
||||
type: object
|
||||
properties:
|
||||
error:
|
||||
type: string
|
||||
description: Error message
|
||||
example: "invalid request"
|
||||
|
||||
responses:
|
||||
BadRequest:
|
||||
description: Bad request - invalid parameters or malformed request
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
Unauthorized:
|
||||
description: Unauthorized - invalid or missing authentication token
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
NotFound:
|
||||
description: Resource not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
UnprocessableEntity:
|
||||
description: Unprocessable entity - request cannot be processed
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
InternalServerError:
|
||||
description: Internal server error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
HealthRes:
|
||||
description: Service Health Check.
|
||||
content:
|
||||
application/health+json:
|
||||
schema:
|
||||
$ref: './schemas/health_info.yaml'
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -9,11 +9,11 @@ info:
|
||||
Some useful links:
|
||||
- [The Magistrala repository](https://github.com/absmach/magistrala)
|
||||
contact:
|
||||
email: info@mainflux.com
|
||||
email: info@absmach.eu
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: https://github.com/absmach/magistrala/blob/master/LICENSE
|
||||
version: 0.14.0
|
||||
url: https://github.com/absmach/magistrala/blob/main/LICENSE
|
||||
version: 0.18.0
|
||||
|
||||
servers:
|
||||
- url: http://localhost:8008
|
||||
@@ -24,10 +24,10 @@ tags:
|
||||
description: Everything about your Messages
|
||||
externalDocs:
|
||||
description: Find out more about messages
|
||||
url: https://docs.magistrala.abstractmachines.fr/
|
||||
|
||||
url: https://magistrala.absmach.eu/docs/
|
||||
|
||||
paths:
|
||||
/channels/{id}/messages:
|
||||
/m/{domainPrefix}/c/{channelPrefix}:
|
||||
post:
|
||||
summary: Sends message to the communication channel
|
||||
description: |
|
||||
@@ -36,7 +36,8 @@ paths:
|
||||
tags:
|
||||
- messages
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/ID"
|
||||
- $ref: "#/components/parameters/domainPrefix"
|
||||
- $ref: "#/components/parameters/channelPrefix"
|
||||
requestBody:
|
||||
$ref: "#/components/requestBodies/MessageReq"
|
||||
responses:
|
||||
@@ -46,21 +47,24 @@ paths:
|
||||
description: Message discarded due to its malformed content.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"403":
|
||||
description: Access denied to the requested resource.
|
||||
"404":
|
||||
description: Message discarded due to invalid channel id.
|
||||
"415":
|
||||
description: Message discarded due to invalid or missing content type.
|
||||
'500':
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
/health:
|
||||
get:
|
||||
summary: Retrieves service health check info.
|
||||
tags:
|
||||
- health
|
||||
security: []
|
||||
responses:
|
||||
'200':
|
||||
"200":
|
||||
$ref: "#/components/responses/HealthRes"
|
||||
'500':
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
components:
|
||||
@@ -128,13 +132,21 @@ components:
|
||||
$ref: "#/components/schemas/SenMLRecord"
|
||||
|
||||
parameters:
|
||||
ID:
|
||||
name: id
|
||||
description: Unique channel identifier.
|
||||
domainPrefix:
|
||||
name: domainPrefix
|
||||
description: ID or route of the domain associated with the channel and client.
|
||||
in: path
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
example: mydomain
|
||||
required: true
|
||||
channelPrefix:
|
||||
name: channelPrefix
|
||||
description: ID or route of the channel connected to the client.
|
||||
in: path
|
||||
schema:
|
||||
type: string
|
||||
example: mychannel
|
||||
required: true
|
||||
|
||||
requestBodies:
|
||||
@@ -154,13 +166,13 @@ components:
|
||||
responses:
|
||||
ServiceError:
|
||||
description: Unexpected server-side error occurred.
|
||||
|
||||
|
||||
HealthRes:
|
||||
description: Service Health Check.
|
||||
content:
|
||||
application/json:
|
||||
application/health+json:
|
||||
schema:
|
||||
$ref: "./schemas/HealthInfo.yml"
|
||||
$ref: "./schemas/health_info.yaml"
|
||||
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
@@ -168,13 +180,13 @@ components:
|
||||
scheme: bearer
|
||||
bearerFormat: uuid
|
||||
description: |
|
||||
* Thing access: "Authorization: Thing <thing_key>"
|
||||
* Client access: "Authorization: Client <client_key>"
|
||||
|
||||
basicAuth:
|
||||
type: http
|
||||
scheme: basic
|
||||
description: |
|
||||
* Things access: "Authorization: Basic <base64-encoded_credentials>"
|
||||
* Clients access: "Authorization: Basic <base64-encoded_credentials>"
|
||||
|
||||
security:
|
||||
- bearerAuth: []
|
||||
@@ -9,28 +9,29 @@ info:
|
||||
Some useful links:
|
||||
- [The Magistrala repository](https://github.com/absmach/magistrala)
|
||||
contact:
|
||||
email: info@mainflux.com
|
||||
email: info@absmach.eu
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: https://github.com/absmach/magistrala/blob/master/LICENSE
|
||||
version: 0.14.0
|
||||
url: https://github.com/absmach/magistrala/blob/main/LICENSE
|
||||
version: 0.18.5
|
||||
|
||||
servers:
|
||||
- url: http://localhost:9014
|
||||
- url: https://localhost:9014
|
||||
- url: http://localhost:9015
|
||||
- url: https://localhost:9015
|
||||
|
||||
|
||||
tags:
|
||||
- name: notifiers
|
||||
description: Everything about your Notifiers
|
||||
externalDocs:
|
||||
description: Find out more about notifiers
|
||||
url: https://docs.magistrala.abstractmachines.fr/
|
||||
|
||||
url: https://magistrala.absmach.eu/docs/
|
||||
|
||||
paths:
|
||||
/subscriptions:
|
||||
post:
|
||||
operationId: createSubscription
|
||||
summary: Create subscription
|
||||
description: Creates a new subscription give a topic and contact.
|
||||
tags:
|
||||
@@ -42,13 +43,20 @@ paths:
|
||||
$ref: "#/components/responses/Create"
|
||||
"400":
|
||||
description: Failed due to malformed JSON.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"403":
|
||||
description: Failed to perform authorization over the entity.
|
||||
"409":
|
||||
description: Failed due to using an existing topic and contact.
|
||||
"415":
|
||||
description: Missing or invalid content type.
|
||||
"422":
|
||||
description: Database can't process request.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
get:
|
||||
operationId: listSubscriptions
|
||||
summary: List subscriptions
|
||||
description: List subscriptions given list parameters.
|
||||
tags:
|
||||
@@ -65,10 +73,17 @@ paths:
|
||||
description: Failed due to malformed query parameters.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"403":
|
||||
description: Failed to perform authorization over the entity.
|
||||
"404":
|
||||
description: A non-existent entity request.
|
||||
"422":
|
||||
description: Database can't process request.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
/subscriptions/{id}:
|
||||
get:
|
||||
operationId: viewSubscription
|
||||
summary: Get subscription with the provided id
|
||||
description: Retrieves a subscription with the provided id.
|
||||
tags:
|
||||
@@ -78,11 +93,20 @@ paths:
|
||||
responses:
|
||||
"200":
|
||||
$ref: "#/components/responses/View"
|
||||
"400":
|
||||
description: Failed due to malformed ID.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"403":
|
||||
description: Failed to perform authorization over the entity.
|
||||
"404":
|
||||
description: A non-existent entity request.
|
||||
"422":
|
||||
description: Database can't process request.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
delete:
|
||||
operationId: removeSubscription
|
||||
summary: Delete subscription with the provided id
|
||||
description: Removes a subscription with the provided id.
|
||||
tags:
|
||||
@@ -94,6 +118,12 @@ paths:
|
||||
description: Subscription removed
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"403":
|
||||
description: Failed to perform authorization over the entity.
|
||||
"404":
|
||||
description: A non-existent entity request.
|
||||
"422":
|
||||
description: Database can't process request.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
/health:
|
||||
@@ -101,10 +131,11 @@ paths:
|
||||
summary: Retrieves service health check info.
|
||||
tags:
|
||||
- health
|
||||
security: []
|
||||
responses:
|
||||
'200':
|
||||
"200":
|
||||
$ref: "#/components/responses/HealthRes"
|
||||
'500':
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
components:
|
||||
@@ -124,7 +155,7 @@ components:
|
||||
description: An id of the owner who created subscription.
|
||||
topic:
|
||||
type: string
|
||||
example: topic.subtopic
|
||||
example: topic/subtopic
|
||||
description: Topic to which the user subscribes.
|
||||
contact:
|
||||
type: string
|
||||
@@ -135,12 +166,12 @@ components:
|
||||
properties:
|
||||
topic:
|
||||
type: string
|
||||
example: topic.subtopic
|
||||
example: topic/subtopic
|
||||
description: Topic to which the user subscribes.
|
||||
contact:
|
||||
type: string
|
||||
example: user@example.com
|
||||
description: The contact of the user to which the notification will be sent.
|
||||
description: The contact of the user to which the notification will be sent.
|
||||
Page:
|
||||
type: object
|
||||
properties:
|
||||
@@ -229,6 +260,11 @@ components:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Subscription"
|
||||
links:
|
||||
delete:
|
||||
operationId: removeSubscription
|
||||
parameters:
|
||||
id: $response.body#/id
|
||||
Page:
|
||||
description: Data retrieved.
|
||||
content:
|
||||
@@ -240,9 +276,9 @@ components:
|
||||
HealthRes:
|
||||
description: Service Health Check.
|
||||
content:
|
||||
application/json:
|
||||
application/health+json:
|
||||
schema:
|
||||
$ref: "./schemas/HealthInfo.yml"
|
||||
$ref: "./schemas/health_info.yaml"
|
||||
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
@@ -9,34 +9,33 @@ info:
|
||||
Some useful links:
|
||||
- [The Magistrala repository](https://github.com/absmach/magistrala)
|
||||
contact:
|
||||
email: info@mainflux.com
|
||||
email: info@absmach.eu
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: https://github.com/absmach/magistrala/blob/master/LICENSE
|
||||
version: 0.14.0
|
||||
url: https://github.com/absmach/magistrala/blob/main/LICENSE
|
||||
version: 0.18.5
|
||||
|
||||
servers:
|
||||
- url: http://localhost:9003
|
||||
- url: https://localhost:9003
|
||||
- url: http://localhost:9005
|
||||
- url: https://localhost:9005
|
||||
- url: http://localhost:9007
|
||||
- url: https://localhost:9007
|
||||
- url: http://localhost:9009
|
||||
- url: https://localhost:9009
|
||||
- url: http://localhost:9011
|
||||
- url: https://localhost:9011
|
||||
|
||||
|
||||
tags:
|
||||
- name: readers
|
||||
description: Everything about your Readers
|
||||
externalDocs:
|
||||
description: Find out more about readers
|
||||
url: https://docs.magistrala.abstractmachines.fr/
|
||||
url: https://magistrala.absmach.eu/docs/
|
||||
|
||||
paths:
|
||||
/channels/{chanId}/messages:
|
||||
/{domainID}/channels/{chanId}/messages:
|
||||
get:
|
||||
operationId: getMessages
|
||||
summary: Retrieves messages sent to single channel
|
||||
description: |
|
||||
Retrieves a list of messages sent to specific channel. Due to
|
||||
@@ -46,6 +45,7 @@ paths:
|
||||
tags:
|
||||
- readers
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/DomainID"
|
||||
- $ref: "#/components/parameters/ChanId"
|
||||
- $ref: "#/components/parameters/Limit"
|
||||
- $ref: "#/components/parameters/Offset"
|
||||
@@ -57,24 +57,30 @@ paths:
|
||||
- $ref: "#/components/parameters/DataValue"
|
||||
- $ref: "#/components/parameters/From"
|
||||
- $ref: "#/components/parameters/To"
|
||||
- $ref: "#/components/parameters/Aggregation"
|
||||
- $ref: "#/components/parameters/Interval"
|
||||
responses:
|
||||
'200':
|
||||
"200":
|
||||
$ref: "#/components/responses/MessagesPageRes"
|
||||
'400':
|
||||
"400":
|
||||
description: Failed due to malformed query parameters.
|
||||
'401':
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
'500':
|
||||
"403":
|
||||
description: Failed to perform authorization over the entity.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
/health:
|
||||
get:
|
||||
operationId: health
|
||||
summary: Retrieves service health check info.
|
||||
tags:
|
||||
- health
|
||||
security: []
|
||||
responses:
|
||||
'200':
|
||||
"200":
|
||||
$ref: "#/components/responses/HealthRes"
|
||||
'500':
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
components:
|
||||
@@ -136,6 +142,14 @@ components:
|
||||
description: Time of updating measurement.
|
||||
|
||||
parameters:
|
||||
DomainID:
|
||||
name: domainID
|
||||
description: Unique domain identifier.
|
||||
in: path
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
required: true
|
||||
ChanId:
|
||||
name: chanId
|
||||
description: Unique channel identifier.
|
||||
@@ -226,6 +240,7 @@ components:
|
||||
in: query
|
||||
schema:
|
||||
type: number
|
||||
example: 1709218556069
|
||||
required: false
|
||||
To:
|
||||
name: to
|
||||
@@ -233,6 +248,34 @@ components:
|
||||
in: query
|
||||
schema:
|
||||
type: number
|
||||
example: 1709218757503
|
||||
required: false
|
||||
Aggregation:
|
||||
name: aggregation
|
||||
description: Aggregation function.
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
enum:
|
||||
- MAX
|
||||
- AVG
|
||||
- MIN
|
||||
- SUM
|
||||
- COUNT
|
||||
- max
|
||||
- min
|
||||
- sum
|
||||
- avg
|
||||
- count
|
||||
example: MAX
|
||||
required: false
|
||||
Interval:
|
||||
name: interval
|
||||
description: Aggregation interval.
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
example: 10s
|
||||
required: false
|
||||
|
||||
responses:
|
||||
@@ -247,9 +290,9 @@ components:
|
||||
HealthRes:
|
||||
description: Service Health Check.
|
||||
content:
|
||||
application/json:
|
||||
application/health+json:
|
||||
schema:
|
||||
$ref: "./schemas/HealthInfo.yml"
|
||||
$ref: "./schemas/health_info.yaml"
|
||||
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
@@ -0,0 +1,553 @@
|
||||
# Copyright (c) Abstract Machines
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
openapi: 3.0.1
|
||||
info:
|
||||
title: Magistrala Reports Service API
|
||||
description: |
|
||||
HTTP API for managing reports service.
|
||||
version: 0.18.5
|
||||
servers:
|
||||
- url: http://localhost:9017
|
||||
tags:
|
||||
- name: reports
|
||||
description: Operations related to report configurations and generation
|
||||
paths:
|
||||
/{domainID}/reports:
|
||||
post:
|
||||
operationId: generateReport
|
||||
summary: Generate a report
|
||||
description: Generates a report based on the provided configuration or an existing config. The action determines the response format.
|
||||
tags:
|
||||
- reports
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/DomainID'
|
||||
security:
|
||||
- bearerAuth: []
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GenerateReportRequest'
|
||||
responses:
|
||||
'200':
|
||||
description: Report generated successfully (content varies by action)
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GenerateReportResponse'
|
||||
application/octet-stream:
|
||||
schema:
|
||||
type: string
|
||||
format: binary
|
||||
'400':
|
||||
description: Invalid request parameters
|
||||
'401':
|
||||
description: Missing or invalid access token
|
||||
'500':
|
||||
$ref: '#/components/responses/ServiceError'
|
||||
|
||||
/{domainID}/reports/configs:
|
||||
post:
|
||||
operationId: addReportConfig
|
||||
summary: Create a report configuration
|
||||
description: Creates a new report configuration.
|
||||
tags:
|
||||
- reports
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/DomainID'
|
||||
security:
|
||||
- bearerAuth: []
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/AddReportConfigRequest'
|
||||
responses:
|
||||
'201':
|
||||
description: Report configuration created
|
||||
headers:
|
||||
Location:
|
||||
schema:
|
||||
type: string
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ReportConfig'
|
||||
'400':
|
||||
description: Invalid request body
|
||||
'401':
|
||||
description: Missing or invalid access token
|
||||
'500':
|
||||
$ref: '#/components/responses/ServiceError'
|
||||
get:
|
||||
operationId: listReportConfigs
|
||||
summary: List report configurations
|
||||
description: Retrieves a paginated list of report configurations.
|
||||
tags:
|
||||
- reports
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/DomainID'
|
||||
- $ref: '#/components/parameters/Offset'
|
||||
- $ref: '#/components/parameters/Limit'
|
||||
security:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
'200':
|
||||
description: List of report configurations
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ListReportsConfigResponse'
|
||||
'400':
|
||||
description: Invalid query parameters
|
||||
'401':
|
||||
description: Missing or invalid access token
|
||||
'500':
|
||||
$ref: '#/components/responses/ServiceError'
|
||||
|
||||
/{domainID}/reports/configs/{reportID}:
|
||||
get:
|
||||
operationId: viewReportConfig
|
||||
summary: View a report configuration
|
||||
description: Retrieves details of a specific report configuration.
|
||||
tags:
|
||||
- reports
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/DomainID'
|
||||
- $ref: '#/components/parameters/ReportID'
|
||||
security:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
'200':
|
||||
description: Report configuration details
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ReportConfig'
|
||||
'404':
|
||||
description: Report configuration not found
|
||||
'401':
|
||||
description: Missing or invalid access token
|
||||
'500':
|
||||
$ref: '#/components/responses/ServiceError'
|
||||
patch:
|
||||
operationId: updateReportConfig
|
||||
summary: Update a report configuration
|
||||
description: Updates specified fields of a report configuration.
|
||||
tags:
|
||||
- reports
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/DomainID'
|
||||
- $ref: '#/components/parameters/ReportID'
|
||||
security:
|
||||
- bearerAuth: []
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/UpdateReportConfigRequest'
|
||||
responses:
|
||||
'200':
|
||||
description: Report configuration updated
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ReportConfig'
|
||||
'400':
|
||||
description: Invalid request body
|
||||
'401':
|
||||
description: Missing or invalid access token
|
||||
'404':
|
||||
description: Report configuration not found
|
||||
'500':
|
||||
$ref: '#/components/responses/ServiceError'
|
||||
delete:
|
||||
operationId: deleteReportConfig
|
||||
summary: Delete a report configuration
|
||||
description: Permanently deletes a report configuration.
|
||||
tags:
|
||||
- reports
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/DomainID'
|
||||
- $ref: '#/components/parameters/ReportID'
|
||||
security:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
'204':
|
||||
description: Report configuration deleted
|
||||
'401':
|
||||
description: Missing or invalid access token
|
||||
'404':
|
||||
description: Report configuration not found
|
||||
'500':
|
||||
$ref: '#/components/responses/ServiceError'
|
||||
|
||||
/{domainID}/reports/configs/{reportID}/schedule:
|
||||
patch:
|
||||
operationId: updateReportSchedule
|
||||
summary: Update report schedule
|
||||
description: Updates the schedule of a report configuration.
|
||||
tags:
|
||||
- reports
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/DomainID'
|
||||
- $ref: '#/components/parameters/ReportID'
|
||||
security:
|
||||
- bearerAuth: []
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Schedule'
|
||||
responses:
|
||||
'200':
|
||||
description: Schedule updated
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ReportConfig'
|
||||
'400':
|
||||
description: Invalid schedule
|
||||
'401':
|
||||
description: Missing or invalid access token
|
||||
'404':
|
||||
description: Report configuration not found
|
||||
'500':
|
||||
$ref: '#/components/responses/ServiceError'
|
||||
|
||||
/{domainID}/reports/configs/{reportID}/enable:
|
||||
post:
|
||||
operationId: enableReportConfig
|
||||
summary: Enable a report configuration
|
||||
description: Enables a report configuration to generate scheduled reports.
|
||||
tags:
|
||||
- reports
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/DomainID'
|
||||
- $ref: '#/components/parameters/ReportID'
|
||||
security:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
'200':
|
||||
description: Report configuration enabled
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ReportConfig'
|
||||
'401':
|
||||
description: Missing or invalid access token
|
||||
'404':
|
||||
description: Report configuration not found
|
||||
'500':
|
||||
$ref: '#/components/responses/ServiceError'
|
||||
|
||||
/{domainID}/reports/configs/{reportID}/disable:
|
||||
post:
|
||||
operationId: disableReportConfig
|
||||
summary: Disable a report configuration
|
||||
description: Disables a report configuration, stopping scheduled reports.
|
||||
tags:
|
||||
- reports
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/DomainID'
|
||||
- $ref: '#/components/parameters/ReportID'
|
||||
security:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
'200':
|
||||
description: Report configuration disabled
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ReportConfig'
|
||||
'401':
|
||||
description: Missing or invalid access token
|
||||
'404':
|
||||
description: Report configuration not found
|
||||
'500':
|
||||
$ref: '#/components/responses/ServiceError'
|
||||
|
||||
/health:
|
||||
get:
|
||||
summary: Service health check
|
||||
tags:
|
||||
- health
|
||||
responses:
|
||||
'200':
|
||||
$ref: '#/components/responses/HealthRes'
|
||||
|
||||
components:
|
||||
schemas:
|
||||
ReportConfig:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
readOnly: true
|
||||
name:
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
domain_id:
|
||||
type: string
|
||||
readOnly: true
|
||||
schedule:
|
||||
$ref: '#/components/schemas/Schedule'
|
||||
config:
|
||||
$ref: '#/components/schemas/MetricConfig'
|
||||
email:
|
||||
$ref: '#/components/schemas/EmailSetting'
|
||||
metrics:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/ReqMetric'
|
||||
status:
|
||||
$ref: '#/components/schemas/Status'
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
readOnly: true
|
||||
created_by:
|
||||
type: string
|
||||
readOnly: true
|
||||
updated_at:
|
||||
type: string
|
||||
format: date-time
|
||||
readOnly: true
|
||||
updated_by:
|
||||
type: string
|
||||
readOnly: true
|
||||
required:
|
||||
- name
|
||||
- metrics
|
||||
- config
|
||||
|
||||
Schedule:
|
||||
type: object
|
||||
properties:
|
||||
recurring:
|
||||
type: string
|
||||
enum: [None, Daily, Weekly, Monthly]
|
||||
recurring_period:
|
||||
type: integer
|
||||
minimum: 1
|
||||
start_time:
|
||||
type: string
|
||||
format: date-time
|
||||
next_run:
|
||||
type: string
|
||||
format: date-time
|
||||
readOnly: true
|
||||
|
||||
MetricConfig:
|
||||
type: object
|
||||
properties:
|
||||
title:
|
||||
type: string
|
||||
maxLength: 100
|
||||
format:
|
||||
type: string
|
||||
enum: [pdf, csv, html]
|
||||
aggregation:
|
||||
$ref: '#/components/schemas/AggConfig'
|
||||
|
||||
AggConfig:
|
||||
type: object
|
||||
properties:
|
||||
window:
|
||||
type: string
|
||||
function:
|
||||
type: string
|
||||
enum: [sum, average, max, min]
|
||||
|
||||
EmailSetting:
|
||||
type: object
|
||||
properties:
|
||||
recipients:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
format: email
|
||||
subject:
|
||||
type: string
|
||||
body_template:
|
||||
type: string
|
||||
required:
|
||||
- recipients
|
||||
- subject
|
||||
|
||||
ReqMetric:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
enum: [gauge, counter, histogram]
|
||||
parameters:
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
- type
|
||||
|
||||
Status:
|
||||
type: string
|
||||
enum: [enabled, disabled]
|
||||
|
||||
GenerateReportRequest:
|
||||
type: object
|
||||
properties:
|
||||
action:
|
||||
type: string
|
||||
enum: [view, download, email]
|
||||
config_id:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
schedule:
|
||||
$ref: '#/components/schemas/Schedule'
|
||||
config:
|
||||
$ref: '#/components/schemas/MetricConfig'
|
||||
email:
|
||||
$ref: '#/components/schemas/EmailSetting'
|
||||
metrics:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/ReqMetric'
|
||||
required:
|
||||
- action
|
||||
|
||||
GenerateReportResponse:
|
||||
type: object
|
||||
properties:
|
||||
total:
|
||||
type: integer
|
||||
from:
|
||||
type: string
|
||||
format: date-time
|
||||
to:
|
||||
type: string
|
||||
format: date-time
|
||||
aggregation:
|
||||
$ref: '#/components/schemas/AggConfig'
|
||||
reports:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Report'
|
||||
|
||||
Report:
|
||||
type: object
|
||||
properties:
|
||||
timestamp:
|
||||
type: string
|
||||
format: date-time
|
||||
value:
|
||||
type: number
|
||||
metric_name:
|
||||
type: string
|
||||
|
||||
AddReportConfigRequest:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
schedule:
|
||||
$ref: '#/components/schemas/Schedule'
|
||||
config:
|
||||
$ref: '#/components/schemas/MetricConfig'
|
||||
email:
|
||||
$ref: '#/components/schemas/EmailSetting'
|
||||
metrics:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/ReqMetric'
|
||||
status:
|
||||
$ref: '#/components/schemas/Status'
|
||||
required:
|
||||
- name
|
||||
- metrics
|
||||
- config
|
||||
|
||||
UpdateReportConfigRequest:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
schedule:
|
||||
$ref: '#/components/schemas/Schedule'
|
||||
config:
|
||||
$ref: '#/components/schemas/MetricConfig'
|
||||
email:
|
||||
$ref: '#/components/schemas/EmailSetting'
|
||||
metrics:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/ReqMetric'
|
||||
status:
|
||||
$ref: '#/components/schemas/Status'
|
||||
|
||||
ListReportsConfigResponse:
|
||||
type: object
|
||||
properties:
|
||||
total:
|
||||
type: integer
|
||||
offset:
|
||||
type: integer
|
||||
limit:
|
||||
type: integer
|
||||
report_configs:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/ReportConfig'
|
||||
|
||||
parameters:
|
||||
DomainID:
|
||||
name: domainID
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
ReportID:
|
||||
name: reportID
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
Offset:
|
||||
name: offset
|
||||
in: query
|
||||
schema:
|
||||
type: integer
|
||||
default: 0
|
||||
minimum: 0
|
||||
Limit:
|
||||
name: limit
|
||||
in: query
|
||||
schema:
|
||||
type: integer
|
||||
default: 10
|
||||
minimum: 1
|
||||
maximum: 100
|
||||
|
||||
responses:
|
||||
ServiceError:
|
||||
description: Unexpected server error
|
||||
HealthRes:
|
||||
description: Service Health Check.
|
||||
content:
|
||||
application/health+json:
|
||||
schema:
|
||||
$ref: './schemas/health_info.yaml'
|
||||
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
@@ -0,0 +1,586 @@
|
||||
# Copyright (c) Abstract Machines
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
openapi: 3.0.1
|
||||
info:
|
||||
title: Magistrala Rules Engine API
|
||||
description: |
|
||||
HTTP API for managing rules engine service.
|
||||
Some useful links:
|
||||
- [The Magistrala repository](https://github.com/absmach/magistrala)
|
||||
contact:
|
||||
email: info@absmach.eu
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: https://github.com/absmach/magistrala/blob/main/LICENSE
|
||||
version: 0.18.5
|
||||
|
||||
servers:
|
||||
- url: http://localhost:9008
|
||||
- url: http://localhost:9008
|
||||
|
||||
tags:
|
||||
- name: rules engine
|
||||
description: Everything about your Rules Engine
|
||||
externalDocs:
|
||||
description: Find out more about rules engine
|
||||
url: https://magistrala.absmach.eu/docs/
|
||||
|
||||
paths:
|
||||
/{domainID}/rules:
|
||||
post:
|
||||
operationId: createRule
|
||||
summary: Create Rule
|
||||
description: |
|
||||
Creates a new rule for message processing
|
||||
tags:
|
||||
- rules
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/DomainID'
|
||||
security:
|
||||
- bearerAuth: []
|
||||
requestBody:
|
||||
$ref: '#/components/requestBodies/RuleCreateReq'
|
||||
responses:
|
||||
'201':
|
||||
$ref: '#/components/responses/RuleCreateRes'
|
||||
'400':
|
||||
description: Failed due to malformed JSON
|
||||
'401':
|
||||
description: Missing or invalid access token
|
||||
'415':
|
||||
description: Missing or invalid content type
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
"503":
|
||||
description: Failed to receive response from the clients service.
|
||||
get:
|
||||
operationId: getRules
|
||||
summary: List Rules
|
||||
description: |
|
||||
Retrieves a list of rules with optional filtering
|
||||
tags:
|
||||
- rules
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/DomainID'
|
||||
- $ref: '#/components/parameters/Offset'
|
||||
- $ref: '#/components/parameters/Limit'
|
||||
- $ref: '#/components/parameters/InputChannel'
|
||||
- $ref: '#/components/parameters/OutputChannel'
|
||||
- $ref: '#/components/parameters/Status'
|
||||
security:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
'200':
|
||||
$ref: '#/components/responses/RuleListRes'
|
||||
'400':
|
||||
description: Failed due to malformed query parameters
|
||||
'401':
|
||||
description: Missing or invalid access token
|
||||
"422":
|
||||
description: Database can't process request.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
/{domainID}/rules/{ruleID}:
|
||||
get:
|
||||
operationId: getRule
|
||||
summary: View Rule
|
||||
description: Retrieves a rule by ID
|
||||
tags:
|
||||
- rules
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/DomainID'
|
||||
- $ref: '#/components/parameters/RuleID'
|
||||
security:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
'200':
|
||||
$ref: '#/components/responses/RuleRes'
|
||||
"400":
|
||||
description: Missing or invalid rule
|
||||
"403":
|
||||
description: Failed to perform authorization over the entity
|
||||
'401':
|
||||
description: Missing or invalid access token
|
||||
'404':
|
||||
description: Rule does not exist
|
||||
"422":
|
||||
description: Database can't process request
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
put:
|
||||
operationId: updateRule
|
||||
summary: Update Rule
|
||||
description: Updates an existing rule
|
||||
tags:
|
||||
- rules
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/DomainID'
|
||||
- $ref: '#/components/parameters/RuleID'
|
||||
security:
|
||||
- bearerAuth: []
|
||||
requestBody:
|
||||
$ref: '#/components/requestBodies/RuleUpdateReq'
|
||||
responses:
|
||||
'200':
|
||||
$ref: '#/components/responses/RuleRes'
|
||||
'400':
|
||||
description: Failed due to malformed JSON
|
||||
'401':
|
||||
description: Missing or invalid access token
|
||||
'404':
|
||||
description: Rule does not exist
|
||||
"415":
|
||||
description: Missing or invalid content type.
|
||||
"422":
|
||||
description: Database can't process request.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
delete:
|
||||
operationId: removeRule
|
||||
summary: Delete Rule
|
||||
description: Deletes a rule
|
||||
tags:
|
||||
- rules
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/DomainID'
|
||||
- $ref: '#/components/parameters/RuleID'
|
||||
security:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
'204':
|
||||
description: Rule deleted successfully
|
||||
"400":
|
||||
description: Failed due to malformed rule ID
|
||||
'401':
|
||||
description: Missing or invalid access token
|
||||
"403":
|
||||
description: Failed to perform authorization over the entity
|
||||
"422":
|
||||
description: Database can't process request
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
/{domainID}/rules/{ruleID}/enable:
|
||||
put:
|
||||
operationId: enableRule
|
||||
summary: Enable Rule
|
||||
description: Enables a rule for processing
|
||||
tags:
|
||||
- rules
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/DomainID'
|
||||
- $ref: '#/components/parameters/RuleID'
|
||||
security:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
'200':
|
||||
description: Rule enabled successfully
|
||||
"400":
|
||||
description: Failed due to malformed JSON
|
||||
'401':
|
||||
description: Missing or invalid access token
|
||||
"403":
|
||||
description: Failed to perform authorization over the entity
|
||||
'404':
|
||||
description: Rule does not exist
|
||||
"422":
|
||||
description: Database can't process request.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
/{domainID}/rules/{ruleID}/disable:
|
||||
put:
|
||||
operationId: disableRule
|
||||
summary: Disable Rule
|
||||
description: Disables a rule from processing
|
||||
tags:
|
||||
- Rules
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/DomainID'
|
||||
- $ref: '#/components/parameters/RuleID'
|
||||
security:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
'200':
|
||||
description: Rule disabled successfully
|
||||
"400":
|
||||
description: Failed due to malformed JSON
|
||||
'401':
|
||||
description: Missing or invalid access token
|
||||
"403":
|
||||
description: Failed to perform authorization over the entity
|
||||
'404':
|
||||
description: Rule does not exist
|
||||
"422":
|
||||
description: Database can't process request
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
/health:
|
||||
get:
|
||||
summary: Retrieves service health check info.
|
||||
tags:
|
||||
- health
|
||||
security: []
|
||||
responses:
|
||||
"200":
|
||||
$ref: "#/components/responses/HealthRes"
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
components:
|
||||
schemas:
|
||||
RulesListRes:
|
||||
type: object
|
||||
properties:
|
||||
total:
|
||||
type: integer
|
||||
description: Total number of results
|
||||
minimum: 0
|
||||
offset:
|
||||
type: integer
|
||||
description: Number of items to skip during retrieval
|
||||
minimum: 0
|
||||
default: 0
|
||||
limit:
|
||||
type: integer
|
||||
description: Size of the subset to retrieve
|
||||
maximum: 100
|
||||
default: 10
|
||||
rules:
|
||||
type: array
|
||||
minItems: 0
|
||||
uniqueItems: true
|
||||
items:
|
||||
$ref: '#/components/schemas/Rule'
|
||||
required:
|
||||
- rules
|
||||
|
||||
Rule:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
description: Unique rule identifier
|
||||
name:
|
||||
type: string
|
||||
description: Rule name
|
||||
domain:
|
||||
type: string
|
||||
description: Domain ID this rule belongs to
|
||||
metadata:
|
||||
type: object
|
||||
description: Custom metadata
|
||||
additionalProperties:
|
||||
type: string
|
||||
input_channel:
|
||||
type: string
|
||||
description: Input channel for receiving messages
|
||||
input_topic:
|
||||
type: string
|
||||
description: Input topic for receiving messages
|
||||
logic:
|
||||
type: object
|
||||
description: Rule processing logic script
|
||||
properties:
|
||||
script:
|
||||
type: string
|
||||
description: Script content
|
||||
output_channel:
|
||||
type: string
|
||||
description: Output channel for processed messages
|
||||
output_topic:
|
||||
type: string
|
||||
description: Output topic for processed messages
|
||||
schedule:
|
||||
type: object
|
||||
description: Rule execution schedule
|
||||
properties:
|
||||
start_datetime:
|
||||
type: string
|
||||
format: date-time
|
||||
description: When the schedule becomes active
|
||||
time:
|
||||
type: string
|
||||
format: date-time
|
||||
description: Specific time for the rule to run
|
||||
recurring:
|
||||
type: string
|
||||
description: Schedule recurrence pattern
|
||||
enum: [None, Daily, Weekly, Monthly]
|
||||
recurring_period:
|
||||
type: integer
|
||||
minimum: 1
|
||||
description: Controls how many intervals to skip between executions (1 = every interval, 2 = every second interval, etc.)
|
||||
status:
|
||||
type: string
|
||||
description: Rule status
|
||||
enum: [enabled, disabled]
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
description: Creation timestamp
|
||||
readOnly: true
|
||||
created_by:
|
||||
type: string
|
||||
description: User who created the rule
|
||||
updated_at:
|
||||
type: string
|
||||
format: date-time
|
||||
description: Last update timestamp
|
||||
readOnly: true
|
||||
updated_by:
|
||||
type: string
|
||||
description: User who last updated the rule
|
||||
required:
|
||||
- name
|
||||
- domain
|
||||
- input_channel
|
||||
- input_topic
|
||||
- logic
|
||||
- status
|
||||
|
||||
parameters:
|
||||
DomainID:
|
||||
name: domainID
|
||||
description: Domain ID
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
RuleID:
|
||||
name: ruleID
|
||||
description: Rule ID
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
Offset:
|
||||
name: offset
|
||||
description: Number of items to skip
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
default: 0
|
||||
minimum: 0
|
||||
Limit:
|
||||
name: limit
|
||||
description: Size of the subset
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
default: 10
|
||||
minimum: 1
|
||||
InputChannel:
|
||||
name: input_channel
|
||||
description: Filter by input channel
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
OutputChannel:
|
||||
name: output_channel
|
||||
description: Filter by output channel
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
Status:
|
||||
name: status
|
||||
description: Filter by rule status
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
enum: [enabled, disabled]
|
||||
default: enabled
|
||||
|
||||
requestBodies:
|
||||
RuleCreateReq:
|
||||
description: JSON-formatted document describing the new rule
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: Rule name
|
||||
domain:
|
||||
type: string
|
||||
description: Domain ID this rule belongs to
|
||||
metadata:
|
||||
type: object
|
||||
description: Custom metadata
|
||||
additionalProperties:
|
||||
type: string
|
||||
input_channel:
|
||||
type: string
|
||||
description: Input channel for receiving messages
|
||||
input_topic:
|
||||
type: string
|
||||
description: Input topic for receiving messages
|
||||
logic:
|
||||
type: object
|
||||
description: Rule processing logic script
|
||||
properties:
|
||||
script:
|
||||
type: string
|
||||
description: Script content
|
||||
output_channel:
|
||||
type: string
|
||||
description: Output channel for processed messages
|
||||
output_topic:
|
||||
type: string
|
||||
description: Output topic for processed messages
|
||||
schedule:
|
||||
type: object
|
||||
description: Rule execution schedule
|
||||
properties:
|
||||
start_datetime:
|
||||
type: string
|
||||
format: date-time
|
||||
description: When the schedule becomes active
|
||||
time:
|
||||
type: string
|
||||
format: date-time
|
||||
description: Specific time for the rule to run
|
||||
recurring:
|
||||
type: string
|
||||
description: Schedule recurrence pattern
|
||||
enum: [None, Daily, Weekly, Monthly]
|
||||
recurring_period:
|
||||
type: integer
|
||||
minimum: 1
|
||||
description: Controls how many intervals to skip between executions
|
||||
status:
|
||||
type: string
|
||||
description: Rule status
|
||||
enum: [enabled, disabled]
|
||||
required:
|
||||
- name
|
||||
- domain
|
||||
- input_channel
|
||||
- input_topic
|
||||
- logic
|
||||
- schedule
|
||||
RuleUpdateReq:
|
||||
description: JSON-formatted document describing the rule update
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: Rule name
|
||||
metadata:
|
||||
type: object
|
||||
description: Custom metadata
|
||||
additionalProperties:
|
||||
type: string
|
||||
input_channel:
|
||||
type: string
|
||||
description: Input channel for receiving messages
|
||||
input_topic:
|
||||
type: string
|
||||
description: Input topic for receiving messages
|
||||
logic:
|
||||
type: object
|
||||
description: Rule processing logic script
|
||||
properties:
|
||||
script:
|
||||
type: string
|
||||
description: Script content
|
||||
output_channel:
|
||||
type: string
|
||||
description: Output channel for processed messages
|
||||
output_topic:
|
||||
type: string
|
||||
description: Output topic for processed messages
|
||||
schedule:
|
||||
type: object
|
||||
description: Rule execution schedule
|
||||
properties:
|
||||
start_datetime:
|
||||
type: string
|
||||
format: date-time
|
||||
description: When the schedule becomes active
|
||||
time:
|
||||
type: string
|
||||
format: date-time
|
||||
description: Specific time for the rule to run
|
||||
recurring:
|
||||
type: string
|
||||
description: Schedule recurrence pattern
|
||||
enum: [None, Daily, Weekly, Monthly]
|
||||
recurring_period:
|
||||
type: integer
|
||||
minimum: 1
|
||||
description: Controls how many intervals to skip between executions
|
||||
status:
|
||||
type: string
|
||||
description: Rule status
|
||||
enum: [enabled, disabled]
|
||||
|
||||
responses:
|
||||
RuleCreateRes:
|
||||
description: Rule registered
|
||||
headers:
|
||||
Location:
|
||||
content:
|
||||
text/plain:
|
||||
schema:
|
||||
type: string
|
||||
description: Created rule's relative URL (i.e. /rules/{ruleID})
|
||||
RuleListRes:
|
||||
description: Data retrieved
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RulesListRes'
|
||||
RuleRes:
|
||||
description: Data retrieved
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Rule'
|
||||
links:
|
||||
update:
|
||||
operationId: updateRule
|
||||
parameters:
|
||||
ruleID: $response.body#/id
|
||||
enable:
|
||||
operationId: enableRule
|
||||
parameters:
|
||||
ruleID: $response.body#/id
|
||||
disable:
|
||||
operationId: disableRule
|
||||
parameters:
|
||||
ruleID: $response.body#/id
|
||||
delete:
|
||||
operationId: removeRule
|
||||
parameters:
|
||||
ruleID: $response.body#/id
|
||||
ServiceError:
|
||||
description: Unexpected server-side error occurred
|
||||
HealthRes:
|
||||
description: Service Health Check
|
||||
content:
|
||||
application/health+json:
|
||||
schema:
|
||||
$ref: "./schemas/health_info.yaml"
|
||||
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
description: |
|
||||
* Users access: "Authorization: Bearer <user_token>"
|
||||
@@ -11,11 +11,11 @@ properties:
|
||||
version:
|
||||
type: string
|
||||
description: Service version.
|
||||
example: 0.0.1
|
||||
example: v0.18.0
|
||||
commit:
|
||||
type: string
|
||||
description: Service commit hash.
|
||||
example: 7d6f4dc4f7f0c1fa3dc24eddfb18bb5073ff4f62
|
||||
example: 73362210dd2e04e389eaddb802cab3fe03976593
|
||||
description:
|
||||
type: string
|
||||
description: Service description.
|
||||
@@ -23,4 +23,8 @@ properties:
|
||||
build_time:
|
||||
type: string
|
||||
description: Service build time.
|
||||
example: 1970-01-01_00:00:00
|
||||
example: 2024-02-01_12:18:15
|
||||
instance_id:
|
||||
type: string
|
||||
description: Service instance ID.
|
||||
example: 8edbf8af-7db7-4218-bb4f-a8a929ff5266
|
||||
@@ -0,0 +1,395 @@
|
||||
# Copyright (c) Abstract Machines
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
components:
|
||||
schemas:
|
||||
NewRole:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
example: bb7edb32-2eac-4aad-aebe-ed96fe073879
|
||||
description: Role unique identifier.
|
||||
name:
|
||||
type: string
|
||||
description: Role's name.
|
||||
example: "roleName"
|
||||
entity_id:
|
||||
type: string
|
||||
format: uuid
|
||||
example: bb7edb32-2eac-4aad-aebe-ed96fe073879
|
||||
description: Entity unique identifier.
|
||||
created_by:
|
||||
type: string
|
||||
format: uuid
|
||||
example: bb7edb32-2eac-4aad-aebe-ed96fe073879
|
||||
description: Role creator unique identifier.
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
example: "2019-11-26 13:31:52"
|
||||
description: Time when the channel was created.
|
||||
updated_by:
|
||||
type: string
|
||||
format: uuid
|
||||
example: ""
|
||||
description: Role updater unique identifier.
|
||||
updated_at:
|
||||
type: string
|
||||
format: date-time
|
||||
example: ""
|
||||
description: Time when the channel was created.
|
||||
|
||||
Role:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
example: bb7edb32-2eac-4aad-aebe-ed96fe073879
|
||||
description: Role unique identifier.
|
||||
name:
|
||||
type: string
|
||||
description: Role's name.
|
||||
example: "roleName"
|
||||
entity_id:
|
||||
type: string
|
||||
format: uuid
|
||||
example: bb7edb32-2eac-4aad-aebe-ed96fe073879
|
||||
description: Entity unique identifier.
|
||||
created_by:
|
||||
type: string
|
||||
format: uuid
|
||||
example: bb7edb32-2eac-4aad-aebe-ed96fe073879
|
||||
description: Role creator unique identifier.
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
example: "2019-11-26 13:31:52"
|
||||
description: Time when the channel was created.
|
||||
updated_by:
|
||||
type: string
|
||||
format: uuid
|
||||
example: bb7edb32-2eac-4aad-aebe-ed96fe073879
|
||||
description: Role updater unique identifier.
|
||||
updated_at:
|
||||
type: string
|
||||
format: date-time
|
||||
example: "2019-11-26 13:31:52"
|
||||
description: Time when the channel was created.
|
||||
|
||||
CreateRoleObj:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: Role's name.
|
||||
example: "roleName"
|
||||
optional_actions:
|
||||
type: array
|
||||
description: List of optional actions.
|
||||
items:
|
||||
type: string
|
||||
example:
|
||||
[
|
||||
"read",
|
||||
"update",
|
||||
]
|
||||
optional_members:
|
||||
type: array
|
||||
minItems: 0
|
||||
description: List of optional members.
|
||||
items:
|
||||
type: string
|
||||
example:
|
||||
[
|
||||
"5dc1ce4b-7cc9-4f12-98a6-9d74cc4980bb",
|
||||
"c01ed106-e52d-4aa4-bed3-39f360177cfa",
|
||||
]
|
||||
|
||||
UpdateRoleObj:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: Role's name.
|
||||
|
||||
RolesPage:
|
||||
type: object
|
||||
properties:
|
||||
roles:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Role'
|
||||
description: List of roles.
|
||||
total:
|
||||
type: integer
|
||||
description: Total number of roles.
|
||||
example: 1
|
||||
offset:
|
||||
type: integer
|
||||
description: Number of items to skip during retrieval.
|
||||
limit:
|
||||
type: integer
|
||||
example: 10
|
||||
description: Maximum number of items to return in one page.
|
||||
|
||||
EntityMembersPage:
|
||||
type: object
|
||||
properties:
|
||||
groups:
|
||||
type: array
|
||||
minItems: 0
|
||||
uniqueItems: true
|
||||
items:
|
||||
$ref: "#/components/schemas/EntityMembersObj"
|
||||
total:
|
||||
type: integer
|
||||
example: 1
|
||||
description: Total number of items.
|
||||
offset:
|
||||
type: integer
|
||||
description: Number of items to skip during retrieval.
|
||||
limit:
|
||||
type: integer
|
||||
example: 10
|
||||
description: Maximum number of items to return in one page.
|
||||
required:
|
||||
- groups
|
||||
- total
|
||||
- offset
|
||||
|
||||
RoleActionsObj:
|
||||
type: object
|
||||
properties:
|
||||
actions:
|
||||
type: array
|
||||
description: List of actions to be added to a role.
|
||||
items:
|
||||
type: string
|
||||
example:
|
||||
[
|
||||
"read",
|
||||
"update",
|
||||
]
|
||||
|
||||
RoleMembersObj:
|
||||
type: object
|
||||
properties:
|
||||
members:
|
||||
type: array
|
||||
description: List of members to be added to a role.
|
||||
items:
|
||||
type: string
|
||||
example:
|
||||
[
|
||||
"5dc1ce4b-7cc9-4f12-98a6-9d74cc4980bb",
|
||||
"c01ed106-e52d-4aa4-bed3-39f360177cfa",
|
||||
]
|
||||
|
||||
EntityMembersObj:
|
||||
type: object
|
||||
properties:
|
||||
members:
|
||||
type: array
|
||||
description: List of members with assigned roles and actions.
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
description: Unique identifier of the member.
|
||||
roles:
|
||||
type: array
|
||||
description: List of roles assigned to the member.
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
description: Unique identifier of the role.
|
||||
name:
|
||||
type: string
|
||||
description: Name of the role.
|
||||
actions:
|
||||
type: array
|
||||
description: List of actions the member can perform.
|
||||
items:
|
||||
type: string
|
||||
access_type:
|
||||
type: string
|
||||
description: Type of access granted.
|
||||
enum: [read, write, admin] # Adjust based on your actual access types.
|
||||
example:
|
||||
members:
|
||||
- id: "5dc1ce4b-7cc9-4f12-98a6-9d74cc4980bb"
|
||||
roles:
|
||||
- id: "a1b2c3d4-e5f6-7890-1234-56789abcdef0"
|
||||
name: "Admin"
|
||||
actions: ["create", "update", "delete"]
|
||||
access_type: "admin"
|
||||
- id: "c01ed106-e52d-4aa4-bed3-39f360177cfa"
|
||||
roles:
|
||||
- id: "b2c3d4e5-f678-9012-3456-789abcdef012"
|
||||
name: "Editor"
|
||||
actions: ["read", "update"]
|
||||
access_type: "write"
|
||||
|
||||
|
||||
AvailableActionsObj:
|
||||
type: object
|
||||
properties:
|
||||
available_actions:
|
||||
type: array
|
||||
description: List of all available actions.
|
||||
items:
|
||||
type: string
|
||||
example:
|
||||
[
|
||||
"read",
|
||||
"update",
|
||||
]
|
||||
|
||||
parameters:
|
||||
RoleName:
|
||||
name: roleName
|
||||
description: Role's name.
|
||||
in: path
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
example: "roleName"
|
||||
RoleID:
|
||||
name: roleID
|
||||
description: Role ID.
|
||||
in: path
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
example: "roleID"
|
||||
RoleIDQuery:
|
||||
name: role_id
|
||||
description: Filter by role ID.
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
required: false
|
||||
example: bb7edb32-2eac-4aad-aebe-ed96fe073879
|
||||
RoleNameQuery:
|
||||
name: role_name
|
||||
description: Filter by role name.
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
required: false
|
||||
example: admin
|
||||
ActionsQuery:
|
||||
name: actions
|
||||
description: Filter by actions. Multiple actions can be specified separated by comma.
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
required: false
|
||||
example: "action1,action2"
|
||||
|
||||
requestBodies:
|
||||
CreateRoleReq:
|
||||
description: JSON- formatted object decsribing a new role to be created.
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/CreateRoleObj'
|
||||
|
||||
UpdateRoleReq:
|
||||
description: JSON- formatted object decsribing a role to be updated.
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/UpdateRoleObj'
|
||||
|
||||
AddRoleActionsReq:
|
||||
description: JSON- formatted object decsribing an action to be added to a role.
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RoleActionsObj'
|
||||
|
||||
AddRoleMembersReq:
|
||||
description: JSON- formatted object decsribing a member to be added to a role.
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RoleMembersObj'
|
||||
|
||||
responses:
|
||||
CreateRoleRes:
|
||||
description: Role created successfully.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/NewRole'
|
||||
|
||||
ListRolesRes:
|
||||
description: Role retrieved successfully.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RolesPage'
|
||||
|
||||
GetRoleRes:
|
||||
description: Role retrieved successfully.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Role'
|
||||
|
||||
AddRoleActionsRes:
|
||||
description: Action added to role successfully.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RoleActionsObj'
|
||||
|
||||
ListRoleActionsRes:
|
||||
description: Role actions retrieved successfully.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RoleActionsObj'
|
||||
|
||||
AddRoleMembersRes:
|
||||
description: Member added to role successfully.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RoleMembersObj'
|
||||
|
||||
ListRoleMembersRes:
|
||||
description: Role members retrieved successfully.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RoleMembersObj'
|
||||
|
||||
ListAvailableActionsRes:
|
||||
description: Available actions retrieved successfully.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/AvailableActionsObj'
|
||||
|
||||
|
||||
ListEntityMembersRes:
|
||||
description: Entity members retrieved successfully.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/EntityMembersObj'
|
||||
File diff suppressed because it is too large
Load Diff
-2625
File diff suppressed because it is too large
Load Diff
-211
@@ -1,211 +0,0 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package magistrala;
|
||||
option go_package = "./magistrala";
|
||||
|
||||
// AuthzService is a service that provides authentication and authorization
|
||||
// functionalities for the things service.
|
||||
service AuthzService {
|
||||
// Authorize checks if the subject is authorized to perform
|
||||
// the action on the object.
|
||||
rpc Authorize(AuthorizeReq) returns (AuthorizeRes) {}
|
||||
}
|
||||
|
||||
// AuthService is a service that provides authentication and authorization
|
||||
// functionalities for the users service.
|
||||
service AuthService {
|
||||
rpc Issue(IssueReq) returns (Token) {}
|
||||
rpc Refresh(RefreshReq) returns (Token) {}
|
||||
rpc Identify(IdentityReq) returns (IdentityRes) {}
|
||||
rpc Authorize(AuthorizeReq) returns (AuthorizeRes) {}
|
||||
rpc AddPolicy(AddPolicyReq) returns (AddPolicyRes) {}
|
||||
rpc AddPolicies(AddPoliciesReq) returns (AddPoliciesRes) {}
|
||||
rpc DeletePolicy(DeletePolicyReq) returns (DeletePolicyRes) {}
|
||||
rpc DeletePolicies(DeletePoliciesReq) returns (DeletePoliciesRes) {}
|
||||
rpc ListObjects(ListObjectsReq) returns (ListObjectsRes) {}
|
||||
rpc ListAllObjects(ListObjectsReq) returns (ListObjectsRes) {}
|
||||
rpc CountObjects(CountObjectsReq) returns (CountObjectsRes) {}
|
||||
rpc ListSubjects(ListSubjectsReq) returns (ListSubjectsRes) {}
|
||||
rpc ListAllSubjects(ListSubjectsReq) returns (ListSubjectsRes) {}
|
||||
rpc CountSubjects(CountSubjectsReq) returns (CountSubjectsRes) {}
|
||||
rpc ListPermissions(ListPermissionsReq) returns (ListPermissionsRes) {}
|
||||
}
|
||||
|
||||
// If a token is not carrying any information itself, the type
|
||||
// field can be used to determine how to validate the token.
|
||||
// Also, different tokens can be encoded in different ways.
|
||||
message Token {
|
||||
string accessToken = 1;
|
||||
optional string refreshToken = 2;
|
||||
string accessType = 3;
|
||||
}
|
||||
|
||||
message IdentityReq {
|
||||
string token = 1;
|
||||
}
|
||||
|
||||
message IdentityRes {
|
||||
string id = 1; // IMPROVEMENT NOTE: change name from "id" to "subject" , sub in jwt = user id + domain id //
|
||||
string user_id = 2; // user id
|
||||
string domain_id = 3; // domain id
|
||||
}
|
||||
|
||||
message IssueReq {
|
||||
string user_id = 1;
|
||||
optional string domain_id = 2;
|
||||
uint32 type = 3;
|
||||
string oauth_provider = 4;
|
||||
string oauth_access_token = 5;
|
||||
string oauth_refresh_token = 6;
|
||||
}
|
||||
|
||||
message RefreshReq {
|
||||
string refresh_token = 1;
|
||||
optional string domain_id = 2;
|
||||
}
|
||||
|
||||
message AuthorizeReq {
|
||||
string domain = 1; // Domain
|
||||
string subject_type = 2; // Thing or User
|
||||
string subject_kind = 3; // ID or Token
|
||||
string subject_relation = 4; // Subject relation
|
||||
string subject = 5; // Subject value (id or token, depending on kind)
|
||||
string relation = 6; // Relation to filter
|
||||
string permission = 7; // Action
|
||||
string object = 8; // Object ID
|
||||
string object_type = 9; // Thing, User, Group
|
||||
}
|
||||
|
||||
message AuthorizeRes {
|
||||
bool authorized = 1;
|
||||
string id = 2;
|
||||
}
|
||||
|
||||
message AddPolicyReq {
|
||||
string domain = 1;
|
||||
string subject_type = 2;
|
||||
string subject_relation = 3;
|
||||
string subject_kind = 4;
|
||||
string subject = 5;
|
||||
string relation = 6;
|
||||
string permission = 7;
|
||||
string object = 8;
|
||||
string object_kind = 9;
|
||||
string object_type = 10;
|
||||
}
|
||||
|
||||
message AddPoliciesReq{
|
||||
repeated AddPolicyReq addPoliciesReq= 1;
|
||||
}
|
||||
|
||||
message AddPolicyRes { bool added = 1; }
|
||||
|
||||
message AddPoliciesRes { bool added = 1; }
|
||||
|
||||
message DeletePolicyReq {
|
||||
string domain = 1;
|
||||
string subject_type = 2;
|
||||
string subject_relation = 3;
|
||||
string subject_kind = 4;
|
||||
string subject = 5;
|
||||
string relation = 6;
|
||||
string permission = 7;
|
||||
string object = 8;
|
||||
string object_kind = 9;
|
||||
string object_type = 10;
|
||||
}
|
||||
|
||||
message DeletePoliciesReq {
|
||||
repeated DeletePolicyReq deletePoliciesReq = 1;
|
||||
}
|
||||
|
||||
message DeletePolicyRes { bool deleted = 1; }
|
||||
|
||||
message DeletePoliciesRes { bool deleted = 1; }
|
||||
|
||||
message ListObjectsReq {
|
||||
string domain = 1;
|
||||
string subject_type = 2;
|
||||
string subject_relation = 3;
|
||||
string subject = 4;
|
||||
string relation = 5;
|
||||
string permission = 6;
|
||||
string object = 7;
|
||||
string object_type = 8;
|
||||
string nextPageToken = 9;
|
||||
int32 limit = 10;
|
||||
}
|
||||
|
||||
message ListObjectsRes {
|
||||
repeated string policies = 1;
|
||||
string nextPageToken = 2;
|
||||
}
|
||||
|
||||
message CountObjectsReq {
|
||||
string domain = 1;
|
||||
string subject_type = 2;
|
||||
string subject_relation = 3;
|
||||
string subject = 4;
|
||||
string relation = 5;
|
||||
string permission = 6;
|
||||
string object = 7;
|
||||
string object_type = 8;
|
||||
string nextPageToken = 9;
|
||||
}
|
||||
|
||||
message CountObjectsRes { int64 count = 1; }
|
||||
|
||||
message ListSubjectsReq {
|
||||
string domain = 1;
|
||||
string subject_type = 2;
|
||||
string subject_relation = 3;
|
||||
string subject = 4;
|
||||
string relation = 5;
|
||||
string permission = 6;
|
||||
string object = 7;
|
||||
string object_type = 8;
|
||||
string nextPageToken = 9;
|
||||
int32 limit = 10;
|
||||
}
|
||||
|
||||
message ListSubjectsRes {
|
||||
repeated string policies = 1;
|
||||
string nextPageToken = 2;
|
||||
}
|
||||
|
||||
message CountSubjectsReq {
|
||||
string domain = 1;
|
||||
string subject_type = 2;
|
||||
string subject_relation = 3;
|
||||
string subject = 4;
|
||||
string relation = 5;
|
||||
string permission = 6;
|
||||
string object = 7;
|
||||
string object_type = 8;
|
||||
string nextPageToken = 9;
|
||||
}
|
||||
|
||||
message CountSubjectsRes { int64 count = 1; }
|
||||
|
||||
message ListPermissionsReq {
|
||||
string domain = 1;
|
||||
string subject_type = 2;
|
||||
string subject_relation = 3;
|
||||
string subject = 4;
|
||||
string object = 5;
|
||||
string object_type = 6;
|
||||
repeated string filter_permissions = 7;
|
||||
}
|
||||
|
||||
message ListPermissionsRes {
|
||||
string domain = 1;
|
||||
string subject_type = 2;
|
||||
string subject_relation = 3;
|
||||
string subject = 4;
|
||||
string object = 5;
|
||||
string object_type = 6;
|
||||
repeated string permissions = 7;
|
||||
}
|
||||
+331
-41
@@ -1,6 +1,6 @@
|
||||
# Auth - Authentication and Authorization service
|
||||
|
||||
Auth service provides authentication features as an API for managing authentication keys as well as administering groups of entities - `things` and `users`.
|
||||
Auth service provides authentication features as an API for managing authentication keys as well as administering groups of entities - `clients` and `users`.
|
||||
|
||||
## Authentication
|
||||
|
||||
@@ -25,7 +25,7 @@ Authentication keys are represented and distributed by the corresponding [JWT](j
|
||||
|
||||
User keys are issued when user logs in. Each user request (other than `registration` and `login`) contains user key that is used to authenticate the user.
|
||||
|
||||
API keys are similar to the User keys. The main difference is that API keys have configurable expiration time. If no time is set, the key will never expire. For that reason, API keys are _the only key type that can be revoked_. This also means that, despite being used as a JWT, it requires a query to the database to validate the API key. The user with API key can perform all the same actions as the user with login key (can act on behalf of the user for Thing, Channel, or user profile management), _except issuing new API keys_.
|
||||
API keys are similar to the User keys. The main difference is that API keys have configurable expiration time. If no time is set, the key will never expire. For that reason, API keys are _the only key type that can be revoked_. This also means that, despite being used as a JWT, it requires a query to the database to validate the API key. The user with API key can perform all the same actions as the user with login key (can act on behalf of the user for Client, Channel, or user profile management), _except issuing new API keys_.
|
||||
|
||||
Recovery key is the password recovery key. It's short-lived token used for password recovery process.
|
||||
|
||||
@@ -40,7 +40,7 @@ The following actions are supported:
|
||||
|
||||
## Domains
|
||||
|
||||
Domains are used to group users and things. Each domain has a unique alias that is used to identify the domain. Domains are used to group users and their entities.
|
||||
Domains are used to group users and clients. Each domain has a unique `route` that is associated with the domain. Domains are used to group users and their entities.
|
||||
|
||||
Domain consists of the following fields:
|
||||
|
||||
@@ -48,7 +48,7 @@ Domain consists of the following fields:
|
||||
- Name - name of the domain
|
||||
- Tags - array of tags
|
||||
- Metadata - Arbitrary, object-encoded domain's data
|
||||
- Alias - unique alias of the domain
|
||||
- Route - unique route of the domain used in messaging
|
||||
- CreatedAt - timestamp at which the domain is created
|
||||
- UpdatedAt - timestamp at which the domain is updated
|
||||
- UpdatedBy - user that updated the domain
|
||||
@@ -59,44 +59,54 @@ Domain consists of the following fields:
|
||||
|
||||
The service is configured using the environment variables presented in the following table. Note that any unset variables will be replaced with their default values.
|
||||
|
||||
| Variable | Description | Default |
|
||||
| ------------------------------ | ----------------------------------------------------------------------- | -------------------------------- |
|
||||
| MG_AUTH_LOG_LEVEL | Log level for the Auth service (debug, info, warn, error) | info |
|
||||
| MG_AUTH_DB_HOST | Database host address | localhost |
|
||||
| MG_AUTH_DB_PORT | Database host port | 5432 |
|
||||
| MG_AUTH_DB_USER | Database user | magistrala |
|
||||
| MG_AUTH_DB_PASSWORD | Database password | magistrala |
|
||||
| MG_AUTH_DB_NAME | Name of the database used by the service | auth |
|
||||
| MG_AUTH_DB_SSL_MODE | Database connection SSL mode (disable, require, verify-ca, verify-full) | disable |
|
||||
| MG_AUTH_DB_SSL_CERT | Path to the PEM encoded certificate file | "" |
|
||||
| MG_AUTH_DB_SSL_KEY | Path to the PEM encoded key file | "" |
|
||||
| MG_AUTH_DB_SSL_ROOT_CERT | Path to the PEM encoded root certificate file | "" |
|
||||
| MG_AUTH_HTTP_HOST | Auth service HTTP host | "" |
|
||||
| MG_AUTH_HTTP_PORT | Auth service HTTP port | 8189 |
|
||||
| MG_AUTH_HTTP_SERVER_CERT | Path to the PEM encoded HTTP server certificate file | "" |
|
||||
| MG_AUTH_HTTP_SERVER_KEY | Path to the PEM encoded HTTP server key file | "" |
|
||||
| MG_AUTH_GRPC_HOST | Auth service gRPC host | "" |
|
||||
| MG_AUTH_GRPC_PORT | Auth service gRPC port | 8181 |
|
||||
| MG_AUTH_GRPC_SERVER_CERT | Path to the PEM encoded gRPC server certificate file | "" |
|
||||
| MG_AUTH_GRPC_SERVER_KEY | Path to the PEM encoded gRPC server key file | "" |
|
||||
| MG_AUTH_GRPC_SERVER_CA_CERTS | Path to the PEM encoded gRPC server CA certificate file | "" |
|
||||
| MG_AUTH_GRPC_CLIENT_CA_CERTS | Path to the PEM encoded gRPC client CA certificate file | "" |
|
||||
| MG_AUTH_SECRET_KEY | String used for signing tokens | secret |
|
||||
| MG_AUTH_ACCESS_TOKEN_DURATION | The access token expiration period | 1h |
|
||||
| MG_AUTH_REFRESH_TOKEN_DURATION | The refresh token expiration period | 24h |
|
||||
| MG_AUTH_INVITATION_DURATION | The invitation token expiration period | 168h |
|
||||
| MG_SPICEDB_HOST | SpiceDB host address | localhost |
|
||||
| MG_SPICEDB_PORT | SpiceDB host port | 50051 |
|
||||
| MG_SPICEDB_PRE_SHARED_KEY | SpiceDB pre-shared key | 12345678 |
|
||||
| MG_SPICEDB_SCHEMA_FILE | Path to SpiceDB schema file | ./docker/spicedb/schema.zed |
|
||||
| MG_JAEGER_URL | Jaeger server URL | <http://jaeger:14268/api/traces> |
|
||||
| MG_JAEGER_TRACE_RATIO | Jaeger sampling ratio | 1.0 |
|
||||
| MG_SEND_TELEMETRY | Send telemetry to magistrala call home server | true |
|
||||
| MG_AUTH_ADAPTER_INSTANCE_ID | Adapter instance ID | "" |
|
||||
| Variable | Description | Default |
|
||||
| :------------------------------- | :----------------------------------------------------------------------------------- | :----------------------------- |
|
||||
| `MG_AUTH_LOG_LEVEL` | Log level for the Auth service (debug, info, warn, error) | info |
|
||||
| `MG_AUTH_DB_HOST` | Database host address | localhost |
|
||||
| `MG_AUTH_DB_PORT` | Database host port | 5432 |
|
||||
| `MG_AUTH_DB_USER` | Database user | magistrala |
|
||||
| `MG_AUTH_DB_PASSWORD` | Database password | magistrala |
|
||||
| `MG_AUTH_DB_NAME` | Name of the database used by the service | auth |
|
||||
| `MG_AUTH_DB_SSL_MODE` | Database connection SSL mode (disable, require, verify-ca, verify-full) | disable |
|
||||
| `MG_AUTH_DB_SSL_CERT` | Path to the PEM encoded certificate file | "" |
|
||||
| `MG_AUTH_DB_SSL_KEY` | Path to the PEM encoded key file | "" |
|
||||
| `MG_AUTH_DB_SSL_ROOT_CERT` | Path to the PEM encoded root certificate file | "" |
|
||||
| `MG_AUTH_HTTP_HOST` | Auth service HTTP host | "" |
|
||||
| `MG_AUTH_HTTP_PORT` | Auth service HTTP port | 8189 |
|
||||
| `MG_AUTH_HTTP_SERVER_CERT` | Path to the PEM encoded HTTP server certificate file | "" |
|
||||
| `MG_AUTH_HTTP_SERVER_KEY` | Path to the PEM encoded HTTP server key file | "" |
|
||||
| `MG_AUTH_GRPC_HOST` | Auth service gRPC host | "" |
|
||||
| `MG_AUTH_GRPC_PORT` | Auth service gRPC port | 8181 |
|
||||
| `MG_AUTH_GRPC_SERVER_CERT` | Path to the PEM encoded gRPC server certificate file | "" |
|
||||
| `MG_AUTH_GRPC_SERVER_KEY` | Path to the PEM encoded gRPC server key file | "" |
|
||||
| `MG_AUTH_GRPC_SERVER_CA_CERTS` | Path to the PEM encoded gRPC server CA certificate file | "" |
|
||||
| `MG_AUTH_GRPC_CLIENT_CA_CERTS` | Path to the PEM encoded gRPC client CA certificate file | "" |
|
||||
| `MG_AUTH_SECRET_KEY` | String used for signing tokens | secret |
|
||||
| `MG_AUTH_ACCESS_TOKEN_DURATION` | The access token expiration period | 1h |
|
||||
| `MG_AUTH_REFRESH_TOKEN_DURATION` | The refresh token expiration period | 24h |
|
||||
| `MG_AUTH_INVITATION_DURATION` | The invitation token expiration period | 168h |
|
||||
| `MG_AUTH_CACHE_URL` | Redis URL for caching PAT scopes | redis://localhost:6379/0 |
|
||||
| `MG_AUTH_CACHE_KEY_DURATION` | Duration for which PAT scope cache keys are valid | 10m |
|
||||
| `MG_SPICEDB_HOST` | SpiceDB host address | localhost |
|
||||
| `MG_SPICEDB_PORT` | SpiceDB host port | 50051 |
|
||||
| `MG_SPICEDB_PRE_SHARED_KEY` | SpiceDB pre-shared key | 12345678 |
|
||||
| `MG_SPICEDB_SCHEMA_FILE` | Path to SpiceDB schema file | ./docker/spicedb/schema.zed |
|
||||
| `MG_JAEGER_URL` | Jaeger server URL | <http://jaeger:4318/v1/traces> |
|
||||
| `MG_JAEGER_TRACE_RATIO` | Jaeger sampling ratio | 1.0 |
|
||||
| `MG_SEND_TELEMETRY` | Send telemetry to magistrala call home server | true |
|
||||
| `MG_ADAPTER_INSTANCE_ID` | Adapter instance ID | "" |
|
||||
| `MG_CALLOUT_URLS` | Comma-separated list of callout URLs | "" |
|
||||
| `MG_CALLOUT_METHOD` | Callout method | POST |
|
||||
| `MG_CALLOUT_TLS_VERIFICATION` | Enable TLS verification for callouts | true |
|
||||
| `MG_CALLOUT_TIMEOUT` | Callout timeout | 10s |
|
||||
| `MG_CALLOUT_CA_CERT` | Path to CA certificate file | "" |
|
||||
| `MG_CALLOUT_CERT` | Path to client certificate file | "" |
|
||||
| `MG_CALLOUT_KEY` | Path to client key file | "" |
|
||||
| `MG_CALLOUT_OPERATIONS` | Invoke callout if the authorization permission matches any of the given permissions. | "" |
|
||||
|
||||
## Deployment
|
||||
|
||||
The service itself is distributed as Docker container. Check the [`auth`](https://github.com/absmach/magistrala/blob/master/docker/docker-compose.yml) service section in docker-compose to see how service is deployed.
|
||||
The service itself is distributed as Docker container. Check the [`auth`](https://github.com/absmach/magistrala/blob/main/docker/docker-compose.yaml) service section in docker-compose file to see how service is deployed.
|
||||
|
||||
Running this service outside of container requires working instance of the postgres database, SpiceDB, and Jaeger server.
|
||||
To start the service outside of the container, execute the following shell script:
|
||||
@@ -146,14 +156,294 @@ MG_JAEGER_URL=http://localhost:14268/api/traces \
|
||||
MG_JAEGER_TRACE_RATIO=1.0 \
|
||||
MG_SEND_TELEMETRY=true \
|
||||
MG_AUTH_ADAPTER_INSTANCE_ID="" \
|
||||
MG_CALLOUT_URLS="" \
|
||||
MG_CALLOUT_METHOD="POST" \
|
||||
MG_CALLOUT_TLS_VERIFICATION=true \
|
||||
$GOBIN/magistrala-auth
|
||||
```
|
||||
|
||||
Setting `MG_AUTH_HTTP_SERVER_CERT` and `MG_AUTH_HTTP_SERVER_KEY` will enable TLS against the service. The service expects a file in PEM format for both the certificate and the key.
|
||||
Setting `MG_AUTH_GRPC_SERVER_CERT` and `MG_AUTH_GRPC_SERVER_KEY` will enable TLS against the service. The service expects a file in PEM format for both the certificate and the key. Setting `MG_AUTH_GRPC_SERVER_CA_CERTS` will enable TLS against the service trusting only those CAs that are provided. The service expects a file in PEM format of trusted CAs. Setting `MG_AUTH_GRPC_CLIENT_CA_CERTS` will enable TLS against the service trusting only those CAs that are provided. The service expects a file in PEM format of trusted CAs.
|
||||
|
||||
## Personal Access Tokens (PATs)
|
||||
|
||||
Personal Access Tokens (PATs) provide a secure way to authenticate with Magistrala APIs without using your primary credentials. They are particularly useful for automation, CI/CD pipelines, and integrating with third-party services.
|
||||
|
||||
### Overview
|
||||
|
||||
PATs in Magistrala are designed with the following features:
|
||||
|
||||
- **Scoped Access**: Each token can be limited to specific operations on specific resources
|
||||
- **Expiration Control**: Set custom expiration times for tokens
|
||||
- **Revocable**: Tokens can be revoked at any time
|
||||
- **Auditable**: Track when tokens were last used
|
||||
- **Secure**: Tokens are stored as hashes, not in plaintext
|
||||
|
||||
### Token Structure
|
||||
|
||||
A PAT consists of three parts separated by underscores:
|
||||
|
||||
```bash
|
||||
pat_<encoded-user-and-pat-id>_<random-string>
|
||||
```
|
||||
|
||||
Where:
|
||||
|
||||
- `pat` is a fixed prefix
|
||||
- `<encoded-user-and-pat-id>` is a base64-encoded combination of the user ID and PAT ID
|
||||
- `<random-string>` is a randomly generated string for additional security
|
||||
|
||||
### PAT Operations
|
||||
|
||||
Magistrala supports the following operations for PATs:
|
||||
|
||||
| Operation | Description |
|
||||
| ----------- | ------------------------------------ |
|
||||
| `create` | Create a new resource |
|
||||
| `read` | Read/view a resource |
|
||||
| `list` | List resources |
|
||||
| `update` | Update/modify a resource |
|
||||
| `delete` | Delete a resource |
|
||||
| `share` | Share a resource with others |
|
||||
| `unshare` | Remove sharing permissions |
|
||||
| `publish` | Publish messages to a channel |
|
||||
| `subscribe` | Subscribe to messages from a channel |
|
||||
|
||||
### Entity Types
|
||||
|
||||
PATs can be scoped to the following entity types:
|
||||
|
||||
| Entity Type | Description |
|
||||
| ------------ | ---------------------- |
|
||||
| `groups` | User groups |
|
||||
| `channels` | Communication channels |
|
||||
| `clients` | Client applications |
|
||||
| `domains` | Organizational domains |
|
||||
| `users` | User accounts |
|
||||
| `dashboards` | Dashboard interfaces |
|
||||
| `messages` | Message content |
|
||||
|
||||
### API Examples
|
||||
|
||||
#### Creating a PAT
|
||||
|
||||
```bash
|
||||
curl --location 'http://localhost:9001/pats' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--header 'Authorization: Bearer <access_token>' \
|
||||
--data '{
|
||||
"name": "test pat",
|
||||
"description": "testing pat",
|
||||
"duration": "24h"
|
||||
}'
|
||||
```
|
||||
|
||||
Response:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "a2500226-95dc-4285-87e2-e693e4a0a976",
|
||||
"user_id": "user123",
|
||||
"name": "pat 1",
|
||||
"description": "for creating any client or channel",
|
||||
"secret": "pat_dXNlcjEyM19hMjUwMDIyNi05NWRjLTQyODUtODdlMi1lNjkzZTRhMGE5NzY=_randomstring...",
|
||||
"issued_at": "2025-02-27T11:20:59Z",
|
||||
"expires_at": "2025-02-28T11:20:59Z"
|
||||
}
|
||||
```
|
||||
|
||||
#### Adding Scopes to a PAT
|
||||
|
||||
```bash
|
||||
curl --location --request PATCH 'http://localhost:9001/pats/a2500226-95dc-4285-87e2-e693e4a0a976/scope/add' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--header 'Authorization: Bearer <access_token>' \
|
||||
--data '{
|
||||
"scopes": [
|
||||
{
|
||||
"optional_domain_id": "c16c980a-9d4c-4793-8fb2-c81304cf1d9f",
|
||||
"entity_type": "clients",
|
||||
"operation": "create",
|
||||
"entity_id": "*"
|
||||
},
|
||||
{
|
||||
"optional_domain_id": "c16c980a-9d4c-4793-8fb2-c81304cf1d9f",
|
||||
"entity_type": "channels",
|
||||
"operation": "create",
|
||||
"entity_id": "cfbc6936-5748-4339-a8ef-37b64b02bc96"
|
||||
},
|
||||
{
|
||||
"entity_type": "dashboards",
|
||||
"optional_domain_id": "c16c980a-9d4c-4793-8fb2-c81304cf1d9f",
|
||||
"operation": "read",
|
||||
"entity_id": "*"
|
||||
}
|
||||
]
|
||||
}'
|
||||
```
|
||||
|
||||
#### Listing PATs
|
||||
|
||||
```bash
|
||||
curl --location 'http://localhost:9001/pats' \
|
||||
--header 'Authorization: Bearer <access_token>'
|
||||
```
|
||||
|
||||
#### Listing Scopes for a PAT
|
||||
|
||||
```bash
|
||||
curl --location 'http://localhost:9001/pats/a2500226-95dc-4285-87e2-e693e4a0a976/scopes' \
|
||||
--header 'Authorization: Bearer <access_token>'
|
||||
```
|
||||
|
||||
#### Revoking a PAT
|
||||
|
||||
```bash
|
||||
curl --location --request PATCH 'http://localhost:9001/pats/a2500226-95dc-4285-87e2-e693e4a0a976/revoke' \
|
||||
--header 'Authorization: Bearer <access_token>'
|
||||
```
|
||||
|
||||
#### Resetting a PAT Secret
|
||||
|
||||
```bash
|
||||
curl --location --request PATCH 'http://localhost:9001/pats/a2500226-95dc-4285-87e2-e693e4a0a976/reset' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--header 'Authorization: Bearer <access_token>' \
|
||||
--data '{
|
||||
"duration": "720h"
|
||||
}'
|
||||
```
|
||||
|
||||
### Using PATs for Authentication
|
||||
|
||||
When making API requests, include the PAT in the Authorization header:
|
||||
|
||||
```bash
|
||||
Authorization: Bearer pat_<encoded-user-and-pat-id>_<random-string>
|
||||
```
|
||||
|
||||
#### Example: Creating a Client Using PAT
|
||||
|
||||
```bash
|
||||
curl --location 'http://localhost:9006/c16c980a-9d4c-4793-8fb2-c81304cf1d9f/clients' \
|
||||
--header 'accept: application/json' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--header 'Authorization: Bearer pat_etKoiXKTR6a0zdgsBHC00qJQAiaV3EKFh+Lmk+SgqXY=_u7@5fyjgti9V@#Bw^bS*SPmX3OnH=HTvKwmIbxIuyBjoI|6FASo9egjKD^u-M$b|2Dpt3CXZtv&4k+hmYYjk&C$57AV59P%-iDV0' \
|
||||
--data '{
|
||||
"name": "test client",
|
||||
"tags": [
|
||||
"tag1",
|
||||
"tag2"
|
||||
],
|
||||
"metadata":{"units":"km"},
|
||||
"status": "enabled"
|
||||
}'
|
||||
```
|
||||
|
||||
This example shows how to create a client in a specific domain (`c16c980a-9d4c-4793-8fb2-c81304cf1d9f`) using a PAT for authentication. The PAT must have the appropriate scope (e.g., `clients` entity type with `create` operation) for this domain.
|
||||
|
||||
### Wildcard Entity IDs
|
||||
|
||||
When defining scopes for PATs, you can use the wildcard character `*` for the `entity_id` field to grant permissions for all entities of a specific type. This is particularly useful for automation tasks that need to operate on multiple resources.
|
||||
|
||||
For example:
|
||||
|
||||
- `"entity_id": "*"` - Grants permission for all entities of the specified type
|
||||
- `"entity_id": "specific-id"` - Grants permission only for the entity with the specified ID
|
||||
|
||||
Using wildcards should be done carefully, as they grant broader permissions. Always follow the principle of least privilege by granting only the permissions necessary for the intended use case.
|
||||
|
||||
### Scope Examples
|
||||
|
||||
#### Allow Creating Any Client in a Domain
|
||||
|
||||
```json
|
||||
{
|
||||
"optional_domain_id": "domain_id",
|
||||
"entity_type": "clients",
|
||||
"operation": "create",
|
||||
"entity_id": "*"
|
||||
}
|
||||
```
|
||||
|
||||
This scope allows the PAT to create any client within the specified domain. The wildcard `*` for `entity_id` means the token can create any client, not just a specific one.
|
||||
|
||||
#### Allow Publishing to a Specific Channel
|
||||
|
||||
```json
|
||||
{
|
||||
"optional_domain_id": "domain_id",
|
||||
"entity_type": "channels",
|
||||
"operation": "publish",
|
||||
"entity_id": "channel_id"
|
||||
}
|
||||
```
|
||||
|
||||
This scope restricts the PAT to only publish to a specific channel (`channel_id`) within the specified domain. No wildcard is used, so the permission is limited to just this one channel.
|
||||
|
||||
#### Allow Reading All Dashboards
|
||||
|
||||
```json
|
||||
{
|
||||
"optional_domain_id": "domain_id",
|
||||
"entity_type": "dashboards",
|
||||
"operation": "read",
|
||||
"entity_id": "*"
|
||||
}
|
||||
```
|
||||
|
||||
This scope allows the PAT to read all dashboards within the specified domain. The wildcard `*` for `entity_id` means the token can read any dashboard in that domain.
|
||||
|
||||
### Best Practices
|
||||
|
||||
1. **Limit Scope**: Always use the principle of least privilege when creating PATs
|
||||
2. **Set Expirations**: Use reasonable expiration times for tokens
|
||||
3. **Rotate Regularly**: Reset token secrets periodically
|
||||
4. **Audit Usage**: Monitor when tokens are used
|
||||
5. **Revoke Unused**: Remove tokens that are no longer needed
|
||||
|
||||
### Implementation Details
|
||||
|
||||
PATs are stored in the database with the following schema:
|
||||
|
||||
```sql
|
||||
CREATE TABLE IF NOT EXISTS pats (
|
||||
id VARCHAR(36) PRIMARY KEY,
|
||||
name VARCHAR(254) NOT NULL,
|
||||
user_id VARCHAR(36),
|
||||
description TEXT,
|
||||
secret TEXT,
|
||||
issued_at TIMESTAMPTZ,
|
||||
expires_at TIMESTAMPTZ,
|
||||
updated_at TIMESTAMPTZ,
|
||||
revoked BOOLEAN,
|
||||
revoked_at TIMESTAMPTZ,
|
||||
last_used_at TIMESTAMPTZ,
|
||||
UNIQUE (id, name, secret)
|
||||
)
|
||||
|
||||
CREATE TABLE IF NOT EXISTS pat_scopes (
|
||||
id VARCHAR(36) PRIMARY KEY,
|
||||
pat_id VARCHAR(36) REFERENCES pats(id) ON DELETE CASCADE,
|
||||
optional_domain_id VARCHAR(36),
|
||||
entity_type VARCHAR(50) NOT NULL,
|
||||
operation VARCHAR(50) NOT NULL,
|
||||
entity_id VARCHAR(50) NOT NULL,
|
||||
UNIQUE (pat_id, optional_domain_id, entity_type, operation, entity_id)
|
||||
)
|
||||
```
|
||||
|
||||
### Authorization
|
||||
|
||||
When a PAT is used for authentication:
|
||||
|
||||
1. The system parses the token to extract the user ID and PAT ID
|
||||
2. It verifies the token hasn't been revoked or expired
|
||||
3. It checks if the requested operation is allowed by the token's scopes
|
||||
4. If all checks pass, the operation is authorized
|
||||
|
||||
## Usage
|
||||
|
||||
For more information about service capabilities and its usage, please check out the [API documentation](https://api.mainflux.io/?urls.primaryName=auth.yml).
|
||||
For more information about service capabilities and its usage, please check out the [API documentation](https://docs.api.magistrala.absmach.eu/?urls.primaryName=auth.yaml).
|
||||
|
||||
[doc]: https://docs.mainflux.io
|
||||
[doc]: https://magistrala.absmach.eu/docs/
|
||||
@@ -0,0 +1,150 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
grpcAuthV1 "github.com/absmach/magistrala/api/grpc/auth/v1"
|
||||
"github.com/absmach/magistrala/auth"
|
||||
grpcapi "github.com/absmach/magistrala/auth/api/grpc"
|
||||
"github.com/go-kit/kit/endpoint"
|
||||
kitgrpc "github.com/go-kit/kit/transport/grpc"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
const authSvcName = "auth.v1.AuthService"
|
||||
|
||||
type authGrpcClient struct {
|
||||
authenticate endpoint.Endpoint
|
||||
authorize endpoint.Endpoint
|
||||
timeout time.Duration
|
||||
}
|
||||
|
||||
var _ grpcAuthV1.AuthServiceClient = (*authGrpcClient)(nil)
|
||||
|
||||
// NewAuthClient returns new auth gRPC client instance.
|
||||
func NewAuthClient(conn *grpc.ClientConn, timeout time.Duration) grpcAuthV1.AuthServiceClient {
|
||||
return &authGrpcClient{
|
||||
authenticate: kitgrpc.NewClient(
|
||||
conn,
|
||||
authSvcName,
|
||||
"Authenticate",
|
||||
encodeIdentifyRequest,
|
||||
decodeIdentifyResponse,
|
||||
grpcAuthV1.AuthNRes{},
|
||||
).Endpoint(),
|
||||
authorize: kitgrpc.NewClient(
|
||||
conn,
|
||||
authSvcName,
|
||||
"Authorize",
|
||||
encodeAuthorizeRequest,
|
||||
decodeAuthorizeResponse,
|
||||
grpcAuthV1.AuthZRes{},
|
||||
).Endpoint(),
|
||||
timeout: timeout,
|
||||
}
|
||||
}
|
||||
|
||||
func (client authGrpcClient) Authenticate(ctx context.Context, token *grpcAuthV1.AuthNReq, _ ...grpc.CallOption) (*grpcAuthV1.AuthNRes, error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, client.timeout)
|
||||
defer cancel()
|
||||
|
||||
res, err := client.authenticate(ctx, authenticateReq{token: token.GetToken()})
|
||||
if err != nil {
|
||||
return &grpcAuthV1.AuthNRes{}, grpcapi.DecodeError(err)
|
||||
}
|
||||
ir := res.(authenticateRes)
|
||||
return &grpcAuthV1.AuthNRes{Id: ir.id, UserId: ir.userID, UserRole: uint32(ir.userRole), Verified: ir.verified, TokenType: uint32(ir.tokenType)}, nil
|
||||
}
|
||||
|
||||
func encodeIdentifyRequest(_ context.Context, grpcReq any) (any, error) {
|
||||
req := grpcReq.(authenticateReq)
|
||||
return &grpcAuthV1.AuthNReq{Token: req.token}, nil
|
||||
}
|
||||
|
||||
func decodeIdentifyResponse(_ context.Context, grpcRes any) (any, error) {
|
||||
res := grpcRes.(*grpcAuthV1.AuthNRes)
|
||||
return authenticateRes{id: res.GetId(), userID: res.GetUserId(), userRole: auth.Role(res.UserRole), verified: res.GetVerified(), tokenType: auth.KeyType(res.GetTokenType())}, nil
|
||||
}
|
||||
|
||||
func (client authGrpcClient) Authorize(ctx context.Context, req *grpcAuthV1.AuthZReq, _ ...grpc.CallOption) (r *grpcAuthV1.AuthZRes, err error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, client.timeout)
|
||||
defer cancel()
|
||||
|
||||
var authReqData authReq
|
||||
|
||||
if req != nil {
|
||||
policyReq := req.GetPolicyReq()
|
||||
patReq := req.GetPatReq()
|
||||
|
||||
if policyReq != nil {
|
||||
authReqData = authReq{
|
||||
Domain: policyReq.GetDomain(),
|
||||
SubjectType: policyReq.GetSubjectType(),
|
||||
Subject: policyReq.GetSubject(),
|
||||
SubjectKind: policyReq.GetSubjectKind(),
|
||||
Relation: policyReq.GetRelation(),
|
||||
Permission: policyReq.GetPermission(),
|
||||
ObjectType: policyReq.GetObjectType(),
|
||||
Object: policyReq.GetObject(),
|
||||
}
|
||||
}
|
||||
|
||||
if patReq != nil {
|
||||
if patReq.GetDomain() != "" {
|
||||
authReqData.Domain = patReq.GetDomain()
|
||||
}
|
||||
authReqData.UserID = patReq.GetUserId()
|
||||
authReqData.PatID = patReq.GetPatId()
|
||||
authReqData.EntityType = patReq.GetEntityType()
|
||||
authReqData.Operation = patReq.GetOperation()
|
||||
authReqData.EntityID = patReq.GetEntityId()
|
||||
}
|
||||
}
|
||||
|
||||
res, err := client.authorize(ctx, authReqData)
|
||||
if err != nil {
|
||||
return &grpcAuthV1.AuthZRes{}, grpcapi.DecodeError(err)
|
||||
}
|
||||
|
||||
ar := res.(authorizeRes)
|
||||
return &grpcAuthV1.AuthZRes{Authorized: ar.authorized, Id: ar.id}, nil
|
||||
}
|
||||
|
||||
func decodeAuthorizeResponse(_ context.Context, grpcRes any) (any, error) {
|
||||
res := grpcRes.(*grpcAuthV1.AuthZRes)
|
||||
return authorizeRes{authorized: res.Authorized, id: res.Id}, nil
|
||||
}
|
||||
|
||||
func encodeAuthorizeRequest(_ context.Context, grpcReq any) (any, error) {
|
||||
req := grpcReq.(authReq)
|
||||
|
||||
authZReq := &grpcAuthV1.AuthZReq{
|
||||
PolicyReq: &grpcAuthV1.PolicyReq{
|
||||
Domain: req.Domain,
|
||||
SubjectType: req.SubjectType,
|
||||
Subject: req.Subject,
|
||||
SubjectKind: req.SubjectKind,
|
||||
Relation: req.Relation,
|
||||
Permission: req.Permission,
|
||||
ObjectType: req.ObjectType,
|
||||
Object: req.Object,
|
||||
},
|
||||
}
|
||||
|
||||
if req.PatID != "" {
|
||||
authZReq.PatReq = &grpcAuthV1.PATReq{
|
||||
PatId: req.PatID,
|
||||
Domain: req.Domain,
|
||||
Operation: req.Operation,
|
||||
UserId: req.UserID,
|
||||
EntityId: req.EntityID,
|
||||
EntityType: req.EntityType,
|
||||
}
|
||||
}
|
||||
|
||||
return authZReq, nil
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Package api contains implementation of certs service HTTP API.
|
||||
package api
|
||||
// Package auth contains implementation of Auth service gRPC API.
|
||||
package auth
|
||||
@@ -0,0 +1,69 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/absmach/magistrala/auth"
|
||||
"github.com/absmach/magistrala/pkg/policies"
|
||||
"github.com/go-kit/kit/endpoint"
|
||||
)
|
||||
|
||||
func authenticateEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request any) (any, error) {
|
||||
req := request.(authenticateReq)
|
||||
if err := req.validate(); err != nil {
|
||||
return authenticateRes{}, err
|
||||
}
|
||||
|
||||
key, err := svc.Identify(ctx, req.token)
|
||||
if err != nil {
|
||||
return authenticateRes{}, err
|
||||
}
|
||||
|
||||
return authenticateRes{id: key.ID, userID: key.Subject, userRole: key.Role, verified: key.Verified, tokenType: key.Type}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func authorizeEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request any) (any, error) {
|
||||
req := request.(authReq)
|
||||
|
||||
if err := req.validate(); err != nil {
|
||||
return authorizeRes{}, err
|
||||
}
|
||||
|
||||
var pat *auth.PATAuthz
|
||||
if req.PatID != "" {
|
||||
entityType, err := auth.ParseEntityType(req.EntityType)
|
||||
if err != nil {
|
||||
return authorizeRes{authorized: false}, err
|
||||
}
|
||||
pat = &auth.PATAuthz{
|
||||
PatID: req.PatID,
|
||||
UserID: req.UserID,
|
||||
EntityType: entityType,
|
||||
EntityID: req.EntityID,
|
||||
Operation: req.Operation,
|
||||
Domain: req.Domain,
|
||||
}
|
||||
}
|
||||
|
||||
err := svc.Authorize(ctx, policies.Policy{
|
||||
Domain: req.Domain,
|
||||
SubjectType: req.SubjectType,
|
||||
SubjectKind: req.SubjectKind,
|
||||
Subject: req.Subject,
|
||||
Relation: req.Relation,
|
||||
Permission: req.Permission,
|
||||
ObjectType: req.ObjectType,
|
||||
Object: req.Object,
|
||||
}, pat)
|
||||
if err != nil {
|
||||
return authorizeRes{authorized: false}, err
|
||||
}
|
||||
return authorizeRes{authorized: true}, nil
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package auth
|
||||
|
||||
import (
|
||||
apiutil "github.com/absmach/magistrala/api/http/util"
|
||||
)
|
||||
|
||||
type authenticateReq struct {
|
||||
token string
|
||||
}
|
||||
|
||||
func (req authenticateReq) validate() error {
|
||||
if req.token == "" {
|
||||
return apiutil.ErrBearerToken
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// authReq represents authorization request. It contains:
|
||||
// 1. subject - an action invoker
|
||||
// 2. object - an entity over which action will be executed
|
||||
// 3. action - type of action that will be executed (read/write).
|
||||
type authReq struct {
|
||||
Domain string
|
||||
SubjectType string
|
||||
SubjectKind string
|
||||
Subject string
|
||||
Relation string
|
||||
Permission string
|
||||
ObjectType string
|
||||
Object string
|
||||
|
||||
// PAT authorization fields
|
||||
UserID string
|
||||
PatID string
|
||||
EntityType string
|
||||
Operation string
|
||||
EntityID string
|
||||
}
|
||||
|
||||
func (req authReq) validate() error {
|
||||
if req.PatID != "" {
|
||||
if req.UserID == "" {
|
||||
return apiutil.ErrMissingUserID
|
||||
}
|
||||
if req.EntityID == "" {
|
||||
return apiutil.ErrMissingID
|
||||
}
|
||||
if req.EntityType == "" {
|
||||
return apiutil.ErrMissingPolicyObj
|
||||
}
|
||||
}
|
||||
|
||||
if req.Subject == "" || req.SubjectType == "" {
|
||||
return apiutil.ErrMissingPolicySub
|
||||
}
|
||||
|
||||
if req.Object == "" || req.ObjectType == "" {
|
||||
return apiutil.ErrMissingPolicyObj
|
||||
}
|
||||
|
||||
if req.Permission == "" {
|
||||
return apiutil.ErrMalformedPolicyPer
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package auth
|
||||
|
||||
import "github.com/absmach/magistrala/auth"
|
||||
|
||||
type authenticateRes struct {
|
||||
id string
|
||||
userID string
|
||||
userRole auth.Role
|
||||
verified bool
|
||||
tokenType auth.KeyType
|
||||
}
|
||||
|
||||
type authorizeRes struct {
|
||||
id string
|
||||
authorized bool
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
grpcAuthV1 "github.com/absmach/magistrala/api/grpc/auth/v1"
|
||||
"github.com/absmach/magistrala/auth"
|
||||
grpcapi "github.com/absmach/magistrala/auth/api/grpc"
|
||||
kitgrpc "github.com/go-kit/kit/transport/grpc"
|
||||
)
|
||||
|
||||
var _ grpcAuthV1.AuthServiceServer = (*authGrpcServer)(nil)
|
||||
|
||||
type authGrpcServer struct {
|
||||
grpcAuthV1.UnimplementedAuthServiceServer
|
||||
authorize kitgrpc.Handler
|
||||
authenticate kitgrpc.Handler
|
||||
}
|
||||
|
||||
// NewAuthServer returns new AuthnServiceServer instance.
|
||||
func NewAuthServer(svc auth.Service) grpcAuthV1.AuthServiceServer {
|
||||
return &authGrpcServer{
|
||||
authorize: kitgrpc.NewServer(
|
||||
(authorizeEndpoint(svc)),
|
||||
decodeAuthorizeRequest,
|
||||
encodeAuthorizeResponse,
|
||||
),
|
||||
|
||||
authenticate: kitgrpc.NewServer(
|
||||
(authenticateEndpoint(svc)),
|
||||
decodeAuthenticateRequest,
|
||||
encodeAuthenticateResponse,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
func (s *authGrpcServer) Authenticate(ctx context.Context, req *grpcAuthV1.AuthNReq) (*grpcAuthV1.AuthNRes, error) {
|
||||
_, res, err := s.authenticate.ServeGRPC(ctx, req)
|
||||
if err != nil {
|
||||
return nil, grpcapi.EncodeError(err)
|
||||
}
|
||||
return res.(*grpcAuthV1.AuthNRes), nil
|
||||
}
|
||||
|
||||
func (s *authGrpcServer) Authorize(ctx context.Context, req *grpcAuthV1.AuthZReq) (*grpcAuthV1.AuthZRes, error) {
|
||||
_, res, err := s.authorize.ServeGRPC(ctx, req)
|
||||
if err != nil {
|
||||
return nil, grpcapi.EncodeError(err)
|
||||
}
|
||||
return res.(*grpcAuthV1.AuthZRes), nil
|
||||
}
|
||||
|
||||
func decodeAuthenticateRequest(_ context.Context, grpcReq any) (any, error) {
|
||||
req := grpcReq.(*grpcAuthV1.AuthNReq)
|
||||
return authenticateReq{token: req.GetToken()}, nil
|
||||
}
|
||||
|
||||
func encodeAuthenticateResponse(_ context.Context, grpcRes any) (any, error) {
|
||||
res := grpcRes.(authenticateRes)
|
||||
return &grpcAuthV1.AuthNRes{Id: res.id, UserId: res.userID, UserRole: uint32(res.userRole), Verified: res.verified, TokenType: uint32(res.tokenType)}, nil
|
||||
}
|
||||
|
||||
func decodeAuthorizeRequest(_ context.Context, grpcReq any) (any, error) {
|
||||
req := grpcReq.(*grpcAuthV1.AuthZReq)
|
||||
if req == nil {
|
||||
return authReq{}, nil
|
||||
}
|
||||
|
||||
policyReq := req.GetPolicyReq()
|
||||
patReq := req.GetPatReq()
|
||||
|
||||
if policyReq == nil {
|
||||
return authReq{}, nil
|
||||
}
|
||||
|
||||
authRequest := authReq{
|
||||
Domain: policyReq.GetDomain(),
|
||||
SubjectType: policyReq.GetSubjectType(),
|
||||
SubjectKind: policyReq.GetSubjectKind(),
|
||||
Subject: policyReq.GetSubject(),
|
||||
Relation: policyReq.GetRelation(),
|
||||
Permission: policyReq.GetPermission(),
|
||||
ObjectType: policyReq.GetObjectType(),
|
||||
Object: policyReq.GetObject(),
|
||||
}
|
||||
|
||||
if patReq != nil {
|
||||
if patReq.GetDomain() != "" {
|
||||
authRequest.Domain = patReq.GetDomain()
|
||||
}
|
||||
authRequest.UserID = patReq.GetUserId()
|
||||
authRequest.PatID = patReq.GetPatId()
|
||||
authRequest.EntityType = patReq.GetEntityType()
|
||||
authRequest.Operation = patReq.GetOperation()
|
||||
authRequest.EntityID = patReq.GetEntityId()
|
||||
}
|
||||
|
||||
return authRequest, nil
|
||||
}
|
||||
|
||||
func encodeAuthorizeResponse(_ context.Context, grpcRes any) (any, error) {
|
||||
res := grpcRes.(authorizeRes)
|
||||
return &grpcAuthV1.AuthZRes{Authorized: res.authorized, Id: res.id}, nil
|
||||
}
|
||||
@@ -1,766 +0,0 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package grpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/absmach/magistrala"
|
||||
"github.com/absmach/magistrala/auth"
|
||||
"github.com/absmach/magistrala/pkg/errors"
|
||||
svcerr "github.com/absmach/magistrala/pkg/errors/service"
|
||||
"github.com/go-kit/kit/endpoint"
|
||||
kitgrpc "github.com/go-kit/kit/transport/grpc"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
const svcName = "magistrala.AuthService"
|
||||
|
||||
var _ magistrala.AuthServiceClient = (*grpcClient)(nil)
|
||||
|
||||
type grpcClient struct {
|
||||
issue endpoint.Endpoint
|
||||
refresh endpoint.Endpoint
|
||||
identify endpoint.Endpoint
|
||||
authorize endpoint.Endpoint
|
||||
addPolicy endpoint.Endpoint
|
||||
addPolicies endpoint.Endpoint
|
||||
deletePolicy endpoint.Endpoint
|
||||
deletePolicies endpoint.Endpoint
|
||||
listObjects endpoint.Endpoint
|
||||
listAllObjects endpoint.Endpoint
|
||||
countObjects endpoint.Endpoint
|
||||
listSubjects endpoint.Endpoint
|
||||
listAllSubjects endpoint.Endpoint
|
||||
countSubjects endpoint.Endpoint
|
||||
listPermissions endpoint.Endpoint
|
||||
timeout time.Duration
|
||||
}
|
||||
|
||||
// NewClient returns new gRPC client instance.
|
||||
func NewClient(conn *grpc.ClientConn, timeout time.Duration) magistrala.AuthServiceClient {
|
||||
return &grpcClient{
|
||||
issue: kitgrpc.NewClient(
|
||||
conn,
|
||||
svcName,
|
||||
"Issue",
|
||||
encodeIssueRequest,
|
||||
decodeIssueResponse,
|
||||
magistrala.Token{},
|
||||
).Endpoint(),
|
||||
refresh: kitgrpc.NewClient(
|
||||
conn,
|
||||
svcName,
|
||||
"Refresh",
|
||||
encodeRefreshRequest,
|
||||
decodeRefreshResponse,
|
||||
magistrala.Token{},
|
||||
).Endpoint(),
|
||||
identify: kitgrpc.NewClient(
|
||||
conn,
|
||||
svcName,
|
||||
"Identify",
|
||||
encodeIdentifyRequest,
|
||||
decodeIdentifyResponse,
|
||||
magistrala.IdentityRes{},
|
||||
).Endpoint(),
|
||||
authorize: kitgrpc.NewClient(
|
||||
conn,
|
||||
svcName,
|
||||
"Authorize",
|
||||
encodeAuthorizeRequest,
|
||||
decodeAuthorizeResponse,
|
||||
magistrala.AuthorizeRes{},
|
||||
).Endpoint(),
|
||||
addPolicy: kitgrpc.NewClient(
|
||||
conn,
|
||||
svcName,
|
||||
"AddPolicy",
|
||||
encodeAddPolicyRequest,
|
||||
decodeAddPolicyResponse,
|
||||
magistrala.AddPolicyRes{},
|
||||
).Endpoint(),
|
||||
addPolicies: kitgrpc.NewClient(
|
||||
conn,
|
||||
svcName,
|
||||
"AddPolicies",
|
||||
encodeAddPoliciesRequest,
|
||||
decodeAddPoliciesResponse,
|
||||
magistrala.AddPoliciesRes{},
|
||||
).Endpoint(),
|
||||
deletePolicy: kitgrpc.NewClient(
|
||||
conn,
|
||||
svcName,
|
||||
"DeletePolicy",
|
||||
encodeDeletePolicyRequest,
|
||||
decodeDeletePolicyResponse,
|
||||
magistrala.DeletePolicyRes{},
|
||||
).Endpoint(),
|
||||
deletePolicies: kitgrpc.NewClient(
|
||||
conn,
|
||||
svcName,
|
||||
"DeletePolicies",
|
||||
encodeDeletePoliciesRequest,
|
||||
decodeDeletePoliciesResponse,
|
||||
magistrala.DeletePoliciesRes{},
|
||||
).Endpoint(),
|
||||
listObjects: kitgrpc.NewClient(
|
||||
conn,
|
||||
svcName,
|
||||
"ListObjects",
|
||||
encodeListObjectsRequest,
|
||||
decodeListObjectsResponse,
|
||||
magistrala.ListObjectsRes{},
|
||||
).Endpoint(),
|
||||
listAllObjects: kitgrpc.NewClient(
|
||||
conn,
|
||||
svcName,
|
||||
"ListAllObjects",
|
||||
encodeListObjectsRequest,
|
||||
decodeListObjectsResponse,
|
||||
magistrala.ListObjectsRes{},
|
||||
).Endpoint(),
|
||||
countObjects: kitgrpc.NewClient(
|
||||
conn,
|
||||
svcName,
|
||||
"CountObjects",
|
||||
encodeCountObjectsRequest,
|
||||
decodeCountObjectsResponse,
|
||||
magistrala.CountObjectsRes{},
|
||||
).Endpoint(),
|
||||
listSubjects: kitgrpc.NewClient(
|
||||
conn,
|
||||
svcName,
|
||||
"ListSubjects",
|
||||
encodeListSubjectsRequest,
|
||||
decodeListSubjectsResponse,
|
||||
magistrala.ListSubjectsRes{},
|
||||
).Endpoint(),
|
||||
listAllSubjects: kitgrpc.NewClient(
|
||||
conn,
|
||||
svcName,
|
||||
"ListAllSubjects",
|
||||
encodeListSubjectsRequest,
|
||||
decodeListSubjectsResponse,
|
||||
magistrala.ListSubjectsRes{},
|
||||
).Endpoint(),
|
||||
countSubjects: kitgrpc.NewClient(
|
||||
conn,
|
||||
svcName,
|
||||
"CountSubjects",
|
||||
encodeCountSubjectsRequest,
|
||||
decodeCountSubjectsResponse,
|
||||
magistrala.CountSubjectsRes{},
|
||||
).Endpoint(),
|
||||
listPermissions: kitgrpc.NewClient(
|
||||
conn,
|
||||
svcName,
|
||||
"ListPermissions",
|
||||
encodeListPermissionsRequest,
|
||||
decodeListPermissionsResponse,
|
||||
magistrala.ListPermissionsRes{},
|
||||
).Endpoint(),
|
||||
|
||||
timeout: timeout,
|
||||
}
|
||||
}
|
||||
|
||||
func (client grpcClient) Issue(ctx context.Context, req *magistrala.IssueReq, _ ...grpc.CallOption) (*magistrala.Token, error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, client.timeout)
|
||||
defer cancel()
|
||||
|
||||
res, err := client.issue(ctx, issueReq{
|
||||
userID: req.GetUserId(),
|
||||
domainID: req.GetDomainId(),
|
||||
keyType: auth.KeyType(req.GetType()),
|
||||
oauthToken: auth.OAuthToken{
|
||||
Provider: req.GetOauthProvider(),
|
||||
AccessToken: req.GetOauthAccessToken(),
|
||||
RefreshToken: req.GetOauthRefreshToken(),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return &magistrala.Token{}, decodeError(err)
|
||||
}
|
||||
return res.(*magistrala.Token), nil
|
||||
}
|
||||
|
||||
func encodeIssueRequest(_ context.Context, grpcReq interface{}) (interface{}, error) {
|
||||
req := grpcReq.(issueReq)
|
||||
return &magistrala.IssueReq{
|
||||
UserId: req.userID,
|
||||
DomainId: &req.domainID,
|
||||
Type: uint32(req.keyType),
|
||||
OauthProvider: req.oauthToken.Provider,
|
||||
OauthAccessToken: req.oauthToken.AccessToken,
|
||||
OauthRefreshToken: req.oauthToken.RefreshToken,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func decodeIssueResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
return grpcRes, nil
|
||||
}
|
||||
|
||||
func (client grpcClient) Refresh(ctx context.Context, req *magistrala.RefreshReq, _ ...grpc.CallOption) (*magistrala.Token, error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, client.timeout)
|
||||
defer cancel()
|
||||
|
||||
res, err := client.refresh(ctx, refreshReq{refreshToken: req.GetRefreshToken(), domainID: req.GetDomainId()})
|
||||
if err != nil {
|
||||
return &magistrala.Token{}, decodeError(err)
|
||||
}
|
||||
return res.(*magistrala.Token), nil
|
||||
}
|
||||
|
||||
func encodeRefreshRequest(_ context.Context, grpcReq interface{}) (interface{}, error) {
|
||||
req := grpcReq.(refreshReq)
|
||||
return &magistrala.RefreshReq{RefreshToken: req.refreshToken, DomainId: &req.domainID}, nil
|
||||
}
|
||||
|
||||
func decodeRefreshResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
return grpcRes, nil
|
||||
}
|
||||
|
||||
func (client grpcClient) Identify(ctx context.Context, token *magistrala.IdentityReq, _ ...grpc.CallOption) (*magistrala.IdentityRes, error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, client.timeout)
|
||||
defer cancel()
|
||||
|
||||
res, err := client.identify(ctx, identityReq{token: token.GetToken()})
|
||||
if err != nil {
|
||||
return &magistrala.IdentityRes{}, decodeError(err)
|
||||
}
|
||||
ir := res.(identityRes)
|
||||
return &magistrala.IdentityRes{Id: ir.id, UserId: ir.userID, DomainId: ir.domainID}, nil
|
||||
}
|
||||
|
||||
func encodeIdentifyRequest(_ context.Context, grpcReq interface{}) (interface{}, error) {
|
||||
req := grpcReq.(identityReq)
|
||||
return &magistrala.IdentityReq{Token: req.token}, nil
|
||||
}
|
||||
|
||||
func decodeIdentifyResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
res := grpcRes.(*magistrala.IdentityRes)
|
||||
return identityRes{id: res.GetId(), userID: res.GetUserId(), domainID: res.GetDomainId()}, nil
|
||||
}
|
||||
|
||||
func (client grpcClient) Authorize(ctx context.Context, req *magistrala.AuthorizeReq, _ ...grpc.CallOption) (r *magistrala.AuthorizeRes, err error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, client.timeout)
|
||||
defer cancel()
|
||||
|
||||
res, err := client.authorize(ctx, authReq{
|
||||
Domain: req.GetDomain(),
|
||||
SubjectType: req.GetSubjectType(),
|
||||
Subject: req.GetSubject(),
|
||||
SubjectKind: req.GetSubjectKind(),
|
||||
Relation: req.GetRelation(),
|
||||
Permission: req.GetPermission(),
|
||||
ObjectType: req.GetObjectType(),
|
||||
Object: req.GetObject(),
|
||||
})
|
||||
if err != nil {
|
||||
return &magistrala.AuthorizeRes{}, decodeError(err)
|
||||
}
|
||||
|
||||
ar := res.(authorizeRes)
|
||||
return &magistrala.AuthorizeRes{Authorized: ar.authorized, Id: ar.id}, nil
|
||||
}
|
||||
|
||||
func decodeAuthorizeResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
res := grpcRes.(*magistrala.AuthorizeRes)
|
||||
return authorizeRes{authorized: res.Authorized, id: res.Id}, nil
|
||||
}
|
||||
|
||||
func encodeAuthorizeRequest(_ context.Context, grpcReq interface{}) (interface{}, error) {
|
||||
req := grpcReq.(authReq)
|
||||
return &magistrala.AuthorizeReq{
|
||||
Domain: req.Domain,
|
||||
SubjectType: req.SubjectType,
|
||||
Subject: req.Subject,
|
||||
SubjectKind: req.SubjectKind,
|
||||
Relation: req.Relation,
|
||||
Permission: req.Permission,
|
||||
ObjectType: req.ObjectType,
|
||||
Object: req.Object,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (client grpcClient) AddPolicy(ctx context.Context, in *magistrala.AddPolicyReq, opts ...grpc.CallOption) (*magistrala.AddPolicyRes, error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, client.timeout)
|
||||
defer cancel()
|
||||
|
||||
res, err := client.addPolicy(ctx, policyReq{
|
||||
Domain: in.GetDomain(),
|
||||
SubjectType: in.GetSubjectType(),
|
||||
SubjectKind: in.GetSubjectKind(),
|
||||
Subject: in.GetSubject(),
|
||||
Relation: in.GetRelation(),
|
||||
Permission: in.GetPermission(),
|
||||
ObjectType: in.GetObjectType(),
|
||||
ObjectKind: in.GetObjectKind(),
|
||||
Object: in.GetObject(),
|
||||
})
|
||||
if err != nil {
|
||||
return &magistrala.AddPolicyRes{}, decodeError(err)
|
||||
}
|
||||
|
||||
apr := res.(addPolicyRes)
|
||||
return &magistrala.AddPolicyRes{Added: apr.added}, nil
|
||||
}
|
||||
|
||||
func decodeAddPolicyResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
res := grpcRes.(*magistrala.AddPolicyRes)
|
||||
return addPolicyRes{added: res.Added}, nil
|
||||
}
|
||||
|
||||
func encodeAddPolicyRequest(_ context.Context, grpcReq interface{}) (interface{}, error) {
|
||||
req := grpcReq.(policyReq)
|
||||
return &magistrala.AddPolicyReq{
|
||||
Domain: req.Domain,
|
||||
SubjectType: req.SubjectType,
|
||||
SubjectKind: req.SubjectKind,
|
||||
Subject: req.Subject,
|
||||
Relation: req.Relation,
|
||||
Permission: req.Permission,
|
||||
ObjectType: req.ObjectType,
|
||||
ObjectKind: req.ObjectKind,
|
||||
Object: req.Object,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (client grpcClient) AddPolicies(ctx context.Context, in *magistrala.AddPoliciesReq, opts ...grpc.CallOption) (*magistrala.AddPoliciesRes, error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, client.timeout)
|
||||
defer cancel()
|
||||
r := policiesReq{}
|
||||
if in.GetAddPoliciesReq() != nil {
|
||||
for _, mgApr := range in.GetAddPoliciesReq() {
|
||||
r = append(r, policyReq{
|
||||
Domain: mgApr.GetDomain(),
|
||||
SubjectType: mgApr.GetSubjectType(),
|
||||
SubjectKind: mgApr.GetSubjectKind(),
|
||||
Subject: mgApr.GetSubject(),
|
||||
Relation: mgApr.GetRelation(),
|
||||
Permission: mgApr.GetPermission(),
|
||||
ObjectType: mgApr.GetObjectType(),
|
||||
ObjectKind: mgApr.GetObjectKind(),
|
||||
Object: mgApr.GetObject(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
res, err := client.addPolicies(ctx, r)
|
||||
if err != nil {
|
||||
return &magistrala.AddPoliciesRes{}, decodeError(err)
|
||||
}
|
||||
|
||||
apr := res.(addPoliciesRes)
|
||||
return &magistrala.AddPoliciesRes{Added: apr.added}, nil
|
||||
}
|
||||
|
||||
func decodeAddPoliciesResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
res := grpcRes.(*magistrala.AddPoliciesRes)
|
||||
return addPoliciesRes{added: res.Added}, nil
|
||||
}
|
||||
|
||||
func encodeAddPoliciesRequest(_ context.Context, grpcReq interface{}) (interface{}, error) {
|
||||
reqs := grpcReq.(policiesReq)
|
||||
|
||||
addPolicies := []*magistrala.AddPolicyReq{}
|
||||
|
||||
for _, req := range reqs {
|
||||
addPolicies = append(addPolicies, &magistrala.AddPolicyReq{
|
||||
Domain: req.Domain,
|
||||
SubjectType: req.SubjectType,
|
||||
SubjectKind: req.SubjectKind,
|
||||
Subject: req.Subject,
|
||||
Relation: req.Relation,
|
||||
Permission: req.Permission,
|
||||
ObjectType: req.ObjectType,
|
||||
ObjectKind: req.ObjectKind,
|
||||
Object: req.Object,
|
||||
})
|
||||
}
|
||||
return &magistrala.AddPoliciesReq{AddPoliciesReq: addPolicies}, nil
|
||||
}
|
||||
|
||||
func (client grpcClient) DeletePolicy(ctx context.Context, in *magistrala.DeletePolicyReq, opts ...grpc.CallOption) (*magistrala.DeletePolicyRes, error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, client.timeout)
|
||||
defer cancel()
|
||||
|
||||
res, err := client.deletePolicy(ctx, policyReq{
|
||||
Domain: in.GetDomain(),
|
||||
SubjectType: in.GetSubjectType(),
|
||||
SubjectKind: in.GetSubjectKind(),
|
||||
Subject: in.GetSubject(),
|
||||
Relation: in.GetRelation(),
|
||||
Permission: in.GetPermission(),
|
||||
ObjectType: in.GetObjectType(),
|
||||
ObjectKind: in.GetObjectKind(),
|
||||
Object: in.GetObject(),
|
||||
})
|
||||
if err != nil {
|
||||
return &magistrala.DeletePolicyRes{}, decodeError(err)
|
||||
}
|
||||
|
||||
dpr := res.(deletePolicyRes)
|
||||
return &magistrala.DeletePolicyRes{Deleted: dpr.deleted}, nil
|
||||
}
|
||||
|
||||
func decodeDeletePolicyResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
res := grpcRes.(*magistrala.DeletePolicyRes)
|
||||
return deletePolicyRes{deleted: res.GetDeleted()}, nil
|
||||
}
|
||||
|
||||
func encodeDeletePolicyRequest(_ context.Context, grpcReq interface{}) (interface{}, error) {
|
||||
req := grpcReq.(policyReq)
|
||||
return &magistrala.DeletePolicyReq{
|
||||
Domain: req.Domain,
|
||||
SubjectType: req.SubjectType,
|
||||
SubjectKind: req.SubjectKind,
|
||||
Subject: req.Subject,
|
||||
Relation: req.Relation,
|
||||
Permission: req.Permission,
|
||||
ObjectType: req.ObjectType,
|
||||
ObjectKind: req.ObjectKind,
|
||||
Object: req.Object,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (client grpcClient) DeletePolicies(ctx context.Context, in *magistrala.DeletePoliciesReq, opts ...grpc.CallOption) (*magistrala.DeletePoliciesRes, error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, client.timeout)
|
||||
defer cancel()
|
||||
r := policiesReq{}
|
||||
|
||||
if in.GetDeletePoliciesReq() != nil {
|
||||
for _, mgApr := range in.GetDeletePoliciesReq() {
|
||||
r = append(r, policyReq{
|
||||
Domain: mgApr.GetDomain(),
|
||||
SubjectType: mgApr.GetSubjectType(),
|
||||
SubjectKind: mgApr.GetSubjectKind(),
|
||||
Subject: mgApr.GetSubject(),
|
||||
Relation: mgApr.GetRelation(),
|
||||
Permission: mgApr.GetPermission(),
|
||||
ObjectType: mgApr.GetObjectType(),
|
||||
ObjectKind: mgApr.GetObjectKind(),
|
||||
Object: mgApr.GetObject(),
|
||||
})
|
||||
}
|
||||
}
|
||||
res, err := client.deletePolicies(ctx, r)
|
||||
if err != nil {
|
||||
return &magistrala.DeletePoliciesRes{}, decodeError(err)
|
||||
}
|
||||
|
||||
dpr := res.(deletePoliciesRes)
|
||||
return &magistrala.DeletePoliciesRes{Deleted: dpr.deleted}, nil
|
||||
}
|
||||
|
||||
func decodeDeletePoliciesResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
res := grpcRes.(*magistrala.DeletePoliciesRes)
|
||||
return deletePoliciesRes{deleted: res.GetDeleted()}, nil
|
||||
}
|
||||
|
||||
func encodeDeletePoliciesRequest(_ context.Context, grpcReq interface{}) (interface{}, error) {
|
||||
reqs := grpcReq.(policiesReq)
|
||||
|
||||
deletePolicies := []*magistrala.DeletePolicyReq{}
|
||||
|
||||
for _, req := range reqs {
|
||||
deletePolicies = append(deletePolicies, &magistrala.DeletePolicyReq{
|
||||
Domain: req.Domain,
|
||||
SubjectType: req.SubjectType,
|
||||
SubjectKind: req.SubjectKind,
|
||||
Subject: req.Subject,
|
||||
Relation: req.Relation,
|
||||
Permission: req.Permission,
|
||||
ObjectType: req.ObjectType,
|
||||
ObjectKind: req.ObjectKind,
|
||||
Object: req.Object,
|
||||
})
|
||||
}
|
||||
return &magistrala.DeletePoliciesReq{DeletePoliciesReq: deletePolicies}, nil
|
||||
}
|
||||
|
||||
func (client grpcClient) ListObjects(ctx context.Context, in *magistrala.ListObjectsReq, opts ...grpc.CallOption) (*magistrala.ListObjectsRes, error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, client.timeout)
|
||||
defer cancel()
|
||||
|
||||
res, err := client.listObjects(ctx, listObjectsReq{
|
||||
Domain: in.GetDomain(),
|
||||
SubjectType: in.GetSubjectType(),
|
||||
Subject: in.GetSubject(),
|
||||
Relation: in.GetRelation(),
|
||||
Permission: in.GetPermission(),
|
||||
ObjectType: in.GetObjectType(),
|
||||
Object: in.GetObject(),
|
||||
})
|
||||
if err != nil {
|
||||
return &magistrala.ListObjectsRes{}, decodeError(err)
|
||||
}
|
||||
|
||||
lpr := res.(listObjectsRes)
|
||||
return &magistrala.ListObjectsRes{Policies: lpr.policies}, nil
|
||||
}
|
||||
|
||||
func decodeListObjectsResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
res := grpcRes.(*magistrala.ListObjectsRes)
|
||||
return listObjectsRes{policies: res.GetPolicies()}, nil
|
||||
}
|
||||
|
||||
func encodeListObjectsRequest(_ context.Context, grpcReq interface{}) (interface{}, error) {
|
||||
req := grpcReq.(listObjectsReq)
|
||||
return &magistrala.ListObjectsReq{
|
||||
Domain: req.Domain,
|
||||
SubjectType: req.SubjectType,
|
||||
Subject: req.Subject,
|
||||
Relation: req.Relation,
|
||||
Permission: req.Permission,
|
||||
ObjectType: req.ObjectType,
|
||||
Object: req.Object,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (client grpcClient) ListAllObjects(ctx context.Context, in *magistrala.ListObjectsReq, opts ...grpc.CallOption) (*magistrala.ListObjectsRes, error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, client.timeout)
|
||||
defer cancel()
|
||||
|
||||
res, err := client.listAllObjects(ctx, listObjectsReq{
|
||||
Domain: in.GetDomain(),
|
||||
SubjectType: in.GetSubjectType(),
|
||||
Subject: in.GetSubject(),
|
||||
Relation: in.GetRelation(),
|
||||
Permission: in.GetPermission(),
|
||||
ObjectType: in.GetObjectType(),
|
||||
Object: in.GetObject(),
|
||||
})
|
||||
if err != nil {
|
||||
return &magistrala.ListObjectsRes{}, decodeError(err)
|
||||
}
|
||||
|
||||
lpr := res.(listObjectsRes)
|
||||
return &magistrala.ListObjectsRes{Policies: lpr.policies}, nil
|
||||
}
|
||||
|
||||
func (client grpcClient) CountObjects(ctx context.Context, in *magistrala.CountObjectsReq, opts ...grpc.CallOption) (*magistrala.CountObjectsRes, error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, client.timeout)
|
||||
defer cancel()
|
||||
|
||||
res, err := client.countObjects(ctx, countObjectsReq{
|
||||
Domain: in.GetDomain(),
|
||||
SubjectType: in.GetSubjectType(),
|
||||
Subject: in.GetSubject(),
|
||||
Relation: in.GetRelation(),
|
||||
Permission: in.GetPermission(),
|
||||
ObjectType: in.GetObjectType(),
|
||||
Object: in.GetObject(),
|
||||
})
|
||||
if err != nil {
|
||||
return &magistrala.CountObjectsRes{}, decodeError(err)
|
||||
}
|
||||
|
||||
cp := res.(countObjectsRes)
|
||||
return &magistrala.CountObjectsRes{Count: int64(cp.count)}, nil
|
||||
}
|
||||
|
||||
func decodeCountObjectsResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
res := grpcRes.(*magistrala.CountObjectsRes)
|
||||
return countObjectsRes{count: int(res.GetCount())}, nil
|
||||
}
|
||||
|
||||
func encodeCountObjectsRequest(_ context.Context, grpcReq interface{}) (interface{}, error) {
|
||||
req := grpcReq.(countObjectsReq)
|
||||
return &magistrala.CountObjectsReq{
|
||||
Domain: req.Domain,
|
||||
SubjectType: req.SubjectType,
|
||||
Subject: req.Subject,
|
||||
Relation: req.Relation,
|
||||
Permission: req.Permission,
|
||||
ObjectType: req.ObjectType,
|
||||
Object: req.Object,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (client grpcClient) ListSubjects(ctx context.Context, in *magistrala.ListSubjectsReq, opts ...grpc.CallOption) (*magistrala.ListSubjectsRes, error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, client.timeout)
|
||||
defer cancel()
|
||||
|
||||
res, err := client.listSubjects(ctx, listSubjectsReq{
|
||||
Domain: in.GetDomain(),
|
||||
SubjectType: in.GetSubjectType(),
|
||||
Subject: in.GetSubject(),
|
||||
Relation: in.GetRelation(),
|
||||
Permission: in.GetPermission(),
|
||||
ObjectType: in.GetObjectType(),
|
||||
Object: in.GetObject(),
|
||||
NextPageToken: in.GetNextPageToken(),
|
||||
})
|
||||
if err != nil {
|
||||
return &magistrala.ListSubjectsRes{}, decodeError(err)
|
||||
}
|
||||
|
||||
lpr := res.(listSubjectsRes)
|
||||
return &magistrala.ListSubjectsRes{Policies: lpr.policies}, nil
|
||||
}
|
||||
|
||||
func decodeListSubjectsResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
res := grpcRes.(*magistrala.ListSubjectsRes)
|
||||
return listSubjectsRes{policies: res.GetPolicies()}, nil
|
||||
}
|
||||
|
||||
func encodeListSubjectsRequest(_ context.Context, grpcReq interface{}) (interface{}, error) {
|
||||
req := grpcReq.(listSubjectsReq)
|
||||
return &magistrala.ListSubjectsReq{
|
||||
Domain: req.Domain,
|
||||
SubjectType: req.SubjectType,
|
||||
Subject: req.Subject,
|
||||
Relation: req.Relation,
|
||||
Permission: req.Permission,
|
||||
ObjectType: req.ObjectType,
|
||||
Object: req.Object,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (client grpcClient) ListAllSubjects(ctx context.Context, in *magistrala.ListSubjectsReq, opts ...grpc.CallOption) (*magistrala.ListSubjectsRes, error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, client.timeout)
|
||||
defer cancel()
|
||||
|
||||
res, err := client.listAllSubjects(ctx, listSubjectsReq{
|
||||
Domain: in.GetDomain(),
|
||||
SubjectType: in.GetSubjectType(),
|
||||
Subject: in.GetSubject(),
|
||||
Relation: in.GetRelation(),
|
||||
Permission: in.GetPermission(),
|
||||
ObjectType: in.GetObjectType(),
|
||||
Object: in.GetObject(),
|
||||
})
|
||||
if err != nil {
|
||||
return &magistrala.ListSubjectsRes{}, decodeError(err)
|
||||
}
|
||||
|
||||
lpr := res.(listSubjectsRes)
|
||||
return &magistrala.ListSubjectsRes{Policies: lpr.policies}, nil
|
||||
}
|
||||
|
||||
func (client grpcClient) CountSubjects(ctx context.Context, in *magistrala.CountSubjectsReq, opts ...grpc.CallOption) (*magistrala.CountSubjectsRes, error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, client.timeout)
|
||||
defer cancel()
|
||||
|
||||
res, err := client.countSubjects(ctx, countSubjectsReq{
|
||||
Domain: in.GetDomain(),
|
||||
SubjectType: in.GetSubjectType(),
|
||||
Subject: in.GetSubject(),
|
||||
Relation: in.GetRelation(),
|
||||
Permission: in.GetPermission(),
|
||||
ObjectType: in.GetObjectType(),
|
||||
Object: in.GetObject(),
|
||||
})
|
||||
if err != nil {
|
||||
return &magistrala.CountSubjectsRes{}, err
|
||||
}
|
||||
|
||||
cp := res.(countSubjectsRes)
|
||||
return &magistrala.CountSubjectsRes{Count: int64(cp.count)}, err
|
||||
}
|
||||
|
||||
func decodeCountSubjectsResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
res := grpcRes.(*magistrala.CountSubjectsRes)
|
||||
return countSubjectsRes{count: int(res.GetCount())}, nil
|
||||
}
|
||||
|
||||
func encodeCountSubjectsRequest(_ context.Context, grpcReq interface{}) (interface{}, error) {
|
||||
req := grpcReq.(countSubjectsReq)
|
||||
return &magistrala.CountSubjectsReq{
|
||||
Domain: req.Domain,
|
||||
SubjectType: req.SubjectType,
|
||||
Subject: req.Subject,
|
||||
Relation: req.Relation,
|
||||
Permission: req.Permission,
|
||||
ObjectType: req.ObjectType,
|
||||
Object: req.Object,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (client grpcClient) ListPermissions(ctx context.Context, in *magistrala.ListPermissionsReq, opts ...grpc.CallOption) (*magistrala.ListPermissionsRes, error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, client.timeout)
|
||||
defer cancel()
|
||||
|
||||
res, err := client.listPermissions(ctx, listPermissionsReq{
|
||||
Domain: in.GetDomain(),
|
||||
SubjectType: in.GetSubjectType(),
|
||||
Subject: in.GetSubject(),
|
||||
SubjectRelation: in.GetSubjectRelation(),
|
||||
ObjectType: in.GetObjectType(),
|
||||
Object: in.GetObject(),
|
||||
FilterPermissions: in.GetFilterPermissions(),
|
||||
})
|
||||
if err != nil {
|
||||
return &magistrala.ListPermissionsRes{}, decodeError(err)
|
||||
}
|
||||
|
||||
lp := res.(listPermissionsRes)
|
||||
return &magistrala.ListPermissionsRes{
|
||||
Domain: lp.Domain,
|
||||
SubjectType: lp.SubjectType,
|
||||
Subject: lp.Subject,
|
||||
SubjectRelation: lp.SubjectRelation,
|
||||
ObjectType: lp.ObjectType,
|
||||
Object: lp.Object,
|
||||
Permissions: lp.Permissions,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func decodeListPermissionsResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
res := grpcRes.(*magistrala.ListPermissionsRes)
|
||||
return listPermissionsRes{
|
||||
Domain: res.GetDomain(),
|
||||
SubjectType: res.GetSubjectType(),
|
||||
Subject: res.GetSubject(),
|
||||
SubjectRelation: res.GetSubjectRelation(),
|
||||
ObjectType: res.GetObjectType(),
|
||||
Object: res.GetObject(),
|
||||
Permissions: res.GetPermissions(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func encodeListPermissionsRequest(_ context.Context, grpcReq interface{}) (interface{}, error) {
|
||||
req := grpcReq.(listPermissionsReq)
|
||||
return &magistrala.ListPermissionsReq{
|
||||
Domain: req.Domain,
|
||||
SubjectType: req.SubjectType,
|
||||
Subject: req.Subject,
|
||||
ObjectType: req.ObjectType,
|
||||
Object: req.Object,
|
||||
FilterPermissions: req.FilterPermissions,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func decodeError(err error) error {
|
||||
if st, ok := status.FromError(err); ok {
|
||||
switch st.Code() {
|
||||
case codes.NotFound:
|
||||
return errors.Wrap(svcerr.ErrNotFound, errors.New(st.Message()))
|
||||
case codes.InvalidArgument:
|
||||
return errors.Wrap(errors.ErrMalformedEntity, errors.New(st.Message()))
|
||||
case codes.AlreadyExists:
|
||||
return errors.Wrap(svcerr.ErrConflict, errors.New(st.Message()))
|
||||
case codes.Unauthenticated:
|
||||
return errors.Wrap(svcerr.ErrAuthentication, errors.New(st.Message()))
|
||||
case codes.OK:
|
||||
if msg := st.Message(); msg != "" {
|
||||
return errors.Wrap(errors.ErrUnidentified, errors.New(msg))
|
||||
}
|
||||
return nil
|
||||
case codes.FailedPrecondition:
|
||||
return errors.Wrap(errors.ErrMalformedEntity, errors.New(st.Message()))
|
||||
case codes.PermissionDenied:
|
||||
return errors.Wrap(svcerr.ErrAuthorization, errors.New(st.Message()))
|
||||
default:
|
||||
return errors.Wrap(fmt.Errorf("unexpected gRPC status: %s (status code:%v)", st.Code().String(), st.Code()), errors.New(st.Message()))
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -1,352 +0,0 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package grpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/absmach/magistrala/auth"
|
||||
"github.com/go-kit/kit/endpoint"
|
||||
)
|
||||
|
||||
func issueEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
req := request.(issueReq)
|
||||
if err := req.validate(); err != nil {
|
||||
return issueRes{}, err
|
||||
}
|
||||
|
||||
key := auth.Key{
|
||||
Type: req.keyType,
|
||||
User: req.userID,
|
||||
Domain: req.domainID,
|
||||
OAuth: req.oauthToken,
|
||||
}
|
||||
tkn, err := svc.Issue(ctx, "", key)
|
||||
if err != nil {
|
||||
return issueRes{}, err
|
||||
}
|
||||
ret := issueRes{
|
||||
accessToken: tkn.AccessToken,
|
||||
refreshToken: tkn.RefreshToken,
|
||||
accessType: tkn.AccessType,
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
}
|
||||
|
||||
func refreshEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
req := request.(refreshReq)
|
||||
if err := req.validate(); err != nil {
|
||||
return issueRes{}, err
|
||||
}
|
||||
|
||||
key := auth.Key{Domain: req.domainID, Type: auth.RefreshKey}
|
||||
tkn, err := svc.Issue(ctx, req.refreshToken, key)
|
||||
if err != nil {
|
||||
return issueRes{}, err
|
||||
}
|
||||
ret := issueRes{
|
||||
accessToken: tkn.AccessToken,
|
||||
refreshToken: tkn.RefreshToken,
|
||||
accessType: tkn.AccessType,
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
}
|
||||
|
||||
func identifyEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
req := request.(identityReq)
|
||||
if err := req.validate(); err != nil {
|
||||
return identityRes{}, err
|
||||
}
|
||||
|
||||
key, err := svc.Identify(ctx, req.token)
|
||||
if err != nil {
|
||||
return identityRes{}, err
|
||||
}
|
||||
|
||||
return identityRes{id: key.Subject, userID: key.User, domainID: key.Domain}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func authorizeEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
req := request.(authReq)
|
||||
|
||||
if err := req.validate(); err != nil {
|
||||
return authorizeRes{}, err
|
||||
}
|
||||
err := svc.Authorize(ctx, auth.PolicyReq{
|
||||
Domain: req.Domain,
|
||||
SubjectType: req.SubjectType,
|
||||
SubjectKind: req.SubjectKind,
|
||||
Subject: req.Subject,
|
||||
Relation: req.Relation,
|
||||
Permission: req.Permission,
|
||||
ObjectType: req.ObjectType,
|
||||
Object: req.Object,
|
||||
})
|
||||
if err != nil {
|
||||
return authorizeRes{authorized: false}, err
|
||||
}
|
||||
return authorizeRes{authorized: true}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func addPolicyEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
req := request.(policyReq)
|
||||
if err := req.validate(); err != nil {
|
||||
return addPolicyRes{}, err
|
||||
}
|
||||
|
||||
err := svc.AddPolicy(ctx, auth.PolicyReq{
|
||||
Domain: req.Domain,
|
||||
SubjectType: req.SubjectType,
|
||||
SubjectKind: req.SubjectKind,
|
||||
Subject: req.Subject,
|
||||
Relation: req.Relation,
|
||||
Permission: req.Permission,
|
||||
ObjectType: req.ObjectType,
|
||||
ObjectKind: req.ObjectKind,
|
||||
Object: req.Object,
|
||||
})
|
||||
if err != nil {
|
||||
return addPolicyRes{}, err
|
||||
}
|
||||
return addPolicyRes{added: true}, err
|
||||
}
|
||||
}
|
||||
|
||||
func addPoliciesEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
reqs := request.(policiesReq)
|
||||
if err := reqs.validate(); err != nil {
|
||||
return addPoliciesRes{}, err
|
||||
}
|
||||
|
||||
prs := []auth.PolicyReq{}
|
||||
|
||||
for _, req := range reqs {
|
||||
prs = append(prs, auth.PolicyReq{
|
||||
Domain: req.Domain,
|
||||
SubjectType: req.SubjectType,
|
||||
SubjectKind: req.SubjectKind,
|
||||
Subject: req.Subject,
|
||||
Relation: req.Relation,
|
||||
Permission: req.Permission,
|
||||
ObjectType: req.ObjectType,
|
||||
ObjectKind: req.ObjectKind,
|
||||
Object: req.Object,
|
||||
})
|
||||
}
|
||||
|
||||
if err := svc.AddPolicies(ctx, prs); err != nil {
|
||||
return addPoliciesRes{}, err
|
||||
}
|
||||
return addPoliciesRes{added: true}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func deletePolicyEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
req := request.(policyReq)
|
||||
if err := req.validate(); err != nil {
|
||||
return deletePolicyRes{}, err
|
||||
}
|
||||
|
||||
err := svc.DeletePolicy(ctx, auth.PolicyReq{
|
||||
Domain: req.Domain,
|
||||
SubjectKind: req.SubjectKind,
|
||||
SubjectType: req.SubjectType,
|
||||
Subject: req.Subject,
|
||||
Relation: req.Relation,
|
||||
Permission: req.Permission,
|
||||
ObjectType: req.ObjectType,
|
||||
ObjectKind: req.ObjectKind,
|
||||
Object: req.Object,
|
||||
})
|
||||
if err != nil {
|
||||
return deletePolicyRes{}, err
|
||||
}
|
||||
return deletePolicyRes{deleted: true}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func deletePoliciesEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
reqs := request.(policiesReq)
|
||||
if err := reqs.validate(); err != nil {
|
||||
return deletePoliciesRes{}, err
|
||||
}
|
||||
|
||||
prs := []auth.PolicyReq{}
|
||||
|
||||
for _, req := range reqs {
|
||||
prs = append(prs, auth.PolicyReq{
|
||||
Domain: req.Domain,
|
||||
SubjectType: req.SubjectType,
|
||||
SubjectKind: req.SubjectKind,
|
||||
Subject: req.Subject,
|
||||
Relation: req.Relation,
|
||||
Permission: req.Permission,
|
||||
ObjectType: req.ObjectType,
|
||||
ObjectKind: req.ObjectKind,
|
||||
Object: req.Object,
|
||||
})
|
||||
}
|
||||
|
||||
if err := svc.DeletePolicies(ctx, prs); err != nil {
|
||||
return deletePoliciesRes{}, err
|
||||
}
|
||||
return deletePoliciesRes{deleted: true}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func listObjectsEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
req := request.(listObjectsReq)
|
||||
|
||||
page, err := svc.ListObjects(ctx, auth.PolicyReq{
|
||||
Domain: req.Domain,
|
||||
SubjectType: req.SubjectType,
|
||||
Subject: req.Subject,
|
||||
Relation: req.Relation,
|
||||
Permission: req.Permission,
|
||||
ObjectType: req.ObjectType,
|
||||
Object: req.Object,
|
||||
}, req.NextPageToken, req.Limit)
|
||||
if err != nil {
|
||||
return listObjectsRes{}, err
|
||||
}
|
||||
return listObjectsRes{policies: page.Policies, nextPageToken: page.NextPageToken}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func listAllObjectsEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
req := request.(listObjectsReq)
|
||||
|
||||
page, err := svc.ListAllObjects(ctx, auth.PolicyReq{
|
||||
Domain: req.Domain,
|
||||
SubjectType: req.SubjectType,
|
||||
Subject: req.Subject,
|
||||
Relation: req.Relation,
|
||||
Permission: req.Permission,
|
||||
ObjectType: req.ObjectType,
|
||||
Object: req.Object,
|
||||
})
|
||||
if err != nil {
|
||||
return listObjectsRes{}, err
|
||||
}
|
||||
return listObjectsRes{policies: page.Policies, nextPageToken: page.NextPageToken}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func countObjectsEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
req := request.(countObjectsReq)
|
||||
|
||||
count, err := svc.CountObjects(ctx, auth.PolicyReq{
|
||||
Domain: req.Domain,
|
||||
SubjectType: req.SubjectType,
|
||||
Subject: req.Subject,
|
||||
Relation: req.Relation,
|
||||
Permission: req.Permission,
|
||||
ObjectType: req.ObjectType,
|
||||
Object: req.Object,
|
||||
})
|
||||
if err != nil {
|
||||
return countObjectsRes{}, err
|
||||
}
|
||||
return countObjectsRes{count: count}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func listSubjectsEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
req := request.(listSubjectsReq)
|
||||
|
||||
page, err := svc.ListSubjects(ctx, auth.PolicyReq{
|
||||
Domain: req.Domain,
|
||||
SubjectType: req.SubjectType,
|
||||
Subject: req.Subject,
|
||||
Relation: req.Relation,
|
||||
Permission: req.Permission,
|
||||
ObjectType: req.ObjectType,
|
||||
Object: req.Object,
|
||||
}, req.NextPageToken, req.Limit)
|
||||
if err != nil {
|
||||
return listSubjectsRes{}, err
|
||||
}
|
||||
return listSubjectsRes{policies: page.Policies, nextPageToken: page.NextPageToken}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func listAllSubjectsEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
req := request.(listSubjectsReq)
|
||||
|
||||
page, err := svc.ListAllSubjects(ctx, auth.PolicyReq{
|
||||
Domain: req.Domain,
|
||||
SubjectType: req.SubjectType,
|
||||
Subject: req.Subject,
|
||||
Relation: req.Relation,
|
||||
Permission: req.Permission,
|
||||
ObjectType: req.ObjectType,
|
||||
Object: req.Object,
|
||||
})
|
||||
if err != nil {
|
||||
return listSubjectsRes{}, err
|
||||
}
|
||||
return listSubjectsRes{policies: page.Policies, nextPageToken: page.NextPageToken}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func countSubjectsEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
req := request.(countSubjectsReq)
|
||||
|
||||
count, err := svc.CountSubjects(ctx, auth.PolicyReq{
|
||||
Domain: req.Domain,
|
||||
SubjectType: req.SubjectType,
|
||||
Subject: req.Subject,
|
||||
Relation: req.Relation,
|
||||
Permission: req.Permission,
|
||||
ObjectType: req.ObjectType,
|
||||
Object: req.Object,
|
||||
})
|
||||
if err != nil {
|
||||
return countSubjectsRes{}, err
|
||||
}
|
||||
return countSubjectsRes{count: count}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func listPermissionsEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
req := request.(listPermissionsReq)
|
||||
permissions, err := svc.ListPermissions(ctx, auth.PolicyReq{
|
||||
SubjectType: req.SubjectType,
|
||||
SubjectRelation: req.SubjectRelation,
|
||||
Subject: req.Subject,
|
||||
Object: req.Object,
|
||||
ObjectType: req.ObjectType,
|
||||
}, req.FilterPermissions)
|
||||
if err != nil {
|
||||
return listPermissionsRes{}, err
|
||||
}
|
||||
return listPermissionsRes{
|
||||
SubjectType: req.SubjectType,
|
||||
SubjectRelation: req.SubjectRelation,
|
||||
Subject: req.Subject,
|
||||
Object: req.Object,
|
||||
ObjectType: req.ObjectType,
|
||||
Permissions: permissions,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,161 +0,0 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package grpc
|
||||
|
||||
import (
|
||||
"github.com/absmach/magistrala/auth"
|
||||
"github.com/absmach/magistrala/internal/apiutil"
|
||||
)
|
||||
|
||||
type identityReq struct {
|
||||
token string
|
||||
}
|
||||
|
||||
func (req identityReq) validate() error {
|
||||
if req.token == "" {
|
||||
return apiutil.ErrBearerToken
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type issueReq struct {
|
||||
userID string
|
||||
domainID string // optional
|
||||
keyType auth.KeyType
|
||||
oauthToken auth.OAuthToken
|
||||
}
|
||||
|
||||
func (req issueReq) validate() error {
|
||||
if req.keyType != auth.AccessKey &&
|
||||
req.keyType != auth.APIKey &&
|
||||
req.keyType != auth.RecoveryKey &&
|
||||
req.keyType != auth.InvitationKey {
|
||||
return apiutil.ErrInvalidAuthKey
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type refreshReq struct {
|
||||
refreshToken string
|
||||
domainID string // optional
|
||||
}
|
||||
|
||||
func (req refreshReq) validate() error {
|
||||
if req.refreshToken == "" {
|
||||
return apiutil.ErrMissingSecret
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// authReq represents authorization request. It contains:
|
||||
// 1. subject - an action invoker
|
||||
// 2. object - an entity over which action will be executed
|
||||
// 3. action - type of action that will be executed (read/write).
|
||||
type authReq struct {
|
||||
Domain string
|
||||
SubjectType string
|
||||
SubjectKind string
|
||||
Subject string
|
||||
Relation string
|
||||
Permission string
|
||||
ObjectType string
|
||||
Object string
|
||||
}
|
||||
|
||||
func (req authReq) validate() error {
|
||||
if req.Subject == "" || req.SubjectType == "" {
|
||||
return apiutil.ErrMissingPolicySub
|
||||
}
|
||||
|
||||
if req.Object == "" || req.ObjectType == "" {
|
||||
return apiutil.ErrMissingPolicyObj
|
||||
}
|
||||
|
||||
if req.Permission == "" {
|
||||
return apiutil.ErrMalformedPolicyPer
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type policyReq struct {
|
||||
Domain string
|
||||
SubjectType string
|
||||
Subject string
|
||||
SubjectKind string
|
||||
Relation string
|
||||
Permission string
|
||||
ObjectType string
|
||||
ObjectKind string
|
||||
Object string
|
||||
}
|
||||
|
||||
func (req policyReq) validate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type policiesReq []policyReq
|
||||
|
||||
func (prs policiesReq) validate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type listObjectsReq struct {
|
||||
Domain string
|
||||
SubjectType string
|
||||
Subject string
|
||||
Relation string
|
||||
Permission string
|
||||
ObjectType string
|
||||
Object string
|
||||
NextPageToken string
|
||||
Limit int32
|
||||
}
|
||||
|
||||
type countObjectsReq struct {
|
||||
Domain string
|
||||
SubjectType string
|
||||
Subject string
|
||||
Relation string
|
||||
Permission string
|
||||
ObjectType string
|
||||
Object string
|
||||
NextPageToken string
|
||||
}
|
||||
|
||||
type listSubjectsReq struct {
|
||||
Domain string
|
||||
SubjectType string
|
||||
Subject string
|
||||
Relation string
|
||||
Permission string
|
||||
ObjectType string
|
||||
Object string
|
||||
NextPageToken string
|
||||
Limit int32
|
||||
}
|
||||
|
||||
type countSubjectsReq struct {
|
||||
Domain string
|
||||
SubjectType string
|
||||
Subject string
|
||||
Relation string
|
||||
Permission string
|
||||
ObjectType string
|
||||
Object string
|
||||
NextPageToken string
|
||||
}
|
||||
|
||||
type listPermissionsReq struct {
|
||||
Domain string
|
||||
SubjectType string
|
||||
Subject string
|
||||
SubjectRelation string
|
||||
ObjectType string
|
||||
Object string
|
||||
FilterPermissions []string
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package grpc
|
||||
|
||||
type identityRes struct {
|
||||
id string
|
||||
userID string
|
||||
domainID string
|
||||
}
|
||||
|
||||
type issueRes struct {
|
||||
accessToken string
|
||||
refreshToken string
|
||||
accessType string
|
||||
}
|
||||
|
||||
type authorizeRes struct {
|
||||
id string
|
||||
authorized bool
|
||||
}
|
||||
|
||||
type addPolicyRes struct {
|
||||
added bool
|
||||
}
|
||||
type addPoliciesRes struct {
|
||||
added bool
|
||||
}
|
||||
|
||||
type deletePolicyRes struct {
|
||||
deleted bool
|
||||
}
|
||||
|
||||
type deletePoliciesRes struct {
|
||||
deleted bool
|
||||
}
|
||||
|
||||
type listObjectsRes struct {
|
||||
policies []string
|
||||
nextPageToken string
|
||||
}
|
||||
|
||||
type countObjectsRes struct {
|
||||
count int
|
||||
}
|
||||
|
||||
type listSubjectsRes struct {
|
||||
policies []string
|
||||
nextPageToken string
|
||||
}
|
||||
|
||||
type countSubjectsRes struct {
|
||||
count int
|
||||
}
|
||||
|
||||
type listPermissionsRes struct {
|
||||
Domain string
|
||||
SubjectType string
|
||||
Subject string
|
||||
SubjectRelation string
|
||||
ObjectType string
|
||||
Object string
|
||||
Permissions []string
|
||||
}
|
||||
@@ -1,565 +0,0 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package grpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/absmach/magistrala"
|
||||
"github.com/absmach/magistrala/auth"
|
||||
"github.com/absmach/magistrala/internal/apiutil"
|
||||
"github.com/absmach/magistrala/pkg/errors"
|
||||
svcerr "github.com/absmach/magistrala/pkg/errors/service"
|
||||
kitgrpc "github.com/go-kit/kit/transport/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
var _ magistrala.AuthServiceServer = (*grpcServer)(nil)
|
||||
|
||||
var (
|
||||
defThingsFilterPermissions = []string{
|
||||
auth.AdminPermission,
|
||||
auth.DeletePermission,
|
||||
auth.EditPermission,
|
||||
auth.ViewPermission,
|
||||
auth.SharePermission,
|
||||
auth.PublishPermission,
|
||||
auth.SubscribePermission,
|
||||
}
|
||||
|
||||
defGroupsFilterPermissions = []string{
|
||||
auth.AdminPermission,
|
||||
auth.DeletePermission,
|
||||
auth.EditPermission,
|
||||
auth.ViewPermission,
|
||||
auth.MembershipPermission,
|
||||
auth.SharePermission,
|
||||
}
|
||||
|
||||
defDomainsFilterPermissions = []string{
|
||||
auth.AdminPermission,
|
||||
auth.EditPermission,
|
||||
auth.ViewPermission,
|
||||
auth.MembershipPermission,
|
||||
auth.SharePermission,
|
||||
}
|
||||
defPlatformFilterPermissions = []string{
|
||||
auth.AdminPermission,
|
||||
auth.MembershipPermission,
|
||||
}
|
||||
)
|
||||
|
||||
type grpcServer struct {
|
||||
magistrala.UnimplementedAuthServiceServer
|
||||
issue kitgrpc.Handler
|
||||
refresh kitgrpc.Handler
|
||||
identify kitgrpc.Handler
|
||||
authorize kitgrpc.Handler
|
||||
addPolicy kitgrpc.Handler
|
||||
addPolicies kitgrpc.Handler
|
||||
deletePolicy kitgrpc.Handler
|
||||
deletePolicies kitgrpc.Handler
|
||||
listObjects kitgrpc.Handler
|
||||
listAllObjects kitgrpc.Handler
|
||||
countObjects kitgrpc.Handler
|
||||
listSubjects kitgrpc.Handler
|
||||
listAllSubjects kitgrpc.Handler
|
||||
countSubjects kitgrpc.Handler
|
||||
listPermissions kitgrpc.Handler
|
||||
}
|
||||
|
||||
// NewServer returns new AuthServiceServer instance.
|
||||
func NewServer(svc auth.Service) magistrala.AuthServiceServer {
|
||||
return &grpcServer{
|
||||
issue: kitgrpc.NewServer(
|
||||
(issueEndpoint(svc)),
|
||||
decodeIssueRequest,
|
||||
encodeIssueResponse,
|
||||
),
|
||||
refresh: kitgrpc.NewServer(
|
||||
(refreshEndpoint(svc)),
|
||||
decodeRefreshRequest,
|
||||
encodeIssueResponse,
|
||||
),
|
||||
identify: kitgrpc.NewServer(
|
||||
(identifyEndpoint(svc)),
|
||||
decodeIdentifyRequest,
|
||||
encodeIdentifyResponse,
|
||||
),
|
||||
authorize: kitgrpc.NewServer(
|
||||
(authorizeEndpoint(svc)),
|
||||
decodeAuthorizeRequest,
|
||||
encodeAuthorizeResponse,
|
||||
),
|
||||
addPolicy: kitgrpc.NewServer(
|
||||
(addPolicyEndpoint(svc)),
|
||||
decodeAddPolicyRequest,
|
||||
encodeAddPolicyResponse,
|
||||
),
|
||||
addPolicies: kitgrpc.NewServer(
|
||||
(addPoliciesEndpoint(svc)),
|
||||
decodeAddPoliciesRequest,
|
||||
encodeAddPoliciesResponse,
|
||||
),
|
||||
deletePolicy: kitgrpc.NewServer(
|
||||
(deletePolicyEndpoint(svc)),
|
||||
decodeDeletePolicyRequest,
|
||||
encodeDeletePolicyResponse,
|
||||
),
|
||||
deletePolicies: kitgrpc.NewServer(
|
||||
(deletePoliciesEndpoint(svc)),
|
||||
decodeDeletePoliciesRequest,
|
||||
encodeDeletePoliciesResponse,
|
||||
),
|
||||
listObjects: kitgrpc.NewServer(
|
||||
(listObjectsEndpoint(svc)),
|
||||
decodeListObjectsRequest,
|
||||
encodeListObjectsResponse,
|
||||
),
|
||||
listAllObjects: kitgrpc.NewServer(
|
||||
(listAllObjectsEndpoint(svc)),
|
||||
decodeListObjectsRequest,
|
||||
encodeListObjectsResponse,
|
||||
),
|
||||
countObjects: kitgrpc.NewServer(
|
||||
(countObjectsEndpoint(svc)),
|
||||
decodeCountObjectsRequest,
|
||||
encodeCountObjectsResponse,
|
||||
),
|
||||
listSubjects: kitgrpc.NewServer(
|
||||
(listSubjectsEndpoint(svc)),
|
||||
decodeListSubjectsRequest,
|
||||
encodeListSubjectsResponse,
|
||||
),
|
||||
listAllSubjects: kitgrpc.NewServer(
|
||||
(listAllSubjectsEndpoint(svc)),
|
||||
decodeListSubjectsRequest,
|
||||
encodeListSubjectsResponse,
|
||||
),
|
||||
countSubjects: kitgrpc.NewServer(
|
||||
(countSubjectsEndpoint(svc)),
|
||||
decodeCountSubjectsRequest,
|
||||
encodeCountSubjectsResponse,
|
||||
),
|
||||
listPermissions: kitgrpc.NewServer(
|
||||
(listPermissionsEndpoint(svc)),
|
||||
decodeListPermissionsRequest,
|
||||
encodeListPermissionsResponse,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
func (s *grpcServer) Issue(ctx context.Context, req *magistrala.IssueReq) (*magistrala.Token, error) {
|
||||
_, res, err := s.issue.ServeGRPC(ctx, req)
|
||||
if err != nil {
|
||||
return nil, encodeError(err)
|
||||
}
|
||||
return res.(*magistrala.Token), nil
|
||||
}
|
||||
|
||||
func (s *grpcServer) Refresh(ctx context.Context, req *magistrala.RefreshReq) (*magistrala.Token, error) {
|
||||
_, res, err := s.refresh.ServeGRPC(ctx, req)
|
||||
if err != nil {
|
||||
return nil, encodeError(err)
|
||||
}
|
||||
return res.(*magistrala.Token), nil
|
||||
}
|
||||
|
||||
func (s *grpcServer) Identify(ctx context.Context, token *magistrala.IdentityReq) (*magistrala.IdentityRes, error) {
|
||||
_, res, err := s.identify.ServeGRPC(ctx, token)
|
||||
if err != nil {
|
||||
return nil, encodeError(err)
|
||||
}
|
||||
return res.(*magistrala.IdentityRes), nil
|
||||
}
|
||||
|
||||
func (s *grpcServer) Authorize(ctx context.Context, req *magistrala.AuthorizeReq) (*magistrala.AuthorizeRes, error) {
|
||||
_, res, err := s.authorize.ServeGRPC(ctx, req)
|
||||
if err != nil {
|
||||
return nil, encodeError(err)
|
||||
}
|
||||
return res.(*magistrala.AuthorizeRes), nil
|
||||
}
|
||||
|
||||
func (s *grpcServer) AddPolicy(ctx context.Context, req *magistrala.AddPolicyReq) (*magistrala.AddPolicyRes, error) {
|
||||
_, res, err := s.addPolicy.ServeGRPC(ctx, req)
|
||||
if err != nil {
|
||||
return nil, encodeError(err)
|
||||
}
|
||||
return res.(*magistrala.AddPolicyRes), nil
|
||||
}
|
||||
|
||||
func (s *grpcServer) AddPolicies(ctx context.Context, req *magistrala.AddPoliciesReq) (*magistrala.AddPoliciesRes, error) {
|
||||
_, res, err := s.addPolicies.ServeGRPC(ctx, req)
|
||||
if err != nil {
|
||||
return nil, encodeError(err)
|
||||
}
|
||||
return res.(*magistrala.AddPoliciesRes), nil
|
||||
}
|
||||
|
||||
func (s *grpcServer) DeletePolicy(ctx context.Context, req *magistrala.DeletePolicyReq) (*magistrala.DeletePolicyRes, error) {
|
||||
_, res, err := s.deletePolicy.ServeGRPC(ctx, req)
|
||||
if err != nil {
|
||||
return nil, encodeError(err)
|
||||
}
|
||||
return res.(*magistrala.DeletePolicyRes), nil
|
||||
}
|
||||
|
||||
func (s *grpcServer) DeletePolicies(ctx context.Context, req *magistrala.DeletePoliciesReq) (*magistrala.DeletePoliciesRes, error) {
|
||||
_, res, err := s.deletePolicies.ServeGRPC(ctx, req)
|
||||
if err != nil {
|
||||
return nil, encodeError(err)
|
||||
}
|
||||
return res.(*magistrala.DeletePoliciesRes), nil
|
||||
}
|
||||
|
||||
func (s *grpcServer) ListObjects(ctx context.Context, req *magistrala.ListObjectsReq) (*magistrala.ListObjectsRes, error) {
|
||||
_, res, err := s.listObjects.ServeGRPC(ctx, req)
|
||||
if err != nil {
|
||||
return nil, encodeError(err)
|
||||
}
|
||||
return res.(*magistrala.ListObjectsRes), nil
|
||||
}
|
||||
|
||||
func (s *grpcServer) ListAllObjects(ctx context.Context, req *magistrala.ListObjectsReq) (*magistrala.ListObjectsRes, error) {
|
||||
_, res, err := s.listAllObjects.ServeGRPC(ctx, req)
|
||||
if err != nil {
|
||||
return nil, encodeError(err)
|
||||
}
|
||||
return res.(*magistrala.ListObjectsRes), nil
|
||||
}
|
||||
|
||||
func (s *grpcServer) CountObjects(ctx context.Context, req *magistrala.CountObjectsReq) (*magistrala.CountObjectsRes, error) {
|
||||
_, res, err := s.countObjects.ServeGRPC(ctx, req)
|
||||
if err != nil {
|
||||
return nil, encodeError(err)
|
||||
}
|
||||
return res.(*magistrala.CountObjectsRes), nil
|
||||
}
|
||||
|
||||
func (s *grpcServer) ListSubjects(ctx context.Context, req *magistrala.ListSubjectsReq) (*magistrala.ListSubjectsRes, error) {
|
||||
_, res, err := s.listSubjects.ServeGRPC(ctx, req)
|
||||
if err != nil {
|
||||
return nil, encodeError(err)
|
||||
}
|
||||
return res.(*magistrala.ListSubjectsRes), nil
|
||||
}
|
||||
|
||||
func (s *grpcServer) ListAllSubjects(ctx context.Context, req *magistrala.ListSubjectsReq) (*magistrala.ListSubjectsRes, error) {
|
||||
_, res, err := s.listAllSubjects.ServeGRPC(ctx, req)
|
||||
if err != nil {
|
||||
return nil, encodeError(err)
|
||||
}
|
||||
return res.(*magistrala.ListSubjectsRes), nil
|
||||
}
|
||||
|
||||
func (s *grpcServer) CountSubjects(ctx context.Context, req *magistrala.CountSubjectsReq) (*magistrala.CountSubjectsRes, error) {
|
||||
_, res, err := s.countSubjects.ServeGRPC(ctx, req)
|
||||
if err != nil {
|
||||
return nil, encodeError(err)
|
||||
}
|
||||
return res.(*magistrala.CountSubjectsRes), nil
|
||||
}
|
||||
|
||||
func (s *grpcServer) ListPermissions(ctx context.Context, req *magistrala.ListPermissionsReq) (*magistrala.ListPermissionsRes, error) {
|
||||
_, res, err := s.listPermissions.ServeGRPC(ctx, req)
|
||||
if err != nil {
|
||||
return nil, encodeError(err)
|
||||
}
|
||||
return res.(*magistrala.ListPermissionsRes), nil
|
||||
}
|
||||
|
||||
func decodeIssueRequest(_ context.Context, grpcReq interface{}) (interface{}, error) {
|
||||
req := grpcReq.(*magistrala.IssueReq)
|
||||
return issueReq{
|
||||
userID: req.GetUserId(),
|
||||
domainID: req.GetDomainId(),
|
||||
keyType: auth.KeyType(req.GetType()),
|
||||
oauthToken: auth.OAuthToken{
|
||||
Provider: req.GetOauthProvider(),
|
||||
AccessToken: req.GetOauthAccessToken(),
|
||||
RefreshToken: req.GetOauthRefreshToken(),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func decodeRefreshRequest(_ context.Context, grpcReq interface{}) (interface{}, error) {
|
||||
req := grpcReq.(*magistrala.RefreshReq)
|
||||
return refreshReq{refreshToken: req.GetRefreshToken(), domainID: req.GetDomainId()}, nil
|
||||
}
|
||||
|
||||
func encodeIssueResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
res := grpcRes.(issueRes)
|
||||
|
||||
return &magistrala.Token{
|
||||
AccessToken: res.accessToken,
|
||||
RefreshToken: &res.refreshToken,
|
||||
AccessType: res.accessType,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func decodeIdentifyRequest(_ context.Context, grpcReq interface{}) (interface{}, error) {
|
||||
req := grpcReq.(*magistrala.IdentityReq)
|
||||
return identityReq{token: req.GetToken()}, nil
|
||||
}
|
||||
|
||||
func encodeIdentifyResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
res := grpcRes.(identityRes)
|
||||
return &magistrala.IdentityRes{Id: res.id, UserId: res.userID, DomainId: res.domainID}, nil
|
||||
}
|
||||
|
||||
func decodeAuthorizeRequest(_ context.Context, grpcReq interface{}) (interface{}, error) {
|
||||
req := grpcReq.(*magistrala.AuthorizeReq)
|
||||
return authReq{
|
||||
Domain: req.GetDomain(),
|
||||
SubjectType: req.GetSubjectType(),
|
||||
SubjectKind: req.GetSubjectKind(),
|
||||
Subject: req.GetSubject(),
|
||||
Relation: req.GetRelation(),
|
||||
Permission: req.GetPermission(),
|
||||
ObjectType: req.GetObjectType(),
|
||||
Object: req.GetObject(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func encodeAuthorizeResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
res := grpcRes.(authorizeRes)
|
||||
return &magistrala.AuthorizeRes{Authorized: res.authorized, Id: res.id}, nil
|
||||
}
|
||||
|
||||
func decodeAddPolicyRequest(_ context.Context, grpcReq interface{}) (interface{}, error) {
|
||||
req := grpcReq.(*magistrala.AddPolicyReq)
|
||||
return policyReq{
|
||||
Domain: req.GetDomain(),
|
||||
SubjectType: req.GetSubjectType(),
|
||||
SubjectKind: req.GetSubjectKind(),
|
||||
Subject: req.GetSubject(),
|
||||
Relation: req.GetRelation(),
|
||||
Permission: req.GetPermission(),
|
||||
ObjectType: req.GetObjectType(),
|
||||
ObjectKind: req.GetObjectKind(),
|
||||
Object: req.GetObject(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func encodeAddPolicyResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
res := grpcRes.(addPolicyRes)
|
||||
return &magistrala.AddPolicyRes{Added: res.added}, nil
|
||||
}
|
||||
|
||||
func decodeAddPoliciesRequest(_ context.Context, grpcReq interface{}) (interface{}, error) {
|
||||
reqs := grpcReq.(*magistrala.AddPoliciesReq)
|
||||
r := policiesReq{}
|
||||
for _, req := range reqs.AddPoliciesReq {
|
||||
r = append(r, policyReq{
|
||||
Domain: req.GetDomain(),
|
||||
SubjectType: req.GetSubjectType(),
|
||||
SubjectKind: req.GetSubjectKind(),
|
||||
Subject: req.GetSubject(),
|
||||
Relation: req.GetRelation(),
|
||||
Permission: req.GetPermission(),
|
||||
ObjectType: req.GetObjectType(),
|
||||
ObjectKind: req.GetObjectKind(),
|
||||
Object: req.GetObject(),
|
||||
})
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func encodeAddPoliciesResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
res := grpcRes.(addPoliciesRes)
|
||||
return &magistrala.AddPoliciesRes{Added: res.added}, nil
|
||||
}
|
||||
|
||||
func decodeDeletePolicyRequest(_ context.Context, grpcReq interface{}) (interface{}, error) {
|
||||
req := grpcReq.(*magistrala.DeletePolicyReq)
|
||||
return policyReq{
|
||||
Domain: req.GetDomain(),
|
||||
SubjectType: req.GetSubjectType(),
|
||||
SubjectKind: req.GetSubjectKind(),
|
||||
Subject: req.GetSubject(),
|
||||
Relation: req.GetRelation(),
|
||||
Permission: req.GetPermission(),
|
||||
ObjectType: req.GetObjectType(),
|
||||
ObjectKind: req.GetObjectKind(),
|
||||
Object: req.GetObject(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func encodeDeletePolicyResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
res := grpcRes.(deletePolicyRes)
|
||||
return &magistrala.DeletePolicyRes{Deleted: res.deleted}, nil
|
||||
}
|
||||
|
||||
func decodeDeletePoliciesRequest(_ context.Context, grpcReq interface{}) (interface{}, error) {
|
||||
reqs := grpcReq.(*magistrala.DeletePoliciesReq)
|
||||
r := policiesReq{}
|
||||
for _, req := range reqs.DeletePoliciesReq {
|
||||
r = append(r, policyReq{
|
||||
Domain: req.GetDomain(),
|
||||
SubjectType: req.GetSubjectType(),
|
||||
SubjectKind: req.GetSubjectKind(),
|
||||
Subject: req.GetSubject(),
|
||||
Relation: req.GetRelation(),
|
||||
Permission: req.GetPermission(),
|
||||
ObjectType: req.GetObjectType(),
|
||||
ObjectKind: req.GetObjectKind(),
|
||||
Object: req.GetObject(),
|
||||
})
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func encodeDeletePoliciesResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
res := grpcRes.(deletePoliciesRes)
|
||||
return &magistrala.DeletePoliciesRes{Deleted: res.deleted}, nil
|
||||
}
|
||||
|
||||
func decodeListObjectsRequest(_ context.Context, grpcReq interface{}) (interface{}, error) {
|
||||
req := grpcReq.(*magistrala.ListObjectsReq)
|
||||
return listObjectsReq{
|
||||
Domain: req.GetDomain(),
|
||||
SubjectType: req.GetSubjectType(),
|
||||
Subject: req.GetSubject(),
|
||||
Relation: req.GetRelation(),
|
||||
Permission: req.GetPermission(),
|
||||
ObjectType: req.GetObjectType(),
|
||||
Object: req.GetObject(),
|
||||
NextPageToken: req.GetNextPageToken(),
|
||||
Limit: req.GetLimit(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func encodeListObjectsResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
res := grpcRes.(listObjectsRes)
|
||||
return &magistrala.ListObjectsRes{Policies: res.policies}, nil
|
||||
}
|
||||
|
||||
func decodeCountObjectsRequest(_ context.Context, grpcReq interface{}) (interface{}, error) {
|
||||
req := grpcReq.(*magistrala.CountObjectsReq)
|
||||
return countObjectsReq{
|
||||
Domain: req.GetDomain(),
|
||||
SubjectType: req.GetSubjectType(),
|
||||
Subject: req.GetSubject(),
|
||||
Relation: req.GetRelation(),
|
||||
Permission: req.GetPermission(),
|
||||
ObjectType: req.GetObjectType(),
|
||||
Object: req.GetObject(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func encodeCountObjectsResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
res := grpcRes.(countObjectsRes)
|
||||
return &magistrala.CountObjectsRes{Count: int64(res.count)}, nil
|
||||
}
|
||||
|
||||
func decodeListSubjectsRequest(_ context.Context, grpcReq interface{}) (interface{}, error) {
|
||||
req := grpcReq.(*magistrala.ListSubjectsReq)
|
||||
return listSubjectsReq{
|
||||
Domain: req.GetDomain(),
|
||||
SubjectType: req.GetSubjectType(),
|
||||
Subject: req.GetSubject(),
|
||||
Relation: req.GetRelation(),
|
||||
Permission: req.GetPermission(),
|
||||
ObjectType: req.GetObjectType(),
|
||||
Object: req.GetObject(), NextPageToken: req.GetNextPageToken(), Limit: req.GetLimit(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func encodeListSubjectsResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
res := grpcRes.(listSubjectsRes)
|
||||
return &magistrala.ListSubjectsRes{Policies: res.policies}, nil
|
||||
}
|
||||
|
||||
func decodeCountSubjectsRequest(_ context.Context, grpcReq interface{}) (interface{}, error) {
|
||||
req := grpcReq.(*magistrala.CountSubjectsReq)
|
||||
return countSubjectsReq{
|
||||
Domain: req.GetDomain(),
|
||||
SubjectType: req.GetSubjectType(),
|
||||
Subject: req.GetSubject(),
|
||||
Relation: req.GetRelation(),
|
||||
Permission: req.GetPermission(),
|
||||
ObjectType: req.GetObjectType(),
|
||||
Object: req.GetObject(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func encodeCountSubjectsResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
res := grpcRes.(countSubjectsRes)
|
||||
return &magistrala.CountSubjectsRes{Count: int64(res.count)}, nil
|
||||
}
|
||||
|
||||
func decodeListPermissionsRequest(_ context.Context, grpcReq interface{}) (interface{}, error) {
|
||||
req := grpcReq.(*magistrala.ListPermissionsReq)
|
||||
var fp []string
|
||||
|
||||
switch req.GetObjectType() {
|
||||
case auth.ThingType:
|
||||
fp = defThingsFilterPermissions
|
||||
case auth.GroupType:
|
||||
fp = defGroupsFilterPermissions
|
||||
case auth.PlatformType:
|
||||
fp = defPlatformFilterPermissions
|
||||
case auth.DomainType:
|
||||
fp = defDomainsFilterPermissions
|
||||
default:
|
||||
return nil, apiutil.ErrMalformedPolicy
|
||||
}
|
||||
if len(req.GetFilterPermissions()) > 0 {
|
||||
fp = req.GetFilterPermissions()
|
||||
}
|
||||
return listPermissionsReq{
|
||||
Domain: req.GetDomain(),
|
||||
SubjectType: req.GetSubjectType(),
|
||||
Subject: req.GetSubject(),
|
||||
SubjectRelation: req.GetSubjectRelation(),
|
||||
ObjectType: req.GetObjectType(),
|
||||
Object: req.GetObject(),
|
||||
FilterPermissions: fp,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func encodeListPermissionsResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
res := grpcRes.(listPermissionsRes)
|
||||
return &magistrala.ListPermissionsRes{
|
||||
Domain: res.Domain,
|
||||
SubjectType: res.SubjectType,
|
||||
Subject: res.Subject,
|
||||
SubjectRelation: res.SubjectRelation,
|
||||
ObjectType: res.ObjectType,
|
||||
Object: res.Object,
|
||||
Permissions: res.Permissions,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func encodeError(err error) error {
|
||||
switch {
|
||||
case errors.Contains(err, nil):
|
||||
return nil
|
||||
case errors.Contains(err, errors.ErrMalformedEntity),
|
||||
errors.Contains(err, svcerr.ErrInvalidPolicy),
|
||||
err == apiutil.ErrInvalidAuthKey,
|
||||
err == apiutil.ErrMissingID,
|
||||
err == apiutil.ErrMissingMemberType,
|
||||
err == apiutil.ErrMissingPolicySub,
|
||||
err == apiutil.ErrMissingPolicyObj,
|
||||
err == apiutil.ErrMalformedPolicyAct:
|
||||
return status.Error(codes.InvalidArgument, err.Error())
|
||||
case errors.Contains(err, svcerr.ErrAuthentication),
|
||||
errors.Contains(err, auth.ErrKeyExpired),
|
||||
err == apiutil.ErrMissingEmail,
|
||||
err == apiutil.ErrBearerToken:
|
||||
return status.Error(codes.Unauthenticated, err.Error())
|
||||
case errors.Contains(err, svcerr.ErrAuthorization),
|
||||
errors.Contains(err, svcerr.ErrDomainAuthorization):
|
||||
return status.Error(codes.PermissionDenied, err.Error())
|
||||
case errors.Contains(err, svcerr.ErrNotFound):
|
||||
return status.Error(codes.NotFound, err.Error())
|
||||
case errors.Contains(err, svcerr.ErrConflict):
|
||||
return status.Error(codes.AlreadyExists, err.Error())
|
||||
default:
|
||||
return status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package token
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
grpcTokenV1 "github.com/absmach/magistrala/api/grpc/token/v1"
|
||||
"github.com/absmach/magistrala/auth"
|
||||
grpcapi "github.com/absmach/magistrala/auth/api/grpc"
|
||||
"github.com/go-kit/kit/endpoint"
|
||||
kitgrpc "github.com/go-kit/kit/transport/grpc"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
const tokenSvcName = "token.v1.TokenService"
|
||||
|
||||
type tokenGrpcClient struct {
|
||||
issue endpoint.Endpoint
|
||||
refresh endpoint.Endpoint
|
||||
revoke endpoint.Endpoint
|
||||
listUserRefreshTokens endpoint.Endpoint
|
||||
timeout time.Duration
|
||||
}
|
||||
|
||||
var _ grpcTokenV1.TokenServiceClient = (*tokenGrpcClient)(nil)
|
||||
|
||||
// NewTokenClient returns new token gRPC client instance.
|
||||
func NewTokenClient(conn *grpc.ClientConn, timeout time.Duration) grpcTokenV1.TokenServiceClient {
|
||||
return &tokenGrpcClient{
|
||||
issue: kitgrpc.NewClient(
|
||||
conn,
|
||||
tokenSvcName,
|
||||
"Issue",
|
||||
encodeIssueRequest,
|
||||
decodeIssueResponse,
|
||||
grpcTokenV1.Token{},
|
||||
).Endpoint(),
|
||||
refresh: kitgrpc.NewClient(
|
||||
conn,
|
||||
tokenSvcName,
|
||||
"Refresh",
|
||||
encodeRefreshRequest,
|
||||
decodeRefreshResponse,
|
||||
grpcTokenV1.Token{},
|
||||
).Endpoint(),
|
||||
revoke: kitgrpc.NewClient(
|
||||
conn,
|
||||
tokenSvcName,
|
||||
"Revoke",
|
||||
encodeRevokeRequest,
|
||||
decodeRevokeResponse,
|
||||
grpcTokenV1.RevokeRes{},
|
||||
).Endpoint(),
|
||||
listUserRefreshTokens: kitgrpc.NewClient(
|
||||
conn,
|
||||
tokenSvcName,
|
||||
"ListUserRefreshTokens",
|
||||
encodeListUserRefreshTokensRequest,
|
||||
decodeListUserRefreshTokensResponse,
|
||||
grpcTokenV1.ListUserRefreshTokensRes{},
|
||||
).Endpoint(),
|
||||
timeout: timeout,
|
||||
}
|
||||
}
|
||||
|
||||
func (client tokenGrpcClient) Issue(ctx context.Context, req *grpcTokenV1.IssueReq, _ ...grpc.CallOption) (*grpcTokenV1.Token, error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, client.timeout)
|
||||
defer cancel()
|
||||
|
||||
res, err := client.issue(ctx, issueReq{
|
||||
userID: req.GetUserId(),
|
||||
userRole: auth.Role(req.GetUserRole()),
|
||||
keyType: auth.KeyType(req.GetType()),
|
||||
verified: req.GetVerified(),
|
||||
description: req.GetDescription(),
|
||||
})
|
||||
if err != nil {
|
||||
return &grpcTokenV1.Token{}, grpcapi.DecodeError(err)
|
||||
}
|
||||
return res.(*grpcTokenV1.Token), nil
|
||||
}
|
||||
|
||||
func encodeIssueRequest(_ context.Context, grpcReq any) (any, error) {
|
||||
req := grpcReq.(issueReq)
|
||||
return &grpcTokenV1.IssueReq{
|
||||
UserId: req.userID,
|
||||
UserRole: uint32(req.userRole),
|
||||
Type: uint32(req.keyType),
|
||||
Verified: req.verified,
|
||||
Description: req.description,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func decodeIssueResponse(_ context.Context, grpcRes any) (any, error) {
|
||||
return grpcRes, nil
|
||||
}
|
||||
|
||||
func (client tokenGrpcClient) Refresh(ctx context.Context, req *grpcTokenV1.RefreshReq, _ ...grpc.CallOption) (*grpcTokenV1.Token, error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, client.timeout)
|
||||
defer cancel()
|
||||
|
||||
res, err := client.refresh(ctx, refreshReq{refreshToken: req.GetRefreshToken(), verified: req.GetVerified()})
|
||||
if err != nil {
|
||||
return &grpcTokenV1.Token{}, grpcapi.DecodeError(err)
|
||||
}
|
||||
return res.(*grpcTokenV1.Token), nil
|
||||
}
|
||||
|
||||
func encodeRefreshRequest(_ context.Context, grpcReq any) (any, error) {
|
||||
req := grpcReq.(refreshReq)
|
||||
return &grpcTokenV1.RefreshReq{RefreshToken: req.refreshToken, Verified: req.verified}, nil
|
||||
}
|
||||
|
||||
func decodeRefreshResponse(_ context.Context, grpcRes any) (any, error) {
|
||||
return grpcRes, nil
|
||||
}
|
||||
|
||||
func (client tokenGrpcClient) Revoke(ctx context.Context, req *grpcTokenV1.RevokeReq, _ ...grpc.CallOption) (*grpcTokenV1.RevokeRes, error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, client.timeout)
|
||||
defer cancel()
|
||||
|
||||
res, err := client.revoke(ctx, revokeReq{userID: req.GetUserId(), tokenID: req.GetTokenId()})
|
||||
if err != nil {
|
||||
return &grpcTokenV1.RevokeRes{}, grpcapi.DecodeError(err)
|
||||
}
|
||||
return res.(*grpcTokenV1.RevokeRes), nil
|
||||
}
|
||||
|
||||
func encodeRevokeRequest(_ context.Context, grpcReq any) (any, error) {
|
||||
req := grpcReq.(revokeReq)
|
||||
return &grpcTokenV1.RevokeReq{UserId: req.userID, TokenId: req.tokenID}, nil
|
||||
}
|
||||
|
||||
func decodeRevokeResponse(_ context.Context, grpcRes any) (any, error) {
|
||||
return grpcRes, nil
|
||||
}
|
||||
|
||||
func (client tokenGrpcClient) ListUserRefreshTokens(ctx context.Context, req *grpcTokenV1.ListUserRefreshTokensReq, _ ...grpc.CallOption) (*grpcTokenV1.ListUserRefreshTokensRes, error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, client.timeout)
|
||||
defer cancel()
|
||||
|
||||
res, err := client.listUserRefreshTokens(ctx, listUserRefreshTokensReq{userID: req.GetUserId()})
|
||||
if err != nil {
|
||||
return &grpcTokenV1.ListUserRefreshTokensRes{}, grpcapi.DecodeError(err)
|
||||
}
|
||||
return res.(*grpcTokenV1.ListUserRefreshTokensRes), nil
|
||||
}
|
||||
|
||||
func encodeListUserRefreshTokensRequest(_ context.Context, grpcReq any) (any, error) {
|
||||
req := grpcReq.(listUserRefreshTokensReq)
|
||||
return &grpcTokenV1.ListUserRefreshTokensReq{UserId: req.userID}, nil
|
||||
}
|
||||
|
||||
func decodeListUserRefreshTokensResponse(_ context.Context, grpcRes any) (any, error) {
|
||||
return grpcRes, nil
|
||||
}
|
||||
@@ -2,4 +2,4 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Package grpc contains implementation of Auth service gRPC API.
|
||||
package grpc
|
||||
package token
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user