Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve DRO validation step #1667

Open
benbakowski opened this issue Feb 24, 2025 · 0 comments
Open

Improve DRO validation step #1667

benbakowski opened this issue Feb 24, 2025 · 0 comments
Labels
Enhancement New feature or request

Comments

@benbakowski
Copy link
Contributor

Feature and motivation

We've had a number of cases where installations have failed at the DRO stage, and this has been tracked to malformed redhat-marketplace-pull-secret secrets.

Extend the DRO installation role so that we validate the provided secret in step

.

Validation logic can be seen in:

#!/usr/bin/env bash

# This script is use to parse jwt token and get the required details from it.

PROGDIR="$( cd `dirname $0` ; pwd )"

function usage(){
    echo "---------------------------------------------------------------------------------------"
    echo "Usage: "
    echo "      Use this script to get the field(s) value from accesstoken body in properties file."
    echo "      script:  "
    echo "          ./parse-jwt-token.sh -t <jwt-accesstoken> -f <field-name> [-v <is-valid-for-seconds>]"
    echo "      args:"
    echo "          - t i.e: <jwt-accesstoken> is accesstoken generated from external identity."
    echo "          - f i.e: <field-name> can be comma separated values "
    echo "      optional:"
    echo "          - v when provided , it checks the token is valid for that many seconds or not."
    echo "---------------------------------------------------------------------------------------"
}

declare -A OPTIONS
# read options  
while [[ "$#" -gt 0 ]]; do
  OPTION="$1"
  shift
  case $OPTION in
  -h | --help | help)
        usage
        exit 0
        ;;
  -t | --jwt)
    TOKEN_TO_PARSE="$1"
    shift
    ;;
  -f | --field)
    FIELDS_TO_FETCH="$1"
    shift
    ;;
  -v | --valid-for-seconds)
    VALIDITY_FOR_SECONDS="$1"
    shift
    ;;
  *)
    VALUE="$1"
    OPTIONS["$OPTION"]="$VALUE"
    shift
    ;;
  esac
done

function check_if_accecc_token_valid(){
    exp_value=$1
    #alertThreshold=600
    alertThreshold=$VALIDITY_FOR_SECONDS
    echo "exp_value  $exp_value"

    exp_time_converted_to_datetime=$(date -d @$exp_value)
    echo "exp_time_converted_to_datetime = $exp_time_converted_to_datetime"

    startTime=$exp_value
    currentTime=$(date +%s)
    echo "currentTime = $currentTime"
    #alertThreshold=600
    currentTime_after_threshold=`expr $currentTime + $alertThreshold`
    echo "currentTime_after_threshold = $currentTime_after_threshold"

    current_time_converted_to_datetime=$(date -d @$currentTime_after_threshold)
    echo "current_time_converted_to_datetime = $current_time_converted_to_datetime"

    if [[ $exp_time_converted_to_datetime > $current_time_converted_to_datetime ]];then
        echo "TOKEN VALID."
        return 0
    else
        echo "TOKEN EXPIRED."
        return 1
    fi
}

function decode_base64_url() {
  local len=$((${#1} % 4))
  local result="$1"
  if [ $len -eq 2 ]; then result="$1"'=='
  elif [ $len -eq 3 ]; then result="$1"'=' 
  fi
  echo "$result" | tr '_-' '/+' | base64 -d
}

# $1 => JWT to decode
# $2 => either 1 for header or 2 for body (default is 2)
function decode_jwt_body() {
    decode_base64_url $(echo -n $1 | cut -d "." -f ${2:-2}) | jq .; 
}

function main(){
    #echo "$TOKEN_TO_PARSE"
    JWT_BODY_DECODED=$(decode_jwt_body $TOKEN_TO_PARSE)
    # echo "JWT_BODY_DECODED = $JWT_BODY_DECODED"
    
    if [[ ! -z $VALIDITY_FOR_SECONDS ]];then
        echo "check if token is valid for next $VALIDITY_FOR_SECONDS seconds."
        exp_value=$(echo $JWT_BODY_DECODED | jq '.exp')
        echo "exp : $exp_value"
        # validate if token is valid for new
        check_if_accecc_token_valid "$exp_value"
        rc=$?
        if [ $rc -ne 0 ]; then
            echo "!!! ERROR !!! INVALID TOKEN."
            exit 1
        fi
    fi
    
    if [[ ! -z $FIELDS_TO_FETCH ]];then
        local local_jwt_prop_file_path="${PROGDIR}/jwt-extracted.properties"
        IFS=', ' read -r -a arr_fields_name <<< "$FIELDS_TO_FETCH"
        > $local_jwt_prop_file_path
        for field_name in "${arr_fields_name[@]}"
        do
            echo "$field_name"
            field_value=$(echo $JWT_BODY_DECODED | jq '.'$field_name'[] | .')
            if [[ -z $field_value ]];then
                field_value=$(echo $JWT_BODY_DECODED | jq '.'$field_name'')
            fi
            echo "field_name: $field_name"
            echo "field_value: $field_value"
            echo "----------------------------------------------------------"

            if [[ $field_name == "groups" ]];then
                SRE_MCSP_GROUPS_TOKEN_VALUE=""
                declare -a field_value_as_arr=($field_value)
                delim=","
                SRE_MCSP_GROUPS_TOKEN_VALUE=""
                for item in "${field_value_as_arr[@]}"; do
                    SRE_MCSP_GROUPS_TOKEN_VALUE="$SRE_MCSP_GROUPS_TOKEN_VALUE$delim$item"
                    delim=","
                done
                echo "$SRE_MCSP_GROUPS_TOKEN_VALUE"
                field_value=$(echo "${SRE_MCSP_GROUPS_TOKEN_VALUE/,/}")                
            fi
            field_value=$(echo $field_value | tr -d '"')
            printf '%s\n' "$field_name=${field_value}" >> $local_jwt_prop_file_path
        done
        first_access_token_value=$(echo $TOKEN_TO_PARSE | tr -d '"' )
        printf '%s\n' "first_access_token=${first_access_token_value}" >> $local_jwt_prop_file_path
    fi
}
main

Usage example

No change in the experience, just helps catch errors in incorrect ER keys.

@benbakowski benbakowski added the Enhancement New feature or request label Feb 24, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant