Commit 305e4c53 authored by Matija Obreza's avatar Matija Obreza

Merge branch 'genesys-456-users-of-a-partner' into 'master'

Support for runtime-define authorities granted to users

See merge request genesys-pgr/application-blocks!60
parents f3f1cc89 169882e2
...@@ -138,7 +138,10 @@ public abstract class BasicUser<R extends GrantedAuthority> extends AclSid imple ...@@ -138,7 +138,10 @@ public abstract class BasicUser<R extends GrantedAuthority> extends AclSid imple
@Temporal(TemporalType.TIMESTAMP) @Temporal(TemporalType.TIMESTAMP)
private Date lastLogin; private Date lastLogin;
@Transient
@JsonIgnore
private Set<String> runtimeAuthorities;
/** /**
* Instantiates a new basic user. * Instantiates a new basic user.
*/ */
...@@ -331,7 +334,12 @@ public abstract class BasicUser<R extends GrantedAuthority> extends AclSid imple ...@@ -331,7 +334,12 @@ public abstract class BasicUser<R extends GrantedAuthority> extends AclSid imple
@Transient @Transient
@Override @Override
public Collection<? extends GrantedAuthority> getAuthorities() { public Collection<? extends GrantedAuthority> getAuthorities() {
return getRoles().stream().map(role -> new SimpleGrantedAuthority(role.getAuthority())).collect(Collectors.toSet()); Set<SimpleGrantedAuthority> authorities = new HashSet<>();
authorities.addAll(getRoles().stream().map(role -> new SimpleGrantedAuthority(role.getAuthority())).collect(Collectors.toSet()));
if (runtimeAuthorities != null) {
authorities.addAll(runtimeAuthorities.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toSet()));
}
return authorities;
} }
/* /*
...@@ -443,4 +451,13 @@ public abstract class BasicUser<R extends GrantedAuthority> extends AclSid imple ...@@ -443,4 +451,13 @@ public abstract class BasicUser<R extends GrantedAuthority> extends AclSid imple
public void setLastLogin(Date lastLogin) { public void setLastLogin(Date lastLogin) {
this.lastLogin = lastLogin; this.lastLogin = lastLogin;
} }
/**
* Additional authorities
*
* @param authorities
*/
public void setRuntimeAuthorities(Set<String> authorities) {
this.runtimeAuthorities = authorities;
}
} }
...@@ -54,13 +54,26 @@ public interface CustomAclService extends JsonSidConverter.SidProvider { ...@@ -54,13 +54,26 @@ public interface CustomAclService extends JsonSidConverter.SidProvider {
AclSid getSid(Long id); AclSid getSid(Long id);
/** /**
* Gets the sid of the specified authority. * Gets the sid for the specified authority.
* *
* @param authority the authority (must start with "ROLE_") * @param authority the authority (must start with "ROLE_")
* @return the authority sid * @return the authority sid
*/ */
AclSid getAuthoritySid(String authority); AclSid getAuthoritySid(String authority);
/**
* Gets (and creates if missing) the sid for the specified authority.
*
* @param authority the authority (must start with "ROLE_")
* @return the authority sid
*/
AclSid ensureAuthoritySid(String authority);
/**
* Removes the sid of the specified authority
*/
AclSid removeAuthoritySid(String authorityName);
/** /**
* List authority sids. * List authority sids.
* *
...@@ -91,6 +104,15 @@ public interface CustomAclService extends JsonSidConverter.SidProvider { ...@@ -91,6 +104,15 @@ public interface CustomAclService extends JsonSidConverter.SidProvider {
*/ */
AclObjectIdentity updateParentObject(long objectIdIdentity, long parentObjectId); AclObjectIdentity updateParentObject(long objectIdIdentity, long parentObjectId);
/**
* Set ACL parent object for inherited permissions
*
* @param target the target ACL object on which to change ACL
* @param parent the parent ACL object
* @return
*/
AclObjectIdentity setAclParent(AclAwareModel target, AclAwareModel parent);
/** /**
* Removes the permissions on ACL model. * Removes the permissions on ACL model.
* *
...@@ -183,7 +205,7 @@ public interface CustomAclService extends JsonSidConverter.SidProvider { ...@@ -183,7 +205,7 @@ public interface CustomAclService extends JsonSidConverter.SidProvider {
* @return the acl object identity * @return the acl object identity
*/ */
AclObjectIdentity removePermissions(AclObjectIdentity objectIdentity, AclSid aclSid); AclObjectIdentity removePermissions(AclObjectIdentity objectIdentity, AclSid aclSid);
/** /**
* Gets the acl entries. * Gets the acl entries.
* *
...@@ -272,7 +294,7 @@ public interface CustomAclService extends JsonSidConverter.SidProvider { ...@@ -272,7 +294,7 @@ public interface CustomAclService extends JsonSidConverter.SidProvider {
* Wraps {@link AclObjectIdentity} and adds list of inherited permissions. * Wraps {@link AclObjectIdentity} and adds list of inherited permissions.
*/ */
public static class AclObjectIdentityExt { public static class AclObjectIdentityExt {
@JsonUnwrapped @JsonUnwrapped
public AclObjectIdentity original; public AclObjectIdentity original;
@JsonSerialize(converter = AclEntriesToPermissions.class) @JsonSerialize(converter = AclEntriesToPermissions.class)
public List<AclEntry> inherited = new ArrayList<>(); public List<AclEntry> inherited = new ArrayList<>();
......
...@@ -156,9 +156,18 @@ public abstract class BasicUserServiceImpl<R extends GrantedAuthority, T extends ...@@ -156,9 +156,18 @@ public abstract class BasicUserServiceImpl<R extends GrantedAuthority, T extends
if (user == null) { if (user == null) {
throw new UsernameNotFoundException(username); throw new UsernameNotFoundException(username);
} }
user.setRuntimeAuthorities(getRuntimeAuthorities(user));
return user; return user;
} }
/**
* Allow the application to register additional authorities
*
* @param user
* @return the same object
*/
protected abstract Set<String> getRuntimeAuthorities(T user);
/* /*
* (non-Javadoc) * (non-Javadoc)
* @see org.genesys.blocks.security.service.BasicUserService#getUser(long) * @see org.genesys.blocks.security.service.BasicUserService#getUser(long)
......
...@@ -116,10 +116,33 @@ public class CustomAclServiceImpl implements CustomAclService { ...@@ -116,10 +116,33 @@ public class CustomAclServiceImpl implements CustomAclService {
} }
@Override @Override
@Transactional(propagation = Propagation.REQUIRED)
public AclSid getAuthoritySid(String authority) { public AclSid getAuthoritySid(String authority) {
return aclSidPersistence.findBySidAndPrincipal(authority, false);
}
@Override
@Transactional(propagation = Propagation.REQUIRED)
public AclSid ensureAuthoritySid(String authority) {
return ensureSidForAuthority(authority); return ensureSidForAuthority(authority);
} }
@Override
@Transactional(propagation = Propagation.REQUIRED)
public AclSid removeAuthoritySid(String authority) {
AclSid authoritySid = aclSidPersistence.findBySidAndPrincipal(authority, false);
if (authoritySid == null) {
LOG.warn("ACL SID for authority {} does not exist", authority);
return null;
}
// Remove ACL entries
removePermissionsFor(authoritySid);
aclSidPersistence.delete(authoritySid);
return authoritySid;
}
@Override @Override
@Transactional(propagation = Propagation.REQUIRED) @Transactional(propagation = Propagation.REQUIRED)
...@@ -233,6 +256,15 @@ public class CustomAclServiceImpl implements CustomAclService { ...@@ -233,6 +256,15 @@ public class CustomAclServiceImpl implements CustomAclService {
} }
} }
} }
@Override
@PreAuthorize("hasRole('ADMINISTRATOR')")
public AclObjectIdentity setAclParent(AclAwareModel target, AclAwareModel parent) {
final AclObjectIdentity objectIdentity = getObjectIdentity(target);
final AclObjectIdentity parentIdentity = parent == null ? null : getObjectIdentity(parent);
return updateAclParentObject(objectIdentity, parentIdentity);
}
@Override @Override
@PreAuthorize("hasRole('ADMINISTRATOR')") @PreAuthorize("hasRole('ADMINISTRATOR')")
...@@ -243,15 +275,21 @@ public class CustomAclServiceImpl implements CustomAclService { ...@@ -243,15 +275,21 @@ public class CustomAclServiceImpl implements CustomAclService {
return null; return null;
} }
final AclObjectIdentity parentObject = aclObjectIdentityPersistence.findOne(parentObjectId); final AclObjectIdentity parentIdentity = aclObjectIdentityPersistence.findOne(parentObjectId);
if (parentObject == null) { if (parentIdentity == null) {
LOG.warn("ACL object identity not found by id={}", objectIdIdentity); LOG.warn("ACL object identity not found by id={}", objectIdIdentity);
return null; return null;
} }
return updateAclParentObject(objectIdentity, parentIdentity);
}
private AclObjectIdentity updateAclParentObject(final AclObjectIdentity objectIdentity, final AclObjectIdentity parentObject) {
try { try {
LOG.trace("Updating ACL parent to {}", parentObject); LOG.trace("Updating ACL parent to {}", parentObject);
objectIdentity.setParentObject(parentObject); objectIdentity.setParentObject(parentObject);
objectIdentity.setEntriesInheriting(parentObject != null);
return aclObjectIdentityPersistence.save(objectIdentity); return aclObjectIdentityPersistence.save(objectIdentity);
} finally { } finally {
clearAclCache(); clearAclCache();
...@@ -534,14 +572,19 @@ public class CustomAclServiceImpl implements CustomAclService { ...@@ -534,14 +572,19 @@ public class CustomAclServiceImpl implements CustomAclService {
if (permissions == null) { if (permissions == null) {
throw new NullPointerException("Permissions must be provided, was null."); throw new NullPointerException("Permissions must be provided, was null.");
} }
final AclObjectIdentity objectIdentity = ensureObjectIdentity(entity);
return setPermissions(objectIdentity, sid, permissions);
}
private AclObjectIdentity ensureObjectIdentity(final AclAwareModel entity) {
String className = entity.getClass().getName(); String className = entity.getClass().getName();
if (entity instanceof ClassAclOid<?>) { if (entity instanceof ClassAclOid<?>) {
className = ((ClassAclOid<?>) entity).getClassName(); className = ((ClassAclOid<?>) entity).getClassName();
} }
final AclObjectIdentity objectIdentity = ensureObjectIdentity(entity.getId(), className); final AclObjectIdentity objectIdentity = ensureObjectIdentity(entity.getId(), className);
return setPermissions(objectIdentity, sid, permissions); return objectIdentity;
} }
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_UNCOMMITTED) @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_UNCOMMITTED)
...@@ -744,11 +787,16 @@ public class CustomAclServiceImpl implements CustomAclService { ...@@ -744,11 +787,16 @@ public class CustomAclServiceImpl implements CustomAclService {
public void makePubliclyReadable(AclAwareModel entity, boolean publiclyReadable) { public void makePubliclyReadable(AclAwareModel entity, boolean publiclyReadable) {
AclSid roleEveryone = getAuthoritySid("ROLE_EVERYONE"); AclSid roleEveryone = getAuthoritySid("ROLE_EVERYONE");
Permissions readPermissions = new Permissions().grantNone(); if (!publiclyReadable) {
final AclObjectIdentity objectIdentity = ensureObjectIdentity(entity);
removePermissions(objectIdentity, roleEveryone);
readPermissions.read = publiclyReadable; } else {
setPermissions(entity, roleEveryone, readPermissions); Permissions readPermissions = new Permissions().grantNone();
readPermissions.read = publiclyReadable;
setPermissions(entity, roleEveryone, readPermissions);
}
} }
@Override @Override
......
...@@ -18,16 +18,14 @@ package org.genesys.blocks.security.config; ...@@ -18,16 +18,14 @@ package org.genesys.blocks.security.config;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Set;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.genesys.blocks.oauth.service.OAuthServiceImpl; import org.genesys.blocks.oauth.service.OAuthServiceImpl;
import org.genesys.blocks.security.NotUniqueUserException; import org.genesys.blocks.security.NotUniqueUserException;
import org.genesys.blocks.security.UserException; import org.genesys.blocks.security.UserException;
import org.genesys.blocks.security.model.BasicUser.AccountType;
import org.genesys.blocks.security.model.TestUser; import org.genesys.blocks.security.model.TestUser;
import org.genesys.blocks.security.model.UserRole; import org.genesys.blocks.security.model.UserRole;
import org.genesys.blocks.security.model.BasicUser.AccountType;
import org.genesys.blocks.security.persistence.TestUserPersistence; import org.genesys.blocks.security.persistence.TestUserPersistence;
import org.genesys.blocks.security.service.BasicUserService; import org.genesys.blocks.security.service.BasicUserService;
import org.genesys.blocks.security.service.PasswordPolicy.PasswordPolicyException; import org.genesys.blocks.security.service.PasswordPolicy.PasswordPolicyException;
...@@ -49,6 +47,9 @@ import org.springframework.security.oauth2.provider.token.TokenStore; ...@@ -49,6 +47,9 @@ import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore; import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
/** /**
* The Class ApplicationConfig. * The Class ApplicationConfig.
* *
...@@ -136,6 +137,11 @@ public class ApplicationConfig { ...@@ -136,6 +137,11 @@ public class ApplicationConfig {
public TestUser getUserByEmail(final String email) throws UsernameNotFoundException { public TestUser getUserByEmail(final String email) throws UsernameNotFoundException {
return testUserRepository.findByEmail(email); return testUserRepository.findByEmail(email);
} }
@Override
protected Set<String> getRuntimeAuthorities(TestUser user) {
return null;
}
@Override @Override
@Transactional @Transactional
......
...@@ -84,11 +84,11 @@ public class PermissionsTest extends ServiceTest { ...@@ -84,11 +84,11 @@ public class PermissionsTest extends ServiceTest {
*/ */
@Test @Test
public void testAuthoritySid() { public void testAuthoritySid() {
AclSid roleSid = aclService.getAuthoritySid(UserRole.EXTRAROLE.name()); AclSid roleSid = aclService.ensureAuthoritySid(UserRole.EXTRAROLE.name());
assertThat(roleSid, not(nullValue())); assertThat(roleSid, not(nullValue()));
assertThat(roleSid.getId(), not(nullValue())); assertThat(roleSid.getId(), not(nullValue()));
roleSid = aclService.getAuthoritySid(UserRole.EXTRAROLE.name()); roleSid = aclService.ensureAuthoritySid(UserRole.EXTRAROLE.name());
assertThat(roleSid, not(nullValue())); assertThat(roleSid, not(nullValue()));
assertThat(roleSid.getId(), not(nullValue())); assertThat(roleSid.getId(), not(nullValue()));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment