Skip to content

Instantly share code, notes, and snippets.

@clochix
Created November 4, 2019 08:19
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save clochix/cbc7aa4da38807f955a2f8aa77436f51 to your computer and use it in GitHub Desktop.
Save clochix/cbc7aa4da38807f955a2f8aa77436f51 to your computer and use it in GitHub Desktop.
Sample bash script to interact with CozyCloud File API
#!/usr/bin/env bash
cozycli ()
(
server=''
token=''
tokenpath='token.json'
registrationpath='registration.json'
verbose='-s'
lastcode=''
lastres=''
curlstack() {
if [ -r "$tokenpath" ]; then
token="$(jq -r '.access_token' "$tokenpath")"
fi
res=$(curl $verbose -w "%{http_code}\n" -H "Origin: https://${server}" -H "Authorization: Bearer ${token}" "$@")
lastcode=$(echo "$res" | tail -n 1)
lastres=$(echo "$res" | head -n -1)
}
## Options management
options=()
while true; do
case "$1" in
-v)
verbose='-v'
shift
;;
"--")
shift
break
;;
"")
break
;;
*)
options+=("$1")
shift
;;
esac
done
source ./common.sh
case "${options[0]}" in
"token")
server=$(echo "${options[1]}" | sed 's/https:\/\///g')
if [ "$server" = "" ]; then
logerr "Usage: ${FUNCNAME[0]} token URL [scope]"
logerr " default scope: io.cozy.files:GET"
return 1
fi
if [ ${#options[*]} -eq 2 ]; then
scope="io.cozy.files:GET"
else
unset options[0]
unset options[1]
scope="${options[*]}"
fi
echo "Getting token for $server with scope $scope"
curl -s -X POST -H "Host: ${server}" -H "Content-Type: application/json" -H "Accept: application/json" -d '{"redirect_uris": ["http://localhost:8080"],"client_name": "cozycli","software_id": "cozycli"}' https://${server}/auth/register | jq ".server=\"${server}\"" > "$registrationpath"
chmod 600 "$registrationpath"
state="$(cat /proc/sys/kernel/random/uuid)"
clientid="$(jq -r '.client_id' "$registrationpath")"
clientsecret="$(jq -r '.client_secret' "$registrationpath")"
url="$(curl -s -L -w "%{url_effective}" -o /dev/null "https://${server}/auth/authorize?client_id={$clientid}&response_type=code&scope=${scope}&state=${state}&redirect_uri=http%3A%2F%2Flocalhost:8080")"
echo "Open this URL in your browser"
echo "$url"
answer=$(mktemp)
chmod 600 "$answer"
nc -l -p 8080 -q 1 -c 'while read -r request remaining;do echo $request $remaining >> '${answer}';if [ "$remaining" = "" ];then break;fi;done;echo "HTTP/1.1 200 OK\n\nOK"';
IFS=";" read -r code state2<<< $(sed -E "s/^.*&code=([^&]*)&state=(.*) .*$/\1;\2/" "$answer")
rm -f $answer
if [ "$state2" != "$state" ]; then
echo "Wrong state! Expected ${state}, got ${state2}"
fi
curl -s -o "$tokenpath" -X POST -H "Host: ${server}" -H "Content-Type: application/x-www-form-urlencoded" -H "Accept: application/json" -d "grant_type=authorization_code&code=${code}&client_id=${clientid}&client_secret=${clientsecret}" https://${server}/auth/access_token
chmod 600 "$tokenpath"
curlstack "https://${server}/permissions/self"
echo "$lastcode"
echo "$lastres"
echo "Done!"
;;
"revoke")
clientid="$(jq -r '.client_id' "$registrationpath")"
server="$(jq -r '.server' "$registrationpath")"
token="$(jq -r '.registration_access_token' "$registrationpath")"
res=$(curl $verbose -w "%{http_code}\n" -H "Origin: https://${server}" -H "Authorization: Bearer ${token}" -X DELETE "https://${server}/auth/register/${clientid}")
lastcode=$(echo "$res" | tail -n 1)
lastres=$(echo "$res" | head -n -1)
if [ "$lastcode" = "204" ]; then
echo "Revoked"
rm -i "$registrationpath"
rm -i "$tokenpath"
else
echo "Error"
echo "$lastcode"
echo "$lastres"
return 1
fi
;;
"backup")
if [ ${#options[*]} -ne 2 ]; then
logerr "Usage: ${FUNCNAME[0]} backup path"
return 1
fi
server="$(jq -r '.server' "$registrationpath")"
curlstack -H "Accept: application/zip" -X POST "https://${server}/files/archive" -OJ -d '{"data": {"type": "io.cozy.files.archives", "attributes": {"name": "Backup", "files": ["'${options[1]}'"]}}}'
if [ "$lastcode" = "200" ]; then
echo "Done"
ls -l Backup.zip
else
echo "Error"
echo "$lastcode"
echo "$lastres"
return 1
fi
;;
"paste")
if [ ${#options[*]} -eq 2 ]; then
folderid="io.cozy.files.root-dir"
pastefile="${options[1]}"
else
folderid="${options[1]}"
pastefile="${options[2]}"
fi
name=$(basename "${pastefile}" | xxd -plain -c 1000 | sed 's/\(..\)/%\1/g;s/%0a//g')
contenttype=$(file --mime-type -b "${pastefile}")
output=$(mktemp)
server="$(jq -r '.server' "$registrationpath")"
curlstack -H "Date: $(LANG=C date)" \
-H "Content-Type: ${contenttype}" \
--data-binary "@${pastefile}" \
-X POST -o "$output" "https://${server}/files/${folderid}?Type=file&Name=${name}"
curfile=$(cat "$output")
curfileid=$(echo "$curfile" | jq -r '.data.id')
rm "$output"
echo '{"data":{"type":"io.cozy.permissions","attributes":{"permissions":{"files":{"type":"io.cozy.files","verbs":["GET"],"values":["'${curfileid}'"]}}}}}'
curlstack --data '{"data":{"type":"io.cozy.permissions","attributes":{"permissions":{"files":{"type":"io.cozy.files","verbs":["GET"],"values":["'${curfileid}'"]}}}}}' \
-X POST -o "$output" "https://${server}/permissions?codes=email"
shortcode=$(jq -r '.data.attributes.shortcodes.email' "$output")
rm "$output"
echo "https://$(echo $server | sed -E 's/^(\w+)/\1-drive/')/public?sharecode=${shortcode}"
;;
*)
server="$(jq -r '.server' "$registrationpath")"
url="https://${server}${options[0]}"
unset options[0]
curlstack --url "$url" "${options[*]}"
echo "$lastcode"
echo "$lastres"
;;
esac
)
complete -W "token revoke backup paste" cozycli
cozypaste ()
(
if [ ! -r paste.json ]; then
read -r -p "server: " server
read -r -p "folderid: " folder
cozycli token "$server" io.cozy.files:ALL:${folder}
echo '{"folderid": "'${folder}'"}' > paste.json
else
folder="$(jq -r '.folderid' paste.json)"
fi
cozycli paste "$folder" "$1"
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment