Jan Dittberner
f27f2bf801
- update go tool in Jenkinsfile - update go version in go.mod - update README.md - update dependencies
211 lines
No EOL
11 KiB
Markdown
211 lines
No EOL
11 KiB
Markdown
# CAcert board voting service
|
|
|
|
This project contains the source code for the CAcert board voting software running on https://motion.cacert.org/.
|
|
|
|
## Ideas
|
|
|
|
The board voting system is meant to be used by the elected committee members of CAcert Inc. to allow them to do votes on
|
|
decisions in a distributed way. The system keeps track of the individual decisions and votes. It takes care of
|
|
authenticating board members using client certificates and performs timekeeping for decisions. The system sends voting
|
|
requests to all board members and takes care of sending reminders as well es decision results.
|
|
|
|
There is a concept of proxy votes that mean that one member of the board is allowed to vote in representation of another
|
|
member of a board.
|
|
|
|
## License
|
|
|
|
The CAcert board voting software is licensed under the terms of the Apache License, Version 2.0.
|
|
|
|
Copyright 2017-2022 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.19
|
|
* sqlite3 and development headers
|
|
* GNU make
|
|
* nodejs, npm and gulp (only needed if you intend to update the [jQuery] or [Fomantic-UI] CSS and JavaScript)
|
|
|
|
On a Debian 12 (Bookworm) 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 |
|
|
|-------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------|
|
|
| `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 |
|
|
| `mail_config.smtp_host` | Mail server host (production value is `localhost`) | `localhost` |
|
|
| `mail_config.smtp_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`) |
|
|
| `mail_config.base_url` | The base URL of your application instance (production value is https://motions.cacert.org) | use https://localhost:8443 |
|
|
| `mail_config.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) |
|
|
| `mail_config.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) |
|
|
| `mail_config.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) |
|
|
| `timeouts.idle` | idle timeout setting for HTTP and HTTPS (default: 1 minute) | specify a nano second value |
|
|
| `timeouts.read` | read timeout setting for HTTP and HTTPS (default: 5 seconds) | |
|
|
| `timeouts.read_header` | header read timeout setting for HTTP and HTTPS (default: 5 seconds) | |
|
|
| `timeouts.write` | write timeout setting for HTTP and HTTPS (default: 10 seconds) | |
|
|
|
|
### 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/cli.html) to set up a small testing SMTP
|
|
server that logs to stdout:
|
|
|
|
```shell script
|
|
sudo apt install python3-aiosmtpd
|
|
python3 -m aiosmtpd -n
|
|
```
|
|
|
|
Another good local SMTP debugging tool is [MailHog](https://github.com/mailhog/MailHog) which provides a web based
|
|
user interface and a REST API to inspect received mails.
|
|
|
|
### Build and run
|
|
|
|
```shell script
|
|
make
|
|
./cacert-boardvoting
|
|
```
|
|
|
|
### Build UI resources
|
|
|
|
[Fomantic-UI] is used as a CSS framework. Configuration is stored in `semantic.json` in the
|
|
project root directory.
|
|
|
|
Building the UI resource requires
|
|
|
|
* NodeJS >= v8
|
|
* NPM >= v5
|
|
|
|
To install fomantic-ui and build the UI resources do:
|
|
|
|
```
|
|
npm install
|
|
cd node_modules/fomantic-ui
|
|
npx gulp build
|
|
```
|
|
|
|
## Code structure
|
|
|
|
```
|
|
├── cmd
|
|
│ └── boardvoting
|
|
├── config.yaml.example
|
|
├── debian
|
|
├── go.mod
|
|
├── go.sum
|
|
├── internal
|
|
│ ├── app
|
|
│ ├── forms
|
|
│ ├── handlers
|
|
│ ├── jobs
|
|
│ ├── mailtemplates
|
|
│ ├── mailtemplates.go
|
|
│ ├── middleware
|
|
│ ├── migrations
|
|
│ ├── migrations.go
|
|
│ ├── models
|
|
│ ├── notifications
|
|
│ └── validator
|
|
├── Jenkinsfile
|
|
├── LICENSE
|
|
├── Makefile
|
|
├── package.json
|
|
├── package-lock.json
|
|
├── README.md
|
|
├── semantic.json
|
|
└── ui
|
|
├── efs.go
|
|
├── html
|
|
├── semantic
|
|
└── static
|
|
```
|
|
|
|
The `cmd/boardvoting` directory contains the application code.
|
|
|
|
The `internal/migrations` directory contains database migration scripts.
|
|
|
|
Static assets and [Go templates] for HTML pages are stored in `ui/static` and `ui/html`.
|
|
|
|
Email templates are stored in `internal/mailtemplates`.
|
|
|
|
All Go code besides the main application is stored in subdirectories of `internal`.
|
|
|
|
The `ui/semantic` directory contains a download of [Fomantic-UI].
|
|
|
|
The entry point into the application is `cmd/boardvoting/main.go`. `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 [Fomantic-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/
|
|
|
|
[Fomantic-UI]: https://fomantic-ui.com/ |