Commit ab6dc88b authored by Matija Obreza's avatar Matija Obreza

Support for runtime-define authorities granted to users

parent f3f1cc89
......@@ -138,6 +138,9 @@ public abstract class BasicUser<R extends GrantedAuthority> extends AclSid imple
@Temporal(TemporalType.TIMESTAMP)
private Date lastLogin;
@Transient
@JsonIgnore
private Set<String> runtimeAuthorities;
/**
* Instantiates a new basic user.
......@@ -331,7 +334,15 @@ public abstract class BasicUser<R extends GrantedAuthority> extends AclSid imple
@Transient
@Override
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()));
System.err.println("User has extra runtime authorities: " + runtimeAuthorities);
} else {
System.err.println("User has no extra runtime authorities: " + runtimeAuthorities);
}
return authorities;
}
/*
......@@ -443,4 +454,13 @@ public abstract class BasicUser<R extends GrantedAuthority> extends AclSid imple
public void setLastLogin(Date 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 {
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_")
* @return the authority sid
*/
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.
*
......
......@@ -156,9 +156,18 @@ public abstract class BasicUserServiceImpl<R extends GrantedAuthority, T extends
if (user == null) {
throw new UsernameNotFoundException(username);
}
user.setRuntimeAuthorities(getRuntimeAuthorities(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)
* @see org.genesys.blocks.security.service.BasicUserService#getUser(long)
......
......@@ -116,11 +116,34 @@ public class CustomAclServiceImpl implements CustomAclService {
}
@Override
@Transactional(propagation = Propagation.REQUIRED)
public AclSid getAuthoritySid(String authority) {
return aclSidPersistence.findBySidAndPrincipal(authority, false);
}
@Override
@Transactional(propagation = Propagation.REQUIRED)
public AclSid ensureAuthoritySid(String 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
@Transactional(propagation = Propagation.REQUIRED)
public void createOrUpdatePermissions(final AclAwareModel target) {
......@@ -535,13 +558,18 @@ public class CustomAclServiceImpl implements CustomAclService {
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();
if (entity instanceof ClassAclOid<?>) {
className = ((ClassAclOid<?>) entity).getClassName();
}
final AclObjectIdentity objectIdentity = ensureObjectIdentity(entity.getId(), className);
return setPermissions(objectIdentity, sid, permissions);
return objectIdentity;
}
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_UNCOMMITTED)
......@@ -744,12 +772,17 @@ public class CustomAclServiceImpl implements CustomAclService {
public void makePubliclyReadable(AclAwareModel entity, boolean publiclyReadable) {
AclSid roleEveryone = getAuthoritySid("ROLE_EVERYONE");
Permissions readPermissions = new Permissions().grantNone();
if (!publiclyReadable) {
final AclObjectIdentity objectIdentity = ensureObjectIdentity(entity);
removePermissions(objectIdentity, roleEveryone);
readPermissions.read = publiclyReadable;
} else {
Permissions readPermissions = new Permissions().grantNone();
readPermissions.read = publiclyReadable;
setPermissions(entity, roleEveryone, readPermissions);
}
}
@Override
@Transactional
......
......@@ -18,16 +18,14 @@ package org.genesys.blocks.security.config;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import java.util.Set;
import org.genesys.blocks.oauth.service.OAuthServiceImpl;
import org.genesys.blocks.security.NotUniqueUserException;
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.UserRole;
import org.genesys.blocks.security.model.BasicUser.AccountType;
import org.genesys.blocks.security.persistence.TestUserPersistence;
import org.genesys.blocks.security.service.BasicUserService;
import org.genesys.blocks.security.service.PasswordPolicy.PasswordPolicyException;
......@@ -49,6 +47,9 @@ import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;
import org.springframework.transaction.annotation.Transactional;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
/**
* The Class ApplicationConfig.
*
......@@ -137,6 +138,11 @@ public class ApplicationConfig {
return testUserRepository.findByEmail(email);
}
@Override
protected Set<String> getRuntimeAuthorities(TestUser user) {
return null;
}
@Override
@Transactional
public TestUser createUser(final String email, final String fullName, final String password, final AccountType accountType) throws NotUniqueUserException,
......
......@@ -84,11 +84,11 @@ public class PermissionsTest extends ServiceTest {
*/
@Test
public void testAuthoritySid() {
AclSid roleSid = aclService.getAuthoritySid(UserRole.EXTRAROLE.name());
AclSid roleSid = aclService.ensureAuthoritySid(UserRole.EXTRAROLE.name());
assertThat(roleSid, 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.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