Fixed JWT and added tests for the gatekeeper

This commit is contained in:
kexkey
2021-11-17 01:07:28 -05:00
parent f62a7f4cf9
commit 1c8219b0c7
14 changed files with 822 additions and 355 deletions

View File

@@ -1,13 +1,14 @@
FROM nginx:1.18.0-alpine
RUN apk add --update --no-cache \
bash \
bash \
git \
openssl \
fcgiwrap \
spawn-fcgi \
curl \
jq
jq \
coreutils
COPY auth.sh /etc/nginx/conf.d/
COPY default.conf /etc/nginx/conf.d/default.conf

View File

@@ -88,7 +88,7 @@ If you don't want to use HTTPS, just copy default.conf instead of default-ssl.co
docker build -t authapi .
```
If you are using it independantly from the Docker stack (docker-compose.yml), you can run it like that:
If you are using it independently from the Docker stack (docker-compose.yml), you can run it like this:
```shell
docker run -d --rm --name authapi -p 80:80 -p 443:443 --network cyphernodenet -v "~/cyphernode-ssl/certs:/etc/ssl/certs" -v "~/cyphernode-ssl/private:/etc/ssl/private" authapi
@@ -108,16 +108,16 @@ Authorization: Bearer <token>
token = hhh.ppp.sss
```
...where hhh is the header in base64, ppp is the payload in base64 and sss is the signature. Here are the expected formats and contents:
...where hhh is the header in unpadded base64url, ppp is the payload in unpadded base64url and sss is the signature in unpadded base64url. Here are the expected formats and contents:
```shell
header = {"alg":"HS256","typ":"JWT"}
header64 = base64(header) = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9Cg==
header64 = unpad(base64url(header)) = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
```
```shell
payload = {"id":"001","exp":1538528077}
payload64 = base64(payload) = eyJpZCI6IjAwMSIsImV4cCI6MTUzODUyODA3N30K
payload64 = unpad(base64url(payload)) = eyJpZCI6IjAwMSIsImV4cCI6MTUzODUyODA3N30
```
The "id" property is the client id and the "exp" property should be current epoch time + 10 seconds, like:
@@ -129,7 +129,7 @@ $((`date +"%s"`+10))
...so that the request will be expired in 10 seconds. That should take care of most Replay attacks if any. You should run nginx with TLS so that the replay attack can't be possible.
```shell
signature = hmacsha256(header64.payload64, key)
signature = unpad(base64url(hmacsha256(header64.payload64, key)))
```
```shell
@@ -147,21 +147,21 @@ curl -v -H "Authorization: Bearer hhh.ppp.sss" localhost
10 seconds request expiration:
```shell
id="001";h64=$(echo -n "{\"alg\":\"HS256\",\"typ\":\"JWT\"}" | base64);p64=$(echo -n "{\"id\":\"$id\",\"exp\":$((`date +"%s"`+10))}" | base64);k="2df1eeea370eacdc5cf7e96c2d82140d1568079a5d4d87006ec8718a98883b36";s=$(echo -n "$h64.$p64" | openssl dgst -hmac "$k" -sha256 -r | cut -sd ' ' -f1);token="$h64.$p64.$s";curl -v -H "Authorization: Bearer $token" -k https://localhost/getbestblockhash
id="003";key="926c4cced4efd969ea9e40e1666b985319af842a4b0b641c157713959ebd49cb";h64=$(echo -n '{"alg":"HS256","typ":"JWT"}' | basenc --base64url | tr -d '=');p64=$(echo -n '{"id":"'${id}'","exp":'$((`date +"%s"`+10))'}' | basenc --base64url | tr -d '=');sig=$(echo -n "${h64}.${p64}" | openssl dgst -hmac "${key}" -sha256 -r -binary | basenc --base64url | tr -d '=');token="${h64}.${p64}.${sig}";curl -v -H "Authorization: Bearer ${token}" -k https://localhost:2009/v0/getbestblockhash
```
60 seconds request expiration:
```shell
id="001";h64=$(echo -n "{\"alg\":\"HS256\",\"typ\":\"JWT\"}" | base64);p64=$(echo -n "{\"id\":\"$id\",\"exp\":$((`date +"%s"`+60))}" | base64);k="2df1eeea370eacdc5cf7e96c2d82140d1568079a5d4d87006ec8718a98883b36";s=$(echo -n "$h64.$p64" | openssl dgst -hmac "$k" -sha256 -r | cut -sd ' ' -f1);token="$h64.$p64.$s";curl -v -H "Authorization: Bearer $token" -k https://localhost/getbestblockhash
id="003";key="926c4cced4efd969ea9e40e1666b985319af842a4b0b641c157713959ebd49cb";h64=$(echo -n '{"alg":"HS256","typ":"JWT"}' | basenc --base64url | tr -d '=');p64=$(echo -n '{"id":"'${id}'","exp":'$((`date +"%s"`+60))'}' | basenc --base64url | tr -d '=');sig=$(echo -n "${h64}.${p64}" | openssl dgst -hmac "${key}" -sha256 -r -binary | basenc --base64url | tr -d '=');token="${h64}.${p64}.${sig}";curl -v -H "Authorization: Bearer ${token}" -k https://localhost:2009/v0/getbestblockhash
```
## Technicalities
```shell
h64=$(echo -n "{\"alg\":\"HS256\",\"typ\":\"JWT\"}" | base64)
p64=$(echo -n "{\"id\":\"001\",\"exp\":$((`date +"%s"`+10))}" | base64)
k="2df1eeea370eacdc5cf7e96c2d82140d1568079a5d4d87006ec8718a98883b36"
s=$(echo -n "$h64.$p64" | openssl dgst -hmac "$k" -sha256 -r | cut -sd ' ' -f1)
token="$h64.$p64.$s"
h64=$(echo -n '{"alg":"HS256","typ":"JWT"}' | basenc --base64url | tr -d '=')
p64=$(echo -n '{"id":"001","exp":1637032766}' | basenc --base64url | tr -d '=')
key="2df1eeea370eacdc5cf7e96c2d82140d1568079a5d4d87006ec8718a98883b36"
sig=$(echo -n "${h64}.${p64}" | openssl dgst -hmac "${key}" -sha256 -r -binary | basenc --base64url | tr -d '=')
token="${h64}.${p64}.${sig}"
```

View File

