Added docker-compose ranpm
[nonrtric/plt/ranpm.git] / docker-proj / scripts / populate_keycloak.sh
1 #!/bin/bash
2
3 #  ============LICENSE_START===============================================
4 #  Copyright (C) 2023 Nordix Foundation. All rights reserved.
5 #  ========================================================================
6 #  Licensed under the Apache License, Version 2.0 (the "License");
7 #  you may not use this file except in compliance with the License.
8 #  You may obtain a copy of the License at
9 #
10 #       http://www.apache.org/licenses/LICENSE-2.0
11 #
12 #  Unless required by applicable law or agreed to in writing, software
13 #  distributed under the License is distributed on an "AS IS" BASIS,
14 #  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 #  See the License for the specific language governing permissions and
16 #  limitations under the License.
17 #  ============LICENSE_END=================================================
18 #
19
20 # Script intended to be sourced by other script to add functions to the keycloak rest API
21
22 KC_URL=http://localhost:8462
23 echo "Keycloak url: "$KC_URL
24
25 __get_admin_token() {
26     echo "Get admin token"
27     ADMIN_TOKEN=""
28     while [ "${#ADMIN_TOKEN}" -lt 20 ]; do
29         ADMIN_TOKEN=$(curl -s -X POST --max-time 2     "$KC_URL/realms/master/protocol/openid-connect/token"     -H "Content-Type: application/x-www-form-urlencoded"     -d "username=admin" -d "password=admin" -d 'grant_type=password' -d "client_id=admin-cli"  |  jq -r '.access_token')
30         if [ "${#ADMIN_TOKEN}" -lt 20 ]; then
31             echo "Could not get admin token, retrying..."
32             echo "Retrieved token: $ADMIN_TOKEN"
33         fi
34     done
35     echo "Admin token: ${ADMIN_TOKEN:0:10}..."
36     echo $ADMIN_TOKEN > .admin_token
37     __ADM_TOKEN_TS=$SECONDS
38 }
39
40 __check_admin_token() {
41     __diff=$(($SECONDS-$__ADM_TOKEN_TS))
42     if [ $__diff -gt 15 ]; then
43         __get_admin_token
44     fi
45 }
46
47 __get_admin_token
48
49 indent1() { sed 's/^/ /'; }
50 indent2() { sed 's/^/  /'; }
51
52 decode_token() {
53     echo "Decoding access_token"
54     echo $1 | jq -R 'split(".") | .[0,1] | @base64d | fromjson'
55 }
56
57 decode_jwt() {
58     echo "Decoding jwt"
59     echo $1 | jq -r .access_token | jq -R 'split(".") | .[0,1] | @base64d | fromjson'
60 }
61
62 list_realms() {
63     echo "Listing all realms"
64     __check_admin_token
65     curl -s \
66         -X GET \
67         -H "Authorization: Bearer ${ADMIN_TOKEN}" \
68         "$KC_URL/admin/realms" | jq -r '.[].id' | indent2
69 }
70 delete_realms() {
71     echo "$@"
72     for realm in "$@"; do
73         echo "Attempt to delete realm: $realm"
74         __check_admin_token
75         curl -s \
76         -X DELETE \
77         -H "Authorization: Bearer ${ADMIN_TOKEN}" \
78         "$KC_URL/admin/realms/$realm" | indent1
79         if [ $? -ne 0 ]; then
80             echo "Command failed"
81             exit 1
82         fi
83         echo " OK"
84     done
85 }
86
87 create_realms() {
88     echo "Creating realms: $@"
89     while [ $# -gt 0 ]; do
90         echo " Attempt to create realm: $1"
91         __check_admin_token
92 cat > .jsonfile1 <<- "EOF"
93 {
94 "realm":"$__realm_name",
95 "enabled":true
96 }
97 EOF
98         export __realm_name=$1
99         envsubst < .jsonfile1 > .jsonfile2
100         curl -s \
101         -X POST \
102         -H "Authorization: Bearer ${ADMIN_TOKEN}" \
103         -H "Content-Type: application/json" \
104         -d @".jsonfile2" \
105         "$KC_URL/admin/realms" | indent2
106         if [ $? -ne 0 ]; then
107             echo "Command failed"
108             exit 1
109         fi
110         echo "  OK"
111         shift
112     done
113 }
114
115 create_clients() {
116     __realm=$1
117     shift
118     echo "Attempt to create clients $@ for realm: $__realm"
119
120 cat > .jsonfile1 <<- "EOF"
121 {
122    "clientId":"$__client_name",
123    "publicClient": false,
124    "serviceAccountsEnabled": true,
125    "rootUrl":"https://example.com/example/",
126    "adminUrl":"https://example.com/example/"
127 }
128 EOF
129     while [ $# -gt 0 ]; do
130         echo " Creating client: $1"
131         __check_admin_token
132         export __client_name=$1
133         envsubst < .jsonfile1 > .jsonfile2
134         curl -s \
135         -X POST \
136         -H "Authorization: Bearer ${ADMIN_TOKEN}" \
137         -H "Content-Type: application/json" \
138         -d @".jsonfile2" \
139         "$KC_URL/admin/realms/$__realm/clients" | indent1
140         if [ $? -ne 0 ]; then
141             echo "Command failed"
142             exit 1
143         fi
144         echo " OK"
145         shift
146     done
147 }
148
149 __get_client_id() {
150     __client_data=$(curl -s \
151         -X GET \
152         -H "Authorization: Bearer ${ADMIN_TOKEN}" \
153         "$KC_URL/admin/realms/$1/clients?clientId=$2")
154     if [ $? -ne 0 ]; then
155         return 1
156     fi
157     __client_id=$(echo $__client_data |  jq -r '.[0].id')
158     echo $__client_id
159     return 0
160 }
161
162 generate_client_secrets() {
163     __realm=$1
164     shift
165     echo "Attempt to generate secret for clients $@ in realm $__realm"
166     while [ $# -gt 0 ]; do
167         __check_admin_token
168         __client_id=$(__get_client_id $__realm $1)
169         if [ $? -ne 0 ]; then
170             echo "Command failed"
171             exit 1
172         fi
173         echo " Client id for client $1 in realm $__realm: "$__client_id | indent1
174         echo "  Creating secret"
175         __client_secret=$(curl -s \
176                 -X POST \
177                 -H "Authorization: Bearer ${ADMIN_TOKEN}" \
178                 "$KC_URL/admin/realms/$__realm/clients/$__client_id/client-secret")
179         if [ $? -ne 0 ]; then
180             echo "Command failed"
181             exit 1
182         fi
183         __client_secret=$(curl -s \
184                 -X GET \
185                 -H "Authorization: Bearer ${ADMIN_TOKEN}" \
186                 "$KC_URL/admin/realms/$__realm/clients/$__client_id/client-secret")
187         if [ $? -ne 0 ]; then
188             echo "Command failed"
189             exit 1
190         fi
191         __client_secret=$(echo $__client_secret | jq -r .value)
192         echo "  Client secret for client $1 in realm $__realm: "$__client_secret | indent1
193         echo $__client_secret > ".sec_$__realm""_$1"
194         echo "   OK"
195         shift
196     done
197 }
198
199 create_client_roles() {
200     # <realm-name> <client-name> [<role-name>]+
201     __check_admin_token
202     __client_id=$(__get_client_id $1 $2)
203     if [ $? -ne 0 ]; then
204         echo "Command failed"
205         exit 1
206     fi
207     __realm=$1
208     shift; shift;
209     while [ $# -gt 0 ]; do
210
211 cat > .jsonfile1 <<- "EOF"
212 {
213    "name":"$__role"
214 }
215 EOF
216         export __role=$1
217         envsubst < .jsonfile1 > .jsonfile2
218         curl -s \
219         -X POST \
220         -H "Authorization: Bearer ${ADMIN_TOKEN}" \
221         -H "Content-Type: application/json" \
222         -d @".jsonfile2" \
223         "$KC_URL/admin/realms/$__realm/clients/$__client_id/roles" | indent1
224         if [ $? -ne 0 ]; then
225             echo "Command failed"
226             exit 1
227         fi
228         shift
229     done
230 }
231
232 __get_service_account_id() {
233     # <realm-name> <client-id>
234     __service_account_data=$(curl -s \
235         -X GET \
236         -H "Authorization: Bearer ${ADMIN_TOKEN}" \
237         "$KC_URL/admin/realms/$1/clients/$2/service-account-user")
238     if [ $? -ne 0 ]; then
239         return 1
240     fi
241     __service_account_id=$(echo $__service_account_data |  jq -r '.id')
242     echo $__service_account_id
243     return 0
244 }
245
246 __get_client_available_role_id() {
247     # <realm-name> <service-account-id> <client-id> <client-role-name>
248     __client_role_data=$(curl -s \
249         -X GET \
250         -H "Authorization: Bearer ${ADMIN_TOKEN}" \
251         "$KC_URL/admin/realms/$1/users/$2/role-mappings/clients/$3/available")
252     if [ $? -ne 0 ]; then
253         return 1
254     fi
255     #__client_role_id=$(echo $__client_role_data |  jq -r '.id')
256     __client_role_id=$(echo $__client_role_data | jq  -r '.[] | select(.name=="'$4'") | .id ')
257     echo $__client_role_id
258     return 0
259 }
260
261 __get_client_mapped_role_id() {
262     # <realm-name> <service-account-id> <client-id> <client-role-name>
263     __client_role_data=$(curl -s \
264         -X GET \
265         -H "Authorization: Bearer ${ADMIN_TOKEN}" \
266         "$KC_URL/admin/realms/$1/users/$2/role-mappings/clients/$3")
267     if [ $? -ne 0 ]; then
268         return 1
269     fi
270     #__client_role_id=$(echo $__client_role_data |  jq -r '.id')
271     __client_role_id=$(echo $__client_role_data | jq  -r '.[] | select(.name=="'$4'") | .id ')
272     echo $__client_role_id
273     return 0
274 }
275
276 add_client_roles_mapping()  {
277     # <realm-name> <client-name> [<role-name>]+
278     echo "Attempt to add roles ${@:3} to client $2 in realm $1"
279     __check_admin_token
280     __realm=$1
281     __client=$2
282     __client_id=$(__get_client_id $__realm $__client)
283     if [ $? -ne 0 ]; then
284         echo "Command failed"
285         exit 1
286     fi
287     echo " Client id for client $__client in realm $__realm: "$__client_id | indent1
288     __service_account_id=$(__get_service_account_id $__realm $__client_id)
289     if [ $? -ne 0 ]; then
290         echo "Command failed"
291         exit 1
292     fi
293     echo " Service account id for client $__client in realm $__realm: "$__service_account_id | indent1
294     shift; shift
295     __cntr=0
296     __all_roles=$@
297     while [ $# -gt 0 ]; do
298         if [ $__cntr -eq 0 ]; then
299             echo "[" > .jsonfile2
300         fi
301         __client_role_id=$(__get_client_available_role_id $__realm $__service_account_id $__client_id $1)
302         if [ $? -ne 0 ]; then
303             echo "Command failed"
304             exit 1
305         fi
306
307         __role='{"name":"'$1'","id":"'$__client_role_id'","composite": false,"clientRole": true}'
308         if [ $__cntr -gt 0 ]; then
309             echo "," >> .jsonfile2
310         fi
311         echo $__role >> .jsonfile2
312         let __cntr=__cntr+1
313         shift
314     done
315     echo "]" >> .jsonfile2
316     echo "  Adding roles $__all_roles to client $__client in realm $__realm"
317
318     curl -s \
319     -X POST \
320     -H "Authorization: Bearer ${ADMIN_TOKEN}" \
321     -H "Content-Type: application/json" \
322     -d @".jsonfile2" \
323     "$KC_URL/admin/realms/$__realm/users/$__service_account_id/role-mappings/clients/$__client_id" | indent2
324     if [ $? -ne 0 ]; then
325         echo "Command failed"
326         exit 1
327     fi
328     echo "  OK"
329 }
330
331
332
333 remove_client_roles_mapping()  {
334     # <realm-name> <client-name> [<role-name>]+
335     echo "Attempt to removed roles ${@:3} from client $2 in realm $1"
336     __check_admin_token
337     __realm=$1
338     __client=$2
339     __client_id=$(__get_client_id $__realm $__client)
340     if [ $? -ne 0 ]; then
341         echo "Command failed"
342         exit 1
343     fi
344     echo " Client id for client $__client in realm $__realm: "$__client_id | indent1
345     __service_account_id=$(__get_service_account_id $__realm $__client_id)
346     if [ $? -ne 0 ]; then
347         echo "Command failed"
348         exit 1
349     fi
350     echo " Service account id for client $__client in realm $__realm: "$__service_account_id | indent1
351     shift; shift
352     __cntr=0
353     __all_roles=$@
354     while [ $# -gt 0 ]; do
355         if [ $__cntr -eq 0 ]; then
356             echo "[" > .jsonfile2
357         fi
358         __client_role_id=$(__get_client_mapped_role_id $__realm $__service_account_id $__client_id $1)
359         if [ $? -ne 0 ]; then
360             echo "Command failed"
361             exit 1
362         fi
363
364         __role='{"name":"'$1'","id":"'$__client_role_id'","composite": false,"clientRole": true}'
365         if [ $__cntr -gt 0 ]; then
366             echo "," >> .jsonfile2
367         fi
368         echo $__role >> .jsonfile2
369         let __cntr=__cntr+1
370         shift
371     done
372     echo "]" >> .jsonfile2
373     echo "  Removing roles $__all_roles from client $__client in realm $__realm"
374
375     curl -s \
376     -X DELETE \
377     -H "Authorization: Bearer ${ADMIN_TOKEN}" \
378     -H "Content-Type: application/json" \
379     -d @".jsonfile2" \
380     "$KC_URL/admin/realms/$__realm/users/$__service_account_id/role-mappings/clients/$__client_id" | indent2
381     if [ $? -ne 0 ]; then
382         echo "Command failed"
383         exit 1
384     fi
385     echo "  OK"
386 }
387
388 add_client_hardcoded-claim-mapper() {
389 # <realm-name> <client-name> <mapper-name> <claim-name> <claim-value>
390     __check_admin_token
391     __realm=$1
392     __client=$2
393     export __mapper_name=$3
394     export __claim_name=$4
395     export __claim_value=$5
396
397     __client_id=$(__get_client_id $__realm $__client)
398     if [ $? -ne 0 ]; then
399         echo " Fatal error when getting client id, response: "$?
400         exit 1
401     fi
402     cat > .jsonfile1 <<- "EOF"
403 {
404     "name": "$__mapper_name",
405     "protocol": "openid-connect",
406     "protocolMapper": "oidc-hardcoded-claim-mapper",
407     "consentRequired": false,
408     "config": {
409       "claim.value": "$__claim_value",
410       "userinfo.token.claim": "true",
411       "id.token.claim": "true",
412       "access.token.claim": "true",
413       "claim.name": "$__claim_name",
414       "access.tokenResponse.claim": "false"
415     }
416 }
417 EOF
418     envsubst < .jsonfile1 > .jsonfile2
419     curl -s \
420     -X POST \
421     -H "Authorization: Bearer ${ADMIN_TOKEN}" \
422     -H "Content-Type: application/json" \
423     -d @".jsonfile2" \
424     "$KC_URL/admin/realms/nonrtric-realm/clients/"$__client_id"/protocol-mappers/models" | indent2
425     if [ $? -ne 0 ]; then
426         echo "Command failed"
427         exit 1
428     fi
429     set +x
430     cat .jsonfile2
431     echo "  OK"
432 }
433
434 # Get a client token
435 # args: <realm-name> <client-name>
436 get_client_token() {
437     __check_admin_token
438     __realm=$1
439     __client=$2
440     __client_id=$(__get_client_id $__realm $__client)
441     if [ $? -ne 0 ]; then
442         echo " Fatal error when getting client id, response: "$?
443         exit 1
444     fi
445
446     __client_secret=$(curl -s -f \
447             -X GET \
448             -H "Authorization: Bearer ${ADMIN_TOKEN}" \
449             "$KC_URL/admin/realms/$__realm/clients/$__client_id/client-secret")
450     if [ $? -ne 0 ]; then
451         echo " Fatal error when getting client secret, response: "$?
452         exit 1
453     fi
454
455     __client_secret=$(echo $__client_secret | jq -r .value)
456
457         __TMP_TOKEN=$(curl -s -f -X POST $KC_URL/realms/$__realm/protocol/openid-connect/token   \
458                   -H Content-Type:application/x-www-form-urlencoded \
459                   -d client_id="$__client" -d client_secret="$__client_secret" -d grant_type=client_credentials)
460         if [ $? -ne 0 ]; then
461                 echo " Fatal error when getting client token, response: "$?
462                 exit 1
463         fi
464
465         echo $__TMP_TOKEN| jq -r .access_token
466         return 0
467 }