-
Notifications
You must be signed in to change notification settings - Fork 4
/
htdecodetoken
executable file
·143 lines (125 loc) · 3.03 KB
/
htdecodetoken
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#!/bin/bash
# Based on
# https://gist.github.com/thomasdarimont/46358bc8167fce059d83a1ebdb92b0e7
# Modified to understand WLCG Bearer Token Discovery and to have an option
# to print the algorithm in the first part of the token
usage()
{
echo 'Usage: htdecodetoken [-a] [-H] [file]'
echo
echo 'Decodes a JSON Web Token'
echo ' -a: show algorithm portion of JWT'
echo ' -H: show dates in human readable format instead of epoch'
echo 'File name may be "-" to read from stdin.'
echo 'If file name not given, follows WLCG Bearer Token Discovery'
echo ' which is to first try $BEARER_TOKEN, next $BEARER_TOKEN_FILE,'
echo ' and next ${XDG_RUNTIME_DIR:-/tmp}/bt_u`id -u`.'
echo 'If scitokens-verify is available, will also validate the token.'
exit 1
} >&2
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 --decode
}
decode_jwt() {
local showalg=$1
local token=$2
if "$showalg" ; then
decode_base64_url "$(echo "$token"|cut -d. -f1)" | jq .
fi
decode_base64_url "$(echo "$token"|cut -d. -f2)" | jq .
}
human_dates() {
local wrd
local w1
local date
for wrd in "$@"; do
w1=${wrd/,/}
if [[ "$w1" =~ ^[0-9]+$ ]]; then
# field is entirely numeric
echo -n "\"$(date --date=@$w1)\""
if [ "$wrd" != "$w1" ]; then
# add the comma back
echo ','
else
echo
fi
else
echo "$wrd"
fi
done
}
# script starts here -- "main"
set -e
SHOWALG=false
HUMANDATE=false
NUMSHIFT=0
while getopts ":aH" opt; do
case "$opt" in
a)
SHOWALG=true
(( NUMSHIFT+=1 ))
;;
H)
HUMANDATE=true
(( NUMSHIFT+=1 ))
;;
*)
usage
esac
done
shift "$NUMSHIFT"
TOKEN=""
TOKENFILE=""
if [ $# = 0 ]; then
if [ -n "$BEARER_TOKEN" ]; then
TOKEN="$BEARER_TOKEN"
else
TOKENFILE="${BEARER_TOKEN_FILE:-${XDG_RUNTIME_DIR:-/tmp}/bt_u`id -u`}"
fi
elif [ $# = 1 ]; then
if [ "$1" = - ]; then
read TOKEN # from stdin
else
TOKENFILE="$1"
fi
else
usage
fi
if [ -n "$TOKENFILE" ]; then
if [ ! -e "$TOKENFILE" ]; then
echo "$TOKENFILE not found" >&2
exit 1
fi
# the -n is needed here for when there is no ending newline in the file
read TOKEN <$TOKENFILE || [ -n "$TOKEN" ]
fi
if [ -z "$TOKEN" ]; then
echo "Token is empty" >&2
usage
fi
JWT="$(decode_jwt "$SHOWALG" "$TOKEN")"
if "$HUMANDATE" ; then
READABLE="$(human_dates $JWT)"
echo $READABLE | jq .
else
echo "$JWT" | jq .
fi
set +e
VERIFY="$(command -v scitokens-verify)"
if [ $? != 0 ]; then
# silently exit if scitokens-verify not found
exit
fi
VERIFYOUT="$($VERIFY $TOKEN)"
RET=$?
if [ $RET != 0 ]; then
if [ -n "$VERIFYOUT" ]; then
echo "$VERIFYOUT" >&2
fi
exit $RET
fi