mirror of
https://github.com/absmach/magistrala.git
synced 2026-08-07 23:32:14 +00:00
Compare commits
423 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 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 |
@@ -5,6 +5,10 @@
|
||||
coverage:
|
||||
ignore:
|
||||
- "tools/*"
|
||||
- "cmd/*"
|
||||
- "coap/*"
|
||||
- "**/mocks*"
|
||||
- "*/mocks/*"
|
||||
- "*/middleware/*"
|
||||
- "pkg/sid/mock.go"
|
||||
- "pkg/tracing/utils.go"
|
||||
- "pkg/prometheus/*"
|
||||
+1
-1
@@ -1 +1 @@
|
||||
* @absmach/magistrala
|
||||
* @absmach/supermq
|
||||
|
||||
@@ -5,7 +5,7 @@ blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Google group
|
||||
url: https://groups.google.com/forum/#!forum/mainflux
|
||||
about: Join the Magistrala community on Google group.
|
||||
about: Join the SuperMQ community on Google group.
|
||||
- name: Gitter
|
||||
url: https://gitter.im/mainflux/mainflux
|
||||
about: Join the Magistrala community on Gitter.
|
||||
about: Join the SuperMQ community on Gitter.
|
||||
@@ -3,8 +3,8 @@ 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/main/CONTRIBUTING.md) file for detailed contributing guidelines.
|
||||
Pull request title should be `SMQ-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/supermq/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,183 @@
|
||||
# Copyright (c) Abstract Machines
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: Property Based Tests
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- ".github/workflows/api-tests.yaml"
|
||||
- "api/**"
|
||||
- "auth/api/http/**"
|
||||
- "channels/api/http/**"
|
||||
- "clients/api/http/**"
|
||||
- "domains/api/http/**"
|
||||
- "groups/api/http/**"
|
||||
- "http/api/**"
|
||||
- "journal/api/**"
|
||||
- "users/api/**"
|
||||
|
||||
env:
|
||||
TOKENS_URL: http://localhost:9002/users/tokens/issue
|
||||
CREATE_DOMAINS_URL: http://localhost:9003/domains
|
||||
USER_IDENTITY: admin@example.com
|
||||
USER_SECRET: 12345678
|
||||
DOMAIN_NAME: demo-test
|
||||
USERS_URL: http://localhost:9002
|
||||
DOMAIN_URL: http://localhost:9003
|
||||
CLIENTS_URL: http://localhost:9006
|
||||
CHANNELS_URL: http://localhost:9005
|
||||
GROUPS_URL: http://localhost:9004
|
||||
HTTP_ADAPTER_URL: http://localhost:8008
|
||||
AUTH_URL: http://localhost:9001
|
||||
JOURNAL_URL: http://localhost:9021
|
||||
|
||||
jobs:
|
||||
api-test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: 1.25.x
|
||||
cache-dependency-path: "go.sum"
|
||||
|
||||
- name: Build images
|
||||
run: make all -j $(nproc) && make dockers_dev -j $(nproc)
|
||||
|
||||
- name: Start containers
|
||||
run: make run up args="-d" && make run_addons up args="-d"
|
||||
|
||||
- name: Set access token
|
||||
run: |
|
||||
export USER_TOKEN=$(curl -sSX POST $TOKENS_URL -H "Content-Type: application/json" -d "{\"identity\": \"$USER_IDENTITY\",\"secret\": \"$USER_SECRET\"}" | jq -r .access_token)
|
||||
export DOMAIN_ID=$(curl -sSX POST $CREATE_DOMAINS_URL -H "Content-Type: application/json" -H "Authorization: Bearer $USER_TOKEN" -d "{\"name\":\"$DOMAIN_NAME\",\"route\":\"$DOMAIN_NAME\"}" | jq -r .id)
|
||||
echo "USER_TOKEN=$USER_TOKEN" >> $GITHUB_ENV
|
||||
export CLIENT_SECRET=$(supermq-cli provision test | /usr/bin/grep -Eo '"secret": "[^"]+"' | awk 'NR % 2 == 0' | sed 's/"secret": "\(.*\)"/\1/')
|
||||
echo "CLIENT_SECRET=$CLIENT_SECRET" >> $GITHUB_ENV
|
||||
|
||||
- name: Check for changes in specific paths
|
||||
uses: dorny/paths-filter@v3
|
||||
id: changes
|
||||
with:
|
||||
filters: |
|
||||
journal:
|
||||
- ".github/workflows/api-tests.yaml"
|
||||
- "apidocs/openapi/journal.yaml"
|
||||
- "journal/api/**"
|
||||
|
||||
auth:
|
||||
- ".github/workflows/api-tests.yaml"
|
||||
- "apidocs/openapi/auth.yaml"
|
||||
- "auth/api/http/**"
|
||||
|
||||
domains:
|
||||
- ".github/workflows/api-tests.yaml"
|
||||
- "apidocs/openapi/domains.yaml"
|
||||
- "domains/api/http/**"
|
||||
|
||||
http:
|
||||
- ".github/workflows/api-tests.yaml"
|
||||
- "apidocs/openapi/http.yaml"
|
||||
- "http/api/**"
|
||||
|
||||
clients:
|
||||
- ".github/workflows/api-tests.yaml"
|
||||
- "apidocs/openapi/clients.yaml"
|
||||
- "clients/api/http/**"
|
||||
|
||||
channels:
|
||||
- ".github/workflows/api-tests.yaml"
|
||||
- "apidocs/openapi/channels.yaml"
|
||||
- "channels/api/http/**"
|
||||
|
||||
groups:
|
||||
- ".github/workflows/api-tests.yaml"
|
||||
- "apidocs/openapi/groups.yaml"
|
||||
- "groups/api/http/**"
|
||||
|
||||
users:
|
||||
- ".github/workflows/api-tests.yaml"
|
||||
- "apidocs/openapi/users.yaml"
|
||||
- "users/api/**"
|
||||
|
||||
- name: Run Users API tests
|
||||
if: steps.changes.outputs.users == 'true'
|
||||
uses: schemathesis/action@v2.1.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,stateful'
|
||||
|
||||
- name: Run Groups API tests
|
||||
if: steps.changes.outputs.groups == 'true'
|
||||
uses: schemathesis/action@v2.1.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'
|
||||
|
||||
- name: Run Clients API tests
|
||||
if: steps.changes.outputs.clients == 'true'
|
||||
uses: schemathesis/action@v2.1.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'
|
||||
|
||||
- name: Run Channels API tests
|
||||
if: steps.changes.outputs.channels == 'true'
|
||||
uses: schemathesis/action@v2.1.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'
|
||||
|
||||
- name: Run HTTP Adapter API tests
|
||||
if: steps.changes.outputs.http == 'true'
|
||||
uses: schemathesis/action@v2.1.0
|
||||
with:
|
||||
schema: apidocs/openapi/http.yaml
|
||||
base-url: ${{ env.HTTP_ADAPTER_URL }}
|
||||
checks: all
|
||||
args: '--header "Authorization: Client ${{ env.CLIENT_SECRET }}" --suppress-health-check=filter_too_much --exclude-checks=positive_data_acceptance --phases=examples'
|
||||
|
||||
- name: Run Auth API tests
|
||||
if: steps.changes.outputs.auth == 'true'
|
||||
uses: schemathesis/action@v2.1.0
|
||||
with:
|
||||
schema: apidocs/openapi/auth.yaml
|
||||
base-url: ${{ env.AUTH_URL }}
|
||||
checks: all
|
||||
args: '--header "Authorization: Bearer ${{ env.USER_TOKEN }}" --suppress-health-check=filter_too_much --exclude-checks=positive_data_acceptance --phases=examples'
|
||||
|
||||
- name: Run Domains API tests
|
||||
if: steps.changes.outputs.domains == 'true'
|
||||
uses: schemathesis/action@v2.1.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'
|
||||
|
||||
- name: Run Journal API tests
|
||||
if: steps.changes.outputs.journal == 'true'
|
||||
uses: schemathesis/action@v2.1.0
|
||||
with:
|
||||
schema: apidocs/openapi/journal.yaml
|
||||
base-url: ${{ env.JOURNAL_URL }}
|
||||
checks: all
|
||||
args: '--header "Authorization: Bearer ${{ env.USER_TOKEN }}" --suppress-health-check=filter_too_much --exclude-checks=positive_data_acceptance --phases=examples'
|
||||
|
||||
- name: Stop containers
|
||||
if: always()
|
||||
run: make run down args="-v" && make run_addons down args="-v"
|
||||
@@ -1,244 +0,0 @@
|
||||
# Copyright (c) Abstract Machines
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: Property Based Tests
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- ".github/workflows/api-tests.yml"
|
||||
- "api/**"
|
||||
- "auth/api/http/**"
|
||||
- "bootstrap/api**"
|
||||
- "certs/api/**"
|
||||
- "consumers/notifiers/api/**"
|
||||
- "http/api/**"
|
||||
- "invitations/api/**"
|
||||
- "journal/api/**"
|
||||
- "provision/api/**"
|
||||
- "readers/api/**"
|
||||
- "things/api/**"
|
||||
- "users/api/**"
|
||||
|
||||
env:
|
||||
TOKENS_URL: http://localhost:9002/users/tokens/issue
|
||||
DOMAINS_URL: http://localhost:8189/domains
|
||||
USER_IDENTITY: admin@example.com
|
||||
USER_SECRET: 12345678
|
||||
DOMAIN_NAME: demo-test
|
||||
USERS_URL: http://localhost:9002
|
||||
THINGS_URL: http://localhost:9000
|
||||
HTTP_ADAPTER_URL: http://localhost:8008
|
||||
INVITATIONS_URL: http://localhost:9020
|
||||
AUTH_URL: http://localhost:8189
|
||||
BOOTSTRAP_URL: http://localhost:9013
|
||||
CERTS_URL: http://localhost:9019
|
||||
PROVISION_URL: http://localhost:9016
|
||||
POSTGRES_READER_URL: http://localhost:9009
|
||||
TIMESCALE_READER_URL: http://localhost:9011
|
||||
JOURNAL_URL: http://localhost:9021
|
||||
|
||||
jobs:
|
||||
api-test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: 1.22.x
|
||||
cache-dependency-path: "go.sum"
|
||||
|
||||
- name: Build images
|
||||
run: make all -j $(nproc) && make dockers_dev -j $(nproc)
|
||||
|
||||
- name: Start containers
|
||||
run: make run up args="-d" && make run_addons up args="-d"
|
||||
|
||||
- name: Set access token
|
||||
run: |
|
||||
export USER_TOKEN=$(curl -sSX POST $TOKENS_URL -H "Content-Type: application/json" -d "{\"identity\": \"$USER_IDENTITY\",\"secret\": \"$USER_SECRET\"}" | jq -r .access_token)
|
||||
export DOMAIN_ID=$(curl -sSX POST $DOMAINS_URL -H "Content-Type: application/json" -H "Authorization: Bearer $USER_TOKEN" -d "{\"name\":\"$DOMAIN_NAME\",\"alias\":\"$DOMAIN_NAME\"}" | jq -r .id)
|
||||
export USER_TOKEN=$(curl -sSX POST $TOKENS_URL -H "Content-Type: application/json" -d "{\"identity\": \"$USER_IDENTITY\",\"secret\": \"$USER_SECRET\",\"domain_id\": \"$DOMAIN_ID\"}" | jq -r .access_token)
|
||||
echo "USER_TOKEN=$USER_TOKEN" >> $GITHUB_ENV
|
||||
export THING_SECRET=$(magistrala-cli provision test | /usr/bin/grep -Eo '"secret": "[^"]+"' | awk 'NR % 2 == 0' | sed 's/"secret": "\(.*\)"/\1/')
|
||||
echo "THING_SECRET=$THING_SECRET" >> $GITHUB_ENV
|
||||
|
||||
- name: Check for changes in specific paths
|
||||
uses: dorny/paths-filter@v3
|
||||
id: changes
|
||||
with:
|
||||
filters: |
|
||||
journal:
|
||||
- ".github/workflows/api-tests.yml"
|
||||
- "api/openapi/journal.yml"
|
||||
- "journal/api/**"
|
||||
|
||||
auth:
|
||||
- ".github/workflows/api-tests.yml"
|
||||
- "api/openapi/auth.yml"
|
||||
- "auth/api/http/**"
|
||||
|
||||
bootstrap:
|
||||
- ".github/workflows/api-tests.yml"
|
||||
- "api/openapi/bootstrap.yml"
|
||||
- "bootstrap/api/**"
|
||||
|
||||
certs:
|
||||
- ".github/workflows/api-tests.yml"
|
||||
- "api/openapi/certs.yml"
|
||||
- "certs/api/**"
|
||||
|
||||
http:
|
||||
- ".github/workflows/api-tests.yml"
|
||||
- "api/openapi/http.yml"
|
||||
- "http/api/**"
|
||||
|
||||
invitations:
|
||||
- ".github/workflows/api-tests.yml"
|
||||
- "api/openapi/invitations.yml"
|
||||
- "invitations/api/**"
|
||||
|
||||
provision:
|
||||
- ".github/workflows/api-tests.yml"
|
||||
- "api/openapi/provision.yml"
|
||||
- "provision/api/**"
|
||||
|
||||
readers:
|
||||
- ".github/workflows/api-tests.yml"
|
||||
- "api/openapi/readers.yml"
|
||||
- "readers/api/**"
|
||||
|
||||
things:
|
||||
- ".github/workflows/api-tests.yml"
|
||||
- "api/openapi/things.yml"
|
||||
- "things/api/**"
|
||||
|
||||
users:
|
||||
- ".github/workflows/api-tests.yml"
|
||||
- "api/openapi/users.yml"
|
||||
- "users/api/**"
|
||||
|
||||
- name: Run Users API tests
|
||||
if: steps.changes.outputs.users == 'true'
|
||||
uses: schemathesis/action@v1
|
||||
with:
|
||||
schema: api/openapi/users.yml
|
||||
base-url: ${{ env.USERS_URL }}
|
||||
checks: all
|
||||
report: false
|
||||
args: '--header "Authorization: Bearer ${{ env.USER_TOKEN }}" --contrib-openapi-formats-uuid --hypothesis-suppress-health-check=filter_too_much --stateful=links'
|
||||
|
||||
- name: Run Things API tests
|
||||
if: steps.changes.outputs.things == 'true'
|
||||
uses: schemathesis/action@v1
|
||||
with:
|
||||
schema: api/openapi/things.yml
|
||||
base-url: ${{ env.THINGS_URL }}
|
||||
checks: all
|
||||
report: false
|
||||
args: '--header "Authorization: Bearer ${{ env.USER_TOKEN }}" --contrib-openapi-formats-uuid --hypothesis-suppress-health-check=filter_too_much --stateful=links'
|
||||
|
||||
- name: Run HTTP Adapter API tests
|
||||
if: steps.changes.outputs.http == 'true'
|
||||
uses: schemathesis/action@v1
|
||||
with:
|
||||
schema: api/openapi/http.yml
|
||||
base-url: ${{ env.HTTP_ADAPTER_URL }}
|
||||
checks: all
|
||||
report: false
|
||||
args: '--header "Authorization: Thing ${{ env.THING_SECRET }}" --contrib-openapi-formats-uuid --hypothesis-suppress-health-check=filter_too_much --stateful=links'
|
||||
|
||||
- name: Run Invitations API tests
|
||||
if: steps.changes.outputs.invitations == 'true'
|
||||
uses: schemathesis/action@v1
|
||||
with:
|
||||
schema: api/openapi/invitations.yml
|
||||
base-url: ${{ env.INVITATIONS_URL }}
|
||||
checks: all
|
||||
report: false
|
||||
args: '--header "Authorization: Bearer ${{ env.USER_TOKEN }}" --contrib-openapi-formats-uuid --hypothesis-suppress-health-check=filter_too_much --stateful=links'
|
||||
|
||||
- name: Run Auth API tests
|
||||
if: steps.changes.outputs.auth == 'true'
|
||||
uses: schemathesis/action@v1
|
||||
with:
|
||||
schema: api/openapi/auth.yml
|
||||
base-url: ${{ env.AUTH_URL }}
|
||||
checks: all
|
||||
report: false
|
||||
args: '--header "Authorization: Bearer ${{ env.USER_TOKEN }}" --contrib-openapi-formats-uuid --hypothesis-suppress-health-check=filter_too_much --stateful=links'
|
||||
|
||||
- name: Run Journal API tests
|
||||
if: steps.changes.outputs.journal == 'true'
|
||||
uses: schemathesis/action@v1
|
||||
with:
|
||||
schema: api/openapi/journal.yml
|
||||
base-url: ${{ env.JOURNAL_URL }}
|
||||
checks: all
|
||||
report: false
|
||||
args: '--header "Authorization: Bearer ${{ env.USER_TOKEN }}" --contrib-openapi-formats-uuid --hypothesis-suppress-health-check=filter_too_much --stateful=links'
|
||||
|
||||
- name: Run Bootstrap API tests
|
||||
if: steps.changes.outputs.bootstrap == 'true'
|
||||
uses: schemathesis/action@v1
|
||||
with:
|
||||
schema: api/openapi/bootstrap.yml
|
||||
base-url: ${{ env.BOOTSTRAP_URL }}
|
||||
checks: all
|
||||
report: false
|
||||
args: '--header "Authorization: Bearer ${{ env.USER_TOKEN }}" --contrib-openapi-formats-uuid --hypothesis-suppress-health-check=filter_too_much --stateful=links'
|
||||
|
||||
- name: Run Certs API tests
|
||||
if: steps.changes.outputs.certs == 'true'
|
||||
uses: schemathesis/action@v1
|
||||
with:
|
||||
schema: api/openapi/certs.yml
|
||||
base-url: ${{ env.CERTS_URL }}
|
||||
checks: all
|
||||
report: false
|
||||
args: '--header "Authorization: Bearer ${{ env.USER_TOKEN }}" --contrib-openapi-formats-uuid --hypothesis-suppress-health-check=filter_too_much --stateful=links'
|
||||
|
||||
- name: Run Provision API tests
|
||||
if: steps.changes.outputs.provision == 'true'
|
||||
uses: schemathesis/action@v1
|
||||
with:
|
||||
schema: api/openapi/provision.yml
|
||||
base-url: ${{ env.PROVISION_URL }}
|
||||
checks: all
|
||||
report: false
|
||||
args: '--header "Authorization: Bearer ${{ env.USER_TOKEN }}" --contrib-openapi-formats-uuid --hypothesis-suppress-health-check=filter_too_much --stateful=links'
|
||||
|
||||
- name: Seed Messages
|
||||
if: steps.changes.outputs.readers == 'true'
|
||||
run: |
|
||||
make cli
|
||||
./build/cli provision test
|
||||
|
||||
- name: Run Postgres Reader API tests
|
||||
if: steps.changes.outputs.readers == 'true'
|
||||
uses: schemathesis/action@v1
|
||||
with:
|
||||
schema: api/openapi/readers.yml
|
||||
base-url: ${{ env.POSTGRES_READER_URL }}
|
||||
checks: all
|
||||
report: false
|
||||
args: '--header "Authorization: Bearer ${{ env.USER_TOKEN }}" --contrib-openapi-formats-uuid --hypothesis-suppress-health-check=filter_too_much --stateful=links'
|
||||
|
||||
- name: Run Timescale Reader API tests
|
||||
if: steps.changes.outputs.readers == 'true'
|
||||
uses: schemathesis/action@v1
|
||||
with:
|
||||
schema: api/openapi/readers.yml
|
||||
base-url: ${{ env.TIMESCALE_READER_URL }}
|
||||
checks: all
|
||||
report: false
|
||||
args: '--header "Authorization: Bearer ${{ env.USER_TOKEN }}" --contrib-openapi-formats-uuid --hypothesis-suppress-health-check=filter_too_much --stateful=links'
|
||||
|
||||
- name: Stop containers
|
||||
if: always()
|
||||
run: make run down args="-v" && make run_addons down args="-v"
|
||||
@@ -12,21 +12,29 @@ jobs:
|
||||
build-and-push:
|
||||
name: Build and Push
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Fetch tags for the build
|
||||
run: |
|
||||
git fetch --prune --unshallow --tags
|
||||
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: 1.22.x
|
||||
go-version: 1.25.x
|
||||
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: Run tests
|
||||
run: |
|
||||
make test
|
||||
@@ -36,7 +44,6 @@ jobs:
|
||||
with:
|
||||
token: ${{ secrets.CODECOV }}
|
||||
files: ./coverage/*.out
|
||||
codecov_yml_path: tools/codecov.yml
|
||||
verbose: true
|
||||
|
||||
- name: Set up Docker Build
|
||||
@@ -51,12 +58,20 @@ jobs:
|
||||
|
||||
- name: Compile check for rabbitmq
|
||||
run: |
|
||||
MG_MESSAGE_BROKER_TYPE=rabbitmq make mqtt
|
||||
SMQ_MESSAGE_BROKER_TYPE=msg_rabbitmq make mqtt
|
||||
|
||||
- name: Compile check for redis
|
||||
run: |
|
||||
MG_ES_TYPE=redis make mqtt
|
||||
SMQ_ES_TYPE=es_redis make mqtt
|
||||
|
||||
- name: Build and push Dockers
|
||||
- name: Build and push Docker images
|
||||
run: |
|
||||
make latest -j $(nproc)
|
||||
|
||||
- name: Trigger Helm Chart Deployment
|
||||
if: success() && github.event_name == 'push' && github.ref == 'refs/heads/main'
|
||||
uses: peter-evans/repository-dispatch@v4
|
||||
with:
|
||||
token: ${{ secrets.REPO_DISPATCH_TOKEN }}
|
||||
repository: absmach/amdm
|
||||
event-type: deploy-latest-smq-images
|
||||
@@ -0,0 +1,141 @@
|
||||
# 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@v5
|
||||
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: 1.25.x
|
||||
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@v3
|
||||
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:
|
||||
- ".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"
|
||||
- "journal/journal.go"
|
||||
- "consumers/notifier.go"
|
||||
|
||||
- name: Set up protoc
|
||||
if: steps.changes.outputs.proto == 'true'
|
||||
run: |
|
||||
PROTOC_VERSION=33.0
|
||||
PROTOC_GEN_VERSION=v1.36.10
|
||||
PROTOC_GRPC_VERSION=v1.5.1
|
||||
|
||||
# Export the variables so they are available in future steps
|
||||
echo "PROTOC_VERSION=$PROTOC_VERSION" >> $GITHUB_ENV
|
||||
echo "PROTOC_GEN_VERSION=$PROTOC_GEN_VERSION" >> $GITHUB_ENV
|
||||
echo "PROTOC_GRPC_VERSION=$PROTOC_GRPC_VERSION" >> $GITHUB_ENV
|
||||
|
||||
# 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 "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_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: |
|
||||
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,217 +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@v5
|
||||
with:
|
||||
go-version: 1.22.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@v3
|
||||
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"
|
||||
- "pkg/authz.go"
|
||||
- "pkg/authn.go"
|
||||
- "auth/domains.go"
|
||||
- "auth/keys.go"
|
||||
- "auth/service.go"
|
||||
- "pkg/events/events.go"
|
||||
- "provision/service.go"
|
||||
- "pkg/groups/groups.go"
|
||||
- "bootstrap/service.go"
|
||||
- "bootstrap/configs.go"
|
||||
- "invitations/invitations.go"
|
||||
- "users/emailer.go"
|
||||
- "users/hasher.go"
|
||||
- "mqtt/events/streams.go"
|
||||
- "readers/messages.go"
|
||||
- "lora/routemap.go"
|
||||
- "consumers/notifiers/notifier.go"
|
||||
- "consumers/notifiers/service.go"
|
||||
- "consumers/notifiers/subscriptions.go"
|
||||
- "certs/certs.go"
|
||||
- "certs/pki/vault.go"
|
||||
- "certs/service.go"
|
||||
- "journal/journal.go"
|
||||
- "magistrala/auth_grpc.pb.go"
|
||||
|
||||
- name: Set up protoc
|
||||
if: steps.changes.outputs.proto == 'true'
|
||||
run: |
|
||||
PROTOC_VERSION=27.1
|
||||
PROTOC_GEN_VERSION=v1.34.2
|
||||
PROTOC_GRPC_VERSION=v1.4.0
|
||||
|
||||
# Export the variables so they are available in future steps
|
||||
echo "PROTOC_VERSION=$PROTOC_VERSION" >> $GITHUB_ENV
|
||||
echo "PROTOC_GEN_VERSION=$PROTOC_GEN_VERSION" >> $GITHUB_ENV
|
||||
echo "PROTOC_GRPC_VERSION=$PROTOC_GRPC_VERSION" >> $GITHUB_ENV
|
||||
|
||||
# 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 "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_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.43.2
|
||||
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/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 ./auth/mocks/token_client.go ./auth/mocks/token_client.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
|
||||
mv ./bootstrap/mocks/service.go ./bootstrap/mocks/service.go.tmp
|
||||
mv ./bootstrap/mocks/configs.go ./bootstrap/mocks/configs.go.tmp
|
||||
mv ./invitations/mocks/service.go ./invitations/mocks/service.go.tmp
|
||||
mv ./invitations/mocks/repository.go ./invitations/mocks/repository.go.tmp
|
||||
mv ./users/mocks/emailer.go ./users/mocks/emailer.go.tmp
|
||||
mv ./users/mocks/hasher.go ./users/mocks/hasher.go.tmp
|
||||
mv ./mqtt/mocks/events.go ./mqtt/mocks/events.go.tmp
|
||||
mv ./readers/mocks/messages.go ./readers/mocks/messages.go.tmp
|
||||
mv ./consumers/notifiers/mocks/notifier.go ./consumers/notifiers/mocks/notifier.go.tmp
|
||||
mv ./consumers/notifiers/mocks/service.go ./consumers/notifiers/mocks/service.go.tmp
|
||||
mv ./consumers/notifiers/mocks/repository.go ./consumers/notifiers/mocks/repository.go.tmp
|
||||
mv ./certs/mocks/pki.go ./certs/mocks/pki.go.tmp
|
||||
mv ./certs/mocks/service.go ./certs/mocks/service.go.tmp
|
||||
mv ./journal/mocks/repository.go ./journal/mocks/repository.go.tmp
|
||||
mv ./journal/mocks/service.go ./journal/mocks/service.go.tmp
|
||||
mv ./auth/mocks/domains_client.go ./auth/mocks/domains_client.go.tmp
|
||||
mv ./things/mocks/things_client.go ./things/mocks/things_client.go.tmp
|
||||
mv ./pkg/authz/mocks/authz.go ./pkg/authz/mocks/authz.go.tmp
|
||||
mv ./pkg/authn/mocks/authn.go ./pkg/authn/mocks/authn.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/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/authn/mocks/authn.go "Authn Service Client .pkg/authn/mocks/authn.go"
|
||||
check_mock_changes ./pkg/authz/mocks/authz.go "Authz Service Client .pkg/authz/mocks/authz.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"
|
||||
check_mock_changes ./bootstrap/mocks/service.go "Bootstrap Service ./bootstrap/mocks/service.go"
|
||||
check_mock_changes ./bootstrap/mocks/configs.go "Bootstrap Repository ./bootstrap/mocks/configs.go"
|
||||
check_mock_changes ./invitations/mocks/service.go "Invitations Service ./invitations/mocks/service.go"
|
||||
check_mock_changes ./invitations/mocks/repository.go "Invitations Repository ./invitations/mocks/repository.go"
|
||||
check_mock_changes ./users/mocks/emailer.go "Users Emailer ./users/mocks/emailer.go"
|
||||
check_mock_changes ./users/mocks/hasher.go "Users Hasher ./users/mocks/hasher.go"
|
||||
check_mock_changes ./mqtt/mocks/events.go "MQTT Events Store ./mqtt/mocks/events.go"
|
||||
check_mock_changes ./readers/mocks/messages.go "Message Readers ./readers/mocks/messages.go"
|
||||
check_mock_changes ./consumers/notifiers/mocks/notifier.go "Notifiers Notifier ./consumers/notifiers/mocks/notifier.go"
|
||||
check_mock_changes ./consumers/notifiers/mocks/service.go "Notifiers Service ./consumers/notifiers/mocks/service.go"
|
||||
check_mock_changes ./consumers/notifiers/mocks/repository.go "Notifiers Repository ./consumers/notifiers/mocks/repository.go"
|
||||
check_mock_changes ./certs/mocks/pki.go "PKI ./certs/mocks/pki.go"
|
||||
check_mock_changes ./certs/mocks/service.go "Certs Service ./certs/mocks/service.go"
|
||||
check_mock_changes ./journal/mocks/repository.go "Journal Repository ./journal/mocks/repository.go"
|
||||
check_mock_changes ./journal/mocks/service.go "Journal Service ./journal/mocks/service.go"
|
||||
check_mock_changes ./auth/mocks/domains_client.go "Domains Service Client ./auth/mocks/domains_client.go"
|
||||
check_mock_changes ./auth/mocks/token_client.go "Token Service Client ./auth/mocks/token_client.go"
|
||||
check_mock_changes ./things/mocks/things_client.go "Things Service Client things/mocks/things_client.go"
|
||||
@@ -16,14 +16,14 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Check License Header
|
||||
run: |
|
||||
CHECK=""
|
||||
for file in $(grep -rl --exclude-dir={.git,build,**vernemq**} \
|
||||
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} \
|
||||
--exclude={CODEOWNERS,LICENSE,MAINTAINERS,enabled_plugins,rabbitmq.conf} \
|
||||
.); do
|
||||
|
||||
if ! head -n 5 "$file" | grep -q "Copyright (c) Abstract Machines"; then
|
||||
|
||||
@@ -13,14 +13,14 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Swagger UI action
|
||||
id: swagger-ui-action
|
||||
uses: blokovi/swagger-ui-action@main
|
||||
with:
|
||||
dir: "./api/openapi"
|
||||
pattern: "*.yml"
|
||||
dir: "./apidocs/openapi"
|
||||
pattern: "*.yaml"
|
||||
debug: "true"
|
||||
|
||||
- name: Deploy to GitHub Pages
|
||||
@@ -28,4 +28,4 @@ jobs:
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
publish_dir: swagger-ui
|
||||
cname: docs.api.magistrala.abstractmachines.fr
|
||||
cname: docs.api.supermq.absmach.eu
|
||||
|
||||
@@ -15,27 +15,38 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: 1.22.x
|
||||
go-version: 1.25.x
|
||||
cache-dependency-path: "go.sum"
|
||||
|
||||
- name: Fetch Certs
|
||||
run: |
|
||||
make fetch_certs
|
||||
if [[ -n $(git status --porcelain docker/addons/certs) ]]; then
|
||||
echo "Certs docker file is not up to date. Please update it"
|
||||
git diff docker/addons/certs
|
||||
exit 1
|
||||
else
|
||||
exit 0
|
||||
fi
|
||||
|
||||
- name: Install protolint
|
||||
run: |
|
||||
go install github.com/yoheimuta/protolint/cmd/protolint@latest
|
||||
|
||||
- name: Lint Protobuf Files
|
||||
run: |
|
||||
protolint .
|
||||
protolint .
|
||||
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@v6
|
||||
- name: Run linters
|
||||
uses: golangci/golangci-lint-action@v8
|
||||
with:
|
||||
version: v1.60.3
|
||||
args: --config ./tools/config/golangci.yml
|
||||
version: v2.4.0
|
||||
args: --config ./tools/config/.golangci.yaml
|
||||
|
||||
- name: Build all Binaries
|
||||
run: |
|
||||
@@ -43,11 +54,11 @@ jobs:
|
||||
|
||||
- name: Compile check for rabbitmq
|
||||
run: |
|
||||
MG_MESSAGE_BROKER_TYPE=rabbitmq make mqtt
|
||||
SMQ_MESSAGE_BROKER_TYPE=msg_rabbitmq make mqtt
|
||||
|
||||
- name: Compile check for redis
|
||||
run: |
|
||||
MG_ES_TYPE=redis make mqtt
|
||||
SMQ_ES_TYPE=es_redis make mqtt
|
||||
|
||||
run-tests:
|
||||
name: Run tests
|
||||
@@ -56,14 +67,14 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: 1.22.x
|
||||
go-version: 1.25.x
|
||||
cache-dependency-path: "go.sum"
|
||||
|
||||
- name: Check for changes in specific paths
|
||||
@@ -73,7 +84,7 @@ jobs:
|
||||
base: main
|
||||
filters: |
|
||||
workflow:
|
||||
- ".github/workflows/tests.yml"
|
||||
- ".github/workflows/tests.yaml"
|
||||
|
||||
auth:
|
||||
- "auth/**"
|
||||
@@ -84,49 +95,78 @@ jobs:
|
||||
- "pkg/ulid/**"
|
||||
- "pkg/uuid/**"
|
||||
|
||||
bootstrap:
|
||||
- "bootstrap/**"
|
||||
- "cmd/bootstrap/**"
|
||||
- "auth.pb.go"
|
||||
- "auth_grpc.pb.go"
|
||||
- "auth/**"
|
||||
- "pkg/sdk/**"
|
||||
- "pkg/events/**"
|
||||
|
||||
certs:
|
||||
- "certs/**"
|
||||
- "cmd/certs/**"
|
||||
channels:
|
||||
- "channels/**"
|
||||
- "cmd/channels/**"
|
||||
- "auth.pb.go"
|
||||
- "auth_grpc.pb.go"
|
||||
- "auth/**"
|
||||
- "pkg/sdk/**"
|
||||
- "clients/api/grpc/**"
|
||||
- "groups/api/grpc/**"
|
||||
- "domains/api/grpc/**"
|
||||
- "internal/grpc/**"
|
||||
|
||||
cli:
|
||||
- "cli/**"
|
||||
- "cmd/cli/**"
|
||||
- "pkg/sdk/**"
|
||||
|
||||
coap:
|
||||
- "coap/**"
|
||||
- "cmd/coap/**"
|
||||
- "auth.pb.go"
|
||||
- "auth_grpc.pb.go"
|
||||
- "things/**"
|
||||
- "pkg/messaging/**"
|
||||
|
||||
consumers:
|
||||
- "consumers/**"
|
||||
- "cmd/postgres-writer/**"
|
||||
- "cmd/timescale-writer/**"
|
||||
- "cmd/smpp-notifier/**"
|
||||
- "cmd/smtp-notifier/**"
|
||||
clients:
|
||||
- "clients/**"
|
||||
- "cmd/clients/**"
|
||||
- "auth.pb.go"
|
||||
- "auth_grpc.pb.go"
|
||||
- "auth/**"
|
||||
- "pkg/ulid/**"
|
||||
- "pkg/uuid/**"
|
||||
- "pkg/events/**"
|
||||
- "groups/api/grpc/**"
|
||||
- "channels/api/grpc/**"
|
||||
- "domains/api/grpc/**"
|
||||
- "internal/grpc/**"
|
||||
|
||||
coap:
|
||||
- "coap/**"
|
||||
- "cmd/coap/**"
|
||||
- "auth.pb.go"
|
||||
- "auth_grpc.pb.go"
|
||||
- "clients/**"
|
||||
- "pkg/messaging/**"
|
||||
|
||||
domains:
|
||||
- "domains/**"
|
||||
- "cmd/domains/**"
|
||||
- "auth.pb.go"
|
||||
- "auth_grpc.pb.go"
|
||||
- "auth/**"
|
||||
- "internal/grpc/**"
|
||||
|
||||
groups:
|
||||
- "groups/**"
|
||||
- "cmd/groups/**"
|
||||
- "auth.pb.go"
|
||||
- "auth_grpc.pb.go"
|
||||
- "auth/**"
|
||||
- "pkg/ulid/**"
|
||||
- "pkg/uuid/**"
|
||||
- "clients/api/grpc/**"
|
||||
- "channels/api/grpc/**"
|
||||
- "domains/api/grpc/**"
|
||||
- "internal/grpc/**"
|
||||
|
||||
http:
|
||||
- "http/**"
|
||||
- "cmd/http/**"
|
||||
- "auth.pb.go"
|
||||
- "auth_grpc.pb.go"
|
||||
- "clients/**"
|
||||
- "pkg/messaging/**"
|
||||
- "logger/**"
|
||||
|
||||
internal:
|
||||
- "internal/**"
|
||||
|
||||
journal:
|
||||
- "journal/**"
|
||||
- "cmd/journal/**"
|
||||
@@ -135,26 +175,6 @@ jobs:
|
||||
- "auth/**"
|
||||
- "pkg/events/**"
|
||||
|
||||
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/**"
|
||||
|
||||
logger:
|
||||
- "logger/**"
|
||||
|
||||
@@ -163,7 +183,7 @@ jobs:
|
||||
- "cmd/mqtt/**"
|
||||
- "auth.pb.go"
|
||||
- "auth_grpc.pb.go"
|
||||
- "things/**"
|
||||
- "clients/**"
|
||||
- "pkg/messaging/**"
|
||||
- "logger/**"
|
||||
- "pkg/events/**"
|
||||
@@ -186,19 +206,15 @@ jobs:
|
||||
- "pkg/errors/**"
|
||||
- "pkg/groups/**"
|
||||
- "auth/**"
|
||||
- "bootstrap/**"
|
||||
- "certs/**"
|
||||
- "consumers/**"
|
||||
- "http/**"
|
||||
- "internal/*"
|
||||
- "internal/api/**"
|
||||
- "internal/apiutil/**"
|
||||
- "internal/groups/**"
|
||||
- "invitations/**"
|
||||
- "provision/**"
|
||||
- "readers/**"
|
||||
- "things/**"
|
||||
- "clients/**"
|
||||
- "users/**"
|
||||
- "channels/**"
|
||||
- "domains/**"
|
||||
- "groups/**"
|
||||
- "journal/**"
|
||||
- "api/http/**"
|
||||
|
||||
pkg-transformers:
|
||||
- "pkg/transformers/**"
|
||||
@@ -209,31 +225,6 @@ jobs:
|
||||
pkg-uuid:
|
||||
- "pkg/uuid/**"
|
||||
|
||||
provision:
|
||||
- "provision/**"
|
||||
- "cmd/provision/**"
|
||||
- "logger/**"
|
||||
- "pkg/sdk/**"
|
||||
|
||||
readers:
|
||||
- "readers/**"
|
||||
- "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/ulid/**"
|
||||
- "pkg/uuid/**"
|
||||
- "pkg/events/**"
|
||||
|
||||
users:
|
||||
- "users/**"
|
||||
- "cmd/users/**"
|
||||
@@ -249,14 +240,14 @@ jobs:
|
||||
- "cmd/ws/**"
|
||||
- "auth.pb.go"
|
||||
- "auth_grpc.pb.go"
|
||||
- "things/**"
|
||||
- "clients/**"
|
||||
- "pkg/messaging/**"
|
||||
|
||||
- name: Create coverage directory
|
||||
run: |
|
||||
mkdir coverage
|
||||
|
||||
- name: Run Journal tests
|
||||
- name: Run journal tests
|
||||
if: steps.changes.outputs.journal == 'true' || steps.changes.outputs.workflow == 'true'
|
||||
run: |
|
||||
go test --race -v -count=1 -coverprofile=coverage/journal.out ./journal/...
|
||||
@@ -266,15 +257,10 @@ jobs:
|
||||
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'
|
||||
- name: Run domains tests
|
||||
if: steps.changes.outputs.domains == '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/...
|
||||
go test --race -v -count=1 -coverprofile=coverage/domains.out ./domains/...
|
||||
|
||||
- name: Run cli tests
|
||||
if: steps.changes.outputs.cli == 'true' || steps.changes.outputs.workflow == 'true'
|
||||
@@ -286,11 +272,6 @@ jobs:
|
||||
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: |
|
||||
@@ -301,11 +282,6 @@ jobs:
|
||||
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: |
|
||||
@@ -356,26 +332,26 @@ jobs:
|
||||
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'
|
||||
- name: Run clients tests
|
||||
if: steps.changes.outputs.clients == 'true' || steps.changes.outputs.workflow == 'true'
|
||||
run: |
|
||||
go test --race -v -count=1 -coverprofile=coverage/provision.out ./provision/...
|
||||
go test --race -v -count=1 -coverprofile=coverage/clients.out ./clients/...
|
||||
|
||||
- name: Run readers tests
|
||||
if: steps.changes.outputs.readers == 'true' || steps.changes.outputs.workflow == 'true'
|
||||
- name: Run channels tests
|
||||
if: steps.changes.outputs.channels == '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/...
|
||||
go test --race -v -count=1 -coverprofile=coverage/channels.out ./channels/...
|
||||
|
||||
- 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 groups tests
|
||||
if: steps.changes.outputs.groups == 'true' || steps.changes.outputs.workflow == 'true'
|
||||
run: |
|
||||
go test --race -v -count=1 -coverprofile=coverage/groups.out ./groups/...
|
||||
|
||||
- name: Run WebSocket tests
|
||||
if: steps.changes.outputs.ws == 'true' || steps.changes.outputs.workflow == 'true'
|
||||
run: |
|
||||
@@ -386,5 +362,4 @@ jobs:
|
||||
with:
|
||||
token: ${{ secrets.CODECOV }}
|
||||
files: ./coverage/*.out
|
||||
codecov_yml_path: tools/codecov.yml
|
||||
verbose: true
|
||||
+2
-2
@@ -16,5 +16,5 @@ coverage
|
||||
# Schemathesis
|
||||
.hypothesis
|
||||
|
||||
# Ignore Vault data directory as it contains runtime-generated data
|
||||
docker/addons/vault/data/
|
||||
# Ignore Openbao data directory as it contains runtime-generated data
|
||||
docker/addons/certs/openbao/
|
||||
|
||||
+6
-6
@@ -1,12 +1,12 @@
|
||||
# Adopters
|
||||
|
||||
As Magistrala Community grows, we'd like to keep track of Magistrala adopters to grow the community, contact other users, share experiences and best practices.
|
||||
As SuperMQ Community grows, we'd like to keep track of SuperMQ adopters to grow the community, contact other users, share experiences and best practices.
|
||||
|
||||
To accomplish this, we created a public ledger. The list of organizations and users who consider themselves as Magistrala adopters and that **publicly/officially** shared information and/or details of their adoption journey(optional).
|
||||
To accomplish this, we created a public ledger. The list of organizations and users who consider themselves as SuperMQ adopters and that **publicly/officially** shared information and/or details of their adoption journey(optional).
|
||||
Where users themselves directly maintain the list.
|
||||
|
||||
## Adding yourself as an adopter
|
||||
If you are using Magistrala, please consider adding yourself as an adopter with a brief description of your use case by opening a pull request to this file and adding a section describing your adoption of Magistrala technology.
|
||||
If you are using SuperMQ, please consider adding yourself as an adopter with a brief description of your use case by opening a pull request to this file and adding a section describing your adoption of SuperMQ technology.
|
||||
|
||||
**Please send PRs to add or remove organizations/users**
|
||||
|
||||
@@ -25,12 +25,12 @@ Pull request commit must be [signed](https://docs.github.com/en/github/authentic
|
||||
* There is no minimum requirement or adaptation size, but we request to list permanent deployments only, i.e., no demo or trial deployments. Commercial or production use is not required. A well-done home lab setup can be equally impressive as a large-scale commercial deployment.
|
||||
|
||||
|
||||
**The list of organizations/users that have publicly shared the usage of Magistrala:**
|
||||
**The list of organizations/users that have publicly shared the usage of SuperMQ:**
|
||||
|
||||
**Note**: Several other organizations/users couldn't publicly share their usage details but are active project contributors and Magistrala Community members.
|
||||
**Note**: Several other organizations/users couldn't publicly share their usage details but are active project contributors and SuperMQ Community members.
|
||||
|
||||
|
||||
## 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/main/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/supermq/blob/main/MAINTAINERS) and you will be permanently removed from the list.
|
||||
|
||||
+11
-11
@@ -1,11 +1,11 @@
|
||||
# Contributing to Magistrala
|
||||
# Contributing to SuperMQ
|
||||
|
||||
The following is a set of guidelines to contribute to Magistrala and its libraries, which are
|
||||
The following is a set of guidelines to contribute to SuperMQ and its libraries, which are
|
||||
hosted on the [Abstract Machines Organization](https://github.com/absmach) on GitHub.
|
||||
|
||||
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@abstractmachines.fr](mailto:abuse@abstractmachines.fr).
|
||||
|
||||
## Reporting issues
|
||||
|
||||
@@ -13,7 +13,7 @@ Reporting issues are a great way to contribute to the project. We are perpetuall
|
||||
thorough bug report.
|
||||
|
||||
Before raising a new issue, check [our issue
|
||||
list](https://github.com/absmach/magistrala/issues) to determine if it already contains the
|
||||
list](https://github.com/absmach/supermq/issues) to determine if it already contains the
|
||||
problem that you are facing.
|
||||
|
||||
A good bug report shouldn't leave others needing to chase you for more information. Please be as detailed as possible. The following questions might serve as a template for writing a detailed
|
||||
@@ -41,23 +41,23 @@ To contribute to the project, [fork](https://help.github.com/articles/fork-a-rep
|
||||
clone your fork repository, and configure the remotes:
|
||||
|
||||
```
|
||||
git clone https://github.com/<your-username>/magistrala.git
|
||||
cd magistrala
|
||||
git remote add upstream https://github.com/absmach/magistrala.git
|
||||
git clone https://github.com/<your-username>/supermq.git
|
||||
cd supermq
|
||||
git remote add upstream https://github.com/absmach/supermq.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 `SMQ-[issue-number]`
|
||||
to help us keep track of your contribution scope:
|
||||
|
||||
```
|
||||
git checkout -b MG-[issue-number]
|
||||
git checkout -b SMQ-[issue-number]
|
||||
```
|
||||
|
||||
Commit your changes in logical chunks. When you are ready to commit, make sure
|
||||
@@ -80,7 +80,7 @@ git pull --rebase upstream main
|
||||
Push your topic branch up to your fork:
|
||||
|
||||
```
|
||||
git push origin MG-[issue-number]
|
||||
git push origin SMQ-[issue-number]
|
||||
```
|
||||
|
||||
[Open a Pull Request](https://help.github.com/articles/using-pull-requests/) with a clear title
|
||||
|
||||
@@ -176,7 +176,7 @@
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Copyright 2015-2020 Magistrala
|
||||
Copyright 2015-2020 SuperMQ
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
# Magistrala follows the timeless, highly efficient and totally unfair system
|
||||
# SuperMQ 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.
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
[[drasko]]
|
||||
Name = "Drasko Draskovic"
|
||||
Email = "draasko.draskovic@abstractmachines.fr"
|
||||
Email = "drasko@abstractmachines.fr"
|
||||
GitHub = "drasko"
|
||||
|
||||
# However, this role serves only in dead-lock events, or in a special and very rare cases
|
||||
@@ -18,7 +18,7 @@
|
||||
# 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.
|
||||
# A reference list of all maintainers of the SuperMQ project.
|
||||
|
||||
# ADD YOURSELF HERE IN ALPHABETICAL ORDER
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
# 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 postgres-writer postgres-reader timescale-writer \
|
||||
timescale-reader cli bootstrap mqtt provision certs invitations journal
|
||||
TEST_API_SERVICES = journal auth bootstrap certs http invitations notifiers provision readers things users
|
||||
SMQ_DOCKER_IMAGE_NAME_PREFIX ?= supermq
|
||||
BUILD_DIR ?= build
|
||||
SERVICES = auth users clients groups channels domains http coap ws cli mqtt journal
|
||||
TEST_API_SERVICES = journal auth certs http clients users channels groups domains
|
||||
TEST_API = $(addprefix test_api_,$(TEST_API_SERVICES))
|
||||
DOCKERS = $(addprefix docker_,$(SERVICES))
|
||||
DOCKERS_DEV = $(addprefix docker_dev_,$(SERVICES))
|
||||
@@ -14,33 +13,38 @@ GOARCH ?= amd64
|
||||
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
|
||||
GRPC_MTLS_CERT_FILES_EXISTS = 0
|
||||
MOCKERY_VERSION=v2.43.2
|
||||
ifneq ($(MG_MESSAGE_BROKER_TYPE),)
|
||||
MG_MESSAGE_BROKER_TYPE := $(MG_MESSAGE_BROKER_TYPE)
|
||||
MOCKERY = $(GOBIN)/mockery
|
||||
MOCKERY_VERSION=3.5.5
|
||||
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 ($(SMQ_MESSAGE_BROKER_TYPE),)
|
||||
SMQ_MESSAGE_BROKER_TYPE := $(SMQ_MESSAGE_BROKER_TYPE)
|
||||
else
|
||||
MG_MESSAGE_BROKER_TYPE=nats
|
||||
SMQ_MESSAGE_BROKER_TYPE=msg_nats
|
||||
endif
|
||||
|
||||
ifneq ($(MG_ES_TYPE),)
|
||||
MG_ES_TYPE := $(MG_ES_TYPE)
|
||||
ifneq ($(SMQ_ES_TYPE),)
|
||||
SMQ_ES_TYPE := $(SMQ_ES_TYPE)
|
||||
else
|
||||
MG_ES_TYPE=nats
|
||||
SMQ_ES_TYPE=es_nats
|
||||
endif
|
||||
|
||||
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 \
|
||||
-X 'github.com/absmach/magistrala.BuildTime=$(TIME)' \
|
||||
-X 'github.com/absmach/magistrala.Version=$(VERSION)' \
|
||||
-X 'github.com/absmach/magistrala.Commit=$(COMMIT)'" \
|
||||
go build -tags $(SMQ_MESSAGE_BROKER_TYPE) -tags $(SMQ_ES_TYPE) -ldflags "-s -w \
|
||||
-X 'github.com/absmach/supermq.BuildTime=$(TIME)' \
|
||||
-X 'github.com/absmach/supermq.Version=$(VERSION)' \
|
||||
-X 'github.com/absmach/supermq.Commit=$(COMMIT)'" \
|
||||
-o ${BUILD_DIR}/$(1) cmd/$(1)/main.go
|
||||
endef
|
||||
|
||||
@@ -55,7 +59,7 @@ define make_docker
|
||||
--build-arg VERSION=$(VERSION) \
|
||||
--build-arg COMMIT=$(COMMIT) \
|
||||
--build-arg TIME=$(TIME) \
|
||||
--tag=$(MG_DOCKER_IMAGE_NAME_PREFIX)/$(svc) \
|
||||
--tag=$(SMQ_DOCKER_IMAGE_NAME_PREFIX)/$(svc) \
|
||||
-f docker/Dockerfile .
|
||||
endef
|
||||
|
||||
@@ -65,13 +69,13 @@ define make_docker_dev
|
||||
docker build \
|
||||
--no-cache \
|
||||
--build-arg SVC=$(svc) \
|
||||
--tag=$(MG_DOCKER_IMAGE_NAME_PREFIX)/$(svc) \
|
||||
--tag=$(SMQ_DOCKER_IMAGE_NAME_PREFIX)/$(svc) \
|
||||
-f docker/Dockerfile.dev ./build
|
||||
endef
|
||||
|
||||
ADDON_SERVICES = bootstrap journal provision certs timescale-reader timescale-writer postgres-reader postgres-writer
|
||||
ADDON_SERVICES = journal certs
|
||||
|
||||
EXTERNAL_SERVICES = vault prometheus
|
||||
EXTERNAL_SERVICES = prometheus
|
||||
|
||||
ifneq ($(filter run%,$(firstword $(MAKECMDGOALS))),)
|
||||
temp_args := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))
|
||||
@@ -102,35 +106,40 @@ clean:
|
||||
|
||||
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=$(SMQ_DOCKER_IMAGE_NAME_PREFIX) -f dangling=true -q | xargs -r docker volume rm
|
||||
endif
|
||||
|
||||
install:
|
||||
for file in $(BUILD_DIR)/*; do \
|
||||
cp $$file $(GOBIN)/magistrala-`basename $$file`; \
|
||||
cp $$file $(GOBIN)/supermq-`basename $$file`; \
|
||||
done
|
||||
|
||||
mocks:
|
||||
@which mockery > /dev/null || go install github.com/vektra/mockery/v2@$(MOCKERY_VERSION)
|
||||
@unset MOCKERY_VERSION && go generate ./...
|
||||
mockery --config ./tools/config/mockery.yaml
|
||||
mocks: $(MOCKERY)
|
||||
@$(MOCKERY) --config ./tools/config/.mockery.yaml
|
||||
|
||||
$(MOCKERY):
|
||||
@mkdir -p $(GOBIN)
|
||||
@mkdir -p mockery
|
||||
@echo ">> downloading mockery $(MOCKERY_VERSION)..."
|
||||
@curl -sL https://github.com/vektra/mockery/releases/download/v$(MOCKERY_VERSION)/mockery_$(MOCKERY_VERSION)_Linux_x86_64.tar.gz | tar -xz -C mockery
|
||||
@mv mockery/mockery $(GOBIN)
|
||||
@rm -r mockery
|
||||
|
||||
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\|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 st > /dev/null || (echo "schemathesis not found, please install it from https://github.com/schemathesis/schemathesis#getting-started" && exit 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"; \
|
||||
@@ -138,40 +147,40 @@ define test_api_service
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
@if [ "$(svc)" = "http" ] && [ -z "$(THING_SECRET)" ]; then \
|
||||
echo "THING_SECRET is not set"; \
|
||||
@if [ "$(svc)" = "http" ] && [ -z "$(CLIENT_SECRET)" ]; then \
|
||||
echo "CLIENT_SECRET is not set"; \
|
||||
echo "Please set it to a valid secret"; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
@if [ "$(svc)" = "http" ]; then \
|
||||
st run api/openapi/$(svc).yml \
|
||||
uvx schemathesis run apidocs/openapi/$(svc).yaml \
|
||||
--checks all \
|
||||
--base-url $(2) \
|
||||
--header "Authorization: Thing $(THING_SECRET)" \
|
||||
--contrib-openapi-formats-uuid \
|
||||
--hypothesis-suppress-health-check=filter_too_much \
|
||||
--stateful=links; \
|
||||
--url $(2) \
|
||||
--header "Authorization: Client $(CLIENT_SECRET)" \
|
||||
--suppress-health-check=filter_too_much \
|
||||
--exclude-checks=positive_data_acceptance \
|
||||
--phases=examples,stateful; \
|
||||
else \
|
||||
st run api/openapi/$(svc).yml \
|
||||
uvx schemathesis run apidocs/openapi/$(svc).yaml \
|
||||
--checks all \
|
||||
--base-url $(2) \
|
||||
--url $(2) \
|
||||
--header "Authorization: Bearer $(USER_TOKEN)" \
|
||||
--contrib-openapi-formats-uuid \
|
||||
--hypothesis-suppress-health-check=filter_too_much \
|
||||
--stateful=links; \
|
||||
--suppress-health-check=filter_too_much \
|
||||
--exclude-checks=positive_data_acceptance \
|
||||
--exclude-operation-id=requestPasswordReset \
|
||||
--phases=examples,stateful; \
|
||||
fi
|
||||
endef
|
||||
|
||||
test_api_users: TEST_API_URL := http://localhost:9002
|
||||
test_api_things: TEST_API_URL := http://localhost:9000
|
||||
test_api_clients: TEST_API_URL := http://localhost:9006
|
||||
test_api_domains: TEST_API_URL := http://localhost:9003
|
||||
test_api_channels: TEST_API_URL := http://localhost:9005
|
||||
test_api_groups: TEST_API_URL := http://localhost:9004
|
||||
test_api_http: TEST_API_URL := http://localhost:8008
|
||||
test_api_invitations: TEST_API_URL := http://localhost:9020
|
||||
test_api_auth: TEST_API_URL := http://localhost:8189
|
||||
test_api_bootstrap: TEST_API_URL := http://localhost:9013
|
||||
test_api_auth: TEST_API_URL := http://localhost:9001
|
||||
test_api_certs: TEST_API_URL := http://localhost:9019
|
||||
test_api_provision: TEST_API_URL := http://localhost:9016
|
||||
test_api_readers: TEST_API_URL := http://localhost:9009 # This can be the URL of any reader service.
|
||||
test_api_journal: TEST_API_URL := http://localhost:9021
|
||||
|
||||
$(TEST_API):
|
||||
@@ -179,7 +188,8 @@ $(TEST_API):
|
||||
|
||||
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,$(@))
|
||||
@@ -195,7 +205,7 @@ dockers_dev: $(DOCKERS_DEV)
|
||||
|
||||
define docker_push
|
||||
for svc in $(SERVICES); do \
|
||||
docker push $(MG_DOCKER_IMAGE_NAME_PREFIX)/$$svc:$(1); \
|
||||
docker push $(SMQ_DOCKER_IMAGE_NAME_PREFIX)/$$svc:$(1); \
|
||||
done
|
||||
endef
|
||||
|
||||
@@ -210,7 +220,7 @@ release:
|
||||
git checkout $(version)
|
||||
$(MAKE) dockers
|
||||
for svc in $(SERVICES); do \
|
||||
docker tag $(MG_DOCKER_IMAGE_NAME_PREFIX)/$$svc $(MG_DOCKER_IMAGE_NAME_PREFIX)/$$svc:$(version); \
|
||||
docker tag $(SMQ_DOCKER_IMAGE_NAME_PREFIX)/$$svc $(SMQ_DOCKER_IMAGE_NAME_PREFIX)/$$svc:$(version); \
|
||||
done
|
||||
$(call docker_push,$(version))
|
||||
|
||||
@@ -218,42 +228,49 @@ rundev:
|
||||
cd scripts && ./run.sh
|
||||
|
||||
grpc_mtls_certs:
|
||||
$(MAKE) -C docker/ssl auth_grpc_certs things_grpc_certs
|
||||
$(MAKE) -C docker/ssl auth_grpc_certs clients_grpc_certs
|
||||
|
||||
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
|
||||
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 auth_grpc_certs clients_grpc_certs
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
fetch_certs:
|
||||
@./scripts/certs.sh
|
||||
|
||||
run: check_certs
|
||||
docker compose -f docker/docker-compose.yml --env-file docker/.env -p $(DOCKER_PROJECT) $(DOCKER_COMPOSE_COMMAND) $(args)
|
||||
docker compose -f docker/docker-compose.yaml --env-file docker/.env -p $(DOCKER_PROJECT) $(DOCKER_COMPOSE_COMMAND) $(args)
|
||||
|
||||
run_addons: check_certs
|
||||
$(foreach SVC,$(RUN_ADDON_ARGS),$(if $(filter $(SVC),$(ADDON_SERVICES) $(EXTERNAL_SERVICES)),,$(error Invalid Service $(SVC))))
|
||||
@docker compose -f docker/docker-compose.yaml --env-file ./docker/.env -p $(DOCKER_PROJECT) up -d auth domains 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) & \
|
||||
if [ "$$SVC" = "certs" ]; then \
|
||||
docker compose -f docker/addons/$$SVC/docker-compose.yaml -f docker/certs-docker-compose-override.yaml --env-file ./docker/.env --env-file ./docker/addons/$$SVC/.env -p $(DOCKER_PROJECT) $(DOCKER_COMPOSE_COMMAND) $(args) & \
|
||||
else \
|
||||
SMQ_ADDONS_CERTS_PATH_PREFIX="../." docker compose -f docker/addons/$$SVC/docker-compose.yaml -p $(DOCKER_PROJECT) --env-file ./docker/.env $(DOCKER_COMPOSE_COMMAND) $(args) & \
|
||||
fi; \
|
||||
done
|
||||
|
||||
run_live: check_certs
|
||||
GOPATH=$(go env GOPATH) docker compose -f docker/docker-compose.yaml -f docker/docker-compose-live.yaml --env-file docker/.env -p $(DOCKER_PROJECT) $(DOCKER_COMPOSE_COMMAND) $(args)
|
||||
|
||||
@@ -1,191 +1,118 @@
|
||||
# Magistrala
|
||||
<div align="center">
|
||||
|
||||
[](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]
|
||||
# SuperMQ
|
||||
|
||||
**Planetary event-driven infrastructure**
|
||||
|
||||
**Made with ❤️ by [Abstract Machines](https://abstractmachines.fr/)**
|
||||
|
||||
[](https://github.com/absmach/supermq/actions/workflows/build.yaml)
|
||||
[](https://github.com/absmach/supermq/actions/workflows/check-license.yaml)
|
||||
[](https://github.com/absmach/supermq/actions/workflows/check-generated-files.yaml)
|
||||
[](https://goreportcard.com/report/github.com/absmach/supermq)
|
||||
[](https://codecov.io/gh/absmach/supermq)
|
||||
[](LICENSE)
|
||||
[](https://matrix.to/#/#supermq:matrix.org)
|
||||
|
||||
### [Guide](https://docs.supermq.abstractmachines.fr) | [Contributing](CONTRIBUTING.md) | [Website](https://abstractmachines.fr/) | [Chat](https://matrix.to/#/#supermq:matrix.org)
|
||||
|
||||
![banner][banner]
|
||||
</div>
|
||||
|
||||
Magistrala is modern, scalable, secure, open-source, and patent-free IoT cloud platform written in Go.
|
||||
|
||||
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.
|
||||
|
||||
For more details, check out the [official documentation][docs].
|
||||
For extra bits and services see [our contrib repository][contrib].
|
||||
## Introduction 📖
|
||||
|
||||
## Features
|
||||
SuperMQ is a distributed, highly scalable, and secure open-source cloud platform for messaging and event-driven architecture (EDA). It is a planetarily distributed, highly scalable, and secure platform that serves as a robust foundation for building advanced real-time and reactive systems.
|
||||
|
||||
- Multi-protocol connectivity and bridging (HTTP, MQTT, WebSocket and CoAP; see [contrib repository][contrib] for LoRa and OPC UA)
|
||||
- Device management and provisioning (Zero Touch provisioning)
|
||||
- Mutual TLS Authentication (mTLS) using X.509 Certificates
|
||||
- Fine-grained access control (policies, ABAC/RBAC)
|
||||
- Message persistence (Timescale and PostgresSQL - see [contrib repository][contrib] for Cassandra, InfluxDB, and MongoDB support)
|
||||
- Platform logging and instrumentation support (Prometheus and OpenTelemetry)
|
||||
- Event sourcing
|
||||
- Container-based deployment using [Docker][docker] and [Kubernetes][kubernetes]
|
||||
- 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
|
||||
## Why SuperMQ Stands Out 🚀
|
||||
|
||||
## Prerequisites
|
||||
SuperMQ bridges the gap between various network protocols (HTTP, MQTT, WebSocket, CoAP, and more) to provide a seamless messaging experience. Whether you're working on IoT solutions, real-time data pipelines, or event-driven systems, SuperMQ has you covered. 🌐✨
|
||||
|
||||
The following are needed to run Magistrala:
|
||||
## Key Features 🌟
|
||||
|
||||
- [Docker](https://docs.docker.com/install/) (version 26.0.0)
|
||||
- **Multi-Protocol Connectivity**: HTTP, MQTT, WebSocket, CoAP, and more! 🌉
|
||||
- **Secure by Design**: Mutual TLS (mTLS) with X.509 Certificates, JWT support, and multi-protocol authorization. 🔒
|
||||
- **Fine-Grained Access Control**: Support for ABAC and RBAC policies. 📜
|
||||
- **Multi-Tenant**: Manage multiple domains seamlessly. 🏢
|
||||
- **Multi-User**: Unlimited organizational hierarchies for user management. 👥
|
||||
- **Application Management**: Group and share messaging clients for streamlined operations. 📱
|
||||
- **Ease of Use**: Simple and powerful communication channel management, grouping, and sharing. ✨
|
||||
- **Personal Access Tokens (PATs)**: Scoped and revocable tokens for enhanced security. 🔑
|
||||
- **Observability**: Integrated logging and instrumentation with Prometheus and OpenTelemetry. 📈
|
||||
- **Event Sourcing**: Build robust and scalable architectures. ⚡
|
||||
- **Edge and IoT Ready**: Supports MQTT and CoAP protocols for seamless IoT gateway and sensor communication and management. 🌍
|
||||
- **Developer-Friendly**: SDKs, CLI tools, and comprehensive documentation to get you started. 👩💻👨💻
|
||||
- **Production-Ready**: Container-based deployment using Docker and Kubernetes. 🐳☸️
|
||||
|
||||
Developing Magistrala will also require:
|
||||
## Installation 🛠️
|
||||
|
||||
- [Go](https://golang.org/doc/install) (version 1.21)
|
||||
- [Protobuf](https://github.com/protocolbuffers/protobuf#protocol-compiler-installation) (version 25.1)
|
||||
|
||||
## Install
|
||||
|
||||
Once the prerequisites are installed, execute the following commands from the project's root:
|
||||
Clone the repository and start SuperMQ services:
|
||||
|
||||
```bash
|
||||
docker compose -f docker/docker-compose.yml --env-file docker/.env -p git_github_com_absmach_magistrala_git_ up
|
||||
git clone https://github.com/absmach/supermq.git
|
||||
cd supermq
|
||||
docker compose -f docker/docker-compose.yaml --env-file docker/.env up
|
||||
```
|
||||
|
||||
This will bring up the Magistrala docker services and interconnect them. This command can also be executed using the project's included Makefile:
|
||||
Or use the [Makefile](Makefile) for a simpler command:
|
||||
|
||||
```bash
|
||||
make run
|
||||
```
|
||||
|
||||
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
|
||||
For production deployments, check our [Kubernetes guide](https://docs.supermq.abstractmachines.fr/kubernetes). ⚙️
|
||||
|
||||
```bash
|
||||
git checkout tags/<release_number> -b <release_number>
|
||||
# e.g. `git checkout tags/0.13.0 -b 0.13.0`
|
||||
```
|
||||
### Usage 📤📥
|
||||
|
||||
Check that `.env` file contains:
|
||||
|
||||
```bash
|
||||
MG_RELEASE_TAG=<release_number>
|
||||
```
|
||||
|
||||
> `docker-compose` should be used for development and testing deployments. For production we suggest using [Kubernetes](https://docs.magistrala.abstractmachines.fr/kubernetes).
|
||||
|
||||
## 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:
|
||||
#### Using the CLI:
|
||||
|
||||
```bash
|
||||
make cli
|
||||
./build/cli version
|
||||
./build/supermq-cli status
|
||||
```
|
||||
|
||||
Additional details on using the CLI can be found in the [CLI documentation](https://docs.magistrala.abstractmachines.fr/cli).
|
||||
This command retrieves the status of the SuperMQ server and outputs it to the console.
|
||||
|
||||
## Documentation
|
||||
#### Using HTTP with Curl:
|
||||
|
||||
Official documentation is hosted at [Magistrala official docs page][docs]. Documentation is auto-generated, checkout the instructions on [official docs repository](https://github.com/absmach/magistrala-docs):
|
||||
```bash
|
||||
curl -X GET http://localhost:8080/status
|
||||
```
|
||||
|
||||
If you spot an error or a need for corrections, please let us know - or even better: send us a PR.
|
||||
This request fetches the server status over HTTP and provides a JSON response.
|
||||
|
||||
## Authors
|
||||
See our [CLI documentation](https://docs.supermq.abstractmachines.fr/cli) for more details.
|
||||
|
||||
Main architect and BDFL of Magistrala project is [@drasko][drasko].
|
||||
## Documentation 📚
|
||||
|
||||
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.
|
||||
The official documentation is hosted at [SuperMQ docs page](https://docs.supermq.abstractmachines.fr).
|
||||
|
||||
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.
|
||||
Documentation is auto-generated, check out the instructions in the [docs repository](https://github.com/absmach/supermq-docs).
|
||||
If you spot an error or a need for corrections, please let us know - or even better: send us a PR! 💌
|
||||
|
||||
Maintainers are listed in [MAINTAINERS](MAINTAINERS) file.
|
||||
## Community and Contributing 🤝
|
||||
|
||||
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.
|
||||
Thank you for your interest in SuperMQ and the desire to contribute!
|
||||
|
||||
## 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.
|
||||
1. Take a look at our [open issues](https://github.com/absmach/supermq/issues). The [good-first-issue](https://github.com/absmach/supermq/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.
|
||||
|
||||
Also, explore our [contrib][contrib] repository for extra services such as Cassandra, InfluxDB, MongoDB readers and writers, LoRa, OPC UA support, Digital Twins, and more. If you have a contribution that is not a good fit for the core monorepo (it's specific to your use case, it's an additional feature or a new service, it's optional or an add-on), this is a great place to submit the pull request.
|
||||
Join our community:
|
||||
|
||||
### We're Hiring
|
||||
- [Matrix Room](https://matrix.to/#/#supermq\:matrix.org)
|
||||
|
||||
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.
|
||||
## Professional Support 💼
|
||||
|
||||
> The best way to grab our attention is, of course, by sending PRs :sunglasses:.
|
||||
Need help deploying SuperMQ or integrating it into your system? Reach out to **[Abstract Machines](https://abstractmachines.fr/)** for professional support and guidance.
|
||||
|
||||
## Community
|
||||
## License 📜
|
||||
|
||||
- [Google group][forum]
|
||||
- [Gitter][gitter]
|
||||
- [Twitter][twitter]
|
||||
SuperMQ is open-source software licensed under the [Apache License 2.0](LICENSE). Contributions are welcome!
|
||||
|
||||
## License
|
||||
## Acknowledgments 🙌
|
||||
|
||||
[Apache-2.0](LICENSE)
|
||||
Special thanks to the amazing contributors who make SuperMQ possible. Check out the [MAINTAINERS](MAINTAINERS) file to see the team behind the magic.
|
||||
|
||||
[](https://app.fossa.com/projects/git%2Bgithub.com%2Fabsmach%2Fmagistrala?ref=badge_large&issueType=license)
|
||||
## Data Collection for Magistrala
|
||||
Ready to build the future of messaging and event-driven systems? Let's get started! 🚀
|
||||
|
||||
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/absmach/magistrala-docs/blob/main/docs/img/gopherBanner.jpg
|
||||
[docs]: https://docs.magistrala.abstractmachines.fr
|
||||
[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/absmach
|
||||
[agent]: https://github.com/absmach/agent
|
||||
[export]: https://github.com/absmach/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.magistrala.abstractmachines.fr/
|
||||
[contrib]: https://www.github.com/absmach/mg-contrib
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package magistrala
|
||||
package supermq
|
||||
|
||||
// Response contains HTTP response specific methods.
|
||||
type Response interface {
|
||||
|
||||
@@ -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,485 @@
|
||||
// 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.10
|
||||
// protoc v6.33.0
|
||||
// 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"` // token id
|
||||
UserId string `protobuf:"bytes,2,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` // user id
|
||||
UserRole uint32 `protobuf:"varint,3,opt,name=user_role,json=userRole,proto3" json:"user_role,omitempty"` // user role
|
||||
Verified bool `protobuf:"varint,4,opt,name=verified,proto3" json:"verified,omitempty"` // verified user
|
||||
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
|
||||
}
|
||||
|
||||
type AuthZReq struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Domain string `protobuf:"bytes,1,opt,name=domain,proto3" json:"domain,omitempty"` // Domain
|
||||
SubjectType string `protobuf:"bytes,2,opt,name=subject_type,json=subjectType,proto3" json:"subject_type,omitempty"` // Client or User
|
||||
SubjectKind string `protobuf:"bytes,3,opt,name=subject_kind,json=subjectKind,proto3" json:"subject_kind,omitempty"` // ID or Token
|
||||
SubjectRelation string `protobuf:"bytes,4,opt,name=subject_relation,json=subjectRelation,proto3" json:"subject_relation,omitempty"` // Subject relation
|
||||
Subject string `protobuf:"bytes,5,opt,name=subject,proto3" json:"subject,omitempty"` // Subject value (id or token, depending on kind)
|
||||
Relation string `protobuf:"bytes,6,opt,name=relation,proto3" json:"relation,omitempty"` // Relation to filter
|
||||
Permission string `protobuf:"bytes,7,opt,name=permission,proto3" json:"permission,omitempty"` // Action
|
||||
Object string `protobuf:"bytes,8,opt,name=object,proto3" json:"object,omitempty"` // Object ID
|
||||
ObjectType string `protobuf:"bytes,9,opt,name=object_type,json=objectType,proto3" json:"object_type,omitempty"` // Client, User, Group
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *AuthZReq) Reset() {
|
||||
*x = AuthZReq{}
|
||||
mi := &file_auth_v1_auth_proto_msgTypes[2]
|
||||
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[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 AuthZReq.ProtoReflect.Descriptor instead.
|
||||
func (*AuthZReq) Descriptor() ([]byte, []int) {
|
||||
return file_auth_v1_auth_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *AuthZReq) GetDomain() string {
|
||||
if x != nil {
|
||||
return x.Domain
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AuthZReq) GetSubjectType() string {
|
||||
if x != nil {
|
||||
return x.SubjectType
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AuthZReq) GetSubjectKind() string {
|
||||
if x != nil {
|
||||
return x.SubjectKind
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AuthZReq) GetSubjectRelation() string {
|
||||
if x != nil {
|
||||
return x.SubjectRelation
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AuthZReq) GetSubject() string {
|
||||
if x != nil {
|
||||
return x.Subject
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AuthZReq) GetRelation() string {
|
||||
if x != nil {
|
||||
return x.Relation
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AuthZReq) GetPermission() string {
|
||||
if x != nil {
|
||||
return x.Permission
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AuthZReq) GetObject() string {
|
||||
if x != nil {
|
||||
return x.Object
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AuthZReq) GetObjectType() string {
|
||||
if x != nil {
|
||||
return x.ObjectType
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type AuthZPatReq struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` // User id
|
||||
PatId string `protobuf:"bytes,2,opt,name=pat_id,json=patId,proto3" json:"pat_id,omitempty"` // Pat id
|
||||
EntityType uint32 `protobuf:"varint,3,opt,name=entity_type,json=entityType,proto3" json:"entity_type,omitempty"` // Entity type
|
||||
OptionalDomainId string `protobuf:"bytes,4,opt,name=optional_domain_id,json=optionalDomainId,proto3" json:"optional_domain_id,omitempty"` // Optional domain id
|
||||
Operation uint32 `protobuf:"varint,6,opt,name=operation,proto3" json:"operation,omitempty"` // Operation
|
||||
EntityId string `protobuf:"bytes,7,opt,name=entity_id,json=entityId,proto3" json:"entity_id,omitempty"` // EntityID
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *AuthZPatReq) Reset() {
|
||||
*x = AuthZPatReq{}
|
||||
mi := &file_auth_v1_auth_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *AuthZPatReq) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*AuthZPatReq) ProtoMessage() {}
|
||||
|
||||
func (x *AuthZPatReq) 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 AuthZPatReq.ProtoReflect.Descriptor instead.
|
||||
func (*AuthZPatReq) Descriptor() ([]byte, []int) {
|
||||
return file_auth_v1_auth_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *AuthZPatReq) GetUserId() string {
|
||||
if x != nil {
|
||||
return x.UserId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AuthZPatReq) GetPatId() string {
|
||||
if x != nil {
|
||||
return x.PatId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AuthZPatReq) GetEntityType() uint32 {
|
||||
if x != nil {
|
||||
return x.EntityType
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *AuthZPatReq) GetOptionalDomainId() string {
|
||||
if x != nil {
|
||||
return x.OptionalDomainId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AuthZPatReq) GetOperation() uint32 {
|
||||
if x != nil {
|
||||
return x.Operation
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *AuthZPatReq) GetEntityId() string {
|
||||
if x != nil {
|
||||
return x.EntityId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
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[4]
|
||||
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[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 AuthZRes.ProtoReflect.Descriptor instead.
|
||||
func (*AuthZRes) Descriptor() ([]byte, []int) {
|
||||
return file_auth_v1_auth_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
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\"l\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\"\xa2\x02\n" +
|
||||
"\bAuthZReq\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\"\xc7\x01\n" +
|
||||
"\vAuthZPatReq\x12\x17\n" +
|
||||
"\auser_id\x18\x01 \x01(\tR\x06userId\x12\x15\n" +
|
||||
"\x06pat_id\x18\x02 \x01(\tR\x05patId\x12\x1f\n" +
|
||||
"\ventity_type\x18\x03 \x01(\rR\n" +
|
||||
"entityType\x12,\n" +
|
||||
"\x12optional_domain_id\x18\x04 \x01(\tR\x10optionalDomainId\x12\x1c\n" +
|
||||
"\toperation\x18\x06 \x01(\rR\toperation\x12\x1b\n" +
|
||||
"\tentity_id\x18\a \x01(\tR\bentityId\":\n" +
|
||||
"\bAuthZRes\x12\x1e\n" +
|
||||
"\n" +
|
||||
"authorized\x18\x01 \x01(\bR\n" +
|
||||
"authorized\x12\x0e\n" +
|
||||
"\x02id\x18\x02 \x01(\tR\x02id2\xf0\x01\n" +
|
||||
"\vAuthService\x123\n" +
|
||||
"\tAuthorize\x12\x11.auth.v1.AuthZReq\x1a\x11.auth.v1.AuthZRes\"\x00\x129\n" +
|
||||
"\fAuthorizePAT\x12\x14.auth.v1.AuthZPatReq\x1a\x11.auth.v1.AuthZRes\"\x00\x126\n" +
|
||||
"\fAuthenticate\x12\x11.auth.v1.AuthNReq\x1a\x11.auth.v1.AuthNRes\"\x00\x129\n" +
|
||||
"\x0fAuthenticatePAT\x12\x11.auth.v1.AuthNReq\x1a\x11.auth.v1.AuthNRes\"\x00B-Z+github.com/absmach/supermq/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, 5)
|
||||
var file_auth_v1_auth_proto_goTypes = []any{
|
||||
(*AuthNReq)(nil), // 0: auth.v1.AuthNReq
|
||||
(*AuthNRes)(nil), // 1: auth.v1.AuthNRes
|
||||
(*AuthZReq)(nil), // 2: auth.v1.AuthZReq
|
||||
(*AuthZPatReq)(nil), // 3: auth.v1.AuthZPatReq
|
||||
(*AuthZRes)(nil), // 4: auth.v1.AuthZRes
|
||||
}
|
||||
var file_auth_v1_auth_proto_depIdxs = []int32{
|
||||
2, // 0: auth.v1.AuthService.Authorize:input_type -> auth.v1.AuthZReq
|
||||
3, // 1: auth.v1.AuthService.AuthorizePAT:input_type -> auth.v1.AuthZPatReq
|
||||
0, // 2: auth.v1.AuthService.Authenticate:input_type -> auth.v1.AuthNReq
|
||||
0, // 3: auth.v1.AuthService.AuthenticatePAT:input_type -> auth.v1.AuthNReq
|
||||
4, // 4: auth.v1.AuthService.Authorize:output_type -> auth.v1.AuthZRes
|
||||
4, // 5: auth.v1.AuthService.AuthorizePAT:output_type -> auth.v1.AuthZRes
|
||||
1, // 6: auth.v1.AuthService.Authenticate:output_type -> auth.v1.AuthNRes
|
||||
1, // 7: auth.v1.AuthService.AuthenticatePAT:output_type -> auth.v1.AuthNRes
|
||||
4, // [4:8] is the sub-list for method output_type
|
||||
0, // [0:4] 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_auth_v1_auth_proto_init() }
|
||||
func file_auth_v1_auth_proto_init() {
|
||||
if File_auth_v1_auth_proto != nil {
|
||||
return
|
||||
}
|
||||
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: 5,
|
||||
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,244 @@
|
||||
// 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.5.1
|
||||
// - protoc v6.33.0
|
||||
// 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_AuthorizePAT_FullMethodName = "/auth.v1.AuthService/AuthorizePAT"
|
||||
AuthService_Authenticate_FullMethodName = "/auth.v1.AuthService/Authenticate"
|
||||
AuthService_AuthenticatePAT_FullMethodName = "/auth.v1.AuthService/AuthenticatePAT"
|
||||
)
|
||||
|
||||
// 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 SuperMQ services.
|
||||
type AuthServiceClient interface {
|
||||
Authorize(ctx context.Context, in *AuthZReq, opts ...grpc.CallOption) (*AuthZRes, error)
|
||||
AuthorizePAT(ctx context.Context, in *AuthZPatReq, opts ...grpc.CallOption) (*AuthZRes, error)
|
||||
Authenticate(ctx context.Context, in *AuthNReq, opts ...grpc.CallOption) (*AuthNRes, error)
|
||||
AuthenticatePAT(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) AuthorizePAT(ctx context.Context, in *AuthZPatReq, opts ...grpc.CallOption) (*AuthZRes, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(AuthZRes)
|
||||
err := c.cc.Invoke(ctx, AuthService_AuthorizePAT_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
|
||||
}
|
||||
|
||||
func (c *authServiceClient) AuthenticatePAT(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_AuthenticatePAT_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 SuperMQ services.
|
||||
type AuthServiceServer interface {
|
||||
Authorize(context.Context, *AuthZReq) (*AuthZRes, error)
|
||||
AuthorizePAT(context.Context, *AuthZPatReq) (*AuthZRes, error)
|
||||
Authenticate(context.Context, *AuthNReq) (*AuthNRes, error)
|
||||
AuthenticatePAT(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.Errorf(codes.Unimplemented, "method Authorize not implemented")
|
||||
}
|
||||
func (UnimplementedAuthServiceServer) AuthorizePAT(context.Context, *AuthZPatReq) (*AuthZRes, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method AuthorizePAT not implemented")
|
||||
}
|
||||
func (UnimplementedAuthServiceServer) Authenticate(context.Context, *AuthNReq) (*AuthNRes, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Authenticate not implemented")
|
||||
}
|
||||
func (UnimplementedAuthServiceServer) AuthenticatePAT(context.Context, *AuthNReq) (*AuthNRes, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method AuthenticatePAT 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 pancis, 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_AuthorizePAT_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(AuthZPatReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(AuthServiceServer).AuthorizePAT(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: AuthService_AuthorizePAT_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(AuthServiceServer).AuthorizePAT(ctx, req.(*AuthZPatReq))
|
||||
}
|
||||
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)
|
||||
}
|
||||
|
||||
func _AuthService_AuthenticatePAT_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).AuthenticatePAT(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: AuthService_AuthenticatePAT_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(AuthServiceServer).AuthenticatePAT(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: "AuthorizePAT",
|
||||
Handler: _AuthService_AuthorizePAT_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Authenticate",
|
||||
Handler: _AuthService_Authenticate_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "AuthenticatePAT",
|
||||
Handler: _AuthService_AuthenticatePAT_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "auth/v1/auth.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.10
|
||||
// protoc v6.33.0
|
||||
// source: channels/v1/channels.proto
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
v1 "github.com/absmach/supermq/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\"\x00B1Z/github.com/absmach/supermq/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.5.1
|
||||
// - protoc v6.33.0
|
||||
// source: channels/v1/channels.proto
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
context "context"
|
||||
v1 "github.com/absmach/supermq/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.Errorf(codes.Unimplemented, "method Authorize not implemented")
|
||||
}
|
||||
func (UnimplementedChannelsServiceServer) RemoveClientConnections(context.Context, *RemoveClientConnectionsReq) (*RemoveClientConnectionsRes, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method RemoveClientConnections not implemented")
|
||||
}
|
||||
func (UnimplementedChannelsServiceServer) UnsetParentGroupFromChannels(context.Context, *UnsetParentGroupFromChannelsReq) (*UnsetParentGroupFromChannelsRes, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method UnsetParentGroupFromChannels not implemented")
|
||||
}
|
||||
func (UnimplementedChannelsServiceServer) RetrieveEntity(context.Context, *v1.RetrieveEntityReq) (*v1.RetrieveEntityRes, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method RetrieveEntity not implemented")
|
||||
}
|
||||
func (UnimplementedChannelsServiceServer) RetrieveIDByRoute(context.Context, *v1.RetrieveIDByRouteReq) (*v1.RetrieveEntityRes, error) {
|
||||
return nil, status.Errorf(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 pancis, 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.10
|
||||
// protoc v6.33.0
|
||||
// source: clients/v1/clients.proto
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
v1 "github.com/absmach/supermq/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\"\x00B0Z.github.com/absmach/supermq/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.5.1
|
||||
// - protoc v6.33.0
|
||||
// source: clients/v1/clients.proto
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
context "context"
|
||||
v1 "github.com/absmach/supermq/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 SuperMQ 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 SuperMQ 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.Errorf(codes.Unimplemented, "method Authenticate not implemented")
|
||||
}
|
||||
func (UnimplementedClientsServiceServer) RetrieveEntity(context.Context, *v1.RetrieveEntityReq) (*v1.RetrieveEntityRes, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method RetrieveEntity not implemented")
|
||||
}
|
||||
func (UnimplementedClientsServiceServer) RetrieveEntities(context.Context, *v1.RetrieveEntitiesReq) (*v1.RetrieveEntitiesRes, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method RetrieveEntities not implemented")
|
||||
}
|
||||
func (UnimplementedClientsServiceServer) AddConnections(context.Context, *v1.AddConnectionsReq) (*v1.AddConnectionsRes, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method AddConnections not implemented")
|
||||
}
|
||||
func (UnimplementedClientsServiceServer) RemoveConnections(context.Context, *v1.RemoveConnectionsReq) (*v1.RemoveConnectionsRes, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method RemoveConnections not implemented")
|
||||
}
|
||||
func (UnimplementedClientsServiceServer) RemoveChannelConnections(context.Context, *RemoveChannelConnectionsReq) (*RemoveChannelConnectionsRes, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method RemoveChannelConnections not implemented")
|
||||
}
|
||||
func (UnimplementedClientsServiceServer) UnsetParentGroupFromClient(context.Context, *UnsetParentGroupFromClientReq) (*UnsetParentGroupFromClientRes, error) {
|
||||
return nil, status.Errorf(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 pancis, 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.10
|
||||
// protoc v6.33.0
|
||||
// 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\bdomainIdB/Z-github.com/absmach/supermq/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.10
|
||||
// protoc v6.33.0
|
||||
// source: domains/v1/domains.proto
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
v1 "github.com/absmach/supermq/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\"\x00B5Z3github.com/absmach/supermq/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.5.1
|
||||
// - protoc v6.33.0
|
||||
// source: domains/v1/domains.proto
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
context "context"
|
||||
v1 "github.com/absmach/supermq/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 SuperMQ 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 SuperMQ 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.Errorf(codes.Unimplemented, "method DeleteUserFromDomains not implemented")
|
||||
}
|
||||
func (UnimplementedDomainsServiceServer) RetrieveStatus(context.Context, *v1.RetrieveEntityReq) (*v1.RetrieveEntityRes, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method RetrieveStatus not implemented")
|
||||
}
|
||||
func (UnimplementedDomainsServiceServer) RetrieveIDByRoute(context.Context, *v1.RetrieveIDByRouteReq) (*v1.RetrieveEntityRes, error) {
|
||||
return nil, status.Errorf(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 pancis, 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.10
|
||||
// protoc v6.33.0
|
||||
// source: groups/v1/groups.proto
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
v1 "github.com/absmach/supermq/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\"\x00B/Z-github.com/absmach/supermq/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.5.1
|
||||
// - protoc v6.33.0
|
||||
// source: groups/v1/groups.proto
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
context "context"
|
||||
v1 "github.com/absmach/supermq/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 SuperMQ 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 SuperMQ 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.Errorf(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 pancis, 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,287 @@
|
||||
// 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.10
|
||||
// protoc v6.33.0
|
||||
// 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"`
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// 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[2]
|
||||
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[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 Token.ProtoReflect.Descriptor instead.
|
||||
func (*Token) Descriptor() ([]byte, []int) {
|
||||
return file_token_v1_token_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
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 ""
|
||||
}
|
||||
|
||||
var File_token_v1_token_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_token_v1_token_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x14token/v1/token.proto\x12\btoken.v1\"p\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\"M\n" +
|
||||
"\n" +
|
||||
"RefreshReq\x12#\n" +
|
||||
"\rrefresh_token\x18\x01 \x01(\tR\frefreshToken\x12\x1a\n" +
|
||||
"\bverified\x18\x02 \x01(\bR\bverified\"\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_token2r\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\"\x00B.Z,github.com/absmach/supermq/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, 3)
|
||||
var file_token_v1_token_proto_goTypes = []any{
|
||||
(*IssueReq)(nil), // 0: token.v1.IssueReq
|
||||
(*RefreshReq)(nil), // 1: token.v1.RefreshReq
|
||||
(*Token)(nil), // 2: token.v1.Token
|
||||
}
|
||||
var file_token_v1_token_proto_depIdxs = []int32{
|
||||
0, // 0: token.v1.TokenService.Issue:input_type -> token.v1.IssueReq
|
||||
1, // 1: token.v1.TokenService.Refresh:input_type -> token.v1.RefreshReq
|
||||
2, // 2: token.v1.TokenService.Issue:output_type -> token.v1.Token
|
||||
2, // 3: token.v1.TokenService.Refresh:output_type -> token.v1.Token
|
||||
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_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[2].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: 3,
|
||||
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,162 @@
|
||||
// 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.5.1
|
||||
// - protoc v6.33.0
|
||||
// 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"
|
||||
)
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// 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)
|
||||
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.Errorf(codes.Unimplemented, "method Issue not implemented")
|
||||
}
|
||||
func (UnimplementedTokenServiceServer) Refresh(context.Context, *RefreshReq) (*Token, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Refresh 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 pancis, 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)
|
||||
}
|
||||
|
||||
// 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,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "token/v1/token.proto",
|
||||
}
|
||||
@@ -0,0 +1,331 @@
|
||||
// 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/supermq"
|
||||
apiutil "github.com/absmach/supermq/api/http/util"
|
||||
"github.com/absmach/supermq/clients"
|
||||
"github.com/absmach/supermq/groups"
|
||||
"github.com/absmach/supermq/pkg/errors"
|
||||
svcerr "github.com/absmach/supermq/pkg/errors/service"
|
||||
"github.com/absmach/supermq/users"
|
||||
"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"
|
||||
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 = clients.Enabled
|
||||
DefUserStatus = users.Enabled
|
||||
DefGroupStatus = groups.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.(supermq.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
|
||||
}
|
||||
|
||||
var wrapper error
|
||||
if errors.Contains(err, apiutil.ErrValidation) {
|
||||
wrapper, err = errors.Unwrap(err)
|
||||
}
|
||||
|
||||
switch {
|
||||
case errors.Contains(err, errors.ErrTryAgain):
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
case errors.Contains(err, errors.ErrEmailAlreadyExists),
|
||||
errors.Contains(err, errors.ErrUsernameNotAvailable),
|
||||
errors.Contains(err, errors.ErrRouteNotAvailable),
|
||||
errors.Contains(err, errors.ErrChannelRouteNotAvailable),
|
||||
errors.Contains(err, errors.ErrDomainRouteNotAvailable),
|
||||
errors.Contains(err, svcerr.ErrExternalAuthProviderCouldNotChangePassword),
|
||||
errors.Contains(err, svcerr.ErrExternalAuthProviderCouldNotResetPassword),
|
||||
errors.Contains(err, svcerr.ErrExternalAuthProviderCouldNotUpdate):
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
case errors.Contains(err, svcerr.ErrAuthorization),
|
||||
errors.Contains(err, svcerr.ErrDomainAuthorization),
|
||||
errors.Contains(err, svcerr.ErrUnauthorizedPAT),
|
||||
errors.Contains(err, svcerr.ErrSuperAdminAction):
|
||||
err = unwrap(err)
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
|
||||
case errors.Contains(err, svcerr.ErrAuthentication),
|
||||
errors.Contains(err, apiutil.ErrBearerToken),
|
||||
errors.Contains(err, svcerr.ErrLogin),
|
||||
errors.Contains(err, apiutil.ErrUnsupportedTokenType):
|
||||
err = unwrap(err)
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
case errors.Contains(err, svcerr.ErrMalformedEntity),
|
||||
errors.Contains(err, apiutil.ErrMalformedPolicy),
|
||||
errors.Contains(err, apiutil.ErrMissingSecret),
|
||||
errors.Contains(err, errors.ErrMalformedEntity),
|
||||
errors.Contains(err, apiutil.ErrMissingID),
|
||||
errors.Contains(err, apiutil.ErrInvalidVerification),
|
||||
errors.Contains(err, apiutil.ErrMissingName),
|
||||
errors.Contains(err, apiutil.ErrMissingEmail),
|
||||
errors.Contains(err, apiutil.ErrInvalidEmail),
|
||||
errors.Contains(err, apiutil.ErrMissingHost),
|
||||
errors.Contains(err, apiutil.ErrInvalidResetPass),
|
||||
errors.Contains(err, apiutil.ErrEmptyList),
|
||||
errors.Contains(err, apiutil.ErrMissingMemberKind),
|
||||
errors.Contains(err, apiutil.ErrMissingMemberType),
|
||||
errors.Contains(err, apiutil.ErrLimitSize),
|
||||
errors.Contains(err, apiutil.ErrBearerKey),
|
||||
errors.Contains(err, svcerr.ErrInvalidStatus),
|
||||
errors.Contains(err, apiutil.ErrNameSize),
|
||||
errors.Contains(err, apiutil.ErrInvalidIDFormat),
|
||||
errors.Contains(err, apiutil.ErrInvalidQueryParams),
|
||||
errors.Contains(err, apiutil.ErrMissingRelation),
|
||||
errors.Contains(err, apiutil.ErrValidation),
|
||||
errors.Contains(err, apiutil.ErrMissingPass),
|
||||
errors.Contains(err, apiutil.ErrMissingConfPass),
|
||||
errors.Contains(err, apiutil.ErrPasswordFormat),
|
||||
errors.Contains(err, svcerr.ErrInvalidRole),
|
||||
errors.Contains(err, svcerr.ErrInvalidPolicy),
|
||||
errors.Contains(err, apiutil.ErrInvitationState),
|
||||
errors.Contains(err, apiutil.ErrInvalidAPIKey),
|
||||
errors.Contains(err, svcerr.ErrViewEntity),
|
||||
errors.Contains(err, apiutil.ErrMissingCertData),
|
||||
errors.Contains(err, apiutil.ErrInvalidContact),
|
||||
errors.Contains(err, apiutil.ErrInvalidTopic),
|
||||
errors.Contains(err, apiutil.ErrInvalidCertData),
|
||||
errors.Contains(err, apiutil.ErrEmptyMessage),
|
||||
errors.Contains(err, apiutil.ErrInvalidLevel),
|
||||
errors.Contains(err, apiutil.ErrInvalidDirection),
|
||||
errors.Contains(err, apiutil.ErrInvalidEntityType),
|
||||
errors.Contains(err, apiutil.ErrMissingEntityType),
|
||||
errors.Contains(err, apiutil.ErrInvalidTimeFormat),
|
||||
errors.Contains(err, svcerr.ErrSearch),
|
||||
errors.Contains(err, apiutil.ErrEmptySearchQuery),
|
||||
errors.Contains(err, apiutil.ErrLenSearchQuery),
|
||||
errors.Contains(err, apiutil.ErrMissingDomainID),
|
||||
errors.Contains(err, apiutil.ErrMissingUserID),
|
||||
errors.Contains(err, apiutil.ErrMissingPATID),
|
||||
errors.Contains(err, apiutil.ErrMissingUsername),
|
||||
errors.Contains(err, apiutil.ErrMissingUsernameEmail),
|
||||
errors.Contains(err, apiutil.ErrMissingFirstName),
|
||||
errors.Contains(err, apiutil.ErrMissingLastName),
|
||||
errors.Contains(err, apiutil.ErrInvalidUsername),
|
||||
errors.Contains(err, apiutil.ErrMissingIdentity),
|
||||
errors.Contains(err, apiutil.ErrInvalidProfilePictureURL),
|
||||
errors.Contains(err, apiutil.ErrSelfParentingNotAllowed),
|
||||
errors.Contains(err, apiutil.ErrMissingChildrenGroupIDs),
|
||||
errors.Contains(err, apiutil.ErrMissingParentGroupID),
|
||||
errors.Contains(err, apiutil.ErrMissingConnectionType),
|
||||
errors.Contains(err, apiutil.ErrMissingRoleName),
|
||||
errors.Contains(err, apiutil.ErrMissingRoleID),
|
||||
errors.Contains(err, apiutil.ErrMissingPolicyEntityType),
|
||||
errors.Contains(err, apiutil.ErrMissingRoleMembers),
|
||||
errors.Contains(err, apiutil.ErrMissingDescription),
|
||||
errors.Contains(err, apiutil.ErrMissingEntityID),
|
||||
errors.Contains(err, apiutil.ErrInvalidRouteFormat),
|
||||
errors.Contains(err, svcerr.ErrRetainOneMember),
|
||||
errors.Contains(err, apiutil.ErrMissingRoute):
|
||||
err = unwrap(err)
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
|
||||
case errors.Contains(err, svcerr.ErrCreateEntity),
|
||||
errors.Contains(err, svcerr.ErrUpdateEntity),
|
||||
errors.Contains(err, svcerr.ErrRemoveEntity),
|
||||
errors.Contains(err, svcerr.ErrEnableClient),
|
||||
errors.Contains(err, svcerr.ErrEnableUser),
|
||||
errors.Contains(err, svcerr.ErrDisableUser):
|
||||
err = unwrap(err)
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
|
||||
case errors.Contains(err, svcerr.ErrNotFound):
|
||||
err = unwrap(err)
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
|
||||
case errors.Contains(err, errors.ErrStatusAlreadyAssigned),
|
||||
errors.Contains(err, svcerr.ErrInvitationAlreadyRejected),
|
||||
errors.Contains(err, svcerr.ErrInvitationAlreadyAccepted),
|
||||
errors.Contains(err, svcerr.ErrConflict):
|
||||
err = unwrap(err)
|
||||
w.WriteHeader(http.StatusConflict)
|
||||
|
||||
case errors.Contains(err, apiutil.ErrUnsupportedContentType):
|
||||
err = unwrap(err)
|
||||
w.WriteHeader(http.StatusUnsupportedMediaType)
|
||||
|
||||
default:
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
if wrapper != nil {
|
||||
err = errors.Wrap(wrapper, err)
|
||||
}
|
||||
|
||||
if errorVal, ok := err.(errors.Error); ok {
|
||||
if err := json.NewEncoder(w).Encode(errorVal); err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func unwrap(err error) error {
|
||||
wrapper, err := errors.Unwrap(err)
|
||||
if wrapper != nil {
|
||||
return wrapper
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package api_test
|
||||
package http_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -10,16 +10,16 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/absmach/magistrala"
|
||||
"github.com/absmach/magistrala/internal/api"
|
||||
"github.com/absmach/magistrala/internal/testsutil"
|
||||
"github.com/absmach/magistrala/pkg/apiutil"
|
||||
"github.com/absmach/magistrala/pkg/errors"
|
||||
svcerr "github.com/absmach/magistrala/pkg/errors/service"
|
||||
"github.com/absmach/supermq"
|
||||
api "github.com/absmach/supermq/api/http"
|
||||
apiutil "github.com/absmach/supermq/api/http/util"
|
||||
"github.com/absmach/supermq/internal/testsutil"
|
||||
"github.com/absmach/supermq/pkg/errors"
|
||||
svcerr "github.com/absmach/supermq/pkg/errors/service"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
var _ magistrala.Response = (*response)(nil)
|
||||
var _ supermq.Response = (*response)(nil)
|
||||
|
||||
var validUUID = testsutil.GenerateUUID(&testing.T{})
|
||||
|
||||
@@ -115,7 +115,7 @@ func TestEncodeResponse(t *testing.T) {
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
resp interface{}
|
||||
resp any
|
||||
header http.Header
|
||||
code int
|
||||
body []byte
|
||||
@@ -0,0 +1,6 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// 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/supermq"
|
||||
"github.com/go-chi/chi/v5/middleware"
|
||||
)
|
||||
|
||||
func RequestIDMiddleware(idp supermq.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))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package apiutil
|
||||
package util
|
||||
|
||||
import "github.com/absmach/magistrala/pkg/errors"
|
||||
import "github.com/absmach/supermq/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
|
||||
@@ -21,6 +21,30 @@ var (
|
||||
// ErrMissingID indicates missing entity ID.
|
||||
ErrMissingID = errors.New("missing entity id")
|
||||
|
||||
// ErrMissingEntityID indicates missing entity ID.
|
||||
ErrMissingEntityID = errors.New("missing entity id")
|
||||
|
||||
// ErrMissingClientID indicates missing client ID.
|
||||
ErrMissingClientID = errors.New("missing cient id")
|
||||
|
||||
// ErrMissingChannelID indicates missing client ID.
|
||||
ErrMissingChannelID = errors.New("missing channel id")
|
||||
|
||||
// ErrMissingConnectionType indicates missing connection tpye.
|
||||
ErrMissingConnectionType = errors.New("missing connection type")
|
||||
|
||||
// ErrMissingParentGroupID indicates missing parent group ID.
|
||||
ErrMissingParentGroupID = errors.New("missing parent group id")
|
||||
|
||||
// ErrMissingChildrenGroupIDs indicates missing children group IDs.
|
||||
ErrMissingChildrenGroupIDs = errors.New("missing children group ids")
|
||||
|
||||
// ErrSelfParentingNotAllowed indicates child id is same as parent id.
|
||||
ErrSelfParentingNotAllowed = errors.New("self parenting not allowed")
|
||||
|
||||
// ErrInvalidChildGroupID indicates invalid child group ID.
|
||||
ErrInvalidChildGroupID = errors.New("invalid child group id")
|
||||
|
||||
// ErrInvalidAuthKey indicates invalid auth key.
|
||||
ErrInvalidAuthKey = errors.New("invalid auth key")
|
||||
|
||||
@@ -39,6 +63,9 @@ var (
|
||||
// ErrLimitSize indicates that an invalid limit.
|
||||
ErrLimitSize = errors.New("invalid limit size")
|
||||
|
||||
// ErrLevel indicates that an invalid level.
|
||||
ErrLevel = errors.New("invalid level")
|
||||
|
||||
// ErrOffsetSize indicates an invalid offset.
|
||||
ErrOffsetSize = errors.New("invalid offset size")
|
||||
|
||||
@@ -54,6 +81,18 @@ var (
|
||||
// ErrEmptyList indicates that entity data is empty.
|
||||
ErrEmptyList = errors.New("empty list provided")
|
||||
|
||||
// ErrMissingRoleName indicates that role name is empty.
|
||||
ErrMissingRoleName = errors.New("empty role name")
|
||||
|
||||
// ErrMissingRoleID indicates that role id is empty.
|
||||
ErrMissingRoleID = errors.New("empty role id")
|
||||
|
||||
// ErrMissingRoleOperations indicates that role operations are empty.
|
||||
ErrMissingRoleOperations = errors.New("empty role operations")
|
||||
|
||||
// ErrMissingRoleMembers indicates that role members are empty.
|
||||
ErrMissingRoleMembers = errors.New("empty role members")
|
||||
|
||||
// ErrMalformedPolicy indicates that policies are malformed.
|
||||
ErrMalformedPolicy = errors.New("malformed policy")
|
||||
|
||||
@@ -105,6 +144,9 @@ var (
|
||||
// ErrInvalidComparator indicates an invalid comparator.
|
||||
ErrInvalidComparator = errors.New("invalid comparator")
|
||||
|
||||
// ErrMissingMemberIDs indicates missing member ids.
|
||||
ErrMissingMemberIDs = errors.New("missing member ids")
|
||||
|
||||
// ErrMissingMemberType indicates missing group member type.
|
||||
ErrMissingMemberType = errors.New("missing group member type")
|
||||
|
||||
@@ -120,9 +162,6 @@ var (
|
||||
// ErrInvalidAPIKey indicates an invalid API key type.
|
||||
ErrInvalidAPIKey = errors.New("invalid api key type")
|
||||
|
||||
// ErrBootstrapState indicates an invalid bootstrap state.
|
||||
ErrBootstrapState = errors.New("invalid bootstrap state")
|
||||
|
||||
// ErrInvitationState indicates an invalid invitation state.
|
||||
ErrInvitationState = errors.New("invalid invitation state")
|
||||
|
||||
@@ -138,8 +177,8 @@ var (
|
||||
// ErrMissingName indicates missing identity name.
|
||||
ErrMissingName = errors.New("missing identity name")
|
||||
|
||||
// ErrMissingName indicates missing alias.
|
||||
ErrMissingAlias = errors.New("missing alias")
|
||||
// ErrMissingRoute indicates missing route.
|
||||
ErrMissingRoute = errors.New("missing route")
|
||||
|
||||
// ErrInvalidLevel indicates an invalid group level.
|
||||
ErrInvalidLevel = errors.New("invalid group level (should be between 0 and 5)")
|
||||
@@ -195,7 +234,7 @@ var (
|
||||
// ErrMissingUsername indicates missing user name.
|
||||
ErrMissingUsername = errors.New("missing username")
|
||||
|
||||
// ErrInvalidUsername indicates missing user name.
|
||||
// ErrInvalidUsername indicates invalid user name.
|
||||
ErrInvalidUsername = errors.New("invalid username")
|
||||
|
||||
// ErrMissingFirstName indicates missing first name.
|
||||
@@ -206,4 +245,33 @@ var (
|
||||
|
||||
// ErrInvalidProfilePictureURL indicates that the profile picture url is invalid.
|
||||
ErrInvalidProfilePictureURL = errors.New("invalid profile picture url")
|
||||
|
||||
ErrMultipleEntitiesFilter = errors.New("multiple entities are provided in filter are not supported")
|
||||
|
||||
// ErrMissingDescription indicates missing description.
|
||||
ErrMissingDescription = errors.New("missing description")
|
||||
|
||||
// ErrUnsupportedTokenType indicates that this type of token is not supported.
|
||||
ErrUnsupportedTokenType = errors.New("unsupported content token type")
|
||||
|
||||
// ErrMissingUserID indicates missing user ID.
|
||||
ErrMissingUserID = errors.New("missing user id")
|
||||
|
||||
// ErrMissingPATID indicates missing pat ID.
|
||||
ErrMissingPATID = errors.New("missing pat id")
|
||||
|
||||
// ErrInvalidNameFormat indicates invalid name format.
|
||||
ErrInvalidNameFormat = errors.New("invalid name format")
|
||||
|
||||
// ErrInvalidRouteFormat indicates invalid route format.
|
||||
ErrInvalidRouteFormat = errors.New("invalid route format")
|
||||
|
||||
// ErrMissingUsernameEmail indicates missing user name / email.
|
||||
ErrMissingUsernameEmail = errors.New("missing username / email")
|
||||
|
||||
// ErrInvalidVerification indicates invalid email verification.
|
||||
ErrInvalidVerification = errors.New("invalid verification")
|
||||
|
||||
// ErrEmailNotVerified indicates invalid email not verified.
|
||||
ErrEmailNotVerified = errors.New("email not verified")
|
||||
)
|
||||
@@ -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 {
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package apiutil
|
||||
package util
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
@@ -11,8 +11,8 @@ import (
|
||||
// BearerPrefix represents the token prefix for Bearer authentication scheme.
|
||||
const BearerPrefix = "Bearer "
|
||||
|
||||
// ThingPrefix represents the key prefix for Thing authentication scheme.
|
||||
const ThingPrefix = "Thing "
|
||||
// ClientPrefix represents the key prefix for Client authentication scheme.
|
||||
const ClientPrefix = "Client "
|
||||
|
||||
// ExtractBearerToken returns value of the bearer token. If there is no bearer token - an empty value is returned.
|
||||
func ExtractBearerToken(r *http.Request) string {
|
||||
@@ -25,13 +25,13 @@ func ExtractBearerToken(r *http.Request) string {
|
||||
return strings.TrimPrefix(token, BearerPrefix)
|
||||
}
|
||||
|
||||
// ExtractThingKey returns value of the thing key. If there is no thing key - an empty value is returned.
|
||||
func ExtractThingKey(r *http.Request) string {
|
||||
// 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, ThingPrefix) {
|
||||
if !strings.HasPrefix(token, ClientPrefix) {
|
||||
return ""
|
||||
}
|
||||
|
||||
return strings.TrimPrefix(token, ThingPrefix)
|
||||
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/pkg/apiutil"
|
||||
apiutil "github.com/absmach/supermq/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"
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/absmach/magistrala/pkg/errors"
|
||||
"github.com/absmach/supermq/pkg/errors"
|
||||
kithttp "github.com/go-kit/kit/transport/http"
|
||||
)
|
||||
|
||||
@@ -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,10 +11,10 @@ import (
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
mglog "github.com/absmach/magistrala/logger"
|
||||
"github.com/absmach/magistrala/pkg/apiutil"
|
||||
"github.com/absmach/magistrala/pkg/errors"
|
||||
svcerr "github.com/absmach/magistrala/pkg/errors/service"
|
||||
apiutil "github.com/absmach/supermq/api/http/util"
|
||||
smqlog "github.com/absmach/supermq/logger"
|
||||
"github.com/absmach/supermq/pkg/errors"
|
||||
svcerr "github.com/absmach/supermq/pkg/errors/service"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@@ -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)
|
||||
@@ -355,7 +355,7 @@ func TestLoggingErrorEncoder(t *testing.T) {
|
||||
encCalled = true
|
||||
}
|
||||
|
||||
errorEncoder := apiutil.LoggingErrorEncoder(mglog.NewMock(), encFunc)
|
||||
errorEncoder := apiutil.LoggingErrorEncoder(smqlog.NewMock(), encFunc)
|
||||
errorEncoder(context.Background(), c.err, httptest.NewRecorder())
|
||||
|
||||
assert.True(t, encCalled)
|
||||
@@ -1,5 +0,0 @@
|
||||
# Magistrala OpenAPI Specification
|
||||
|
||||
This folder contains an OpenAPI specifications for Magistrala API.
|
||||
|
||||
View specification in Swagger UI at [docs.api.magistrala.abstractmachines.fr](https://docs.api.magistrala.abstractmachines.fr)
|
||||
@@ -1,833 +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@abstractmachines.fr
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: https://github.com/absmach/magistrala/blob/main/LICENSE
|
||||
version: 0.14.0
|
||||
|
||||
servers:
|
||||
- url: http://localhost:8189
|
||||
- url: https://localhost:8189
|
||||
|
||||
tags:
|
||||
- name: Keys
|
||||
description: Everything about your Keys.
|
||||
externalDocs:
|
||||
description: Find out more about keys
|
||||
url: https://docs.magistrala.abstractmachines.fr/
|
||||
|
||||
- name: Domains
|
||||
description: Everything about your Domains.
|
||||
externalDocs:
|
||||
description: Find out more about domains
|
||||
url: https://docs.magistrala.abstractmachines.fr/
|
||||
|
||||
- name: Health
|
||||
description: Service health check endpoint.
|
||||
externalDocs:
|
||||
description: Find out more about health check
|
||||
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"
|
||||
"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"
|
||||
|
||||
/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"
|
||||
"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"
|
||||
|
||||
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"
|
||||
|
||||
/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"
|
||||
"400":
|
||||
description: Malformed entity specification.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"403":
|
||||
description: Failed authorization over the domain.
|
||||
"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 user from domain
|
||||
description: |
|
||||
Unassign user from domain that is identified by the domain ID.
|
||||
tags:
|
||||
- Domains
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/DomainID"
|
||||
requestBody:
|
||||
$ref: "#/components/requestBodies/UnassignUsersReq"
|
||||
security:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
"204":
|
||||
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:
|
||||
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.
|
||||
"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.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
/users/{userID}/domains:
|
||||
get:
|
||||
tags:
|
||||
- Domains
|
||||
summary: Lists domains associated with a user.
|
||||
description: |
|
||||
Retrieves a list of domains associated with a user. 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/UserID"
|
||||
- $ref: "#/components/parameters/Limit"
|
||||
- $ref: "#/components/parameters/Offset"
|
||||
- $ref: "#/components/parameters/Metadata"
|
||||
- $ref: "#/components/parameters/Status"
|
||||
security:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
"200":
|
||||
$ref: "#/components/responses/DomainsPageRes"
|
||||
"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
|
||||
security: []
|
||||
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:
|
||||
- domains
|
||||
- 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
|
||||
|
||||
AssignUserDomainRelationReq:
|
||||
type: object
|
||||
properties:
|
||||
user_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", "contributor", "member", "guest"]
|
||||
example: "administrator"
|
||||
description: Policy relations.
|
||||
required:
|
||||
- user_ids
|
||||
- relation
|
||||
UnassignUserDomainRelationReq:
|
||||
type: object
|
||||
properties:
|
||||
user_id:
|
||||
type: string
|
||||
format: uuid
|
||||
example: bb7edb32-2eac-4aad-aebe-ed96fe073879
|
||||
description: User unique identifier.
|
||||
required:
|
||||
- user_id
|
||||
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:
|
||||
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/AssignUserDomainRelationReq"
|
||||
|
||||
UnassignUsersReq:
|
||||
description: JSON-formated document describing the policy related to unassigning user from a domain
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/UnassignUserDomainRelationReq"
|
||||
|
||||
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:
|
||||
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"
|
||||
links:
|
||||
revoke:
|
||||
operationId: revokeKey
|
||||
parameters:
|
||||
keyID: $response.body#/id
|
||||
|
||||
HealthRes:
|
||||
description: Service Health Check.
|
||||
content:
|
||||
application/health+json:
|
||||
schema:
|
||||
$ref: "./schemas/HealthInfo.yml"
|
||||
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
description: |
|
||||
* Users access: "Authorization: Bearer <user_token>"
|
||||
|
||||
security:
|
||||
- bearerAuth: []
|
||||
@@ -1,689 +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@abstractmachines.fr
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: https://github.com/absmach/magistrala/blob/main/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:
|
||||
/{domainID}/things/configs:
|
||||
post:
|
||||
operationId: createConfig
|
||||
summary: Adds new config
|
||||
description: |
|
||||
Adds new config to the list of config owned by user identified using
|
||||
the provided access token.
|
||||
tags:
|
||||
- configs
|
||||
parameters:
|
||||
- $ref: "auth.yml#/components/parameters/DomainID"
|
||||
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.
|
||||
"403":
|
||||
description: Failed to perform authorization over the entity.
|
||||
"404":
|
||||
description: A non-existent entity request.
|
||||
"409":
|
||||
description: Failed due to using an existing identity.
|
||||
"415":
|
||||
description: Missing or invalid content type.
|
||||
"422":
|
||||
description: Database can't process request.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
"503":
|
||||
description: Failed to receive response from the things service.
|
||||
get:
|
||||
operationId: getConfigs
|
||||
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: "auth.yml#/components/parameters/DomainID"
|
||||
- $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.
|
||||
"422":
|
||||
description: Database can't process request.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
/{domainID}/things/configs/{configId}:
|
||||
get:
|
||||
operationId: getConfig
|
||||
summary: Retrieves config info (with channels).
|
||||
tags:
|
||||
- configs
|
||||
parameters:
|
||||
- $ref: "auth.yml#/components/parameters/DomainID"
|
||||
- $ref: "#/components/parameters/ConfigId"
|
||||
responses:
|
||||
"200":
|
||||
$ref: "#/components/responses/ConfigRes"
|
||||
"400":
|
||||
description: Missing or invalid config.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"403":
|
||||
description: Failed to perform authorization over the entity.
|
||||
"404":
|
||||
description: Config does not exist.
|
||||
"422":
|
||||
description: Database can't process request.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
put:
|
||||
operationId: updateConfig
|
||||
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: "auth.yml#/components/parameters/DomainID"
|
||||
- $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.
|
||||
"403":
|
||||
description: Failed to perform authorization over the entity.
|
||||
"404":
|
||||
description: Config does not exist.
|
||||
"415":
|
||||
description: Missing or invalid content type.
|
||||
"422":
|
||||
description: Database can't process request.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
delete:
|
||||
operationId: removeConfig
|
||||
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: "auth.yml#/components/parameters/DomainID"
|
||||
- $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.
|
||||
"403":
|
||||
description: Failed to perform authorization over the entity.
|
||||
"422":
|
||||
description: Database can't process request.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
/{domainID}/things/configs/certs/{configId}:
|
||||
patch:
|
||||
operationId: updateConfigCerts
|
||||
summary: Updates certs
|
||||
description: |
|
||||
Update is performed by replacing the current certificate data with values
|
||||
provided in a request payload.
|
||||
tags:
|
||||
- configs
|
||||
parameters:
|
||||
- $ref: "auth.yml#/components/parameters/DomainID"
|
||||
- $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.
|
||||
"403":
|
||||
description: Failed to perform authorization over the entity.
|
||||
"404":
|
||||
description: Config does not exist.
|
||||
"415":
|
||||
description: Missing or invalid content type.
|
||||
"422":
|
||||
description: Database can't process request.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
/{domainID}/things/configs/connections/{configId}:
|
||||
put:
|
||||
operationId: updateConfigConnections
|
||||
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: "auth.yml#/components/parameters/DomainID"
|
||||
- $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.
|
||||
"403":
|
||||
description: Failed to perform authorization over the entity.
|
||||
"404":
|
||||
description: Config does not exist.
|
||||
"415":
|
||||
description: Missing or invalid content type.
|
||||
"422":
|
||||
description: Database can't process request.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
/things/bootstrap/{externalId}:
|
||||
get:
|
||||
operationId: getBootstrapConfig
|
||||
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.
|
||||
"422":
|
||||
description: Database can't process request.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
/things/bootstrap/secure/{externalId}:
|
||||
get:
|
||||
operationId: getSecureBootstrapConfig
|
||||
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"
|
||||
"400":
|
||||
description: Failed due to malformed JSON.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"404":
|
||||
description: |
|
||||
Failed to retrieve corresponding config.
|
||||
"422":
|
||||
description: Database can't process request.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
/{domainID}/things/state/{configId}:
|
||||
put:
|
||||
operationId: updateConfigState
|
||||
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: "auth.yml#/components/parameters/DomainID"
|
||||
- $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.
|
||||
"404":
|
||||
description: A non-existent entity request.
|
||||
"415":
|
||||
description: Missing or invalid content type.
|
||||
"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:
|
||||
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
|
||||
format: uuid
|
||||
description: ID of the corresponding Magistrala Thing.
|
||||
channels:
|
||||
type: array
|
||||
minItems: 0
|
||||
items:
|
||||
type: string
|
||||
format: uuid
|
||||
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
|
||||
format: uuid
|
||||
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"
|
||||
links:
|
||||
update:
|
||||
operationId: updateConfig
|
||||
parameters:
|
||||
configId: $response.body#/id
|
||||
updateCerts:
|
||||
operationId: updateConfigCerts
|
||||
parameters:
|
||||
configId: $response.body#/id
|
||||
updateConnections:
|
||||
operationId: updateConfigConnections
|
||||
parameters:
|
||||
configId: $response.body#/id
|
||||
updateState:
|
||||
operationId: updateConfigState
|
||||
parameters:
|
||||
configId: $response.body#/id
|
||||
delete:
|
||||
operationId: removeConfig
|
||||
parameters:
|
||||
configId: $response.body#/id
|
||||
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/health+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,313 +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@abstractmachines.fr
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: https://github.com/absmach/magistrala/blob/main/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:
|
||||
/{domainID}/certs:
|
||||
post:
|
||||
operationId: createCert
|
||||
summary: Creates a certificate for thing
|
||||
description: Creates a certificate for thing
|
||||
tags:
|
||||
- certs
|
||||
parameters:
|
||||
- $ref: "auth.yml#/components/parameters/DomainID"
|
||||
requestBody:
|
||||
$ref: "#/components/requestBodies/CertReq"
|
||||
responses:
|
||||
"201":
|
||||
description: Created
|
||||
"400":
|
||||
description: Failed due to malformed JSON.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"403":
|
||||
description: Failed to perform authorization over the entity.
|
||||
"415":
|
||||
description: Missing or invalid content type.
|
||||
"422":
|
||||
description: Database can't process request.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
/{domainID}/certs/{certID}:
|
||||
get:
|
||||
operationId: getCert
|
||||
summary: Retrieves a certificate
|
||||
description: |
|
||||
Retrieves a certificate for a given cert ID.
|
||||
tags:
|
||||
- certs
|
||||
parameters:
|
||||
- $ref: "auth.yml#/components/parameters/DomainID"
|
||||
- $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.
|
||||
"403":
|
||||
description: Failed to perform authorization over the entity.
|
||||
"404":
|
||||
description: |
|
||||
Failed to retrieve corresponding certificate.
|
||||
"422":
|
||||
description: Database can't process request.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
delete:
|
||||
operationId: revokeCert
|
||||
summary: Revokes a certificate
|
||||
description: |
|
||||
Revokes a certificate for a given cert ID.
|
||||
tags:
|
||||
- certs
|
||||
parameters:
|
||||
- $ref: "auth.yml#/components/parameters/DomainID"
|
||||
- $ref: "#/components/parameters/CertID"
|
||||
responses:
|
||||
"200":
|
||||
$ref: "#/components/responses/RevokeRes"
|
||||
"400":
|
||||
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: |
|
||||
Failed to revoke corresponding certificate.
|
||||
"422":
|
||||
description: Database can't process request.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
/{domainID}/serials/{thingID}:
|
||||
get:
|
||||
operationId: getSerials
|
||||
summary: Retrieves certificates' serial IDs
|
||||
description: |
|
||||
Retrieves a list of certificates' serial IDs for a given thing ID.
|
||||
tags:
|
||||
- certs
|
||||
parameters:
|
||||
- $ref: "auth.yml#/components/parameters/DomainID"
|
||||
- $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.
|
||||
"403":
|
||||
description: Failed to perform authorization over the entity.
|
||||
"404":
|
||||
description: |
|
||||
Failed to retrieve corresponding certificates.
|
||||
"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:
|
||||
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"
|
||||
links:
|
||||
serial:
|
||||
operationId: getSerials
|
||||
parameters:
|
||||
thingID: $response.body#/thing_id
|
||||
delete:
|
||||
operationId: revokeCert
|
||||
parameters:
|
||||
certID: $response.body#/serial
|
||||
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/health+json:
|
||||
schema:
|
||||
$ref: "./schemas/HealthInfo.yml"
|
||||
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
description: |
|
||||
* Users access: "Authorization: Bearer <user_token>"
|
||||
|
||||
security:
|
||||
- bearerAuth: []
|
||||
@@ -1,537 +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@abstractmachines.fr
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: https://github.com/absmach/magistrala/blob/main/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:
|
||||
operationId: sendInvitation
|
||||
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.
|
||||
"403":
|
||||
description: Failed to perform authorization over the entity.
|
||||
"404":
|
||||
description: A non-existent entity request.
|
||||
"409":
|
||||
description: Failed due to using an existing identity.
|
||||
"415":
|
||||
description: Missing or invalid content type.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
get:
|
||||
operationId: listInvitations
|
||||
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.
|
||||
"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"
|
||||
|
||||
/invitations/accept:
|
||||
post:
|
||||
operationId: acceptInvitation
|
||||
summary: Accept invitation
|
||||
description: |
|
||||
Current logged in user accepts invitation to join domain.
|
||||
tags:
|
||||
- Invitations
|
||||
security:
|
||||
- bearerAuth: []
|
||||
requestBody:
|
||||
$ref: "#/components/requestBodies/AcceptInvitationReq"
|
||||
responses:
|
||||
"204":
|
||||
description: Invitation accepted.
|
||||
"400":
|
||||
description: Failed due to malformed query parameters.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"404":
|
||||
description: A non-existent entity request.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
/invitations/reject:
|
||||
post:
|
||||
operationId: rejectInvitation
|
||||
summary: Reject invitation
|
||||
description: |
|
||||
Current logged in user rejects invitation to join domain.
|
||||
tags:
|
||||
- Invitations
|
||||
security:
|
||||
- bearerAuth: []
|
||||
requestBody:
|
||||
$ref: "#/components/requestBodies/AcceptInvitationReq"
|
||||
responses:
|
||||
"204":
|
||||
description: Invitation rejected.
|
||||
"400":
|
||||
description: Failed due to malformed query parameters.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"404":
|
||||
description: A non-existent entity request.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
/invitations/{user_id}/{domain_id}:
|
||||
get:
|
||||
operationId: getInvitation
|
||||
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.
|
||||
"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: deleteInvitation
|
||||
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.
|
||||
"403":
|
||||
description: Failed to perform authorization over the entity.
|
||||
"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
|
||||
security: []
|
||||
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
|
||||
- contributor
|
||||
- member
|
||||
- guest
|
||||
- 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
|
||||
- contributor
|
||||
- member
|
||||
- guest
|
||||
- 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
|
||||
- contributor
|
||||
- member
|
||||
- guest
|
||||
- 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"
|
||||
links:
|
||||
delete:
|
||||
operationId: deleteInvitation
|
||||
parameters:
|
||||
user_id: $response.body#/user_id
|
||||
domain_id: $response.body#/domain_id
|
||||
|
||||
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,292 +0,0 @@
|
||||
# Copyright (c) Abstract Machines
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
openapi: 3.0.1
|
||||
info:
|
||||
title: Magistrala Notifiers service
|
||||
description: |
|
||||
HTTP API for Notifiers service.
|
||||
Some useful links:
|
||||
- [The Magistrala repository](https://github.com/absmach/magistrala)
|
||||
contact:
|
||||
email: info@abstractmachines.fr
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: https://github.com/absmach/magistrala/blob/main/LICENSE
|
||||
version: 0.14.0
|
||||
|
||||
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/
|
||||
|
||||
paths:
|
||||
/subscriptions:
|
||||
post:
|
||||
operationId: createSubscription
|
||||
summary: Create subscription
|
||||
description: Creates a new subscription give a topic and contact.
|
||||
tags:
|
||||
- notifiers
|
||||
requestBody:
|
||||
$ref: "#/components/requestBodies/Create"
|
||||
responses:
|
||||
"201":
|
||||
$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:
|
||||
- notifiers
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/Topic"
|
||||
- $ref: "#/components/parameters/Contact"
|
||||
- $ref: "#/components/parameters/Offset"
|
||||
- $ref: "#/components/parameters/Limit"
|
||||
responses:
|
||||
"200":
|
||||
$ref: "#/components/responses/Page"
|
||||
"400":
|
||||
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:
|
||||
- notifiers
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/Id"
|
||||
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:
|
||||
- notifiers
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/Id"
|
||||
responses:
|
||||
"204":
|
||||
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:
|
||||
get:
|
||||
summary: Retrieves service health check info.
|
||||
tags:
|
||||
- health
|
||||
security: []
|
||||
responses:
|
||||
"200":
|
||||
$ref: "#/components/responses/HealthRes"
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
components:
|
||||
schemas:
|
||||
Subscription:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: ulid
|
||||
example: 01EWDVKBQSG80B6PQRS9PAAY35
|
||||
description: ULID id of the subscription.
|
||||
owner_id:
|
||||
type: string
|
||||
format: uuid
|
||||
example: 18167738-f7a8-4e96-a123-58c3cd14de3a
|
||||
description: An id of the owner who created subscription.
|
||||
topic:
|
||||
type: string
|
||||
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.
|
||||
CreateSubscription:
|
||||
type: object
|
||||
properties:
|
||||
topic:
|
||||
type: string
|
||||
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.
|
||||
Page:
|
||||
type: object
|
||||
properties:
|
||||
subscriptions:
|
||||
type: array
|
||||
minItems: 0
|
||||
uniqueItems: true
|
||||
items:
|
||||
$ref: "#/components/schemas/Subscription"
|
||||
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.
|
||||
|
||||
parameters:
|
||||
Id:
|
||||
name: id
|
||||
description: Unique identifier.
|
||||
in: path
|
||||
schema:
|
||||
type: string
|
||||
format: ulid
|
||||
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
|
||||
Topic:
|
||||
name: topic
|
||||
description: Topic name.
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
required: false
|
||||
Contact:
|
||||
name: contact
|
||||
description: Subscription contact.
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
required: false
|
||||
|
||||
requestBodies:
|
||||
Create:
|
||||
description: JSON-formatted document describing the new subscription to be created
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/CreateSubscription"
|
||||
|
||||
responses:
|
||||
Create:
|
||||
description: Created a new subscription.
|
||||
headers:
|
||||
Location:
|
||||
content:
|
||||
text/plain:
|
||||
schema:
|
||||
type: string
|
||||
description: Created subscription relative URL
|
||||
example: /subscriptions/{id}
|
||||
View:
|
||||
description: View subscription.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Subscription"
|
||||
links:
|
||||
delete:
|
||||
operationId: removeSubscription
|
||||
parameters:
|
||||
id: $response.body#/id
|
||||
Page:
|
||||
description: Data retrieved.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Page"
|
||||
ServiceError:
|
||||
description: Unexpected server-side error occurred.
|
||||
HealthRes:
|
||||
description: Service Health Check.
|
||||
content:
|
||||
application/health+json:
|
||||
schema:
|
||||
$ref: "./schemas/HealthInfo.yml"
|
||||
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
description: |
|
||||
* Users access: "Authorization: Bearer <user_token>"
|
||||
|
||||
security:
|
||||
- bearerAuth: []
|
||||
@@ -1,129 +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@abstracmachines.fr
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: https://github.com/absmach/magistrala/blob/main/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:
|
||||
/{domainID}/mapping:
|
||||
post:
|
||||
summary: Adds new device to proxy
|
||||
description: Adds new device to proxy
|
||||
tags:
|
||||
- provision
|
||||
parameters:
|
||||
- $ref: "auth.yml#/components/parameters/DomainID"
|
||||
requestBody:
|
||||
$ref: "#/components/requestBodies/ProvisionReq"
|
||||
responses:
|
||||
"201":
|
||||
description: Created
|
||||
"400":
|
||||
description: Failed due to malformed JSON.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"415":
|
||||
description: Missing or invalid content type.
|
||||
"422":
|
||||
description: Database can't process request.
|
||||
"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
|
||||
parameters:
|
||||
- $ref: "auth.yml#/components/parameters/DomainID"
|
||||
responses:
|
||||
"200":
|
||||
$ref: "#/components/responses/ProvisionRes"
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"415":
|
||||
description: Missing or invalid content type.
|
||||
"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:
|
||||
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/health+json:
|
||||
schema:
|
||||
$ref: "./schemas/HealthInfo.yml"
|
||||
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
description: |
|
||||
* Users access: "Authorization: Bearer <user_token>"
|
||||
|
||||
security:
|
||||
- bearerAuth: []
|
||||
@@ -1,314 +0,0 @@
|
||||
# Copyright (c) Abstract Machines
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
openapi: 3.0.1
|
||||
info:
|
||||
title: Magistrala reader service
|
||||
description: |
|
||||
HTTP API for reading messages.
|
||||
Some useful links:
|
||||
- [The Magistrala repository](https://github.com/absmach/magistrala)
|
||||
contact:
|
||||
email: info@abstractmachines.fr
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: https://github.com/absmach/magistrala/blob/main/LICENSE
|
||||
version: 0.14.0
|
||||
|
||||
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/
|
||||
|
||||
paths:
|
||||
/{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
|
||||
performance concerns, data is retrieved in subsets. The API readers must
|
||||
ensure that the entire dataset is consumed either by making subsequent
|
||||
requests, or by increasing the subset size of the initial request.
|
||||
tags:
|
||||
- readers
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/DomainID"
|
||||
- $ref: "#/components/parameters/ChanId"
|
||||
- $ref: "#/components/parameters/Limit"
|
||||
- $ref: "#/components/parameters/Offset"
|
||||
- $ref: "#/components/parameters/Publisher"
|
||||
- $ref: "#/components/parameters/Name"
|
||||
- $ref: "#/components/parameters/Value"
|
||||
- $ref: "#/components/parameters/BoolValue"
|
||||
- $ref: "#/components/parameters/StringValue"
|
||||
- $ref: "#/components/parameters/DataValue"
|
||||
- $ref: "#/components/parameters/From"
|
||||
- $ref: "#/components/parameters/To"
|
||||
- $ref: "#/components/parameters/Aggregation"
|
||||
- $ref: "#/components/parameters/Interval"
|
||||
responses:
|
||||
"200":
|
||||
$ref: "#/components/responses/MessagesPageRes"
|
||||
"400":
|
||||
description: Failed due to malformed query parameters.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
/health:
|
||||
get:
|
||||
operationId: health
|
||||
summary: Retrieves service health check info.
|
||||
tags:
|
||||
- health
|
||||
security: []
|
||||
responses:
|
||||
"200":
|
||||
$ref: "#/components/responses/HealthRes"
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
components:
|
||||
schemas:
|
||||
MessagesPage:
|
||||
type: object
|
||||
properties:
|
||||
total:
|
||||
type: number
|
||||
description: Total number of items that are present on the system.
|
||||
offset:
|
||||
type: number
|
||||
description: Number of items that were skipped during retrieval.
|
||||
limit:
|
||||
type: number
|
||||
description: Size of the subset that was retrieved.
|
||||
messages:
|
||||
type: array
|
||||
minItems: 0
|
||||
uniqueItems: true
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
channel:
|
||||
type: integer
|
||||
description: Unique channel id.
|
||||
publisher:
|
||||
type: integer
|
||||
description: Unique publisher id.
|
||||
protocol:
|
||||
type: string
|
||||
description: Protocol name.
|
||||
name:
|
||||
type: string
|
||||
description: Measured parameter name.
|
||||
unit:
|
||||
type: string
|
||||
description: Value unit.
|
||||
value:
|
||||
type: number
|
||||
description: Measured value in number.
|
||||
stringValue:
|
||||
type: string
|
||||
description: Measured value in string format.
|
||||
boolValue:
|
||||
type: boolean
|
||||
description: Measured value in boolean format.
|
||||
dataValue:
|
||||
type: string
|
||||
description: Measured value in binary format.
|
||||
valueSum:
|
||||
type: number
|
||||
description: Sum value.
|
||||
time:
|
||||
type: number
|
||||
description: Time of measurement.
|
||||
updateTime:
|
||||
type: number
|
||||
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.
|
||||
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
|
||||
Publisher:
|
||||
name: Publisher
|
||||
description: Unique thing identifier.
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
required: false
|
||||
Name:
|
||||
name: name
|
||||
description: SenML message name.
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
required: false
|
||||
Value:
|
||||
name: v
|
||||
description: SenML message value.
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
required: false
|
||||
BoolValue:
|
||||
name: vb
|
||||
description: SenML message bool value.
|
||||
in: query
|
||||
schema:
|
||||
type: boolean
|
||||
required: false
|
||||
StringValue:
|
||||
name: vs
|
||||
description: SenML message string value.
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
required: false
|
||||
DataValue:
|
||||
name: vd
|
||||
description: SenML message data value.
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
required: false
|
||||
Comparator:
|
||||
name: comparator
|
||||
description: Value comparison operator.
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
default: eq
|
||||
enum:
|
||||
- eq
|
||||
- lt
|
||||
- le
|
||||
- gt
|
||||
- ge
|
||||
required: false
|
||||
From:
|
||||
name: from
|
||||
description: SenML message time in nanoseconds (integer part represents seconds).
|
||||
in: query
|
||||
schema:
|
||||
type: number
|
||||
example: 1709218556069
|
||||
required: false
|
||||
To:
|
||||
name: to
|
||||
description: SenML message time in nanoseconds (integer part represents seconds).
|
||||
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:
|
||||
MessagesPageRes:
|
||||
description: Data retrieved.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/MessagesPage"
|
||||
ServiceError:
|
||||
description: Unexpected server-side error occurred.
|
||||
HealthRes:
|
||||
description: Service Health Check.
|
||||
content:
|
||||
application/health+json:
|
||||
schema:
|
||||
$ref: "./schemas/HealthInfo.yml"
|
||||
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
description: |
|
||||
* Users access: "Authorization: Bearer <user_token>"
|
||||
|
||||
thingAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: uuid
|
||||
description: |
|
||||
* Things access: "Authorization: Thing <thing_key>"
|
||||
|
||||
security:
|
||||
- bearerAuth: []
|
||||
- thingAuth: []
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,13 +2,13 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
asyncapi: '2.6.0'
|
||||
id: 'https://github.com/absmach/magistrala/blob/main/api/asyncapi/mqtt.yml'
|
||||
id: 'https://github.com/absmach/supermq/blob/main/api/asyncapi/mqtt.yaml'
|
||||
info:
|
||||
title: Magistrala MQTT Adapter
|
||||
version: '1.0.0'
|
||||
title: SuperMQ MQTT Adapter
|
||||
version: '0.18.0'
|
||||
contact:
|
||||
name: Magistrala Team
|
||||
url: 'https://github.com/absmach/magistrala'
|
||||
name: SuperMQ Team
|
||||
url: 'https://github.com/absmach/supermq'
|
||||
email: info@abstractmachines.fr
|
||||
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.
|
||||
@@ -16,9 +16,9 @@ info:
|
||||
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: 'https://github.com/absmach/magistrala/blob/main/LICENSE'
|
||||
|
||||
|
||||
url: 'https://github.com/absmach/supermq/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/main/api/asyncapi/websocket.yml'
|
||||
id: 'https://github.com/absmach/supermq/blob/main/api/asyncapi/websocket.yaml'
|
||||
info:
|
||||
title: Magistrala WebSocket adapter
|
||||
title: SuperMQ 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'
|
||||
name: SuperMQ Team
|
||||
url: 'https://github.com/absmach/supermq'
|
||||
email: info@abstractmachines.fr
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: 'https://github.com/absmach/magistrala/blob/main/LICENSE'
|
||||
url: 'https://github.com/absmach/supermq/blob/main/LICENSE'
|
||||
tags:
|
||||
- name: WebSocket
|
||||
defaultContentType: application/json
|
||||
@@ -28,14 +28,18 @@ servers:
|
||||
description: Hostname of the WebSocket adapter
|
||||
default: localhost
|
||||
port:
|
||||
description: Magistrala WebSocket Adapter port
|
||||
description: SuperMQ WebSocket Adapter port
|
||||
default: '8186'
|
||||
|
||||
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:
|
||||
@@ -70,7 +74,7 @@ channels:
|
||||
- bearerAuth: []
|
||||
/version:
|
||||
subscribe:
|
||||
summary: Get the version of the Magistrala adapter
|
||||
summary: Get the version of the SuperMQ adapter
|
||||
operationId: getVersion
|
||||
bindings:
|
||||
http:
|
||||
@@ -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 @@
|
||||
# SuperMQ OpenAPI Specification
|
||||
|
||||
This folder contains an OpenAPI specifications for SuperMQ API.
|
||||
|
||||
View specification in Swagger UI at [docs.api.supermq.abstractmachines.fr](https://docs.api.supermq.abstractmachines.fr)
|
||||
@@ -0,0 +1,840 @@
|
||||
# Copyright (c) Abstract Machines
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: SuperMQ 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 SuperMQ repository](https://github.com/absmach/supermq)
|
||||
contact:
|
||||
email: info@abstractmachines.fr
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: https://github.com/absmach/supermq/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://docs.supermq.abstractmachines.fr/
|
||||
- name: PATs
|
||||
description: Everything about your Personal Access Tokens.
|
||||
externalDocs:
|
||||
description: Find out more about Personal Access Tokens
|
||||
url: https://docs.supermq.abstractmachines.fr/
|
||||
- name: Health
|
||||
description: Service health check endpoint.
|
||||
externalDocs:
|
||||
description: Find out more about health check
|
||||
url: https://docs.supermq.abstractmachines.fr/
|
||||
|
||||
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.
|
||||
"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.
|
||||
"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:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
example: "c5747f2f-2a7c-4fe1-b41a-51a5ae290945"
|
||||
description: Scope unique identifier
|
||||
pat_id:
|
||||
type: string
|
||||
format: uuid
|
||||
example: "9118de62-c680-46b7-ad0a-21748a52833a"
|
||||
description: PAT ID this scope belongs to
|
||||
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
|
||||
properties:
|
||||
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
|
||||
duration:
|
||||
type: string
|
||||
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
|
||||
properties:
|
||||
duration:
|
||||
type: string
|
||||
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
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
@@ -3,17 +3,17 @@
|
||||
|
||||
openapi: 3.0.1
|
||||
info:
|
||||
title: Magistrala http adapter
|
||||
title: SuperMQ http adapter
|
||||
description: |
|
||||
HTTP API for sending messages through communication channels.
|
||||
Some useful links:
|
||||
- [The Magistrala repository](https://github.com/absmach/magistrala)
|
||||
- [The SuperMQ repository](https://github.com/absmach/supermq)
|
||||
contact:
|
||||
email: info@abstractmachines.fr
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: https://github.com/absmach/magistrala/blob/main/LICENSE
|
||||
version: 0.14.0
|
||||
url: https://github.com/absmach/supermq/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://docs.supermq.abstractmachines.fr/
|
||||
|
||||
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:
|
||||
@@ -129,13 +130,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:
|
||||
@@ -161,7 +170,7 @@ components:
|
||||
content:
|
||||
application/health+json:
|
||||
schema:
|
||||
$ref: "./schemas/HealthInfo.yml"
|
||||
$ref: "./schemas/health_info.yaml"
|
||||
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
@@ -169,13 +178,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: []
|
||||
@@ -3,17 +3,17 @@
|
||||
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: Magistrala Journal Log Service
|
||||
title: SuperMQ Journal Log Service
|
||||
description: |
|
||||
This is the Journal Log Server based on the OpenAPI 3.0 specification. It is the HTTP API for viewing journal log history. 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)
|
||||
- [The SuperMQ repository](https://github.com/absmach/supermq)
|
||||
contact:
|
||||
email: info@mainflux.com
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: https://github.com/absmach/magistrala/blob/master/LICENSE
|
||||
version: 0.14.0
|
||||
url: https://github.com/absmach/supermq/blob/main/LICENSE
|
||||
version: 0.18.0
|
||||
|
||||
servers:
|
||||
- url: http://localhost:9021
|
||||
@@ -65,6 +65,39 @@ paths:
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
/{domainID}/journal/client/{clientID}/telemetry:
|
||||
get:
|
||||
tags:
|
||||
- journal-log
|
||||
summary: View client telemetry
|
||||
description: |
|
||||
Retrieves telemetry data for a specific client within a domain.
|
||||
This includes connection status, messages sent/received, and other metrics.
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/domain_id"
|
||||
- $ref: '#/components/parameters/client_id'
|
||||
security:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
"200":
|
||||
description: Client telemetry data retrieved successfully
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Telemetry"
|
||||
"400":
|
||||
description: Failed due to malformed request parameters.
|
||||
"401":
|
||||
description: Missing or invalid access token provided.
|
||||
"403":
|
||||
description: Failed to perform authorization over the entity.
|
||||
"404":
|
||||
description: Client not found.
|
||||
"422":
|
||||
description: Database can't process request.
|
||||
"500":
|
||||
$ref: "#/components/responses/ServiceError"
|
||||
|
||||
/{domainID}/journal/{entityType}/{id}:
|
||||
get:
|
||||
tags:
|
||||
@@ -119,6 +152,45 @@ paths:
|
||||
|
||||
components:
|
||||
schemas:
|
||||
Telemetry:
|
||||
type: object
|
||||
properties:
|
||||
client_id:
|
||||
type: string
|
||||
format: uuid
|
||||
description: Unique identifier of the client
|
||||
example: "bb7edb32-2eac-4aad-aebe-ed96fe073879"
|
||||
domain_id:
|
||||
type: string
|
||||
format: uuid
|
||||
description: Unique identifier of the domain
|
||||
example: "29d425c8-542b-4614-8a4d-a5951945d720"
|
||||
subscriptions:
|
||||
type: integer
|
||||
format: int64
|
||||
description: Number of active subscriptions for the client
|
||||
example: 5
|
||||
inbound_messages:
|
||||
type: integer
|
||||
format: int64
|
||||
description: Number of messages received by the client
|
||||
example: 1234567
|
||||
outbound_messages:
|
||||
type: integer
|
||||
format: int64
|
||||
description: Number of messages sent by the client
|
||||
example: 987654
|
||||
first_seen:
|
||||
type: string
|
||||
format: date-time
|
||||
description: Timestamp when the client was first seen
|
||||
example: "2024-01-11T10:00:00.000Z"
|
||||
last_seen:
|
||||
type: string
|
||||
format: date-time
|
||||
description: Timestamp when the client was last seen
|
||||
example: "2024-01-11T12:05:07.449053Z"
|
||||
|
||||
Journal:
|
||||
type: object
|
||||
properties:
|
||||
@@ -195,15 +267,25 @@ components:
|
||||
required: true
|
||||
example: bb7edb32-2eac-4aad-aebe-ed96fe073879
|
||||
|
||||
client_id:
|
||||
name: clientID
|
||||
description: Unique identifier for a client
|
||||
in: path
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
required: true
|
||||
example: bb7edb32-2eac-4aad-aebe-ed96fe073879
|
||||
|
||||
entity_type:
|
||||
name: entityType
|
||||
description: Type of entity, e.g. user, group, thing, etc.entityType
|
||||
description: Type of entity, e.g. group, client, channel.
|
||||
in: path
|
||||
schema:
|
||||
type: string
|
||||
enum:
|
||||
- group
|
||||
- thing
|
||||
- client
|
||||
- channel
|
||||
required: true
|
||||
example: group
|
||||
@@ -220,7 +302,7 @@ components:
|
||||
|
||||
id:
|
||||
name: id
|
||||
description: Unique identifier for an entity, e.g. group, channel or thing. Used together with entity_type.
|
||||
description: Unique identifier for an entity, e.g. group, channel or client. Used together with entity_type.
|
||||
in: path
|
||||
schema:
|
||||
type: string
|
||||
@@ -323,7 +405,7 @@ components:
|
||||
content:
|
||||
application/health+json:
|
||||
schema:
|
||||
$ref: "./schemas/HealthInfo.yml"
|
||||
$ref: "./schemas/health_info.yaml"
|
||||
|
||||
ServiceError:
|
||||
description: Unexpected server-side error occurred.
|
||||
@@ -11,7 +11,7 @@ properties:
|
||||
version:
|
||||
type: string
|
||||
description: Service version.
|
||||
example: v0.14.0
|
||||
example: v0.18.0
|
||||
commit:
|
||||
type: string
|
||||
description: Service commit hash.
|
||||
@@ -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'
|
||||
@@ -3,17 +3,17 @@
|
||||
|
||||
openapi: 3.0.1
|
||||
info:
|
||||
title: Magistrala twins service
|
||||
title: SuperMQ twins service
|
||||
description: |
|
||||
HTTP API for managing digital twins and their states.
|
||||
Some useful links:
|
||||
- [The Magistrala repository](https://github.com/absmach/magistrala)
|
||||
- [The SuperMQ repository](https://github.com/absmach/supermq)
|
||||
contact:
|
||||
email: info@abstractmachines.fr
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: https://github.com/absmach/magistrala/blob/main/LICENSE
|
||||
version: 0.14.0
|
||||
url: https://github.com/absmach/supermq/blob/main/LICENSE
|
||||
version: 0.18.0
|
||||
|
||||
servers:
|
||||
- url: http://localhost:9018
|
||||
@@ -24,7 +24,7 @@ tags:
|
||||
description: Everything about your Twins
|
||||
externalDocs:
|
||||
description: Find out more about twins
|
||||
url: https://docs.magistrala.abstractmachines.fr/
|
||||
url: https://docs.supermq.abstractmachines.fr/
|
||||
|
||||
paths:
|
||||
/twins:
|
||||
@@ -244,7 +244,7 @@ components:
|
||||
description: Name of the attribute.
|
||||
channel:
|
||||
type: string
|
||||
description: Magistrala channel used by attribute.
|
||||
description: SuperMQ channel used by attribute.
|
||||
subtopic:
|
||||
type: string
|
||||
description: Subtopic used by attribute.
|
||||
@@ -278,7 +278,7 @@ components:
|
||||
properties:
|
||||
owner:
|
||||
type: string
|
||||
description: Email address of Magistrala user that owns twin.
|
||||
description: Email address of SuperMQ user that owns twin.
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
@@ -417,7 +417,7 @@ components:
|
||||
content:
|
||||
application/health+json:
|
||||
schema:
|
||||
$ref: "./schemas/HealthInfo.yml"
|
||||
$ref: "./schemas/health_info.yaml"
|
||||
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
File diff suppressed because it is too large
Load Diff
-993
@@ -1,993 +0,0 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.34.2
|
||||
// protoc v5.27.1
|
||||
// source: auth.proto
|
||||
|
||||
package magistrala
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
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)
|
||||
)
|
||||
|
||||
// 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
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
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"`
|
||||
}
|
||||
|
||||
func (x *Token) Reset() {
|
||||
*x = Token{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_auth_proto_msgTypes[0]
|
||||
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_auth_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && 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_auth_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
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 AuthNReq struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"`
|
||||
}
|
||||
|
||||
func (x *AuthNReq) Reset() {
|
||||
*x = AuthNReq{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_auth_proto_msgTypes[1]
|
||||
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_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && 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_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *AuthNReq) GetToken() string {
|
||||
if x != nil {
|
||||
return x.Token
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type AuthNRes struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // change "id" to "subject", sub in jwt = user + domain id
|
||||
UserId string `protobuf:"bytes,2,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` // user id
|
||||
DomainId string `protobuf:"bytes,3,opt,name=domain_id,json=domainId,proto3" json:"domain_id,omitempty"` // domain id
|
||||
}
|
||||
|
||||
func (x *AuthNRes) Reset() {
|
||||
*x = AuthNRes{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_auth_proto_msgTypes[2]
|
||||
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_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && 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_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
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) GetDomainId() string {
|
||||
if x != nil {
|
||||
return x.DomainId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type IssueReq struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
|
||||
Type uint32 `protobuf:"varint,2,opt,name=type,proto3" json:"type,omitempty"`
|
||||
}
|
||||
|
||||
func (x *IssueReq) Reset() {
|
||||
*x = IssueReq{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_auth_proto_msgTypes[3]
|
||||
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_auth_proto_msgTypes[3]
|
||||
if protoimpl.UnsafeEnabled && 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_auth_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *IssueReq) GetUserId() string {
|
||||
if x != nil {
|
||||
return x.UserId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *IssueReq) GetType() uint32 {
|
||||
if x != nil {
|
||||
return x.Type
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type RefreshReq struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
RefreshToken string `protobuf:"bytes,1,opt,name=refresh_token,json=refreshToken,proto3" json:"refresh_token,omitempty"`
|
||||
}
|
||||
|
||||
func (x *RefreshReq) Reset() {
|
||||
*x = RefreshReq{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_auth_proto_msgTypes[4]
|
||||
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_auth_proto_msgTypes[4]
|
||||
if protoimpl.UnsafeEnabled && 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_auth_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *RefreshReq) GetRefreshToken() string {
|
||||
if x != nil {
|
||||
return x.RefreshToken
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type AuthZReq struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Domain string `protobuf:"bytes,1,opt,name=domain,proto3" json:"domain,omitempty"` // Domain
|
||||
SubjectType string `protobuf:"bytes,2,opt,name=subject_type,json=subjectType,proto3" json:"subject_type,omitempty"` // Thing or User
|
||||
SubjectKind string `protobuf:"bytes,3,opt,name=subject_kind,json=subjectKind,proto3" json:"subject_kind,omitempty"` // ID or Token
|
||||
SubjectRelation string `protobuf:"bytes,4,opt,name=subject_relation,json=subjectRelation,proto3" json:"subject_relation,omitempty"` // Subject relation
|
||||
Subject string `protobuf:"bytes,5,opt,name=subject,proto3" json:"subject,omitempty"` // Subject value (id or token, depending on kind)
|
||||
Relation string `protobuf:"bytes,6,opt,name=relation,proto3" json:"relation,omitempty"` // Relation to filter
|
||||
Permission string `protobuf:"bytes,7,opt,name=permission,proto3" json:"permission,omitempty"` // Action
|
||||
Object string `protobuf:"bytes,8,opt,name=object,proto3" json:"object,omitempty"` // Object ID
|
||||
ObjectType string `protobuf:"bytes,9,opt,name=object_type,json=objectType,proto3" json:"object_type,omitempty"` // Thing, User, Group
|
||||
}
|
||||
|
||||
func (x *AuthZReq) Reset() {
|
||||
*x = AuthZReq{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_auth_proto_msgTypes[5]
|
||||
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_proto_msgTypes[5]
|
||||
if protoimpl.UnsafeEnabled && 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_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
func (x *AuthZReq) GetDomain() string {
|
||||
if x != nil {
|
||||
return x.Domain
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AuthZReq) GetSubjectType() string {
|
||||
if x != nil {
|
||||
return x.SubjectType
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AuthZReq) GetSubjectKind() string {
|
||||
if x != nil {
|
||||
return x.SubjectKind
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AuthZReq) GetSubjectRelation() string {
|
||||
if x != nil {
|
||||
return x.SubjectRelation
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AuthZReq) GetSubject() string {
|
||||
if x != nil {
|
||||
return x.Subject
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AuthZReq) GetRelation() string {
|
||||
if x != nil {
|
||||
return x.Relation
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AuthZReq) GetPermission() string {
|
||||
if x != nil {
|
||||
return x.Permission
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AuthZReq) GetObject() string {
|
||||
if x != nil {
|
||||
return x.Object
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AuthZReq) GetObjectType() string {
|
||||
if x != nil {
|
||||
return x.ObjectType
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type AuthZRes struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Authorized bool `protobuf:"varint,1,opt,name=authorized,proto3" json:"authorized,omitempty"`
|
||||
Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"`
|
||||
}
|
||||
|
||||
func (x *AuthZRes) Reset() {
|
||||
*x = AuthZRes{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_auth_proto_msgTypes[6]
|
||||
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_proto_msgTypes[6]
|
||||
if protoimpl.UnsafeEnabled && 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_proto_rawDescGZIP(), []int{6}
|
||||
}
|
||||
|
||||
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 ""
|
||||
}
|
||||
|
||||
type DeleteUserRes struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Deleted bool `protobuf:"varint,1,opt,name=deleted,proto3" json:"deleted,omitempty"`
|
||||
}
|
||||
|
||||
func (x *DeleteUserRes) Reset() {
|
||||
*x = DeleteUserRes{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_auth_proto_msgTypes[7]
|
||||
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_auth_proto_msgTypes[7]
|
||||
if protoimpl.UnsafeEnabled && 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_auth_proto_rawDescGZIP(), []int{7}
|
||||
}
|
||||
|
||||
func (x *DeleteUserRes) GetDeleted() bool {
|
||||
if x != nil {
|
||||
return x.Deleted
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type DeleteUserReq struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
}
|
||||
|
||||
func (x *DeleteUserReq) Reset() {
|
||||
*x = DeleteUserReq{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_auth_proto_msgTypes[8]
|
||||
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_auth_proto_msgTypes[8]
|
||||
if protoimpl.UnsafeEnabled && 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_auth_proto_rawDescGZIP(), []int{8}
|
||||
}
|
||||
|
||||
func (x *DeleteUserReq) GetId() string {
|
||||
if x != nil {
|
||||
return x.Id
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type ThingsAuthzReq struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
ChannelId string `protobuf:"bytes,1,opt,name=channel_id,json=channelId,proto3" json:"channel_id,omitempty"`
|
||||
ThingId string `protobuf:"bytes,2,opt,name=thing_id,json=thingId,proto3" json:"thing_id,omitempty"`
|
||||
ThingKey string `protobuf:"bytes,3,opt,name=thing_key,json=thingKey,proto3" json:"thing_key,omitempty"`
|
||||
Permission string `protobuf:"bytes,4,opt,name=permission,proto3" json:"permission,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ThingsAuthzReq) Reset() {
|
||||
*x = ThingsAuthzReq{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_auth_proto_msgTypes[9]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ThingsAuthzReq) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ThingsAuthzReq) ProtoMessage() {}
|
||||
|
||||
func (x *ThingsAuthzReq) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_auth_proto_msgTypes[9]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ThingsAuthzReq.ProtoReflect.Descriptor instead.
|
||||
func (*ThingsAuthzReq) Descriptor() ([]byte, []int) {
|
||||
return file_auth_proto_rawDescGZIP(), []int{9}
|
||||
}
|
||||
|
||||
func (x *ThingsAuthzReq) GetChannelId() string {
|
||||
if x != nil {
|
||||
return x.ChannelId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ThingsAuthzReq) GetThingId() string {
|
||||
if x != nil {
|
||||
return x.ThingId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ThingsAuthzReq) GetThingKey() string {
|
||||
if x != nil {
|
||||
return x.ThingKey
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ThingsAuthzReq) GetPermission() string {
|
||||
if x != nil {
|
||||
return x.Permission
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type ThingsAuthzRes struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Authorized bool `protobuf:"varint,1,opt,name=authorized,proto3" json:"authorized,omitempty"`
|
||||
Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ThingsAuthzRes) Reset() {
|
||||
*x = ThingsAuthzRes{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_auth_proto_msgTypes[10]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ThingsAuthzRes) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ThingsAuthzRes) ProtoMessage() {}
|
||||
|
||||
func (x *ThingsAuthzRes) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_auth_proto_msgTypes[10]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ThingsAuthzRes.ProtoReflect.Descriptor instead.
|
||||
func (*ThingsAuthzRes) Descriptor() ([]byte, []int) {
|
||||
return file_auth_proto_rawDescGZIP(), []int{10}
|
||||
}
|
||||
|
||||
func (x *ThingsAuthzRes) GetAuthorized() bool {
|
||||
if x != nil {
|
||||
return x.Authorized
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *ThingsAuthzRes) GetId() string {
|
||||
if x != nil {
|
||||
return x.Id
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var File_auth_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_auth_proto_rawDesc = []byte{
|
||||
0x0a, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0a, 0x6d, 0x61,
|
||||
0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x22, 0x87, 0x01, 0x0a, 0x05, 0x54, 0x6f, 0x6b,
|
||||
0x65, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b,
|
||||
0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73,
|
||||
0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x28, 0x0a, 0x0d, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68,
|
||||
0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0c,
|
||||
0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x88, 0x01, 0x01, 0x12,
|
||||
0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x79, 0x70, 0x65,
|
||||
0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x74, 0x6f, 0x6b,
|
||||
0x65, 0x6e, 0x22, 0x20, 0x0a, 0x08, 0x41, 0x75, 0x74, 0x68, 0x4e, 0x52, 0x65, 0x71, 0x12, 0x14,
|
||||
0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74,
|
||||
0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x50, 0x0a, 0x08, 0x41, 0x75, 0x74, 0x68, 0x4e, 0x52, 0x65, 0x73,
|
||||
0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64,
|
||||
0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x6f, 0x6d,
|
||||
0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x6f,
|
||||
0x6d, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x22, 0x37, 0x0a, 0x08, 0x49, 0x73, 0x73, 0x75, 0x65, 0x52,
|
||||
0x65, 0x71, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74,
|
||||
0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22,
|
||||
0x31, 0x0a, 0x0a, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x71, 0x12, 0x23, 0x0a,
|
||||
0x0d, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b,
|
||||
0x65, 0x6e, 0x22, 0xa2, 0x02, 0x0a, 0x08, 0x41, 0x75, 0x74, 0x68, 0x5a, 0x52, 0x65, 0x71, 0x12,
|
||||
0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x75, 0x62, 0x6a, 0x65,
|
||||
0x63, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73,
|
||||
0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x75,
|
||||
0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x0b, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x29, 0x0a,
|
||||
0x10, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74,
|
||||
0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a,
|
||||
0x65, 0x63, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65,
|
||||
0x63, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1e,
|
||||
0x0a, 0x0a, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x0a, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16,
|
||||
0x0a, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06,
|
||||
0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74,
|
||||
0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x62, 0x6a,
|
||||
0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x0a, 0x08, 0x41, 0x75, 0x74, 0x68, 0x5a,
|
||||
0x52, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65,
|
||||
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
|
||||
0x7a, 0x65, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x02, 0x69, 0x64, 0x22, 0x29, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65,
|
||||
0x72, 0x52, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x22, 0x1f,
|
||||
0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x12,
|
||||
0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22,
|
||||
0x87, 0x01, 0x0a, 0x0e, 0x54, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x41, 0x75, 0x74, 0x68, 0x7a, 0x52,
|
||||
0x65, 0x71, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x69, 0x64,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x49,
|
||||
0x64, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09,
|
||||
0x74, 0x68, 0x69, 0x6e, 0x67, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x08, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x4b, 0x65, 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x65, 0x72,
|
||||
0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70,
|
||||
0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x40, 0x0a, 0x0e, 0x54, 0x68, 0x69,
|
||||
0x6e, 0x67, 0x73, 0x41, 0x75, 0x74, 0x68, 0x7a, 0x52, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x61,
|
||||
0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52,
|
||||
0x0a, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69,
|
||||
0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x32, 0x56, 0x0a, 0x0d, 0x54,
|
||||
0x68, 0x69, 0x6e, 0x67, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x45, 0x0a, 0x09,
|
||||
0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x12, 0x1a, 0x2e, 0x6d, 0x61, 0x67, 0x69,
|
||||
0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, 0x54, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x41, 0x75, 0x74,
|
||||
0x68, 0x7a, 0x52, 0x65, 0x71, 0x1a, 0x1a, 0x2e, 0x6d, 0x61, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61,
|
||||
0x6c, 0x61, 0x2e, 0x54, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x41, 0x75, 0x74, 0x68, 0x7a, 0x52, 0x65,
|
||||
0x73, 0x22, 0x00, 0x32, 0x7a, 0x0a, 0x0c, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x53, 0x65, 0x72, 0x76,
|
||||
0x69, 0x63, 0x65, 0x12, 0x32, 0x0a, 0x05, 0x49, 0x73, 0x73, 0x75, 0x65, 0x12, 0x14, 0x2e, 0x6d,
|
||||
0x61, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, 0x49, 0x73, 0x73, 0x75, 0x65, 0x52,
|
||||
0x65, 0x71, 0x1a, 0x11, 0x2e, 0x6d, 0x61, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e,
|
||||
0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x07, 0x52, 0x65, 0x66, 0x72, 0x65,
|
||||
0x73, 0x68, 0x12, 0x16, 0x2e, 0x6d, 0x61, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e,
|
||||
0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x6d, 0x61, 0x67,
|
||||
0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x00, 0x32,
|
||||
0x86, 0x01, 0x0a, 0x0b, 0x41, 0x75, 0x74, 0x68, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12,
|
||||
0x39, 0x0a, 0x09, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x12, 0x14, 0x2e, 0x6d,
|
||||
0x61, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x5a, 0x52,
|
||||
0x65, 0x71, 0x1a, 0x14, 0x2e, 0x6d, 0x61, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e,
|
||||
0x41, 0x75, 0x74, 0x68, 0x5a, 0x52, 0x65, 0x73, 0x22, 0x00, 0x12, 0x3c, 0x0a, 0x0c, 0x41, 0x75,
|
||||
0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x14, 0x2e, 0x6d, 0x61, 0x67,
|
||||
0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x4e, 0x52, 0x65, 0x71,
|
||||
0x1a, 0x14, 0x2e, 0x6d, 0x61, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, 0x41, 0x75,
|
||||
0x74, 0x68, 0x4e, 0x52, 0x65, 0x73, 0x22, 0x00, 0x32, 0x61, 0x0a, 0x0e, 0x44, 0x6f, 0x6d, 0x61,
|
||||
0x69, 0x6e, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4f, 0x0a, 0x15, 0x44, 0x65,
|
||||
0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x44, 0x6f, 0x6d, 0x61,
|
||||
0x69, 0x6e, 0x73, 0x12, 0x19, 0x2e, 0x6d, 0x61, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61,
|
||||
0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x19,
|
||||
0x2e, 0x6d, 0x61, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x2e, 0x44, 0x65, 0x6c, 0x65,
|
||||
0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x22, 0x00, 0x42, 0x0e, 0x5a, 0x0c, 0x2e,
|
||||
0x2f, 0x6d, 0x61, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_auth_proto_rawDescOnce sync.Once
|
||||
file_auth_proto_rawDescData = file_auth_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_auth_proto_rawDescGZIP() []byte {
|
||||
file_auth_proto_rawDescOnce.Do(func() {
|
||||
file_auth_proto_rawDescData = protoimpl.X.CompressGZIP(file_auth_proto_rawDescData)
|
||||
})
|
||||
return file_auth_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_auth_proto_msgTypes = make([]protoimpl.MessageInfo, 11)
|
||||
var file_auth_proto_goTypes = []any{
|
||||
(*Token)(nil), // 0: magistrala.Token
|
||||
(*AuthNReq)(nil), // 1: magistrala.AuthNReq
|
||||
(*AuthNRes)(nil), // 2: magistrala.AuthNRes
|
||||
(*IssueReq)(nil), // 3: magistrala.IssueReq
|
||||
(*RefreshReq)(nil), // 4: magistrala.RefreshReq
|
||||
(*AuthZReq)(nil), // 5: magistrala.AuthZReq
|
||||
(*AuthZRes)(nil), // 6: magistrala.AuthZRes
|
||||
(*DeleteUserRes)(nil), // 7: magistrala.DeleteUserRes
|
||||
(*DeleteUserReq)(nil), // 8: magistrala.DeleteUserReq
|
||||
(*ThingsAuthzReq)(nil), // 9: magistrala.ThingsAuthzReq
|
||||
(*ThingsAuthzRes)(nil), // 10: magistrala.ThingsAuthzRes
|
||||
}
|
||||
var file_auth_proto_depIdxs = []int32{
|
||||
9, // 0: magistrala.ThingsService.Authorize:input_type -> magistrala.ThingsAuthzReq
|
||||
3, // 1: magistrala.TokenService.Issue:input_type -> magistrala.IssueReq
|
||||
4, // 2: magistrala.TokenService.Refresh:input_type -> magistrala.RefreshReq
|
||||
5, // 3: magistrala.AuthService.Authorize:input_type -> magistrala.AuthZReq
|
||||
1, // 4: magistrala.AuthService.Authenticate:input_type -> magistrala.AuthNReq
|
||||
8, // 5: magistrala.DomainsService.DeleteUserFromDomains:input_type -> magistrala.DeleteUserReq
|
||||
10, // 6: magistrala.ThingsService.Authorize:output_type -> magistrala.ThingsAuthzRes
|
||||
0, // 7: magistrala.TokenService.Issue:output_type -> magistrala.Token
|
||||
0, // 8: magistrala.TokenService.Refresh:output_type -> magistrala.Token
|
||||
6, // 9: magistrala.AuthService.Authorize:output_type -> magistrala.AuthZRes
|
||||
2, // 10: magistrala.AuthService.Authenticate:output_type -> magistrala.AuthNRes
|
||||
7, // 11: magistrala.DomainsService.DeleteUserFromDomains:output_type -> magistrala.DeleteUserRes
|
||||
6, // [6:12] is the sub-list for method output_type
|
||||
0, // [0:6] 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_auth_proto_init() }
|
||||
func file_auth_proto_init() {
|
||||
if File_auth_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_auth_proto_msgTypes[0].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*Token); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_auth_proto_msgTypes[1].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*AuthNReq); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_auth_proto_msgTypes[2].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*AuthNRes); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_auth_proto_msgTypes[3].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*IssueReq); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_auth_proto_msgTypes[4].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*RefreshReq); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_auth_proto_msgTypes[5].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*AuthZReq); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_auth_proto_msgTypes[6].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*AuthZRes); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_auth_proto_msgTypes[7].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*DeleteUserRes); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_auth_proto_msgTypes[8].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*DeleteUserReq); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_auth_proto_msgTypes[9].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*ThingsAuthzReq); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_auth_proto_msgTypes[10].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*ThingsAuthzRes); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
file_auth_proto_msgTypes[0].OneofWrappers = []any{}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_auth_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 11,
|
||||
NumExtensions: 0,
|
||||
NumServices: 4,
|
||||
},
|
||||
GoTypes: file_auth_proto_goTypes,
|
||||
DependencyIndexes: file_auth_proto_depIdxs,
|
||||
MessageInfos: file_auth_proto_msgTypes,
|
||||
}.Build()
|
||||
File_auth_proto = out.File
|
||||
file_auth_proto_rawDesc = nil
|
||||
file_auth_proto_goTypes = nil
|
||||
file_auth_proto_depIdxs = nil
|
||||
}
|
||||
-98
@@ -1,98 +0,0 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package magistrala;
|
||||
option go_package = "./magistrala";
|
||||
|
||||
// ThingsService is a service that provides things authorization functionalities
|
||||
// for magistrala services.
|
||||
service ThingsService {
|
||||
// Authorize checks if the thing is authorized to perform
|
||||
// the action on the channel.
|
||||
rpc Authorize(ThingsAuthzReq) returns (ThingsAuthzRes) {}
|
||||
}
|
||||
|
||||
service TokenService {
|
||||
rpc Issue(IssueReq) returns (Token) {}
|
||||
rpc Refresh(RefreshReq) returns (Token) {}
|
||||
}
|
||||
|
||||
// AuthService is a service that provides authentication and authorization
|
||||
// functionalities for magistrala services.
|
||||
service AuthService {
|
||||
rpc Authorize(AuthZReq) returns (AuthZRes) {}
|
||||
rpc Authenticate(AuthNReq) returns (AuthNRes) {}
|
||||
}
|
||||
|
||||
// DomainsService is a service that provides access to domains
|
||||
// functionalities for magistrala services.
|
||||
service DomainsService {
|
||||
rpc DeleteUserFromDomains(DeleteUserReq) returns (DeleteUserRes) {}
|
||||
}
|
||||
|
||||
// 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 access_token = 1;
|
||||
optional string refresh_token = 2;
|
||||
string access_type = 3;
|
||||
}
|
||||
|
||||
message AuthNReq {
|
||||
string token = 1;
|
||||
}
|
||||
|
||||
message AuthNRes {
|
||||
string id = 1; // change "id" to "subject", sub in jwt = user + domain id
|
||||
string user_id = 2; // user id
|
||||
string domain_id = 3; // domain id
|
||||
}
|
||||
|
||||
message IssueReq {
|
||||
string user_id = 1;
|
||||
uint32 type = 2;
|
||||
}
|
||||
|
||||
message RefreshReq {
|
||||
string refresh_token = 1;
|
||||
}
|
||||
|
||||
message AuthZReq {
|
||||
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 AuthZRes {
|
||||
bool authorized = 1;
|
||||
string id = 2;
|
||||
}
|
||||
|
||||
message DeleteUserRes {
|
||||
bool deleted = 1;
|
||||
}
|
||||
|
||||
message DeleteUserReq {
|
||||
string id = 1;
|
||||
}
|
||||
|
||||
message ThingsAuthzReq {
|
||||
string channel_id = 1;
|
||||
string thing_id = 2;
|
||||
string thing_key = 3;
|
||||
string permission = 4;
|
||||
}
|
||||
|
||||
message ThingsAuthzRes {
|
||||
bool authorized = 1;
|
||||
string id = 2;
|
||||
}
|
||||
+370
-80
@@ -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
|
||||
|
||||
@@ -8,7 +8,7 @@ User service is using Auth service gRPC API to obtain login token or password re
|
||||
|
||||
- ID - key ID
|
||||
- Type - one of the three types described below
|
||||
- IssuerID - an ID of the Magistrala User who issued the key
|
||||
- IssuerID - an ID of the SuperMQ User who issued the key
|
||||
- Subject - user ID for which the key is issued
|
||||
- IssuedAt - the timestamp when the key is issued
|
||||
- ExpiresAt - the timestamp after which the key is invalid
|
||||
@@ -25,11 +25,11 @@ 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.
|
||||
|
||||
For in-depth explanation of the aforementioned scenarios, as well as thorough understanding of Magistrala, please check out the [official documentation][doc].
|
||||
For in-depth explanation of the aforementioned scenarios, as well as thorough understanding of SuperMQ, please check out the [official documentation][doc].
|
||||
|
||||
The following actions are supported:
|
||||
|
||||
@@ -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,53 +59,63 @@ 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:4318/v1/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 |
|
||||
| ----------------------------------- | ------------------------------------------------------------------------------------ | ------------------------------ |
|
||||
| SMQ_AUTH_LOG_LEVEL | Log level for the Auth service (debug, info, warn, error) | info |
|
||||
| SMQ_AUTH_DB_HOST | Database host address | localhost |
|
||||
| SMQ_AUTH_DB_PORT | Database host port | 5432 |
|
||||
| SMQ_AUTH_DB_USER | Database user | supermq |
|
||||
| SMQ_AUTH_DB_PASSWORD | Database password | supermq |
|
||||
| SMQ_AUTH_DB_NAME | Name of the database used by the service | auth |
|
||||
| SMQ_AUTH_DB_SSL_MODE | Database connection SSL mode (disable, require, verify-ca, verify-full) | disable |
|
||||
| SMQ_AUTH_DB_SSL_CERT | Path to the PEM encoded certificate file | "" |
|
||||
| SMQ_AUTH_DB_SSL_KEY | Path to the PEM encoded key file | "" |
|
||||
| SMQ_AUTH_DB_SSL_ROOT_CERT | Path to the PEM encoded root certificate file | "" |
|
||||
| SMQ_AUTH_HTTP_HOST | Auth service HTTP host | "" |
|
||||
| SMQ_AUTH_HTTP_PORT | Auth service HTTP port | 8189 |
|
||||
| SMQ_AUTH_HTTP_SERVER_CERT | Path to the PEM encoded HTTP server certificate file | "" |
|
||||
| SMQ_AUTH_HTTP_SERVER_KEY | Path to the PEM encoded HTTP server key file | "" |
|
||||
| SMQ_AUTH_GRPC_HOST | Auth service gRPC host | "" |
|
||||
| SMQ_AUTH_GRPC_PORT | Auth service gRPC port | 8181 |
|
||||
| SMQ_AUTH_GRPC_SERVER_CERT | Path to the PEM encoded gRPC server certificate file | "" |
|
||||
| SMQ_AUTH_GRPC_SERVER_KEY | Path to the PEM encoded gRPC server key file | "" |
|
||||
| SMQ_AUTH_GRPC_SERVER_CA_CERTS | Path to the PEM encoded gRPC server CA certificate file | "" |
|
||||
| SMQ_AUTH_GRPC_CLIENT_CA_CERTS | Path to the PEM encoded gRPC client CA certificate file | "" |
|
||||
| SMQ_AUTH_SECRET_KEY | String used for signing tokens | secret |
|
||||
| SMQ_AUTH_ACCESS_TOKEN_DURATION | The access token expiration period | 1h |
|
||||
| SMQ_AUTH_REFRESH_TOKEN_DURATION | The refresh token expiration period | 24h |
|
||||
| SMQ_AUTH_INVITATION_DURATION | The invitation token expiration period | 168h |
|
||||
| SMQ_AUTH_CACHE_URL | Redis URL for caching PAT scopes | redis://localhost:6379/0 |
|
||||
| SMQ_AUTH_CACHE_KEY_DURATION | Duration for which PAT scope cache keys are valid | 10m |
|
||||
| SMQ_SPICEDB_HOST | SpiceDB host address | localhost |
|
||||
| SMQ_SPICEDB_PORT | SpiceDB host port | 50051 |
|
||||
| SMQ_SPICEDB_PRE_SHARED_KEY | SpiceDB pre-shared key | 12345678 |
|
||||
| SMQ_SPICEDB_SCHEMA_FILE | Path to SpiceDB schema file | ./docker/spicedb/schema.zed |
|
||||
| SMQ_JAEGER_URL | Jaeger server URL | <http://jaeger:4318/v1/traces> |
|
||||
| SMQ_JAEGER_TRACE_RATIO | Jaeger sampling ratio | 1.0 |
|
||||
| SMQ_SEND_TELEMETRY | Send telemetry to supermq call home server | true |
|
||||
| SMQ_ADAPTER_INSTANCE_ID | Adapter instance ID | "" |
|
||||
| SMQ_CALLOUT_URLS | Comma-separated list of callout URLs | "" |
|
||||
| SMQ_CALLOUT_METHOD | Callout method | POST |
|
||||
| SMQ_CALLOUT_TLS_VERIFICATION | Enable TLS verification for callouts | true |
|
||||
| SMQ_CALLOUT_TIMEOUT | Callout timeout | 10s |
|
||||
| SMQ_CALLOUT_CA_CERT | Path to CA certificate file | "" |
|
||||
| SMQ_CALLOUT_CERT | Path to client certificate file | "" |
|
||||
| SMQ_CALLOUT_KEY | Path to client key file | "" |
|
||||
| SMQ_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/main/docker/docker-compose.yml) service section in docker-compose file to see how service is deployed.
|
||||
The service itself is distributed as Docker container. Check the [`auth`](https://github.com/absmach/supermq/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:
|
||||
|
||||
```bash
|
||||
# download the latest version of the service
|
||||
git clone https://github.com/absmach/magistrala
|
||||
git clone https://github.com/absmach/supermq
|
||||
|
||||
cd magistrala
|
||||
cd supermq
|
||||
|
||||
# compile the service
|
||||
make auth
|
||||
@@ -114,46 +124,326 @@ make auth
|
||||
make install
|
||||
|
||||
# set the environment variables and run the service
|
||||
MG_AUTH_LOG_LEVEL=info \
|
||||
MG_AUTH_DB_HOST=localhost \
|
||||
MG_AUTH_DB_PORT=5432 \
|
||||
MG_AUTH_DB_USER=magistrala \
|
||||
MG_AUTH_DB_PASSWORD=magistrala \
|
||||
MG_AUTH_DB_NAME=auth \
|
||||
MG_AUTH_DB_SSL_MODE=disable \
|
||||
MG_AUTH_DB_SSL_CERT="" \
|
||||
MG_AUTH_DB_SSL_KEY="" \
|
||||
MG_AUTH_DB_SSL_ROOT_CERT="" \
|
||||
MG_AUTH_HTTP_HOST=localhost \
|
||||
MG_AUTH_HTTP_PORT=8189 \
|
||||
MG_AUTH_HTTP_SERVER_CERT="" \
|
||||
MG_AUTH_HTTP_SERVER_KEY="" \
|
||||
MG_AUTH_GRPC_HOST=localhost \
|
||||
MG_AUTH_GRPC_PORT=8181 \
|
||||
MG_AUTH_GRPC_SERVER_CERT="" \
|
||||
MG_AUTH_GRPC_SERVER_KEY="" \
|
||||
MG_AUTH_GRPC_SERVER_CA_CERTS="" \
|
||||
MG_AUTH_GRPC_CLIENT_CA_CERTS="" \
|
||||
MG_AUTH_SECRET_KEY=secret \
|
||||
MG_AUTH_ACCESS_TOKEN_DURATION=1h \
|
||||
MG_AUTH_REFRESH_TOKEN_DURATION=24h \
|
||||
MG_AUTH_INVITATION_DURATION=168h \
|
||||
MG_SPICEDB_HOST=localhost \
|
||||
MG_SPICEDB_PORT=50051 \
|
||||
MG_SPICEDB_PRE_SHARED_KEY=12345678 \
|
||||
MG_SPICEDB_SCHEMA_FILE=./docker/spicedb/schema.zed \
|
||||
MG_JAEGER_URL=http://localhost:14268/api/traces \
|
||||
MG_JAEGER_TRACE_RATIO=1.0 \
|
||||
MG_SEND_TELEMETRY=true \
|
||||
MG_AUTH_ADAPTER_INSTANCE_ID="" \
|
||||
$GOBIN/magistrala-auth
|
||||
SMQ_AUTH_LOG_LEVEL=info \
|
||||
SMQ_AUTH_DB_HOST=localhost \
|
||||
SMQ_AUTH_DB_PORT=5432 \
|
||||
SMQ_AUTH_DB_USER=supermq \
|
||||
SMQ_AUTH_DB_PASSWORD=supermq \
|
||||
SMQ_AUTH_DB_NAME=auth \
|
||||
SMQ_AUTH_DB_SSL_MODE=disable \
|
||||
SMQ_AUTH_DB_SSL_CERT="" \
|
||||
SMQ_AUTH_DB_SSL_KEY="" \
|
||||
SMQ_AUTH_DB_SSL_ROOT_CERT="" \
|
||||
SMQ_AUTH_HTTP_HOST=localhost \
|
||||
SMQ_AUTH_HTTP_PORT=8189 \
|
||||
SMQ_AUTH_HTTP_SERVER_CERT="" \
|
||||
SMQ_AUTH_HTTP_SERVER_KEY="" \
|
||||
SMQ_AUTH_GRPC_HOST=localhost \
|
||||
SMQ_AUTH_GRPC_PORT=8181 \
|
||||
SMQ_AUTH_GRPC_SERVER_CERT="" \
|
||||
SMQ_AUTH_GRPC_SERVER_KEY="" \
|
||||
SMQ_AUTH_GRPC_SERVER_CA_CERTS="" \
|
||||
SMQ_AUTH_GRPC_CLIENT_CA_CERTS="" \
|
||||
SMQ_AUTH_SECRET_KEY=secret \
|
||||
SMQ_AUTH_ACCESS_TOKEN_DURATION=1h \
|
||||
SMQ_AUTH_REFRESH_TOKEN_DURATION=24h \
|
||||
SMQ_AUTH_INVITATION_DURATION=168h \
|
||||
SMQ_SPICEDB_HOST=localhost \
|
||||
SMQ_SPICEDB_PORT=50051 \
|
||||
SMQ_SPICEDB_PRE_SHARED_KEY=12345678 \
|
||||
SMQ_SPICEDB_SCHEMA_FILE=./docker/spicedb/schema.zed \
|
||||
SMQ_JAEGER_URL=http://localhost:14268/api/traces \
|
||||
SMQ_JAEGER_TRACE_RATIO=1.0 \
|
||||
SMQ_SEND_TELEMETRY=true \
|
||||
SMQ_AUTH_ADAPTER_INSTANCE_ID="" \
|
||||
SMQ_CALLOUT_URLS="" \
|
||||
SMQ_CALLOUT_METHOD="POST" \
|
||||
SMQ_CALLOUT_TLS_VERIFICATION=true \
|
||||
$GOBIN/supermq-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.
|
||||
Setting `SMQ_AUTH_HTTP_SERVER_CERT` and `SMQ_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 `SMQ_AUTH_GRPC_SERVER_CERT` and `SMQ_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 `SMQ_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 `SMQ_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 SuperMQ APIs without using your primary credentials. They are particularly useful for automation, CI/CD pipelines, and integrating with third-party services.
|
||||
|
||||
### Overview
|
||||
|
||||
PATs in SuperMQ 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:
|
||||
|
||||
```
|
||||
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
|
||||
|
||||
SuperMQ 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:
|
||||
|
||||
```
|
||||
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://docs.api.magistrala.abstractmachines.fr/?urls.primaryName=auth.yml).
|
||||
For more information about service capabilities and its usage, please check out the [API documentation](https://docs.api.supermq.abstractmachines.fr/?urls.primaryName=auth.yaml).
|
||||
|
||||
[doc]: https://docs.magistrala.abstractmachines.fr
|
||||
[doc]: https://docs.supermq.abstractmachines.fr
|
||||
|
||||
@@ -7,25 +7,28 @@ import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/absmach/magistrala"
|
||||
grpcapi "github.com/absmach/magistrala/auth/api/grpc"
|
||||
grpcAuthV1 "github.com/absmach/supermq/api/grpc/auth/v1"
|
||||
"github.com/absmach/supermq/auth"
|
||||
grpcapi "github.com/absmach/supermq/auth/api/grpc"
|
||||
"github.com/go-kit/kit/endpoint"
|
||||
kitgrpc "github.com/go-kit/kit/transport/grpc"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
const authSvcName = "magistrala.AuthService"
|
||||
const authSvcName = "auth.v1.AuthService"
|
||||
|
||||
type authGrpcClient struct {
|
||||
authenticate endpoint.Endpoint
|
||||
authorize endpoint.Endpoint
|
||||
timeout time.Duration
|
||||
authenticate endpoint.Endpoint
|
||||
authenticatePAT endpoint.Endpoint
|
||||
authorize endpoint.Endpoint
|
||||
authorizePAT endpoint.Endpoint
|
||||
timeout time.Duration
|
||||
}
|
||||
|
||||
var _ magistrala.AuthServiceClient = (*authGrpcClient)(nil)
|
||||
var _ grpcAuthV1.AuthServiceClient = (*authGrpcClient)(nil)
|
||||
|
||||
// NewAuthClient returns new auth gRPC client instance.
|
||||
func NewAuthClient(conn *grpc.ClientConn, timeout time.Duration) magistrala.AuthServiceClient {
|
||||
func NewAuthClient(conn *grpc.ClientConn, timeout time.Duration) grpcAuthV1.AuthServiceClient {
|
||||
return &authGrpcClient{
|
||||
authenticate: kitgrpc.NewClient(
|
||||
conn,
|
||||
@@ -33,7 +36,15 @@ func NewAuthClient(conn *grpc.ClientConn, timeout time.Duration) magistrala.Auth
|
||||
"Authenticate",
|
||||
encodeIdentifyRequest,
|
||||
decodeIdentifyResponse,
|
||||
magistrala.AuthNRes{},
|
||||
grpcAuthV1.AuthNRes{},
|
||||
).Endpoint(),
|
||||
authenticatePAT: kitgrpc.NewClient(
|
||||
conn,
|
||||
authSvcName,
|
||||
"AuthenticatePAT",
|
||||
encodeIdentifyRequest,
|
||||
decodeIdentifyPATResponse,
|
||||
grpcAuthV1.AuthNRes{},
|
||||
).Endpoint(),
|
||||
authorize: kitgrpc.NewClient(
|
||||
conn,
|
||||
@@ -41,35 +52,60 @@ func NewAuthClient(conn *grpc.ClientConn, timeout time.Duration) magistrala.Auth
|
||||
"Authorize",
|
||||
encodeAuthorizeRequest,
|
||||
decodeAuthorizeResponse,
|
||||
magistrala.AuthZRes{},
|
||||
grpcAuthV1.AuthZRes{},
|
||||
).Endpoint(),
|
||||
authorizePAT: kitgrpc.NewClient(
|
||||
conn,
|
||||
authSvcName,
|
||||
"AuthorizePAT",
|
||||
encodeAuthorizePATRequest,
|
||||
decodeAuthorizeResponse,
|
||||
grpcAuthV1.AuthZRes{},
|
||||
).Endpoint(),
|
||||
timeout: timeout,
|
||||
}
|
||||
}
|
||||
|
||||
func (client authGrpcClient) Authenticate(ctx context.Context, token *magistrala.AuthNReq, _ ...grpc.CallOption) (*magistrala.AuthNRes, error) {
|
||||
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 &magistrala.AuthNRes{}, grpcapi.DecodeError(err)
|
||||
return &grpcAuthV1.AuthNRes{}, grpcapi.DecodeError(err)
|
||||
}
|
||||
ir := res.(authenticateRes)
|
||||
return &magistrala.AuthNRes{Id: ir.id, UserId: ir.userID, DomainId: ir.domainID}, nil
|
||||
return &grpcAuthV1.AuthNRes{Id: ir.id, UserId: ir.userID, UserRole: uint32(ir.userRole), Verified: ir.verified}, nil
|
||||
}
|
||||
|
||||
func encodeIdentifyRequest(_ context.Context, grpcReq interface{}) (interface{}, error) {
|
||||
func encodeIdentifyRequest(_ context.Context, grpcReq any) (any, error) {
|
||||
req := grpcReq.(authenticateReq)
|
||||
return &magistrala.AuthNReq{Token: req.token}, nil
|
||||
return &grpcAuthV1.AuthNReq{Token: req.token}, nil
|
||||
}
|
||||
|
||||
func decodeIdentifyResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
res := grpcRes.(*magistrala.AuthNRes)
|
||||
return authenticateRes{id: res.GetId(), userID: res.GetUserId(), domainID: res.GetDomainId()}, 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()}, nil
|
||||
}
|
||||
|
||||
func (client authGrpcClient) Authorize(ctx context.Context, req *magistrala.AuthZReq, _ ...grpc.CallOption) (r *magistrala.AuthZRes, err error) {
|
||||
func (client authGrpcClient) AuthenticatePAT(ctx context.Context, token *grpcAuthV1.AuthNReq, _ ...grpc.CallOption) (*grpcAuthV1.AuthNRes, error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, client.timeout)
|
||||
defer cancel()
|
||||
|
||||
res, err := client.authenticatePAT(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)}, nil
|
||||
}
|
||||
|
||||
func decodeIdentifyPATResponse(_ context.Context, grpcRes any) (any, error) {
|
||||
res := grpcRes.(*grpcAuthV1.AuthNRes)
|
||||
return authenticateRes{id: res.GetId(), userID: res.GetUserId(), userRole: auth.Role(res.UserRole)}, 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()
|
||||
|
||||
@@ -84,21 +120,21 @@ func (client authGrpcClient) Authorize(ctx context.Context, req *magistrala.Auth
|
||||
Object: req.GetObject(),
|
||||
})
|
||||
if err != nil {
|
||||
return &magistrala.AuthZRes{}, grpcapi.DecodeError(err)
|
||||
return &grpcAuthV1.AuthZRes{}, grpcapi.DecodeError(err)
|
||||
}
|
||||
|
||||
ar := res.(authorizeRes)
|
||||
return &magistrala.AuthZRes{Authorized: ar.authorized, Id: ar.id}, nil
|
||||
return &grpcAuthV1.AuthZRes{Authorized: ar.authorized, Id: ar.id}, nil
|
||||
}
|
||||
|
||||
func decodeAuthorizeResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
res := grpcRes.(*magistrala.AuthZRes)
|
||||
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 interface{}) (interface{}, error) {
|
||||
func encodeAuthorizeRequest(_ context.Context, grpcReq any) (any, error) {
|
||||
req := grpcReq.(authReq)
|
||||
return &magistrala.AuthZReq{
|
||||
return &grpcAuthV1.AuthZReq{
|
||||
Domain: req.Domain,
|
||||
SubjectType: req.SubjectType,
|
||||
Subject: req.Subject,
|
||||
@@ -109,3 +145,35 @@ func encodeAuthorizeRequest(_ context.Context, grpcReq interface{}) (interface{}
|
||||
Object: req.Object,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (client authGrpcClient) AuthorizePAT(ctx context.Context, req *grpcAuthV1.AuthZPatReq, _ ...grpc.CallOption) (r *grpcAuthV1.AuthZRes, err error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, client.timeout)
|
||||
defer cancel()
|
||||
|
||||
res, err := client.authorizePAT(ctx, authPATReq{
|
||||
userID: req.GetUserId(),
|
||||
patID: req.GetPatId(),
|
||||
entityType: auth.EntityType(req.GetEntityType()),
|
||||
optionalDomainID: req.GetOptionalDomainId(),
|
||||
operation: auth.Operation(req.GetOperation()),
|
||||
entityID: req.GetEntityId(),
|
||||
})
|
||||
if err != nil {
|
||||
return &grpcAuthV1.AuthZRes{}, grpcapi.DecodeError(err)
|
||||
}
|
||||
|
||||
ar := res.(authorizeRes)
|
||||
return &grpcAuthV1.AuthZRes{Authorized: ar.authorized, Id: ar.id}, nil
|
||||
}
|
||||
|
||||
func encodeAuthorizePATRequest(_ context.Context, grpcReq any) (any, error) {
|
||||
req := grpcReq.(authPATReq)
|
||||
return &grpcAuthV1.AuthZPatReq{
|
||||
UserId: req.userID,
|
||||
PatId: req.patID,
|
||||
EntityType: uint32(req.entityType),
|
||||
OptionalDomainId: req.optionalDomainID,
|
||||
Operation: uint32(req.operation),
|
||||
EntityId: req.entityID,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -6,13 +6,13 @@ package auth
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/absmach/magistrala/auth"
|
||||
"github.com/absmach/magistrala/pkg/policies"
|
||||
"github.com/absmach/supermq/auth"
|
||||
"github.com/absmach/supermq/pkg/policies"
|
||||
"github.com/go-kit/kit/endpoint"
|
||||
)
|
||||
|
||||
func authenticateEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
return func(ctx context.Context, request any) (any, error) {
|
||||
req := request.(authenticateReq)
|
||||
if err := req.validate(); err != nil {
|
||||
return authenticateRes{}, err
|
||||
@@ -23,12 +23,28 @@ func authenticateEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
return authenticateRes{}, err
|
||||
}
|
||||
|
||||
return authenticateRes{id: key.Subject, userID: key.User, domainID: key.Domain}, nil
|
||||
return authenticateRes{userID: key.Subject, userRole: key.Role, verified: key.Verified}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func authenticatePATEndpoint(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
|
||||
}
|
||||
|
||||
pat, err := svc.IdentifyPAT(ctx, req.token)
|
||||
if err != nil {
|
||||
return authenticateRes{}, err
|
||||
}
|
||||
|
||||
return authenticateRes{id: pat.ID, userID: pat.User, userRole: pat.Role}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func authorizeEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
return func(ctx context.Context, request any) (any, error) {
|
||||
req := request.(authReq)
|
||||
|
||||
if err := req.validate(); err != nil {
|
||||
@@ -50,3 +66,18 @@ func authorizeEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
return authorizeRes{authorized: true}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func authorizePATEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request any) (any, error) {
|
||||
req := request.(authPATReq)
|
||||
|
||||
if err := req.validate(); err != nil {
|
||||
return authorizeRes{}, err
|
||||
}
|
||||
err := svc.AuthorizePAT(ctx, req.userID, req.patID, req.entityType, req.optionalDomainID, req.operation, req.entityID)
|
||||
if err != nil {
|
||||
return authorizeRes{authorized: false}, err
|
||||
}
|
||||
return authorizeRes{authorized: true}, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,13 +10,13 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/absmach/magistrala"
|
||||
"github.com/absmach/magistrala/auth"
|
||||
grpcapi "github.com/absmach/magistrala/auth/api/grpc/auth"
|
||||
"github.com/absmach/magistrala/internal/testsutil"
|
||||
"github.com/absmach/magistrala/pkg/apiutil"
|
||||
"github.com/absmach/magistrala/pkg/errors"
|
||||
svcerr "github.com/absmach/magistrala/pkg/errors/service"
|
||||
grpcAuthV1 "github.com/absmach/supermq/api/grpc/auth/v1"
|
||||
apiutil "github.com/absmach/supermq/api/http/util"
|
||||
"github.com/absmach/supermq/auth"
|
||||
grpcapi "github.com/absmach/supermq/auth/api/grpc/auth"
|
||||
"github.com/absmach/supermq/internal/testsutil"
|
||||
"github.com/absmach/supermq/pkg/errors"
|
||||
svcerr "github.com/absmach/supermq/pkg/errors/service"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"google.golang.org/grpc"
|
||||
@@ -28,11 +28,11 @@ const (
|
||||
secret = "secret"
|
||||
email = "test@example.com"
|
||||
id = "testID"
|
||||
thingsType = "things"
|
||||
clientsType = "clients"
|
||||
usersType = "users"
|
||||
description = "Description"
|
||||
groupName = "mgx"
|
||||
adminpermission = "admin"
|
||||
groupName = "smqx"
|
||||
adminPermission = "admin"
|
||||
|
||||
authoritiesObj = "authorities"
|
||||
memberRelation = "member"
|
||||
@@ -41,18 +41,21 @@ const (
|
||||
invalidDuration = 7 * 24 * time.Hour
|
||||
validToken = "valid"
|
||||
inValidToken = "invalid"
|
||||
validPATToken = "valid"
|
||||
inValidPATToken = "invalid"
|
||||
validPolicy = "valid"
|
||||
)
|
||||
|
||||
var (
|
||||
domainID = testsutil.GenerateUUID(&testing.T{})
|
||||
authAddr = fmt.Sprintf("localhost:%d", port)
|
||||
clientID = testsutil.GenerateUUID(&testing.T{})
|
||||
)
|
||||
|
||||
func startGRPCServer(svc auth.Service, port int) *grpc.Server {
|
||||
listener, _ := net.Listen("tcp", fmt.Sprintf(":%d", port))
|
||||
server := grpc.NewServer()
|
||||
magistrala.RegisterAuthServiceServer(server, grpcapi.NewAuthServer(svc))
|
||||
grpcAuthV1.RegisterAuthServiceServer(server, grpcapi.NewAuthServer(svc))
|
||||
go func() {
|
||||
err := server.Serve(listener)
|
||||
assert.Nil(&testing.T{}, err, fmt.Sprintf(`"Unexpected error creating auth server %s"`, err))
|
||||
@@ -64,147 +67,152 @@ func startGRPCServer(svc auth.Service, port int) *grpc.Server {
|
||||
func TestIdentify(t *testing.T) {
|
||||
conn, err := grpc.NewClient(authAddr, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
assert.Nil(t, err, fmt.Sprintf("Unexpected error creating client connection %s", err))
|
||||
defer conn.Close()
|
||||
grpcClient := grpcapi.NewAuthClient(conn, time.Second)
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
token string
|
||||
idt *magistrala.AuthNRes
|
||||
idt *grpcAuthV1.AuthNRes
|
||||
svcErr error
|
||||
err error
|
||||
}{
|
||||
{
|
||||
desc: "authenticate user with valid user token",
|
||||
token: validToken,
|
||||
idt: &magistrala.AuthNRes{Id: id, UserId: email, DomainId: domainID},
|
||||
idt: &grpcAuthV1.AuthNRes{UserId: id, UserRole: uint32(auth.UserRole)},
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
desc: "authenticate user with invalid user token",
|
||||
token: "invalid",
|
||||
idt: &magistrala.AuthNRes{},
|
||||
idt: &grpcAuthV1.AuthNRes{},
|
||||
svcErr: svcerr.ErrAuthentication,
|
||||
err: svcerr.ErrAuthentication,
|
||||
},
|
||||
{
|
||||
desc: "authenticate user with empty token",
|
||||
token: "",
|
||||
idt: &magistrala.AuthNRes{},
|
||||
idt: &grpcAuthV1.AuthNRes{},
|
||||
err: apiutil.ErrBearerToken,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
svcCall := svc.On("Identify", mock.Anything, mock.Anything, mock.Anything).Return(auth.Key{Subject: id, User: email, Domain: domainID}, tc.svcErr)
|
||||
idt, err := grpcClient.Authenticate(context.Background(), &magistrala.AuthNReq{Token: tc.token})
|
||||
if idt != nil {
|
||||
assert.Equal(t, tc.idt, idt, fmt.Sprintf("%s: expected %v got %v", tc.desc, tc.idt, idt))
|
||||
}
|
||||
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
|
||||
svcCall.Unset()
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
svcCall := svc.On("Identify", mock.Anything, mock.Anything).Return(auth.Key{Subject: id, Role: auth.UserRole}, tc.svcErr)
|
||||
idt, err := grpcClient.Authenticate(context.Background(), &grpcAuthV1.AuthNReq{Token: tc.token})
|
||||
if idt != nil {
|
||||
assert.Equal(t, tc.idt, idt, fmt.Sprintf("%s: expected %v got %v", tc.desc, tc.idt, idt))
|
||||
}
|
||||
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
|
||||
svcCall.Unset()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuthorize(t *testing.T) {
|
||||
conn, err := grpc.NewClient(authAddr, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
assert.Nil(t, err, fmt.Sprintf("Unexpected error creating client connection %s", err))
|
||||
defer conn.Close()
|
||||
|
||||
grpcClient := grpcapi.NewAuthClient(conn, time.Second)
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
token string
|
||||
authRequest *magistrala.AuthZReq
|
||||
authResponse *magistrala.AuthZRes
|
||||
authRequest *grpcAuthV1.AuthZReq
|
||||
authResponse *grpcAuthV1.AuthZRes
|
||||
err error
|
||||
}{
|
||||
{
|
||||
desc: "authorize user with authorized token",
|
||||
token: validToken,
|
||||
authRequest: &magistrala.AuthZReq{
|
||||
authRequest: &grpcAuthV1.AuthZReq{
|
||||
Subject: id,
|
||||
SubjectType: usersType,
|
||||
Object: authoritiesObj,
|
||||
ObjectType: usersType,
|
||||
Relation: memberRelation,
|
||||
Permission: adminpermission,
|
||||
Permission: adminPermission,
|
||||
},
|
||||
authResponse: &magistrala.AuthZRes{Authorized: true},
|
||||
authResponse: &grpcAuthV1.AuthZRes{Authorized: true},
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
desc: "authorize user with unauthorized token",
|
||||
token: inValidToken,
|
||||
authRequest: &magistrala.AuthZReq{
|
||||
authRequest: &grpcAuthV1.AuthZReq{
|
||||
Subject: id,
|
||||
SubjectType: usersType,
|
||||
Object: authoritiesObj,
|
||||
ObjectType: usersType,
|
||||
Relation: memberRelation,
|
||||
Permission: adminpermission,
|
||||
Permission: adminPermission,
|
||||
},
|
||||
authResponse: &magistrala.AuthZRes{Authorized: false},
|
||||
authResponse: &grpcAuthV1.AuthZRes{Authorized: false},
|
||||
err: svcerr.ErrAuthorization,
|
||||
},
|
||||
{
|
||||
desc: "authorize user with empty subject",
|
||||
token: validToken,
|
||||
authRequest: &magistrala.AuthZReq{
|
||||
authRequest: &grpcAuthV1.AuthZReq{
|
||||
Subject: "",
|
||||
SubjectType: usersType,
|
||||
Object: authoritiesObj,
|
||||
ObjectType: usersType,
|
||||
Relation: memberRelation,
|
||||
Permission: adminpermission,
|
||||
Permission: adminPermission,
|
||||
},
|
||||
authResponse: &magistrala.AuthZRes{Authorized: false},
|
||||
authResponse: &grpcAuthV1.AuthZRes{Authorized: false},
|
||||
err: apiutil.ErrMissingPolicySub,
|
||||
},
|
||||
{
|
||||
desc: "authorize user with empty subject type",
|
||||
token: validToken,
|
||||
authRequest: &magistrala.AuthZReq{
|
||||
authRequest: &grpcAuthV1.AuthZReq{
|
||||
Subject: id,
|
||||
SubjectType: "",
|
||||
Object: authoritiesObj,
|
||||
ObjectType: usersType,
|
||||
Relation: memberRelation,
|
||||
Permission: adminpermission,
|
||||
Permission: adminPermission,
|
||||
},
|
||||
authResponse: &magistrala.AuthZRes{Authorized: false},
|
||||
authResponse: &grpcAuthV1.AuthZRes{Authorized: false},
|
||||
err: apiutil.ErrMissingPolicySub,
|
||||
},
|
||||
{
|
||||
desc: "authorize user with empty object",
|
||||
token: validToken,
|
||||
authRequest: &magistrala.AuthZReq{
|
||||
authRequest: &grpcAuthV1.AuthZReq{
|
||||
Subject: id,
|
||||
SubjectType: usersType,
|
||||
Object: "",
|
||||
ObjectType: usersType,
|
||||
Relation: memberRelation,
|
||||
Permission: adminpermission,
|
||||
Permission: adminPermission,
|
||||
},
|
||||
authResponse: &magistrala.AuthZRes{Authorized: false},
|
||||
authResponse: &grpcAuthV1.AuthZRes{Authorized: false},
|
||||
err: apiutil.ErrMissingPolicyObj,
|
||||
},
|
||||
{
|
||||
desc: "authorize user with empty object type",
|
||||
token: validToken,
|
||||
authRequest: &magistrala.AuthZReq{
|
||||
authRequest: &grpcAuthV1.AuthZReq{
|
||||
Subject: id,
|
||||
SubjectType: usersType,
|
||||
Object: authoritiesObj,
|
||||
ObjectType: "",
|
||||
Relation: memberRelation,
|
||||
Permission: adminpermission,
|
||||
Permission: adminPermission,
|
||||
},
|
||||
authResponse: &magistrala.AuthZRes{Authorized: false},
|
||||
authResponse: &grpcAuthV1.AuthZRes{Authorized: false},
|
||||
err: apiutil.ErrMissingPolicyObj,
|
||||
},
|
||||
{
|
||||
desc: "authorize user with empty permission",
|
||||
token: validToken,
|
||||
authRequest: &magistrala.AuthZReq{
|
||||
authRequest: &grpcAuthV1.AuthZReq{
|
||||
Subject: id,
|
||||
SubjectType: usersType,
|
||||
Object: authoritiesObj,
|
||||
@@ -212,17 +220,155 @@ func TestAuthorize(t *testing.T) {
|
||||
Relation: memberRelation,
|
||||
Permission: "",
|
||||
},
|
||||
authResponse: &magistrala.AuthZRes{Authorized: false},
|
||||
authResponse: &grpcAuthV1.AuthZRes{Authorized: false},
|
||||
err: apiutil.ErrMalformedPolicyPer,
|
||||
},
|
||||
}
|
||||
for _, tc := range cases {
|
||||
svccall := svc.On("Authorize", mock.Anything, mock.Anything).Return(tc.err)
|
||||
ar, err := grpcClient.Authorize(context.Background(), tc.authRequest)
|
||||
if ar != nil {
|
||||
assert.Equal(t, tc.authResponse, ar, fmt.Sprintf("%s: expected %v got %v", tc.desc, tc.authResponse, ar))
|
||||
}
|
||||
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
|
||||
svccall.Unset()
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
svcCall := svc.On("Authorize", mock.Anything, mock.Anything).Return(tc.err)
|
||||
ar, err := grpcClient.Authorize(context.Background(), tc.authRequest)
|
||||
if ar != nil {
|
||||
assert.Equal(t, tc.authResponse, ar, fmt.Sprintf("%s: expected %v got %v", tc.desc, tc.authResponse, ar))
|
||||
}
|
||||
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
|
||||
svcCall.Unset()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIdentifyPAT(t *testing.T) {
|
||||
conn, err := grpc.NewClient(authAddr, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
assert.Nil(t, err, fmt.Sprintf("Unexpected error creating client connection %s", err))
|
||||
defer conn.Close()
|
||||
grpcClient := grpcapi.NewAuthClient(conn, time.Second)
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
token string
|
||||
idt *grpcAuthV1.AuthNRes
|
||||
svcErr error
|
||||
err error
|
||||
}{
|
||||
{
|
||||
desc: "authenticate user with valid user token",
|
||||
token: validToken,
|
||||
idt: &grpcAuthV1.AuthNRes{Id: id, UserId: clientID},
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
desc: "authenticate user with invalid user token",
|
||||
token: "invalid",
|
||||
idt: &grpcAuthV1.AuthNRes{},
|
||||
svcErr: svcerr.ErrAuthentication,
|
||||
err: svcerr.ErrAuthentication,
|
||||
},
|
||||
{
|
||||
desc: "authenticate user with empty token",
|
||||
token: "",
|
||||
idt: &grpcAuthV1.AuthNRes{},
|
||||
err: apiutil.ErrBearerToken,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
svcCall := svc.On("IdentifyPAT", mock.Anything, tc.token).Return(auth.PAT{ID: id, User: clientID, IssuedAt: time.Now()}, tc.svcErr)
|
||||
idt, err := grpcClient.AuthenticatePAT(context.Background(), &grpcAuthV1.AuthNReq{Token: tc.token})
|
||||
if idt != nil {
|
||||
assert.Equal(t, tc.idt, idt, fmt.Sprintf("%s: expected %v got %v", tc.desc, tc.idt, idt))
|
||||
}
|
||||
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
|
||||
svcCall.Unset()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuthorizePAT(t *testing.T) {
|
||||
conn, err := grpc.NewClient(authAddr, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
assert.Nil(t, err, fmt.Sprintf("Unexpected error creating client connection %s", err))
|
||||
defer conn.Close()
|
||||
|
||||
grpcClient := grpcapi.NewAuthClient(conn, time.Second)
|
||||
cases := []struct {
|
||||
desc string
|
||||
token string
|
||||
authRequest *grpcAuthV1.AuthZPatReq
|
||||
authResponse *grpcAuthV1.AuthZRes
|
||||
err error
|
||||
}{
|
||||
{
|
||||
desc: "authorize user with authorized token",
|
||||
token: validPATToken,
|
||||
authRequest: &grpcAuthV1.AuthZPatReq{
|
||||
UserId: id,
|
||||
PatId: id,
|
||||
EntityType: uint32(auth.ClientsType),
|
||||
OptionalDomainId: domainID,
|
||||
Operation: uint32(auth.CreateOp),
|
||||
EntityId: clientID,
|
||||
},
|
||||
authResponse: &grpcAuthV1.AuthZRes{Authorized: true},
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
desc: "authorize user with unauthorized token",
|
||||
token: inValidPATToken,
|
||||
authRequest: &grpcAuthV1.AuthZPatReq{
|
||||
UserId: id,
|
||||
PatId: id,
|
||||
EntityType: uint32(auth.ClientsType),
|
||||
OptionalDomainId: domainID,
|
||||
Operation: uint32(auth.CreateOp),
|
||||
EntityId: clientID,
|
||||
},
|
||||
authResponse: &grpcAuthV1.AuthZRes{Authorized: false},
|
||||
err: svcerr.ErrAuthorization,
|
||||
},
|
||||
{
|
||||
desc: "authorize user with missing user id",
|
||||
token: validPATToken,
|
||||
authRequest: &grpcAuthV1.AuthZPatReq{
|
||||
PatId: id,
|
||||
EntityType: uint32(auth.ClientsType),
|
||||
OptionalDomainId: domainID,
|
||||
Operation: uint32(auth.CreateOp),
|
||||
EntityId: clientID,
|
||||
},
|
||||
authResponse: &grpcAuthV1.AuthZRes{Authorized: false},
|
||||
err: apiutil.ErrMissingUserID,
|
||||
},
|
||||
{
|
||||
desc: "authorize user with missing pat id",
|
||||
token: validPATToken,
|
||||
authRequest: &grpcAuthV1.AuthZPatReq{
|
||||
UserId: id,
|
||||
EntityType: uint32(auth.ClientsType),
|
||||
OptionalDomainId: domainID,
|
||||
Operation: uint32(auth.CreateOp),
|
||||
EntityId: clientID,
|
||||
},
|
||||
authResponse: &grpcAuthV1.AuthZRes{Authorized: false},
|
||||
err: apiutil.ErrMissingPATID,
|
||||
},
|
||||
}
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
svcCall := svc.On("AuthorizePAT",
|
||||
mock.Anything,
|
||||
tc.authRequest.UserId,
|
||||
tc.authRequest.PatId,
|
||||
mock.Anything,
|
||||
tc.authRequest.OptionalDomainId,
|
||||
mock.Anything,
|
||||
mock.Anything,
|
||||
mock.Anything).Return(tc.err)
|
||||
ar, err := grpcClient.AuthorizePAT(context.Background(), tc.authRequest)
|
||||
if ar != nil {
|
||||
assert.Equal(t, tc.authResponse, ar, fmt.Sprintf("%s: expected %v got %v", tc.desc, tc.authResponse, ar))
|
||||
}
|
||||
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
|
||||
svcCall.Unset()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"github.com/absmach/magistrala/pkg/apiutil"
|
||||
apiutil "github.com/absmach/supermq/api/http/util"
|
||||
"github.com/absmach/supermq/auth"
|
||||
)
|
||||
|
||||
type authenticateReq struct {
|
||||
@@ -49,3 +50,22 @@ func (req authReq) validate() error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type authPATReq struct {
|
||||
userID string
|
||||
patID string
|
||||
entityType auth.EntityType
|
||||
optionalDomainID string
|
||||
operation auth.Operation
|
||||
entityID string
|
||||
}
|
||||
|
||||
func (req authPATReq) validate() error {
|
||||
if req.userID == "" {
|
||||
return apiutil.ErrMissingUserID
|
||||
}
|
||||
if req.patID == "" {
|
||||
return apiutil.ErrMissingPATID
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -3,10 +3,13 @@
|
||||
|
||||
package auth
|
||||
|
||||
import smqauth "github.com/absmach/supermq/auth"
|
||||
|
||||
type authenticateRes struct {
|
||||
id string
|
||||
userID string
|
||||
domainID string
|
||||
userRole smqauth.Role
|
||||
verified bool
|
||||
}
|
||||
|
||||
type authorizeRes struct {
|
||||
|
||||
@@ -6,22 +6,24 @@ package auth
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/absmach/magistrala"
|
||||
"github.com/absmach/magistrala/auth"
|
||||
grpcapi "github.com/absmach/magistrala/auth/api/grpc"
|
||||
grpcAuthV1 "github.com/absmach/supermq/api/grpc/auth/v1"
|
||||
"github.com/absmach/supermq/auth"
|
||||
grpcapi "github.com/absmach/supermq/auth/api/grpc"
|
||||
kitgrpc "github.com/go-kit/kit/transport/grpc"
|
||||
)
|
||||
|
||||
var _ magistrala.AuthServiceServer = (*authGrpcServer)(nil)
|
||||
var _ grpcAuthV1.AuthServiceServer = (*authGrpcServer)(nil)
|
||||
|
||||
type authGrpcServer struct {
|
||||
magistrala.UnimplementedAuthServiceServer
|
||||
authorize kitgrpc.Handler
|
||||
authenticate kitgrpc.Handler
|
||||
grpcAuthV1.UnimplementedAuthServiceServer
|
||||
authorize kitgrpc.Handler
|
||||
authenticate kitgrpc.Handler
|
||||
authenticatePAT kitgrpc.Handler
|
||||
authorizePAT kitgrpc.Handler
|
||||
}
|
||||
|
||||
// NewAuthServer returns new AuthnServiceServer instance.
|
||||
func NewAuthServer(svc auth.Service) magistrala.AuthServiceServer {
|
||||
func NewAuthServer(svc auth.Service) grpcAuthV1.AuthServiceServer {
|
||||
return &authGrpcServer{
|
||||
authorize: kitgrpc.NewServer(
|
||||
(authorizeEndpoint(svc)),
|
||||
@@ -34,37 +36,62 @@ func NewAuthServer(svc auth.Service) magistrala.AuthServiceServer {
|
||||
decodeAuthenticateRequest,
|
||||
encodeAuthenticateResponse,
|
||||
),
|
||||
|
||||
authenticatePAT: kitgrpc.NewServer(
|
||||
(authenticatePATEndpoint(svc)),
|
||||
decodeAuthenticateRequest,
|
||||
encodeAuthenticatePATResponse,
|
||||
),
|
||||
|
||||
authorizePAT: kitgrpc.NewServer(
|
||||
(authorizePATEndpoint(svc)),
|
||||
decodeAuthorizePATRequest,
|
||||
encodeAuthorizeResponse,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
func (s *authGrpcServer) Authenticate(ctx context.Context, req *magistrala.AuthNReq) (*magistrala.AuthNRes, error) {
|
||||
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.(*magistrala.AuthNRes), nil
|
||||
return res.(*grpcAuthV1.AuthNRes), nil
|
||||
}
|
||||
|
||||
func (s *authGrpcServer) Authorize(ctx context.Context, req *magistrala.AuthZReq) (*magistrala.AuthZRes, error) {
|
||||
func (s *authGrpcServer) AuthenticatePAT(ctx context.Context, req *grpcAuthV1.AuthNReq) (*grpcAuthV1.AuthNRes, error) {
|
||||
_, res, err := s.authenticatePAT.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.(*magistrala.AuthZRes), nil
|
||||
return res.(*grpcAuthV1.AuthZRes), nil
|
||||
}
|
||||
|
||||
func decodeAuthenticateRequest(_ context.Context, grpcReq interface{}) (interface{}, error) {
|
||||
req := grpcReq.(*magistrala.AuthNReq)
|
||||
func decodeAuthenticateRequest(_ context.Context, grpcReq any) (any, error) {
|
||||
req := grpcReq.(*grpcAuthV1.AuthNReq)
|
||||
return authenticateReq{token: req.GetToken()}, nil
|
||||
}
|
||||
|
||||
func encodeAuthenticateResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
func encodeAuthenticateResponse(_ context.Context, grpcRes any) (any, error) {
|
||||
res := grpcRes.(authenticateRes)
|
||||
return &magistrala.AuthNRes{Id: res.id, UserId: res.userID, DomainId: res.domainID}, nil
|
||||
return &grpcAuthV1.AuthNRes{Id: res.id, UserId: res.userID, UserRole: uint32(res.userRole), Verified: res.verified}, nil
|
||||
}
|
||||
|
||||
func decodeAuthorizeRequest(_ context.Context, grpcReq interface{}) (interface{}, error) {
|
||||
req := grpcReq.(*magistrala.AuthZReq)
|
||||
func encodeAuthenticatePATResponse(_ context.Context, grpcRes any) (any, error) {
|
||||
res := grpcRes.(authenticateRes)
|
||||
return &grpcAuthV1.AuthNRes{Id: res.id, UserId: res.userID, UserRole: uint32(res.userRole)}, nil
|
||||
}
|
||||
|
||||
func decodeAuthorizeRequest(_ context.Context, grpcReq any) (any, error) {
|
||||
req := grpcReq.(*grpcAuthV1.AuthZReq)
|
||||
return authReq{
|
||||
Domain: req.GetDomain(),
|
||||
SubjectType: req.GetSubjectType(),
|
||||
@@ -77,7 +104,27 @@ func decodeAuthorizeRequest(_ context.Context, grpcReq interface{}) (interface{}
|
||||
}, nil
|
||||
}
|
||||
|
||||
func encodeAuthorizeResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
func encodeAuthorizeResponse(_ context.Context, grpcRes any) (any, error) {
|
||||
res := grpcRes.(authorizeRes)
|
||||
return &magistrala.AuthZRes{Authorized: res.authorized, Id: res.id}, nil
|
||||
return &grpcAuthV1.AuthZRes{Authorized: res.authorized, Id: res.id}, nil
|
||||
}
|
||||
|
||||
func decodeAuthorizePATRequest(_ context.Context, grpcReq any) (any, error) {
|
||||
req := grpcReq.(*grpcAuthV1.AuthZPatReq)
|
||||
return authPATReq{
|
||||
userID: req.GetUserId(),
|
||||
patID: req.GetPatId(),
|
||||
entityType: auth.EntityType(req.GetEntityType()),
|
||||
optionalDomainID: req.GetOptionalDomainId(),
|
||||
operation: auth.Operation(req.GetOperation()),
|
||||
entityID: req.GetEntityId(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *authGrpcServer) AuthorizePAT(ctx context.Context, req *grpcAuthV1.AuthZPatReq) (*grpcAuthV1.AuthZRes, error) {
|
||||
_, res, err := s.authorizePAT.ServeGRPC(ctx, req)
|
||||
if err != nil {
|
||||
return nil, grpcapi.EncodeError(err)
|
||||
}
|
||||
return res.(*grpcAuthV1.AuthZRes), nil
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/absmach/magistrala/auth/mocks"
|
||||
"github.com/absmach/supermq/auth/mocks"
|
||||
)
|
||||
|
||||
var svc *mocks.Service
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package domains
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/absmach/magistrala"
|
||||
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 domainsSvcName = "magistrala.DomainsService"
|
||||
|
||||
var _ magistrala.DomainsServiceClient = (*domainsGrpcClient)(nil)
|
||||
|
||||
type domainsGrpcClient struct {
|
||||
deleteUserFromDomains endpoint.Endpoint
|
||||
timeout time.Duration
|
||||
}
|
||||
|
||||
// NewDomainsClient returns new domains gRPC client instance.
|
||||
func NewDomainsClient(conn *grpc.ClientConn, timeout time.Duration) magistrala.DomainsServiceClient {
|
||||
return &domainsGrpcClient{
|
||||
deleteUserFromDomains: kitgrpc.NewClient(
|
||||
conn,
|
||||
domainsSvcName,
|
||||
"DeleteUserFromDomains",
|
||||
encodeDeleteUserRequest,
|
||||
decodeDeleteUserResponse,
|
||||
magistrala.DeleteUserRes{},
|
||||
).Endpoint(),
|
||||
|
||||
timeout: timeout,
|
||||
}
|
||||
}
|
||||
|
||||
func (client domainsGrpcClient) DeleteUserFromDomains(ctx context.Context, in *magistrala.DeleteUserReq, opts ...grpc.CallOption) (*magistrala.DeleteUserRes, error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, client.timeout)
|
||||
defer cancel()
|
||||
|
||||
res, err := client.deleteUserFromDomains(ctx, deleteUserPoliciesReq{
|
||||
ID: in.GetId(),
|
||||
})
|
||||
if err != nil {
|
||||
return &magistrala.DeleteUserRes{}, grpcapi.DecodeError(err)
|
||||
}
|
||||
|
||||
dpr := res.(deleteUserRes)
|
||||
return &magistrala.DeleteUserRes{Deleted: dpr.deleted}, nil
|
||||
}
|
||||
|
||||
func decodeDeleteUserResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
res := grpcRes.(*magistrala.DeleteUserRes)
|
||||
return deleteUserRes{deleted: res.GetDeleted()}, nil
|
||||
}
|
||||
|
||||
func encodeDeleteUserRequest(_ context.Context, grpcReq interface{}) (interface{}, error) {
|
||||
req := grpcReq.(deleteUserPoliciesReq)
|
||||
return &magistrala.DeleteUserReq{
|
||||
Id: req.ID,
|
||||
}, nil
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package domains
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/absmach/magistrala/auth"
|
||||
"github.com/go-kit/kit/endpoint"
|
||||
)
|
||||
|
||||
func deleteUserFromDomainsEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
req := request.(deleteUserPoliciesReq)
|
||||
if err := req.validate(); err != nil {
|
||||
return deleteUserRes{}, err
|
||||
}
|
||||
|
||||
if err := svc.DeleteUserFromDomains(ctx, req.ID); err != nil {
|
||||
return deleteUserRes{}, err
|
||||
}
|
||||
|
||||
return deleteUserRes{deleted: true}, nil
|
||||
}
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package domains_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/absmach/magistrala"
|
||||
"github.com/absmach/magistrala/auth"
|
||||
grpcapi "github.com/absmach/magistrala/auth/api/grpc/domains"
|
||||
"github.com/absmach/magistrala/pkg/apiutil"
|
||||
"github.com/absmach/magistrala/pkg/errors"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
)
|
||||
|
||||
const (
|
||||
port = 8081
|
||||
secret = "secret"
|
||||
email = "test@example.com"
|
||||
id = "testID"
|
||||
thingsType = "things"
|
||||
usersType = "users"
|
||||
description = "Description"
|
||||
groupName = "mgx"
|
||||
adminpermission = "admin"
|
||||
|
||||
authoritiesObj = "authorities"
|
||||
memberRelation = "member"
|
||||
loginDuration = 30 * time.Minute
|
||||
refreshDuration = 24 * time.Hour
|
||||
invalidDuration = 7 * 24 * time.Hour
|
||||
validToken = "valid"
|
||||
inValidToken = "invalid"
|
||||
validPolicy = "valid"
|
||||
)
|
||||
|
||||
var authAddr = fmt.Sprintf("localhost:%d", port)
|
||||
|
||||
func startGRPCServer(svc auth.Service, port int) *grpc.Server {
|
||||
listener, _ := net.Listen("tcp", fmt.Sprintf(":%d", port))
|
||||
server := grpc.NewServer()
|
||||
magistrala.RegisterDomainsServiceServer(server, grpcapi.NewDomainsServer(svc))
|
||||
go func() {
|
||||
err := server.Serve(listener)
|
||||
assert.Nil(&testing.T{}, err, fmt.Sprintf(`"Unexpected error creating auth server %s"`, err))
|
||||
}()
|
||||
|
||||
return server
|
||||
}
|
||||
|
||||
func TestDeleteUserFromDomains(t *testing.T) {
|
||||
conn, err := grpc.NewClient(authAddr, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
assert.Nil(t, err, fmt.Sprintf("Unexpected error creating client connection %s", err))
|
||||
grpcClient := grpcapi.NewDomainsClient(conn, time.Second)
|
||||
|
||||
cases := []struct {
|
||||
desc string
|
||||
token string
|
||||
deleteUserReq *magistrala.DeleteUserReq
|
||||
deleteUserRes *magistrala.DeleteUserRes
|
||||
err error
|
||||
}{
|
||||
{
|
||||
desc: "delete valid req",
|
||||
token: validToken,
|
||||
deleteUserReq: &magistrala.DeleteUserReq{
|
||||
Id: id,
|
||||
},
|
||||
deleteUserRes: &magistrala.DeleteUserRes{Deleted: true},
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
desc: "delete invalid req with invalid token",
|
||||
token: inValidToken,
|
||||
deleteUserReq: &magistrala.DeleteUserReq{},
|
||||
deleteUserRes: &magistrala.DeleteUserRes{Deleted: false},
|
||||
err: apiutil.ErrMissingID,
|
||||
},
|
||||
{
|
||||
desc: "delete invalid req with invalid token",
|
||||
token: inValidToken,
|
||||
deleteUserReq: &magistrala.DeleteUserReq{
|
||||
Id: id,
|
||||
},
|
||||
deleteUserRes: &magistrala.DeleteUserRes{Deleted: false},
|
||||
err: apiutil.ErrMissingPolicyEntityType,
|
||||
},
|
||||
}
|
||||
for _, tc := range cases {
|
||||
repoCall := svc.On("DeleteUserFromDomains", mock.Anything, tc.deleteUserReq.Id).Return(tc.err)
|
||||
dpr, err := grpcClient.DeleteUserFromDomains(context.Background(), tc.deleteUserReq)
|
||||
assert.Equal(t, tc.deleteUserRes.GetDeleted(), dpr.GetDeleted(), fmt.Sprintf("%s: expected %v got %v", tc.desc, tc.deleteUserRes.GetDeleted(), dpr.GetDeleted()))
|
||||
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
|
||||
repoCall.Unset()
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package domains
|
||||
|
||||
import (
|
||||
"github.com/absmach/magistrala/pkg/apiutil"
|
||||
)
|
||||
|
||||
type deleteUserPoliciesReq struct {
|
||||
ID string
|
||||
}
|
||||
|
||||
func (req deleteUserPoliciesReq) validate() error {
|
||||
if req.ID == "" {
|
||||
return apiutil.ErrMissingID
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package domains
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/absmach/magistrala"
|
||||
"github.com/absmach/magistrala/auth"
|
||||
grpcapi "github.com/absmach/magistrala/auth/api/grpc"
|
||||
kitgrpc "github.com/go-kit/kit/transport/grpc"
|
||||
)
|
||||
|
||||
var _ magistrala.DomainsServiceServer = (*domainsGrpcServer)(nil)
|
||||
|
||||
type domainsGrpcServer struct {
|
||||
magistrala.UnimplementedDomainsServiceServer
|
||||
deleteUserFromDomains kitgrpc.Handler
|
||||
}
|
||||
|
||||
func NewDomainsServer(svc auth.Service) magistrala.DomainsServiceServer {
|
||||
return &domainsGrpcServer{
|
||||
deleteUserFromDomains: kitgrpc.NewServer(
|
||||
(deleteUserFromDomainsEndpoint(svc)),
|
||||
decodeDeleteUserRequest,
|
||||
encodeDeleteUserResponse,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
func decodeDeleteUserRequest(_ context.Context, grpcReq interface{}) (interface{}, error) {
|
||||
req := grpcReq.(*magistrala.DeleteUserReq)
|
||||
return deleteUserPoliciesReq{
|
||||
ID: req.GetId(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func encodeDeleteUserResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
res := grpcRes.(deleteUserRes)
|
||||
return &magistrala.DeleteUserRes{Deleted: res.deleted}, nil
|
||||
}
|
||||
|
||||
func (s *domainsGrpcServer) DeleteUserFromDomains(ctx context.Context, req *magistrala.DeleteUserReq) (*magistrala.DeleteUserRes, error) {
|
||||
_, res, err := s.deleteUserFromDomains.ServeGRPC(ctx, req)
|
||||
if err != nil {
|
||||
return nil, grpcapi.EncodeError(err)
|
||||
}
|
||||
return res.(*magistrala.DeleteUserRes), nil
|
||||
}
|
||||
@@ -7,15 +7,15 @@ import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/absmach/magistrala"
|
||||
"github.com/absmach/magistrala/auth"
|
||||
grpcapi "github.com/absmach/magistrala/auth/api/grpc"
|
||||
grpcTokenV1 "github.com/absmach/supermq/api/grpc/token/v1"
|
||||
"github.com/absmach/supermq/auth"
|
||||
grpcapi "github.com/absmach/supermq/auth/api/grpc"
|
||||
"github.com/go-kit/kit/endpoint"
|
||||
kitgrpc "github.com/go-kit/kit/transport/grpc"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
const tokenSvcName = "magistrala.TokenService"
|
||||
const tokenSvcName = "token.v1.TokenService"
|
||||
|
||||
type tokenGrpcClient struct {
|
||||
issue endpoint.Endpoint
|
||||
@@ -23,10 +23,10 @@ type tokenGrpcClient struct {
|
||||
timeout time.Duration
|
||||
}
|
||||
|
||||
var _ magistrala.TokenServiceClient = (*tokenGrpcClient)(nil)
|
||||
var _ grpcTokenV1.TokenServiceClient = (*tokenGrpcClient)(nil)
|
||||
|
||||
// NewAuthClient returns new auth gRPC client instance.
|
||||
func NewTokenClient(conn *grpc.ClientConn, timeout time.Duration) magistrala.TokenServiceClient {
|
||||
func NewTokenClient(conn *grpc.ClientConn, timeout time.Duration) grpcTokenV1.TokenServiceClient {
|
||||
return &tokenGrpcClient{
|
||||
issue: kitgrpc.NewClient(
|
||||
conn,
|
||||
@@ -34,7 +34,7 @@ func NewTokenClient(conn *grpc.ClientConn, timeout time.Duration) magistrala.Tok
|
||||
"Issue",
|
||||
encodeIssueRequest,
|
||||
decodeIssueResponse,
|
||||
magistrala.Token{},
|
||||
grpcTokenV1.Token{},
|
||||
).Endpoint(),
|
||||
refresh: kitgrpc.NewClient(
|
||||
conn,
|
||||
@@ -42,54 +42,58 @@ func NewTokenClient(conn *grpc.ClientConn, timeout time.Duration) magistrala.Tok
|
||||
"Refresh",
|
||||
encodeRefreshRequest,
|
||||
decodeRefreshResponse,
|
||||
magistrala.Token{},
|
||||
grpcTokenV1.Token{},
|
||||
).Endpoint(),
|
||||
timeout: timeout,
|
||||
}
|
||||
}
|
||||
|
||||
func (client tokenGrpcClient) Issue(ctx context.Context, req *magistrala.IssueReq, _ ...grpc.CallOption) (*magistrala.Token, error) {
|
||||
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(),
|
||||
keyType: auth.KeyType(req.GetType()),
|
||||
userID: req.GetUserId(),
|
||||
userRole: auth.Role(req.GetUserRole()),
|
||||
keyType: auth.KeyType(req.GetType()),
|
||||
verified: req.GetVerified(),
|
||||
})
|
||||
if err != nil {
|
||||
return &magistrala.Token{}, grpcapi.DecodeError(err)
|
||||
return &grpcTokenV1.Token{}, grpcapi.DecodeError(err)
|
||||
}
|
||||
return res.(*magistrala.Token), nil
|
||||
return res.(*grpcTokenV1.Token), nil
|
||||
}
|
||||
|
||||
func encodeIssueRequest(_ context.Context, grpcReq interface{}) (interface{}, error) {
|
||||
func encodeIssueRequest(_ context.Context, grpcReq any) (any, error) {
|
||||
req := grpcReq.(issueReq)
|
||||
return &magistrala.IssueReq{
|
||||
UserId: req.userID,
|
||||
Type: uint32(req.keyType),
|
||||
return &grpcTokenV1.IssueReq{
|
||||
UserId: req.userID,
|
||||
UserRole: uint32(req.userRole),
|
||||
Type: uint32(req.keyType),
|
||||
Verified: req.verified,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func decodeIssueResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
func decodeIssueResponse(_ context.Context, grpcRes any) (any, error) {
|
||||
return grpcRes, nil
|
||||
}
|
||||
|
||||
func (client tokenGrpcClient) Refresh(ctx context.Context, req *magistrala.RefreshReq, _ ...grpc.CallOption) (*magistrala.Token, error) {
|
||||
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()})
|
||||
res, err := client.refresh(ctx, refreshReq{refreshToken: req.GetRefreshToken(), verified: req.GetVerified()})
|
||||
if err != nil {
|
||||
return &magistrala.Token{}, grpcapi.DecodeError(err)
|
||||
return &grpcTokenV1.Token{}, grpcapi.DecodeError(err)
|
||||
}
|
||||
return res.(*magistrala.Token), nil
|
||||
return res.(*grpcTokenV1.Token), nil
|
||||
}
|
||||
|
||||
func encodeRefreshRequest(_ context.Context, grpcReq interface{}) (interface{}, error) {
|
||||
func encodeRefreshRequest(_ context.Context, grpcReq any) (any, error) {
|
||||
req := grpcReq.(refreshReq)
|
||||
return &magistrala.RefreshReq{RefreshToken: req.refreshToken}, nil
|
||||
return &grpcTokenV1.RefreshReq{RefreshToken: req.refreshToken, Verified: req.verified}, nil
|
||||
}
|
||||
|
||||
func decodeRefreshResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
func decodeRefreshResponse(_ context.Context, grpcRes any) (any, error) {
|
||||
return grpcRes, nil
|
||||
}
|
||||
|
||||
@@ -6,20 +6,22 @@ package token
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/absmach/magistrala/auth"
|
||||
"github.com/absmach/supermq/auth"
|
||||
"github.com/go-kit/kit/endpoint"
|
||||
)
|
||||
|
||||
func issueEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
return func(ctx context.Context, request any) (any, error) {
|
||||
req := request.(issueReq)
|
||||
if err := req.validate(); err != nil {
|
||||
return issueRes{}, err
|
||||
}
|
||||
|
||||
key := auth.Key{
|
||||
Type: req.keyType,
|
||||
User: req.userID,
|
||||
Type: req.keyType,
|
||||
Subject: req.userID,
|
||||
Role: req.userRole,
|
||||
Verified: req.verified,
|
||||
}
|
||||
tkn, err := svc.Issue(ctx, "", key)
|
||||
if err != nil {
|
||||
@@ -35,13 +37,13 @@ func issueEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
}
|
||||
|
||||
func refreshEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
return func(ctx context.Context, request any) (any, error) {
|
||||
req := request.(refreshReq)
|
||||
if err := req.validate(); err != nil {
|
||||
return issueRes{}, err
|
||||
}
|
||||
|
||||
key := auth.Key{Type: auth.RefreshKey}
|
||||
key := auth.Key{Type: auth.RefreshKey, Verified: req.verified}
|
||||
tkn, err := svc.Issue(ctx, req.refreshToken, key)
|
||||
if err != nil {
|
||||
return issueRes{}, err
|
||||
|
||||
@@ -10,13 +10,13 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/absmach/magistrala"
|
||||
"github.com/absmach/magistrala/auth"
|
||||
grpcapi "github.com/absmach/magistrala/auth/api/grpc/token"
|
||||
"github.com/absmach/magistrala/internal/testsutil"
|
||||
"github.com/absmach/magistrala/pkg/apiutil"
|
||||
"github.com/absmach/magistrala/pkg/errors"
|
||||
svcerr "github.com/absmach/magistrala/pkg/errors/service"
|
||||
grpcTokenV1 "github.com/absmach/supermq/api/grpc/token/v1"
|
||||
apiutil "github.com/absmach/supermq/api/http/util"
|
||||
"github.com/absmach/supermq/auth"
|
||||
grpcapi "github.com/absmach/supermq/auth/api/grpc/token"
|
||||
"github.com/absmach/supermq/internal/testsutil"
|
||||
"github.com/absmach/supermq/pkg/errors"
|
||||
svcerr "github.com/absmach/supermq/pkg/errors/service"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"google.golang.org/grpc"
|
||||
@@ -24,15 +24,15 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
port = 8081
|
||||
port = 8082
|
||||
secret = "secret"
|
||||
email = "test@example.com"
|
||||
id = "testID"
|
||||
thingsType = "things"
|
||||
clientsType = "clients"
|
||||
usersType = "users"
|
||||
description = "Description"
|
||||
groupName = "mgx"
|
||||
adminpermission = "admin"
|
||||
groupName = "smqx"
|
||||
adminPermission = "admin"
|
||||
|
||||
authoritiesObj = "authorities"
|
||||
memberRelation = "member"
|
||||
@@ -52,7 +52,7 @@ var (
|
||||
func startGRPCServer(svc auth.Service, port int) *grpc.Server {
|
||||
listener, _ := net.Listen("tcp", fmt.Sprintf(":%d", port))
|
||||
server := grpc.NewServer()
|
||||
magistrala.RegisterTokenServiceServer(server, grpcapi.NewTokenServer(svc))
|
||||
grpcTokenV1.RegisterTokenServiceServer(server, grpcapi.NewTokenServer(svc))
|
||||
go func() {
|
||||
err := server.Serve(listener)
|
||||
assert.Nil(&testing.T{}, err, fmt.Sprintf(`"Unexpected error creating auth server %s"`, err))
|
||||
@@ -63,6 +63,7 @@ func startGRPCServer(svc auth.Service, port int) *grpc.Server {
|
||||
|
||||
func TestIssue(t *testing.T) {
|
||||
conn, err := grpc.NewClient(authAddr, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
defer conn.Close()
|
||||
assert.Nil(t, err, fmt.Sprintf("Unexpected error creating client connection %s", err))
|
||||
grpcClient := grpcapi.NewTokenClient(conn, time.Second)
|
||||
|
||||
@@ -117,17 +118,16 @@ func TestIssue(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
svcCall := svc.On("Issue", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(tc.issueResponse, tc.err)
|
||||
_, err := grpcClient.Issue(context.Background(), &magistrala.IssueReq{UserId: tc.userId, Type: uint32(tc.kind)})
|
||||
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
|
||||
svcCall.Unset()
|
||||
})
|
||||
svcCall := svc.On("Issue", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(tc.issueResponse, tc.err)
|
||||
_, err := grpcClient.Issue(context.Background(), &grpcTokenV1.IssueReq{UserId: tc.userId, Type: uint32(tc.kind)})
|
||||
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
|
||||
svcCall.Unset()
|
||||
}
|
||||
}
|
||||
|
||||
func TestRefresh(t *testing.T) {
|
||||
conn, err := grpc.NewClient(authAddr, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
defer conn.Close()
|
||||
assert.Nil(t, err, fmt.Sprintf("Unexpected error creating client connection %s", err))
|
||||
grpcClient := grpcapi.NewTokenClient(conn, time.Second)
|
||||
|
||||
@@ -161,11 +161,9 @@ func TestRefresh(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
svcCall := svc.On("Issue", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(tc.issueResponse, tc.err)
|
||||
_, err := grpcClient.Refresh(context.Background(), &magistrala.RefreshReq{RefreshToken: tc.token})
|
||||
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
|
||||
svcCall.Unset()
|
||||
})
|
||||
svcCall := svc.On("Issue", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(tc.issueResponse, tc.err)
|
||||
_, err := grpcClient.Refresh(context.Background(), &grpcTokenV1.RefreshReq{RefreshToken: tc.token})
|
||||
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s: expected %s got %s\n", tc.desc, tc.err, err))
|
||||
svcCall.Unset()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,13 +4,15 @@
|
||||
package token
|
||||
|
||||
import (
|
||||
"github.com/absmach/magistrala/auth"
|
||||
"github.com/absmach/magistrala/pkg/apiutil"
|
||||
apiutil "github.com/absmach/supermq/api/http/util"
|
||||
"github.com/absmach/supermq/auth"
|
||||
)
|
||||
|
||||
type issueReq struct {
|
||||
userID string
|
||||
keyType auth.KeyType
|
||||
userID string
|
||||
userRole auth.Role
|
||||
keyType auth.KeyType
|
||||
verified bool
|
||||
}
|
||||
|
||||
func (req issueReq) validate() error {
|
||||
@@ -26,6 +28,7 @@ func (req issueReq) validate() error {
|
||||
|
||||
type refreshReq struct {
|
||||
refreshToken string
|
||||
verified bool
|
||||
}
|
||||
|
||||
func (req refreshReq) validate() error {
|
||||
|
||||
@@ -6,22 +6,22 @@ package token
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/absmach/magistrala"
|
||||
"github.com/absmach/magistrala/auth"
|
||||
grpcapi "github.com/absmach/magistrala/auth/api/grpc"
|
||||
grpcTokenV1 "github.com/absmach/supermq/api/grpc/token/v1"
|
||||
"github.com/absmach/supermq/auth"
|
||||
grpcapi "github.com/absmach/supermq/auth/api/grpc"
|
||||
kitgrpc "github.com/go-kit/kit/transport/grpc"
|
||||
)
|
||||
|
||||
var _ magistrala.TokenServiceServer = (*tokenGrpcServer)(nil)
|
||||
var _ grpcTokenV1.TokenServiceServer = (*tokenGrpcServer)(nil)
|
||||
|
||||
type tokenGrpcServer struct {
|
||||
magistrala.UnimplementedTokenServiceServer
|
||||
grpcTokenV1.UnimplementedTokenServiceServer
|
||||
issue kitgrpc.Handler
|
||||
refresh kitgrpc.Handler
|
||||
}
|
||||
|
||||
// NewAuthServer returns new AuthnServiceServer instance.
|
||||
func NewTokenServer(svc auth.Service) magistrala.TokenServiceServer {
|
||||
func NewTokenServer(svc auth.Service) grpcTokenV1.TokenServiceServer {
|
||||
return &tokenGrpcServer{
|
||||
issue: kitgrpc.NewServer(
|
||||
(issueEndpoint(svc)),
|
||||
@@ -36,39 +36,41 @@ func NewTokenServer(svc auth.Service) magistrala.TokenServiceServer {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *tokenGrpcServer) Issue(ctx context.Context, req *magistrala.IssueReq) (*magistrala.Token, error) {
|
||||
func (s *tokenGrpcServer) Issue(ctx context.Context, req *grpcTokenV1.IssueReq) (*grpcTokenV1.Token, error) {
|
||||
_, res, err := s.issue.ServeGRPC(ctx, req)
|
||||
if err != nil {
|
||||
return nil, grpcapi.EncodeError(err)
|
||||
}
|
||||
return res.(*magistrala.Token), nil
|
||||
return res.(*grpcTokenV1.Token), nil
|
||||
}
|
||||
|
||||
func (s *tokenGrpcServer) Refresh(ctx context.Context, req *magistrala.RefreshReq) (*magistrala.Token, error) {
|
||||
func (s *tokenGrpcServer) Refresh(ctx context.Context, req *grpcTokenV1.RefreshReq) (*grpcTokenV1.Token, error) {
|
||||
_, res, err := s.refresh.ServeGRPC(ctx, req)
|
||||
if err != nil {
|
||||
return nil, grpcapi.EncodeError(err)
|
||||
}
|
||||
return res.(*magistrala.Token), nil
|
||||
return res.(*grpcTokenV1.Token), nil
|
||||
}
|
||||
|
||||
func decodeIssueRequest(_ context.Context, grpcReq interface{}) (interface{}, error) {
|
||||
req := grpcReq.(*magistrala.IssueReq)
|
||||
func decodeIssueRequest(_ context.Context, grpcReq any) (any, error) {
|
||||
req := grpcReq.(*grpcTokenV1.IssueReq)
|
||||
return issueReq{
|
||||
userID: req.GetUserId(),
|
||||
keyType: auth.KeyType(req.GetType()),
|
||||
userID: req.GetUserId(),
|
||||
userRole: auth.Role(req.GetUserRole()),
|
||||
keyType: auth.KeyType(req.GetType()),
|
||||
verified: req.Verified,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func decodeRefreshRequest(_ context.Context, grpcReq interface{}) (interface{}, error) {
|
||||
req := grpcReq.(*magistrala.RefreshReq)
|
||||
return refreshReq{refreshToken: req.GetRefreshToken()}, nil
|
||||
func decodeRefreshRequest(_ context.Context, grpcReq any) (any, error) {
|
||||
req := grpcReq.(*grpcTokenV1.RefreshReq)
|
||||
return refreshReq{refreshToken: req.GetRefreshToken(), verified: req.Verified}, nil
|
||||
}
|
||||
|
||||
func encodeIssueResponse(_ context.Context, grpcRes interface{}) (interface{}, error) {
|
||||
func encodeIssueResponse(_ context.Context, grpcRes any) (any, error) {
|
||||
res := grpcRes.(issueRes)
|
||||
|
||||
return &magistrala.Token{
|
||||
return &grpcTokenV1.Token{
|
||||
AccessToken: res.accessToken,
|
||||
RefreshToken: &res.refreshToken,
|
||||
AccessType: res.accessType,
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/absmach/magistrala/auth/mocks"
|
||||
"github.com/absmach/supermq/auth/mocks"
|
||||
)
|
||||
|
||||
var svc *mocks.Service
|
||||
|
||||
@@ -6,10 +6,10 @@ package grpc
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/absmach/magistrala/auth"
|
||||
"github.com/absmach/magistrala/pkg/apiutil"
|
||||
"github.com/absmach/magistrala/pkg/errors"
|
||||
svcerr "github.com/absmach/magistrala/pkg/errors/service"
|
||||
apiutil "github.com/absmach/supermq/api/http/util"
|
||||
"github.com/absmach/supermq/auth"
|
||||
"github.com/absmach/supermq/pkg/errors"
|
||||
svcerr "github.com/absmach/supermq/pkg/errors/service"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
@@ -25,7 +25,9 @@ func EncodeError(err error) error {
|
||||
err == apiutil.ErrMissingMemberType,
|
||||
err == apiutil.ErrMissingPolicySub,
|
||||
err == apiutil.ErrMissingPolicyObj,
|
||||
err == apiutil.ErrMalformedPolicyAct:
|
||||
err == apiutil.ErrMalformedPolicyAct,
|
||||
err == apiutil.ErrMissingUserID,
|
||||
err == apiutil.ErrMissingPATID:
|
||||
return status.Error(codes.InvalidArgument, err.Error())
|
||||
case errors.Contains(err, svcerr.ErrAuthentication),
|
||||
errors.Contains(err, auth.ErrKeyExpired),
|
||||
|
||||
@@ -1,201 +0,0 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package domains
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/absmach/magistrala/auth"
|
||||
"github.com/absmach/magistrala/internal/api"
|
||||
"github.com/absmach/magistrala/pkg/apiutil"
|
||||
"github.com/absmach/magistrala/pkg/errors"
|
||||
"github.com/go-chi/chi/v5"
|
||||
)
|
||||
|
||||
func decodeCreateDomainRequest(_ context.Context, r *http.Request) (interface{}, error) {
|
||||
if !strings.Contains(r.Header.Get("Content-Type"), api.ContentType) {
|
||||
return nil, errors.Wrap(apiutil.ErrValidation, apiutil.ErrUnsupportedContentType)
|
||||
}
|
||||
req := createDomainReq{
|
||||
token: apiutil.ExtractBearerToken(r),
|
||||
}
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
return nil, errors.Wrap(apiutil.ErrValidation, errors.Wrap(err, errors.ErrMalformedEntity))
|
||||
}
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
func decodeRetrieveDomainRequest(_ context.Context, r *http.Request) (interface{}, error) {
|
||||
req := retrieveDomainRequest{
|
||||
token: apiutil.ExtractBearerToken(r),
|
||||
domainID: chi.URLParam(r, "domainID"),
|
||||
}
|
||||
return req, nil
|
||||
}
|
||||
|
||||
func decodeRetrieveDomainPermissionsRequest(_ context.Context, r *http.Request) (interface{}, error) {
|
||||
req := retrieveDomainPermissionsRequest{
|
||||
token: apiutil.ExtractBearerToken(r),
|
||||
domainID: chi.URLParam(r, "domainID"),
|
||||
}
|
||||
return req, nil
|
||||
}
|
||||
|
||||
func decodeUpdateDomainRequest(_ context.Context, r *http.Request) (interface{}, error) {
|
||||
if !strings.Contains(r.Header.Get("Content-Type"), api.ContentType) {
|
||||
return nil, errors.Wrap(apiutil.ErrValidation, apiutil.ErrUnsupportedContentType)
|
||||
}
|
||||
|
||||
req := updateDomainReq{
|
||||
token: apiutil.ExtractBearerToken(r),
|
||||
domainID: chi.URLParam(r, "domainID"),
|
||||
}
|
||||
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
return nil, errors.Wrap(apiutil.ErrValidation, errors.Wrap(err, errors.ErrMalformedEntity))
|
||||
}
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
func decodeListDomainRequest(ctx context.Context, r *http.Request) (interface{}, error) {
|
||||
page, err := decodePageRequest(ctx, r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req := listDomainsReq{
|
||||
token: apiutil.ExtractBearerToken(r),
|
||||
page: page,
|
||||
}
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
func decodeEnableDomainRequest(_ context.Context, r *http.Request) (interface{}, error) {
|
||||
req := enableDomainReq{
|
||||
token: apiutil.ExtractBearerToken(r),
|
||||
domainID: chi.URLParam(r, "domainID"),
|
||||
}
|
||||
return req, nil
|
||||
}
|
||||
|
||||
func decodeDisableDomainRequest(_ context.Context, r *http.Request) (interface{}, error) {
|
||||
req := disableDomainReq{
|
||||
token: apiutil.ExtractBearerToken(r),
|
||||
domainID: chi.URLParam(r, "domainID"),
|
||||
}
|
||||
return req, nil
|
||||
}
|
||||
|
||||
func decodeFreezeDomainRequest(_ context.Context, r *http.Request) (interface{}, error) {
|
||||
req := freezeDomainReq{
|
||||
token: apiutil.ExtractBearerToken(r),
|
||||
domainID: chi.URLParam(r, "domainID"),
|
||||
}
|
||||
return req, nil
|
||||
}
|
||||
|
||||
func decodeAssignUsersRequest(_ context.Context, r *http.Request) (interface{}, error) {
|
||||
if !strings.Contains(r.Header.Get("Content-Type"), api.ContentType) {
|
||||
return nil, errors.Wrap(apiutil.ErrValidation, apiutil.ErrUnsupportedContentType)
|
||||
}
|
||||
|
||||
req := assignUsersReq{
|
||||
token: apiutil.ExtractBearerToken(r),
|
||||
domainID: chi.URLParam(r, "domainID"),
|
||||
}
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
return nil, errors.Wrap(apiutil.ErrValidation, errors.Wrap(err, errors.ErrMalformedEntity))
|
||||
}
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
func decodeUnassignUserRequest(_ context.Context, r *http.Request) (interface{}, error) {
|
||||
if !strings.Contains(r.Header.Get("Content-Type"), api.ContentType) {
|
||||
return nil, errors.Wrap(apiutil.ErrValidation, apiutil.ErrUnsupportedContentType)
|
||||
}
|
||||
|
||||
req := unassignUserReq{
|
||||
token: apiutil.ExtractBearerToken(r),
|
||||
domainID: chi.URLParam(r, "domainID"),
|
||||
}
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
return nil, errors.Wrap(apiutil.ErrValidation, errors.Wrap(err, errors.ErrMalformedEntity))
|
||||
}
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
func decodeListUserDomainsRequest(ctx context.Context, r *http.Request) (interface{}, error) {
|
||||
page, err := decodePageRequest(ctx, r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req := listUserDomainsReq{
|
||||
token: apiutil.ExtractBearerToken(r),
|
||||
userID: chi.URLParam(r, "userID"),
|
||||
page: page,
|
||||
}
|
||||
return req, nil
|
||||
}
|
||||
|
||||
func decodePageRequest(_ context.Context, r *http.Request) (page, error) {
|
||||
s, err := apiutil.ReadStringQuery(r, api.StatusKey, api.DefClientStatus)
|
||||
if err != nil {
|
||||
return page{}, errors.Wrap(apiutil.ErrValidation, err)
|
||||
}
|
||||
st, err := auth.ToStatus(s)
|
||||
if err != nil {
|
||||
return page{}, errors.Wrap(apiutil.ErrValidation, err)
|
||||
}
|
||||
o, err := apiutil.ReadNumQuery[uint64](r, api.OffsetKey, api.DefOffset)
|
||||
if err != nil {
|
||||
return page{}, errors.Wrap(apiutil.ErrValidation, err)
|
||||
}
|
||||
or, err := apiutil.ReadStringQuery(r, api.OrderKey, api.DefOrder)
|
||||
if err != nil {
|
||||
return page{}, errors.Wrap(apiutil.ErrValidation, err)
|
||||
}
|
||||
dir, err := apiutil.ReadStringQuery(r, api.DirKey, api.DefDir)
|
||||
if err != nil {
|
||||
return page{}, errors.Wrap(apiutil.ErrValidation, err)
|
||||
}
|
||||
l, err := apiutil.ReadNumQuery[uint64](r, api.LimitKey, api.DefLimit)
|
||||
if err != nil {
|
||||
return page{}, errors.Wrap(apiutil.ErrValidation, err)
|
||||
}
|
||||
m, err := apiutil.ReadMetadataQuery(r, api.MetadataKey, nil)
|
||||
if err != nil {
|
||||
return page{}, errors.Wrap(apiutil.ErrValidation, err)
|
||||
}
|
||||
n, err := apiutil.ReadStringQuery(r, api.NameKey, "")
|
||||
if err != nil {
|
||||
return page{}, errors.Wrap(apiutil.ErrValidation, err)
|
||||
}
|
||||
t, err := apiutil.ReadStringQuery(r, api.TagKey, "")
|
||||
if err != nil {
|
||||
return page{}, errors.Wrap(apiutil.ErrValidation, err)
|
||||
}
|
||||
p, err := apiutil.ReadStringQuery(r, api.PermissionKey, "")
|
||||
if err != nil {
|
||||
return page{}, errors.Wrap(apiutil.ErrValidation, err)
|
||||
}
|
||||
|
||||
return page{
|
||||
offset: o,
|
||||
order: or,
|
||||
dir: dir,
|
||||
limit: l,
|
||||
name: n,
|
||||
metadata: m,
|
||||
tag: t,
|
||||
permission: p,
|
||||
status: st,
|
||||
}, nil
|
||||
}
|
||||
@@ -1,225 +0,0 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package domains
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/absmach/magistrala/auth"
|
||||
"github.com/absmach/magistrala/pkg/apiutil"
|
||||
"github.com/absmach/magistrala/pkg/errors"
|
||||
"github.com/go-kit/kit/endpoint"
|
||||
)
|
||||
|
||||
func createDomainEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
req := request.(createDomainReq)
|
||||
if err := req.validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
d := auth.Domain{
|
||||
Name: req.Name,
|
||||
Metadata: req.Metadata,
|
||||
Tags: req.Tags,
|
||||
Alias: req.Alias,
|
||||
}
|
||||
domain, err := svc.CreateDomain(ctx, req.token, d)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return createDomainRes{domain}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func retrieveDomainEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
req := request.(retrieveDomainRequest)
|
||||
if err := req.validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
domain, err := svc.RetrieveDomain(ctx, req.token, req.domainID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return retrieveDomainRes{domain}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func retrieveDomainPermissionsEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
req := request.(retrieveDomainPermissionsRequest)
|
||||
if err := req.validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
permissions, err := svc.RetrieveDomainPermissions(ctx, req.token, req.domainID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return retrieveDomainPermissionsRes{Permissions: permissions}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func updateDomainEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
req := request.(updateDomainReq)
|
||||
if err := req.validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var metadata auth.Metadata
|
||||
if req.Metadata != nil {
|
||||
metadata = *req.Metadata
|
||||
}
|
||||
d := auth.DomainReq{
|
||||
Name: req.Name,
|
||||
Metadata: &metadata,
|
||||
Tags: req.Tags,
|
||||
Alias: req.Alias,
|
||||
}
|
||||
domain, err := svc.UpdateDomain(ctx, req.token, req.domainID, d)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return updateDomainRes{domain}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func listDomainsEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
req := request.(listDomainsReq)
|
||||
if err := req.validate(); err != nil {
|
||||
return nil, errors.Wrap(apiutil.ErrValidation, err)
|
||||
}
|
||||
|
||||
page := auth.Page{
|
||||
Offset: req.offset,
|
||||
Limit: req.limit,
|
||||
Name: req.name,
|
||||
Metadata: req.metadata,
|
||||
Order: req.order,
|
||||
Dir: req.dir,
|
||||
Tag: req.tag,
|
||||
Permission: req.permission,
|
||||
Status: req.status,
|
||||
}
|
||||
dp, err := svc.ListDomains(ctx, req.token, page)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return listDomainsRes{dp}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func enableDomainEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
req := request.(enableDomainReq)
|
||||
if err := req.validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
enable := auth.EnabledStatus
|
||||
d := auth.DomainReq{
|
||||
Status: &enable,
|
||||
}
|
||||
if _, err := svc.ChangeDomainStatus(ctx, req.token, req.domainID, d); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return enableDomainRes{}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func disableDomainEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
req := request.(disableDomainReq)
|
||||
if err := req.validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
disable := auth.DisabledStatus
|
||||
d := auth.DomainReq{
|
||||
Status: &disable,
|
||||
}
|
||||
if _, err := svc.ChangeDomainStatus(ctx, req.token, req.domainID, d); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return disableDomainRes{}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func freezeDomainEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
req := request.(freezeDomainReq)
|
||||
if err := req.validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
freeze := auth.FreezeStatus
|
||||
d := auth.DomainReq{
|
||||
Status: &freeze,
|
||||
}
|
||||
if _, err := svc.ChangeDomainStatus(ctx, req.token, req.domainID, d); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return freezeDomainRes{}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func assignDomainUsersEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
req := request.(assignUsersReq)
|
||||
if err := req.validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := svc.AssignUsers(ctx, req.token, req.domainID, req.UserIDs, req.Relation); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return assignUsersRes{}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func unassignDomainUserEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
req := request.(unassignUserReq)
|
||||
if err := req.validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := svc.UnassignUser(ctx, req.token, req.domainID, req.UserID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return unassignUsersRes{}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func listUserDomainsEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
req := request.(listUserDomainsReq)
|
||||
if err := req.validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
page := auth.Page{
|
||||
Offset: req.offset,
|
||||
Limit: req.limit,
|
||||
Name: req.name,
|
||||
Metadata: req.metadata,
|
||||
Order: req.order,
|
||||
Dir: req.dir,
|
||||
Tag: req.tag,
|
||||
Permission: req.permission,
|
||||
Status: req.status,
|
||||
}
|
||||
dp, err := svc.ListUserDomains(ctx, req.token, req.userID, page)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return listUserDomainsRes{dp}, nil
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,231 +0,0 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package domains
|
||||
|
||||
import (
|
||||
"github.com/absmach/magistrala/auth"
|
||||
"github.com/absmach/magistrala/pkg/apiutil"
|
||||
)
|
||||
|
||||
type page struct {
|
||||
offset uint64
|
||||
limit uint64
|
||||
order string
|
||||
dir string
|
||||
name string
|
||||
metadata map[string]interface{}
|
||||
tag string
|
||||
permission string
|
||||
status auth.Status
|
||||
}
|
||||
|
||||
type createDomainReq struct {
|
||||
token string
|
||||
Name string `json:"name"`
|
||||
Metadata map[string]interface{} `json:"metadata,omitempty"`
|
||||
Tags []string `json:"tags,omitempty"`
|
||||
Alias string `json:"alias"`
|
||||
}
|
||||
|
||||
func (req createDomainReq) validate() error {
|
||||
if req.token == "" {
|
||||
return apiutil.ErrBearerToken
|
||||
}
|
||||
|
||||
if req.Name == "" {
|
||||
return apiutil.ErrMissingName
|
||||
}
|
||||
|
||||
if req.Alias == "" {
|
||||
return apiutil.ErrMissingAlias
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type retrieveDomainRequest struct {
|
||||
token string
|
||||
domainID string
|
||||
}
|
||||
|
||||
func (req retrieveDomainRequest) validate() error {
|
||||
if req.token == "" {
|
||||
return apiutil.ErrBearerToken
|
||||
}
|
||||
|
||||
if req.domainID == "" {
|
||||
return apiutil.ErrMissingID
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type retrieveDomainPermissionsRequest struct {
|
||||
token string
|
||||
domainID string
|
||||
}
|
||||
|
||||
func (req retrieveDomainPermissionsRequest) validate() error {
|
||||
if req.token == "" {
|
||||
return apiutil.ErrBearerToken
|
||||
}
|
||||
|
||||
if req.domainID == "" {
|
||||
return apiutil.ErrMissingID
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type updateDomainReq struct {
|
||||
token string
|
||||
domainID string
|
||||
Name *string `json:"name,omitempty"`
|
||||
Metadata *map[string]interface{} `json:"metadata,omitempty"`
|
||||
Tags *[]string `json:"tags,omitempty"`
|
||||
Alias *string `json:"alias,omitempty"`
|
||||
}
|
||||
|
||||
func (req updateDomainReq) validate() error {
|
||||
if req.token == "" {
|
||||
return apiutil.ErrBearerToken
|
||||
}
|
||||
|
||||
if req.domainID == "" {
|
||||
return apiutil.ErrMissingID
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type listDomainsReq struct {
|
||||
token string
|
||||
page
|
||||
}
|
||||
|
||||
func (req listDomainsReq) validate() error {
|
||||
if req.token == "" {
|
||||
return apiutil.ErrBearerToken
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type enableDomainReq struct {
|
||||
token string
|
||||
domainID string
|
||||
}
|
||||
|
||||
func (req enableDomainReq) validate() error {
|
||||
if req.token == "" {
|
||||
return apiutil.ErrBearerToken
|
||||
}
|
||||
|
||||
if req.domainID == "" {
|
||||
return apiutil.ErrMissingID
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type disableDomainReq struct {
|
||||
token string
|
||||
domainID string
|
||||
}
|
||||
|
||||
func (req disableDomainReq) validate() error {
|
||||
if req.token == "" {
|
||||
return apiutil.ErrBearerToken
|
||||
}
|
||||
|
||||
if req.domainID == "" {
|
||||
return apiutil.ErrMissingID
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type freezeDomainReq struct {
|
||||
token string
|
||||
domainID string
|
||||
}
|
||||
|
||||
func (req freezeDomainReq) validate() error {
|
||||
if req.token == "" {
|
||||
return apiutil.ErrBearerToken
|
||||
}
|
||||
|
||||
if req.domainID == "" {
|
||||
return apiutil.ErrMissingID
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type assignUsersReq struct {
|
||||
token string
|
||||
domainID string
|
||||
UserIDs []string `json:"user_ids"`
|
||||
Relation string `json:"relation"`
|
||||
}
|
||||
|
||||
func (req assignUsersReq) validate() error {
|
||||
if req.token == "" {
|
||||
return apiutil.ErrBearerToken
|
||||
}
|
||||
|
||||
if req.domainID == "" {
|
||||
return apiutil.ErrMissingID
|
||||
}
|
||||
|
||||
if len(req.UserIDs) == 0 {
|
||||
return apiutil.ErrMissingID
|
||||
}
|
||||
|
||||
if req.Relation == "" {
|
||||
return apiutil.ErrMissingRelation
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type unassignUserReq struct {
|
||||
token string
|
||||
domainID string
|
||||
UserID string `json:"user_id"`
|
||||
}
|
||||
|
||||
func (req unassignUserReq) validate() error {
|
||||
if req.token == "" {
|
||||
return apiutil.ErrBearerToken
|
||||
}
|
||||
|
||||
if req.domainID == "" {
|
||||
return apiutil.ErrMissingID
|
||||
}
|
||||
|
||||
if req.UserID == "" {
|
||||
return apiutil.ErrMalformedPolicy
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type listUserDomainsReq struct {
|
||||
token string
|
||||
userID string
|
||||
page
|
||||
}
|
||||
|
||||
func (req listUserDomainsReq) validate() error {
|
||||
if req.token == "" {
|
||||
return apiutil.ErrBearerToken
|
||||
}
|
||||
|
||||
if req.userID == "" {
|
||||
return apiutil.ErrMissingID
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package domains
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
|
||||
"github.com/absmach/magistrala/auth"
|
||||
"github.com/absmach/magistrala/internal/api"
|
||||
"github.com/absmach/magistrala/pkg/apiutil"
|
||||
"github.com/go-chi/chi/v5"
|
||||
kithttp "github.com/go-kit/kit/transport/http"
|
||||
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
||||
)
|
||||
|
||||
func MakeHandler(svc auth.Service, mux *chi.Mux, logger *slog.Logger) *chi.Mux {
|
||||
opts := []kithttp.ServerOption{
|
||||
kithttp.ServerErrorEncoder(apiutil.LoggingErrorEncoder(logger, api.EncodeError)),
|
||||
}
|
||||
|
||||
mux.Route("/domains", func(r chi.Router) {
|
||||
r.Post("/", otelhttp.NewHandler(kithttp.NewServer(
|
||||
createDomainEndpoint(svc),
|
||||
decodeCreateDomainRequest,
|
||||
api.EncodeResponse,
|
||||
opts...,
|
||||
), "create_domain").ServeHTTP)
|
||||
|
||||
r.Get("/", otelhttp.NewHandler(kithttp.NewServer(
|
||||
listDomainsEndpoint(svc),
|
||||
decodeListDomainRequest,
|
||||
api.EncodeResponse,
|
||||
opts...,
|
||||
), "list_domains").ServeHTTP)
|
||||
|
||||
r.Route("/{domainID}", func(r chi.Router) {
|
||||
r.Get("/", otelhttp.NewHandler(kithttp.NewServer(
|
||||
retrieveDomainEndpoint(svc),
|
||||
decodeRetrieveDomainRequest,
|
||||
api.EncodeResponse,
|
||||
opts...,
|
||||
), "view_domain").ServeHTTP)
|
||||
|
||||
r.Get("/permissions", otelhttp.NewHandler(kithttp.NewServer(
|
||||
retrieveDomainPermissionsEndpoint(svc),
|
||||
decodeRetrieveDomainPermissionsRequest,
|
||||
api.EncodeResponse,
|
||||
opts...,
|
||||
), "view_domain_permissions").ServeHTTP)
|
||||
|
||||
r.Patch("/", otelhttp.NewHandler(kithttp.NewServer(
|
||||
updateDomainEndpoint(svc),
|
||||
decodeUpdateDomainRequest,
|
||||
api.EncodeResponse,
|
||||
opts...,
|
||||
), "update_domain").ServeHTTP)
|
||||
|
||||
r.Post("/enable", otelhttp.NewHandler(kithttp.NewServer(
|
||||
enableDomainEndpoint(svc),
|
||||
decodeEnableDomainRequest,
|
||||
api.EncodeResponse,
|
||||
opts...,
|
||||
), "enable_domain").ServeHTTP)
|
||||
|
||||
r.Post("/disable", otelhttp.NewHandler(kithttp.NewServer(
|
||||
disableDomainEndpoint(svc),
|
||||
decodeDisableDomainRequest,
|
||||
api.EncodeResponse,
|
||||
opts...,
|
||||
), "disable_domain").ServeHTTP)
|
||||
|
||||
r.Post("/freeze", otelhttp.NewHandler(kithttp.NewServer(
|
||||
freezeDomainEndpoint(svc),
|
||||
decodeFreezeDomainRequest,
|
||||
api.EncodeResponse,
|
||||
opts...,
|
||||
), "freeze_domain").ServeHTTP)
|
||||
|
||||
r.Route("/users", func(r chi.Router) {
|
||||
r.Post("/assign", otelhttp.NewHandler(kithttp.NewServer(
|
||||
assignDomainUsersEndpoint(svc),
|
||||
decodeAssignUsersRequest,
|
||||
api.EncodeResponse,
|
||||
opts...,
|
||||
), "assign_domain_users").ServeHTTP)
|
||||
|
||||
r.Post("/unassign", otelhttp.NewHandler(kithttp.NewServer(
|
||||
unassignDomainUserEndpoint(svc),
|
||||
decodeUnassignUserRequest,
|
||||
api.EncodeResponse,
|
||||
opts...,
|
||||
), "unassign_domain_users").ServeHTTP)
|
||||
})
|
||||
})
|
||||
})
|
||||
mux.Get("/users/{userID}/domains", otelhttp.NewHandler(kithttp.NewServer(
|
||||
listUserDomainsEndpoint(svc),
|
||||
decodeListUserDomainsRequest,
|
||||
api.EncodeResponse,
|
||||
opts...,
|
||||
), "list_domains_by_user_id").ServeHTTP)
|
||||
|
||||
return mux
|
||||
}
|
||||
@@ -7,12 +7,12 @@ import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/absmach/magistrala/auth"
|
||||
"github.com/absmach/supermq/auth"
|
||||
"github.com/go-kit/kit/endpoint"
|
||||
)
|
||||
|
||||
func issueEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
return func(ctx context.Context, request any) (any, error) {
|
||||
req := request.(issueKeyReq)
|
||||
if err := req.validate(); err != nil {
|
||||
return nil, err
|
||||
@@ -44,7 +44,7 @@ func issueEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
}
|
||||
|
||||
func retrieveEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
return func(ctx context.Context, request any) (any, error) {
|
||||
req := request.(keyReq)
|
||||
|
||||
if err := req.validate(); err != nil {
|
||||
@@ -71,7 +71,7 @@ func retrieveEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
}
|
||||
|
||||
func revokeEndpoint(svc auth.Service) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
return func(ctx context.Context, request any) (any, error) {
|
||||
req := request.(keyReq)
|
||||
|
||||
if err := req.validate(); err != nil {
|
||||
|
||||
@@ -14,15 +14,15 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/absmach/magistrala/auth"
|
||||
httpapi "github.com/absmach/magistrala/auth/api/http"
|
||||
"github.com/absmach/magistrala/auth/jwt"
|
||||
"github.com/absmach/magistrala/auth/mocks"
|
||||
mglog "github.com/absmach/magistrala/logger"
|
||||
"github.com/absmach/magistrala/pkg/apiutil"
|
||||
svcerr "github.com/absmach/magistrala/pkg/errors/service"
|
||||
policymocks "github.com/absmach/magistrala/pkg/policies/mocks"
|
||||
"github.com/absmach/magistrala/pkg/uuid"
|
||||
apiutil "github.com/absmach/supermq/api/http/util"
|
||||
"github.com/absmach/supermq/auth"
|
||||
httpapi "github.com/absmach/supermq/auth/api/http"
|
||||
"github.com/absmach/supermq/auth/jwt"
|
||||
"github.com/absmach/supermq/auth/mocks"
|
||||
smqlog "github.com/absmach/supermq/logger"
|
||||
svcerr "github.com/absmach/supermq/pkg/errors/service"
|
||||
policymocks "github.com/absmach/supermq/pkg/policies/mocks"
|
||||
"github.com/absmach/supermq/pkg/uuid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
)
|
||||
@@ -37,6 +37,11 @@ const (
|
||||
invalidDuration = 7 * 24 * time.Hour
|
||||
)
|
||||
|
||||
var (
|
||||
krepo *mocks.KeyRepository
|
||||
pEvaluator *policymocks.Evaluator
|
||||
)
|
||||
|
||||
type issueRequest struct {
|
||||
Duration time.Duration `json:"duration,omitempty"`
|
||||
Type uint32 `json:"type,omitempty"`
|
||||
@@ -67,24 +72,25 @@ func (tr testRequest) make() (*http.Response, error) {
|
||||
return tr.client.Do(req)
|
||||
}
|
||||
|
||||
func newService() (auth.Service, *mocks.KeyRepository) {
|
||||
krepo := new(mocks.KeyRepository)
|
||||
drepo := new(mocks.DomainsRepository)
|
||||
func newService() auth.Service {
|
||||
krepo = new(mocks.KeyRepository)
|
||||
pRepo := new(mocks.PATSRepository)
|
||||
cache := new(mocks.Cache)
|
||||
hash := new(mocks.Hasher)
|
||||
idProvider := uuid.NewMock()
|
||||
pService := new(policymocks.Service)
|
||||
pEvaluator := new(policymocks.Evaluator)
|
||||
|
||||
pEvaluator = new(policymocks.Evaluator)
|
||||
t := jwt.New([]byte(secret))
|
||||
|
||||
return auth.New(krepo, drepo, idProvider, t, pEvaluator, pService, loginDuration, refreshDuration, invalidDuration), krepo
|
||||
return auth.New(krepo, pRepo, cache, hash, idProvider, t, pEvaluator, pService, loginDuration, refreshDuration, invalidDuration)
|
||||
}
|
||||
|
||||
func newServer(svc auth.Service) *httptest.Server {
|
||||
mux := httpapi.MakeHandler(svc, mglog.NewMock(), "")
|
||||
mux := httpapi.MakeHandler(svc, smqlog.NewMock(), "")
|
||||
return httptest.NewServer(mux)
|
||||
}
|
||||
|
||||
func toJSON(data interface{}) string {
|
||||
func toJSON(data any) string {
|
||||
jsonData, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
return ""
|
||||
@@ -93,9 +99,11 @@ func toJSON(data interface{}) string {
|
||||
}
|
||||
|
||||
func TestIssue(t *testing.T) {
|
||||
svc, krepo := newService()
|
||||
token, err := svc.Issue(context.Background(), "", auth.Key{Type: auth.AccessKey, IssuedAt: time.Now(), Subject: id})
|
||||
svc := newService()
|
||||
policyCall := pEvaluator.On("CheckPolicy", mock.Anything, mock.Anything).Return(nil)
|
||||
token, err := svc.Issue(context.Background(), "", auth.Key{Type: auth.AccessKey, Role: auth.UserRole, IssuedAt: time.Now(), Subject: id})
|
||||
assert.Nil(t, err, fmt.Sprintf("Issuing login key expected to succeed: %s", err))
|
||||
policyCall.Unset()
|
||||
|
||||
ts := newServer(svc)
|
||||
defer ts.Close()
|
||||
@@ -193,24 +201,28 @@ func TestIssue(t *testing.T) {
|
||||
token: tc.token,
|
||||
body: strings.NewReader(tc.req),
|
||||
}
|
||||
repocall := krepo.On("Save", mock.Anything, mock.Anything).Return("", nil)
|
||||
repoCall := krepo.On("Save", mock.Anything, mock.Anything).Return("", nil)
|
||||
policyCall := pEvaluator.On("CheckPolicy", mock.Anything, mock.Anything).Return(nil)
|
||||
res, err := req.make()
|
||||
assert.Nil(t, err, fmt.Sprintf("%s: unexpected error %s", tc.desc, err))
|
||||
assert.Equal(t, tc.status, res.StatusCode, fmt.Sprintf("%s: expected status code %d got %d", tc.desc, tc.status, res.StatusCode))
|
||||
repocall.Unset()
|
||||
repoCall.Unset()
|
||||
policyCall.Unset()
|
||||
}
|
||||
}
|
||||
|
||||
func TestRetrieve(t *testing.T) {
|
||||
svc, krepo := newService()
|
||||
token, err := svc.Issue(context.Background(), "", auth.Key{Type: auth.AccessKey, IssuedAt: time.Now(), Subject: id})
|
||||
svc := newService()
|
||||
policyCall := pEvaluator.On("CheckPolicy", mock.Anything, mock.Anything).Return(nil)
|
||||
token, err := svc.Issue(context.Background(), "", auth.Key{Type: auth.AccessKey, Role: auth.UserRole, IssuedAt: time.Now(), Subject: id})
|
||||
assert.Nil(t, err, fmt.Sprintf("Issuing login key expected to succeed: %s", err))
|
||||
key := auth.Key{Type: auth.APIKey, IssuedAt: time.Now(), Subject: id}
|
||||
|
||||
repocall := krepo.On("Save", mock.Anything, mock.Anything).Return(mock.Anything, nil)
|
||||
repoCall := krepo.On("Save", mock.Anything, mock.Anything).Return(mock.Anything, nil)
|
||||
k, err := svc.Issue(context.Background(), token.AccessToken, key)
|
||||
assert.Nil(t, err, fmt.Sprintf("Issuing login key expected to succeed: %s", err))
|
||||
repocall.Unset()
|
||||
repoCall.Unset()
|
||||
policyCall.Unset()
|
||||
|
||||
ts := newServer(svc)
|
||||
defer ts.Close()
|
||||
@@ -267,24 +279,28 @@ func TestRetrieve(t *testing.T) {
|
||||
url: fmt.Sprintf("%s/keys/%s", ts.URL, tc.id),
|
||||
token: tc.token,
|
||||
}
|
||||
repocall := krepo.On("Retrieve", mock.Anything, mock.Anything, mock.Anything).Return(tc.key, tc.err)
|
||||
policyCall := pEvaluator.On("CheckPolicy", mock.Anything, mock.Anything).Return(nil)
|
||||
repoCall := krepo.On("Retrieve", mock.Anything, mock.Anything, mock.Anything).Return(tc.key, tc.err)
|
||||
res, err := req.make()
|
||||
assert.Nil(t, err, fmt.Sprintf("%s: unexpected error %s", tc.desc, err))
|
||||
assert.Equal(t, tc.status, res.StatusCode, fmt.Sprintf("%s: expected status code %d got %d", tc.desc, tc.status, res.StatusCode))
|
||||
repocall.Unset()
|
||||
repoCall.Unset()
|
||||
policyCall.Unset()
|
||||
}
|
||||
}
|
||||
|
||||
func TestRevoke(t *testing.T) {
|
||||
svc, krepo := newService()
|
||||
token, err := svc.Issue(context.Background(), "", auth.Key{Type: auth.AccessKey, IssuedAt: time.Now(), Subject: id})
|
||||
svc := newService()
|
||||
policyCall := pEvaluator.On("CheckPolicy", mock.Anything, mock.Anything).Return(nil)
|
||||
token, err := svc.Issue(context.Background(), "", auth.Key{Type: auth.AccessKey, Role: auth.UserRole, IssuedAt: time.Now(), Subject: id})
|
||||
assert.Nil(t, err, fmt.Sprintf("Issuing login key expected to succeed: %s", err))
|
||||
key := auth.Key{Type: auth.APIKey, IssuedAt: time.Now(), Subject: id}
|
||||
|
||||
repocall := krepo.On("Save", mock.Anything, mock.Anything).Return(mock.Anything, nil)
|
||||
repoCall := krepo.On("Save", mock.Anything, mock.Anything).Return(mock.Anything, nil)
|
||||
k, err := svc.Issue(context.Background(), token.AccessToken, key)
|
||||
assert.Nil(t, err, fmt.Sprintf("Issuing login key expected to succeed: %s", err))
|
||||
repocall.Unset()
|
||||
repoCall.Unset()
|
||||
policyCall.Unset()
|
||||
|
||||
ts := newServer(svc)
|
||||
defer ts.Close()
|
||||
@@ -329,10 +345,10 @@ func TestRevoke(t *testing.T) {
|
||||
url: fmt.Sprintf("%s/keys/%s", ts.URL, tc.id),
|
||||
token: tc.token,
|
||||
}
|
||||
repocall := krepo.On("Remove", mock.Anything, mock.Anything, mock.Anything).Return(nil)
|
||||
repoCall := krepo.On("Remove", mock.Anything, mock.Anything, mock.Anything).Return(nil)
|
||||
res, err := req.make()
|
||||
assert.Nil(t, err, fmt.Sprintf("%s: unexpected error %s", tc.desc, err))
|
||||
assert.Equal(t, tc.status, res.StatusCode, fmt.Sprintf("%s: expected status code %d got %d", tc.desc, tc.status, res.StatusCode))
|
||||
repocall.Unset()
|
||||
repoCall.Unset()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@ package keys
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/absmach/magistrala/auth"
|
||||
"github.com/absmach/magistrala/pkg/apiutil"
|
||||
apiutil "github.com/absmach/supermq/api/http/util"
|
||||
"github.com/absmach/supermq/auth"
|
||||
)
|
||||
|
||||
type issueKeyReq struct {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user