Skip to content

Commit

Permalink
Merge pull request #33 from privacybydesign/chore/gradle-update
Browse files Browse the repository at this point in the history
Gradle update, TomEE 9 support, rate limiting
  • Loading branch information
bobhageman authored Sep 6, 2023
2 parents 4baad65 + 958a946 commit 1a6aef3
Show file tree
Hide file tree
Showing 29 changed files with 1,144 additions and 118 deletions.
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
build/
.gradle/
src/main/resources/config.json
src/main/resources/clientmails/*
*.der
*.pem
node_modules
Expand All @@ -12,7 +11,9 @@ webapp/build
.settings/
bin/
artifacts/
.DS_Store

!src/main/webapp/WEB-INF
src/main/webapp/*
!src/main/webapp/WEB-INF/

.idea/
4 changes: 4 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"java.compile.nullAnalysis.mode": "automatic",
"java.configuration.updateBuildConfiguration": "automatic"
}
26 changes: 26 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@

FROM yarnpkg/node-yarn:latest as webappbuild

ARG LANGUAGE=en

# Build the webapp
COPY ./webapp/ /webapp/
WORKDIR /webapp
RUN yarn install && ./build.sh ${LANGUAGE}

FROM gradle:7.6-jdk11 as javabuild

# Build the java app
COPY ./ /app/
WORKDIR /app
RUN gradle build

FROM tomee:9.0-jre11

# Copy the webapp to the webapps directory
COPY --from=webappbuild /webapp/build/ /usr/local/tomee/webapps/ROOT/

# Copy the war file to the webapps directory
COPY --from=javabuild /app/build/libs/irma_email_issuer-1.1.0.war /usr/local/tomee/webapps/

EXPOSE 8080
61 changes: 53 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,61 @@

# Email server
# irma_email_issuer

Add an email address for use in your [Yivi app](https://github.com/privacybydesign/irma_mobile).
Add an e-mail address for use in your [Yivi app](https://github.com/privacybydesign/irmamobile).

## Running (development)
The easiest way to run the irma_email_issuer for development purposes is via Docker.

## Setting up the server
### Configuration
Various configuration files, keys and settings need to be in place to be able to build and run the apps.

1. To generate the required keys for the issuer, run:
```bash
$ utils/keygen.sh ./src/main/resources/sk ./src/main/resources/pk
```

2. Create the Java app configuration:
Copy the file `src/main/resources/config.sample.json` to `src/main/resources/config.json`.

### Run
Use docker-compose up combined with your localhost IP address as environment variable to spin up the containers:
```bash
$ IP=192.168.1.105 docker-compose up
```
Note: do not use `127.0.0.1` or `0.0.0.0` as IP addresses as this will result in the app not being able to find the issuer.

By default, docker-compose caches docker images, so on a second run the previous built images will be used. A fresh build can be enforced using the --build flag.
```bash
$ IP=192.168.1.105 docker-compose up --build
```

## Manual
The Java api and JavaScript frontend can be built and run manually using the following commands:

1. Generate JWT keys for the issuer
```bash
./utils/keygen.sh ./src/main/resources/sk ./src/main/resources/pk
$ utils/keygen.sh ./src/main/resources/sk ./src/main/resources/pk
```

2. Copy the file `src/main/resources/config.sample.json` to `src/main/resources/config.json` and modify it.

3. Build the webapp:
```bash
$ cd webapp && yarn install && yarn build en && cd ../
```
If you want to build another language, for example Dutch, change `build en` to `build nl`.

4. Copy the file `webapp/config.example.js` to `webapp/build/assets/config.js` and modify it

5. Run the following command in the root directory of this project:
```bash
$ gradle appRun
```

To open the webapp navigate to http://localhost:8080. The API is accessible via http://localhost:8080/irma_email_issuer/api

## Test
You can run the tests, defined in `src/test/java/foundation/privacybydesign/email`, using the following command:
```bash
$ gradle test
```
2. Copy the file `src/main/resources/config.sample.json` to
`build/resources/main/config.json` and modify it.
3. Run `gradle appRun` in the root directory of this project.
4. Navigate to `http://localhost:8080/irma_email_issuer/api/hello`
36 changes: 21 additions & 15 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ group 'foundation.privacybydesign.email'
version '1.1.0'

apply plugin: 'war'
apply plugin: 'org.akhikhl.gretty'
apply plugin: 'org.gretty'

sourceCompatibility = 1.7
sourceCompatibility = 11

buildscript {
repositories {
Expand All @@ -13,32 +13,38 @@ buildscript {
}
}
dependencies {
classpath "gradle.plugin.org.akhikhl.gretty:gretty:1.4.2"
classpath "org.gretty:gretty:4.0.3"
}
}

repositories {
mavenLocal()
maven {
url "https://credentials.github.io/repos/maven2/"
}
mavenCentral()
}

dependencies {
compile 'org.glassfish.jersey.core:jersey-server:2.25'
compile 'org.glassfish.jersey.containers:jersey-container-servlet:2.25'
compile 'ch.qos.logback:logback-classic:1.1.7'
compile 'com.sun.mail:javax.mail:1.5.6'

compile 'org.irmacard.api:irma_api_common:1.2.2'
compile 'foundation.privacybydesign.common:irma_server_common:0.3.2'

testCompile group: 'junit', name: 'junit', version: '4.12'
implementation 'org.glassfish.jersey.core:jersey-server:3.0.0'
implementation 'org.glassfish.jersey.containers:jersey-container-servlet:3.0.0'
implementation 'org.glassfish.jersey.inject:jersey-hk2:3.0.0'
implementation 'ch.qos.logback:logback-classic:1.1.7'
implementation 'com.sun.mail:jakarta.mail:2.0.1'
implementation 'jakarta.ws.rs:jakarta.ws.rs-api:3.1.0'

implementation 'io.jsonwebtoken:jjwt:0.9.1'
implementation 'com.google.code.gson:gson:2.8.9'
implementation 'org.apache.commons:commons-lang3:3.7'
implementation 'org.bouncycastle:bcpkix-jdk15on:1.70'
implementation 'org.bouncycastle:bcprov-jdk15on:1.67'
implementation 'jakarta.xml.bind:jakarta.xml.bind-api:3.0.1'

implementation 'org.irmacard.api:irma_api_common:2.0.0'

testImplementation group: 'junit', name: 'junit', version: '4.13.1'
}

gretty {
contextConfigFile = file('src/main/resources/jetty-env.xml')
scanInterval = 10
inplaceMode = "hard"
extraResourceBase 'webapp/build'
}
61 changes: 61 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
version: "3.8"
name: irma_email_issuer

services:
# Irma issuer service
irmaserver:
image: ghcr.io/privacybydesign/irma:v0.13.2
working_dir: /irmago
ports:
- 8088:8088
expose:
- 8088
networks:
- irma-net
entrypoint:
- "irma"
- "server"
- "--no-auth=false"
- "--requestors={\"irma_email_issuer\":{\"auth_method\":\"publickey\",\"key_file\": \"/config/pk.pem\"} }"
- "--port=8088"
- "--jwt-privkey-file=/config/sk.pem"
- "--url=http://${IP}:8088"
volumes:
- ./src/main/resources/:/config/

# Mailhog service
mailhog:
image: mailhog/mailhog
networks:
# We use a localhost alias such that the test configuration also works for users who run it without Docker.
irma-net:
aliases:
- mailhog.localhost
ports:
- 1025:1025
- 8025:8025 # Port of the web interface

# Service that runs the SMS issuer webapp and api
irma_email_issuer:
platform: linux/x86_64
build:
context: .
dockerfile: Dockerfile
volumes:
# Make keys and config files available for Java app
- ./src/main/resources/:/config/
# Make config.js available for webapp
- ./webapp/config.example.js:/usr/local/tomee/webapps/ROOT/assets/config.js:ro"
ports:
- 8080:8080
expose:
- 8080
networks:
- irma-net

# Docker Desktop for MacOS does not support exposing ports when using host networking. Therefore,
# we have to use bridge networking and expose the ports manually.
# https://github.com/docker/for-mac/issues/1031
networks:
irma-net:
driver: bridge
3 changes: 2 additions & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9.4-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.2-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package foundation.privacybydesign.email;

import foundation.privacybydesign.email.ratelimit.MemoryRateLimit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import jakarta.servlet.ServletContextEvent;
import jakarta.servlet.ServletContextListener;
import jakarta.servlet.annotation.WebListener;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
* Clean up in-memory data structures once in a while.
*/
@WebListener
public class CleanupBackgroundJob implements ServletContextListener {
private static Logger logger = LoggerFactory.getLogger(CleanupBackgroundJob.class);
private ScheduledExecutorService scheduler;

@Override
public void contextInitialized(ServletContextEvent event) {
logger.info("Setting up background cleanup task");
scheduler = Executors.newSingleThreadScheduledExecutor();

scheduler.scheduleAtFixedRate(new Runnable() {
@Override public void run() {
try {
MemoryRateLimit.getInstance().periodicCleanup();
} catch (Exception e) {
logger.error("Failed to run periodic cleanup:");
e.printStackTrace();
}
}
}, 5, 5, TimeUnit.MINUTES);
}

@Override
public void contextDestroyed(ServletContextEvent event) {
scheduler.shutdownNow();
}
}
2 changes: 0 additions & 2 deletions src/main/java/foundation/privacybydesign/email/Client.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.HashMap;

public class Client {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package foundation.privacybydesign.email;

import foundation.privacybydesign.common.BaseConfiguration;
import foundation.privacybydesign.email.common.BaseConfiguration;
import io.jsonwebtoken.SignatureAlgorithm;
import org.irmacard.api.common.util.GsonUtil;
import org.slf4j.Logger;
Expand All @@ -12,7 +12,7 @@
import java.util.HashMap;
import java.util.Map;

public class EmailConfiguration extends BaseConfiguration {
public class EmailConfiguration extends BaseConfiguration<EmailConfiguration> {
private static Logger logger = LoggerFactory.getLogger(Client.class);

static EmailConfiguration instance;
Expand Down Expand Up @@ -109,6 +109,10 @@ public PrivateKey getPrivateKey() throws KeyManagementException {
public SignatureAlgorithm getJwtAlgorithm() { return SignatureAlgorithm.RS256; }

public Client getClient(String token) {
if (clients == null || !clients.containsKey(token)) {
return null;
}

return clients.get(token);
}

Expand Down
26 changes: 0 additions & 26 deletions src/main/java/foundation/privacybydesign/email/EmailProvider.java

This file was deleted.

Loading

0 comments on commit 1a6aef3

Please sign in to comment.