Skip to content

Commit

Permalink
Add support for authenticating a user with an X.509 cert
Browse files Browse the repository at this point in the history
  • Loading branch information
josephcummings committed Mar 18, 2024
1 parent bf8f11c commit 5065516
Show file tree
Hide file tree
Showing 82 changed files with 827 additions and 280 deletions.
49 changes: 49 additions & 0 deletions .github/workflows/plugins-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: tests workflow

on:
workflow_call:

jobs:
plugins:
name: Plugins

strategy:
fail-fast: false
matrix:
test: [ Plugins ]

runs-on: ubuntu-latest
steps:
- name: Login to Cloudsmith
uses: docker/login-action@v3
with:
registry: docker.eventstore.com
username: ${{ secrets.CLOUDSMITH_CICD_USER }}
password: ${{ secrets.CLOUDSMITH_CICD_TOKEN }}

- uses: actions/checkout@v3

- name: Set up JDK 8
uses: actions/setup-java@v3
with:
java-version: '8'
distribution: 'temurin'

- name: Setup Gradle
uses: gradle/gradle-build-action@v2
with:
gradle-version: 7.4

- name: Execute Gradle build
run: ./gradlew ci --tests ${{ matrix.test }}Tests
env:
EVENTSTORE_DOCKER_REGISTRY_ENV: docker.eventstore.com
EVENTSTORE_DOCKER_IMAGE_ENV: eventstore-staging-ee/eventstoredb-commercial
EVENTSTORE_DOCKER_TAG_ENV: 24.2.0-jammy

- uses: actions/upload-artifact@v3
if: failure()
with:
name: esdb_logs.tar.gz
path: db-client-java/esdb_logs.tar.gz
if-no-files-found: error
8 changes: 7 additions & 1 deletion .github/workflows/pull-requests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,10 @@ jobs:

uses: ./.github/workflows/tests.yml
with:
esdb_version: ${{ matrix.version }}
esdb_version: ${{ matrix.version }}

plugins-tests:
needs: build
name: Plugins Tests
uses: ./.github/workflows/plugins-tests.yml
secrets: inherit
4 changes: 2 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
strategy:
fail-fast: false
matrix:
test: [Streams, PersistentSubscriptions, Expectations ]
test: [Streams, PersistentSubscriptions, Expectations]

runs-on: ubuntu-latest
steps:
Expand Down Expand Up @@ -117,4 +117,4 @@ jobs:
SECURE: true

- name: Shutdown cluster
run: docker-compose down
run: docker-compose down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -171,5 +171,5 @@ fabric.properties
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
!gradle-wrapper.jar

# Generated certs
# Generated certificates
certs/
2 changes: 1 addition & 1 deletion configure-tls-for-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ services:
network_mode: "none"

setup:
image: eventstore/es-gencert-cli:1.0.2
image: ghcr.io/eventstore/es-gencert-cli:1.3.0
entrypoint: bash
user: "1000:1000"
command: >
Expand Down
25 changes: 25 additions & 0 deletions configure-user-certs-for-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
version: '3.5'

services:
volumes-provisioner:
image: "hasnat/volumes-provisioner"
environment:
PROVISION_DIRECTORIES: "1000:1000:0755:/tmp/certs"
volumes:
- "./certs:/tmp/certs"
network_mode: "none"

