blob: 3739c9cef71ed413ff8555522a323e4a67f88699 (
about) (
plain)
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
|
#!/bin/sh
# This file is part of Haketilo
#
# Copyright (C) 2021, Wojtek Kosior
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the CC0 1.0 Universal License as published by
# the Creative Commons Corporation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# CC0 1.0 Universal License for more details.
set -e
. ./shell_utils.sh
_PROG_NAME="$0"
OPERATION="$1"
API_KEY="$2"
SECRET="$3"
XPI_PATH="$4"
escape_regex_special() {
printf %s "$1" | sed 's/\([]\.*[-]\)/\\\1/g'
}
# Note: We don't actually parse JSON. We extract needed keys with sed regexes
# which does not work in the general case but is sufficient for now.
_get_json_key() {
local KEY_REG="$(escape_regex_special "$1")"
printf %s "$2" |
awk '{printf "%s", $0}' |
sed 's/^.*\("'"$KEY_REG"'"[[:space:]]*:[[:space:]]*"\([^"]*\)"\).*$/\2/'
}
get_json_key() {
local JSON="$2"
local VALUE="$(_get_json_key "$@")"
if [ "x$VALUE" != "x$JSON" ]; then
printf %s "$VALUE"
fi
}
base64url() {
printf %s "$1" | base64 -w 0 | tr '/+' '_-' | tr -d '='
}
sha256hmac() {
base64url "$(printf %s "$2" | openssl dgst -sha256 -hmac "$1" -binary -)"
}
get_manifest_key() {
get_json_key "$1" "$(unzip -p "$2" manifest.json)"
}
generate_jwt() {
local JWT_HEAD='{"alg":"HS256", "typ":"JWT"}'
local JWT_ID=$(dd if=/dev/random bs=21 count=1 2>/dev/null | base64)
local ISSUED_AT_TIME=$(date -u +%s)
local EXPIRATION_TIME=$((ISSUED_AT_TIME + 300))
local JWT_PAYLOAD="$(cat <<EOF
{
"iss": "$API_KEY",
"jti": "$JWT_ID",
"iat": $ISSUED_AT_TIME,
"exp": $EXPIRATION_TIME
}
EOF
)"
local JWT_MESSAGE=$(base64url "$JWT_HEAD").$(base64url "$JWT_PAYLOAD")
local JWT_SIGNATURE=$(sha256hmac "$SECRET" "$JWT_MESSAGE")
local JWT=$JWT_MESSAGE.$JWT_SIGNATURE
printf "Using JWT: $JWT\n" >&2
printf $JWT
}
get_extension_url() {
EXTENSION_ID="$(get_manifest_key id "$XPI_PATH")"
EXTENSION_VER="$(get_manifest_key version "$XPI_PATH")"
if [ -z "$EXTENSION_ID" -o -z "$EXTENSION_VER" ]; then
printf "Couldn't extract extension id and version. Please check if %s contains proper manifest.json file.\n" \
"$XPI_PATH" >&2
exit 1
fi
printf 'https://addons.mozilla.org/api/v4/addons/%s/versions/%s/' \
"$EXTENSION_ID" "$EXTENSION_VER"
}
print_usage() {
printf 'Usage: %s upload|check|test API_KEY SECRET XPI_PATH\n' \
"$_PROG_NAME" >&2
}
if [ $# != 4 ]; then
print_usage
exit 1
fi
unset RETURNED_DATA
case "$OPERATION" in
test)
curl "https://addons.mozilla.org/api/v4/accounts/profile/" \
-g -H "Authorization: JWT $(generate_jwt)"
printf '\n'
;;
check)
RETURNED_DATA="$(curl $(get_extension_url) \
-g -H "Authorization: JWT $(generate_jwt)")"
;;
upload)
RETURNED_DATA="$(curl $(get_extension_url) \
-g -XPUT --form "upload=@$XPI_PATH" \
-H "Authorization: JWT $(generate_jwt)")"
;;
*)
print_usage
exit 1
;;
esac
if [ -n "$RETURNED_DATA" ]; then
printf "addons.mozilla.org says:\n%s\n" "$RETURNED_DATA"
DOWNLOAD_URL="$(get_json_key download_url "$RETURNED_DATA")"
if [ -n "$DOWNLOAD_URL" ]; then
printf "Downloading extension file from %s\n" "$DOWNLOAD_URL"
curl "$DOWNLOAD_URL" -g -H "Authorization: JWT $(generate_jwt)" -O
fi
fi
|