Skip to content

Commit

Permalink
Merge pull request #38 from groldan/feature/testcontainer
Browse files Browse the repository at this point in the history
New gs-acl-testcontainer artifact to run the ACL service with TestContainers
  • Loading branch information
groldan authored Dec 2, 2023
2 parents d62772a + e25d7f0 commit 25bbc38
Show file tree
Hide file tree
Showing 10 changed files with 301 additions and 107 deletions.
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ test:
./mvnw verify -ntp -T4

test-examples:
./mvnw install -DskipTests -ntp -pl :gs-acl-testcontainer
./mvnw verify -ntp -T4 -f examples/

# Make sure `make package` was run before if anything changed since the last build
Expand All @@ -47,3 +48,8 @@ push-image:
@VERSION=`./mvnw help:evaluate -q -DforceStdout -Dexpression=project.version` && \
docker push $(DOCKER_REPO):$${VERSION}

deploy:
./mvnw clean package deploy \
-s $$MAVEN_SETTINGS \
-pl :gs-acl-client-plugin -pl :gs-acl-api-client-spring6 -pl :gs-acl-testcontainer \
--also-make -ntp -T2 -fae -Dfmt.skip -U -DskipTests
28 changes: 16 additions & 12 deletions examples/java-client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.geoserver.acl.examples</groupId>
<artifactId>acl-examples</artifactId>
<version>2.0</version>
<artifactId>acl-examples</artifactId>
<version>2.0-SNAPSHOT</version>
</parent>
<artifactId>acl-java-client-example</artifactId>
<properties>
Expand All @@ -19,10 +19,10 @@
<testcontainers.version>1.19.3</testcontainers.version>
</properties>
<dependencyManagement>
<dependencies>
<dependencies>
<dependency>
<groupId>org.geoserver.acl</groupId>
<artifactId>gs-acl-bom</artifactId>
<groupId>org.geoserver.acl</groupId>
<artifactId>gs-acl-bom</artifactId>
<version>${acl.version}</version>
<type>pom</type>
<scope>import</scope>
Expand All @@ -33,14 +33,14 @@
<version>${testcontainers.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.geoserver.acl.integration.openapi</groupId>
<artifactId>gs-acl-api-client</artifactId>
</dependency>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
Expand All @@ -60,20 +60,24 @@
<version>2.7.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.geoserver.acl</groupId>
<artifactId>gs-acl-testcontainer</artifactId>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0</version>
</plugin>
</plugins>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertTrue;

import java.util.List;

import org.geoserver.acl.authorization.AccessInfo;
import org.geoserver.acl.authorization.AccessRequest;
import org.geoserver.acl.authorization.AuthorizationService;
Expand All @@ -18,100 +16,98 @@
import org.geoserver.acl.domain.rules.Rule;
import org.geoserver.acl.domain.rules.RuleAdminService;
import org.geoserver.acl.domain.rules.RuleAdminServiceImpl;
import org.geoserver.acl.testcontainer.GeoServerAclContainer;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;

import java.util.List;

/**
* Demonstrates how to use {@link AclClientAdaptor} to use the domain API directly
* instead of the raw OpenAPI to manipulate rules and perform authorization requests.
* Demonstrates how to use {@link AclClientAdaptor} to use the domain API directly instead of the
* raw OpenAPI to manipulate rules and perform authorization requests.
*/
@Testcontainers(disabledWithoutDocker = true)
class JavaClientAdaptorExampleTest {

private static final String dockerImageName = "geoservercloud/geoserver-acl:2.0-SNAPSHOT";

// container port the application runs on with the 'dev' profile
private static final int DEV_PORT = 9000;

@Container
static GenericContainer<?> aclServer = new GenericContainer<>(dockerImageName)
// enabling the spring dev profile uses an embedded database and port 9000
.withEnv("SPRING_PROFILES_ACTIVE", "dev").withExposedPorts(9000);

/**
* {@link AclClient} provides the raw API clients through
* {@link AclClient#getAdminRulesApi()}, {@link AclClient#getRulesApi()}, and
* {@link AclClient#getAuthorizationApi()}
*/
private AclClient client;

/**
* {@link AclClientAdaptor} provides domain repositories and the authorization
* implementation using the {@link AclClient} API client through
* {@link AclClientAdaptor#getAdminRuleRepository()},
* {@link AclClientAdaptor#getRuleRepository()}, and
* {@link AclClientAdaptor#getAuthorizationService()}
*/
AclClientAdaptor adaptor;

@BeforeEach
void beforeEach() {
assertTrue(aclServer.isRunning());

final Integer mappedPort = aclServer.getMappedPort(DEV_PORT);
final String apiUrl = String.format("http://localhost:%d/acl/api", mappedPort);
final String username = "admin";
final String password = "s3cr3t";

client = new AclClient()//
.setBasePath(apiUrl)//
.setUsername(username)//
.setPassword(password);

adaptor = new AclClientAdaptor(client);
}

@Test
void testRulesAndAuthorization() {
List<Rule> rules = createSampleRules();
assertThat(rules).isNotEmpty();

// Get the AuthorizationService that will defer requests to the remote ACL service
AuthorizationService authService = adaptor.getAuthorizationService();

// a user with ROLE_USER has access to layers in the users_ws workspace
AccessRequest request = AccessRequest.builder()//
.user("john")
.roles("ROLE_AUTHENTICATED", "ROLE_USER")//
.workspace("users_ws")//
.layer("layer")//
.build();

AccessInfo accessInfo = authService.getAccessInfo(request);
assertThat(accessInfo.getGrant()).isEqualTo(GrantType.ALLOW);

// but does not have access to layers in the editors_ws workspace
request = request.withWorkspace("editors_ws");

accessInfo = authService.getAccessInfo(request);
assertThat(accessInfo.getGrant()).isEqualTo(GrantType.DENY);
}

public List<Rule> createSampleRules() {
// you can use a RuleAdminService using the repository implementation provided
// by the API client adaptor to defer service calls to the remote service
RuleAdminService service = new RuleAdminServiceImpl(adaptor.getRuleRepository());

//prepare rules to insert
Rule r1 = Rule.allow().withPriority(1L).withRolename("ROLE_USER").withWorkspace("users_ws");
Rule r2 = Rule.allow().withPriority(2L).withRolename("ROLE_EDITOR").withWorkspace("editors_ws");

//insert the rules, response comes with assigned id
r1 = service.insert(r1);
r2 = service.insert(r2);
return List.of(r1, r2);
}
@Container
static GeoServerAclContainer aclServer = GeoServerAclContainer.currentVersion().withDevMode();

/**
* {@link AclClient} provides the raw API clients through {@link AclClient#getAdminRulesApi()},
* {@link AclClient#getRulesApi()}, and {@link AclClient#getAuthorizationApi()}
*/
private AclClient client;

/**
* {@link AclClientAdaptor} provides domain repositories and the authorization implementation
* using the {@link AclClient} API client through {@link
* AclClientAdaptor#getAdminRuleRepository()}, {@link AclClientAdaptor#getRuleRepository()}, and
* {@link AclClientAdaptor#getAuthorizationService()}
*/
AclClientAdaptor adaptor;

@BeforeEach
void beforeEach() {
assertTrue(aclServer.isRunning());

final String apiUrl = aclServer.apiUrl();
final String username = aclServer.devAdminUser();
final String password = aclServer.devAdminPassword();

client =
new AclClient() //
.setBasePath(apiUrl) //
.setUsername(username) //
.setPassword(password);

adaptor = new AclClientAdaptor(client);
}

@Test
void testRulesAndAuthorization() {
List<Rule> rules = createSampleRules();
assertThat(rules).isNotEmpty();

// Get the AuthorizationService that will defer requests to the remote ACL service
AuthorizationService authService = adaptor.getAuthorizationService();

// a user with ROLE_USER has access to layers in the users_ws workspace
AccessRequest request =
AccessRequest.builder() //
.user("john")
.roles("ROLE_AUTHENTICATED", "ROLE_USER") //
.workspace("users_ws") //
.layer("layer") //
.build();

AccessInfo accessInfo = authService.getAccessInfo(request);
assertThat(accessInfo.getGrant()).isEqualTo(GrantType.ALLOW);

// but does not have access to layers in the editors_ws workspace
request = request.withWorkspace("editors_ws");

accessInfo = authService.getAccessInfo(request);
assertThat(accessInfo.getGrant()).isEqualTo(GrantType.DENY);
}

public List<Rule> createSampleRules() {
// you can use a RuleAdminService using the repository implementation provided
// by the API client adaptor to defer service calls to the remote service
RuleAdminService service = new RuleAdminServiceImpl(adaptor.getRuleRepository());

// prepare rules to insert
Rule r1 = Rule.allow().withPriority(1L).withRolename("ROLE_USER").withWorkspace("users_ws");
Rule r2 =
Rule.allow()
.withPriority(2L)
.withRolename("ROLE_EDITOR")
.withWorkspace("editors_ws");

// insert the rules, response comes with assigned id
r1 = service.insert(r1);
r2 = service.insert(r2);
return List.of(r1, r2);
}
}
81 changes: 76 additions & 5 deletions examples/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,84 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.geoserver.acl.examples</groupId>
<artifactId>acl-examples</artifactId>
<version>2.0</version>
<version>2.0-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<acl.version>2.0-SNAPSHOT</acl.version>
</properties>


<modules>
<module>java-client</module>
</modules>
<properties>
<acl.version>2.0-SNAPSHOT</acl.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>com.spotify.fmt</groupId>
<artifactId>fmt-maven-plugin</artifactId>
<version>2.21.1</version>
<configuration>
<verbose>false</verbose>
<filesNamePattern>.*\.java</filesNamePattern>
<skip>${fmt.skip}</skip>
<style>aosp</style>
</configuration>
<executions>
<execution>
<goals>
<goal>format</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>flatten-maven-plugin</artifactId>
<version>1.5.0</version>
<inherited>true</inherited>
<configuration>
<updatePomFile>true</updatePomFile>
<!-- see https://www.mojohaus.org/flatten-maven-plugin/flatten-mojo.html#flattenMode -->
<flattenMode>ossrh</flattenMode>
</configuration>
<executions>
<execution>
<id>flatten</id>
<goals>
<goal>flatten</goal>
</goals>
<phase>process-resources</phase>
</execution>
<execution>
<id>flatten.clean</id>
<goals>
<goal>clean</goal>
</goals>
<phase>clean</phase>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.github.ekryd.sortpom</groupId>
<artifactId>sortpom-maven-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<encoding>UTF-8</encoding>
<createBackupFile>false</createBackupFile>
<lineSeparator>\n</lineSeparator>
<nrOfIndentSpace>2</nrOfIndentSpace>
<verifyFail>stop</verifyFail>
<verifyFailOn>strict</verifyFailOn>
</configuration>
<executions>
<execution>
<id>sort</id>
<goals>
<goal>sort</goal>
</goals>
<phase>validate</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
13 changes: 13 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,11 @@
<artifactId>gs-acl-client-plugin</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.geoserver.acl</groupId>
<artifactId>gs-acl-testcontainer</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<repositories>
Expand Down Expand Up @@ -315,6 +320,14 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
Expand Down
Loading

0 comments on commit 25bbc38

Please sign in to comment.