@continuoussecuritytooling/keycloak-reporter 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.docs/realm-config.json +0 -0
- package/.github/FUNDING.yml +2 -1
- package/.github/workflows/pipeline.yml +33 -15
- package/.github/workflows/release.yml +6 -6
- package/CHANGELOG.md +92 -11
- package/Dockerfile +1 -1
- package/README.md +4 -1
- package/charts/keycloak-reporter/Chart.yaml +3 -3
- package/charts/keycloak-reporter/README.md +1 -1
- package/charts/keycloak-reporter/ci.values.yaml +13 -0
- package/charts/keycloak-reporter/templates/cronjob.yaml +4 -5
- package/charts/keycloak-reporter/templates/tests/test-connection.yaml +57 -0
- package/cli.ts +8 -1
- package/dist/cli.js +132 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/schema.json +70 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/client.js +24 -0
- package/dist/lib/client.js.map +1 -0
- package/dist/lib/convert.js +9 -0
- package/dist/lib/convert.js.map +1 -0
- package/dist/lib/output.js +113 -0
- package/dist/lib/output.js.map +1 -0
- package/dist/lib/user.js +110 -0
- package/dist/lib/user.js.map +1 -0
- package/dist/src/commands.js +30 -0
- package/dist/src/commands.js.map +1 -0
- package/dist/src/config.js +48 -0
- package/dist/src/config.js.map +1 -0
- package/e2e/spec/clients.js +1 -1
- package/e2e/spec/config.js +25 -1
- package/e2e/spec/users.js +1 -1
- package/index.ts +2 -2
- package/keycloak-reporter-1.2.1.tgz +0 -0
- package/package.json +2 -2
- package/src/commands.ts +10 -0
- package/src/config.ts +1 -0
|
File without changes
|
package/.github/FUNDING.yml
CHANGED
|
@@ -18,6 +18,7 @@ jobs:
|
|
|
18
18
|
node_version:
|
|
19
19
|
- 18
|
|
20
20
|
- 20
|
|
21
|
+
- 21
|
|
21
22
|
os:
|
|
22
23
|
- ubuntu-latest
|
|
23
24
|
- macOS-latest
|
|
@@ -49,13 +50,13 @@ jobs:
|
|
|
49
50
|
with:
|
|
50
51
|
version: v3.11.2
|
|
51
52
|
|
|
52
|
-
- uses: actions/setup-python@
|
|
53
|
+
- uses: actions/setup-python@v5
|
|
53
54
|
with:
|
|
54
55
|
python-version: '3.9'
|
|
55
56
|
check-latest: true
|
|
56
57
|
|
|
57
58
|
- name: Helm Chart Testing
|
|
58
|
-
uses: helm/chart-testing-action@v2.6.
|
|
59
|
+
uses: helm/chart-testing-action@v2.6.1
|
|
59
60
|
|
|
60
61
|
- name: Run chart-testing (list-changed)
|
|
61
62
|
id: list-changed
|
|
@@ -73,11 +74,15 @@ jobs:
|
|
|
73
74
|
if: steps.list-changed.outputs.changed == 'true'
|
|
74
75
|
uses: helm/kind-action@v1.8.0
|
|
75
76
|
|
|
76
|
-
- name: Run chart-testing (install)
|
|
77
|
+
- name: Run chart-testing (install - no further args)
|
|
77
78
|
if: steps.list-changed.outputs.changed == 'true'
|
|
78
|
-
run: ct install --target-branch ${{ github.event.repository.default_branch }} --helm-extra-set-args "--set 'keycloak.config.url=http://localhost:8080' --set 'keycloak.config.url=http://localhost:8080' --set 'keycloak.config.clientId=clientId' --set 'keycloak.config.clientSecret=clientSecret'
|
|
79
|
+
run: ct install --target-branch ${{ github.event.repository.default_branch }} --helm-extra-set-args "--set 'keycloak.config.url=http://localhost:8080' --set 'keycloak.config.url=http://localhost:8080' --set 'keycloak.config.clientId=clientId' --set 'keycloak.config.clientSecret=clientSecret'"
|
|
79
80
|
|
|
80
|
-
-
|
|
81
|
+
- name: Run chart-testing (install - with args)
|
|
82
|
+
if: steps.list-changed.outputs.changed == 'true'
|
|
83
|
+
run: ct install --target-branch ${{ github.event.repository.default_branch }} --helm-extra-set-args "-f charts/keycloak-reporter/ci.values.yaml"
|
|
84
|
+
|
|
85
|
+
- uses: actions/upload-artifact@v4
|
|
81
86
|
with:
|
|
82
87
|
name: dist-folder
|
|
83
88
|
path: dist
|
|
@@ -89,6 +94,8 @@ jobs:
|
|
|
89
94
|
matrix:
|
|
90
95
|
node_version:
|
|
91
96
|
- 18
|
|
97
|
+
- 20
|
|
98
|
+
- 21
|
|
92
99
|
os:
|
|
93
100
|
- ubuntu-latest
|
|
94
101
|
steps:
|
|
@@ -98,7 +105,7 @@ jobs:
|
|
|
98
105
|
with:
|
|
99
106
|
node-version: '${{ matrix.node_version }}'
|
|
100
107
|
- name: Install Java
|
|
101
|
-
uses: actions/setup-java@
|
|
108
|
+
uses: actions/setup-java@v4
|
|
102
109
|
with:
|
|
103
110
|
distribution: 'temurin' # See 'Supported distributions' for available options
|
|
104
111
|
java-version: '17'
|
|
@@ -136,7 +143,7 @@ jobs:
|
|
|
136
143
|
- uses: actions/setup-node@v4
|
|
137
144
|
with:
|
|
138
145
|
# renovate: datasource=docker depName=node
|
|
139
|
-
node-version: '
|
|
146
|
+
node-version: '20'
|
|
140
147
|
- name: 'Build Package'
|
|
141
148
|
run: |
|
|
142
149
|
npm run clean
|
|
@@ -145,10 +152,11 @@ jobs:
|
|
|
145
152
|
- name: Write version vars
|
|
146
153
|
run: |
|
|
147
154
|
BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"`
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
echo
|
|
151
|
-
echo "APP_VERSION
|
|
155
|
+
BRANCH=${GITHUB_REF_NAME#v}
|
|
156
|
+
APP_VERSION=$(cat package.json | grep version| head -1 | awk -F: '{ print $2 }' | sed 's/[",]//g')
|
|
157
|
+
echo Version: $APP_VERSION
|
|
158
|
+
echo "VERSION=$APP_VERSION" >> $GITHUB_ENV
|
|
159
|
+
echo "APP_VERSION=$APP_VERSION" >> $GITHUB_ENV
|
|
152
160
|
echo "BUILD_DATE=$BUILD_DATE" >> $GITHUB_ENV
|
|
153
161
|
|
|
154
162
|
- name: Build Container Image
|
|
@@ -156,19 +164,29 @@ jobs:
|
|
|
156
164
|
uses: redhat-actions/buildah-build@v2
|
|
157
165
|
with:
|
|
158
166
|
image: continuoussecuritytooling/keycloak-reporting-cli
|
|
159
|
-
tags: '
|
|
167
|
+
tags: 'latest next ${{env.APP_VERSION}} ${{env.APP_VERSION}}_rc'
|
|
160
168
|
containerfiles: |
|
|
161
169
|
./Dockerfile
|
|
162
170
|
build-args: |
|
|
163
171
|
BUILD_DATE=${{env.BUILD_DATE}}
|
|
164
172
|
APP_VERSION=${{env.APP_VERSION}}
|
|
165
173
|
|
|
174
|
+
- name: Push To NPM Registry
|
|
175
|
+
id: push-to-npm-tagged
|
|
176
|
+
env:
|
|
177
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}
|
|
178
|
+
run: |
|
|
179
|
+
echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc
|
|
180
|
+
(cd core && npm i && npm publish)
|
|
181
|
+
(cd cli && npm i && npm publish)
|
|
182
|
+
if: github.ref_type == 'tag' || github.tag != ''
|
|
183
|
+
|
|
166
184
|
- name: Push To Docker Hub
|
|
167
185
|
id: push-to-dockerhub-preview
|
|
168
186
|
uses: redhat-actions/push-to-registry@v2
|
|
169
187
|
with:
|
|
170
188
|
image: ${{ steps.build-image.outputs.image }}
|
|
171
|
-
tags: ${{
|
|
189
|
+
tags: 'next ${{env.APP_VERSION}}_rc'
|
|
172
190
|
registry: registry.hub.docker.com
|
|
173
191
|
username: continuoussecuritytooling
|
|
174
192
|
password: ${{ secrets.DOCKER_HUB_TOKEN }}
|
|
@@ -179,8 +197,8 @@ jobs:
|
|
|
179
197
|
uses: redhat-actions/push-to-registry@v2
|
|
180
198
|
with:
|
|
181
199
|
image: ${{ steps.build-image.outputs.image }}
|
|
182
|
-
tags: latest ${
|
|
200
|
+
tags: 'latest ${{env.APP_VERSION}}'
|
|
183
201
|
registry: registry.hub.docker.com
|
|
184
202
|
username: continuoussecuritytooling
|
|
185
203
|
password: ${{ secrets.DOCKER_HUB_TOKEN }}
|
|
186
|
-
if: github.ref_type == 'tag'
|
|
204
|
+
if: github.ref_type == 'tag' || github.tag != ''
|
|
@@ -26,22 +26,21 @@ jobs:
|
|
|
26
26
|
- name: Install Helm
|
|
27
27
|
uses: azure/setup-helm@v3
|
|
28
28
|
- name: Install Python
|
|
29
|
-
uses: actions/setup-python@
|
|
29
|
+
uses: actions/setup-python@v5
|
|
30
30
|
with:
|
|
31
31
|
python-version: '3.9'
|
|
32
32
|
check-latest: true
|
|
33
33
|
- name: Set up chart-testing
|
|
34
|
-
uses: helm/chart-testing-action@v2.6.
|
|
34
|
+
uses: helm/chart-testing-action@v2.6.1
|
|
35
35
|
|
|
36
36
|
- name: Run chart-testing (lint)
|
|
37
|
-
run: ct lint --config .ct.yaml
|
|
37
|
+
run: ct lint --config .ct.yaml
|
|
38
38
|
|
|
39
39
|
- name: Run chart-releaser
|
|
40
|
-
uses: helm/chart-releaser-action@v1.
|
|
41
|
-
with:
|
|
42
|
-
charts_dir: charts/
|
|
40
|
+
uses: helm/chart-releaser-action@v1.6.0
|
|
43
41
|
env:
|
|
44
42
|
CR_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
|
|
43
|
+
CR_GENERATE_RELEASE_NOTES: true
|
|
45
44
|
|
|
46
45
|
- name: Login to GitHub Container Registry
|
|
47
46
|
run: |
|
|
@@ -49,6 +48,7 @@ jobs:
|
|
|
49
48
|
|
|
50
49
|
- name: Push Charts to GHCR
|
|
51
50
|
run: |
|
|
51
|
+
shopt -s nullglob
|
|
52
52
|
for pkg in .cr-release-packages/*; do
|
|
53
53
|
if [ -z "${pkg:-}" ]; then
|
|
54
54
|
break
|
package/CHANGELOG.md
CHANGED
|
@@ -1,22 +1,103 @@
|
|
|
1
|
-
# 0.2.0 (2023-
|
|
1
|
+
# [0.8.0](https://github.com/ContinuousSecurityTooling/keycloak-reporter/compare/v0.7.2...v0.8.0) (2023-12-14)
|
|
2
|
+
|
|
3
|
+
### Features
|
|
4
|
+
|
|
5
|
+
* **Config:** Adding config validation and helm test hook ([c29e945](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/c29e945567b4dfcdc9a10e710efa2b1a8c00f970))
|
|
6
|
+
|
|
7
|
+
### Bug Fixes
|
|
8
|
+
|
|
9
|
+
* **deps:** update dependency @continuoussecuritytooling/keycloak-auditor to v1.1.2 ([2b985d5](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/2b985d5daa4d271bf4a1219b6df71b16515b4106))
|
|
10
|
+
* **deps:** update dependency @continuoussecuritytooling/keycloak-auditor to v1.1.3 ([2ed9c0f](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/2ed9c0faff14bc7d43b5e739a48e7175c1e74c4c))
|
|
11
|
+
* **deps:** update dependency @json2csv/node to v7.0.4 ([2488240](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/2488240525fd1d8c20cf5205be50c069e6ac0cd1))
|
|
12
|
+
* **deps:** update dependency @keycloak/keycloak-admin-client to v23 ([12e4485](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/12e4485a0e4c508cc90fe86d3ab39efb647486ce))
|
|
13
|
+
* **deps:** update dependency @keycloak/keycloak-admin-client to v23.0.1 ([babdf78](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/babdf78ce6b0f2736ce6703cb83338e37066639b))
|
|
14
|
+
* **deps:** update dependency npm to v10.2.4 ([8529acf](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/8529acf82bf8ea1581c7510783087ba5d8d45dde))
|
|
15
|
+
* **deps:** update dependency npm to v10.2.5 ([52a3c8b](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/52a3c8b48cbf0ee0d795aa00a9af36291025ae05))
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
## [0.7.2](https://github.com/ContinuousSecurityTooling/keycloak-reporter/compare/v0.7.1...v0.7.2) (2023-11-16)
|
|
2
20
|
|
|
3
21
|
|
|
4
22
|
### Bug Fixes
|
|
5
23
|
|
|
6
|
-
*
|
|
7
|
-
|
|
8
|
-
|
|
24
|
+
* Try to fix release ([ed7ebdf](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/ed7ebdf6ca9677621d19d8f829f611183602135f))
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
## [0.7.1](https://github.com/ContinuousSecurityTooling/keycloak-reporter/compare/v0.7.0...v0.7.1) (2023-11-16)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
### Bug Fixes
|
|
32
|
+
|
|
33
|
+
* **deps:** update dependency @continuoussecuritytooling/keycloak-auditor to v1.1.1 ([4fb7c58](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/4fb7c5801f8d5519d6c7132eabd29976e640cff3))
|
|
34
|
+
* **deps:** update dependency @slack/webhook to v7.0.1 ([1c46ccf](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/1c46ccf7f9a91c4fc85464ddfe9aea8f8e588801))
|
|
35
|
+
* **deps:** update dependency npm to v10.2.3 ([a42ac5c](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/a42ac5c5df195d5e9b15595bb377261f53acca03))
|
|
9
36
|
|
|
10
37
|
|
|
11
38
|
### Features
|
|
12
39
|
|
|
13
|
-
*
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
40
|
+
* Using NodeJS 20 as default ([ba468cf](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/ba468cfa7e17615a38ea5ea7e81c859e1f734f67))
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
# [0.7.0](https://github.com/ContinuousSecurityTooling/keycloak-reporter/compare/v0.6.0...v0.7.0) (2023-11-02)
|
|
45
|
+
|
|
46
|
+
|
|
20
47
|
|
|
48
|
+
# [0.6.0](https://github.com/ContinuousSecurityTooling/keycloak-reporter/compare/4c13fa0642d75b8e229091aca052a83fa8c7eb32...v0.6.0) (2023-11-01)
|
|
21
49
|
|
|
22
50
|
|
|
51
|
+
### Bug Fixes
|
|
52
|
+
|
|
53
|
+
* **Build:** ci health workflow network fix and setup JDK ([9878cac](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/9878cacd99b8c7a66c9c2f7e26d9087f48b809fe))
|
|
54
|
+
* **Chart:** Add only non-empty strings to secret ([eef4332](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/eef433203f33a14a322ecb0a46cd2701ef454eec))
|
|
55
|
+
* **Chart:** Correct default values for install ([50e9b5c](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/50e9b5ccbaeec2661b16cf2d6d959fc66231f21e))
|
|
56
|
+
* **Config:** Adding proper error handling for missing webhook URL ([1515b3d](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/1515b3dde0ec387ec226f8d5fe1ffd4f3a4af00d))
|
|
57
|
+
* **Config:** Correcting handling for auditor endpoint toogle ([d332e13](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/d332e13667e5ff770e2d5dcb1374730dcc896527))
|
|
58
|
+
* **Config:** Let config file overwrite defaults ([2df34a0](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/2df34a047ef8c2275f8ae4ef0d06209c1619d74e))
|
|
59
|
+
* Correct ref error ([2098b15](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/2098b1531e20d2037252f706713e4dd54a620128))
|
|
60
|
+
* Corrected missing variable ([3223ea3](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/3223ea31d33cad3ad7fd8d4b574ed88a737ced81))
|
|
61
|
+
* Corrected renovate config ([af1bd4a](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/af1bd4a6c4c8678d4a4b2ffc97c41b583986f513))
|
|
62
|
+
* **deps:** update dependency @json2csv/node to v7 ([42934da](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/42934da57a546b1a0db324183b3db51c27ff1cc2))
|
|
63
|
+
* **deps:** update dependency @json2csv/node to v7.0.1 ([b0aeb36](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/b0aeb366b07a38d8b648b4a0c763bab578db653a))
|
|
64
|
+
* **deps:** update dependency @json2csv/node to v7.0.2 ([bcca826](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/bcca8267291c79e13dc1bd563d80d59d1d6d0f27))
|
|
65
|
+
* **deps:** update dependency @json2csv/node to v7.0.3 ([e61eaf2](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/e61eaf2b12243cc10903ac6235e03de78e6c4ae7))
|
|
66
|
+
* **deps:** update dependency @keycloak/keycloak-admin-client to v22 ([cf5caac](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/cf5caac67d0a35b56e7c7a16dd5ee815aaf96d6c))
|
|
67
|
+
* **deps:** update dependency @keycloak/keycloak-admin-client to v22.0.4 ([608703c](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/608703ce5f7d6c05c76eb88296c19e34eee20137))
|
|
68
|
+
* **deps:** update dependency @keycloak/keycloak-admin-client to v22.0.5 ([e56d8ad](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/e56d8ada3b1b7e3ce0a456190f1d4a549309480c))
|
|
69
|
+
* **deps:** update dependency @slack/webhook to v7 ([87872b5](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/87872b5bf56877ace56b49e9b70ace6fd90778a2))
|
|
70
|
+
* **deps:** update dependency npm to v10 ([ff38e4f](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/ff38e4faa13b34d7794b9b36f46d11d61fdc90bf))
|
|
71
|
+
* **deps:** update dependency npm to v10.1.0 ([48bf21a](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/48bf21ae8c251993295901f75150580f3b2a9988))
|
|
72
|
+
* **deps:** update dependency npm to v10.2.0 ([203c3f0](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/203c3f03a25838e52dea15eefd564490ba137c2f))
|
|
73
|
+
* **deps:** update dependency npm to v10.2.1 ([1544ee5](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/1544ee58ce2cd0e6f1951d45ce77a4cbaf2b0fac))
|
|
74
|
+
* **deps:** update dependency npm to v9.7.1 ([1eeaf8f](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/1eeaf8fc51a643da62d46e0669751f732069ee3d))
|
|
75
|
+
* **deps:** update dependency openid-client to v5.4.3 ([6cc9fba](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/6cc9fba92585393bb50cc586a8a7f994b8a6431c))
|
|
76
|
+
* **deps:** update dependency openid-client to v5.5.0 ([efebce8](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/efebce81d16b95e9407bff874a62c5832bdc826e))
|
|
77
|
+
* **deps:** update dependency openid-client to v5.6.0 ([b9020b8](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/b9020b82786a5f5ead45262b756c09a58ff4eb3a))
|
|
78
|
+
* **deps:** update dependency openid-client to v5.6.1 ([ce75f52](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/ce75f527b58f3b3e0de240a0933f3bec79ddd7e1))
|
|
79
|
+
* **deps:** update dependency ramda to v0.29.1 ([015da4c](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/015da4c065810d4aeb3d19b3fbc55633f39ba6af))
|
|
80
|
+
* Fix chart deploy ([0f95f78](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/0f95f78cfcb98cac3da5b8c2bdf84c7bca324d57))
|
|
81
|
+
* **Kubernetes:** Adjust helm chart config error ([f074b0e](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/f074b0eca275e8ee07e0dad6096cd64962dcae80))
|
|
82
|
+
* Stick to NodeJS 16 ([595d799](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/595d799510e81de885430d7cc62549dd8a272aee))
|
|
83
|
+
* **Webhooks:** Corrected error handling ([afe2c60](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/afe2c601852ef5564fcaafe6b959475a4271a9ec))
|
|
84
|
+
* **Webhooks:** Correcting webhook additional message handling and improve error handling ([1fe6fdf](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/1fe6fdf3d93dd746c55ea3009a8414cfe3206d2f))
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
### Features
|
|
88
|
+
|
|
89
|
+
* Adding report directory support for archiving ([9347ef1](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/9347ef116b8d753b21e66826792865971ce7571d))
|
|
90
|
+
* Allow chart to pass env vars ([37b19b4](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/37b19b428a07c373f308aee529a1ff376b87156e))
|
|
91
|
+
* **API:** Use audit endpoint ([8ed489a](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/8ed489ae0c3e6b66f8506a6d6b87147e50b9a06c))
|
|
92
|
+
* **Config:** Provide config file functionality ([f9097f9](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/f9097f966c2dfc5240111e9294742ad3821c36ad))
|
|
93
|
+
* **Config:** Use config file in helm chart ([21e0512](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/21e051243df1a3000d2b57f6ee0feab5f6314910))
|
|
94
|
+
* **Helm:** Adding OCI helm chart support ([4b3d433](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/4b3d433e2b94550541b821172c7d270abf2363fa))
|
|
95
|
+
* **Helm:** Initial chart version ([401c740](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/401c7401b1b34b479bb5a370c9d1077a36f653b0)), closes [#1](https://github.com/ContinuousSecurityTooling/keycloak-reporter/issues/1)
|
|
96
|
+
* **OCI:** Use OCI standard labels for container image ([3371f13](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/3371f136f51fa0482c253602b281ed508473ed44))
|
|
97
|
+
* **Report:** Adding id to report ([8dbc3d4](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/8dbc3d4deacba0a5e1729da93b8d933557ebd45b))
|
|
98
|
+
* **Security:** apt-upgrade in docker image ([3ac8217](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/3ac82179fcdcec5ff72179e1f33f5e0e9c50c45f))
|
|
99
|
+
* **Security:** Hardening deployment with security config ([3d9fdec](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/3d9fdec7174bc5287b7c382d4aec8207051d3a11))
|
|
100
|
+
* **Testing:** Adding end2end testing via keycloak local ([036202f](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/036202f47324e8b3e40764fdc3a43a270a2687cf))
|
|
101
|
+
* **Users:** Adding user and client listing functionality ([4c13fa0](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/4c13fa0642d75b8e229091aca052a83fa8c7eb32))
|
|
102
|
+
* **Webhook:** Allow custom text for message ([1707e24](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/1707e249c1c9c4c22b1510c767470a2670a4b33b))
|
|
103
|
+
* **Webhooks:** Adding Support for Teams and Slack ([66da168](https://github.com/ContinuousSecurityTooling/keycloak-reporter/commit/66da168d2cd234ebc6dd961cfe62a3c8191c0ccc)), closes [#2](https://github.com/ContinuousSecurityTooling/keycloak-reporter/issues/2)
|
package/Dockerfile
CHANGED
package/README.md
CHANGED
|
@@ -65,6 +65,9 @@ To install the Helm Chart use the [OCI Package Registry](https://github.com/orgs
|
|
|
65
65
|
helm install keycloak-reporter oci://ghcr.io/cloudtooling/helm-charts
|
|
66
66
|
```
|
|
67
67
|
|
|
68
|
+
>**NOTE**
|
|
69
|
+
>Keep in mind, that you need a client/service account in keycloak with the appropriate rights. You can use this [template](.docs/realm-config.json) to deploy with [keycloak-config-cli](https://github.com/adorsys/keycloak-config-cli) a service account.
|
|
70
|
+
|
|
68
71
|
### Config file
|
|
69
72
|
|
|
70
73
|
You can also provider a config file via env var `CONFIG_FILE` and then just provide the commands, e.g.:
|
|
@@ -86,4 +89,4 @@ And for Teams:
|
|
|
86
89
|
kc-reporter listUsers <Keycloak_Root_URL> <Client_ID> <Client_Secret> --format=json --output=webhook --webhookType=teams --webhookUrl=$WEBHOOK_TESTING_TEAMS
|
|
87
90
|
```
|
|
88
91
|
the following entry in slack will be created:
|
|
89
|
-

|
|
92
|
+

|
|
@@ -15,14 +15,14 @@ type: application
|
|
|
15
15
|
# This is the chart version. This version number should be incremented each time you make changes
|
|
16
16
|
# to the chart and its templates, including the app version.
|
|
17
17
|
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
|
18
|
-
version: 1.1
|
|
18
|
+
version: 1.2.1
|
|
19
19
|
|
|
20
20
|
# This is the version number of the application being deployed. This version number should be
|
|
21
21
|
# incremented each time you make changes to the application. Versions are not expected to
|
|
22
22
|
# follow Semantic Versioning. They should reflect the version the application is using.
|
|
23
23
|
# It is recommended to use it with quotes.
|
|
24
|
-
# renovate: datasource=
|
|
25
|
-
appVersion: '0.
|
|
24
|
+
# renovate: datasource=docker depName=ContinuousSecurityTooling/keycloak-reporter
|
|
25
|
+
appVersion: '0.8.0'
|
|
26
26
|
maintainers:
|
|
27
27
|
# Martin Reinhardt
|
|
28
28
|
- name: hypery2k
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# keycloak-reporter
|
|
2
2
|
|
|
3
|
-
  
|
|
4
4
|
|
|
5
5
|
Keycloak user and client reporting tool for automated regular access checks.
|
|
6
6
|
|
|
@@ -18,7 +18,6 @@ spec:
|
|
|
18
18
|
imagePullSecrets:
|
|
19
19
|
{{- toYaml . | nindent 12 }}
|
|
20
20
|
{{- end }}
|
|
21
|
-
# automountServiceAccountToken: false # fix KubernetesClustersShouldDisableAutomountingAPICredentialsMonitoringEffect OPA policy
|
|
22
21
|
serviceAccountName: {{ default "default" ($.Values.serviceAccount).name }}
|
|
23
22
|
securityContext:
|
|
24
23
|
{{- toYaml $.Values.podSecurityContext | nindent 12 }}
|
|
@@ -28,14 +27,14 @@ spec:
|
|
|
28
27
|
imagePullPolicy: {{ $.Values.image.pullPolicy }}
|
|
29
28
|
command:
|
|
30
29
|
- node
|
|
31
|
-
- /app/cli.js
|
|
30
|
+
- /app/cli.js
|
|
32
31
|
- {{ $config.script }}
|
|
33
32
|
env:
|
|
34
33
|
- name: CONFIG_FILE
|
|
35
34
|
value: "/app/config.json"
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
{{- with $.Values.env }}
|
|
36
|
+
{{- tpl (toYaml .) $ | nindent 16 }}
|
|
37
|
+
{{- end }}
|
|
39
38
|
{{- if $.Values.resources }}
|
|
40
39
|
resources:
|
|
41
40
|
{{- toYaml $.Values.resources | nindent 16 }}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{{- $fullName := include "keycloak-reporter.fullname" . }}
|
|
2
|
+
apiVersion: v1
|
|
3
|
+
kind: Pod
|
|
4
|
+
metadata:
|
|
5
|
+
name: {{ printf "%s-test-connection" $fullName }}
|
|
6
|
+
annotations:
|
|
7
|
+
helm.sh/hook: test
|
|
8
|
+
helm.sh/hook-delete-policy: "hook-succeeded,before-hook-creation"
|
|
9
|
+
helm.sh/hook-weight: "5"
|
|
10
|
+
spec:
|
|
11
|
+
containers:
|
|
12
|
+
- name: config-test
|
|
13
|
+
image: "{{ $.Values.image.repository }}:{{ $.Values.image.tag | default $.Chart.AppVersion }}"
|
|
14
|
+
imagePullPolicy: {{ $.Values.image.pullPolicy }}
|
|
15
|
+
command:
|
|
16
|
+
- node
|
|
17
|
+
- /app/cli.js
|
|
18
|
+
- configTest
|
|
19
|
+
env:
|
|
20
|
+
- name: CONFIG_FILE
|
|
21
|
+
value: "/app/config.json"
|
|
22
|
+
{{- with $.Values.env }}
|
|
23
|
+
{{- tpl (toYaml .) $ | nindent 8 }}
|
|
24
|
+
{{- end }}
|
|
25
|
+
{{- if $.Values.resources }}
|
|
26
|
+
resources:
|
|
27
|
+
{{- toYaml $.Values.resources | nindent 10 }}
|
|
28
|
+
{{- end }}
|
|
29
|
+
securityContext:
|
|
30
|
+
{{- toYaml $.Values.securityContext | nindent 10 }}
|
|
31
|
+
volumeMounts:
|
|
32
|
+
- name: config-file
|
|
33
|
+
mountPath: "/app/config.json"
|
|
34
|
+
subPath: "config.json"
|
|
35
|
+
readOnly: true
|
|
36
|
+
{{- if ($.Values.keycloak.config.volumes).reports }}
|
|
37
|
+
- name: reports-dir
|
|
38
|
+
mountPath: "/app/reports"
|
|
39
|
+
{{- end }}
|
|
40
|
+
{{- if $.Values.nodeSelector }}
|
|
41
|
+
nodeSelector:
|
|
42
|
+
{{ toYaml $.Values.nodeSelector | nindent 4 }}
|
|
43
|
+
{{- end }}
|
|
44
|
+
{{- if $.Values.tolerations }}
|
|
45
|
+
tolerations:
|
|
46
|
+
{{ toYaml $.Values.tolerations | nindent 4 }}
|
|
47
|
+
{{- end }}
|
|
48
|
+
volumes:
|
|
49
|
+
- name: config-file
|
|
50
|
+
secret:
|
|
51
|
+
secretName: {{ $fullName }}
|
|
52
|
+
{{- if ($.Values.keycloak.config.volumes).reports }}
|
|
53
|
+
- name: reports-dir
|
|
54
|
+
persistentVolumeClaim:
|
|
55
|
+
claimName: {{ $fullName }}-reports
|
|
56
|
+
{{- end }}
|
|
57
|
+
restartPolicy: Never
|
package/cli.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { writeFileSync } from 'node:fs';
|
|
|
4
4
|
import path from 'path';
|
|
5
5
|
import yargs from 'yargs/yargs';
|
|
6
6
|
import { hideBin } from 'yargs/helpers';
|
|
7
|
-
import { listUsers, listClients, Options, convertJSON2CSV, post2Webhook } from './index.js';
|
|
7
|
+
import { configTest, listUsers, listClients, Options, convertJSON2CSV, post2Webhook } from './index.js';
|
|
8
8
|
import config from './src/config.js';
|
|
9
9
|
class WebhookConfig {
|
|
10
10
|
type: string;
|
|
@@ -161,4 +161,11 @@ yargs(hideBin(process.argv))
|
|
|
161
161
|
default: false,
|
|
162
162
|
description: 'use auditior rest endpoint',
|
|
163
163
|
})
|
|
164
|
+
.command(
|
|
165
|
+
'configTest [url] [clientId] [clientSecret]',
|
|
166
|
+
'validates keycloak configuration by reading data via REST API',
|
|
167
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
168
|
+
() => {},
|
|
169
|
+
async (argv) => configTest(getKeycloakConfig(config, argv)),
|
|
170
|
+
)
|
|
164
171
|
.parse();
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { writeFileSync } from 'node:fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import yargs from 'yargs/yargs';
|
|
5
|
+
import { hideBin } from 'yargs/helpers';
|
|
6
|
+
import { configTest, listUsers, listClients, convertJSON2CSV, post2Webhook } from './index.js';
|
|
7
|
+
import config from './src/config.js';
|
|
8
|
+
class WebhookConfig {
|
|
9
|
+
constructor(type, url, title, message) {
|
|
10
|
+
this.type = type;
|
|
11
|
+
this.url = url;
|
|
12
|
+
this.title = title;
|
|
13
|
+
this.message = message;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
class ReportConfig {
|
|
17
|
+
}
|
|
18
|
+
function getKeycloakConfig(config, argv) {
|
|
19
|
+
return {
|
|
20
|
+
clientId: config.clientId ? config.clientId : argv.clientId,
|
|
21
|
+
clientSecret: config.clientSecret ? config.clientSecret : argv.clientSecret,
|
|
22
|
+
rootUrl: config.url ? config.url : argv.url,
|
|
23
|
+
useAuditingEndpoint: argv.useAuditingEndpoint == true || config.useAuditingEndpoint.toLowerCase() == 'true',
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function convertData(config, argv, name, title, json) {
|
|
27
|
+
convert(config.format ? config.format : argv.format, config.output ? config.output : argv.output, {
|
|
28
|
+
name,
|
|
29
|
+
directory: argv.reports ? argv.reports : config.reports,
|
|
30
|
+
}, new WebhookConfig(config.webhookType ? config.webhookType : argv.webhookType, config.webhookUrl ? config.webhookUrl : argv.webhookUrl, title, config.webhookMessage ? config.webhookMessage : argv.webhookMessage), json);
|
|
31
|
+
}
|
|
32
|
+
async function convert(format, output, reports, config, json) {
|
|
33
|
+
let outputContent;
|
|
34
|
+
switch (format) {
|
|
35
|
+
case 'csv':
|
|
36
|
+
outputContent = (await convertJSON2CSV(json)).toString();
|
|
37
|
+
break;
|
|
38
|
+
// defaulting to JSON
|
|
39
|
+
default:
|
|
40
|
+
outputContent = JSON.stringify(json);
|
|
41
|
+
}
|
|
42
|
+
if (reports.directory) {
|
|
43
|
+
const date = new Date();
|
|
44
|
+
writeFileSync(path.join(`${reports.directory}`, `${reports.name}_${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}.${format.toLowerCase()}`), outputContent);
|
|
45
|
+
}
|
|
46
|
+
switch (output) {
|
|
47
|
+
case 'webhook':
|
|
48
|
+
if (!config.url) {
|
|
49
|
+
console.error('No valid Webhook URL given');
|
|
50
|
+
throw new Error('Please provide a valid --webhookUrl parameter');
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
console.log(`Sending report via webhook to ${config.type} ....`);
|
|
54
|
+
await post2Webhook(config.type, config.url, config.title, outputContent, config.message);
|
|
55
|
+
console.log('Done sending.');
|
|
56
|
+
}
|
|
57
|
+
catch (e) {
|
|
58
|
+
switch (e.code || e.message) {
|
|
59
|
+
case 'Request failed with status code 400':
|
|
60
|
+
console.error('Invalid Teams Webhook Payload. Check your params.');
|
|
61
|
+
throw new Error('Invalid Teams Payload');
|
|
62
|
+
case 'slack_webhook_http_error':
|
|
63
|
+
console.error('Invalid Slack Webhook Payload. Check your params.');
|
|
64
|
+
throw new Error('Invalid Slack Payload');
|
|
65
|
+
default:
|
|
66
|
+
console.error(`Error during sending webhook.(${e === null || e === void 0 ? void 0 : e.code})`, e === null || e === void 0 ? void 0 : e.original);
|
|
67
|
+
throw e;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
break;
|
|
71
|
+
// defaulting to standard out
|
|
72
|
+
default:
|
|
73
|
+
console.log(outputContent);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
yargs(hideBin(process.argv))
|
|
77
|
+
.command('listUsers [url] [clientId] [clientSecret]', 'fetches all users in the realms.',
|
|
78
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
79
|
+
() => { }, async (argv) => {
|
|
80
|
+
const users = await listUsers(getKeycloakConfig(config, argv));
|
|
81
|
+
convertData(config, argv, 'user_listing', 'User Listing', users);
|
|
82
|
+
})
|
|
83
|
+
.command('listClients [url] [clientId] [clientSecret]', 'fetches all clients in the realms.',
|
|
84
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
85
|
+
() => { }, async (argv) => {
|
|
86
|
+
const clients = await listClients(getKeycloakConfig(config, argv));
|
|
87
|
+
convertData(config, argv, 'client_listing', 'Client Listing', clients);
|
|
88
|
+
})
|
|
89
|
+
.option('format', {
|
|
90
|
+
alias: 'f',
|
|
91
|
+
type: 'string',
|
|
92
|
+
default: 'json',
|
|
93
|
+
description: 'output format, e.g. JSON|CSV',
|
|
94
|
+
})
|
|
95
|
+
.option('output', {
|
|
96
|
+
alias: 'o',
|
|
97
|
+
type: 'string',
|
|
98
|
+
default: 'stdout',
|
|
99
|
+
description: 'output channel',
|
|
100
|
+
})
|
|
101
|
+
.option('webhookType', {
|
|
102
|
+
alias: 'w',
|
|
103
|
+
type: 'string',
|
|
104
|
+
default: 'slack',
|
|
105
|
+
description: 'Webhook Type',
|
|
106
|
+
})
|
|
107
|
+
.option('webhookMessage', {
|
|
108
|
+
alias: 'm',
|
|
109
|
+
type: 'string',
|
|
110
|
+
description: 'Webhook Message',
|
|
111
|
+
})
|
|
112
|
+
.option('webhookUrl', {
|
|
113
|
+
alias: 't',
|
|
114
|
+
type: 'string',
|
|
115
|
+
description: 'Webhook URL',
|
|
116
|
+
})
|
|
117
|
+
.option('reports', {
|
|
118
|
+
alias: 'r',
|
|
119
|
+
type: 'string',
|
|
120
|
+
description: 'Reports directory',
|
|
121
|
+
})
|
|
122
|
+
.option('useAuditingEndpoint', {
|
|
123
|
+
alias: 'a',
|
|
124
|
+
type: 'boolean',
|
|
125
|
+
default: false,
|
|
126
|
+
description: 'use auditior rest endpoint',
|
|
127
|
+
})
|
|
128
|
+
.command('configTest [url] [clientId] [clientSecret]', 'validates keycloak configuration by reading data via REST API',
|
|
129
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
130
|
+
() => { }, async (argv) => configTest(getKeycloakConfig(config, argv)))
|
|
131
|
+
.parse();
|
|
132
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$id": "https://github.com/ContinuousSecurityTooling/keycloak-reporter/blob/main/config/schema.json",
|
|
3
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
4
|
+
"title": "Keycloak Reporter Config",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"definitions": {},
|
|
7
|
+
"required": ["url", "clientId", "clientSecret"],
|
|
8
|
+
"properties": {
|
|
9
|
+
"command": {
|
|
10
|
+
"type": "array",
|
|
11
|
+
"items": {
|
|
12
|
+
"type": "string",
|
|
13
|
+
"enum": ["listClients", "listUsers"]
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"url": {
|
|
17
|
+
"type": "string",
|
|
18
|
+
"description": "Keycloak Server URL"
|
|
19
|
+
},
|
|
20
|
+
"clientId": {
|
|
21
|
+
"type": "string",
|
|
22
|
+
"description": "Keycloak Client used for reporting"
|
|
23
|
+
},
|
|
24
|
+
"clientSecret": {
|
|
25
|
+
"type": "string",
|
|
26
|
+
"description": "Keycloak Client Secret used for reporting"
|
|
27
|
+
},
|
|
28
|
+
"output": {
|
|
29
|
+
"type": "array",
|
|
30
|
+
"items": {
|
|
31
|
+
"type": "string",
|
|
32
|
+
"enum": ["webhook", "stdout"]
|
|
33
|
+
},
|
|
34
|
+
"description": "Output channel to use"
|
|
35
|
+
},
|
|
36
|
+
"format": {
|
|
37
|
+
"type": "array",
|
|
38
|
+
"items": {
|
|
39
|
+
"type": "string",
|
|
40
|
+
"enum": ["json", "csv"]
|
|
41
|
+
},
|
|
42
|
+
"description": "Report format"
|
|
43
|
+
},
|
|
44
|
+
"webhookType": {
|
|
45
|
+
"type": "array",
|
|
46
|
+
"items": {
|
|
47
|
+
"type": "string",
|
|
48
|
+
"enum": ["slack", "teams"]
|
|
49
|
+
},
|
|
50
|
+
"description": "Type of webhook"
|
|
51
|
+
},
|
|
52
|
+
"webhookMessage": {
|
|
53
|
+
"type": "string",
|
|
54
|
+
"description": "Message added to the webhook post"
|
|
55
|
+
},
|
|
56
|
+
"webhookUrl": {
|
|
57
|
+
"type": "string",
|
|
58
|
+
"description": "URL of the webhook"
|
|
59
|
+
},
|
|
60
|
+
"reports": {
|
|
61
|
+
"type": "string",
|
|
62
|
+
"description": "Reports directory"
|
|
63
|
+
},
|
|
64
|
+
"useAuditingEndpoint": {
|
|
65
|
+
"type": "boolean",
|
|
66
|
+
"default": "false",
|
|
67
|
+
"description": "Enable usage of keycloak reporter auditing endpoint"
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEvE,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import KcAdminClient from '@keycloak/keycloak-admin-client';
|
|
2
|
+
import { AuditClient } from '@continuoussecuritytooling/keycloak-auditor';
|
|
3
|
+
export async function createClient(options) {
|
|
4
|
+
const kcAdminClient = options.useAuditingEndpoint
|
|
5
|
+
? new AuditClient(options.rootUrl, 'master')
|
|
6
|
+
: new KcAdminClient({
|
|
7
|
+
baseUrl: options.rootUrl,
|
|
8
|
+
realmName: 'master',
|
|
9
|
+
});
|
|
10
|
+
try {
|
|
11
|
+
// client login
|
|
12
|
+
await kcAdminClient.auth({
|
|
13
|
+
clientId: options.clientId,
|
|
14
|
+
clientSecret: options.clientSecret,
|
|
15
|
+
grantType: 'client_credentials',
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
catch (e) {
|
|
19
|
+
console.error('Check Client Config:', e.response ? e.response.data.error_description : e);
|
|
20
|
+
return Promise.reject();
|
|
21
|
+
}
|
|
22
|
+
return new Promise((resolve) => resolve(kcAdminClient));
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../lib/client.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,iCAAiC,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,6CAA6C,CAAC;AAS1E,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAgB;IACjD,MAAM,aAAa,GAAG,OAAO,CAAC,mBAAmB;QAC/C,CAAC,CAAC,IAAI,WAAW,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC;QAC5C,CAAC,CAAC,IAAI,aAAa,CAAC;YAChB,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,SAAS,EAAE,QAAQ;SACpB,CAAC,CAAC;IACP,IAAI,CAAC;QACH,eAAe;QACf,MAAM,aAAa,CAAC,IAAI,CAAC;YACvB,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,YAAY,EAAE,OAAO,CAAC,YAAY;YAClC,SAAS,EAAE,oBAAoB;SAChC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,sBAAsB,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1F,OAAO,OAAO,CAAC,MAAM,EAAE,CAAC;IAC1B,CAAC;IAED,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC;AAC1D,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { AsyncParser } from '@json2csv/node';
|
|
2
|
+
export async function convertJSON2CSV(json) {
|
|
3
|
+
const opts = {};
|
|
4
|
+
const transformOpts = {};
|
|
5
|
+
const asyncOpts = {};
|
|
6
|
+
const parser = new AsyncParser(opts, transformOpts, asyncOpts);
|
|
7
|
+
return await parser.parse(json).promise();
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=convert.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"convert.js","sourceRoot":"","sources":["../../lib/convert.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,IAAY;IAChD,MAAM,IAAI,GAAG,EAAE,CAAC;IAChB,MAAM,aAAa,GAAG,EAAE,CAAC;IACzB,MAAM,SAAS,GAAG,EAAE,CAAC;IACrB,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,IAAI,EAAE,aAAa,EAAE,SAAS,CAAC,CAAC;IAC/D,OAAO,MAAM,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;AAC5C,CAAC"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { IncomingWebhook as TeamsWebhook } from 'ms-teams-webhook';
|
|
2
|
+
import { IncomingWebhook as SlackWebhook } from '@slack/webhook';
|
|
3
|
+
var WebhookType;
|
|
4
|
+
(function (WebhookType) {
|
|
5
|
+
WebhookType["SLACK"] = "slack";
|
|
6
|
+
WebhookType["TEAMS"] = "teams";
|
|
7
|
+
})(WebhookType || (WebhookType = {}));
|
|
8
|
+
export async function post2Webhook(type, url, title, reportContent, text) {
|
|
9
|
+
//const title= 'Keycloak Reporting';
|
|
10
|
+
const date = new Date();
|
|
11
|
+
switch (type) {
|
|
12
|
+
case WebhookType.TEAMS.toString():
|
|
13
|
+
return new TeamsWebhook(url).send({
|
|
14
|
+
type: 'message',
|
|
15
|
+
attachments: [
|
|
16
|
+
{
|
|
17
|
+
contentType: 'application/vnd.microsoft.card.adaptive',
|
|
18
|
+
content: {
|
|
19
|
+
$schema: 'https://adaptivecards.io/schemas/adaptive-card.json',
|
|
20
|
+
type: 'AdaptiveCard',
|
|
21
|
+
version: '1.2',
|
|
22
|
+
body: [
|
|
23
|
+
{
|
|
24
|
+
type: 'FactSet',
|
|
25
|
+
facts: [
|
|
26
|
+
{
|
|
27
|
+
title: 'Type',
|
|
28
|
+
value: title
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
title: 'Date',
|
|
32
|
+
value: `${date.getDate()}-${date.getMonth() + 1}-${date.getFullYear()}`
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
type: 'TextBlock',
|
|
38
|
+
text: text != null ? text : '',
|
|
39
|
+
wrap: true
|
|
40
|
+
}
|
|
41
|
+
],
|
|
42
|
+
actions: [
|
|
43
|
+
{
|
|
44
|
+
type: 'Action.ShowCard',
|
|
45
|
+
title: 'Show raw report data',
|
|
46
|
+
card: {
|
|
47
|
+
type: 'AdaptiveCard',
|
|
48
|
+
body: [
|
|
49
|
+
{
|
|
50
|
+
type: 'TextBlock',
|
|
51
|
+
text: reportContent,
|
|
52
|
+
wrap: true
|
|
53
|
+
}
|
|
54
|
+
],
|
|
55
|
+
$schema: 'https://adaptivecards.io/schemas/adaptive-card.json'
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
]
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
});
|
|
63
|
+
// defaulting to Slack
|
|
64
|
+
default:
|
|
65
|
+
// eslint-disable-next-line no-case-declarations
|
|
66
|
+
const blockEntries = [
|
|
67
|
+
{
|
|
68
|
+
type: 'section',
|
|
69
|
+
fields: [
|
|
70
|
+
{ type: 'mrkdwn', text: `*Type*: ${title}` },
|
|
71
|
+
{
|
|
72
|
+
type: 'mrkdwn',
|
|
73
|
+
text: `*Date*: ${date.getDate()}-${date.getMonth() + 1}-${date.getFullYear()}`
|
|
74
|
+
}
|
|
75
|
+
]
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
type: 'divider'
|
|
79
|
+
}
|
|
80
|
+
];
|
|
81
|
+
if (text != null) {
|
|
82
|
+
blockEntries.push({
|
|
83
|
+
type: 'context',
|
|
84
|
+
elements: [{ type: 'plain_text', text: text }]
|
|
85
|
+
});
|
|
86
|
+
blockEntries.push({
|
|
87
|
+
type: 'divider'
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
blockEntries.push({
|
|
91
|
+
type: 'context',
|
|
92
|
+
elements: [
|
|
93
|
+
{
|
|
94
|
+
type: 'mrkdwn',
|
|
95
|
+
text: `
|
|
96
|
+
\`\`\`
|
|
97
|
+
${reportContent}
|
|
98
|
+
\`\`\`
|
|
99
|
+
`
|
|
100
|
+
}
|
|
101
|
+
]
|
|
102
|
+
}, {
|
|
103
|
+
type: 'context',
|
|
104
|
+
elements: [{ type: 'plain_text', text: 'Raw report data' }]
|
|
105
|
+
});
|
|
106
|
+
return new SlackWebhook(url).send({
|
|
107
|
+
blocks: blockEntries
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/*
|
|
112
|
+
*/
|
|
113
|
+
//# sourceMappingURL=output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../../lib/output.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,IAAI,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEnE,OAAO,EAAE,eAAe,IAAI,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEjE,IAAK,WAGJ;AAHD,WAAK,WAAW;IACd,8BAAe,CAAA;IACf,8BAAe,CAAA;AACjB,CAAC,EAHI,WAAW,KAAX,WAAW,QAGf;AAOD,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,IAAY,EACZ,GAAW,EACX,KAAa,EACb,aAAqB,EACrB,IAAa;IAEb,oCAAoC;IACpC,MAAM,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;IACxB,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,WAAW,CAAC,KAAK,CAAC,QAAQ,EAAE;YAC/B,OAAO,IAAI,YAAY,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBAChC,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE;oBACX;wBACE,WAAW,EAAE,yCAAyC;wBACtD,OAAO,EAAE;4BACP,OAAO,EAAE,qDAAqD;4BAC9D,IAAI,EAAE,cAAc;4BACpB,OAAO,EAAE,KAAK;4BACd,IAAI,EAAE;gCACJ;oCACE,IAAI,EAAE,SAAS;oCACf,KAAK,EAAE;wCACL;4CACE,KAAK,EAAE,MAAM;4CACb,KAAK,EAAE,KAAK;yCACb;wCACD;4CACE,KAAK,EAAE,MAAM;4CACb,KAAK,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,IACtB,IAAI,CAAC,QAAQ,EAAE,GAAG,CACpB,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE;yCACzB;qCACF;iCACF;gCACD;oCACE,IAAI,EAAE,WAAW;oCACjB,IAAI,EAAE,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;oCAC9B,IAAI,EAAE,IAAI;iCACX;6BACF;4BACD,OAAO,EAAE;gCACP;oCACE,IAAI,EAAE,iBAAiB;oCACvB,KAAK,EAAE,sBAAsB;oCAC7B,IAAI,EAAE;wCACJ,IAAI,EAAE,cAAc;wCACpB,IAAI,EAAE;4CACJ;gDACE,IAAI,EAAE,WAAW;gDACjB,IAAI,EAAE,aAAa;gDACnB,IAAI,EAAE,IAAI;6CACX;yCACF;wCACD,OAAO,EACL,qDAAqD;qCACxD;iCACF;6BACF;yBACF;qBACF;iBACF;aACF,CAAC,CAAC;QACL,sBAAsB;QACtB;YACE,gDAAgD;YAChD,MAAM,YAAY,GAA+C;gBAC/D;oBACE,IAAI,EAAE,SAAS;oBACf,MAAM,EAAE;wBACN,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,KAAK,EAAE,EAAE;wBAC5C;4BACE,IAAI,EAAE,QAAQ;4BACd,IAAI,EAAE,WAAW,IAAI,CAAC,OAAO,EAAE,IAC7B,IAAI,CAAC,QAAQ,EAAE,GAAG,CACpB,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE;yBACzB;qBACF;iBACF;gBACD;oBACE,IAAI,EAAE,SAAS;iBAChB;aACF,CAAC;YACF,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;gBACjB,YAAY,CAAC,IAAI,CAAC;oBAChB,IAAI,EAAE,SAAS;oBACf,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;iBAC/C,CAAC,CAAC;gBACH,YAAY,CAAC,IAAI,CAAC;oBAChB,IAAI,EAAE,SAAS;iBAChB,CAAC,CAAC;YACL,CAAC;YACD,YAAY,CAAC,IAAI,CACf;gBACE,IAAI,EAAE,SAAS;gBACf,QAAQ,EAAE;oBACR;wBACE,IAAI,EAAE,QAAQ;wBACd,IAAI,EAAE;;EAElB,aAAa;;CAEd;qBACY;iBACF;aACF,EACD;gBACE,IAAI,EAAE,SAAS;gBACf,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,iBAAiB,EAAE,CAAC;aAC5D,CACF,CAAC;YACF,OAAO,IAAI,YAAY,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBAChC,MAAM,EAAE,YAAY;aACrB,CAAC,CAAC;IACP,CAAC;AACH,CAAC;AAED;GACG"}
|
package/dist/lib/user.js
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import KcAdminClient from '@keycloak/keycloak-admin-client';
|
|
2
|
+
export async function clientListing(client) {
|
|
3
|
+
let allClients = new Array();
|
|
4
|
+
if (client instanceof KcAdminClient) {
|
|
5
|
+
const currentRealm = client.realmName;
|
|
6
|
+
let realms;
|
|
7
|
+
try {
|
|
8
|
+
// iterate over realms
|
|
9
|
+
realms = await client.realms.find();
|
|
10
|
+
}
|
|
11
|
+
catch (e) {
|
|
12
|
+
console.error('Check Client role:', e.response.statusText);
|
|
13
|
+
return Promise.reject();
|
|
14
|
+
}
|
|
15
|
+
for (const realm of realms) {
|
|
16
|
+
// switch realm
|
|
17
|
+
client.setConfig({
|
|
18
|
+
realmName: realm.realm,
|
|
19
|
+
});
|
|
20
|
+
const realmClients = new Array();
|
|
21
|
+
for (const user of await client.clients.find()) {
|
|
22
|
+
realmClients.push({
|
|
23
|
+
client: user.clientId,
|
|
24
|
+
id: user.id,
|
|
25
|
+
description: user.description,
|
|
26
|
+
realm: realm.realm,
|
|
27
|
+
enabled: user.enabled,
|
|
28
|
+
public: user.publicClient,
|
|
29
|
+
allowedOrigins: JSON.stringify(user.webOrigins),
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
allClients = [...allClients, ...realmClients];
|
|
33
|
+
}
|
|
34
|
+
// switch back to realm
|
|
35
|
+
client.setConfig({
|
|
36
|
+
realmName: currentRealm,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
const clients = await client.clientListing();
|
|
41
|
+
for (const user of clients) {
|
|
42
|
+
allClients.push({
|
|
43
|
+
client: user.clientId,
|
|
44
|
+
id: user.id,
|
|
45
|
+
description: user.description,
|
|
46
|
+
realm: user.realm,
|
|
47
|
+
enabled: user.enabled,
|
|
48
|
+
public: user.publicClient,
|
|
49
|
+
lastLogin: user.lastLogin,
|
|
50
|
+
allowedOrigins: JSON.stringify(user.webOrigins),
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return new Promise((resolve) => resolve(allClients));
|
|
55
|
+
}
|
|
56
|
+
export async function userListing(client) {
|
|
57
|
+
let allUsers = new Array();
|
|
58
|
+
if (client instanceof KcAdminClient) {
|
|
59
|
+
const currentRealm = client.realmName;
|
|
60
|
+
let realms;
|
|
61
|
+
// iterate over realms
|
|
62
|
+
try {
|
|
63
|
+
realms = await client.realms.find();
|
|
64
|
+
}
|
|
65
|
+
catch (e) {
|
|
66
|
+
console.error('Check Client role:', e.response.statusText);
|
|
67
|
+
return Promise.reject();
|
|
68
|
+
}
|
|
69
|
+
for (const realm of realms) {
|
|
70
|
+
// switch realm
|
|
71
|
+
client.setConfig({
|
|
72
|
+
realmName: realm.realm,
|
|
73
|
+
});
|
|
74
|
+
const realmUsers = new Array();
|
|
75
|
+
for (const user of await client.users.find()) {
|
|
76
|
+
realmUsers.push({
|
|
77
|
+
username: user.username,
|
|
78
|
+
id: user.id,
|
|
79
|
+
firstName: user.firstName,
|
|
80
|
+
lastName: user.lastName,
|
|
81
|
+
email: user.email,
|
|
82
|
+
realm: realm.realm,
|
|
83
|
+
enabled: user.enabled,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
allUsers = [...allUsers, ...realmUsers];
|
|
87
|
+
}
|
|
88
|
+
// switch back to realm
|
|
89
|
+
client.setConfig({
|
|
90
|
+
realmName: currentRealm,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
const users = await client.userListing();
|
|
95
|
+
for (const user of users) {
|
|
96
|
+
allUsers.push({
|
|
97
|
+
username: user.username,
|
|
98
|
+
id: user.id,
|
|
99
|
+
firstName: user.firstName,
|
|
100
|
+
lastName: user.lastName,
|
|
101
|
+
email: user.email,
|
|
102
|
+
realm: user.realm,
|
|
103
|
+
lastLogin: user.lastLogin,
|
|
104
|
+
enabled: user.enabled,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return new Promise((resolve) => resolve(allUsers));
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=user.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user.js","sourceRoot":"","sources":["../../lib/user.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,iCAAiC,CAAC;AA2B5D,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAAmC;IAEnC,IAAI,UAAU,GAAG,IAAI,KAAK,EAAwC,CAAC;IACnE,IAAI,MAAM,YAAY,aAAa,EAAE,CAAC;QACpC,MAAM,YAAY,GAAG,MAAM,CAAC,SAAS,CAAC;QACtC,IAAI,MAAM,CAAC;QACX,IAAI,CAAC;YACH,sBAAsB;YACtB,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACtC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,oBAAoB,EAAE,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;YAC3D,OAAO,OAAO,CAAC,MAAM,EAAE,CAAC;QAC1B,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,eAAe;YACf,MAAM,CAAC,SAAS,CAAC;gBACf,SAAS,EAAE,KAAK,CAAC,KAAK;aACvB,CAAC,CAAC;YACH,MAAM,YAAY,GAAG,IAAI,KAAK,EAAU,CAAC;YACzC,KAAK,MAAM,IAAI,IAAI,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;gBAC/C,YAAY,CAAC,IAAI,CAAC;oBAChB,MAAM,EAAE,IAAI,CAAC,QAAQ;oBACrB,EAAE,EAAE,IAAI,CAAC,EAAE;oBACX,WAAW,EAAE,IAAI,CAAC,WAAW;oBAC7B,KAAK,EAAE,KAAK,CAAC,KAAK;oBAClB,OAAO,EAAE,IAAI,CAAC,OAAO;oBACrB,MAAM,EAAE,IAAI,CAAC,YAAY;oBACzB,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC;iBAChD,CAAC,CAAC;YACL,CAAC;YACD,UAAU,GAAG,CAAC,GAAG,UAAU,EAAE,GAAG,YAAY,CAAC,CAAC;QAChD,CAAC;QACD,uBAAuB;QACvB,MAAM,CAAC,SAAS,CAAC;YACf,SAAS,EAAE,YAAY;SACxB,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,aAAa,EAAE,CAAC;QAC7C,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;YAC3B,UAAU,CAAC,IAAI,CAAC;gBACd,MAAM,EAAE,IAAI,CAAC,QAAQ;gBACrB,EAAE,EAAE,IAAI,CAAC,EAAE;gBACX,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,MAAM,EAAE,IAAI,CAAC,YAAY;gBACzB,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC;aAChD,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,MAAmC;IAEnC,IAAI,QAAQ,GAAG,IAAI,KAAK,EAAoC,CAAC;IAC7D,IAAI,MAAM,YAAY,aAAa,EAAE,CAAC;QACpC,MAAM,YAAY,GAAG,MAAM,CAAC,SAAS,CAAC;QACtC,IAAI,MAAM,CAAC;QACX,sBAAsB;QACtB,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACtC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,oBAAoB,EAAE,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;YAC3D,OAAO,OAAO,CAAC,MAAM,EAAE,CAAC;QAC1B,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,eAAe;YACf,MAAM,CAAC,SAAS,CAAC;gBACf,SAAS,EAAE,KAAK,CAAC,KAAK;aACvB,CAAC,CAAC;YACH,MAAM,UAAU,GAAG,IAAI,KAAK,EAAQ,CAAC;YACrC,KAAK,MAAM,IAAI,IAAI,MAAM,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;gBAC7C,UAAU,CAAC,IAAI,CAAC;oBACd,QAAQ,EAAE,IAAI,CAAC,QAAQ;oBACvB,EAAE,EAAE,IAAI,CAAC,EAAE;oBACX,SAAS,EAAE,IAAI,CAAC,SAAS;oBACzB,QAAQ,EAAE,IAAI,CAAC,QAAQ;oBACvB,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,KAAK,EAAE,KAAK,CAAC,KAAK;oBAClB,OAAO,EAAE,IAAI,CAAC,OAAO;iBACtB,CAAC,CAAC;YACL,CAAC;YACD,QAAQ,GAAG,CAAC,GAAG,QAAQ,EAAE,GAAG,UAAU,CAAC,CAAC;QAC1C,CAAC;QACD,uBAAuB;QACvB,MAAM,CAAC,SAAS,CAAC;YACf,SAAS,EAAE,YAAY;SACxB,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,WAAW,EAAE,CAAC;QACzC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,QAAQ,CAAC,IAAI,CAAC;gBACZ,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,EAAE,EAAE,IAAI,CAAC,EAAE;gBACX,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,OAAO,EAAE,IAAI,CAAC,OAAO;aACtB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;AACrD,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { createClient } from '../lib/client.js';
|
|
2
|
+
import { userListing, clientListing } from '../lib/user.js';
|
|
3
|
+
function kcClient(options) {
|
|
4
|
+
return createClient({
|
|
5
|
+
clientId: options.clientId,
|
|
6
|
+
clientSecret: options.clientSecret,
|
|
7
|
+
rootUrl: options.rootUrl,
|
|
8
|
+
useAuditingEndpoint: options.useAuditingEndpoint,
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
export async function listUsers(options) {
|
|
12
|
+
const users = await userListing(await kcClient(options));
|
|
13
|
+
return new Promise((resolve) => resolve(users));
|
|
14
|
+
}
|
|
15
|
+
export async function listClients(options) {
|
|
16
|
+
const clients = await clientListing(await kcClient(options));
|
|
17
|
+
return new Promise((resolve) => resolve(clients));
|
|
18
|
+
}
|
|
19
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
20
|
+
export async function configTest(options) {
|
|
21
|
+
try {
|
|
22
|
+
await userListing(await kcClient(options));
|
|
23
|
+
console.log(`Connection to ${options.rootUrl} was successfull`);
|
|
24
|
+
}
|
|
25
|
+
catch (e) {
|
|
26
|
+
console.error(`Connection to ${options.rootUrl} was not: successfull`, e.response);
|
|
27
|
+
return Promise.reject(e.response.statusText);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/commands.ts"],"names":[],"mappings":"AAMA,OAAO,EAAW,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAQ,WAAW,EAAE,aAAa,EAAU,MAAM,gBAAgB,CAAC;AAE1E,SAAS,QAAQ,CAAC,OAAgB;IAChC,OAAO,YAAY,CAAC;QAClB,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,YAAY,EAAE,OAAO,CAAC,YAAY;QAClC,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,mBAAmB,EAAE,OAAO,CAAC,mBAAmB;KACjD,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAAgB;IAC9C,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,MAAM,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;IACzD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAgB;IAChD,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,MAAM,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;IAC7D,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;AACpD,CAAC;AACD,uDAAuD;AACvD,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,OAAgB;IAC/C,IAAI,CAAC;QACH,MAAM,WAAW,CAAC,MAAM,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;QAC3C,OAAO,CAAC,GAAG,CAAC,iBAAiB,OAAO,CAAC,OAAO,kBAAkB,CAAC,CAAC;IAClE,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,iBAAiB,OAAO,CAAC,OAAO,uBAAuB,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC;QACnF,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IAC/C,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { assoc, pick, mergeAll, mergeDeepRight } from 'ramda';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
import fs from 'fs';
|
|
5
|
+
const schema = JSON.parse(fs.readFileSync(fileURLToPath(path.join(import.meta.url, '../../config/schema.json')), 'utf8'));
|
|
6
|
+
// import the config file
|
|
7
|
+
function buildConfigFromFile(filePath) {
|
|
8
|
+
if (!filePath)
|
|
9
|
+
return {};
|
|
10
|
+
const isAbsolutePath = filePath.charAt(0) === '/';
|
|
11
|
+
return JSON.parse(isAbsolutePath
|
|
12
|
+
? fs.readFileSync(filePath, 'utf8')
|
|
13
|
+
: fs.readFileSync(fileURLToPath(path.join(import.meta.url, '../config', filePath)), 'utf8'));
|
|
14
|
+
}
|
|
15
|
+
// build an object using the defaults in the schema
|
|
16
|
+
function buildDefaults(schema, definitions) {
|
|
17
|
+
return Object.keys(schema.properties).reduce((acc, prop) => {
|
|
18
|
+
let spec = schema.properties[prop];
|
|
19
|
+
if (spec.$ref) {
|
|
20
|
+
spec = definitions[spec.$ref.replace('#/definitions/', '')];
|
|
21
|
+
if (spec && spec.type === 'object') {
|
|
22
|
+
return assoc(prop, buildDefaults(spec, definitions), acc);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return assoc(prop, spec.default, acc);
|
|
26
|
+
}, {});
|
|
27
|
+
}
|
|
28
|
+
// build an object of config values taken from process.env
|
|
29
|
+
function buildEnvironmentVariablesConfig(schema) {
|
|
30
|
+
const trueRx = /^true$/i;
|
|
31
|
+
const configKeys = Object.keys(schema.properties);
|
|
32
|
+
const env = pick(configKeys, process.env);
|
|
33
|
+
return Object.keys(env).reduce((acc, key) => {
|
|
34
|
+
const { type } = schema.properties[key];
|
|
35
|
+
switch (type) {
|
|
36
|
+
case 'integer':
|
|
37
|
+
return assoc(key, parseInt(env[key], 10), acc);
|
|
38
|
+
case 'boolean':
|
|
39
|
+
return assoc(key, trueRx.test(env[key]), acc);
|
|
40
|
+
default:
|
|
41
|
+
return assoc(key, env[key], acc);
|
|
42
|
+
}
|
|
43
|
+
}, {});
|
|
44
|
+
}
|
|
45
|
+
// merge the environment variables, config file values, and defaults
|
|
46
|
+
const config = mergeAll(mergeDeepRight(buildDefaults(schema, schema.definitions), buildConfigFromFile(process.env.CONFIG_FILE)), buildEnvironmentVariablesConfig(schema));
|
|
47
|
+
export default config;
|
|
48
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"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"}
|
package/e2e/spec/clients.js
CHANGED
|
@@ -21,7 +21,7 @@ test('Should list clients as JSON', { timeout: 3000 }, (t) => {
|
|
|
21
21
|
}
|
|
22
22
|
);
|
|
23
23
|
cli.stdout.on('data', (chunk) => {
|
|
24
|
-
console.log(chunk.toString())
|
|
24
|
+
console.log('Response', JSON.parse(chunk.toString()));
|
|
25
25
|
t.equal(JSON.parse(chunk.toString()).length, 24);
|
|
26
26
|
t.end();
|
|
27
27
|
});
|
package/e2e/spec/config.js
CHANGED
|
@@ -19,7 +19,7 @@ test('Should use config file', { timeout: 3000 }, (t) => {
|
|
|
19
19
|
}
|
|
20
20
|
);
|
|
21
21
|
cli.stdout.on('data', (chunk) => {
|
|
22
|
-
console.log(chunk.toString())
|
|
22
|
+
console.log('Response', JSON.parse(chunk.toString()));
|
|
23
23
|
t.equal(JSON.parse(chunk.toString()).length, 24);
|
|
24
24
|
t.end();
|
|
25
25
|
});
|
|
@@ -27,3 +27,27 @@ test('Should use config file', { timeout: 3000 }, (t) => {
|
|
|
27
27
|
t.fail(msg)
|
|
28
28
|
});
|
|
29
29
|
});
|
|
30
|
+
|
|
31
|
+
test('Should validate config', { timeout: 3000 }, (t) => {
|
|
32
|
+
const cli = spawn(
|
|
33
|
+
path.join(path.dirname('.'), 'node'),
|
|
34
|
+
[
|
|
35
|
+
'dist/cli.js',
|
|
36
|
+
'configTest'
|
|
37
|
+
],
|
|
38
|
+
{
|
|
39
|
+
env: {
|
|
40
|
+
CONFIG_FILE: process.cwd() + '/e2e/fixtures/config.json',
|
|
41
|
+
...process.env,
|
|
42
|
+
},
|
|
43
|
+
}
|
|
44
|
+
);
|
|
45
|
+
cli.stdout.on('data', (chunk) => {
|
|
46
|
+
console.log(chunk.toString())
|
|
47
|
+
t.equal(chunk.toString(), 'Connection to http://localhost:8080 was successfull\n');
|
|
48
|
+
t.end();
|
|
49
|
+
});
|
|
50
|
+
cli.stderr.on('data', (msg) => {
|
|
51
|
+
t.fail(msg)
|
|
52
|
+
});
|
|
53
|
+
});
|
package/e2e/spec/users.js
CHANGED
|
@@ -21,7 +21,7 @@ test('Should list users as JSON', { timeout: 3000 }, (t) => {
|
|
|
21
21
|
}
|
|
22
22
|
);
|
|
23
23
|
cli.stdout.on('data', (chunk) => {
|
|
24
|
-
console.log(chunk.toString())
|
|
24
|
+
console.log('Response', JSON.parse(chunk.toString()));
|
|
25
25
|
t.equal(JSON.parse(chunk.toString()).length, 3);
|
|
26
26
|
t.end();
|
|
27
27
|
});
|
package/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { listUsers, listClients } from './src/commands.js';
|
|
1
|
+
export { configTest, listUsers, listClients } from './src/commands.js';
|
|
2
2
|
export { Options } from './lib/client.js';
|
|
3
3
|
export { convertJSON2CSV } from './lib/convert.js';
|
|
4
|
-
export { post2Webhook } from './lib/output.js';
|
|
4
|
+
export { post2Webhook } from './lib/output.js';
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@continuoussecuritytooling/keycloak-reporter",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Reporting Tools for Keycloak",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@continuoussecuritytooling/keycloak-auditor": "^1.1.0",
|
|
29
29
|
"@json2csv/node": "^7.0.0",
|
|
30
|
-
"@keycloak/keycloak-admin-client": "^
|
|
30
|
+
"@keycloak/keycloak-admin-client": "^23.0.0",
|
|
31
31
|
"@slack/webhook": "^7.0.0",
|
|
32
32
|
"ajv": "^8.12.0",
|
|
33
33
|
"install": "^0.13.0",
|
package/src/commands.ts
CHANGED
|
@@ -25,3 +25,13 @@ export async function listClients(options: Options): Promise<Array<Client | Audi
|
|
|
25
25
|
const clients = await clientListing(await kcClient(options));
|
|
26
26
|
return new Promise((resolve) => resolve(clients));
|
|
27
27
|
}
|
|
28
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
29
|
+
export async function configTest(options: Options): Promise<any> {
|
|
30
|
+
try {
|
|
31
|
+
await userListing(await kcClient(options));
|
|
32
|
+
console.log(`Connection to ${options.rootUrl} was successfull`);
|
|
33
|
+
} catch (e) {
|
|
34
|
+
console.error(`Connection to ${options.rootUrl} was not: successfull`, e.response);
|
|
35
|
+
return Promise.reject(e.response.statusText);
|
|
36
|
+
}
|
|
37
|
+
}
|
package/src/config.ts
CHANGED
|
@@ -48,6 +48,7 @@ function buildEnvironmentVariablesConfig(schema) {
|
|
|
48
48
|
}
|
|
49
49
|
}, {});
|
|
50
50
|
}
|
|
51
|
+
|
|
51
52
|
// merge the environment variables, config file values, and defaults
|
|
52
53
|
const config = mergeAll(
|
|
53
54
|
mergeDeepRight(buildDefaults(schema, schema.definitions), buildConfigFromFile(process.env.CONFIG_FILE)),
|