PersonService and AuthenticationDao changes

- Clean up javadocs (remove uncommented parameters and fix method comments)
 - ALF-8996: Administrator users can disable themselves
   - Administrator users cannot be disabled (the repo ignores the request)
   - Administrator users cannot expire, be locked; they remain active no matter what
   - UI attempts to disable admin but the request just does nothing (UI could gray it out, I suppose)
 - (ALF-8805) ALF-9056: RINF 40: Fix XPath query to use selectNodes
   - Final (Team-introduced) Lucene query in PersonServiceImpl
   - Cleanup and better tests
   - Unit test template retrieval for user notification (not easy via UI)


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@28528 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2011-06-22 19:51:46 +00:00
parent 331067bb4a
commit 47b45d9ee1
10 changed files with 403 additions and 460 deletions

View File

@@ -77,27 +77,13 @@
</bean>
<bean id="authenticationDao" class="org.alfresco.repo.security.authentication.RepositoryAuthenticationDao">
<property name="nodeService">
<ref bean="nodeService" />
</property>
<property name="tenantService">
<ref bean="tenantService" />
</property>
<property name="namespaceService">
<ref bean="namespaceService" />
</property>
<property name="userNameMatcher">
<ref bean="userNameMatcher" />
</property>
<property name="passwordEncoder">
<ref bean="passwordEncoder" />
</property>
<property name="policyComponent">
<ref bean="policyComponent" />
</property>
<property name="authenticationCache">
<ref bean="authenticationCache" />
</property>
<property name="nodeService" ref="nodeService" />
<property name="authorityService" ref="authorityService" />
<property name="tenantService" ref="tenantService" />
<property name="namespaceService" ref="namespaceService" />
<property name="passwordEncoder" ref="passwordEncoder" />
<property name="policyComponent" ref="policyComponent" />
<property name="authenticationCache" ref="authenticationCache" />
</bean>
<!-- Authentication service for chaining -->

View File

