Skip to content

Commit

Permalink
integration test WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
Brutus5000 committed Oct 20, 2017
1 parent 22c93d3 commit 7c5bb4e
Show file tree
Hide file tree
Showing 9 changed files with 221 additions and 95 deletions.
6 changes: 5 additions & 1 deletion .idea/compiler.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 28 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ tasks.withType(Test) {
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
apply plugin: 'propdeps'
apply plugin: 'idea'

group = 'faforever'
version = '0.9.1'
Expand All @@ -132,6 +133,12 @@ configurations {
compile.exclude module: "assertj-core"
}

idea {
module {
testSourceDirs += file('src/inttest/java')
}
}

processResources {
filesMatching('**/application.yml') {
filter {
Expand Down Expand Up @@ -234,6 +241,27 @@ configurations.all {
resolutionStrategy.cacheChangingModulesFor 60, 'seconds'
}

sourceSets {
inttest {
java.srcDir 'src/inttest/java'
resources.srcDir 'src/inttest/resources'
compileClasspath += main.output + test.output
runtimeClasspath += main.output + test.output
}
}

configurations {
inttestCompile.extendsFrom testCompile
inttestRuntime.extendsFrom testRuntime
}


task inttest(type: Test) {
testClassesDir = sourceSets.inttest.output.classesDir
classpath = sourceSets.inttest.runtimeClasspath
mustRunAfter test
}

dependencyManagement {
dependencies {
dependency("org.hibernate:hibernate-core:${hibernateVersion}")
Expand Down
109 changes: 109 additions & 0 deletions src/inttest/java/com/faforever/api/user/UserControllerTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package com.faforever.api.user;

import com.faforever.api.data.domain.User;
import com.faforever.api.error.ErrorCode;
import com.faforever.api.security.OAuthScope;
import com.faforever.integration.OAuthHelper;
import com.google.common.collect.Sets;
import org.json.JSONObject;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.skyscreamer.jsonassert.JSONAssert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.context.annotation.Import;
import org.springframework.http.HttpHeaders;
import org.springframework.security.test.context.support.WithUserDetails;
import org.springframework.test.context.jdbc.Sql;
import org.springframework.test.context.jdbc.Sql.ExecutionPhase;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.RequestPostProcessor;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.util.MultiValueMap;
import org.springframework.web.context.WebApplicationContext;

import javax.transaction.Transactional;
import java.util.Collections;

import static junitx.framework.Assert.assertEquals;
import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@Import(OAuthHelper.class)
@Transactional
@Sql(executionPhase = ExecutionPhase.BEFORE_TEST_METHOD, scripts = "classpath:sql/createUsers.sql")
public class UserControllerTest {
protected final static String AUTH_USER = "USER";
protected final static String AUTH_MODERATOR = "MODERATOR";
protected final static String AUTH_ADMIN = "ADMIN";
MockMvc mockMvc;
@Autowired
private WebApplicationContext context;
@Autowired
private OAuthHelper oAuthHelper;

@Autowired
private UserRepository userRepository;

@Before
public void setUp() {
this.mockMvc = MockMvcBuilders
.webAppContextSetup(this.context)
.apply(springSecurity())
.build();
}

void assertApiError(MvcResult mvcResult, ErrorCode errorCode) throws Exception {
JSONObject resonseJson = new JSONObject(mvcResult.getResponse().getContentAsString());
JSONAssert.assertEquals(String.format("{\"errors\":[{\"code\":\"%s\"}]}", errorCode.getCode()), resonseJson, false);
}

@Test
@WithUserDetails(AUTH_USER)
public void changePassword_success() throws Exception {
MultiValueMap<String, String> params = new HttpHeaders();
params.add("currentPassword", AUTH_USER);
params.add("newPassword", "newPassword");

RequestPostProcessor oauthToken = oAuthHelper.addBearerToken(Sets.newHashSet(OAuthScope._WRITE_ACCOUNT_DATA));
mockMvc.perform(post("/users/changePassword").with(oauthToken).params(params))
.andExpect(status().isOk());

User user = userRepository.findOneByLoginIgnoreCase(AUTH_USER).get();
assertEquals(user.getPassword(), "5c29a959abce4eda5f0e7a4e7ea53dce4fa0f0abbe8eaa63717e2fed5f193d31");
}

@Test
@WithUserDetails(AUTH_USER)
public void changePassword_wrongScope() throws Exception {
MultiValueMap<String, String> params = new HttpHeaders();
params.add("currentPassword", AUTH_USER);
params.add("newPassword", "newPassword");

RequestPostProcessor oauthToken = oAuthHelper.addBearerToken(Collections.emptySet());
mockMvc.perform(post("/users/changePassword").with(oauthToken).params(params))
.andExpect(status().isForbidden());
}

@Test
@WithUserDetails(AUTH_USER)
public void changePassword_wrongPassword() throws Exception {
MultiValueMap<String, String> params = new HttpHeaders();
params.add("currentPassword", "wrongPassword");
params.add("newPassword", "newPassword");

RequestPostProcessor oauthToken = oAuthHelper.addBearerToken(Sets.newHashSet(OAuthScope._WRITE_ACCOUNT_DATA));
MvcResult mvcResult = mockMvc.perform(post("/users/changePassword").with(oauthToken).params(params))
.andExpect(status().is4xxClientError())
.andReturn();

assertApiError(mvcResult, ErrorCode.PASSWORD_CHANGE_FAILED_WRONG_PASSWORD);
}
}
14 changes: 14 additions & 0 deletions src/inttest/resources/sql/createUsers.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
DELETE FROM oauth_clients;
DELETE FROM login;

INSERT INTO oauth_clients (id, name, client_secret, client_type, redirect_uris, default_redirect_uri, default_scope)
VALUES ('test', 'test', 'test', 'public', 'http://localhost', 'http://localhost',
'read_events read_achievements upload_map upload_mod write_account_data');

INSERT INTO login (id, login, email, password)
VALUES (1, 'USER', 'user@faforever.com', '92b7b421992ef490f3b75898ec0e511f1a5c02422819d89719b20362b023ee4f');
INSERT INTO login (id, login, email, password)
VALUES (2, 'MODERATOR', 'moderator@faforever.com', '778ac5b81fa251b450f827846378739caee510c31b01cfa9d31822b88bed8441');
INSERT INTO login (id, login, email, password)
VALUES (3, 'ADMIN', 'admin@faforever.com', '835d6dc88b708bc646d6db82c853ef4182fabbd4a8de59c213f2b5ab3ae7d9be');

Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
Expand Down Expand Up @@ -91,6 +92,22 @@ public ErrorResponse processProgrammingError(ProgrammingError ex) {
return response;
}


@ExceptionHandler(AccessDeniedException.class)
@ResponseStatus(HttpStatus.FORBIDDEN)
@ResponseBody
public ErrorResponse processAccessDeniedException(Throwable ex) throws MissingServletRequestPartException {
log.debug("Access denied", ex);

ErrorResponse response = new ErrorResponse();
response.addError(new ErrorResult(
String.valueOf(HttpStatus.FORBIDDEN.value()),
ex.getClass().getName(),
ex.getMessage()
));
return response;
}

@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ResponseBody
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/faforever/api/user/UserController.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@ public void activate(@RequestParam("token") String token) {
userService.activate(token);
}

@PreAuthorize("#oauth2.hasScope('change_password') and hasRole('ROLE_USER')")
@PreAuthorize("#oauth2.hasScope('write_account_data') and hasRole('ROLE_USER')")
@ApiOperation("Changes the password of a previously registered account.")
@RequestMapping(path = "/changePassword", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public void changePassword(@RequestParam("currentPassword") String currentPassword, @RequestParam("newPassword") String newPassword, Authentication authentication) {
userService.changePassword(currentPassword, newPassword, userService.getUser(authentication));
}

@PreAuthorize("#oauth2.hasScope('change_login') and hasRole('ROLE_USER')")
@PreAuthorize("#oauth2.hasScope('write_account_data') and hasRole('ROLE_USER')")
@ApiOperation("Changes the login of a previously registered account.")
@RequestMapping(path = "/changeUsername", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public void changeLogin(@RequestParam("newUsername") String newUsername, Authentication authentication) {
Expand Down

This file was deleted.

45 changes: 45 additions & 0 deletions src/test/java/com/faforever/integration/OAuthHelper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.faforever.integration;

import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.OAuth2Request;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.stereotype.Component;
import org.springframework.test.web.servlet.request.RequestPostProcessor;

import java.util.Set;

@Component
public class OAuthHelper {

@Autowired
AuthorizationServerTokenServices tokenservice;

@Autowired
JwtAccessTokenConverter jwtAccessTokenConverter;

public RequestPostProcessor addBearerToken(Set<String> scope) {
return mockRequest -> {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
OAuth2Request oauth2Request = createOAuth2Request(scope);
OAuth2Authentication oauth2auth = new OAuth2Authentication(oauth2Request, authentication);
OAuth2AccessToken token = tokenservice.createAccessToken(oauth2auth);
token = jwtAccessTokenConverter.enhance(token, oauth2auth);

// Set Authorization header to use Bearer
mockRequest.addHeader("Authorization", "Bearer " + token.getValue());
return mockRequest;
};
}

@NotNull
private OAuth2Request createOAuth2Request(Set<String> scope) {
return new OAuth2Request(null, "test", null, true, scope, null, null, null, null);
}

}

0 comments on commit 7c5bb4e

Please sign in to comment.