Project

General

Profile

Download (3.4 KB) Statistics
| Branch: | Tag: | Revision:

haketilo / upload_amo.sh @ 098e5e50

1
#!/bin/sh
2

    
3
# This file is part of Haketilo
4
#
5
# Copyright (C) 2021, Wojtek Kosior
6
#
7
# This program is free software: you can redistribute it and/or modify
8
# it under the terms of the CC0 1.0 Universal License as published by
9
# the Creative Commons Corporation.
10
#
11
# This program is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
# CC0 1.0 Universal License for more details.
15

    
16
set -e
17

    
18
. ./shell_utils.sh
19

    
20
_PROG_NAME="$0"
21
OPERATION="$1"
22
API_KEY="$2"
23
SECRET="$3"
24
XPI_PATH="$4"
25

    
26
escape_regex_special() {
27
    printf %s "$1" | sed 's/\([]\.*[-]\)/\\\1/g'
28
}
29

    
30
# Note: We don't actually parse JSON. We extract needed keys with sed regexes
31
# which does not work in the general case but is sufficient for now.
32
_get_json_key() {
33
    local KEY_REG="$(escape_regex_special "$1")"
34
    printf %s "$2" |
35
	awk '{printf "%s", $0}' |
36
	sed 's/^.*\("'"$KEY_REG"'"[[:space:]]*:[[:space:]]*"\([^"]*\)"\).*$/\2/'
37
}
38

    
39
get_json_key() {
40
    local JSON="$2"
41
    local VALUE="$(_get_json_key "$@")"
42
    if [ "x$VALUE" != "x$JSON" ]; then
43
	printf %s "$VALUE"
44
    fi
45
}
46

    
47
base64url() {
48
    printf %s "$1" | base64 -w 0 | tr '/+' '_-' | tr -d '='
49
}
50

    
51
sha256hmac() {
52
    base64url "$(printf %s "$2" | openssl dgst -sha256 -hmac "$1" -binary -)"
53
}
54

    
55
get_manifest_key() {
56
    get_json_key "$1" "$(unzip -p "$2" manifest.json)"
57
}
58

    
59
generate_jwt() {
60
    local JWT_HEAD='{"alg":"HS256", "typ":"JWT"}'
61
    local JWT_ID=$(dd if=/dev/random bs=21 count=1 2>/dev/null | base64)
62
    local ISSUED_AT_TIME=$(date -u +%s)
63
    local EXPIRATION_TIME=$((ISSUED_AT_TIME + 300))
64
    local JWT_PAYLOAD="$(cat <<EOF
65
{
66
    "iss": "$API_KEY",
67
    "jti": "$JWT_ID",
68
    "iat": $ISSUED_AT_TIME,
69
    "exp": $EXPIRATION_TIME
70
}
71
EOF
72
	  )"
73
    local JWT_MESSAGE=$(base64url "$JWT_HEAD").$(base64url "$JWT_PAYLOAD")
74
    local JWT_SIGNATURE=$(sha256hmac "$SECRET" "$JWT_MESSAGE")
75
    local JWT=$JWT_MESSAGE.$JWT_SIGNATURE
76
    printf "Using JWT: $JWT\n" >&2
77
    printf $JWT
78
}
79

    
80
get_extension_url() {
81
    EXTENSION_ID="$(get_manifest_key id "$XPI_PATH")"
82
    EXTENSION_VER="$(get_manifest_key version "$XPI_PATH")"
83

    
84
    if [ -z "$EXTENSION_ID" -o -z "$EXTENSION_VER" ]; then
85
	printf "Couldn't extract extension id and version. Please check if %s contains proper manifest.json file.\n" \
86
	       "$XPI_PATH" >&2
87
	exit 1
88
    fi
89

    
90
    printf 'https://addons.mozilla.org/api/v4/addons/%s/versions/%s/' \
91
	   "$EXTENSION_ID" "$EXTENSION_VER"
92
}
93

    
94
print_usage() {
95
    printf 'Usage:  %s upload|check|test API_KEY SECRET XPI_PATH\n' \
96
	   "$_PROG_NAME" >&2
97
}
98

    
99
if [ $# != 4 ]; then
100
    print_usage
101
    exit 1
102
fi
103

    
104
unset RETURNED_DATA
105

    
106
case "$OPERATION" in
107
    test)
108
	curl "https://addons.mozilla.org/api/v4/accounts/profile/" \
109
	     -g -H "Authorization: JWT $(generate_jwt)"
110
	printf '\n'
111
	;;
112
    check)
113
	RETURNED_DATA="$(curl $(get_extension_url) \
114
			      -g -H "Authorization: JWT $(generate_jwt)")"
115
	;;
116
    upload)
117
	RETURNED_DATA="$(curl $(get_extension_url) \
118
			      -g -XPUT --form "upload=@$XPI_PATH" \
119
			      -H "Authorization: JWT $(generate_jwt)")"
120
	;;
121
    *)
122
	print_usage
123
	exit 1
124
	;;
125
esac
126

    
127
if [ -n "$RETURNED_DATA" ]; then
128
    printf "addons.mozilla.org says:\n%s\n" "$RETURNED_DATA"
129
    DOWNLOAD_URL="$(get_json_key download_url "$RETURNED_DATA")"
130
    if [ -n "$DOWNLOAD_URL" ]; then
131
	printf "Downloading extension file from %s\n" "$DOWNLOAD_URL"
132
	curl "$DOWNLOAD_URL" -g -H "Authorization: JWT $(generate_jwt)" -O
133
    fi
134
fi
(13-13/16)