@@ -3,15 +3,29 @@
#
# This is not designed to serve thousands of API key!
#
# 401 = authentication error
# 403 = authorization error
#
# header = {"alg":"HS256","typ":"JWT"}
# header64 = base64(header) = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9Cg==
# header64 = unpad(base64url(header)) = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
#
# payload = {"id":"001","exp":1538528077}
# payload64 = base64(payload) = eyJpZCI6IjAwMSIsImV4cCI6MTUzODUyODA3N30K
# payload64 = unpad(base64url(payload)) = eyJpZCI6IjAwMSIsImV4cCI6MTUzODUyODA3N30K
#
# signature = hmacsha256(header64.payload64, key)
# signature = unpad(base64url(hmacsha256(header64.payload64, key)))
#
# token = header64.payload64.signature = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9Cg==.eyJpZCI6IjAwMSIsImV4cCI6MTUzODUyODA3N30K.signature
# token = header64.payload64.signature = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjAwMSIsImV4cCI6MTUzODUyODA3N30K.signature
#
#
# Previous implementation of gatekeeper had a bug in the generation/validation of the JWT token:
# - The header and payload were in base64 instead of unpadded base64url
# - the signature was in HEX instead of unpadded base64url.
#
# Ref.: Appendix C of RFC 7515, "JSON Web Signature (JWS)"
# https://www.rfc-editor.org/rfc/rfc7515.txt
#
# To stay backward-compatible, we'll validate the right way first and if the
# signature is not valid, we'll validate the old-broken way.
#
. ./trace.sh
@@ -27,11 +41,47 @@ verify_sign() {
trace "[verify_sign] payload64=${payload64}"
trace "[verify_sign] signature=${signature}"
local payload=$(echo -n "${payload64}" | base64 -d)
local exp=$(echo "${payload}" | jq ".exp")
local padding
case $((${#payload64}%4)) in
2) padding='=='
;;
3) padding='='
;;
esac
# When broken-legacy used, padding is always empty because we were using base64
# which is padded
trace "[verify_sign] padding=${padding}"
local payload
local legacy
# When broken-legacy used, this will fail if + and / found in payload because
# it's base64 instead of base64url.
payload=$(echo -n "${payload64}${padding}" | basenc --base64url -d)
if [ "$?" -ne "0" ]; then
# We got a legacy broken JWT with + and / in it
trace "[verify_sign] We got a legacy broken JWT"
legacy=1
fi
# Let's get the base64 broken legacy payload in case we have to validate it below...
# If base64 -d fails, it means we got a correct JWT-formed payload.
local legacypayload
legacypayload=$(echo -n "${payload64}" | base64 -d)
if [ "$?" -ne "0" ]; then
# We got a fixed unpadded base64url, no need to try old-broken validation
trace "[verify_sign] We got a fixed unpadded base64url, no need to try old-broken validation"
legacy=0
fi
local exp
if [ "${legacy}" -eq "1" ]; then
exp=$(echo "${legacypayload}" | jq ".exp")
else
exp=$(echo "${payload}" | jq ".exp")
fi
local current=$(date +"%s")
trace "[verify_sign] payload=${payload}"
trace "[verify_sign] legacypayload=${legacypayload}"
trace "[verify_sign] exp=${exp}"
trace "[verify_sign] current=${current}"
@@ -57,9 +107,23 @@ verify_sign() {
local msg="${header64}.${payload64}"
trace "[verify_sign] msg=${msg}"
local comp_sign=$(echo -n "${msg}" | openssl dgst -hmac "${key}" -sha256 -r | cut -sd ' ' -f1)
local comp_sign
if [ "${legacy}" -eq "1" ]; then
comp_sign=$(echo -n "${msg}" | openssl dgst -hmac "${key}" -sha256 -r | cut -sd ' ' -f1)
else
comp_sign=$(echo -n "${msg}" | openssl dgst -hmac "${key}" -sha256 -r -binary | basenc --base64url | tr -d '=')
fi
trace "[verify_sign] comp_sign=${comp_sign}"
if [ "${comp_sign}" != "${signature}" ] && [ -z "${legacy}" ]; then
# Invalid sig and legacy empty, we don't know if legacy or not...
# So we'll try legacy validation...
trace "[verify_sign] Invalid signature, let's try legacy..."
comp_sign=$(echo -n "${msg}" | openssl dgst -hmac "${key}" -sha256 -r | cut -sd ' ' -f1)
trace "[verify_sign] comp_sign=${comp_sign}"
fi
if [ "${comp_sign}" = "${signature}" ]; then
trace "[verify_sign] Valid signature!"
@@ -71,14 +135,14 @@ verify_sign() {
return
fi
trace "[verify_sign] Invalid group!"
return 1
return 3
fi
trace "[verify_sign] Invalid signature!"
return 1
fi
trace "[verify_sign] Expired!"
return 1
return 3
}
verify_group() {
@@ -95,7 +159,7 @@ verify_group() {
local actiontoinspect=$(echo "$action" | tr -d '_-')
case $actiontoinspect in (*[![:alnum:]]*|"")
trace "[verify_group] Potential code injection, exiting"
return 1
return 3
esac
local needed_group
@@ -124,9 +188,10 @@ verify_group() {
fi
trace "[verify_group] Access NOT granted"
return 1
return 3
}
returncode=0
# $HTTP_AUTHORIZATION = Bearer <token>
# Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjAwMyIsImV4cCI6MTU0MjE0OTMyNH0=.b811067cf79c7009a0a38f110a6e3bf82cc4310aa6afae75b9d915b9febf13f7
@@ -139,8 +204,15 @@ if [ "-${HTTP_AUTHORIZATION%% *}" = "-Bearer" ]; then
if [ -n "$token" ]; then
trace "[auth.sh] Valid format for authorization header"
verify_sign "${token}"
[ "$?" -eq "0" ] && return
returncode=$?
trace "[auth.sh] returncode=${returncode}"
[ "$returncode" -eq "0" ] && return
fi
fi
echo -en "Status: 403 Forbidden\r\n\r\n"
if [ "${returncode}" -eq "1" ]; then
echo -en "Status: 401 Unauthorized\r\n\r\n"
else
echo -en "Status: 403 Forbidden\r\n\r\n"
fi

View File

@@ -1,299 +0,0 @@
#!/bin/sh
# We just want to test the authentication/authorization, not the actual called function
# Replace
# proxy_pass http://cyphernode:8888;
# by
# proxy_pass http://cyphernode:1111;
# in /etc/nginx/conf.d/default.conf to run the tests
test_expiration()
{
# Let's test expiration: 1 second in payload, request 2 seconds later
local id=${1}
# echo "id=${id}"
local k
eval k='$ukey_'$id
local p64=$(echo "{\"id\":\"$id\",\"exp\":$((`date +"%s"`+1))}" | base64)
local s=$(echo -n "$h64.$p64" | openssl dgst -hmac "$k" -sha256 -r | cut -sd ' ' -f1)
local token="$h64.$p64.$s"
echo " Sleeping 2 seconds... "
sleep 2
local rc
echo -n " Testing expired request... "
rc=$(time -f "%E" curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" -k https://localhost/getblockinfo)
[ "${rc}" -ne "403" ] && return 10
return 0
}
test_authentication()
{
# Let's test authentication/signature
local id=${1}
# echo "id=${id}"
local k
eval k='$ukey_'$id
local p64=$(echo "{\"id\":\"$id\",\"exp\":$((`date +"%s"`+10))}" | base64)
local s=$(echo -n "$h64.$p64" | openssl dgst -hmac "$k" -sha256 -r | cut -sd ' ' -f1)
local token="$h64.$p64.$s"
local rc
echo -n " Testing good signature... "
rc=$(time -f "%E" curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" -k https://localhost/getblockinfo)
[ "${rc}" -eq "403" ] && return 20
token="$h64.$p64.a$s"
echo -n " Testing bad signature... "
rc=$(time -f "%E" curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" -k https://localhost/getblockinfo)
[ "${rc}" -ne "403" ] && return 30
return 0
}
test_authorization_watcher()
{
# Let's test autorization
local id=${1}
# echo "id=${id}"
local k
eval k='$ukey_'$id
local p64=$(echo "{\"id\":\"$id\",\"exp\":$((`date +"%s"`+20))}" | base64)
local s=$(echo -n "$h64.$p64" | openssl dgst -hmac "$k" -sha256 -r | cut -sd ' ' -f1)
local token="$h64.$p64.$s"
local rc
# Watcher can:
# watch
echo -n " Testing watch... "
rc=$(time -f "%E" curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" -k https://localhost/watch)
[ "${rc}" -eq "403" ] && return 40
# unwatch
echo -n " Testing unwatch... "
rc=$(time -f "%E" curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" -k https://localhost/unwatch)
[ "${rc}" -eq "403" ] && return 50
# getactivewatches
echo -n " Testing getactivewatches... "
rc=$(time -f "%E" curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" -k https://localhost/getactivewatches)
[ "${rc}" -eq "403" ] && return 60
# getbestblockhash
echo -n " Testing getbestblockhash... "
rc=$(time -f "%E" curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" -k https://localhost/getbestblockhash)
[ "${rc}" -eq "403" ] && return 70
# getbestblockinfo
echo -n " Testing getbestblockinfo... "
rc=$(time -f "%E" curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" -k https://localhost/getbestblockinfo)
[ "${rc}" -eq "403" ] && return 80
# getblockinfo
echo -n " Testing getblockinfo... "
rc=$(time -f "%E" curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" -k https://localhost/getblockinfo)
[ "${rc}" -eq "403" ] && return 90
# gettransaction
echo -n " Testing gettransaction... "
rc=$(time -f "%E" curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" -k https://localhost/gettransaction)
[ "${rc}" -eq "403" ] && return 100
# ln_getinfo
echo -n " Testing ln_getinfo... "
rc=$(time -f "%E" curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" -k https://localhost/ln_getinfo)
[ "${rc}" -eq "403" ] && return 110
# ln_create_invoice
echo -n " Testing ln_create_invoice... "
rc=$(time -f "%E" curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" -k https://localhost/ln_create_invoice)
[ "${rc}" -eq "403" ] && return 120
return 0
}
test_authorization_spender()
{
# Let's test autorization
local id=${1}
# echo "id=${id}"
local is_spender=${2}
# echo "is_spender=${is_spender}"
local k
eval k='$ukey_'$id
local p64=$(echo "{\"id\":\"$id\",\"exp\":$((`date +"%s"`+20))}" | base64)
local s=$(echo -n "$h64.$p64" | openssl dgst -hmac "$k" -sha256 -r | cut -sd ' ' -f1)
local token="$h64.$p64.$s"
local rc
# Spender can do what the watcher can do, plus:
# getbalance
echo -n " Testing getbalance... "
rc=$(time -f "%E" curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" -k https://localhost/getbalance)
[ ${is_spender} = true ] && [ "${rc}" -eq "403" ] && return 430
[ ${is_spender} = false ] && [ "${rc}" -ne "403" ] && return 435
# getnewaddress
echo -n " Testing getnewaddress... "
rc=$(time -f "%E" curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" -k https://localhost/getnewaddress)
[ ${is_spender} = true ] && [ "${rc}" -eq "403" ] && return 440
[ ${is_spender} = false ] && [ "${rc}" -ne "403" ] && return 445
# spend
echo -n " Testing spend... "
rc=$(time -f "%E" curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" -k https://localhost/spend)
[ ${is_spender} = true ] && [ "${rc}" -eq "403" ] && return 450
[ ${is_spender} = false ] && [ "${rc}" -ne "403" ] && return 455
# addtobatch
echo -n " Testing addtobatch... "
rc=$(time -f "%E" curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" -k https://localhost/addtobatch)
[ ${is_spender} = true ] && [ "${rc}" -eq "403" ] && return 460
[ ${is_spender} = false ] && [ "${rc}" -ne "403" ] && return 465
# batchspend
echo -n " Testing batchspend... "
rc=$(time -f "%E" curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" -k https://localhost/batchspend)
[ ${is_spender} = true ] && [ "${rc}" -eq "403" ] && return 470
[ ${is_spender} = false ] && [ "${rc}" -ne "403" ] && return 475
# deriveindex
echo -n " Testing deriveindex... "
rc=$(time -f "%E" curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" -k https://localhost/deriveindex)
[ ${is_spender} = true ] && [ "${rc}" -eq "403" ] && return 480
[ ${is_spender} = false ] && [ "${rc}" -ne "403" ] && return 485
# derivepubpath
echo -n " Testing derivepubpath... "
rc=$(time -f "%E" curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" -k https://localhost/derivepubpath)
[ ${is_spender} = true ] && [ "${rc}" -eq "403" ] && return 490
[ ${is_spender} = false ] && [ "${rc}" -ne "403" ] && return 495
# ln_pay
echo -n " Testing ln_pay... "
rc=$(time -f "%E" curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" -k https://localhost/ln_pay)
[ ${is_spender} = true ] && [ "${rc}" -eq "403" ] && return 500
[ ${is_spender} = false ] && [ "${rc}" -ne "403" ] && return 505
# ln_newaddr
echo -n " Testing ln_newaddr... "
rc=$(time -f "%E" curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" -k https://localhost/ln_newaddr)
[ ${is_spender} = true ] && [ "${rc}" -eq "403" ] && return 510
[ ${is_spender} = false ] && [ "${rc}" -ne "403" ] && return 515
# ots_stamp
echo -n " Testing ots_stamp... "
rc=$(time -f "%E" curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" -k https://localhost/ots_stamp)
[ ${is_spender} = true ] && [ "${rc}" -eq "403" ] && return 520
[ ${is_spender} = false ] && [ "${rc}" -ne "403" ] && return 525
# ots_getfile
echo -n " Testing ots_getfile... "
rc=$(time -f "%E" curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" -k https://localhost/ots_getfile)
[ ${is_spender} = true ] && [ "${rc}" -eq "403" ] && return 530
[ ${is_spender} = false ] && [ "${rc}" -ne "403" ] && return 535
return 0
}
test_authorization_internal()
{
# Let's test autorization
local id=${1}
# echo "id=${id}"
local k
eval k='$ukey_'$id
local p64=$(echo "{\"id\":\"$id\",\"exp\":$((`date +"%s"`+10))}" | base64)
local s=$(echo -n "$h64.$p64" | openssl dgst -hmac "$k" -sha256 -r | cut -sd ' ' -f1)
local token="$h64.$p64.$s"
local rc
# Should be called from inside the Swarm:
# conf
echo -n " Testing conf... "
rc=$(time -f "%E" curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" -k https://localhost/conf)
[ "${rc}" -ne "403" ] && return 920
# executecallbacks
echo -n " Testing executecallbacks... "
rc=$(time -f "%E" curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" -k https://localhost/executecallbacks)
[ "${rc}" -ne "403" ] && return 930
# ots_backoffice
echo -n " Testing ots_backoffice... "
rc=$(time -f "%E" curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" -k https://localhost/ots_backoffice)
[ "${rc}" -ne "403" ] && return 940
return 0
}
kapi_id="001";kapi_key="2df1eeea370eacdc5cf7e96c2d82140d1568079a5d4d87006ec8718a98883b36";kapi_groups="watcher";eval ugroups_${kapi_id}=${kapi_groups};eval ukey_${kapi_id}=${kapi_key}
kapi_id="003";kapi_key="b9b8d527a1a27af2ad1697db3521f883760c342fc386dbc42c4efbb1a4d5e0af";kapi_groups="watcher,spender";eval ugroups_${kapi_id}=${kapi_groups};eval ukey_${kapi_id}=${kapi_key}
kapi_id="005";kapi_key="6c009201b123e8c24c6b74590de28c0c96f3287e88cac9460a2173a53d73fb87";kapi_groups="watcher,spender,admin";eval ugroups_${kapi_id}=${kapi_groups};eval ukey_${kapi_id}=${kapi_key}
h64=$(echo "{\"alg\":\"HS256\",\"typ\":\"JWT\"}" | base64)
# Let's test expiration: 1 second in payload, request 2 seconds later
echo 'test_expiration "001"'
test_expiration "001" ; rc=$? ; [ $rc -ne 0 ] && echo $rc && return $rc
echo 'test_expiration "003"'
test_expiration "003" ; rc=$? ; [ $rc -ne 0 ] && echo $rc && return $rc
echo 'test_expiration "005"'
test_expiration "005" ; rc=$? ; [ $rc -ne 0 ] && echo $rc && return $rc
# Let's test authentication/signature
echo 'test_authentication "001"'
test_authentication "001" ; rc=$? ; [ $rc -ne 0 ] && echo $rc && return $rc
echo 'test_authentication "003"'
test_authentication "003" ; rc=$? ; [ $rc -ne 0 ] && echo $rc && return $rc
echo 'test_authentication "005"'
test_authentication "005" ; rc=$? ; [ $rc -ne 0 ] && echo $rc && return $rc
# Let's test autorization for watcher actions
echo 'test_authorization_watcher "001"'
test_authorization_watcher "001" ; rc=$? ; [ $rc -ne 0 ] && echo $rc && return $rc
echo 'test_authorization_watcher "003"'
test_authorization_watcher "003" ; rc=$? ; [ $rc -ne 0 ] && echo $rc && return $rc
echo 'test_authorization_watcher "005"'
test_authorization_watcher "005" ; rc=$? ; [ $rc -ne 0 ] && echo $rc && return $rc
# Let's test autorization for spender actions
echo 'test_authorization_spender "001" false'
test_authorization_spender "001" false ; rc=$? ; [ $rc -ne 0 ] && echo $rc && return $rc
echo 'test_authorization_spender "003" true'
test_authorization_spender "003" true ; rc=$? ; [ $rc -ne 0 ] && echo $rc && return $rc
echo 'test_authorization_spender "005" true'
test_authorization_spender "005" true ; rc=$? ; [ $rc -ne 0 ] && echo $rc && return $rc
# Let's test autorization for admin actions
#test_authorization_admin "001"
#test_authorization_admin "003"
#test_authorization_admin "005"
# Let's test autorization for internal actions
echo 'test_authorization_internal "001"'
test_authorization_internal "001" ; rc=$? ; [ $rc -ne 0 ] && echo $rc && return $rc
echo 'test_authorization_internal "003"'
test_authorization_internal "003" ; rc=$? ; [ $rc -ne 0 ] && echo $rc && return $rc
echo 'test_authorization_internal "005"'
test_authorization_internal "005" ; rc=$? ; [ $rc -ne 0 ] && echo $rc && return $rc

View File

@@ -0,0 +1,73 @@
# Reset
Color_Off='\033[0m' # Text Reset
# Regular Colors
Black='\033[0;30m' # Black
Red='\033[0;31m' # Red
Green='\033[0;32m' # Green
Yellow='\033[0;33m' # Yellow
Blue='\033[0;34m' # Blue
Purple='\033[0;35m' # Purple
Cyan='\033[0;36m' # Cyan
White='\033[0;37m' # White
# Bold
BBlack='\033[1;30m' # Black
BRed='\033[1;31m' # Red
BGreen='\033[1;32m' # Green
BYellow='\033[1;33m' # Yellow
BBlue='\033[1;34m' # Blue
BPurple='\033[1;35m' # Purple
BCyan='\033[1;36m' # Cyan
BWhite='\033[1;37m' # White
# Underline
UBlack='\033[4;30m' # Black
URed='\033[4;31m' # Red
UGreen='\033[4;32m' # Green
UYellow='\033[4;33m' # Yellow
UBlue='\033[4;34m' # Blue
UPurple='\033[4;35m' # Purple
UCyan='\033[4;36m' # Cyan
UWhite='\033[4;37m' # White
# Background
On_Black='\033[40m' # Black
On_Red='\033[41m' # Red
On_Green='\033[42m' # Green
On_Yellow='\033[43m' # Yellow
On_Blue='\033[44m' # Blue
On_Purple='\033[45m' # Purple
On_Cyan='\033[46m' # Cyan
On_White='\033[47m' # White
# High Intensity
IBlack='\033[0;90m' # Black
IRed='\033[0;91m' # Red
IGreen='\033[0;92m' # Green
IYellow='\033[0;93m' # Yellow
IBlue='\033[0;94m' # Blue
IPurple='\033[0;95m' # Purple
ICyan='\033[0;96m' # Cyan
IWhite='\033[0;97m' # White
# Bold High Intensity
BIBlack='\033[1;90m' # Black
BIRed='\033[1;91m' # Red
BIGreen='\033[1;92m' # Green
BIYellow='\033[1;93m' # Yellow
BIBlue='\033[1;94m' # Blue
BIPurple='\033[1;95m' # Purple
BICyan='\033[1;96m' # Cyan
BIWhite='\033[1;97m' # White
# High Intensity backgrounds
On_IBlack='\033[0;100m' # Black
On_IRed='\033[0;101m' # Red
On_IGreen='\033[0;102m' # Green
On_IYellow='\033[0;103m' # Yellow
On_IBlue='\033[0;104m' # Blue
On_IPurple='\033[0;105m' # Purple
On_ICyan='\033[0;106m' # Cyan
On_IWhite='\033[0;107m' # White

View File

@@ -0,0 +1,612 @@
#!/bin/bash
. ./colors.sh
# We just want to test the authentication/authorization, not the actual called function
# You need jq installed for these tests to run correctly
# This will test this structure of access (api.properties):
# # Watcher can do stuff
# # Spender can do what the watcher can do plus more stuff
# # Admin can do what the spender can do plus even more stuff
# # Stats can:
# action_helloworld=stats
# action_getblockchaininfo=stats
# action_installation_info=stats
# action_getmempoolinfo=stats
# action_getblockhash=stats
#
# # Watcher can do what the stats can do, plus:
# action_watch=watcher
# action_unwatch=watcher
# action_watchxpub=watcher
# action_unwatchxpubbyxpub=watcher
# action_unwatchxpubbylabel=watcher
# action_getactivewatchesbyxpub=watcher
# action_getactivewatchesbylabel=watcher
# action_getactivexpubwatches=watcher
# action_get_txns_by_watchlabel=watcher
# action_get_unused_addresses_by_watchlabel=watcher
# action_watchtxid=watcher
# action_unwatchtxid=watcher
# action_getactivewatches=watcher
# action_getbestblockhash=watcher
# action_getbestblockinfo=watcher
# action_getblockinfo=watcher
# action_gettransaction=watcher
# action_ots_verify=watcher
# action_ots_info=watcher
# action_ln_getinfo=watcher
# action_ln_create_invoice=watcher
# action_ln_getconnectionstring=watcher
# action_ln_decodebolt11=watcher
# action_ln_listpeers=watcher
# action_ln_getroute=watcher
# action_ln_listpays=watcher
# action_ln_paystatus=watcher
# action_bitcoin_estimatesmartfee=watcher
#
# # Spender can do what the watcher can do, plus:
# action_get_txns_spending=spender
# action_getbalance=spender
# action_getbalances=spender
# action_getbalancebyxpub=spender
# action_getbalancebyxpublabel=spender
# action_getnewaddress=spender
# action_spend=spender
# action_bumpfee=spender
# action_addtobatch=spender
# action_batchspend=spender
# action_deriveindex=spender
# action_derivepubpath=spender
# action_deriveindex_bitcoind=spender
# action_derivepubpath_bitcoind=spender
# action_ln_pay=spender
# action_ln_newaddr=spender
# action_ots_stamp=spender
# action_ots_getfile=spender
# action_ln_getinvoice=spender
# action_ln_delinvoice=spender
# action_ln_connectfund=spender
# action_ln_listfunds=spender
# action_ln_withdraw=spender
# action_createbatcher=spender
# action_updatebatcher=spender
# action_removefrombatch=spender
# action_listbatchers=spender
# action_getbatcher=spender
# action_getbatchdetails=spender
#
# # Admin can do what the spender can do, plus:
#
#
# # Should be called from inside the Docker network only:
# action_conf=internal
# action_newblock=internal
# action_executecallbacks=internal
# action_ots_backoffice=internal
#
#
trace() {
if [ "${1}" -le "${TRACING}" ]; then
echo -en "$(date -u +%FT%TZ) ${2}" 1>&2
fi
}
trace_following() {
if [ "${1}" -le "${TRACING}" ]; then
echo -en "${2}" 1>&2
fi
}
start_test_container() {
trace 1 "[stop_test_container] ${BCyan}Starting test container...${Color_Off}\n"
docker run -d --rm -t --name tests-gatekeeper --network=cyphernodenet alpine
sleep 2
}
stop_test_container() {
trace 1 "[stop_test_container] ${BCyan}Stopping existing containers if they are running...${Color_Off}\n"
local containers=$(docker ps -q -f "name=tests-gatekeeper")
if [ -n "${containers}" ]; then
docker stop ${containers}
fi
}
exec_in_test_container() {
local response
local returncode
response=$(docker exec -it tests-gatekeeper "$@")
returncode=${?}
echo -n "${response}" | tr -d '\r\n'
return ${returncode}
}
exec_in_test_container_leave_lf() {
local response
local returncode
response=$(docker exec -it tests-gatekeeper "$@")
returncode=${?}
echo -n "${response}"
return ${returncode}
}
test_auth() {
local fn=${1}
local token=${2}
local has_access=${3}
local httperrorcode=${4}
local returncode
local httpcode
trace 2 "[test_auth] ${BCyan}action=${fn}...${Color_Off}"
httpcode=$(exec_in_test_container curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" --cacert /cert.pem https://gatekeeper:2009/v0/${fn})
returncode=${?}
if ${has_access}; then
trace_following 2 " has access... "
else
trace_following 2 " has NOT access... "
fi
if [ "${returncode}" -ne "0" ] || ${has_access} && [ "${httpcode}" -eq "${httperrorcode}" ] || ! ${has_access} && [ "${httpcode}" -ne "${httperrorcode}" ]; then
trace_following 1 "${On_Red}${BBlack} curl code=${returncode}, HTTP code=${httpcode}!${Color_Off}\n"
return 10
else
trace_following 2 "${On_IGreen}${BBlack} OK ${Color_Off}\n"
fi
}
test_authorization() {
test_auth ${1} ${2} ${3} 403
return $?
}
test_authentication() {
test_auth ${1} ${2} ${3} 401
return $?
}
generate_token() {
local id=${1}
local expired=${2:-false}
local key
local groups
key=$(exec_in_test_container sh -c 'source /keys.properties ; echo $ukey_'${id})
groups=$(exec_in_test_container sh -c 'source /keys.properties ; echo $ugroups_'${id})
trace 3 "[generate_token] id=${id}\n"
trace 3 "[generate_token] key=${key}\n"
trace 3 "[generate_token] groups=${groups}\n"
local h64broken=$(exec_in_test_container sh -c "echo -n '{\"alg\":\"HS256\",\"typ\":\"JWT\"}' | base64")
trace 3 "[generate_token] h64broken=${h64broken}\n"
local h64=$(exec_in_test_container sh -c "echo -n '{\"alg\":\"HS256\",\"typ\":\"JWT\"}' | basenc --base64url | tr -d '='")
trace 3 "[generate_token] h64=${h64}\n"
local d=$(exec_in_test_container date +"%s")
if ! ${expired}; then
d=$((d+100000))
fi
trace 3 "[generate_token] d=${d}\n"
local p64=$(exec_in_test_container sh -c "echo -n '{\"id\":\"${id}\",\"exp\":${d}}' | basenc --base64url | tr -d '='")
trace 3 "[generate_token] p64=${p64}\n"
# local s=$(echo -n "${h64}.${p64}" | openssl dgst -hmac "${key}" -sha256 -r | cut -sd ' ' -f1)
local sig=$(exec_in_test_container sh -c "echo -n \"${h64}.${p64}\" | openssl dgst -hmac \"${key}\" -sha256 -r -binary | basenc --base64url | tr -d '='")
trace 3 "[generate_token] sig=${sig}\n"
local token="${h64}.${p64}.${sig}"
trace 3 "[generate_token] token=${token}\n\n"
trace 1 "[test_gatekeeper] ${BCyan}Current user ${id} with groups ${groups}${Color_Off}\n"
echo -n "${token}"
}
generate_broken_token() {
local id=${1}
local key
local groups
key=$(exec_in_test_container sh -c 'source /keys.properties ; echo $ukey_'${id})
groups=$(exec_in_test_container sh -c 'source /keys.properties ; echo $ugroups_'${id})
trace 3 "[generate_token] id=${id}\n"
trace 3 "[generate_token] key=${key}\n"
trace 3 "[generate_token] groups=${groups}\n"
local h64broken=$(exec_in_test_container sh -c "echo -n '{\"alg\":\"HS256\",\"typ\":\"JWT\"}' | base64")
trace 3 "[generate_token] h64broken=${h64broken}\n"
local d=$(exec_in_test_container date +"%s")
trace 3 "[generate_token] d=${d}\n"
local p64broken=$(exec_in_test_container sh -c "echo -n '{\"id\":\"${id}\",\"exp\":$((d+100000))}' | base64")
trace 3 "[generate_token] p64broken=${p64broken}\n"
local sigbroken=$(exec_in_test_container sh -c "echo -n \"${h64}.${p64}\" | openssl dgst -hmac \"${key}\" -sha256 -r | cut -sd ' ' -f1")
trace 3 "[generate_token] sigbroken=${sigbroken}\n"
local token="${h64broken}.${p64broken}.${sigbroken}"
trace 3 "[generate_token] token=${token}\n\n"
trace 1 "[test_gatekeeper] ${BCyan}Current user ${id} with groups ${groups}${Color_Off}\n"
echo -n "${token}"
}
test_functions_with_broken_token() {
trace 1 "\n\n[test_functions_with_broken_token] ${BCyan}Let's test functions with broken token...${Color_Off}\n\n"
local id=${1}
local token=$(generate_broken_token ${id})
local has_access=${2}
# Stats can:
# action_helloworld=stats
test_authorization "helloworld" "${token}" ${has_access} || return 10
# action_getblockchaininfo=stats
test_authorization "getblockchaininfo" "${token}" ${has_access} || return 20
# action_installation_info=stats
test_authorization "installation_info" "${token}" ${has_access} || return 30
# action_getmempoolinfo=stats
test_authorization "getmempoolinfo" "${token}" ${has_access} || return 40
# action_getblockhash=stats
test_authorization "getblockhash" "${token}" ${has_access} || return 50
trace 1 "\n\n[test_functions_with_broken_token] ${On_IGreen}${BBlack} SUCCESS with user ${id}! ${Color_Off}\n"
}
test_functions_with_wrong_token() {
trace 1 "\n\n[test_functions_with_wrong_token] ${BCyan}Let's test functions with wrong token (we will receive HTTP 401 Unauthorized here)...${Color_Off}\n\n"
local id=${1}
local token=aaa$(generate_token ${id})aaa
local has_access=false
# Stats can:
# action_helloworld=stats
test_authentication "helloworld" "${token}" ${has_access} || return 10
# action_getblockchaininfo=stats
test_authentication "getblockchaininfo" "${token}" ${has_access} || return 20
# action_installation_info=stats
test_authentication "installation_info" "${token}" ${has_access} || return 30
# action_getmempoolinfo=stats
test_authentication "getmempoolinfo" "${token}" ${has_access} || return 40
# action_getblockhash=stats
test_authentication "getblockhash" "${token}" ${has_access} || return 50
trace 1 "\n\n[test_functions_with_wrong_token] ${On_IGreen}${BBlack} SUCCESS with user ${id}! ${Color_Off}\n"
}
test_stats_functions() {
trace 1 "\n\n[test_gatekeeper] ${BCyan}Let's test stats functions...${Color_Off}\n\n"
local id=${1}
local token=$(generate_token ${id})
local has_access=${2}
# Stats can:
# action_helloworld=stats
test_authorization "helloworld" "${token}" ${has_access} || return 10
# action_getblockchaininfo=stats
test_authorization "getblockchaininfo" "${token}" ${has_access} || return 20
# action_installation_info=stats
test_authorization "installation_info" "${token}" ${has_access} || return 30
# action_getmempoolinfo=stats
test_authorization "getmempoolinfo" "${token}" ${has_access} || return 40
# action_getblockhash=stats
test_authorization "getblockhash" "${token}" ${has_access} || return 50
trace 1 "\n\n[test_stats_functions] ${On_IGreen}${BBlack} SUCCESS with user ${id}! ${Color_Off}\n"
}
test_watcher_functions() {
trace 1 "\n\n[test_watcher_functions] ${BCyan}Let's test watcher functions...${Color_Off}\n\n"
local id=${1}
local token=$(generate_token ${id})
local has_access=${2}
# Watcher can:
# action_watch=watcher
test_authorization "watch" "${token}" ${has_access} || return 10
# action_unwatch=watcher
test_authorization "unwatch" "${token}" ${has_access} || return 20
# action_watchxpub=watcher
test_authorization "watchxpub" "${token}" ${has_access} || return 30
# action_unwatchxpubbyxpub=watcher
test_authorization "unwatchxpubbyxpub" "${token}" ${has_access} || return 40
# action_unwatchxpubbylabel=watcher
test_authorization "unwatchxpubbylabel" "${token}" ${has_access} || return 50
# action_getactivewatchesbyxpub=watcher
test_authorization "getactivewatchesbyxpub" "${token}" ${has_access} || return 60
# action_getactivewatchesbylabel=watcher
test_authorization "getactivewatchesbylabel" "${token}" ${has_access} || return 70
# action_getactivexpubwatches=watcher
test_authorization "getactivexpubwatches" "${token}" ${has_access} || return 80
# action_get_txns_by_watchlabel=watcher
test_authorization "get_txns_by_watchlabel" "${token}" ${has_access} || return 90
# action_get_unused_addresses_by_watchlabel=watcher
test_authorization "get_unused_addresses_by_watchlabel" "${token}" ${has_access} || return 100
# action_watchtxid=watcher
test_authorization "watchtxid" "${token}" ${has_access} || return 110
# action_unwatchtxid=watcher
test_authorization "unwatchtxid" "${token}" ${has_access} || return 120
# action_getactivewatches=watcher
test_authorization "getactivewatches" "${token}" ${has_access} || return 130
# action_getbestblockhash=watcher
test_authorization "getbestblockhash" "${token}" ${has_access} || return 140
# action_getbestblockinfo=watcher
test_authorization "getbestblockinfo" "${token}" ${has_access} || return 150
# action_getblockinfo=watcher
test_authorization "getblockinfo" "${token}" ${has_access} || return 160
# action_gettransaction=watcher
test_authorization "gettransaction" "${token}" ${has_access} || return 170
# action_ots_verify=watcher
test_authorization "ots_verify" "${token}" ${has_access} || return 180
# action_ots_info=watcher
test_authorization "ots_info" "${token}" ${has_access} || return 190
# action_ln_getinfo=watcher
test_authorization "ln_getinfo" "${token}" ${has_access} || return 200
# action_ln_create_invoice=watcher
test_authorization "ln_create_invoice" "${token}" ${has_access} || return 210
# action_ln_getconnectionstring=watcher
test_authorization "ln_getconnectionstring" "${token}" ${has_access} || return 220
# action_ln_decodebolt11=watcher
test_authorization "ln_decodebolt11" "${token}" ${has_access} || return 230
# action_ln_listpeers=watcher
test_authorization "ln_listpeers" "${token}" ${has_access} || return 240
# action_ln_getroute=watcher
test_authorization "ln_getroute" "${token}" ${has_access} || return 250
# action_ln_listpays=watcher
test_authorization "ln_listpays" "${token}" ${has_access} || return 260
# action_ln_paystatus=watcher
test_authorization "ln_paystatus" "${token}" ${has_access} || return 270
# action_bitcoin_estimatesmartfee=watcher
test_authorization "bitcoin_estimatesmartfee" "${token}" ${has_access} || return 280
trace 1 "\n\n[test_watcher_functions] ${On_IGreen}${BBlack} SUCCESS with user ${id}! ${Color_Off}\n"
}
test_spender_functions() {
trace 1 "\n\n[test_spender_functions] ${BCyan}Let's test spender functions...${Color_Off}\n"
local id=${1}
local token=$(generate_token ${id})
local has_access=${2}
# Spender can do what the watcher can do, plus:
# action_get_txns_spending=spender
test_authorization "get_txns_spending" "${token}" ${has_access} || return 10
# action_getbalance=spender
test_authorization "getbalance" "${token}" ${has_access} || return 10
# action_getbalances=spender
test_authorization "getbalances" "${token}" ${has_access} || return 10
# action_getbalancebyxpub=spender
test_authorization "getbalancebyxpub" "${token}" ${has_access} || return 10
# action_getbalancebyxpublabel=spender
test_authorization "getbalancebyxpublabel" "${token}" ${has_access} || return 10
# action_getnewaddress=spender
test_authorization "getnewaddress" "${token}" ${has_access} || return 10
# action_spend=spender
test_authorization "spend" "${token}" ${has_access} || return 10
# action_bumpfee=spender
test_authorization "bumpfee" "${token}" ${has_access} || return 10
# action_addtobatch=spender
test_authorization "addtobatch" "${token}" ${has_access} || return 10
# action_batchspend=spender
test_authorization "batchspend" "${token}" ${has_access} || return 10
# action_deriveindex=spender
test_authorization "deriveindex" "${token}" ${has_access} || return 10
# action_derivepubpath=spender
test_authorization "derivepubpath" "${token}" ${has_access} || return 10
# action_deriveindex_bitcoind=spender
test_authorization "deriveindex_bitcoind" "${token}" ${has_access} || return 10
# action_derivepubpath_bitcoind=spender
test_authorization "derivepubpath_bitcoind" "${token}" ${has_access} || return 10
# action_ln_pay=spender
test_authorization "ln_pay" "${token}" ${has_access} || return 10
# action_ln_newaddr=spender
test_authorization "ln_newaddr" "${token}" ${has_access} || return 10
# action_ots_stamp=spender
test_authorization "ots_stamp" "${token}" ${has_access} || return 10
# action_ots_getfile=spender
test_authorization "ots_getfile" "${token}" ${has_access} || return 10
# action_ln_getinvoice=spender
test_authorization "ln_getinvoice" "${token}" ${has_access} || return 10
# action_ln_delinvoice=spender
test_authorization "ln_delinvoice" "${token}" ${has_access} || return 10
# action_ln_connectfund=spender
test_authorization "ln_connectfund" "${token}" ${has_access} || return 10
# action_ln_listfunds=spender
test_authorization "ln_listfunds" "${token}" ${has_access} || return 10
# action_ln_withdraw=spender
test_authorization "ln_withdraw" "${token}" ${has_access} || return 10
# action_createbatcher=spender
test_authorization "createbatcher" "${token}" ${has_access} || return 10
# action_updatebatcher=spender
test_authorization "updatebatcher" "${token}" ${has_access} || return 10
# action_removefrombatch=spender
test_authorization "removefrombatch" "${token}" ${has_access} || return 10
# action_listbatchers=spender
test_authorization "listbatchers" "${token}" ${has_access} || return 10
# action_getbatcher=spender
test_authorization "getbatcher" "${token}" ${has_access} || return 10
# action_getbatchdetails=spender
test_authorization "getbatchdetails" "${token}" ${has_access} || return 10
trace 1 "\n\n[test_spender_functions] ${On_IGreen}${BBlack} SUCCESS with user ${id}! ${Color_Off}\n"
}
test_admin_functions() {
trace 1 "\n\n[test_admin_functions] ${BCyan}Let's test admin functions...${Color_Off}\n"
# Admin can do what the spender can do, plus:
trace 1 "\n\n[test_admin_functions] ${On_IGreen}${BBlack} SUCCESS with user ${id}! ${Color_Off}\n"
}
test_internal_functions() {
trace 1 "\n\n[test_internal_functions] ${BCyan}Let's test internal functions...${Color_Off}\n"
local id=${1}
local token=$(generate_token ${id})
local has_access=${2}
# Should be called from inside the Docker network only:
# action_conf=internal
test_authorization "conf" "${token}" ${has_access} || return 10
# action_newblock=internal
test_authorization "newblock" "${token}" ${has_access} || return 10
# action_executecallbacks=internal
test_authorization "executecallbacks" "${token}" ${has_access} || return 10
# action_ots_backoffice=internal
test_authorization "ots_backoffice" "${token}" ${has_access} || return 10
trace 1 "\n\n[test_internal_functions] ${On_IGreen}${BBlack} SUCCESS with user ${id}! ${Color_Off}\n"
}
test_expired() {
trace 1 "\n\n[test_expired] ${BCyan}Let's test calling a function with an expired token (we will receive HTTP 403 Forbidden here)...${Color_Off}\n\n"
local id=${1}
local token=$(generate_token ${id} true)
local has_access=false
# Stats can:
# action_helloworld=stats
test_authorization "helloworld" "${token}" ${has_access} || return 10
trace 1 "\n\n[test_expired] ${On_IGreen}${BBlack} SUCCESS with user ${id}! ${Color_Off}\n"
}
TRACING=3
stop_test_container
start_test_container
trace 1 "\n\n[test_gatekeeper] ${BCyan}Installing needed packages...${Color_Off}\n"
exec_in_test_container_leave_lf apk add --update curl coreutils openssl
# Copy keys to test container
trace 1 "\n\n[test_gatekeeper] ${BCyan}Copying keys and certs to test container...${Color_Off}\n"
gatekeeperid=$(docker ps -q -f "name=cyphernode_gatekeeper")
testid=$(docker ps -q -f "name=tests-gatekeeper")
docker cp ${gatekeeperid}:/etc/nginx/conf.d/keys.properties - | docker cp - ${testid}:/
docker cp ${gatekeeperid}:/etc/ssl/certs/cert.pem - | docker cp - ${testid}:/
# Test with an expired token
# Test functions with broken legacy token
# Test functions with wrong token
# Stats functions with a stats
# Stats functions with a watcher
# Stats functions with a spender
# Stats functions with a admin
# Watcher functions with a stats
# Watcher functions with a watcher
# Watcher functions with a spender
# Watcher functions with a admin
# Spending functions with a stats
# Spending functions with a watcher
# Spending functions with a spender
# Spending functions with a admin
# Internal functions with a stats
# Internal functions with a watcher
# Internal functions with a spender
# Internal functions with a admin
test_expired 003 \
&& test_functions_with_broken_token 003 true \
&& test_functions_with_wrong_token 003 true \
&& test_stats_functions 000 true \
&& test_stats_functions 001 true \
&& test_stats_functions 002 true \
&& test_stats_functions 003 true \
&& test_watcher_functions 000 false \
&& test_watcher_functions 001 true \
&& test_watcher_functions 002 true \
&& test_watcher_functions 003 true \
&& test_spender_functions 000 false \
&& test_spender_functions 001 false \
&& test_spender_functions 002 true \
&& test_spender_functions 003 true \
&& test_internal_functions 000 false \
&& test_internal_functions 001 false \
&& test_internal_functions 002 false \
&& test_internal_functions 003 false \
|| trace 1 "\n\n[test_gatekeeper] ${On_Red}${BBlack} test_watcher_functions error: ${?} ${Color_Off}\n"
trace 1 "\n\n[test_gatekeeper] ${BCyan}Tearing down...${Color_Off}\n"
wait
stop_test_container
trace 1 "\n\n[test_gatekeeper] ${BCyan}See ya!${Color_Off}\n"