# Queue

A queueing system to be used at labs at EWI (tudelft.nl).

## Contributing and Setup

Please read our [contribution guide](CONTRIBUTING.md) for information about project setup and contributing guidelines.

## Deployment

The `deploy/` directory contains an Ansible playbook that can be used to provision the machine. Specifically, it contains:

 - an nginx site config (`default`) with an upstream for tomcat on port 8080 together with config for a letsencrypt generated SSL certificate.
 - a SystemD configuration (`queue.service`) that runs the jar at `/var/www/queue/queue-0.0.1-SNAPSHOT.jar` as root on startup and logs to `/var/log/queue.log`.
 - an ansible config that installs Oracle java 8, nginx, postgres, haveged, the SystemD job, the jar, and starts the services.
 - an `application.yaml` file with application-specific configuration, such as the database settings.

To run the playbook, first replace the hostname and your SSH key in `deploy/hosts`, then run `./deploy/run.sh`.

### Environments

The system distinguishes two profiles: `development` and `production`. Use the `application.yaml` file to set the active profile. The active profile has the following impact:

- The `DatabaseLoader`, which loads the database with dummy data, is only run if the `development` profile is active.

## Database migrations

The queue uses [liquibase](https://www.liquibase.org/index.html) for database migrations.
The changelog can be found in src/main/resources/changeLog.yaml, the corresponding documentation can be found 
[here](https://www.liquibase.org/documentation/index.html). To run and test a liquibase migration in the development
environment you need to change a few settings in the application properties file.

1. Point Spring to the changelog you want to apply using the: `liquibase.change-log=` property
1. Change the `spring.datasource.url=` property to a persistent h2 url rather than the in-memory variant.

## Roles

A user has a single _default_ role and a single _contextual_ role for every course that he participates in. This distinction is necessary because, for example, a teacher may not be a teacher in every course. The default roles are `STUDENT`,  `TEACHER`, and `ADMIN`. The contextual roles are `STUDENT`, `TA`, `HEAD_TA` and `TEACHER`.

A user can have at most one contextual role within a course. A `TA` is able to handle requests. A `HEAD_TA` can do everything an `TA` can, but may also manage assignments and labs. A `TEACHER` can do everything an `TA` can, but can also remove the course and change the course's name.

The default roles form a hierarchy. That is, an `ADMIN` can do everything a `TEACHER` can, and a `TEACHER` can do everything a `STUDENT` can. A user with default role `STUDENT` has no special permissions. A user with default role `TEACHER` is allowed to create courses. A user with default role `ADMIN` is allowed to change a user's default role.

When an `ADMIN` operates within a course, he acts as a `TEACHER`. It is advised to use the admin account solely for administrative usages (such as setting up a course).

## Security

- Passwords are encrypted with bcrypt, which protects against rainbow table attacks and remains resistant to brute-force attacks when computing power increases.
- All forms are accommodated with an `_csrf` field to protect against CSRF attacks.
- We only support HTTPS connections, because supporting both HTTP and HTTPS is too much of an effort (and there is little to no reason to support HTTP). Spring Security will make sure the HTTP Strict Transport Security (HSTS) headers are set. In development mode, make sure you accept the certificate. On OS X, adding `keystore.p12` to Keychain will get you a green padlock in Chrome. This is required for push notifications, among others.
- All `User`s have a `Role`, which is one of: STUDENT, ASSISTANT, TEACHER, ADMIN.

## SSO

SAML provides Single Sign On (SSO). The Queue system acts as a Service Provider (SP). It requests and obtains an identity assertion from the identity provider (TUDelft gatekeeper). By default, only identity assertions with a max age of 7200 seconds are trusted. This can be changed by updating `maxAuthenticationAge` on the `WebSSOProfileImpl` object. Alternatively, you can force the IDP to re-authenticate the user by setting `forceAuthN` to `true` on the `WebSSOProfileOptions` object.

In development you may not want to go through the SAML process. An in-memory option is available for development and is turned on by default.

### Crypto

The SAML messages are cryptographically signed. The file `security/samlKeystore.jks` is a Java keystore. It has no password (when prompted for a password, enter the empty string). The development keystore contains a key with alias `apollo` and password `nalle123`. For production, you'll want to:

1. Create a PKCS12 file using your private key and a CA signed certificate of it. You can use openssl command for this: `openssl pkcs12 -export -in /etc/ssl/certs/queue_ewi_tudelft_nl.crt -inkey /etc/ssl/private/queue.ewi.tudelft.nl.key -certfile /etc/ssl/certs/queue_ewi_tudelft_nl.crt -out testkeystore.p12`
1. Create a Java keystore (.jks file) using the `keytool`: `keytool -importkeystore -srckeystore testkeystore.p12 -srcstoretype pkcs12 -destkeystore keystore.jks -deststoretype JKS`
1. To list the keys in the Java keystore: `keytool -list -v -keystore keystore.jks`

([source](http://xacmlinfo.org/2014/06/13/how-to-keystore-creating-jks-file-from-existing-private-key-and-certificate/))

### Metadata

The SP metadata can be generated automatically. To do so, visit `/saml/metadata`. The browser will provide a file `spring_saml_metadata.xml`. You need to deliver this file to the TU Delft.

## Push

Notifications are sent using the [Push API](https://developer.mozilla.org/en-US/docs/Web/API/Push_API). The Push API is [experimental](http://caniuse.com/#feat=push-api) and we expect things to break. Note that the Push API requires HTTPS.

## Apache2 config
With regards to deployment and the high number of students, ensure that the value for MaxRequestWorkers in Apache2 is high enough. 
For example, for about 450 first year students, the number 250 was found to be suitable.
The file to edit for this is mpm_prefork.conf and the directive is MaxRequestWorkers.


## Notes to developers

### Security

- To ensure forms have a `_csrf` field, either make sure the form uses `th:action`, as this automagically adds the field or add it by hand as a hidden input field.

### Faster Authentication
- When logging in on the development build, you can speed up the process by leaving out "@tudelft.nl" and the password and it will automatically fill in the credentials for you.

## Support

### GitLab Issues
If you encounter a bug or have a feature request, you can directly add it to our [issue list](https://gitlab.ewi.tudelft.nl/eip/labrador/queue/-/issues). 
When creating an issue, you can select from the "Bug" or "Feature" templates, to help you provide the necessary information.

### Mattermost
We have a dedicated [support channel](https://mattermost.tudelft.nl/educational-software-support/channels/queue) on Mattermost,
where you can ask Queue-related questions.

### Email
You can also email [support-eip-ewi@tudelft.nl](mailto:support-eip-ewi@tudelft.nl) directly for any questions or issues you might have.
