mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
[MNT-24513] Immutable user (IDS): allow to change enabled status (#2789)
* [MNT-24513] Immutable user: allow enabled status change * [MNT-24513] Created 'allow.immutable.user.enabled.status.update' to control whether an immutabled user enabled status can be changed or not * [MNT-24513] Regardless user details enabled status, the person nodeRef enabled status is also checked * [MNT-24513] Prevent LDAP users from being disabled. Changed variable name.
This commit is contained in:
@@ -125,7 +125,7 @@ public class PeopleImpl implements People
|
|||||||
protected ResetPasswordService resetPasswordService;
|
protected ResetPasswordService resetPasswordService;
|
||||||
protected UserRegistrySynchronizer userRegistrySynchronizer;
|
protected UserRegistrySynchronizer userRegistrySynchronizer;
|
||||||
protected Renditions renditions;
|
protected Renditions renditions;
|
||||||
|
private Boolean allowImmutableEnabledUpdate;
|
||||||
|
|
||||||
private final static Map<String, QName> sort_params_to_qnames;
|
private final static Map<String, QName> sort_params_to_qnames;
|
||||||
static
|
static
|
||||||
@@ -202,6 +202,11 @@ public class PeopleImpl implements People
|
|||||||
this.userRegistrySynchronizer = userRegistrySynchronizer;
|
this.userRegistrySynchronizer = userRegistrySynchronizer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setAllowImmutableEnabledUpdate(Boolean allowImmutableEnabledUpdate)
|
||||||
|
{
|
||||||
|
this.allowImmutableEnabledUpdate = allowImmutableEnabledUpdate;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate, perform -me- substitution and canonicalize the person ID.
|
* Validate, perform -me- substitution and canonicalize the person ID.
|
||||||
*
|
*
|
||||||
@@ -708,16 +713,26 @@ public class PeopleImpl implements People
|
|||||||
// if requested, update password
|
// if requested, update password
|
||||||
updatePassword(isAdmin, personIdToUpdate, person);
|
updatePassword(isAdmin, personIdToUpdate, person);
|
||||||
|
|
||||||
if (person.isEnabled() != null)
|
Set<QName> immutableProperties = userRegistrySynchronizer.getPersonMappedProperties(personIdToUpdate);
|
||||||
|
|
||||||
|
Boolean isEnabled = person.isEnabled();
|
||||||
|
if (isEnabled != null)
|
||||||
{
|
{
|
||||||
if (isAdminAuthority(personIdToUpdate))
|
if (isAdminAuthority(personIdToUpdate))
|
||||||
{
|
{
|
||||||
throw new PermissionDeniedException("Admin authority cannot be disabled.");
|
throw new PermissionDeniedException("Admin authority cannot be disabled.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// note: if current user is not an admin then permission denied exception is thrown
|
if (allowImmutableEnabledStatusUpdate(personIdToUpdate, isAdmin, immutableProperties))
|
||||||
MutableAuthenticationService mutableAuthenticationService = (MutableAuthenticationService) authenticationService;
|
{
|
||||||
mutableAuthenticationService.setAuthenticationEnabled(personIdToUpdate, person.isEnabled());
|
LOGGER.info("User " + personIdToUpdate + " is immutable but enabled status will be set to: " + isEnabled);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// note: if current user is not an admin then permission denied exception is thrown
|
||||||
|
MutableAuthenticationService mutableAuthenticationService = (MutableAuthenticationService) authenticationService;
|
||||||
|
mutableAuthenticationService.setAuthenticationEnabled(personIdToUpdate, person.isEnabled());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeRef personNodeRef = personService.getPerson(personIdToUpdate, false);
|
NodeRef personNodeRef = personService.getPerson(personIdToUpdate, false);
|
||||||
@@ -742,9 +757,7 @@ public class PeopleImpl implements People
|
|||||||
properties.putAll(nodes.mapToNodeProperties(customProps));
|
properties.putAll(nodes.mapToNodeProperties(customProps));
|
||||||
}
|
}
|
||||||
|
|
||||||
// MNT-21150 LDAP synced attributes can be changed using REST API
|
// MNT-21150 LDAP synced attributes can't be changed using REST API
|
||||||
Set<QName> immutableProperties = userRegistrySynchronizer.getPersonMappedProperties(personIdToUpdate);
|
|
||||||
|
|
||||||
immutableProperties.forEach(immutableProperty -> {
|
immutableProperties.forEach(immutableProperty -> {
|
||||||
if (properties.containsKey(immutableProperty))
|
if (properties.containsKey(immutableProperty))
|
||||||
{
|
{
|
||||||
@@ -768,6 +781,28 @@ public class PeopleImpl implements People
|
|||||||
return getPerson(personId);
|
return getPerson(personId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean allowImmutableEnabledStatusUpdate(String userId, boolean isAdmin, Set<QName> immutableProperties)
|
||||||
|
{
|
||||||
|
if (allowImmutableEnabledUpdate)
|
||||||
|
{
|
||||||
|
boolean containLdapUserAccountStatus = false;
|
||||||
|
QName propertyNameToCheck = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "userAccountStatusProperty");
|
||||||
|
|
||||||
|
for (QName immutableProperty : immutableProperties)
|
||||||
|
{
|
||||||
|
if (immutableProperty.equals(propertyNameToCheck))
|
||||||
|
{
|
||||||
|
containLdapUserAccountStatus = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return isAdmin && !containLdapUserAccountStatus && !isMutableAuthority(userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private boolean checkCurrentUserOrAdmin(String personId)
|
private boolean checkCurrentUserOrAdmin(String personId)
|
||||||
{
|
{
|
||||||
boolean isAdmin = isAdminAuthority();
|
boolean isAdmin = isAdminAuthority();
|
||||||
|
@@ -764,6 +764,7 @@
|
|||||||
<property name="thumbnailService" ref="ThumbnailService" />
|
<property name="thumbnailService" ref="ThumbnailService" />
|
||||||
<property name="resetPasswordService" ref="resetPasswordService" />
|
<property name="resetPasswordService" ref="resetPasswordService" />
|
||||||
<property name="userRegistrySynchronizer" ref="userRegistrySynchronizer" />
|
<property name="userRegistrySynchronizer" ref="userRegistrySynchronizer" />
|
||||||
|
<property name="allowImmutableEnabledUpdate" value="${allow.immutable.user.enabled.status.update}" />
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="People" class="org.springframework.aop.framework.ProxyFactoryBean">
|
<bean id="People" class="org.springframework.aop.framework.ProxyFactoryBean">
|
||||||
|
@@ -36,7 +36,11 @@ import net.sf.acegisecurity.UserDetails;
|
|||||||
import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
||||||
import net.sf.acegisecurity.providers.dao.User;
|
import net.sf.acegisecurity.providers.dao.User;
|
||||||
|
|
||||||
|
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
||||||
import org.alfresco.repo.tenant.TenantService;
|
import org.alfresco.repo.tenant.TenantService;
|
||||||
|
import org.alfresco.service.cmr.security.AuthenticationService;
|
||||||
|
import org.alfresco.service.cmr.security.MutableAuthenticationService;
|
||||||
|
import org.alfresco.service.cmr.security.PersonService;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
@@ -49,12 +53,30 @@ public class AuthenticationContextImpl implements AuthenticationContext
|
|||||||
private final Log logger = LogFactory.getLog(getClass());
|
private final Log logger = LogFactory.getLog(getClass());
|
||||||
|
|
||||||
private TenantService tenantService;
|
private TenantService tenantService;
|
||||||
|
private PersonService personService;
|
||||||
|
private AuthenticationService authenticationService;
|
||||||
|
private Boolean allowImmutableEnabledUpdate;
|
||||||
|
|
||||||
public void setTenantService(TenantService tenantService)
|
public void setTenantService(TenantService tenantService)
|
||||||
{
|
{
|
||||||
this.tenantService = tenantService;
|
this.tenantService = tenantService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setPersonService(PersonService personService)
|
||||||
|
{
|
||||||
|
this.personService = personService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuthenticationService(AuthenticationService authenticationService)
|
||||||
|
{
|
||||||
|
this.authenticationService = authenticationService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAllowImmutableEnabledUpdate(Boolean allowImmutableEnabledUpdate)
|
||||||
|
{
|
||||||
|
this.allowImmutableEnabledUpdate = allowImmutableEnabledUpdate;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Explicitly set the given validated user details to be authenticated.
|
* Explicitly set the given validated user details to be authenticated.
|
||||||
*
|
*
|
||||||
@@ -70,7 +92,7 @@ public class AuthenticationContextImpl implements AuthenticationContext
|
|||||||
{
|
{
|
||||||
// Apply the same validation that ACEGI would have to the user details - we may be going through a 'back
|
// Apply the same validation that ACEGI would have to the user details - we may be going through a 'back
|
||||||
// door'.
|
// door'.
|
||||||
if (!ud.isEnabled())
|
if (isDisabled(userId, ud))
|
||||||
{
|
{
|
||||||
throw new DisabledException("User is disabled");
|
throw new DisabledException("User is disabled");
|
||||||
}
|
}
|
||||||
@@ -114,6 +136,43 @@ public class AuthenticationContextImpl implements AuthenticationContext
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isDisabled(String userId, UserDetails ud)
|
||||||
|
{
|
||||||
|
boolean isDisabled = !ud.isEnabled();
|
||||||
|
boolean isSystemUser = isSystemUserName(userId);
|
||||||
|
|
||||||
|
if (allowImmutableEnabledUpdate && !isSystemUser)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
boolean isImmutable = isImmutableAuthority(userId);
|
||||||
|
boolean isPersonEnabled = personService.isEnabled(userId);
|
||||||
|
isDisabled = isDisabled || (isImmutable && !isPersonEnabled);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
if (logger.isWarnEnabled())
|
||||||
|
{
|
||||||
|
logger.warn("Failed to determine if person is enabled: " + userId + ", using user details status: " + isDisabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return isDisabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isImmutableAuthority(String authorityName)
|
||||||
|
{
|
||||||
|
return AuthenticationUtil.runAsSystem(new RunAsWork<Boolean>()
|
||||||
|
{
|
||||||
|
@Override public Boolean doWork() throws Exception
|
||||||
|
{
|
||||||
|
MutableAuthenticationService mutableAuthenticationService = (MutableAuthenticationService) authenticationService;
|
||||||
|
return !mutableAuthenticationService.isAuthenticationMutable(authorityName);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public Authentication setSystemUserAsCurrentUser()
|
public Authentication setSystemUserAsCurrentUser()
|
||||||
{
|
{
|
||||||
return setSystemUserAsCurrentUser(TenantService.DEFAULT_DOMAIN);
|
return setSystemUserAsCurrentUser(TenantService.DEFAULT_DOMAIN);
|
||||||
|
@@ -274,6 +274,15 @@
|
|||||||
<property name="tenantService">
|
<property name="tenantService">
|
||||||
<ref bean="tenantService" />
|
<ref bean="tenantService" />
|
||||||
</property>
|
</property>
|
||||||
|
<property name="personService">
|
||||||
|
<ref bean="personService" />
|
||||||
|
</property>
|
||||||
|
<property name="authenticationService">
|
||||||
|
<ref bean="AuthenticationService" />
|
||||||
|
</property>
|
||||||
|
<property name="allowImmutableEnabledUpdate">
|
||||||
|
<value>${allow.immutable.user.enabled.status.update}</value>
|
||||||
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<!-- Simple Authentication component that rejects all authentication requests -->
|
<!-- Simple Authentication component that rejects all authentication requests -->
|
||||||
|
@@ -435,6 +435,9 @@ repo.remote.endpoint=/service
|
|||||||
# persisted.
|
# persisted.
|
||||||
create.missing.people=${server.transaction.allow-writes}
|
create.missing.people=${server.transaction.allow-writes}
|
||||||
|
|
||||||
|
# Allow an immutable user to have its enabled status changed
|
||||||
|
allow.immutable.user.enabled.status.update=false
|
||||||
|
|
||||||
# Create home folders (unless disabled, see next property) as people are created (true) or create them lazily (false)
|
# Create home folders (unless disabled, see next property) as people are created (true) or create them lazily (false)
|
||||||
home.folder.creation.eager=true
|
home.folder.creation.eager=true
|
||||||
# Disable home folder creation - if true then home folders are not created (neither eagerly nor lazily)
|
# Disable home folder creation - if true then home folders are not created (neither eagerly nor lazily)
|
||||||
|
Reference in New Issue
Block a user