-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathfreeboxos_bash_api.sh
255 lines (226 loc) · 7.24 KB
/
freeboxos_bash_api.sh
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
#!/bin/bash
_API_VERSION=
_API_BASE_URL=
_SESSION_TOKEN=
######## GLOBAL VARIABLES ########
_JSON_DATA=
_JSON_DECODE_DATA_KEYS=
_JSON_DECODE_DATA_VALUES=
case "$OSTYPE" in
darwin*) SED_REX='-E' ;;
*) SED_REX='-r' ;;
esac
if echo "test string" | egrep -ao --color=never "test" &>/dev/null; then
GREP='egrep -ao --color=never'
else
GREP='egrep -ao'
fi
######## FUNCTIONS ########
######## FUNCTIONS FROM JSON.SH ########
# This is from https://github.com/dominictarr/JSON.sh
# See LICENSE for more info.
_throw () {
echo "$*" >&2
exit 1
}
_tokenize_json () {
local ESCAPE='(\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})'
local CHAR='[^[:cntrl:]"\\]'
local STRING="\"$CHAR*($ESCAPE$CHAR*)*\""
# The Freebox api don't put quote between string values
# STRING2 solve this problem
local STRING2="[^:,][a-zA-Z][a-zA-Z0-9_-]*[^],}]"
local NUMBER='-?(0|[1-9][0-9]*)([.][0-9]*)?([eE][+-]?[0-9]*)?'
local KEYWORD='null|false|true'
local SPACE='[[:space:]]+'
$GREP "$STRING|$STRING2|$NUMBER|$KEYWORD|$SPACE|." | egrep -v "^$SPACE$"
# " Fix xemacs fontification
}
_parse_array () {
local index=0
local ary=''
read -r token
case "$token" in
']') ;;
*)
while : ; do
_parse_value "${1%*.}" "[$index]."
index=$((index+1))
ary="$ary""$value"
read -r token
case "$token" in
']') break ;;
',') ary="$ary," ;;
*) _throw "EXPECTED , or ] GOT ${token:-EOF}" ;;
esac
read -r token
done
;;
esac
value=$(printf '[%s]' "$ary")
}
_parse_object () {
local key
local obj=''
read -r token
case "$token" in
'}') ;;
*)
while : ; do
case "$token" in
'"'*'"') key=$token;;
*) _throw "EXPECTED string GOT ${token:-EOF}" ;;
esac
read -r token
case "$token" in
':') ;;
*) _throw "EXPECTED : GOT ${token:-EOF}" ;;
esac
read -r token
_parse_value "$1" "$key"
obj="$obj$key:$value"
read -r token
case "$token" in
'}') break ;;
',') obj="$obj," ;;
*) _throw "EXPECTED , or } GOT ${token:-EOF}" ;;
esac
read -r token
done
;;
esac
value=$(printf '{%s}' "$obj")
}
_parse_value () {
local jpath="${1:-}${2:-}"
case "$token" in
'{') _parse_object "$jpath" ;;
'[') _parse_array "$jpath";;
# At this point, the only valid single-character tokens are digits.
''|[!0-9]) _throw "EXPECTED value GOT ${token:-EOF}" ;;
*) value=$token ;;
esac
[ "${value:-}" = '' ] && return
jpath=${jpath//\"\"/.}
jpath=${jpath//\"/}
local key="${jpath%*.}"
[[ "$key" = '' ]] && return
_JSON_DECODE_DATA_KEYS+=("$key")
value=${value#\"} # Remove leading "
value=${value%*\"} # Remove trailing "
value=${value//\\\///} # convert \/ to /
_JSON_DECODE_DATA_VALUES+=("$value")
}
_parse_json () {
read -r token
_parse_value
read -r token
case "$token" in
'') ;;
*) _throw "EXPECTED EOF GOT $token" ;;
esac
}
######## END OF FUNCTIONS FROM JSON.SH ########
function _parse_and_cache_json {
if [[ "$_JSON_DATA" != "$1" ]]; then
_JSON_DATA="$1"
_JSON_DECODE_DATA_KEYS=("")
_JSON_DECODE_DATA_VALUES=("")
_parse_json < <(echo "$_JSON_DATA" | _tokenize_json)
fi
}
function get_json_value_for_key {
_parse_and_cache_json "$1"
local key i=1 max_index=${#_JSON_DECODE_DATA_KEYS[@]};
while [[ $i -lt $max_index ]]; do
if [[ "${_JSON_DECODE_DATA_KEYS[$i]}" = "$2" ]]; then
echo ${_JSON_DECODE_DATA_VALUES[$i]}
return 0
fi
((i++))
done
return 1
}
function dump_json_keys_values {
_parse_and_cache_json "$1"
local key i=1 max_index=${#_JSON_DECODE_DATA_KEYS[@]};
while [[ $i -lt $max_index ]]; do
printf "%s = %s\n" "${_JSON_DECODE_DATA_KEYS[$i]}" "${_JSON_DECODE_DATA_VALUES[$i]}"
((i++))
done
}
function _check_success {
local value=$(get_json_value_for_key "$1" success)
if [[ "$value" != true ]]; then
echo "$(get_json_value_for_key "$1" msg): $(get_json_value_for_key "$1" error_code)" >&2
return 1
fi
return 0
}
function _check_freebox_api {
local answer=$(curl --insecure -s "$FREEBOX_URL/api_version")
_API_VERSION=$(get_json_value_for_key "$answer" api_version | sed 's/\..*//')
_API_BASE_URL=$(get_json_value_for_key "$answer" api_base_url)
}
function call_freebox_api {
local api_url="$1"
local data="${2-}"
local options=("")
local url="$FREEBOX_URL"$( echo "/$_API_BASE_URL/v$_API_VERSION/$api_url" | sed 's@//@/@g')
[[ -n "$_SESSION_TOKEN" ]] && options+=(-H "X-Fbx-App-Auth: $_SESSION_TOKEN")
[[ -n "$data" ]] && options+=(-d "$data")
answer=$(curl --insecure -s "$url" "${options[@]}")
_check_success "$answer" || return 1
echo "$answer"
}
function call_freebox_api_put {
local api_url="$1"
local data="${2-}"
local options=("")
local url="$FREEBOX_URL"$( echo "/$_API_BASE_URL/v$_API_VERSION/$api_url" | sed 's@//@/@g')
[[ -n "$_SESSION_TOKEN" ]] && options+=(-H "X-Fbx-App-Auth: $_SESSION_TOKEN")
[[ -n "$data" ]] && options+=(-d "$data")
answer=$(curl --insecure -X PUT -s "$url" "${options[@]}")
_check_success "$answer" || return 1
echo "$answer"
}
function login_freebox {
local APP_ID="$1"
local APP_TOKEN="$2"
local answer=
answer=$(call_freebox_api 'login') || return 1
local challenge=$(get_json_value_for_key "$answer" "result.challenge")
local password=$(echo -n "$challenge" | openssl dgst -sha1 -hmac "$APP_TOKEN" | sed 's/^(stdin)= //')
answer=$(call_freebox_api '/login/session/' "{\"app_id\":\"${APP_ID}\", \"password\":\"${password}\" }") || return 1
_SESSION_TOKEN=$(get_json_value_for_key "$answer" "result.session_token")
}
function authorize_application {
local APP_ID="$1"
local APP_NAME="$2"
local APP_VERSION="$3"
local DEVICE_NAME="$4"
local answer=
answer=$(call_freebox_api 'login/authorize' "{\"app_id\":\"${APP_ID}\", \"app_name\":\"${APP_NAME}\", \"app_version\":\"${APP_VERSION}\", \"device_name\":\"${DEVICE_NAME}\" }")
local app_token=$(get_json_value_for_key "$answer" "result.app_token")
local track_id=$(get_json_value_for_key "$answer" "result.track_id")
echo 'Please grant/deny access to the application on the Freebox LCD...' >&2
local status='pending'
while [[ "$status" == 'pending' ]]; do
sleep 5
answer=$(call_freebox_api "login/authorize/$track_id")
status=$(get_json_value_for_key "$answer" "result.status")
done
echo "Authorization $status" >&2
[[ "$status" != 'granted' ]] && return 1
echo >&2
cat <<EOF
MY_APP_ID="$APP_ID"
MY_APP_TOKEN="$app_token"
EOF
}
function reboot_freebox {
call_freebox_api '/system/reboot' '{}' >/dev/null
}
######## MAIN ########
# fill _API_VERSION and _API_BASE_URL variables
_check_freebox_api