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
10 # http://www.apache.org/licenses/LICENSE-2.0
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=================================================
20 # Script intended to be sourced by other script to add functions to the keycloak rest API
22 echo "Cluster ip: $KUBERNETESHOST"
24 KC_URL=http://keycloak.nonrtric:8080
25 echo "Keycloak url: "$KC_URL
27 KC_PROXY_PORT=$(kubectl get svc -n nonrtric keycloak-proxy --output jsonpath='{.spec.ports[?(@.name=="http")].nodePort}')
28 echo "Nodeport to keycloak proxy: "$KC_PROXY_PORT
31 echo "Get admin token"
33 while [ "${#ADMIN_TOKEN}" -lt 20 ]; do
34 ADMIN_TOKEN=$(curl --proxy $KUBERNETESHOST:$KC_PROXY_PORT -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')
35 if [ "${#ADMIN_TOKEN}" -lt 20 ]; then
36 echo "Could not get admin token, retrying..."
37 echo "Retrieved token: $ADMIN_TOKEN"
40 echo "Admin token: ${ADMIN_TOKEN:0:10}..."
41 echo $ADMIN_TOKEN > .admin_token
42 __ADM_TOKEN_TS=$SECONDS
45 __check_admin_token() {
46 __diff=$(($SECONDS-$__ADM_TOKEN_TS))
47 if [ $__diff -gt 15 ]; then
54 indent1() { sed 's/^/ /'; }
55 indent2() { sed 's/^/ /'; }
58 echo "Decoding access_token"
59 echo $1 | jq -R 'split(".") | .[0,1] | @base64d | fromjson'
64 echo $1 | jq -r .access_token | jq -R 'split(".") | .[0,1] | @base64d | fromjson'
68 echo "Listing all realms"
70 curl --proxy $KUBERNETESHOST:$KC_PROXY_PORT -s \
72 -H "Authorization: Bearer ${ADMIN_TOKEN}" \
73 "$KC_URL/admin/realms" | jq -r '.[].id' | indent2
78 echo "Attempt to delete realm: $realm"
80 curl --proxy $KUBERNETESHOST:$KC_PROXY_PORT -s \
82 -H "Authorization: Bearer ${ADMIN_TOKEN}" \
83 "$KC_URL/admin/realms/$realm" | indent1
93 echo "Creating realms: $@"
94 while [ $# -gt 0 ]; do
95 echo " Attempt to create realm: $1"
97 cat > .jsonfile1 <<- "EOF"
99 "realm":"$__realm_name",
103 export __realm_name=$1
104 envsubst < .jsonfile1 > .jsonfile2
105 curl --proxy $KUBERNETESHOST:$KC_PROXY_PORT -s \
107 -H "Authorization: Bearer ${ADMIN_TOKEN}" \
108 -H "Content-Type: application/json" \
110 "$KC_URL/admin/realms" | indent2
111 if [ $? -ne 0 ]; then
112 echo "Command failed"
123 echo "Attempt to create clients $@ for realm: $__realm"
125 cat > .jsonfile1 <<- "EOF"
127 "clientId":"$__client_name",
128 "publicClient": false,
129 "serviceAccountsEnabled": true,
130 "rootUrl":"https://example.com/example/",
131 "adminUrl":"https://example.com/example/"
134 while [ $# -gt 0 ]; do
135 echo " Creating client: $1"
137 export __client_name=$1
138 envsubst < .jsonfile1 > .jsonfile2
139 curl --proxy $KUBERNETESHOST:$KC_PROXY_PORT -s \
141 -H "Authorization: Bearer ${ADMIN_TOKEN}" \
142 -H "Content-Type: application/json" \
144 "$KC_URL/admin/realms/$__realm/clients" | indent1
145 if [ $? -ne 0 ]; then
146 echo "Command failed"
155 __client_data=$(curl --proxy $KUBERNETESHOST:$KC_PROXY_PORT -s \
157 -H "Authorization: Bearer ${ADMIN_TOKEN}" \
158 "$KC_URL/admin/realms/$1/clients?clientId=$2")
159 if [ $? -ne 0 ]; then
162 __client_id=$(echo $__client_data | jq -r '.[0].id')
167 generate_client_secrets() {
170 echo "Attempt to generate secret for clients $@ in realm $__realm"
171 while [ $# -gt 0 ]; do
173 __client_id=$(__get_client_id $__realm $1)
174 if [ $? -ne 0 ]; then
175 echo "Command failed"
178 echo " Client id for client $1 in realm $__realm: "$__client_id | indent1
179 echo " Creating secret"
180 __client_secret=$(curl --proxy $KUBERNETESHOST:$KC_PROXY_PORT -s \
182 -H "Authorization: Bearer ${ADMIN_TOKEN}" \
183 "$KC_URL/admin/realms/$__realm/clients/$__client_id/client-secret")
184 if [ $? -ne 0 ]; then
185 echo "Command failed"
188 __client_secret=$(curl --proxy $KUBERNETESHOST:$KC_PROXY_PORT -s \
190 -H "Authorization: Bearer ${ADMIN_TOKEN}" \
191 "$KC_URL/admin/realms/$__realm/clients/$__client_id/client-secret")
192 if [ $? -ne 0 ]; then
193 echo "Command failed"
196 __client_secret=$(echo $__client_secret | jq -r .value)
197 echo " Client secret for client $1 in realm $__realm: "$__client_secret | indent1
198 echo $__client_secret > ".sec_$__realm""_$1"
204 create_client_roles() {
205 # <realm-name> <client-name> [<role-name>]+
207 __client_id=$(__get_client_id $1 $2)
208 if [ $? -ne 0 ]; then
209 echo "Command failed"
214 while [ $# -gt 0 ]; do
216 cat > .jsonfile1 <<- "EOF"
222 envsubst < .jsonfile1 > .jsonfile2
223 curl --proxy $KUBERNETESHOST:$KC_PROXY_PORT -s \
225 -H "Authorization: Bearer ${ADMIN_TOKEN}" \
226 -H "Content-Type: application/json" \
228 "$KC_URL/admin/realms/$__realm/clients/$__client_id/roles" | indent1
229 if [ $? -ne 0 ]; then
230 echo "Command failed"
237 __get_service_account_id() {
238 # <realm-name> <client-id>
239 __service_account_data=$(curl --proxy $KUBERNETESHOST:$KC_PROXY_PORT -s \
241 -H "Authorization: Bearer ${ADMIN_TOKEN}" \
242 "$KC_URL/admin/realms/$1/clients/$2/service-account-user")
243 if [ $? -ne 0 ]; then
246 __service_account_id=$(echo $__service_account_data | jq -r '.id')
247 echo $__service_account_id
251 # curl --proxy $KUBERNETESHOST:$KC_PROXY_PORT -s \
253 # -H "Authorization: Bearer ${ADMIN_TOKEN}" \
254 # "$KC_URL/admin/realms/$__realm/users/$__service_account_id/role-mappings/clients/$__client_id/available"
255 __get_client_available_role_id() {
256 # <realm-name> <service-account-id> <client-id> <client-role-name>
257 __client_role_data=$(curl --proxy $KUBERNETESHOST:$KC_PROXY_PORT -s \
259 -H "Authorization: Bearer ${ADMIN_TOKEN}" \
260 "$KC_URL/admin/realms/$1/users/$2/role-mappings/clients/$3/available")
261 if [ $? -ne 0 ]; then
264 #__client_role_id=$(echo $__client_role_data | jq -r '.id')
265 __client_role_id=$(echo $__client_role_data | jq -r '.[] | select(.name=="'$4'") | .id ')
266 echo $__client_role_id
270 __get_client_mapped_role_id() {
271 # <realm-name> <service-account-id> <client-id> <client-role-name>
272 __client_role_data=$(curl --proxy $KUBERNETESHOST:$KC_PROXY_PORT -s \
274 -H "Authorization: Bearer ${ADMIN_TOKEN}" \
275 "$KC_URL/admin/realms/$1/users/$2/role-mappings/clients/$3")
276 if [ $? -ne 0 ]; then
279 #__client_role_id=$(echo $__client_role_data | jq -r '.id')
280 __client_role_id=$(echo $__client_role_data | jq -r '.[] | select(.name=="'$4'") | .id ')
281 echo $__client_role_id
285 add_client_roles_mapping() {
286 # <realm-name> <client-name> [<role-name>]+
287 echo "Attempt to add roles ${@:3} to client $2 in realm $1"
291 __client_id=$(__get_client_id $__realm $__client)
292 if [ $? -ne 0 ]; then
293 echo "Command failed"
296 echo " Client id for client $__client in realm $__realm: "$__client_id | indent1
297 __service_account_id=$(__get_service_account_id $__realm $__client_id)
298 if [ $? -ne 0 ]; then
299 echo "Command failed"
302 echo " Service account id for client $__client in realm $__realm: "$__service_account_id | indent1
306 while [ $# -gt 0 ]; do
307 if [ $__cntr -eq 0 ]; then
308 echo "[" > .jsonfile2
310 __client_role_id=$(__get_client_available_role_id $__realm $__service_account_id $__client_id $1)
311 if [ $? -ne 0 ]; then
312 echo "Command failed"
315 #echo "CLIENT ROLE ID $1 "$__client_role_id
316 #echo " Role id for role $1 and client $__client in realm $__realm: "$__client_role_id | indent1
317 __role='{"name":"'$1'","id":"'$__client_role_id'","composite": false,"clientRole": true}'
318 if [ $__cntr -gt 0 ]; then
319 echo "," >> .jsonfile2
321 echo $__role >> .jsonfile2
325 echo "]" >> .jsonfile2
326 echo " Adding roles $__all_roles to client $__client in realm $__realm"
328 curl --proxy $KUBERNETESHOST:$KC_PROXY_PORT -s \
330 -H "Authorization: Bearer ${ADMIN_TOKEN}" \
331 -H "Content-Type: application/json" \
333 "$KC_URL/admin/realms/$__realm/users/$__service_account_id/role-mappings/clients/$__client_id" | indent2
334 if [ $? -ne 0 ]; then
335 echo "Command failed"
343 remove_client_roles_mapping() {
344 # <realm-name> <client-name> [<role-name>]+
345 echo "Attempt to removed roles ${@:3} from client $2 in realm $1"
349 __client_id=$(__get_client_id $__realm $__client)
350 if [ $? -ne 0 ]; then
351 echo "Command failed"
354 echo " Client id for client $__client in realm $__realm: "$__client_id | indent1
355 __service_account_id=$(__get_service_account_id $__realm $__client_id)
356 if [ $? -ne 0 ]; then
357 echo "Command failed"
360 echo " Service account id for client $__client in realm $__realm: "$__service_account_id | indent1
364 while [ $# -gt 0 ]; do
365 if [ $__cntr -eq 0 ]; then
366 echo "[" > .jsonfile2
368 __client_role_id=$(__get_client_mapped_role_id $__realm $__service_account_id $__client_id $1)
369 if [ $? -ne 0 ]; then
370 echo "Command failed"
373 #echo "CLIENT ROLE ID $1 "$__client_role_id
374 #echo " Role id for role $1 and client $__client in realm $__realm: "$__client_role_id | indent1
375 __role='{"name":"'$1'","id":"'$__client_role_id'","composite": false,"clientRole": true}'
376 if [ $__cntr -gt 0 ]; then
377 echo "," >> .jsonfile2
379 echo $__role >> .jsonfile2
383 echo "]" >> .jsonfile2
384 echo " Removing roles $__all_roles from client $__client in realm $__realm"
386 curl --proxy $KUBERNETESHOST:$KC_PROXY_PORT -s \
388 -H "Authorization: Bearer ${ADMIN_TOKEN}" \
389 -H "Content-Type: application/json" \
391 "$KC_URL/admin/realms/$__realm/users/$__service_account_id/role-mappings/clients/$__client_id" | indent2
392 if [ $? -ne 0 ]; then
393 echo "Command failed"
399 add_client_hardcoded-claim-mapper() {
400 # <realm-name> <client-name> <mapper-name> <claim-name> <claim-value>
404 export __mapper_name=$3
405 export __claim_name=$4
406 export __claim_value=$5
408 __client_id=$(__get_client_id $__realm $__client)
409 if [ $? -ne 0 ]; then
410 echo " Fatal error when getting client id, response: "$?
413 cat > .jsonfile1 <<- "EOF"
415 "name": "$__mapper_name",
416 "protocol": "openid-connect",
417 "protocolMapper": "oidc-hardcoded-claim-mapper",
418 "consentRequired": false,
420 "claim.value": "$__claim_value",
421 "userinfo.token.claim": "true",
422 "id.token.claim": "true",
423 "access.token.claim": "true",
424 "claim.name": "$__claim_name",
425 "access.tokenResponse.claim": "false"
429 envsubst < .jsonfile1 > .jsonfile2
430 curl --proxy $KUBERNETESHOST:$KC_PROXY_PORT -s \
432 -H "Authorization: Bearer ${ADMIN_TOKEN}" \
433 -H "Content-Type: application/json" \
435 "$KC_URL/admin/realms/nonrtric-realm/clients/"$__client_id"/protocol-mappers/models" | indent2
436 if [ $? -ne 0 ]; then
437 echo "Command failed"
446 # args: <realm-name> <client-name>
451 __client_id=$(__get_client_id $__realm $__client)
452 if [ $? -ne 0 ]; then
453 echo " Fatal error when getting client id, response: "$?
456 #echo " Client id for client $__client in realm $__realm: "$__client_id | indent1
458 __client_secret=$(curl --proxy $KUBERNETESHOST:$KC_PROXY_PORT -s -f \
460 -H "Authorization: Bearer ${ADMIN_TOKEN}" \
461 "$KC_URL/admin/realms/$__realm/clients/$__client_id/client-secret")
462 if [ $? -ne 0 ]; then
463 echo " Fatal error when getting client secret, response: "$?
467 __client_secret=$(echo $__client_secret | jq -r .value)
469 __TMP_TOKEN=$(curl --proxy $KUBERNETESHOST:$KC_PROXY_PORT -f -s -X POST $KC_URL/realms/$__realm/protocol/openid-connect/token \
470 -H Content-Type:application/x-www-form-urlencoded \
471 -d client_id="$__client" -d client_secret="$__client_secret" -d grant_type=client_credentials)
472 if [ $? -ne 0 ]; then
473 echo " Fatal error when getting client token, response: "$?
477 echo $__TMP_TOKEN| jq -r .access_token