Skip to content

Commit

Permalink
Add auth integration tests (#892)
Browse files Browse the repository at this point in the history
* Add auth integration tests

* Change integration test name

* Skip JavaDoc for External Auth HTTP Client

* Update generated HTTP authorization provider package after rebase

* Revert changes to pom.xml for failsafe and Spring

* Rebase onto master and update HTTP authorization provider

* Fix broken auth provider import

* Fix rebasing duplication

* Fix failing auth unit test

* Update authentication test to use BaseIT

* Update CoreServiceAuthorizationIT to BaseIT integration structure

* Update auth integration tests to use BaseIT and related classes

* Remove unnecessary junit dependency and metric registry clear.
  • Loading branch information
woop authored Jul 22, 2020
1 parent bcb9af4 commit 72cc120
Show file tree
Hide file tree
Showing 20 changed files with 894 additions and 65 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/integration_tests.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
name: integration tests

on: [push, pull_request]

jobs:
maven-integration-test:
runs-on: ubuntu-latest
name: Maven Integration Test
name: integration-test-java
steps:
- uses: actions/checkout@v2
- name: Set up JDK 1.8
Expand Down
20 changes: 20 additions & 0 deletions auth/.openapi-generator-ignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
settings.gradle
README.md
pom.xml
gradle
git_push.sh
build.sbt
build.gradle
.travis*
.gitignore
src/main/resources/api.yaml
gradle*
gradle/*
gradle-wrapper.*
gradle**
gradle/
src/main/java/feast/auth/providers/http/HttpAuthorizationProvider.java
src/main/java/feast/auth/providers/http/ketoadaptor/api/CheckAccessApiController.java
src/main/java/feast/auth/providers/http/ketoadaptor/api/KetoAuth.java
src/main/AndroidManifest.xml
.openapi-generator/
76 changes: 66 additions & 10 deletions auth/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,16 @@
<name>Feast Authentication and Authorization</name>

<properties>
<external.auth.client.package.name>feast.auth.generated.client</external.auth.client.package.name>
<feast.auth.providers.http.client.package.name>feast.auth.providers.http.client
</feast.auth.providers.http.client.package.name>
<gson-fire-version>1.8.4</gson-fire-version>
<swagger-core-version>1.5.24</swagger-core-version>
<okhttp-version>3.14.7</okhttp-version>
<gson-version>2.8.6</gson-version>
<commons-lang3-version>3.10</commons-lang3-version>
<javax-annotation-version>1.3.2</javax-annotation-version>
<junit-version>4.13</junit-version>
<springfox-version>2.8.0</springfox-version>
</properties>
<dependencies>
<dependency>
Expand Down Expand Up @@ -60,10 +62,6 @@
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
Expand Down Expand Up @@ -106,6 +104,55 @@
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${springfox-version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${springfox-version}</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.2.11</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>org.openapitools</groupId>
<artifactId>jackson-databind-nullable</artifactId>
<version>0.1.0</version>
</dependency>
<!-- Bean Validation API support -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
<build>
<plugins>
Expand All @@ -115,16 +162,17 @@
<version>4.3.1</version>
<executions>
<execution>
<id>client</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>${project.basedir}/src/main/resources/api.yaml</inputSpec>
<generatorName>java</generatorName>
<packageName>${external.auth.client.package.name}</packageName>
<modelPackage>${external.auth.client.package.name}.model</modelPackage>
<apiPackage>${external.auth.client.package.name}.api</apiPackage>
<invokerPackage>${external.auth.client.package.name}.invoker</invokerPackage>
<packageName>${feast.auth.providers.http.client.package.name}</packageName>
<modelPackage>${feast.auth.providers.http.client.package.name}.model</modelPackage>
<apiPackage>${feast.auth.providers.http.client.package.name}.api</apiPackage>
<invokerPackage>${feast.auth.providers.http.client.package.name}.invoker</invokerPackage>
<configOptions>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
Expand All @@ -143,7 +191,15 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<excludePackageNames>feast.auth.generated.client.api</excludePackageNames>
<excludePackageNames>feast.auth.providers.http.client.*</excludePackageNames>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M4</version>
<configuration>
<argLine>-Xms2048m -Xmx2048m -Djdk.net.URLClassPath.disableClassPathURLCheck=true</argLine>
</configuration>
</plugin>
<plugin>
Expand Down
2 changes: 1 addition & 1 deletion auth/src/main/java/feast/auth/config/SecurityConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

import feast.auth.authentication.DefaultJwtAuthenticationProvider;
import feast.auth.authorization.AuthorizationProvider;
import feast.auth.authorization.HttpAuthorizationProvider;
import feast.auth.providers.http.HttpAuthorizationProvider;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package feast.auth.authorization;
package feast.auth.providers.http;

import feast.auth.authorization.AuthorizationProvider;
import feast.auth.authorization.AuthorizationResult;
import feast.auth.config.CacheConfiguration;
import feast.auth.generated.client.api.DefaultApi;
import feast.auth.generated.client.invoker.ApiClient;
import feast.auth.generated.client.invoker.ApiException;
import feast.auth.generated.client.model.CheckAccessRequest;
import feast.auth.providers.http.client.api.DefaultApi;
import feast.auth.providers.http.client.invoker.ApiClient;
import feast.auth.providers.http.client.invoker.ApiException;
import feast.auth.providers.http.client.model.CheckAccessRequest;
import feast.auth.utils.AuthUtils;
import java.util.Map;
import org.slf4j.Logger;
Expand Down Expand Up @@ -86,7 +88,7 @@ public AuthorizationResult checkAccessToProject(String projectId, Authentication
try {
Jwt credentials = ((Jwt) authentication.getCredentials());
// Make authorization request to external service
feast.auth.generated.client.model.AuthorizationResult authResult =
feast.auth.providers.http.client.model.AuthorizationResult authResult =
this.defaultApiClient.checkAccessPost(
checkAccessRequest, "Bearer " + credentials.getTokenValue());
if (authResult == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@
import feast.auth.config.SecurityProperties;
import feast.auth.config.SecurityProperties.AuthenticationProperties;
import feast.auth.config.SecurityProperties.AuthorizationProperties;
import feast.auth.generated.client.api.DefaultApi;
import feast.auth.generated.client.model.AuthorizationResult;
import feast.auth.generated.client.model.CheckAccessRequest;
import feast.auth.providers.http.HttpAuthorizationProvider;
import feast.auth.providers.http.client.api.DefaultApi;
import feast.auth.providers.http.client.model.AuthorizationResult;
import feast.auth.providers.http.client.model.CheckAccessRequest;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
Expand Down
31 changes: 24 additions & 7 deletions core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@
<artifactId>flyway-maven-plugin</artifactId>
<version>${flyway.version}</version>
</plugin>

</plugins>
</build>

Expand Down Expand Up @@ -315,12 +314,18 @@
<version>5.2.5.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.6.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.6.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>5.6.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
Expand All @@ -333,6 +338,12 @@
<version>1.14.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>sh.ory.keto</groupId>
<artifactId>keto-client</artifactId>
<version>0.4.4-alpha.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>postgresql</artifactId>
Expand All @@ -345,6 +356,12 @@
<version>1.14.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock</artifactId>
<version>2.27.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

@Configuration
@Slf4j
@ComponentScan("feast.auth")
@ComponentScan("feast.auth.config")
public class CoreSecurityConfig {

/**
Expand Down
14 changes: 11 additions & 3 deletions core/src/main/java/feast/core/grpc/CoreServiceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import lombok.extern.slf4j.Slf4j;
import net.devh.boot.grpc.server.service.GrpcService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.context.SecurityContextHolder;

/** Implementation of the feast core GRPC service. */
Expand Down Expand Up @@ -178,10 +179,10 @@ public void listStores(
public void applyFeatureSet(
ApplyFeatureSetRequest request, StreamObserver<ApplyFeatureSetResponse> responseObserver) {

accessManagementService.checkIfProjectMember(
SecurityContextHolder.getContext(), request.getFeatureSet().getSpec().getProject());

String projectId = null;
try {
projectId = request.getFeatureSet().getSpec().getProject();
accessManagementService.checkIfProjectMember(SecurityContextHolder.getContext(), projectId);
ApplyFeatureSetResponse response = specService.applyFeatureSet(request.getFeatureSet());
responseObserver.onNext(response);
responseObserver.onCompleted();
Expand All @@ -192,6 +193,13 @@ public void applyFeatureSet(
e);
responseObserver.onError(
Status.ALREADY_EXISTS.withDescription(e.getMessage()).withCause(e).asRuntimeException());
} catch (AccessDeniedException e) {
log.info(String.format("User prevented from accessing project: %s", projectId));
responseObserver.onError(
Status.PERMISSION_DENIED
.withDescription(e.getMessage())
.withCause(e)
.asRuntimeException());
} catch (Exception e) {
log.error("Exception has occurred in ApplyFeatureSet method: ", e);
responseObserver.onError(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ public void checkIfProjectMember(SecurityContext securityContext, String project
AuthorizationResult result =
this.authorizationProvider.checkAccessToProject(projectId, authentication);
if (!result.isAllowed()) {
throw new AccessDeniedException(result.getFailureReason().orElse("AccessDenied"));
throw new AccessDeniedException(result.getFailureReason().orElse("Access Denied"));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package feast.core.grpc;
package feast.core.auth;

import static org.junit.Assert.assertThrows;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doReturn;
Expand All @@ -29,6 +29,7 @@
import feast.auth.config.SecurityProperties;
import feast.core.config.FeastProperties;
import feast.core.dao.ProjectRepository;
import feast.core.grpc.CoreServiceImpl;
import feast.core.model.Entity;
import feast.core.model.Feature;
import feast.core.model.FeatureSet;
Expand All @@ -53,7 +54,6 @@
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
Expand Down Expand Up @@ -107,8 +107,8 @@ public void shouldNotApplyFeatureSetIfNotProjectMember() throws InvalidProtocolB
ApplyFeatureSetRequest request =
ApplyFeatureSetRequest.newBuilder().setFeatureSet(spec).build();

assertThrows(
AccessDeniedException.class, () -> coreService.applyFeatureSet(request, responseObserver));
coreService.applyFeatureSet(request, responseObserver);
assertEquals("PERMISSION_DENIED: Access Denied", responseObserver.getError().getMessage());
}

@Test
Expand Down
Loading

0 comments on commit 72cc120

Please sign in to comment.