#119 - Added example for use of SpEL expressions in JPQL update statements.
This commit is contained in:
committed by
Oliver Gierke
parent
fbcded19e6
commit
50faabb2af
@@ -15,7 +15,12 @@
|
||||
*/
|
||||
package example.springdata.jpa.security;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToOne;
|
||||
|
||||
/**
|
||||
* @author Thomas Darimont
|
||||
@@ -26,27 +31,76 @@ public class BusinessObject {
|
||||
@Id @GeneratedValue Long id;
|
||||
String data;
|
||||
|
||||
@ManyToOne User owner;
|
||||
|
||||
@ManyToOne
|
||||
User owner;
|
||||
String lastModifiedByUsername;
|
||||
|
||||
Date lastModifiedDate;
|
||||
|
||||
public BusinessObject() {}
|
||||
|
||||
public BusinessObject(String data, User owner) {
|
||||
|
||||
this.data = data;
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(String data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public User getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
public void setOwner(User owner) {
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
public String getLastModifiedByUsername() {
|
||||
return lastModifiedByUsername;
|
||||
}
|
||||
|
||||
public void setLastModifiedByUsername(String lastModifiedByUsername) {
|
||||
this.lastModifiedByUsername = lastModifiedByUsername;
|
||||
}
|
||||
|
||||
public Date getLastModifiedDate() {
|
||||
return lastModifiedDate;
|
||||
}
|
||||
|
||||
public void setLastModifiedDate(Date lastModifiedDate) {
|
||||
this.lastModifiedDate = lastModifiedDate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
|
||||
BusinessObject that = (BusinessObject) o;
|
||||
|
||||
if (data != null ? !data.equals(that.data) : that.data != null) return false;
|
||||
if (id != null ? !id.equals(that.id) : that.id != null) return false;
|
||||
if (owner != null ? !owner.equals(that.owner) : that.owner != null) return false;
|
||||
if (data != null ? !data.equals(that.data) : that.data != null)
|
||||
return false;
|
||||
if (id != null ? !id.equals(that.id) : that.id != null)
|
||||
return false;
|
||||
if (owner != null ? !owner.equals(that.owner) : that.owner != null)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ package example.springdata.jpa.security;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.jpa.repository.Modifying;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.Repository;
|
||||
|
||||
@@ -51,4 +52,11 @@ public interface SecureBusinessObjectRepository extends Repository<BusinessObjec
|
||||
*/
|
||||
@Query("select o from BusinessObject o where o.owner.id = ?#{principal.id} or 1=?#{hasRole('ROLE_ADMIN') ? 1 : 0}")
|
||||
List<BusinessObject> findBusinessObjectsForCurrentUserById();
|
||||
|
||||
/**
|
||||
* Here we demonstrate the use of SecurityContext information in dynamic SPEL parameters in a JPAQL update statement.
|
||||
*/
|
||||
@Modifying
|
||||
@Query("update BusinessObject b set b.data = upper(b.data), b.lastModifiedByUsername = :#{#security.principal.firstname}, b.lastModifiedDate = :#{new java.util.Date()}")
|
||||
void modifiyDataWithRecordingSecurityContext();
|
||||
}
|
||||
|
||||
@@ -21,6 +21,8 @@ import static org.junit.Assert.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -46,10 +48,15 @@ public class SecurityIntegrationTests {
|
||||
@Autowired UserRepository userRepository;
|
||||
@Autowired BusinessObjectRepository businessObjectRepository;
|
||||
@Autowired SecureBusinessObjectRepository secureBusinessObjectRepository;
|
||||
@Autowired EntityManager em;
|
||||
|
||||
User tom;
|
||||
User olli;
|
||||
User admin;
|
||||
|
||||
UsernamePasswordAuthenticationToken olliAuth;
|
||||
UsernamePasswordAuthenticationToken tomAuth;
|
||||
UsernamePasswordAuthenticationToken adminAuth;
|
||||
|
||||
BusinessObject object1;
|
||||
BusinessObject object2;
|
||||
@@ -65,12 +72,16 @@ public class SecurityIntegrationTests {
|
||||
object1 = businessObjectRepository.save(new BusinessObject("object1", olli));
|
||||
object2 = businessObjectRepository.save(new BusinessObject("object2", olli));
|
||||
object3 = businessObjectRepository.save(new BusinessObject("object3", tom));
|
||||
|
||||
olliAuth = new UsernamePasswordAuthenticationToken(olli, "x");
|
||||
tomAuth = new UsernamePasswordAuthenticationToken(tom, "x");
|
||||
adminAuth = new UsernamePasswordAuthenticationToken(admin, "x", singleton(new SimpleGrantedAuthority("ROLE_ADMIN")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findBusinessObjectsForCurrentUserShouldReturnOnlyBusinessObjectsWhereCurrentUserIsOwner() {
|
||||
|
||||
SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken(tom, "x"));
|
||||
SecurityContextHolder.getContext().setAuthentication(tomAuth);
|
||||
|
||||
List<BusinessObject> businessObjects = secureBusinessObjectRepository.findBusinessObjectsForCurrentUser();
|
||||
|
||||
@@ -88,8 +99,7 @@ public class SecurityIntegrationTests {
|
||||
@Test
|
||||
public void findBusinessObjectsForCurrentUserShouldReturnAllObjectsForAdmin() {
|
||||
|
||||
SecurityContextHolder.getContext().setAuthentication(
|
||||
new UsernamePasswordAuthenticationToken(admin, "x", singleton(new SimpleGrantedAuthority("ROLE_ADMIN"))));
|
||||
SecurityContextHolder.getContext().setAuthentication(adminAuth);
|
||||
|
||||
List<BusinessObject> businessObjects = secureBusinessObjectRepository.findBusinessObjectsForCurrentUser();
|
||||
|
||||
@@ -100,14 +110,14 @@ public class SecurityIntegrationTests {
|
||||
@Test
|
||||
public void findBusinessObjectsForCurrentUserByIdShouldReturnOnlyBusinessObjectsWhereCurrentUserIsOwner() {
|
||||
|
||||
SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken(tom, "x"));
|
||||
SecurityContextHolder.getContext().setAuthentication(tomAuth);
|
||||
|
||||
List<BusinessObject> businessObjects = secureBusinessObjectRepository.findBusinessObjectsForCurrentUserById();
|
||||
|
||||
assertThat(businessObjects, hasSize(1));
|
||||
assertThat(businessObjects, contains(object3));
|
||||
|
||||
SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken(olli, "x"));
|
||||
SecurityContextHolder.getContext().setAuthentication(olliAuth);
|
||||
|
||||
businessObjects = secureBusinessObjectRepository.findBusinessObjectsForCurrentUserById();
|
||||
|
||||
@@ -118,13 +128,30 @@ public class SecurityIntegrationTests {
|
||||
@Test
|
||||
public void findBusinessObjectsForCurrentUserByIdShouldReturnAllObjectsForAdmin() {
|
||||
|
||||
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(admin, "x",
|
||||
singleton(new SimpleGrantedAuthority("ROLE_ADMIN")));
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
SecurityContextHolder.getContext().setAuthentication(adminAuth);
|
||||
|
||||
List<BusinessObject> businessObjects = secureBusinessObjectRepository.findBusinessObjectsForCurrentUserById();
|
||||
|
||||
assertThat(businessObjects, hasSize(3));
|
||||
assertThat(businessObjects, contains(object1, object2, object3));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customUpdateStatementShouldAllowToUseSecurityContextInformationViaSpelParameters() {
|
||||
|
||||
SecurityContextHolder.getContext().setAuthentication(adminAuth);
|
||||
|
||||
//Detaching items to get them out of the query cache in order to see the updated values.
|
||||
em.detach(object1);
|
||||
em.detach(object2);
|
||||
em.detach(object3);
|
||||
|
||||
secureBusinessObjectRepository.modifiyDataWithRecordingSecurityContext();
|
||||
|
||||
for(BusinessObject bo : businessObjectRepository.findAll()) {
|
||||
|
||||
assertThat(bo.getLastModifiedDate(), is(notNullValue()));
|
||||
assertThat(bo.getLastModifiedByUsername(), is("admin"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user