Skip to content

Commit

Permalink
Merge pull request #349 from dedis/feat/adds-voting-permissions
Browse files Browse the repository at this point in the history
Feat: adds voting permission
  • Loading branch information
PascalinDe authored Sep 25, 2023
2 parents 2c6c609 + b4499de commit 34ba6ca
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 15 deletions.
1 change: 1 addition & 0 deletions web/backend/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,6 @@ Commands:
addAdmin [options] Given a SCIPER number, the owner would gain full admin permissions
listUserPermissions [options] Lists the permissions -if any- of the owner of a given SCIPER
removeAdmin [options] Given a SCIPER number, the owner would lose all admin privileges -if any-
addVoters [options] Assigns a list of SCIPERs to an Election as Voters
help [command] display help for command
```
2 changes: 2 additions & 0 deletions web/backend/src/.voters.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
123456
321451
36 changes: 35 additions & 1 deletion web/backend/src/cli.ts
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ Backend CLI, currently providing 3 commands for user management:
npx cli removeAdmin --sciper 1234
*/

import { Command } from 'commander';
import { Command, InvalidArgumentError } from 'commander';
import { SequelizeAdapter } from 'casbin-sequelize-adapter';
import { newEnforcer } from 'casbin';
import { curve } from '@dedis/kyber';
import * as fs from 'fs';
import { PERMISSIONS } from './authManager';

const program = new Command();

Expand Down Expand Up @@ -78,4 +80,36 @@ program
console.log(`PUBLIC_KEY=${pub}`);
});

// Imports a list of SCIPERS from a file to allow to vote on a specific election
// the .voters.example file is available as an example
program
.command('addVoters')
.description('Assigns a list of SCIPERs to an Election as Voters')
.requiredOption('-e, --election-id <char>', 'ID of the election')
.requiredOption('-sf, --scipers-file <char>', 'File with line-separated list of SCIPERs')
.action(async ({ electionId, scipersFile }) => {
fs.readFile(scipersFile, 'utf8', async (err: any, data: string) => {
if (err) {
throw new InvalidArgumentError(`Faced a problem trying to process your file: \n ${err}`);
}
const scipers: Array<string> = data.split('\n');
const policies = [];
for (let i = 0; i < scipers.length; i += 1) {
const sciper: number = Number(scipers[i]);
if (Number.isNaN(sciper)) {
throw new InvalidArgumentError(`SCIPER '${sciper}' on line ${i + 1} is not a number`);
}
if (sciper > 999999 || sciper < 100000) {
throw new InvalidArgumentError(
`SCIPER '${sciper}' on line ${i + 1} is outside acceptable range (100000..999999)`
);
}
policies[i] = [scipers[i], electionId, PERMISSIONS.ACTIONS.VOTE];
}
const enforcer = await initEnforcer();
await enforcer.addPolicies(policies);
console.log('Added Voting policies successfully!');
});
});

program.parse();
42 changes: 29 additions & 13 deletions web/backend/src/controllers/dela.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ function sendToDela(dataStr: string, req: express.Request, res: express.Response
let uri = process.env.DELA_NODE_URL + req.baseUrl.slice(4);
// boolean to check
let redirectToDefaultProxy = true;
// in case this is a DKG init request, we must also update the payload.

// in case this is a DKG init request, we must also update the payload.
const dkgInitRegex = /\/evoting\/services\/dkg\/actors$/;
if (uri.match(dkgInitRegex)) {
const dataStr2 = JSON.stringify({ FormID: req.body.FormID });
Expand Down Expand Up @@ -154,6 +154,7 @@ delaRouter.post('/services/dkg/actors', (req, res, next) => {
}
next();
});

delaRouter.use('/services/dkg/actors/:formID', (req, res, next) => {
const { formID } = req.params;
if (!isAuthorized(req.session.userId, formID, PERMISSIONS.ACTIONS.OWN)) {
Expand All @@ -162,6 +163,7 @@ delaRouter.use('/services/dkg/actors/:formID', (req, res, next) => {
}
next();
});

delaRouter.use('/services/shuffle/:formID', (req, res, next) => {
if (!req.session.userId) {
res.status(401).send('Unauthenticated');
Expand All @@ -174,6 +176,32 @@ delaRouter.use('/services/shuffle/:formID', (req, res, next) => {
}
next();
});

delaRouter.post('/forms/:formID/vote', (req, res) => {
if (!req.session.userId) {
res.status(401).send('Authentication required!');
return;
}
if (!isAuthorized(req.session.userId, req.params.formID, PERMISSIONS.ACTIONS.VOTE)) {
res.status(400).send('Unauthorized');
return;
}

// We must set the UserID to know who this ballot is associated to. This is
// only needed to allow users to cast multiple ballots, where only the last
// ballot is taken into account. To preserve anonymity, the web-backend could
// translate UserIDs to another random ID.
// bodyData.UserID = req.session.userId.toString();

// DEBUG: this is only for debugging and needs to be replaced before production
const bodyData = req.body;
console.warn('DEV CODE - randomizing the SCIPER ID to allow for unlimited votes');
bodyData.UserID = makeid(10);

const dataStr = JSON.stringify(bodyData);
sendToDela(dataStr, req, res);
});

delaRouter.delete('/forms/:formID', (req, res) => {
if (!req.session.userId) {
res.status(401).send('Unauthenticated');
Expand Down Expand Up @@ -235,18 +263,6 @@ delaRouter.use('/*', (req, res) => {
}

const bodyData = req.body;

// special case for voting
const regex = /\/api\/evoting\/forms\/.*\/vote/;
if (req.baseUrl.match(regex)) {
// We must set the UserID to know who this ballot is associated to. This is
// only needed to allow users to cast multiple ballots, where only the last
// ballot is taken into account. To preserve anonymity the web-backend could
// translate UserIDs to another random ID.
// bodyData.UserID = req.session.userId.toString();
bodyData.UserID = makeid(10);
}

const dataStr = JSON.stringify(bodyData);

sendToDela(dataStr, req, res);
Expand Down
1 change: 0 additions & 1 deletion web/backend/src/controllers/users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ usersRouter.post('/add_role', (req, res, next) => {
});

// This call (only for admins) allow an admin to remove a role to a user.

usersRouter.post('/remove_role', (req, res, next) => {
if (!isAuthorized(req.session.userId, PERMISSIONS.SUBJECTS.ROLES, PERMISSIONS.ACTIONS.REMOVE)) {
res.status(400).send('Unauthorized - only admins allowed');
Expand Down

0 comments on commit 34ba6ca

Please sign in to comment.