Skip to content

Commit

Permalink
Adds local login and script for testing
Browse files Browse the repository at this point in the history
- Allow for easier development with bypassing the Gaspar login
- Adds a script which does all the initialisations for a first D-voting experience
  • Loading branch information
ineiti committed Sep 25, 2023
1 parent d36c3e4 commit dc7db4b
Show file tree
Hide file tree
Showing 11 changed files with 375 additions and 17 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,8 @@ nodedata/

deb-package/dist/**

.env

dela/
bin/
nodes/
17 changes: 17 additions & 0 deletions scripts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Scripts for running D-voting locally

The following scripts are available to configure and run D-voting locally:

- `run_local.sh` - sets up a complete system with 4 nodes, the db, the authentication-server,
and the frontend.
The script runs only the DB in a docker environment, all the rest is run directly on the machine.
This allows for easier debugging and faster testing of the different parts, mainly the
authentication-server, but also the frontend.
For debugging Dela, you still need to re-run everything.
- `init_dela.sh` - allows to initialize a set of nodes started with `docker-compose.dev.yml`, also
integrated into `run_local.sh`
- `setup_admin.sh` - adds an admin SCIPER to the backend started in `docker-compose.dev.yml`, also
integrated into `run_local.sh`
- `setup_proxies.sh` - adds the proxies to the backend started in `docker-compose.dev.yml`
- `setup_forms.sh` - sets up a new form and optionally votes on it when running in
`docker-compose.dev.yml`
188 changes: 188 additions & 0 deletions scripts/run_local.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
#!/bin/bash -e
# This puts all the different steps of initializing a Dela d-voting network into one shell script.
# This can be used for development by calling the script and then testing the result locally.
# The script must be called from the root of the github tree, else it returns an error.
# If the script is called with `./scripts/run_local.sh clean`, it stops all services.
# For development, the calls to the different parts can be adjusted, e.g., comment all but
# `start_backend` to only restart the backend.

if [[ $( git rev-parse --show-toplevel ) != $( pwd ) ]]; then
echo "ERROR: This script must be started from the root of the git repo"
exit 1
fi

asdf_shell() {
if ! asdf list "$1" | grep -wq "$2"; then
asdf install "$1" "$2"
fi
asdf local "$1" "$2"
}
asdf_shell nodejs 16.20.2
asdf_shell golang 1.21.0
mkdir -p nodes

function build_dela() {
echo "Building dela-node"
if ! [[ -d dela/ ]]; then
git clone -b fix-bbolt https://github.com/dedis/dela.git
fi
export GOBIN=$(pwd)/bin
PATH="$PATH":"$GOBIN"
if ! [[ -f $GOBIN/crypto ]]; then
(cd dela/cli/crypto && go install)
go install ./cli/dvoting
fi

echo "Installing node directories"
for d in backend frontend; do
DIR=web/$d
if ! [[ -d $DIR/node_modules ]]; then
(cd $DIR && npm ci)
fi
done
}

function keypair() {
if ! [[ "$PUBLIC_KEY" ]]; then
if ! [[ -f nodes/keypair ]]; then
echo "Getting keypair"
(cd web/backend && npm run keygen) | tail -n 2 >nodes/keypair
fi
. nodes/keypair
export PUBLIC_KEY PRIVATE_KEY
fi
}

function kill_nodes() {
pkill dvoting || true
rm -rf nodes/node*
}

function init_nodes() {
kill_nodes
keypair

echo "Starting nodes"
for n in $(seq 4); do
NODEPORT=$((2000 + n * 2))
PROXYPORT=$((2001 + n * 2))
NODEDIR=./nodes/node-$n
mkdir -p $NODEDIR
rm -f $NODEDIR/node.log
dvoting --config $NODEDIR start --postinstall --proxyaddr :$PROXYPORT --proxykey $PUBLIC_KEY \
--listen tcp://0.0.0.0:$NODEPORT --public http://localhost:$NODEPORT --routing tree |
ts "Node-$n: " | tee $NODEDIR/node.log &
done

echo "Waiting for nodes to start up"
for n in $(seq 4); do
NODEDIR=./nodes/node-$n
while ! [[ -S $NODEDIR/daemon.sock && -f $NODEDIR/node.log && $(cat $NODEDIR/node.log | wc -l) -ge 2 ]]; do
sleep .2
done
done
}

function init_dela() {
echo "Initializing dela"
echo " Share the certificate"
for n in $(seq 2 4); do
TOKEN_ARGS=$(dvoting --config ./nodes/node-1 minogrpc token)
NODEDIR=./nodes/node-$n
dvoting --config $NODEDIR minogrpc join --address //localhost:2002 $TOKEN_ARGS
done

echo " Create a new chain with the nodes"
for n in $(seq 4); do
NODEDIR=./nodes/node-$n
# add node to the chain
MEMBERS="$MEMBERS --member $(dvoting --config $NODEDIR ordering export)"
done
dvoting --config ./nodes/node-1 ordering setup $MEMBERS

echo " Authorize the signer to handle the access contract on each node"
for s in $(seq 4); do
NODEDIR=./nodes/node-$s
IDENTITY=$(crypto bls signer read --path $NODEDIR/private.key --format BASE64_PUBKEY)
for n in $(seq 4); do
NODEDIR=./nodes/node-$n
dvoting --config $NODEDIR access add --identity "$IDENTITY"
done
done

echo " Update the access contract"
for n in $(seq 4); do
NODEDIR=./nodes/node-$n
IDENTITY=$(crypto bls signer read --path $NODEDIR/private.key --format BASE64_PUBKEY)
dvoting --config ./nodes/node-1 pool add --key ./nodes/node-1/private.key --args go.dedis.ch/dela.ContractArg \
--args go.dedis.ch/dela.Access --args access:grant_id \
--args 0300000000000000000000000000000000000000000000000000000000000000 --args access:grant_contract \
--args go.dedis.ch/dela.Evoting --args access:grant_command --args all --args access:identity --args $IDENTITY \
--args access:command --args GRANT
done
}

function kill_db() {
docker rm -f postgres_dvoting || true
}

function init_db() {
kill_db

echo "Starting postgres database"
docker run -d -v "$(pwd)/web/backend/src/migration.sql:/docker-entrypoint-initdb.d/init.sql" \
-e POSTGRES_PASSWORD=$DATABASE_PASSWORD -e POSTGRES_USER=$DATABASE_USERNAME \
--name postgres_dvoting -p 5432:5432 postgres:15 >/dev/null

echo "Adding SCIPER to admin"
(cd web/backend && npx ts-node src/cli.ts addAdmin --sciper $SCIPER_ADMIN | grep -v Executing)
}

function kill_backend() {
pkill -f "web/backend" || true
}

function start_backend() {
kill_backend
keypair

echo "Running backend"
(cd web/backend && npm run start-dev | ts "Backend: " &)
}

function kill_frontend(){
pkill -f "web/frontend" || true
}

function start_frontend() {
kill_frontend
keypair

echo "Running frontend"
(cd web/frontend && npm run start-dev | ts "Frontend: " &)
}

export SCIPER_ADMIN=100100
export DATABASE_USERNAME=dvoting
export DATABASE_PASSWORD=postgres
export FRONT_END_URL="http://localhost:3000"
export DELA_NODE_URL="http://localhost:2003"
export BACKEND_HOST="localhost"
export BACKEND_PORT="6000"
export SESSION_SECRET="session secret"
export REACT_APP_NOMOCK=on

if [[ "$1" == "clean" ]]; then
kill_frontend
kill_nodes
kill_backend
kill_db
exit
fi

build_dela
init_nodes
init_dela
init_db
start_backend
start_frontend
2 changes: 1 addition & 1 deletion scripts/setup_forms.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ if [ -z "$COOKIE" ]; then
exit 1;
fi

FRONTEND_URL=https://127.0.0.1:3000
FRONTEND_URL=http://127.0.0.1:3000

echo "add form";
RESP=$(curl -k '$FRONTEND_URL/api/evoting/forms' -X POST -H 'Content-Type: application/json' -H "Cookie: connect.sid=$COOKIE" --data-raw '{"Configuration":{"MainTitle":"{\"en\":\"Colours\",\"fr\":\"\",\"de\":\"\"}","Scaffold":[{"ID":"5DRhKsY2","Title":"Colours","TitleFr":"","TitleDe":"","Order":["d0mSUfpv"],"Ranks":[],"Selects":[{"ID":"d0mSUfpv","Title":"{\"en\":\"RGB\",\"fr\":\"\",\"de\":\"\"}","TitleDe":"","TitleFr":"","MaxN":1,"MinN":1,"Choices":["{\"en\":\"Red\"}","{\"en\":\"Green\"}","{\"en\":\"Blue\"}"],"ChoicesMap":{},"Hint":"{\"en\":\"\",\"fr\":\"\",\"de\":\"\"}","HintFr":"","HintDe":""}],"Texts":[],"Subjects":[]}]}}');
Expand Down
10 changes: 6 additions & 4 deletions scripts/setup_proxies.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ if [ -z "$COOKIE" ]; then
exit 1;
fi

FRONTEND_URL=http://127.0.0.1:3000

echo "add proxies";
curl -sk 'https://127.0.0.1:3000/api/proxies/' -X POST -H 'Content-Type: application/json' -H "Cookie: connect.sid=$COOKIE; redirect=/" --data-raw '{"NodeAddr":"localhost:2000","Proxy":"http://localhost:2001"}';
curl -sk 'https://127.0.0.1:3000/api/proxies/' -X POST -H 'Content-Type: application/json' -H "Cookie: connect.sid=$COOKIE; redirect=/" --data-raw '{"NodeAddr":"localhost:2002","Proxy":"http://localhost:2003"}';
curl -sk 'https://127.0.0.1:3000/api/proxies/' -X POST -H 'Content-Type: application/json' -H "Cookie: connect.sid=$COOKIE; redirect=/" --data-raw '{"NodeAddr":"localhost:2004","Proxy":"http://localhost:2005"}';
curl -sk 'https://127.0.0.1:3000/api/proxies/' -X POST -H 'Content-Type: application/json' -H "Cookie: connect.sid=$COOKIE; redirect=/" --data-raw '{"NodeAddr":"localhost:2006","Proxy":"http://localhost:2007"}';
curl -sk "$FRONTEND_URL/api/proxies/" -X POST -H 'Content-Type: application/json' -H "Cookie: connect.sid=$COOKIE; redirect=/" --data-raw '{"NodeAddr":"localhost:2000","Proxy":"http://localhost:2001"}';
curl -sk "$FRONTEND_URL/api/proxies/" -X POST -H 'Content-Type: application/json' -H "Cookie: connect.sid=$COOKIE; redirect=/" --data-raw '{"NodeAddr":"localhost:2002","Proxy":"http://localhost:2003"}';
curl -sk "$FRONTEND_URL/api/proxies/" -X POST -H 'Content-Type: application/json' -H "Cookie: connect.sid=$COOKIE; redirect=/" --data-raw '{"NodeAddr":"localhost:2004","Proxy":"http://localhost:2005"}';
curl -sk "$FRONTEND_URL/api/proxies/" -X POST -H 'Content-Type: application/json' -H "Cookie: connect.sid=$COOKIE; redirect=/" --data-raw '{"NodeAddr":"localhost:2006","Proxy":"http://localhost:2007"}';
1 change: 1 addition & 0 deletions web/backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"type": "commonjs",
"scripts": {
"start": "ts-node -r dotenv/config src/Server.ts dotenv_config_path=config.env",
"start-dev": "NODE_ENV=development ts-node -r dotenv/config src/Server.ts dotenv_config_path=config.env",
"dev": "./node_modules/.bin/nodemon",
"eslint": "./node_modules/.bin/eslint .",
"eslint-fix": "./node_modules/.bin/eslint . --fix",
Expand Down
31 changes: 31 additions & 0 deletions web/backend/src/controllers/authentication.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,37 @@ import { getUserPermissions, setMapAuthorization } from '../authManager';

export const authenticationRouter = express.Router();

authenticationRouter.get('/get_dev_login', (req, res) => {
if (process.env.NODE_ENV !== 'development') {
const err = `/get_dev_login can only be called in development: ${process.env.NODE_ENV}`;
console.error(err);
res.status(500).send(err);
return;
}
if (process.env.SCIPER_ADMIN === undefined) {
const err = 'Please set SCIPER_ADMIN for /get/dev/login endpoint';
console.error(err);
res.status(500).send(err);
return;
}
const sciper = parseInt(process.env.SCIPER_ADMIN, 10);
if (sciper < 100000 || sciper > 999999) {
const err = 'SCIPER_ADMIN must be between 100000 and 999999 included';
console.error(err);
res.status(500).send(err);
return;
}
req.session.userId = sciper;
req.session.lastName = 'develo';
req.session.firstName = 'pment';

const sciperSessions = sciper2sess.get(req.session.userId) || new Set<string>();
sciperSessions.add(req.sessionID);
sciper2sess.set(sciper, sciperSessions);

res.redirect('/logged');
});

// This is via this endpoint that the client request the tequila key, this key
// will then be used for redirection on the tequila server
authenticationRouter.get('/get_teq_key', (req, res) => {
Expand Down
Loading

0 comments on commit dc7db4b

Please sign in to comment.