# CAcert board voting service

This project contains the source code for the CAcert board voting software.

## License

The CAcert board voting software is licensed under the terms of the Apache License, Version 2.0.

   Copyright 2017-2019 Jan Dittberner

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this program except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

## History

The CAcert board voting software is a [Go] reimplementation of the ancient PHP implementation that had been serving the
CAcert board. The Subversion repository at https://svn.cacert.cl/Software does not exist anymore so the last available
version from http://community.cacert.org/board/ has been taken from the system. The latest file changed was `proxy.php`
with a change date of 2011-05-15 23:13 UTC. The latest svn revision was:

```text
Path: .
URL: https://svn.cacert.cl/Software/Voting/vote
Repository Root: https://svn.cacert.cl/Software
Repository UUID: d4452222-2f33-11de-9270-010000000000
Revision: 66
Node Kind: directory
Schedule: normal
Last Changed Author: community.cacert.org
Last Changed Rev: 66
Last Changed Date: 2009-07-12 04:02:38 +0000 (Sun, 12 Jul 2009)
```

---

## Development requirements

Local development requires

* golang >= 1.11
* sqlite3 and development headers
* GNU make
* nodejs, npm and gulp (only needed if you intend to update the [jQuery] or [Semantic UI] CSS and JavaScript)

On a Debian 10 (Buster) system you can run the following command to get all required dependencies:

```bash
sudo apt install libsqlite3-dev golang-go make gulp
```

## Getting started

Clone the code via git:

```shell script
git clone ssh://git.cacert.org/var/cache/git/cacert-boardvoting.git
```

To get started copy `config.yaml.example` to `config.yaml` and customize the parameters. You will also need a set of
X.509 certificates and a private key because the application performs TLS Client certificate authentication. You might
use `openssl` to create a self signed server certificate and retrieve the CAcert class 3 root from the CAcert website:

```shell script
openssl req -new -newkey rsa:2048 -keyout server.key -x509 -out server.crt -subj '/CN=localhost'
curl -o cacert_class3.pem http://www.cacert.org/certs/class3_X0E.crt
```

It is advisable to have a local mail setup that intercepts outgoing email or to use email addresses that you control.

You can use the following table to find useful values for the parameters in `config.yaml`.

Parameter | Description | How to get a valid value
----------|-------------|-------------------------
`notice_mail_address` | email address where notifications about votes are sent (production value is cacert-board@lists.cacert.org) | be creative but do not spam others (i.e. use user+board@your-domain.org)
`vote_notice_mail_address` | email address where notifications about individual votes are sent (production value is cacert-board-votes@lists.cacert.org) | be creative but do not spam others (i.e. use user+votes@your-domain.org)
`notification_sender_address` | sender address for all mails sent by the system (production value is returns@cacert.org) | be creative but do not spam others (i.e. use user+returns@your-domain.org)
`database_file` | a SQLite database file (production value is `database.sqlite`) | keep the default or use something like `local.sqlite`
`client_ca_certificates` | File containing allowed client certificate CA certificates (production value is `cacert_class3.pem`) | use the shell code above
`server_certificate` | X.509 certificate that is used to identify your server (i.e. `server.crt`) | use the filename used as `-out` parameter in the `openssl` invocation above
`server_key` | PEM encoded private key file (i.e. `server.key`) | use the filename used as `-keyout` parameter in the `openssl` invocation above
`cookie_secret` | A base64 encoded random byte value of at least 32 bytes used to encrypt cookies | see [Generating random byte values](#generating-random-byte-values) below
`csrf_key` | A base64 encoded random byte value of at least 32 bytes used to encrypt [CSRF](https://en.wikipedia.org/wiki/Cross-site_request_forgery#Prevention) tokens | see [Generating random byte values](#generating-random-byte-values) below
`base_url` | The base URL of your application instance (production value is https://motions.cacert.org) | use https://localhost:8443
`mail_server`.`host` | Mail server host (production value is `localhost`) | `localhost`
`mail_server`.`port` | Mail server TCP port (production value is `25` | see [how to setup a debugging SMTP server](#debugging-smtp-server) below and choose the port of that (default `8025`)
### Generating random byte values

```shell script
dd if=/dev/urandom bs=32 count=1 2>/dev/null | base64
```

### Debugging SMTP server

You can use [aiosmtpd](https://aiosmtpd.readthedocs.io/en/latest/aiosmtpd/docs/cli.html) to setup a small testing SMTP
server that logs to stdout:

```shell script
sudo apt install python3-aiosmtpd
python3 -m aiosmtpd -n
```

### Build and run

```shell script
make
./cacert-boardvoting
```

## Code structure

```
.
├── boardvoting
│   ├── migrations
│   ├── static
│   └── templates
├── db
└── semantic
```

The `boardvoting` directory contains the application code, database migrations, static assets and [Go templates] for
HTML pages and mail content.

The `db` directory contains the initializer for database migrations.

The `semantic` directory contains a download of [Semantic UI]

The entry point into the application is `boardvoting.go` in the top level directory. `Makefile` controls the build
`Jenkinsfile` contains the pipeline definition for the [Continuous Integration Job]. `package-lock.json` contains the
pinned versions of external JavaScript and CSS assets (use `npm install` to download them into a local `node_modules`
directory). `semantic.json` is the configuration file for the [Semantic UI] CSS framework.

[Continuous Integration Job]: https://jenkins.cacert.org/job/cacert-boardvoting/
[Go]: https://golang.org/
[Go templates]: https://golang.org/pkg/text/template/
[jQuery]: https://jquery.com/
[Semantic UI]: https://semantic-ui.com/