setup:
image: ghcr.io/eventstore/es-gencert-cli:1.3.0
entrypoint: bash
user: "1000:1000"
command: >
-c "mkdir -p ./certs && cd /certs
&& es-gencert-cli create-user -username admin
&& es-gencert-cli create-user -username invalid
&& find . -type f -print0 | xargs -0 chmod 666"
container_name: setup
volumes:
- ./certs:/certs
depends_on:
- volumes-provisioner
18 changes: 18 additions & 0 deletions db-client-java/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ dependencies {
implementation "io.grpc:grpc-protobuf:${grpcVersion}"
implementation "com.fasterxml.jackson.core:jackson-databind:${jacksonVersion}"
implementation 'org.slf4j:slf4j-api:2.0.9'
implementation "org.bouncycastle:bcprov-jdk18on:1.77"
implementation "org.bouncycastle:bcpkix-jdk18on:1.77"

testImplementation "org.junit.jupiter:junit-jupiter-api:${junitVersion}"
testImplementation "org.junit.jupiter:junit-jupiter-params:${junitVersion}"
Expand Down Expand Up @@ -78,6 +80,11 @@ tasks.register("generateCertificates", Exec) {
commandLine 'docker', 'compose', '--file', '../configure-tls-for-tests.yml', 'up'
}

tasks.register("generateUserCertificates", Exec) {
description = "Generates X.509 certificates for Plugins tests"
commandLine 'docker', 'compose', '--file', '../configure-user-certs-for-tests.yml', 'up'
}

tasks.register("startDockerCompose", Exec) {
description = "Starts ESDB cluster"
commandLine 'docker', 'compose', '--file', '../docker-compose.yml', 'up', '-d'
Expand Down Expand Up @@ -125,6 +132,17 @@ tasks.register("clusterTests", Test) {
}
}

tasks.register("pluginsTests", Test) {
dependsOn generateCertificates
dependsOn generateUserCertificates

environment "SECURE", "true"

useJUnitPlatform {
include("**/PluginsTests.class")
}
}

tasks.register("ci", Test) {
useJUnitPlatform()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public AbortProjection(final GrpcClient client, final String projectionName, fin
}

public CompletableFuture execute() {
return this.client.run(channel -> {
return this.client.run(options, channel -> {
Projectionmanagement.DisableReq.Options.Builder optionsBuilder =
Projectionmanagement.DisableReq.Options.newBuilder()
.setName(this.projectionName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
/**
* Options of the abort projection request.
*/
public class AbortProjectionOptions extends OptionsBase<AbortProjectionOptions> {
public class AbortProjectionOptions extends CallOptionsBase<AbortProjectionOptions> {
private AbortProjectionOptions() {
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ abstract class AbstractCreatePersistentSubscription<TPos, TSettings extends Pers
private final GrpcClient client;
private final String group;
private final TSettings settings;
private final OptionsBase options;
private final CallOptionsBase options;
private static final Logger logger = LoggerFactory.getLogger(AbstractCreatePersistentSubscription.class);

public AbstractCreatePersistentSubscription(GrpcClient client, String group,
TSettings settings, OptionsBase options) {
TSettings settings, CallOptionsBase options) {
this.client = client;
this.group = group;
this.settings = settings;
Expand All @@ -30,7 +30,7 @@ protected Persistent.CreateReq.Settings.Builder createSettings(){

@SuppressWarnings({"unchecked", "deprecation"})
public CompletableFuture execute() {
return this.client.runWithArgs(args -> {
return this.client.runWithArgs(options, args -> {
CompletableFuture result = new CompletableFuture();
PersistentSubscriptionsGrpc.PersistentSubscriptionsStub client =
GrpcUtils.configureStub(PersistentSubscriptionsGrpc.newStub(args.getChannel()), this.client.getSettings(), this.options);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public AbstractDeletePersistentSubscription(GrpcClient client, String group, Del

@SuppressWarnings("unchecked")
public CompletableFuture execute() {
return this.client.runWithArgs(args -> {
return this.client.runWithArgs(options, args -> {
CompletableFuture result = new CompletableFuture();
PersistentSubscriptionsGrpc.PersistentSubscriptionsStub client =
GrpcUtils.configureStub(PersistentSubscriptionsGrpc.newStub(args.getChannel()), this.client.getSettings(), this.options);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import java.time.Duration;

class AbstractPersistentSubscriptionSettingsBuilder<T, TSettings extends PersistentSubscriptionSettings> extends OptionsBase<T> {
class AbstractPersistentSubscriptionSettingsBuilder<T, TSettings extends PersistentSubscriptionSettings> extends CallOptionsBase<T> {
private final TSettings settings;

public AbstractPersistentSubscriptionSettingsBuilder(TSettings settings) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ abstract class AbstractRead implements Publisher<ReadMessage> {
protected static final StreamsOuterClass.ReadReq.Options.Builder defaultReadOptions;

private final GrpcClient client;
private final OptionsBase options;
private final CallOptionsBase options;

protected AbstractRead(GrpcClient client, OptionsBase options) {
protected AbstractRead(GrpcClient client, CallOptionsBase options) {
this.client = client;
this.options = options;
}
Expand All @@ -38,7 +38,7 @@ public void subscribe(Subscriber<? super ReadMessage> subscriber) {
subscriber.onSubscribe(readSubscription);

CompletableFuture<ReadSubscription> result = new CompletableFuture<>();
this.client.run(channel -> {
this.client.run(options, channel -> {
StreamsOuterClass.ReadReq request = StreamsOuterClass.ReadReq.newBuilder()
.setOptions(createOptions())
.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ abstract class AbstractRegularSubscription {
protected SubscriptionListener listener;
protected Checkpointer checkpointer = null;
private final GrpcClient client;
private final OptionsBase options;
private final CallOptionsBase options;

protected AbstractRegularSubscription(GrpcClient client, OptionsBase options) {
protected AbstractRegularSubscription(GrpcClient client, CallOptionsBase options) {
this.client = client;
this.options = options;
}
Expand All @@ -42,7 +42,7 @@ protected AbstractRegularSubscription(GrpcClient client, OptionsBase options) {

@SuppressWarnings("unchecked")
public CompletableFuture<Subscription> execute() {
return this.client.run(channel -> {
return this.client.run(options, channel -> {
StreamsOuterClass.ReadReq readReq = StreamsOuterClass.ReadReq.newBuilder()
.setOptions(createOptions())
.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

abstract class AbstractSubscribePersistentSubscription {
protected static final Persistent.ReadReq.Options.Builder defaultReadOptions;
private final GrpcClient connection;
private final GrpcClient client;
private final String group;
private final PersistentSubscriptionListener listener;
private final SubscribePersistentSubscriptionOptions options;
Expand All @@ -25,10 +25,10 @@ abstract class AbstractSubscribePersistentSubscription {
.setStructured(Shared.Empty.getDefaultInstance()));
}

public AbstractSubscribePersistentSubscription(GrpcClient connection, String group,
public AbstractSubscribePersistentSubscription(GrpcClient client, String group,
SubscribePersistentSubscriptionOptions options,
PersistentSubscriptionListener listener) {
this.connection = connection;
this.client = client;
this.group = group;
this.options = options;
this.listener = listener;
Expand All @@ -37,9 +37,9 @@ public AbstractSubscribePersistentSubscription(GrpcClient connection, String gro
protected abstract Persistent.ReadReq.Options.Builder createOptions();

public CompletableFuture<PersistentSubscription> execute() {
return this.connection.runWithArgs(args -> {
return this.client.runWithArgs(options, args -> {
PersistentSubscriptionsGrpc.PersistentSubscriptionsStub client =
GrpcUtils.configureStub(PersistentSubscriptionsGrpc.newStub(args.getChannel()), this.connection.getSettings(), this.options);
GrpcUtils.configureStub(PersistentSubscriptionsGrpc.newStub(args.getChannel()), this.client.getSettings(), this.options);

final CompletableFuture<PersistentSubscription> result = new CompletableFuture<>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@
import java.util.concurrent.CompletableFuture;

abstract class AbstractUpdatePersistentSubscription {
private final GrpcClient connection;
private final GrpcClient client;
private final String group;
private final PersistentSubscriptionSettings settings;
private final OptionsBase options;
private final CallOptionsBase options;
private static final Logger logger = LoggerFactory.getLogger(AbstractUpdatePersistentSubscription.class);

public AbstractUpdatePersistentSubscription(GrpcClient connection, String group,
PersistentSubscriptionSettings settings, OptionsBase options) {
this.connection = connection;
public AbstractUpdatePersistentSubscription(GrpcClient client, String group,
PersistentSubscriptionSettings settings, CallOptionsBase options) {
this.client = client;
this.group = group;
this.settings = settings;
this.options = options;
Expand All @@ -30,10 +30,10 @@ protected Persistent.UpdateReq.Settings.Builder createSettings() {

@SuppressWarnings("unchecked")
public CompletableFuture execute() {
return this.connection.runWithArgs(args -> {
return this.client.runWithArgs(options, args -> {
CompletableFuture result = new CompletableFuture();
PersistentSubscriptionsGrpc.PersistentSubscriptionsStub client =
GrpcUtils.configureStub(PersistentSubscriptionsGrpc.newStub(args.getChannel()), this.connection.getSettings(), this.options);
GrpcUtils.configureStub(PersistentSubscriptionsGrpc.newStub(args.getChannel()), this.client.getSettings(), this.options);
Persistent.UpdateReq.Settings.Builder settingsBuilder = createSettings();

settingsBuilder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public AppendToStream(GrpcClient client, String streamName, Iterator<EventData>
}

public CompletableFuture<WriteResult> execute() {
return this.client.run(channel -> {
return this.client.run(options, channel -> {
CompletableFuture<WriteResult> result = new CompletableFuture<>();
StreamsOuterClass.AppendReq.Options.Builder options = this.options.getExpectedRevision().applyOnWire(StreamsOuterClass.AppendReq.Options.newBuilder()
.setStreamIdentifier(Shared.StreamIdentifier.newBuilder()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.eventstore.dbclient;

class AuthOptionsBase {
private UserCredentials userCredentials;
private UserCertificate userCertificate;

UserCredentials getUserCredentials() {
return this.userCredentials;
}

UserCertificate getUserCertificate() {
return this.userCertificate;
}

void setUserCredentials(UserCredentials userCredentials) {
this.userCredentials = userCredentials;
}

void setUserCertificate(UserCertificate userCertificate) {
this.userCertificate = userCertificate;
}
}
Loading

0 comments on commit 5065516

Please sign in to comment.