@@ -48,7 +48,6 @@ import org.alfresco.repo.policy.PolicyComponent;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.security.authentication.InMemoryTicketComponentImpl.ExpiryMode;
import org.alfresco.repo.security.authentication.InMemoryTicketComponentImpl.Ticket;
import org.alfresco.repo.security.person.UserNameMatcher;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport.TxnReadState;
@@ -57,6 +56,7 @@ import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.cmr.security.MutableAuthenticationService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.namespace.DynamicNamespacePrefixResolver;
@@ -75,45 +75,27 @@ public class AuthenticationTest extends TestCase
private static ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
private NodeService nodeService;
private AuthorityService authorityService;
private TenantService tenantService;
private NodeRef rootNodeRef;
private NodeRef systemNodeRef;
private NodeRef typesNodeRef;
private NodeRef personAndyNodeRef;
private MD4PasswordEncoder passwordEncoder;
private MutableAuthenticationDao dao;
private AuthenticationManager authenticationManager;
private TicketComponent ticketComponent;
private SimpleCache<String, Ticket> ticketsCache;
private MutableAuthenticationService authenticationService;
private MutableAuthenticationService pubAuthenticationService;
private AuthenticationComponent authenticationComponent;
private UserTransaction userTransaction;
private AuthenticationComponent authenticationComponentImpl;
private TransactionService transactionService;
private PersonService pubPersonService;
private PersonService personService;
private UserNameMatcher userNameMatcher;
private UserTransaction userTransaction;
private NodeRef rootNodeRef;
private NodeRef systemNodeRef;
private NodeRef typesNodeRef;
private NodeRef personAndyNodeRef;
// TODO: pending replacement
private Dialect dialect;
@@ -143,6 +125,7 @@ public class AuthenticationTest extends TestCase
dialect = (Dialect) ctx.getBean("dialect");
nodeService = (NodeService) ctx.getBean("nodeService");
authorityService = (AuthorityService) ctx.getBean("authorityService");
tenantService = (TenantService) ctx.getBean("tenantService");
passwordEncoder = (MD4PasswordEncoder) ctx.getBean("passwordEncoder");
ticketComponent = (TicketComponent) ctx.getBean("ticketComponent");
@@ -152,7 +135,6 @@ public class AuthenticationTest extends TestCase
authenticationComponentImpl = (AuthenticationComponent) ctx.getBean("authenticationComponent");
pubPersonService = (PersonService) ctx.getBean("PersonService");
personService = (PersonService) ctx.getBean("personService");
userNameMatcher = (UserNameMatcher) ctx.getBean("userNameMatcher");
policyComponent = (PolicyComponent) ctx.getBean("policyComponent");
authenticationCache = (SimpleCache<String, NodeRef>) ctx.getBean("authenticationCache");
// permissionServiceSPI = (PermissionServiceSPI)
@@ -193,11 +175,11 @@ public class AuthenticationTest extends TestCase
private void deleteAndy()
{
RepositoryAuthenticationDao dao = new RepositoryAuthenticationDao();
dao.setAuthorityService(authorityService);
dao.setTenantService(tenantService);
dao.setNodeService(nodeService);
dao.setNamespaceService(getNamespacePrefixReolsver(""));
dao.setPasswordEncoder(passwordEncoder);
dao.setUserNameMatcher(userNameMatcher);
dao.setPolicyComponent(policyComponent);
dao.setAuthenticationCache(authenticationCache);
@@ -262,9 +244,9 @@ public class AuthenticationTest extends TestCase
// get Person
assertTrue(pubPersonService.personExists(userName));
AuthenticationUtil.runAs(new RunAsWork() {
AuthenticationUtil.runAs(new RunAsWork<Void>() {
public Object doWork() throws Exception
public Void doWork() throws Exception
{
// TODO Auto-generated method stub
assertEquals("andy", ticketComponent.getAuthorityForTicket(pubAuthenticationService.getCurrentTicket()));
@@ -412,9 +394,9 @@ public class AuthenticationTest extends TestCase
RepositoryAuthenticationDao dao = new RepositoryAuthenticationDao();
dao.setTenantService(tenantService);
dao.setNodeService(nodeService);
dao.setAuthorityService(authorityService);
dao.setNamespaceService(getNamespacePrefixReolsver(""));
dao.setPasswordEncoder(passwordEncoder);
dao.setUserNameMatcher(userNameMatcher);
dao.setPolicyComponent(policyComponent);
dao.setAuthenticationCache(authenticationCache);
dao.createUser("Andy", "cabbage".toCharArray());

View File

@@ -79,13 +79,11 @@ public class DefaultMutableAuthenticationDao implements MutableAuthenticationDao
private boolean allowGetCredentialsExpiryDate = false;
/**
* Create a user with the given userName and password
* {@inheritDoc}
* <p/>
* If enabled does nothing
*
* If enabled does nothing.
*
* @param userName
* @param rawPassword
* @throws AuthenticationException
* @throws AlfrescoRuntimeException if the the operation is not allowed
*/
public void createUser(String userName, char[] rawPassword) throws AuthenticationException
{
@@ -96,13 +94,11 @@ public class DefaultMutableAuthenticationDao implements MutableAuthenticationDao
}
/**
* Update a user's password.
* {@inheritDoc}
* <p/>
* If enabled does nothing
*
* If enabled does nothing.
*
* @param userName
* @param rawPassword
* @throws AuthenticationException
* @throws AlfrescoRuntimeException if the the operation is not allowed
*/
public void updateUser(String userName, char[] rawPassword) throws AuthenticationException
{
@@ -113,12 +109,11 @@ public class DefaultMutableAuthenticationDao implements MutableAuthenticationDao
}
/**
* Delete a user.
* {@inheritDoc}
* <p/>
* If enabled does nothing
*
* If enabled does nothing.
*
* @param userName
* @throws AuthenticationException
* @throws AlfrescoRuntimeException if the the operation is not allowed
*/
public void deleteUser(String userName) throws AuthenticationException
{
@@ -129,12 +124,9 @@ public class DefaultMutableAuthenticationDao implements MutableAuthenticationDao
}
/**
* Check is a user exists.
* {@inheritDoc}
*
* If enabled returns true.
*
* @param userName
* @return
* @return <tt>true</tt> always
*/
public boolean userExists(String userName)
{
@@ -143,12 +135,11 @@ public class DefaultMutableAuthenticationDao implements MutableAuthenticationDao
}
/**
* Enable/disable a user.
* {@inheritDoc}
* <p/>
* If enabled does nothing
*
* If enabled does nothing.
*
* @param userName
* @param enabled
* @throws AlfrescoRuntimeException if the the operation is not allowed
*/
public void setEnabled(String userName, boolean enabled)
{
@@ -159,12 +150,11 @@ public class DefaultMutableAuthenticationDao implements MutableAuthenticationDao
}
/**
* Getter for user enabled
* {@inheritDoc}
*
* If enabled returns true.
* @return <tt>true</tt> if enabled
*
* @param userName
* @return
* @throws AlfrescoRuntimeException if the the operation is not allowed
*/
public boolean getEnabled(String userName)
{
@@ -176,12 +166,11 @@ public class DefaultMutableAuthenticationDao implements MutableAuthenticationDao
}
/**
* Set if the account should expire
* {@inheritDoc}
* <p/>
* If enabled does nothing
*
* If enabled does nothing.
*
* @param userName
* @param expires
* @throws AlfrescoRuntimeException if the the operation is not allowed
*/
public void setAccountExpires(String userName, boolean expires)
{
@@ -192,14 +181,12 @@ public class DefaultMutableAuthenticationDao implements MutableAuthenticationDao
}
/**
* Does the account expire?
* {@inheritDoc}
*
* If enabled returns false.
* @return <tt>false</tt> if enabled
*
* @param userName
* @return
* @throws AlfrescoRuntimeException if the the operation is not allowed
*/
public boolean getAccountExpires(String userName)
{
if (!allowSetAccountExpires)
@@ -210,12 +197,11 @@ public class DefaultMutableAuthenticationDao implements MutableAuthenticationDao
}
/**
* Has the account expired?
* {@inheritDoc}
*
* If enabled returns false.
* @return <tt>false</tt> if enabled
*
* @param userName
* @return
* @throws AlfrescoRuntimeException if the the operation is not allowed
*/
public boolean getAccountHasExpired(String userName)
{
@@ -227,12 +213,11 @@ public class DefaultMutableAuthenticationDao implements MutableAuthenticationDao
}
/**
* Set if the password expires.
* {@inheritDoc}
* <p/>
* If enabled does nothing
*
* If enabled does nothing.
*
* @param userName
* @param expires
* @throws AlfrescoRuntimeException if the the operation is not allowed
*/
public void setCredentialsExpire(String userName, boolean expires)
{
@@ -243,12 +228,11 @@ public class DefaultMutableAuthenticationDao implements MutableAuthenticationDao
}
/**
* Do the credentials for the user expire?
* {@inheritDoc}
*
* If enabled returns false.
* @return <tt>false</tt> if enabled
*
* @param userName
* @return
* @throws AlfrescoRuntimeException if the the operation is not allowed
*/
public boolean getCredentialsExpire(String userName)
{
@@ -260,12 +244,11 @@ public class DefaultMutableAuthenticationDao implements MutableAuthenticationDao
}
/**
* Have the credentials for the user expired?
* {@inheritDoc}
*
* If enabled returns false.
* @return <tt>false</tt> if enabled
*
* @param userName
* @return
* @throws AlfrescoRuntimeException if the the operation is not allowed
*/
public boolean getCredentialsHaveExpired(String userName)
{
@@ -277,12 +260,11 @@ public class DefaultMutableAuthenticationDao implements MutableAuthenticationDao
}
/**
* Set if the account is locked.
* {@inheritDoc}
* <p/>
* If enabled does nothing
*
* If enabled does nothing.
*
* @param userName
* @param locked
* @throws AlfrescoRuntimeException if the the operation is not allowed
*/
public void setLocked(String userName, boolean locked)
{
@@ -293,14 +275,14 @@ public class DefaultMutableAuthenticationDao implements MutableAuthenticationDao
}
/**
* Is the account locked?
* {@inheritDoc}
* <p/>
* If enabled does nothing
*
* If enabled returns false.
*
* @param userName
* @return
* @throws AlfrescoRuntimeException if the the operation is not allowed
*/
public boolean getAccountlocked(String userName)
@Override
public boolean getLocked(String userName)
{
if (!allowGetAccountLocked)
{
@@ -310,12 +292,19 @@ public class DefaultMutableAuthenticationDao implements MutableAuthenticationDao
}
/**
* Set the date on which the account expires
* @see #getLocked(String)
*/
public boolean getAccountlocked(String userName)
{
return getLocked(userName);
}
/**
* {@inheritDoc}
* <p/>
* If enabled does nothing
*
* If enabled does nothing.
*
* @param userName
* @param exipryDate
* @throws AlfrescoRuntimeException if the the operation is not allowed
*/
public void setAccountExpiryDate(String userName, Date exipryDate)
{
@@ -326,12 +315,11 @@ public class DefaultMutableAuthenticationDao implements MutableAuthenticationDao
}
/**
* Get the date when this account expires.
* {@inheritDoc}
* <p/>
* @return <tt>null</tt> if enabled
*
* If enabled returns null.
*
* @param userName
* @return
* @throws AlfrescoRuntimeException if the the operation is not allowed
*/
public Date getAccountExpiryDate(String userName)
{
@@ -343,12 +331,11 @@ public class DefaultMutableAuthenticationDao implements MutableAuthenticationDao
}
/**
* Set the date when credentials expire.
* {@inheritDoc}
* <p/>
* If enabled does nothing
*
* If enabled does nothing.
*
* @param userName
* @param exipryDate
* @throws AlfrescoRuntimeException if the the operation is not allowed
*/
public void setCredentialsExpiryDate(String userName, Date exipryDate)
{
@@ -359,12 +346,11 @@ public class DefaultMutableAuthenticationDao implements MutableAuthenticationDao
}
/**
* Get the date when the credentials/password expire.
* {@inheritDoc}
* <p/>
* @return <tt>null</tt> if enabled
*
* If enabled returns null.
*
* @param userName
* @return
* @throws AlfrescoRuntimeException if the the operation is not allowed
*/
public Date getCredentialsExpiryDate(String userName)
{
@@ -376,12 +362,7 @@ public class DefaultMutableAuthenticationDao implements MutableAuthenticationDao
}
/**
* Get the MD4 password hash
*
* Always throws an exception.
*
* @param userName
* @return
* @throws AlfrescoRuntimeException always
*/
public String getMD4HashedPassword(String userName)
{
@@ -389,15 +370,7 @@ public class DefaultMutableAuthenticationDao implements MutableAuthenticationDao
}
/**
* Return the user details for the specified user
*
* Always throws an exception.
*
* @param user
* String
* @return UserDetails
* @exception UsernameNotFoundException
* @exception DataAccessException
* @throws AlfrescoRuntimeException always
*/
public UserDetails loadUserByUsername(String arg0) throws UsernameNotFoundException, DataAccessException
{
@@ -405,13 +378,7 @@ public class DefaultMutableAuthenticationDao implements MutableAuthenticationDao
}
/**
* Return salt for user
*
* Always throws an exception.
*
* @param user
* UserDetails
* @return Object
* @throws AlfrescoRuntimeException always
*/
public Object getSalt(UserDetails user)
{

View File

@@ -33,157 +33,107 @@ public interface MutableAuthenticationDao extends AuthenticationDao, SaltSource
{
/**
* Create a user with the given userName and password
*
* @param userName
* @param rawPassword
* @throws AuthenticationException
*/
public void createUser(String userName, char[] rawPassword) throws AuthenticationException;
/**
* Update a user's password.
*
* @param userName
* @param rawPassword
* @throws AuthenticationException
*/
public void updateUser(String userName, char[] rawPassword) throws AuthenticationException;
/**
* Delete a user.
*
* @param userName
* @throws AuthenticationException
*/
public void deleteUser(String userName) throws AuthenticationException;
/**
* CHeck is a user exists.
*
* @param userName
* @return
* Check is a user exists.
*/
public boolean userExists(String userName);
/**
* Enable/disable a user.
*
* @param userName
* @param enabled
*/
public void setEnabled(String userName, boolean enabled);
/**
* Getter for user enabled
*
* @param userName
* @return
*/
public boolean getEnabled(String userName);
/**
* Set if the account should expire
*
* @param userName
* @param expires
*/
public void setAccountExpires(String userName, boolean expires);
/**
* Does the account expire?
*
* @param userName
* @return
*/
public boolean getAccountExpires(String userName);
/**
* Has the account expired?
*
* @param userName
* @return
*/
public boolean getAccountHasExpired(String userName);
/**
* Set if the password expires.
*
* @param userName
* @param expires
*/
public void setCredentialsExpire(String userName, boolean expires);
/**
* Do the credentials for the user expire?
*
* @param userName
* @return
*/
public boolean getCredentialsExpire(String userName);
/**
* Have the credentials for the user expired?
*
* @param userName
* @return
*/
public boolean getCredentialsHaveExpired(String userName);
/**
* Set if the account is locked.
*
* @param userName
* @param locked
*/
public void setLocked(String userName, boolean locked);
/**
* Check if the account is locked
*
* @param userName the username
*
* @since 4.0
*/
public boolean getLocked(String userName);
/**
* Is the account locked?
*
* @param userName
* @return
* @deprecated Use {@link #getLocked(String)}
*/
public boolean getAccountlocked(String userName);
/**
* Set the date on which the account expires
*
* @param userName
* @param exipryDate
*/
public void setAccountExpiryDate(String userName, Date exipryDate);
/**
* Get the date when this account expires.
*
* @param userName
* @return
*/
public Date getAccountExpiryDate(String userName);
/**
* Set the date when credentials expire.
*
* @param userName
* @param exipryDate
*/
public void setCredentialsExpiryDate(String userName, Date exipryDate);
/**
* Get the date when the credentials/password expire.
*
* @param userName
* @return
*/
public Date getCredentialsExpiryDate(String userName);
/**
* Get the MD4 password hash
*
* @param userName
* @return
*/
public String getMD4HashedPassword(String userName);
}

View File

@@ -39,13 +39,13 @@ import org.alfresco.repo.node.NodeServicePolicies.BeforeDeleteNodePolicy;
import org.alfresco.repo.node.NodeServicePolicies.OnUpdatePropertiesPolicy;
import org.alfresco.repo.policy.JavaBehaviour;
import org.alfresco.repo.policy.PolicyComponent;
import org.alfresco.repo.security.person.UserNameMatcher;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.namespace.NamespacePrefixResolver;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.RegexQNamePattern;
@@ -53,20 +53,20 @@ import org.alfresco.util.EqualsHelper;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.dao.DataAccessException;
/**
* Component to provide authentication using native Alfresco authentication
*
* @since 1.2
*/
public class RepositoryAuthenticationDao implements MutableAuthenticationDao, InitializingBean, OnUpdatePropertiesPolicy, BeforeDeleteNodePolicy
{
private static final StoreRef STOREREF_USERS = new StoreRef("user", "alfrescoUserStore");
private AuthorityService authorityService;
private NodeService nodeService;
private TenantService tenantService;
private NamespacePrefixResolver namespacePrefixResolver;
private PasswordEncoder passwordEncoder;
private UserNameMatcher userNameMatcher;
private PolicyComponent policyComponent;
/** User folder ref cache (Tennant aware) */
@@ -79,21 +79,16 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao, In
super();
}
public boolean getUserNamesAreCaseSensitive()
{
return userNameMatcher.getUserNamesAreCaseSensitive();
}
public void setUserNameMatcher(UserNameMatcher userNameMatcher)
{
this.userNameMatcher = userNameMatcher;
}
public void setNamespaceService(NamespacePrefixResolver namespacePrefixResolver)
{
this.namespacePrefixResolver = namespacePrefixResolver;
}
public void setAuthorityService(AuthorityService authorityService)
{
this.authorityService = authorityService;
}
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
@@ -119,9 +114,6 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao, In
this.authenticationCache = authenticationCache;
}
/* (non-Javadoc)
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
public void afterPropertiesSet() throws Exception
{
this.policyComponent.bindClassBehaviour(
@@ -134,6 +126,7 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao, In
new JavaBehaviour(this, "beforeDeleteNode"));
}
@Override
public UserDetails loadUserByUsername(String incomingUserName) throws UsernameNotFoundException, DataAccessException
{
NodeRef userRef = getUserOrNull(incomingUserName);
@@ -151,7 +144,14 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao, In
GrantedAuthority[] gas = new GrantedAuthority[1];
gas[0] = new GrantedAuthorityImpl("ROLE_AUTHENTICATED");
UserDetails ud = new User(userName, password, getEnabled(userRef), !getAccountHasExpired(userRef), !getCredentialsHaveExpired(userRef), !getAccountlocked(userRef), gas);
UserDetails ud = new User(
userName,
password,
getEnabled(userName, properties),
!getHasExpired(userName, properties),
!getCredentialsHaveExpired(userName, properties),
!getLocked(userName, properties),
gas);
return ud;
}
@@ -176,6 +176,7 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao, In
return result;
}
@Override
public void createUser(String caseSensitiveUserName, char[] rawPassword) throws AuthenticationException
{
tenantService.checkDomainUser(caseSensitiveUserName);
@@ -236,6 +237,7 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao, In
return userNodeRef;
}
@Override
public void updateUser(String userName, char[] rawPassword) throws AuthenticationException
{
NodeRef userRef = getUserOrNull(userName);
@@ -252,6 +254,7 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao, In
nodeService.setProperties(userRef, properties);
}
@Override
public void deleteUser(String userName) throws AuthenticationException
{
NodeRef userRef = getUserOrNull(userName);
@@ -262,33 +265,38 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao, In
nodeService.deleteNode(userRef);
}
@Override
public Object getSalt(UserDetails userDetails)
{
// NodeRef userRef = getUserOrNull(userDetails.getUsername());
// if (userRef == null)
// {
// throw new UsernameNotFoundException("Could not find user by userName:
// " + userDetails.getUsername());
// }
//
// Map<QName, Serializable> properties =
// nodeService.getProperties(userRef);
//
// String salt = DefaultTypeConverter.INSTANCE.convert(String.class,
// properties.get(QName.createQName("usr", "salt",
// namespacePrefixResolver)));
//
// return salt;
return null;
}
@Override
public boolean userExists(String userName)
{
return (getUserOrNull(userName) != null);
}
/**
* @return Returns the user properties or <tt>null</tt> if there are none
*/
private Map<QName, Serializable> getUserProperties(String userName)
{
NodeRef userNodeRef = getUserOrNull(userName);
if (userNodeRef == null)
{
return null;
}
return nodeService.getProperties(userNodeRef);
}
@Override
public boolean getAccountExpires(String userName)
{
if (authorityService.isAdminAuthority(userName))
{
return false; // Admin never expires
}
NodeRef userNode = getUserOrNull(userName);
if (userNode == null)
{
@@ -305,6 +313,7 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao, In
}
}
@Override
public Date getAccountExpiryDate(String userName)
{
NodeRef userNode = getUserOrNull(userName);
@@ -322,20 +331,33 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao, In
}
}
@Override
public boolean getAccountHasExpired(String userName)
{
return getAccountHasExpired(getUserOrNull(userName));
return getHasExpired(userName, null);
}
private boolean getAccountHasExpired(NodeRef userNode)
/**
* @param userName the username
* @param properties user properties or <tt>null</tt> to fetch them
*/
private boolean getHasExpired(String userName, Map<QName, Serializable> properties)
{
if (userNode == null)
if (authorityService.isAdminAuthority(userName))
{
return false; // Admin never expires
}
if (properties == null)
{
properties = getUserProperties(userName);
}
if (properties == null)
{
return false;
}
if (DefaultTypeConverter.INSTANCE.booleanValue(nodeService.getProperty(userNode, ContentModel.PROP_ACCOUNT_EXPIRES)))
if (DefaultTypeConverter.INSTANCE.booleanValue(properties.get(ContentModel.PROP_ACCOUNT_EXPIRES)))
{
Date date = DefaultTypeConverter.INSTANCE.convert(Date.class, nodeService.getProperty(userNode, ContentModel.PROP_ACCOUNT_EXPIRY_DATE));
Date date = DefaultTypeConverter.INSTANCE.convert(Date.class, properties.get(ContentModel.PROP_ACCOUNT_EXPIRY_DATE));
if (date == null)
{
return false;
@@ -351,18 +373,37 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao, In
}
}
@Override
public boolean getLocked(String userName)
{
return getLocked(userName, null);
}
@Override
public boolean getAccountlocked(String userName)
{
return getAccountlocked(getUserOrNull(userName));
return getLocked(userName, null);
}
private boolean getAccountlocked(NodeRef userNode)
/**
* @param userName the username
* @param properties user properties or <tt>null</tt> to fetch them
*/
private boolean getLocked(String userName, Map<QName, Serializable> properties)
{
if (userNode == null)
if (authorityService.isAdminAuthority(userName))
{
return false; // Admin is never locked
}
if (properties == null)
{
properties = getUserProperties(userName);
}
if (properties == null)
{
return false;
}
Serializable ser = nodeService.getProperty(userNode, ContentModel.PROP_ACCOUNT_LOCKED);
Serializable ser = properties.get(ContentModel.PROP_ACCOUNT_LOCKED);
if (ser == null)
{
return false;
@@ -373,18 +414,31 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao, In
}
}
@Override
public boolean getCredentialsExpire(String userName)
{
return getCredentialsExpired(getUserOrNull(userName));
return getCredentialsExpire(userName, null);
}
private boolean getCredentialsExpired(NodeRef userNode)
/**
* @param userName the username
* @param properties user properties or <tt>null</tt> to fetch them
*/
private boolean getCredentialsExpire(String userName, Map<QName, Serializable> properties)
{
if (userNode == null)
if (authorityService.isAdminAuthority(userName))
{
return false; // Admin never expires
}
if (properties == null)
{
properties = getUserProperties(userName);
}
if (properties == null)
{
return false;
}
Serializable ser = nodeService.getProperty(userNode, ContentModel.PROP_CREDENTIALS_EXPIRE);
Serializable ser = properties.get(ContentModel.PROP_CREDENTIALS_EXPIRE);
if (ser == null)
{
return false;
@@ -395,6 +449,7 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao, In
}
}
@Override
public Date getCredentialsExpiryDate(String userName)
{
NodeRef userNode = getUserOrNull(userName);
@@ -412,20 +467,34 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao, In
}
}
@Override
public boolean getCredentialsHaveExpired(String userName)
{
return getCredentialsHaveExpired(getUserOrNull(userName));
return getCredentialsHaveExpired(userName, null);
}
private boolean getCredentialsHaveExpired(NodeRef userNode)
/**
* @param userName the username (never <tt>null</tt>
* @param properties the properties associated with the user or <tt>null</tt> to get them
* @return <tt>true</tt> if the user account has expired
*/
private boolean getCredentialsHaveExpired(String userName, Map<QName, Serializable> properties)
{
if (userNode == null)
if (authorityService.isAdminAuthority(userName))
{
return false; // Admin never expires
}
if (properties == null)
{
properties = getUserProperties(userName);
}
if (properties == null)
{
return false;
}
if (DefaultTypeConverter.INSTANCE.booleanValue(nodeService.getProperty(userNode, ContentModel.PROP_CREDENTIALS_EXPIRE)))
if (DefaultTypeConverter.INSTANCE.booleanValue(properties.get(ContentModel.PROP_CREDENTIALS_EXPIRE)))
{
Date date = DefaultTypeConverter.INSTANCE.convert(Date.class, nodeService.getProperty(userNode, ContentModel.PROP_CREDENTIALS_EXPIRY_DATE));
Date date = DefaultTypeConverter.INSTANCE.convert(Date.class, properties.get(ContentModel.PROP_CREDENTIALS_EXPIRY_DATE));
if (date == null)
{
return false;
@@ -441,18 +510,31 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao, In
}
}
@Override
public boolean getEnabled(String userName)
{
return getEnabled(getUserOrNull(userName));
return getEnabled(userName, null);
}
private boolean getEnabled(NodeRef userNode)
/**
* @param userName the username
* @param properties the user's properties or <tt>null</tt>
*/
private boolean getEnabled(String userName, Map<QName, Serializable> properties)
{
if (userNode == null)
if (authorityService.isAdminAuthority(userName))
{
return true; // Admin is always enabled
}
if (properties == null)
{
properties = getUserProperties(userName);
}
if (properties == null)
{
return false;
}
Serializable ser = nodeService.getProperty(userNode, ContentModel.PROP_ENABLED);
Serializable ser = properties.get(ContentModel.PROP_ENABLED);
if (ser == null)
{
return true;
@@ -463,6 +545,7 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao, In
}
}
@Override
public void setAccountExpires(String userName, boolean expires)
{
NodeRef userNode = getUserOrNull(userName);
@@ -473,6 +556,7 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao, In
nodeService.setProperty(userNode, ContentModel.PROP_ACCOUNT_EXPIRES, Boolean.valueOf(expires));
}
@Override
public void setAccountExpiryDate(String userName, Date exipryDate)
{
NodeRef userNode = getUserOrNull(userName);
@@ -484,6 +568,7 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao, In
}
@Override
public void setCredentialsExpire(String userName, boolean expires)
{
NodeRef userNode = getUserOrNull(userName);
@@ -494,6 +579,7 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao, In
nodeService.setProperty(userNode, ContentModel.PROP_CREDENTIALS_EXPIRE, Boolean.valueOf(expires));
}
@Override
public void setCredentialsExpiryDate(String userName, Date exipryDate)
{
NodeRef userNode = getUserOrNull(userName);
@@ -505,8 +591,14 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao, In
}
@Override
public void setEnabled(String userName, boolean enabled)
{
if (!enabled && authorityService.isAdminAuthority(userName))
{
// Ignore this
return;
}
NodeRef userNode = getUserOrNull(userName);
if (userNode == null)
{
@@ -515,6 +607,7 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao, In
nodeService.setProperty(userNode, ContentModel.PROP_ENABLED, Boolean.valueOf(enabled));
}
@Override
public void setLocked(String userName, boolean locked)
{
NodeRef userNode = getUserOrNull(userName);
@@ -525,6 +618,7 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao, In
nodeService.setProperty(userNode, ContentModel.PROP_ACCOUNT_LOCKED, Boolean.valueOf(locked));
}
@Override
public String getMD4HashedPassword(String userName)
{
NodeRef userNode = getUserOrNull(userName);
@@ -539,6 +633,7 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao, In
}
}
@Override
public void onUpdateProperties(NodeRef nodeRef, Map<QName, Serializable> before, Map<QName, Serializable> after)
{
String uidBefore = DefaultTypeConverter.INSTANCE.convert(String.class, before.get(ContentModel.PROP_USERNAME));
@@ -556,6 +651,7 @@ public class RepositoryAuthenticationDao implements MutableAuthenticationDao, In
}
}
@Override
public void beforeDeleteNode(NodeRef nodeRef)
{
String userName = (String)nodeService.getProperty(nodeRef, ContentModel.PROP_USER_USERNAME);

View File

@@ -39,9 +39,6 @@ import org.springframework.dao.DataAccessException;
public class NullMutableAuthenticationDao implements MutableAuthenticationDao
{
/**
* Method kept just for backward compatibility with older configurations that
* might have been passing in a value.
*
* @param nodeService ignored
*/
public void setNodeService(NodeService nodeService)
@@ -50,278 +47,202 @@ public class NullMutableAuthenticationDao implements MutableAuthenticationDao
}
/**
* Create a user with the given userName and password
*
* @param userName
* @param rawPassword
* @throws AuthenticationException
* @throws AlfrescoRuntimeException Not implemented
*/
@Override
public void createUser(String userName, char[] rawPassword) throws AuthenticationException
{
throw new AlfrescoRuntimeException("Not implemented");
// Nothing to do
}
/**
* Update a user's password.
*
* @param userName
* @param rawPassword
* @throws AuthenticationException
* @throws AlfrescoRuntimeException Not implemented
*/
@Override
public void updateUser(String userName, char[] rawPassword) throws AuthenticationException
{
throw new AlfrescoRuntimeException("Not implemented");
// Nothing to do
}
/**
* Delete a user.
*
* @param userName
* @throws AuthenticationException
* @throws AlfrescoRuntimeException Not implemented
*/
@Override
public void deleteUser(String userName) throws AuthenticationException
{
throw new AlfrescoRuntimeException("Not implemented");
// Nothing to do
}
/**
* Check is a user exists.
*
* @param userName
* @return
* @return <tt>true</tt> always
*/
@Override
public boolean userExists(String userName)
{
return true;
}
/**
* Enable/disable a user.
*
* @param userName
* @param enabled
* @throws AlfrescoRuntimeException Not implemented
*/
@Override
public void setEnabled(String userName, boolean enabled)
{
throw new AlfrescoRuntimeException("Not implemented");
// Nothing to do
}
/**
* Getter for user enabled
*
* @param userName
* @return
* @throws AlfrescoRuntimeException Not implemented
*/
@Override
public boolean getEnabled(String userName)
{
throw new AlfrescoRuntimeException("Not implemented");
// return true;
}
/**
* Set if the account should expire
*
* @param userName
* @param expires
* @throws AlfrescoRuntimeException Not implemented
*/
@Override
public void setAccountExpires(String userName, boolean expires)
{
throw new AlfrescoRuntimeException("Not implemented");
// Nothing to do
}
/**
* Does the account expire?
*
* @param userName
* @return
* @throws AlfrescoRuntimeException Not implemented
*/
@Override
public boolean getAccountExpires(String userName)
{
throw new AlfrescoRuntimeException("Not implemented");
// return false;
}
/**
* Has the account expired?
*
* @param userName
* @return
* @throws AlfrescoRuntimeException Not implemented
*/
@Override
public boolean getAccountHasExpired(String userName)
{
throw new AlfrescoRuntimeException("Not implemented");
// return false;
}
/**
* Set if the password expires.
*
* @param userName
* @param expires
* @throws AlfrescoRuntimeException Not implemented
*/
@Override
public void setCredentialsExpire(String userName, boolean expires)
{
throw new AlfrescoRuntimeException("Not implemented");
// Nothing to do
}
/**
* Do the credentials for the user expire?
*
* @param userName
* @return
* @throws AlfrescoRuntimeException Not implemented
*/
@Override
public boolean getCredentialsExpire(String userName)
{
throw new AlfrescoRuntimeException("Not implemented");
// return false;
}
/**
* Have the credentials for the user expired?
*
* @param userName
* @return
* @throws AlfrescoRuntimeException Not implemented
*/
@Override
public boolean getCredentialsHaveExpired(String userName)
{
throw new AlfrescoRuntimeException("Not implemented");
// return false;
}
/**
* Set if the account is locked.
*
* @param userName
* @param locked
* @throws AlfrescoRuntimeException Not implemented
*/
@Override
public void setLocked(String userName, boolean locked)
{
throw new AlfrescoRuntimeException("Not implemented");
// Nothing to do
}
/**
* Is the account locked?
*
* @param userName
* @return
* @throws AlfrescoRuntimeException Not implemented
*/
@Override
public boolean getLocked(String userName)
{
throw new AlfrescoRuntimeException("Not implemented");
}
/**
* @throws AlfrescoRuntimeException Not implemented
*/
@Override
public boolean getAccountlocked(String userName)
{
throw new AlfrescoRuntimeException("Not implemented");
// return false;
}
/**
* Set the date on which the account expires
*
* @param userName
* @param exipryDate
* @throws AlfrescoRuntimeException Not implemented
*/
@Override
public void setAccountExpiryDate(String userName, Date exipryDate)
{
throw new AlfrescoRuntimeException("Not implemented");
// Nothing to do
}
/**
* Get the date when this account expires.
*
* @param userName
* @return
/**
* @throws AlfrescoRuntimeException Not implemented
*/
@Override
public Date getAccountExpiryDate(String userName)
{
throw new AlfrescoRuntimeException("Not implemented");
// return null;
}
/**
* Set the date when credentials expire.
*
* @param userName
* @param exipryDate
* @throws AlfrescoRuntimeException Not implemented
*/
@Override
public void setCredentialsExpiryDate(String userName, Date exipryDate)
{
throw new AlfrescoRuntimeException("Not implemented");
// Nothing to do
}
/**
* Get the date when the credentials/password expire.
*
* @param userName
* @return
* @throws AlfrescoRuntimeException Not implemented
*/
@Override
public Date getCredentialsExpiryDate(String userName)
{
throw new AlfrescoRuntimeException("Not implemented");
// return null;
}
/**
* Get the MD4 password hash
*
* @param userName
* @return
* @throws AlfrescoRuntimeException Not implemented
*/
@Override
public String getMD4HashedPassword(String userName)
{
throw new AlfrescoRuntimeException("Not implemented");
// return null;
}
/**
* Return the user details for the specified user
*
* @param user String
* @return UserDetails
* @exception UsernameNotFoundException
* @exception DataAccessException
* @throws AlfrescoRuntimeException Not implemented
*/
@Override
public UserDetails loadUserByUsername(String arg0) throws UsernameNotFoundException, DataAccessException
{
throw new AlfrescoRuntimeException("Not implemented");
// return null;
}
/**
* Return salt for user
*
* @param user UserDetails
* @return Object
* @throws AlfrescoRuntimeException Not implemented
*/
@Override
public Object getSalt(UserDetails user)
{
throw new AlfrescoRuntimeException("Not implemented");
// return null;
}
}

View File

@@ -78,8 +78,6 @@ import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.repository.TemplateService;
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.SearchParameters;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.cmr.security.AuthorityType;
@@ -317,11 +315,6 @@ public class PersonServiceImpl extends TransactionListenerAdapter implements Per
this.storeRef = new StoreRef(storeUrl);
}
public UserNameMatcher getUserNameMatcher()
{
return userNameMatcher;
}
public void setUserNameMatcher(UserNameMatcher userNameMatcher)
{
this.userNameMatcher = userNameMatcher;
@@ -384,9 +377,7 @@ public class PersonServiceImpl extends TransactionListenerAdapter implements Per
}
/**
* You can't inject the {@link FileFolderService} directly,
* otherwise spring gets all confused with cyclic dependencies.
* So, look it up from the Service Registry as required
* Avoid injection issues: Look it up from the Service Registry as required
*/
private FileFolderService getFileFolderService()
{
@@ -394,9 +385,15 @@ public class PersonServiceImpl extends TransactionListenerAdapter implements Per
}
/**
* You can't inject the {@link ActionService} directly,
* otherwise spring gets all confused with cyclic dependencies.
* So, look it up from the Service Registry as required
* Avoid injection issues: Look it up from the Service Registry as required
*/
private NamespaceService getNamespaceService()
{
return serviceRegistry.getNamespaceService();
}
/**
* Avoid injection issues: Look it up from the Service Registry as required
*/
private ActionService getActionService()
{
@@ -860,9 +857,14 @@ public class PersonServiceImpl extends TransactionListenerAdapter implements Per
*/
public NodeRef createPerson(Map<QName, Serializable> properties, Set<String> zones)
{
ParameterCheck.mandatory("properties", properties);
String userName = DefaultTypeConverter.INSTANCE.convert(String.class, properties.get(ContentModel.PROP_USERNAME));
if (userName == null)
{
throw new IllegalArgumentException("No username specified when creating the person.");
}
/**
/*
* Check restrictions on the number of users
*/
Long maxUsers = repoAdminService.getRestrictions().getUsers();
@@ -978,48 +980,40 @@ public class PersonServiceImpl extends TransactionListenerAdapter implements Per
getActionService().executeAction(mailAction, noderef, false, true);
}
/**
* Finds the email template and then attempts to find a localized version
*/
private NodeRef getNotifyEmailTemplateNodeRef()
{
/*
* TODO: Use selectNodes
*/
StoreRef spacesStore = new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "SpacesStore");
String query = " PATH:\"app:company_home/app:dictionary/app:email_templates/cm:invite/cm:new-user-email.html.ftl\"";
SearchParameters searchParams = new SearchParameters();
searchParams.addStore(spacesStore);
searchParams.setLanguage(SearchService.LANGUAGE_LUCENE);
searchParams.setQuery(query);
ResultSet results = null;
// Find the new user email template
String xpath = "app:company_home/app:dictionary/app:email_templates/cm:invite/cm:new-user-email.html.ftl";
try
{
results = searchService.query(searchParams);
List<NodeRef> nodeRefs = results.getNodeRefs();
if (nodeRefs.size() == 1)
NodeRef rootNodeRef = nodeService.getRootNode(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE);
List<NodeRef> nodeRefs = searchService.selectNodes(
rootNodeRef,
xpath,
null,
getNamespaceService(),
false);
if (nodeRefs.size() > 1)
{
// Now localise this
NodeRef base = nodeRefs.get(0);
NodeRef local = getFileFolderService().getLocalizedSibling(base);
return local;
logger.error("Found too many email templates using: " + xpath);
nodeRefs = Collections.singletonList(nodeRefs.get(0));
}
else
else if (nodeRefs.size() == 0)
{
throw new InvitationException("Cannot find the email template!");
throw new InvitationException("Cannot find the email template using " + xpath);
}
// Now localise this
NodeRef base = nodeRefs.get(0);
NodeRef local = getFileFolderService().getLocalizedSibling(base);
return local;
}
catch (SearcherException e)
{
throw new InvitationException("Cannot find the email template!", e);
}
finally
{
if (results != null)
{
results.close();
}
}
}
private Map<String,Serializable> buildEmailTemplateModel(Map<QName,Serializable> props)
@@ -1242,7 +1236,14 @@ public class PersonServiceImpl extends TransactionListenerAdapter implements Per
boolean hasMoreItems = results.hasMoreItems();
int pageNum = (skipCount / maxItems) + 1;
logger.debug("getPeople: "+cnt+" items in "+(System.currentTimeMillis()-start)+" msecs [pageNum="+pageNum+",skip="+skipCount+",max="+maxItems+",hasMorePages="+hasMoreItems+",totalCount="+totalCount+",filters="+stringPropFilters+",filtersIgnoreCase="+filterIgnoreCase+"]");
if (logger.isDebugEnabled())
{
logger.debug(
"getPeople: "+cnt+" items in "+(System.currentTimeMillis()-start)+" msecs " +
"[pageNum="+pageNum+",skip="+skipCount+",max="+maxItems+",hasMorePages="+hasMoreItems+
",totalCount="+totalCount+",filters="+stringPropFilters+
",filtersIgnoreCase="+filterIgnoreCase+"]");
}
}
return new PagingPersonResultsImpl(nodeRefs, results.hasMoreItems(), totalCount, results.getQueryExecutionId(), true);

View File

@@ -39,6 +39,7 @@ import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel;
import org.alfresco.query.PagingRequest;
import org.alfresco.repo.policy.BehaviourFilter;
import org.alfresco.repo.security.authentication.AuthenticationException;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.MutableAuthenticationDao;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
@@ -1331,12 +1332,53 @@ public class PersonTest extends TestCase
"orgId",
null);
NodeRef personNodeRef = personService.createPerson(properties);
assertTrue("Person should be enabled.", authenticationDAO.getEnabled(userName));
assertFalse("Person should not be disabled.", nodeService.hasAspect(personNodeRef, ContentModel.ASPECT_PERSON_DISABLED));
authenticationDAO.setEnabled(userName, true);
assertTrue("Person should be enabled.", authenticationDAO.getEnabled(userName));
assertFalse("Person should not be disabled.", nodeService.hasAspect(personNodeRef, ContentModel.ASPECT_PERSON_DISABLED));
authenticationDAO.setEnabled(userName, false);
assertFalse("Person should be disabled.", authenticationDAO.getEnabled(userName));
assertTrue("Person should be disabled.", nodeService.hasAspect(personNodeRef, ContentModel.ASPECT_PERSON_DISABLED));
}
public void testDisableEnableAdmin()
{
String admin = AuthenticationUtil.getAdminUserName();
assertTrue("Admin must be enabled", authenticationDAO.getEnabled(admin));
authenticationDAO.setEnabled(admin, true);
assertTrue("Admin must be enabled", authenticationDAO.getEnabled(admin));
authenticationDAO.setEnabled(admin, false);
assertTrue("Admin must STILL be enabled", authenticationDAO.getEnabled(admin));
assertFalse("Admin must be unlocked", authenticationDAO.getLocked(admin));
authenticationDAO.setLocked(admin, false);
assertFalse("Admin must be unlocked", authenticationDAO.getLocked(admin));
authenticationDAO.setLocked(admin, true);
assertFalse("Admin must STILL be enabled", authenticationDAO.getLocked(admin));
assertFalse("Admin account does not expire", authenticationDAO.getAccountExpires(admin));
authenticationDAO.setAccountExpires(admin, false);
assertFalse("Admin account does not expire", authenticationDAO.getAccountExpires(admin));
authenticationDAO.setAccountExpires(admin, true);
assertFalse("Admin account STILL does not expire", authenticationDAO.getAccountExpires(admin));
}
public void testNotifyPerson()
{
String userName = GUID.generate();
authenticationDAO.createUser(userName, "abc".toCharArray());
Map<QName, Serializable> properties = createDefaultProperties(
userName,
"firstName",
"lastName",
"email@orgId",
"orgId",
null);
personService.createPerson(properties);
personService.notifyPerson(userName, "abc");
}
}

View File

@@ -23,7 +23,6 @@ import java.util.Set;
import org.alfresco.service.Auditable;
import org.alfresco.service.NotAuditable;
import org.alfresco.service.PublicService;
import org.alfresco.service.cmr.repository.NodeRef;
/**

View File

@@ -26,7 +26,6 @@ import java.util.Set;
import org.alfresco.query.PagingRequest;
import org.alfresco.service.Auditable;
import org.alfresco.service.NotAuditable;
import org.alfresco.service.PublicService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.Pair;