DATAREST-397 - Added integration tests to verify Spring Data REST working with Spring Security.
Added integration tests to verify Spring Data REST works with Spring Security as expected. Added method level security to sample repositories and verified HTTP responses to consider those. Added some words on security configuration in the reference documentation. This is also demonstrated by some canonical samples found in [0]. Original pull request: #171. [0] https://github.com/spring-projects/spring-data-examples/issues/21
This commit is contained in:
committed by
Oliver Gierke
parent
5346215d47
commit
ea8baf642b
@@ -74,10 +74,13 @@ public abstract class AbstractWebIntegrationTests {
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
setupMockMvc();
|
||||
this.client = new TestMvcClient(mvc, discoverers);
|
||||
}
|
||||
|
||||
protected void setupMockMvc() {
|
||||
this.mvc = MockMvcBuilders.webAppContextSetup(context).//
|
||||
defaultRequest(get("/").accept(TestMvcClient.DEFAULT_MEDIA_TYPE)).build();
|
||||
this.client = new TestMvcClient(mvc, discoverers);
|
||||
}
|
||||
|
||||
protected MockHttpServletResponse postAndGet(Link link, Object payload, MediaType mediaType) throws Exception {
|
||||
@@ -236,8 +239,6 @@ public abstract class AbstractWebIntegrationTests {
|
||||
};
|
||||
}
|
||||
|
||||
protected abstract Iterable<String> expectedRootLinkRels();
|
||||
|
||||
protected Map<String, String> getPayloadToPost() throws Exception {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
@@ -245,4 +246,4 @@ public abstract class AbstractWebIntegrationTests {
|
||||
protected MultiValueMap<String, String> getRootAndLinkedResources() {
|
||||
return new LinkedMultiValueMap<String, String>(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -48,6 +48,8 @@ import com.jayway.jsonpath.JsonPath;
|
||||
*/
|
||||
public abstract class CommonWebTests extends AbstractWebIntegrationTests {
|
||||
|
||||
protected abstract Iterable<String> expectedRootLinkRels();
|
||||
|
||||
// Root test cases
|
||||
|
||||
@Test
|
||||
|
||||
@@ -103,6 +103,22 @@ public class TestMvcClient {
|
||||
andReturn().getResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform GET [href] with an explicit Accept media type using MockMvc. Verify the requests succeeded and also came
|
||||
* back as the Accept type.
|
||||
*
|
||||
* @param href
|
||||
* @param contentType
|
||||
* @return a mocked servlet response with results from GET [href]
|
||||
* @throws Exception
|
||||
*/
|
||||
public MockHttpServletResponse request(String href, MediaType contentType, HttpHeaders httpHeaders) throws Exception {
|
||||
return mvc.perform(get(href).accept(contentType).headers(httpHeaders)). //
|
||||
andExpect(status().isOk()). //
|
||||
andExpect(content().contentType(contentType)). //
|
||||
andReturn().getResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience wrapper that first expands the link using URI substitution before requesting with the default media
|
||||
* type.
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc.security;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.Table;
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
* @author Greg Turnquist
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "ORDERS")
|
||||
public class Order {
|
||||
|
||||
@Id @GeneratedValue//
|
||||
private Long id;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)//
|
||||
Person creator;
|
||||
|
||||
public Order(Person creator) {
|
||||
this.creator = creator;
|
||||
}
|
||||
|
||||
protected Order() {
|
||||
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public Person getCreator() {
|
||||
return creator;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright 2012-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc.security;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToMany;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.PrePersist;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import org.springframework.data.rest.core.annotation.Description;
|
||||
|
||||
/**
|
||||
* An entity that represents a person.
|
||||
*
|
||||
* @author Jon Brisbin
|
||||
*/
|
||||
@Entity
|
||||
@JsonIgnoreProperties({ "height", "weight" })
|
||||
public class Person {
|
||||
|
||||
private Long id;
|
||||
@Description("A person's first name") private String firstName;
|
||||
@Description("A person's last name") private String lastName;
|
||||
@Description("A person's siblings") private List<Person> siblings = Collections.emptyList();
|
||||
private Person father;
|
||||
@Description("Timestamp this person object was created") private Date created;
|
||||
private int age, height, weight;
|
||||
|
||||
public Person() {}
|
||||
|
||||
public Person(String firstName, String lastName) {
|
||||
this.firstName = firstName;
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public Person addSibling(Person p) {
|
||||
if (siblings == Collections.EMPTY_LIST) {
|
||||
siblings = new ArrayList<Person>();
|
||||
}
|
||||
siblings.add(p);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ManyToMany
|
||||
public List<Person> getSiblings() {
|
||||
return siblings;
|
||||
}
|
||||
|
||||
public void setSiblings(List<Person> siblings) {
|
||||
this.siblings = siblings;
|
||||
}
|
||||
|
||||
@ManyToOne
|
||||
public Person getFather() {
|
||||
return father;
|
||||
}
|
||||
|
||||
public void setFather(Person father) {
|
||||
this.father = father;
|
||||
}
|
||||
|
||||
public Date getCreated() {
|
||||
return created;
|
||||
}
|
||||
|
||||
public void setCreated(Date created) {}
|
||||
|
||||
@PrePersist
|
||||
private void prePersist() {
|
||||
this.created = Calendar.getInstance().getTime();
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public void setHeight(int height) {
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public int getWeight() {
|
||||
return weight;
|
||||
}
|
||||
|
||||
public void setWeight(int weight) {
|
||||
this.weight = weight;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc.security;
|
||||
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
* @author Greg Turnquist
|
||||
*/
|
||||
// tag::code[]
|
||||
@PreAuthorize("hasRole('ROLE_USER')") // <1>
|
||||
public interface PreAuthorizedOrderRepository extends CrudRepository<Order, Long> {
|
||||
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')") // <2>
|
||||
@Override
|
||||
void delete(Long aLong);
|
||||
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
@Override
|
||||
void delete(Order order);
|
||||
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
@Override
|
||||
void delete(Iterable<? extends Order> orders);
|
||||
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
@Override
|
||||
void deleteAll();
|
||||
}
|
||||
// end::code[]
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc.security;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
|
||||
import org.springframework.orm.jpa.JpaTransactionManager;
|
||||
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||
import org.springframework.orm.jpa.vendor.Database;
|
||||
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
|
||||
/**
|
||||
* @author Greg Turnquist
|
||||
*/
|
||||
@Configuration
|
||||
@EnableJpaRepositories
|
||||
@EnableTransactionManagement
|
||||
public class SecureJpaConfiguration {
|
||||
|
||||
@Bean
|
||||
public DataSource dataSource() {
|
||||
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
|
||||
return builder.setType(EmbeddedDatabaseType.HSQL).build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
|
||||
|
||||
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
|
||||
vendorAdapter.setDatabase(Database.HSQL);
|
||||
vendorAdapter.setGenerateDdl(true);
|
||||
|
||||
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
|
||||
factory.setJpaVendorAdapter(vendorAdapter);
|
||||
factory.setPackagesToScan(getClass().getPackage().getName());
|
||||
factory.setPersistenceUnitName("spring-data-rest-webmvc");
|
||||
factory.setDataSource(dataSource());
|
||||
factory.afterPropertiesSet();
|
||||
|
||||
return factory;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PlatformTransactionManager transactionManager() {
|
||||
return new JpaTransactionManager();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package org.springframework.data.rest.webmvc.security;
|
||||
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
|
||||
import org.springframework.security.access.annotation.Secured;
|
||||
|
||||
// tag::code[]
|
||||
@Secured("ROLE_USER") // <1>
|
||||
@RepositoryRestResource(collectionResourceRel = "people", path = "people")
|
||||
public interface SecuredPersonRepository extends CrudRepository<Person, Long> {
|
||||
|
||||
@Secured("ROLE_ADMIN") // <2>
|
||||
@Override
|
||||
void delete(Long aLong);
|
||||
|
||||
@Secured("ROLE_ADMIN")
|
||||
@Override
|
||||
void delete(Person person);
|
||||
|
||||
@Secured("ROLE_ADMIN")
|
||||
@Override
|
||||
void delete(Iterable<? extends Person> persons);
|
||||
|
||||
@Secured("ROLE_ADMIN")
|
||||
@Override
|
||||
void deleteAll();
|
||||
}
|
||||
// end::code[]
|
||||
@@ -0,0 +1,38 @@
|
||||
package org.springframework.data.rest.webmvc.security;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
|
||||
// tag::code[]
|
||||
@Configuration // <1>
|
||||
@EnableWebSecurity
|
||||
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true) // <2>
|
||||
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { // <3>
|
||||
// end::code[]
|
||||
@Autowired
|
||||
public void configureAuth(AuthenticationManagerBuilder auth) throws Exception {
|
||||
|
||||
auth.inMemoryAuthentication()
|
||||
.withUser("user").password("user").roles("USER").and()
|
||||
.withUser("admin").password("admin").roles("USER", "ADMIN");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
|
||||
http.
|
||||
authorizeRequests()
|
||||
.antMatchers(HttpMethod.GET, "/").permitAll() // Ignore security at the root URI.
|
||||
.anyRequest().authenticated()
|
||||
.and()
|
||||
.httpBasic()
|
||||
.and()
|
||||
.csrf().disable(); // Disable CSRF since it's not critical for the scope of testing.
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,262 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc.security;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*;
|
||||
import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.rest.webmvc.AbstractWebIntegrationTests;
|
||||
import org.springframework.data.rest.webmvc.TestMvcClient;
|
||||
import org.springframework.hateoas.Link;
|
||||
import org.springframework.hateoas.config.EnableHypermediaSupport;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor;
|
||||
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.authority.AuthorityUtils;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.util.NestedServletException;
|
||||
|
||||
/**
|
||||
* Test Spring Data REST in the context of being locked down by Spring Security. Uses MockMvc to simulate HTTP-based
|
||||
* interactions. Testing is possible on the repository level, but that doesn't align with the mission
|
||||
* of Spring Data REST.
|
||||
*
|
||||
* @author Greg Turnquist
|
||||
* @author Rob Winch
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = {SecureJpaConfiguration.class, SecurityConfiguration.class})
|
||||
@Transactional
|
||||
@EnableHypermediaSupport(type = EnableHypermediaSupport.HypermediaType.HAL)
|
||||
public class SecurityIntegrationTests extends AbstractWebIntegrationTests {
|
||||
|
||||
@Autowired WebApplicationContext context;
|
||||
@Autowired MethodSecurityInterceptor methodSecurityInterceptor;
|
||||
|
||||
@Autowired SecuredPersonRepository personRepository;
|
||||
@Autowired PreAuthorizedOrderRepository orderRepository;
|
||||
|
||||
@Before
|
||||
@Override
|
||||
public void setUp() {
|
||||
|
||||
super.setUp();
|
||||
|
||||
SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken("user", "user",
|
||||
AuthorityUtils.createAuthorityList("ROLE_USER", "ROLE_ADMIN")));
|
||||
|
||||
personRepository.deleteAll();
|
||||
orderRepository.deleteAll();
|
||||
|
||||
Person frodo = personRepository.save(new Person("Frodo", "Baggins"));
|
||||
orderRepository.save(new Order(frodo));
|
||||
|
||||
SecurityContextHolder.clearContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the configuration used in {@link AbstractWebIntegrationTests} by plugging in Spring Security's
|
||||
* {@link TestSecurityContextHolderPostProcessor} via apply(springSecurity()).
|
||||
*/
|
||||
@Override
|
||||
protected void setupMockMvc() {
|
||||
this.mvc = MockMvcBuilders.webAppContextSetup(context).//
|
||||
defaultRequest(get("/").//
|
||||
accept(TestMvcClient.DEFAULT_MEDIA_TYPE)).//
|
||||
apply(springSecurity()).//
|
||||
build();
|
||||
}
|
||||
|
||||
//=================================================================
|
||||
|
||||
@Test
|
||||
public void deletePersonAccessDeniedForNoCredentials() throws Exception {
|
||||
|
||||
// Getting the collection is not tested here. This is to get the URI that will later be tested for DELETE
|
||||
final String people = client.discoverUnique("people").expand().getHref();
|
||||
|
||||
MockHttpServletResponse response = mvc.perform(get(people).//
|
||||
with(user("user").roles("USER"))).//
|
||||
andReturn().getResponse();
|
||||
String href = assertHasJsonPathValue("$._embedded.people[0]._links.self.href", response);
|
||||
|
||||
// Clear any side effects of logging in to get the URI from security.
|
||||
SecurityContextHolder.clearContext();
|
||||
|
||||
MockHttpServletResponse deleteResponse = mvc.perform(delete(href)).//
|
||||
andExpect(status().isUnauthorized()).//
|
||||
andReturn().getResponse();
|
||||
assertThat(deleteResponse.getErrorMessage(), is("Full authentication is required to access this resource"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deletePersonAccessDeniedForUsers() throws Exception {
|
||||
|
||||
MockHttpServletResponse response = mvc.perform(get(client.discoverUnique("people").expand().getHref()).//
|
||||
with(user("user").roles("USER"))).//
|
||||
andReturn().getResponse();
|
||||
String href = assertHasJsonPathValue("$._embedded.people[0]._links.self.href", response);
|
||||
|
||||
// Clear any side effects of logging in to get the URI from security.
|
||||
SecurityContextHolder.clearContext();
|
||||
|
||||
MockHttpServletResponse deleteResponse = mvc.perform(delete(href).//
|
||||
with(user("user").roles("USER"))).//
|
||||
andExpect(status().isForbidden()).//
|
||||
andReturn().getResponse();
|
||||
assertThat(deleteResponse.getErrorMessage(), is("Access is denied"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deletePersonAccessGrantedForAdmins() throws Exception {
|
||||
|
||||
MockHttpServletResponse response = mvc.perform(get(client.discoverUnique("people").expand().getHref()).//
|
||||
with(user("user").roles("USER", "ADMIN"))).//
|
||||
andReturn().getResponse();
|
||||
String href = assertHasJsonPathValue("$._embedded.people[0]._links.self.href", response);
|
||||
|
||||
// Clear any side effects of logging in to get the URI from security.
|
||||
SecurityContextHolder.clearContext();
|
||||
|
||||
mvc.perform(delete(href).with(user("user").roles("USER", "ADMIN")))
|
||||
.andExpect(status().is(HttpStatus.NO_CONTENT.value()));
|
||||
}
|
||||
|
||||
//=================================================================
|
||||
|
||||
@Test
|
||||
public void findAllPeopleAccessDeniedForNoCredentials() throws Throwable {
|
||||
|
||||
MockHttpServletResponse response = mvc.perform(get(client.discoverUnique("people").expand().getHref())).//
|
||||
andExpect(status().isUnauthorized()).//
|
||||
andReturn().getResponse();
|
||||
assertThat(response.getErrorMessage(), is("Full authentication is required to access this resource"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findAllPeopleAccessGrantedForUsers() throws Throwable {
|
||||
|
||||
mvc.perform(get(client.discoverUnique("people").expand().getHref()).//
|
||||
with(user("user").roles("USER"))).//
|
||||
andExpect(status().isOk());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findAllPeopleAccessGrantedForAdmins() throws Throwable {
|
||||
|
||||
mvc.perform(get(client.discoverUnique("people").expand().getHref()).//
|
||||
with(user("user").roles("USER", "ADMIN"))).//
|
||||
andExpect(status().isOk());
|
||||
}
|
||||
|
||||
//=================================================================
|
||||
|
||||
|
||||
@Test
|
||||
public void deleteOrderAccessDeniedForNoCredentials() throws Exception {
|
||||
|
||||
// Getting the collection is not tested here. This is to get the URI that will later be tested for DELETE
|
||||
MockHttpServletResponse response = mvc.perform(get(client.discoverUnique("orders").expand().getHref()).//
|
||||
with(user("user").roles("USER"))).//
|
||||
andReturn().getResponse();
|
||||
String href = assertHasJsonPathValue("$._embedded.orders[0]._links.self.href", response);
|
||||
|
||||
// Clear any side effects of logging in to get the URI from security.
|
||||
SecurityContextHolder.clearContext();
|
||||
|
||||
MockHttpServletResponse deleteResponse = mvc.perform(delete(href)).//
|
||||
andExpect(status().isUnauthorized()).//
|
||||
andReturn().getResponse();
|
||||
assertThat(deleteResponse.getErrorMessage(), is("Full authentication is required to access this resource"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteOrderAccessDeniedForUsers() throws Exception {
|
||||
|
||||
MockHttpServletResponse response = mvc.perform(get(client.discoverUnique("orders").expand().getHref()).//
|
||||
with(user("user").roles("USER"))).//
|
||||
andReturn().getResponse();
|
||||
String href = assertHasJsonPathValue("$._embedded.orders[0]._links.self.href", response);
|
||||
|
||||
MockHttpServletResponse deleteResponse = mvc.perform(delete(href).with(user("user").roles("USER"))).//
|
||||
andExpect(status().isForbidden()).//
|
||||
andReturn().getResponse();
|
||||
assertThat(deleteResponse.getErrorMessage(), is("Access is denied"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteOrderAccessGrantedForAdmins() throws Exception {
|
||||
|
||||
MockHttpServletResponse response = mvc.perform(get(client.discoverUnique("orders").expand().getHref()).//
|
||||
with(user("user").roles("USER"))).//
|
||||
andReturn().getResponse();
|
||||
String href = assertHasJsonPathValue("$._embedded.orders[0]._links.self.href", response);
|
||||
|
||||
// Clear any side effects of logging in to get the URI from security.
|
||||
SecurityContextHolder.clearContext();
|
||||
|
||||
mvc.perform(delete(href).with(user("user").roles("USER", "ADMIN")))
|
||||
.andExpect(status().is(HttpStatus.NO_CONTENT.value()));
|
||||
}
|
||||
|
||||
//=================================================================
|
||||
|
||||
@Test
|
||||
public void findAllOrdersAccessDeniedForNoCredentials() throws Throwable {
|
||||
|
||||
MockHttpServletResponse response = mvc.perform(get(client.discoverUnique("orders").expand().getHref())).//
|
||||
andExpect(status().isUnauthorized()).//
|
||||
andReturn().getResponse();
|
||||
assertThat(response.getErrorMessage(), is("Full authentication is required to access this resource"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findAllOrdersAccessGrantedForUsers() throws Throwable {
|
||||
|
||||
mvc.perform(get(client.discoverUnique("orders").expand().getHref()).//
|
||||
with(user("user").roles("USER"))).//
|
||||
andExpect(status().isOk());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findAllOrdersAccessGrantedForAdmins() throws Throwable {
|
||||
|
||||
mvc.perform(get(client.discoverUnique("orders").expand().getHref()).//
|
||||
with(user("user").roles("USER", "ADMIN"))).//
|
||||
andExpect(status().isOk());
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user