Added docker-compose ranpm
[nonrtric/plt/ranpm.git] / docker-proj / scripts / populate_keycloak.sh
diff --git a/docker-proj/scripts/populate_keycloak.sh b/docker-proj/scripts/populate_keycloak.sh
new file mode 100755 (executable)
index 0000000..0c6f148
--- /dev/null
@@ -0,0 +1,467 @@
+#!/bin/bash
+
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2023 Nordix Foundation. All rights reserved.
+#  ========================================================================
+#  Licensed under the Apache License, Version 2.0 (the "License");
+#  you may not use this file except in compliance with the License.
+#  You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+#  ============LICENSE_END=================================================
+#
+
+# Script intended to be sourced by other script to add functions to the keycloak rest API
+
+KC_URL=http://localhost:8462
+echo "Keycloak url: "$KC_URL
+
+__get_admin_token() {
+    echo "Get admin token"
+    ADMIN_TOKEN=""
+    while [ "${#ADMIN_TOKEN}" -lt 20 ]; do
+        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')
+        if [ "${#ADMIN_TOKEN}" -lt 20 ]; then
+            echo "Could not get admin token, retrying..."
+            echo "Retrieved token: $ADMIN_TOKEN"
+        fi
+    done
+    echo "Admin token: ${ADMIN_TOKEN:0:10}..."
+    echo $ADMIN_TOKEN > .admin_token
+    __ADM_TOKEN_TS=$SECONDS
+}
+
+__check_admin_token() {
+    __diff=$(($SECONDS-$__ADM_TOKEN_TS))
+    if [ $__diff -gt 15 ]; then
+        __get_admin_token
+    fi
+}
+
+__get_admin_token
+
+indent1() { sed 's/^/ /'; }
+indent2() { sed 's/^/  /'; }
+
+decode_token() {
+    echo "Decoding access_token"
+    echo $1 | jq -R 'split(".") | .[0,1] | @base64d | fromjson'
+}
+
+decode_jwt() {
+    echo "Decoding jwt"
+    echo $1 | jq -r .access_token | jq -R 'split(".") | .[0,1] | @base64d | fromjson'
+}
+
+list_realms() {
+    echo "Listing all realms"
+    __check_admin_token
+    curl -s \
+        -X GET \
+        -H "Authorization: Bearer ${ADMIN_TOKEN}" \
+        "$KC_URL/admin/realms" | jq -r '.[].id' | indent2
+}
+delete_realms() {
+    echo "$@"
+    for realm in "$@"; do
+        echo "Attempt to delete realm: $realm"
+        __check_admin_token
+        curl -s \
+        -X DELETE \
+        -H "Authorization: Bearer ${ADMIN_TOKEN}" \
+        "$KC_URL/admin/realms/$realm" | indent1
+        if [ $? -ne 0 ]; then
+            echo "Command failed"
+            exit 1
+        fi
+        echo " OK"
+    done
+}
+
+create_realms() {
+    echo "Creating realms: $@"
+    while [ $# -gt 0 ]; do
+        echo " Attempt to create realm: $1"
+        __check_admin_token
+cat > .jsonfile1 <<- "EOF"
+{
+"realm":"$__realm_name",
+"enabled":true
+}
+EOF
+        export __realm_name=$1
+        envsubst < .jsonfile1 > .jsonfile2
+        curl -s \
+        -X POST \
+        -H "Authorization: Bearer ${ADMIN_TOKEN}" \
+        -H "Content-Type: application/json" \
+        -d @".jsonfile2" \
+        "$KC_URL/admin/realms" | indent2
+        if [ $? -ne 0 ]; then
+            echo "Command failed"
+            exit 1
+        fi
+        echo "  OK"
+        shift
+    done
+}
+
+create_clients() {
+    __realm=$1
+    shift
+    echo "Attempt to create clients $@ for realm: $__realm"
+
+cat > .jsonfile1 <<- "EOF"
+{
+   "clientId":"$__client_name",
+   "publicClient": false,
+   "serviceAccountsEnabled": true,
+   "rootUrl":"https://example.com/example/",
+   "adminUrl":"https://example.com/example/"
+}
+EOF
+    while [ $# -gt 0 ]; do
+        echo " Creating client: $1"
+        __check_admin_token
+        export __client_name=$1
+        envsubst < .jsonfile1 > .jsonfile2
+        curl -s \
+        -X POST \
+        -H "Authorization: Bearer ${ADMIN_TOKEN}" \
+        -H "Content-Type: application/json" \
+        -d @".jsonfile2" \
+        "$KC_URL/admin/realms/$__realm/clients" | indent1
+        if [ $? -ne 0 ]; then
+            echo "Command failed"
+            exit 1
+        fi
+        echo " OK"
+        shift
+    done
+}
+
+__get_client_id() {
+    __client_data=$(curl -s \
+        -X GET \
+        -H "Authorization: Bearer ${ADMIN_TOKEN}" \
+        "$KC_URL/admin/realms/$1/clients?clientId=$2")
+    if [ $? -ne 0 ]; then
+        return 1
+    fi
+    __client_id=$(echo $__client_data |  jq -r '.[0].id')
+    echo $__client_id
+    return 0
+}
+
+generate_client_secrets() {
+    __realm=$1
+    shift
+    echo "Attempt to generate secret for clients $@ in realm $__realm"
+    while [ $# -gt 0 ]; do
+        __check_admin_token
+        __client_id=$(__get_client_id $__realm $1)
+        if [ $? -ne 0 ]; then
+            echo "Command failed"
+            exit 1
+        fi
+        echo " Client id for client $1 in realm $__realm: "$__client_id | indent1
+        echo "  Creating secret"
+        __client_secret=$(curl -s \
+                -X POST \
+                -H "Authorization: Bearer ${ADMIN_TOKEN}" \
+                "$KC_URL/admin/realms/$__realm/clients/$__client_id/client-secret")
+        if [ $? -ne 0 ]; then
+            echo "Command failed"
+            exit 1
+        fi
+        __client_secret=$(curl -s \
+                -X GET \
+                -H "Authorization: Bearer ${ADMIN_TOKEN}" \
+                "$KC_URL/admin/realms/$__realm/clients/$__client_id/client-secret")
+        if [ $? -ne 0 ]; then
+            echo "Command failed"
+            exit 1
+        fi
+        __client_secret=$(echo $__client_secret | jq -r .value)
+        echo "  Client secret for client $1 in realm $__realm: "$__client_secret | indent1
+        echo $__client_secret > ".sec_$__realm""_$1"
+        echo "   OK"
+        shift
+    done
+}
+
+create_client_roles() {
+    # <realm-name> <client-name> [<role-name>]+
+    __check_admin_token
+    __client_id=$(__get_client_id $1 $2)
+    if [ $? -ne 0 ]; then
+        echo "Command failed"
+        exit 1
+    fi
+    __realm=$1
+    shift; shift;
+    while [ $# -gt 0 ]; do
+
+cat > .jsonfile1 <<- "EOF"
+{
+   "name":"$__role"
+}
+EOF
+        export __role=$1
+        envsubst < .jsonfile1 > .jsonfile2
+        curl -s \
+        -X POST \
+        -H "Authorization: Bearer ${ADMIN_TOKEN}" \
+        -H "Content-Type: application/json" \
+        -d @".jsonfile2" \
+        "$KC_URL/admin/realms/$__realm/clients/$__client_id/roles" | indent1
+        if [ $? -ne 0 ]; then
+            echo "Command failed"
+            exit 1
+        fi
+        shift
+    done
+}
+
+__get_service_account_id() {
+    # <realm-name> <client-id>
+    __service_account_data=$(curl -s \
+        -X GET \
+        -H "Authorization: Bearer ${ADMIN_TOKEN}" \
+        "$KC_URL/admin/realms/$1/clients/$2/service-account-user")
+    if [ $? -ne 0 ]; then
+        return 1
+    fi
+    __service_account_id=$(echo $__service_account_data |  jq -r '.id')
+    echo $__service_account_id
+    return 0
+}
+
+__get_client_available_role_id() {
+    # <realm-name> <service-account-id> <client-id> <client-role-name>
+    __client_role_data=$(curl -s \
+        -X GET \
+        -H "Authorization: Bearer ${ADMIN_TOKEN}" \
+        "$KC_URL/admin/realms/$1/users/$2/role-mappings/clients/$3/available")
+    if [ $? -ne 0 ]; then
+        return 1
+    fi
+    #__client_role_id=$(echo $__client_role_data |  jq -r '.id')
+    __client_role_id=$(echo $__client_role_data | jq  -r '.[] | select(.name=="'$4'") | .id ')
+    echo $__client_role_id
+    return 0
+}
+
+__get_client_mapped_role_id() {
+    # <realm-name> <service-account-id> <client-id> <client-role-name>
+    __client_role_data=$(curl -s \
+        -X GET \
+        -H "Authorization: Bearer ${ADMIN_TOKEN}" \
+        "$KC_URL/admin/realms/$1/users/$2/role-mappings/clients/$3")
+    if [ $? -ne 0 ]; then
+        return 1
+    fi
+    #__client_role_id=$(echo $__client_role_data |  jq -r '.id')
+    __client_role_id=$(echo $__client_role_data | jq  -r '.[] | select(.name=="'$4'") | .id ')
+    echo $__client_role_id
+    return 0
+}
+
+add_client_roles_mapping()  {
+    # <realm-name> <client-name> [<role-name>]+
+    echo "Attempt to add roles ${@:3} to client $2 in realm $1"
+    __check_admin_token
+    __realm=$1
+    __client=$2
+    __client_id=$(__get_client_id $__realm $__client)
+    if [ $? -ne 0 ]; then
+        echo "Command failed"
+        exit 1
+    fi
+    echo " Client id for client $__client in realm $__realm: "$__client_id | indent1
+    __service_account_id=$(__get_service_account_id $__realm $__client_id)
+    if [ $? -ne 0 ]; then
+        echo "Command failed"
+        exit 1
+    fi
+    echo " Service account id for client $__client in realm $__realm: "$__service_account_id | indent1
+    shift; shift
+    __cntr=0
+    __all_roles=$@
+    while [ $# -gt 0 ]; do
+        if [ $__cntr -eq 0 ]; then
+            echo "[" > .jsonfile2
+        fi
+        __client_role_id=$(__get_client_available_role_id $__realm $__service_account_id $__client_id $1)
+        if [ $? -ne 0 ]; then
+            echo "Command failed"
+            exit 1
+        fi
+
+        __role='{"name":"'$1'","id":"'$__client_role_id'","composite": false,"clientRole": true}'
+        if [ $__cntr -gt 0 ]; then
+            echo "," >> .jsonfile2
+        fi
+        echo $__role >> .jsonfile2
+        let __cntr=__cntr+1
+        shift
+    done
+    echo "]" >> .jsonfile2
+    echo "  Adding roles $__all_roles to client $__client in realm $__realm"
+
+    curl -s \
+    -X POST \
+    -H "Authorization: Bearer ${ADMIN_TOKEN}" \
+    -H "Content-Type: application/json" \
+    -d @".jsonfile2" \
+    "$KC_URL/admin/realms/$__realm/users/$__service_account_id/role-mappings/clients/$__client_id" | indent2
+    if [ $? -ne 0 ]; then
+        echo "Command failed"
+        exit 1
+    fi
+    echo "  OK"
+}
+
+
+
+remove_client_roles_mapping()  {
+    # <realm-name> <client-name> [<role-name>]+
+    echo "Attempt to removed roles ${@:3} from client $2 in realm $1"
+    __check_admin_token
+    __realm=$1
+    __client=$2
+    __client_id=$(__get_client_id $__realm $__client)
+    if [ $? -ne 0 ]; then
+        echo "Command failed"
+        exit 1
+    fi
+    echo " Client id for client $__client in realm $__realm: "$__client_id | indent1
+    __service_account_id=$(__get_service_account_id $__realm $__client_id)
+    if [ $? -ne 0 ]; then
+        echo "Command failed"
+        exit 1
+    fi
+    echo " Service account id for client $__client in realm $__realm: "$__service_account_id | indent1
+    shift; shift
+    __cntr=0
+    __all_roles=$@
+    while [ $# -gt 0 ]; do
+        if [ $__cntr -eq 0 ]; then
+            echo "[" > .jsonfile2
+        fi
+        __client_role_id=$(__get_client_mapped_role_id $__realm $__service_account_id $__client_id $1)
+        if [ $? -ne 0 ]; then
+            echo "Command failed"
+            exit 1
+        fi
+
+        __role='{"name":"'$1'","id":"'$__client_role_id'","composite": false,"clientRole": true}'
+        if [ $__cntr -gt 0 ]; then
+            echo "," >> .jsonfile2
+        fi
+        echo $__role >> .jsonfile2
+        let __cntr=__cntr+1
+        shift
+    done
+    echo "]" >> .jsonfile2
+    echo "  Removing roles $__all_roles from client $__client in realm $__realm"
+
+    curl -s \
+    -X DELETE \
+    -H "Authorization: Bearer ${ADMIN_TOKEN}" \
+    -H "Content-Type: application/json" \
+    -d @".jsonfile2" \
+    "$KC_URL/admin/realms/$__realm/users/$__service_account_id/role-mappings/clients/$__client_id" | indent2
+    if [ $? -ne 0 ]; then
+        echo "Command failed"
+        exit 1
+    fi
+    echo "  OK"
+}
+
+add_client_hardcoded-claim-mapper() {
+# <realm-name> <client-name> <mapper-name> <claim-name> <claim-value>
+    __check_admin_token
+    __realm=$1
+    __client=$2
+    export __mapper_name=$3
+    export __claim_name=$4
+    export __claim_value=$5
+
+    __client_id=$(__get_client_id $__realm $__client)
+    if [ $? -ne 0 ]; then
+        echo " Fatal error when getting client id, response: "$?
+        exit 1
+    fi
+    cat > .jsonfile1 <<- "EOF"
+{
+    "name": "$__mapper_name",
+    "protocol": "openid-connect",
+    "protocolMapper": "oidc-hardcoded-claim-mapper",
+    "consentRequired": false,
+    "config": {
+      "claim.value": "$__claim_value",
+      "userinfo.token.claim": "true",
+      "id.token.claim": "true",
+      "access.token.claim": "true",
+      "claim.name": "$__claim_name",
+      "access.tokenResponse.claim": "false"
+    }
+}
+EOF
+    envsubst < .jsonfile1 > .jsonfile2
+    curl -s \
+    -X POST \
+    -H "Authorization: Bearer ${ADMIN_TOKEN}" \
+    -H "Content-Type: application/json" \
+    -d @".jsonfile2" \
+    "$KC_URL/admin/realms/nonrtric-realm/clients/"$__client_id"/protocol-mappers/models" | indent2
+    if [ $? -ne 0 ]; then
+        echo "Command failed"
+        exit 1
+    fi
+    set +x
+    cat .jsonfile2
+    echo "  OK"
+}
+
+# Get a client token
+# args: <realm-name> <client-name>
+get_client_token() {
+    __check_admin_token
+    __realm=$1
+    __client=$2
+    __client_id=$(__get_client_id $__realm $__client)
+    if [ $? -ne 0 ]; then
+        echo " Fatal error when getting client id, response: "$?
+        exit 1
+    fi
+
+    __client_secret=$(curl -s -f \
+            -X GET \
+            -H "Authorization: Bearer ${ADMIN_TOKEN}" \
+            "$KC_URL/admin/realms/$__realm/clients/$__client_id/client-secret")
+    if [ $? -ne 0 ]; then
+        echo " Fatal error when getting client secret, response: "$?
+        exit 1
+    fi
+
+    __client_secret=$(echo $__client_secret | jq -r .value)
+
+       __TMP_TOKEN=$(curl -s -f -X POST $KC_URL/realms/$__realm/protocol/openid-connect/token   \
+                  -H Content-Type:application/x-www-form-urlencoded \
+                  -d client_id="$__client" -d client_secret="$__client_secret" -d grant_type=client_credentials)
+       if [ $? -ne 0 ]; then
+               echo " Fatal error when getting client token, response: "$?
+               exit 1
+       fi
+
+       echo $__TMP_TOKEN| jq -r .access_token
+       return 0
+}