Queue
A queueing system to be used at labs at EWI (tudelft.nl).
Requirements
- Java 8+
Project setup
In order to have the project setup properly for development a few steps need to be taken.
- First the config file should be moved from the template into the actual properties file
by executing
cp src/main/resources/application.yaml.template src/main/resources/application.yaml
from the root directory of the project. - Follow these instructions to submit your work
Run website from IDE
- Install IntelliJ IDEA Professional (free for students)
- Import project from Gradle model
- For IntelliJ to run the project make sure are running jdk 8.
- Start the project by right-clicking
QueueApplication
and clicking 'Run' - Visit http://localhost:8081/
- Finally visit http://localhost:8081/login to login.
Various test users credentials can be found in the
DataBaseLoader
class.
Run website from CLI
gradle build
sudo java -jar build/libs/queue-0.0.1-SNAPSHOT.jar
- Visit http://localhost:8081/
- Finally visit http://localhost:8081/login to login.
Various test users credentials can be found in the
DataBaseLoader
class.
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
.
Note that the current application.yaml
contains spring.jpa.hibernate.ddl-auto=create
which will drop and create the database upon reboot!
Configuration
See application.yaml
. Chrome does not yet fully support the Web Push API and uses GCM to handle sending and delivery of push messages. To use the GCM API you need a GCM API key. This page explains how to obtain one.
You can place an application.yaml
on the classpath which overrides the application.yaml
in the jar itself.
Nowadays, Chrome supports VAPID (Voluntary Application Identification) for Web Push API and it is no longer necessary to obtain an API key. The Web Push library should be updated to the latest version that I'm maintaining at https://github.com/MartijnDwars/web-push. For VAPID, we need to generate yet another keypair..
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 thedevelopment
profile is active. - The
error.html
page only shows stack traces if thedevelopment
profile is active.
Domain
- A
Request
is always initiated by a student. At some point, it will be handled by an assistant.
Database migrations
The queue uses liquibase for database migrations. The changelog can be found in src/main/resources/changeLog.yaml, the corresponding documentation can be found here. To run and test a liquibase migration in the development environment you need to change a few settings in the application properties file.
- Point Spring to the changelog you want to apply using the:
liquibase.change-log=
property - 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
, ASSISTANT
, MANAGER
and TEACHER
.
A user can have at most one contextual role within a course. An ASSISTANT
is able to handle requests. A MANAGER
can do everything an ASSISTANT
can, but may also manage assignments and labs. A TEACHER
can do everything an ASSISTANT
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 adviced 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 accomodated 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 aRole
, 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. The traditional login page is still available at /login
. This requires that a User
with a username and password exists.
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:
- 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
- Create a Java keystore (.jks file) using the
keytool
:keytool -importkeystore -srckeystore testkeystore.p12 -srcstoretype pkcs12 -destkeystore keystore.jks -deststoretype JKS
- To list the keys in the Java keystore:
keytool -list -v -keystore keystore.jks
(source)
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. The Push API is experimental 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 usesth: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.