mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-14 17:58:59 +00:00
Merged mward/5.2.n-custpeopleprops (5.2.1) to 5.2.N (5.2.1)
132754 mward: REPO-1395: add custom properties to people create/get/update. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/DEV/5.2.N/root@132871 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -25,18 +25,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.rest.api;
|
package org.alfresco.rest.api;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import org.alfresco.rest.api.model.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.alfresco.rest.api.model.AssocChild;
|
|
||||||
import org.alfresco.rest.api.model.AssocTarget;
|
|
||||||
import org.alfresco.rest.api.model.Document;
|
|
||||||
import org.alfresco.rest.api.model.Folder;
|
|
||||||
import org.alfresco.rest.api.model.LockInfo;
|
|
||||||
import org.alfresco.rest.api.model.Node;
|
|
||||||
import org.alfresco.rest.api.model.UserInfo;
|
|
||||||
import org.alfresco.rest.framework.resource.content.BasicContentInfo;
|
import org.alfresco.rest.framework.resource.content.BasicContentInfo;
|
||||||
import org.alfresco.rest.framework.resource.content.BinaryResource;
|
import org.alfresco.rest.framework.resource.content.BinaryResource;
|
||||||
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
|
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
|
||||||
@@ -46,6 +35,12 @@ import org.alfresco.service.cmr.repository.StoreRef;
|
|||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.springframework.extensions.webscripts.servlet.FormData;
|
import org.springframework.extensions.webscripts.servlet.FormData;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* File Folder (Nodes) API
|
* File Folder (Nodes) API
|
||||||
*
|
*
|
||||||
@@ -263,6 +258,49 @@ public interface Nodes
|
|||||||
*/
|
*/
|
||||||
Node unlock(String nodeId, Parameters parameters);
|
Node unlock(String nodeId, Parameters parameters);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert from node properties (map of QName to Serializable) retrieved from
|
||||||
|
* the respository to a map of String to Object that can be formatted/expressed
|
||||||
|
* as required by the API JSON response for get nodes, get person etc.
|
||||||
|
*
|
||||||
|
* @param nodeProps
|
||||||
|
* @param selectParam
|
||||||
|
* @param mapUserInfo
|
||||||
|
* @param excludedProps
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Map<String, Object> mapFromNodeProperties(Map<QName, Serializable> nodeProps, List<String> selectParam, Map<String,UserInfo> mapUserInfo, List<QName> excludedProps);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map from the JSON API format of properties (String to Object) to
|
||||||
|
* the typical node properties map used by the repository (QName to Serializable).
|
||||||
|
*
|
||||||
|
* @param props
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Map<QName, Serializable> mapToNodeProperties(Map<String, Object> props);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map from aspects (Set of QName) retrieved from the repository to a
|
||||||
|
* map List of String required that can be formatted/expressed as required
|
||||||
|
* by the API JSON response for get nodes, get person etc.
|
||||||
|
*
|
||||||
|
* @param nodeAspects
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<String> mapFromNodeAspects(Set<QName> nodeAspects);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add aspects to the specified NodeRef. Aspects that appear in the exclusions list
|
||||||
|
* will be ignored.
|
||||||
|
*
|
||||||
|
* @param nodeRef
|
||||||
|
* @param aspectNames
|
||||||
|
* @param exclusions
|
||||||
|
*/
|
||||||
|
void addCustomAspects(NodeRef nodeRef, List<String> aspectNames, List<QName> exclusions);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API Constants - query parameters, etc
|
* API Constants - query parameters, etc
|
||||||
*/
|
*/
|
||||||
|
@@ -888,7 +888,7 @@ public class NodesImpl implements Nodes
|
|||||||
|
|
||||||
if (includeParam.size() > 0)
|
if (includeParam.size() > 0)
|
||||||
{
|
{
|
||||||
node.setProperties(mapFromNodeProperties(properties, includeParam, mapUserInfo));
|
node.setProperties(mapFromNodeProperties(properties, includeParam, mapUserInfo, EXCLUDED_PROPS));
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<QName> aspects = null;
|
Set<QName> aspects = null;
|
||||||
@@ -1076,7 +1076,7 @@ public class NodesImpl implements Nodes
|
|||||||
return nodeAspects;
|
return nodeAspects;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Map<QName, Serializable> mapToNodeProperties(Map<String, Object> props)
|
public Map<QName, Serializable> mapToNodeProperties(Map<String, Object> props)
|
||||||
{
|
{
|
||||||
Map<QName, Serializable> nodeProps = new HashMap<>(props.size());
|
Map<QName, Serializable> nodeProps = new HashMap<>(props.size());
|
||||||
|
|
||||||
@@ -1116,7 +1116,7 @@ public class NodesImpl implements Nodes
|
|||||||
return nodeProps;
|
return nodeProps;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Map<String, Object> mapFromNodeProperties(Map<QName, Serializable> nodeProps, List<String> selectParam, Map<String,UserInfo> mapUserInfo)
|
public Map<String, Object> mapFromNodeProperties(Map<QName, Serializable> nodeProps, List<String> selectParam, Map<String,UserInfo> mapUserInfo, List<QName> excludedProps)
|
||||||
{
|
{
|
||||||
List<QName> selectedProperties;
|
List<QName> selectedProperties;
|
||||||
|
|
||||||
@@ -1126,7 +1126,7 @@ public class NodesImpl implements Nodes
|
|||||||
selectedProperties = new ArrayList<>(nodeProps.size());
|
selectedProperties = new ArrayList<>(nodeProps.size());
|
||||||
for (QName propQName : nodeProps.keySet())
|
for (QName propQName : nodeProps.keySet())
|
||||||
{
|
{
|
||||||
if ((! EXCLUDED_NS.contains(propQName.getNamespaceURI())) && (! EXCLUDED_PROPS.contains(propQName)))
|
if ((! EXCLUDED_NS.contains(propQName.getNamespaceURI())) && (! excludedProps.contains(propQName)))
|
||||||
{
|
{
|
||||||
selectedProperties.add(propQName);
|
selectedProperties.add(propQName);
|
||||||
}
|
}
|
||||||
@@ -1164,7 +1164,7 @@ public class NodesImpl implements Nodes
|
|||||||
return props;
|
return props;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected List<String> mapFromNodeAspects(Set<QName> nodeAspects)
|
public List<String> mapFromNodeAspects(Set<QName> nodeAspects)
|
||||||
{
|
{
|
||||||
List<String> aspectNames = new ArrayList<>(nodeAspects.size());
|
List<String> aspectNames = new ArrayList<>(nodeAspects.size());
|
||||||
|
|
||||||
@@ -1738,21 +1738,7 @@ public class NodesImpl implements Nodes
|
|||||||
nodeRef = createNodeImpl(parentNodeRef, nodeName, nodeTypeQName, props, assocTypeQName);
|
nodeRef = createNodeImpl(parentNodeRef, nodeName, nodeTypeQName, props, assocTypeQName);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> aspectNames = nodeInfo.getAspectNames();
|
addCustomAspects(nodeRef, nodeInfo.getAspectNames(), EXCLUDED_ASPECTS);
|
||||||
if (aspectNames != null)
|
|
||||||
{
|
|
||||||
// node aspects - set any additional aspects
|
|
||||||
Set<QName> aspectQNames = mapToNodeAspects(aspectNames);
|
|
||||||
for (QName aspectQName : aspectQNames)
|
|
||||||
{
|
|
||||||
if (EXCLUDED_ASPECTS.contains(aspectQName) || aspectQName.equals(ContentModel.ASPECT_AUDITABLE))
|
|
||||||
{
|
|
||||||
continue; // ignore
|
|
||||||
}
|
|
||||||
|
|
||||||
nodeService.addAspect(nodeRef, aspectQName, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// eg. to create mandatory assoc(s)
|
// eg. to create mandatory assoc(s)
|
||||||
|
|
||||||
@@ -1775,6 +1761,25 @@ public class NodesImpl implements Nodes
|
|||||||
return newNode;
|
return newNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addCustomAspects(NodeRef nodeRef, List<String> aspectNames, List<QName> exclusions)
|
||||||
|
{
|
||||||
|
if (aspectNames == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// node aspects - set any additional aspects
|
||||||
|
Set<QName> aspectQNames = mapToNodeAspects(aspectNames);
|
||||||
|
for (QName aspectQName : aspectQNames)
|
||||||
|
{
|
||||||
|
if (exclusions.contains(aspectQName) || aspectQName.equals(ContentModel.ASPECT_AUDITABLE))
|
||||||
|
{
|
||||||
|
continue; // ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeService.addAspect(nodeRef, aspectQName, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private NodeRef getOrCreatePath(NodeRef parentNodeRef, String relativePath)
|
private NodeRef getOrCreatePath(NodeRef parentNodeRef, String relativePath)
|
||||||
{
|
{
|
||||||
if (relativePath != null)
|
if (relativePath != null)
|
||||||
|
@@ -26,12 +26,7 @@
|
|||||||
package org.alfresco.rest.api.impl;
|
package org.alfresco.rest.api.impl;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.AbstractList;
|
import java.util.*;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.query.PagingRequest;
|
import org.alfresco.query.PagingRequest;
|
||||||
@@ -76,6 +71,32 @@ import org.alfresco.util.Pair;
|
|||||||
*/
|
*/
|
||||||
public class PeopleImpl implements People
|
public class PeopleImpl implements People
|
||||||
{
|
{
|
||||||
|
private static final List<QName> EXCLUDED_ASPECTS = Arrays.asList();
|
||||||
|
private static final List<QName> EXCLUDED_PROPS = Arrays.asList(
|
||||||
|
ContentModel.PROP_USERNAME,
|
||||||
|
ContentModel.PROP_FIRSTNAME,
|
||||||
|
ContentModel.PROP_LASTNAME,
|
||||||
|
ContentModel.PROP_JOBTITLE,
|
||||||
|
ContentModel.PROP_LOCATION,
|
||||||
|
ContentModel.PROP_TELEPHONE,
|
||||||
|
ContentModel.PROP_MOBILE,
|
||||||
|
ContentModel.PROP_EMAIL,
|
||||||
|
ContentModel.PROP_ORGANIZATION,
|
||||||
|
ContentModel.PROP_COMPANYADDRESS1,
|
||||||
|
ContentModel.PROP_COMPANYADDRESS2,
|
||||||
|
ContentModel.PROP_COMPANYADDRESS3,
|
||||||
|
ContentModel.PROP_COMPANYPOSTCODE,
|
||||||
|
ContentModel.PROP_COMPANYTELEPHONE,
|
||||||
|
ContentModel.PROP_COMPANYFAX,
|
||||||
|
ContentModel.PROP_COMPANYEMAIL,
|
||||||
|
ContentModel.PROP_SKYPE,
|
||||||
|
ContentModel.PROP_INSTANTMSG,
|
||||||
|
ContentModel.PROP_USER_STATUS,
|
||||||
|
ContentModel.PROP_USER_STATUS_TIME,
|
||||||
|
ContentModel.PROP_GOOGLEUSERNAME,
|
||||||
|
ContentModel.PROP_SIZE_QUOTA,
|
||||||
|
ContentModel.PROP_SIZE_CURRENT,
|
||||||
|
ContentModel.PROP_EMAIL_FEED_DISABLED);
|
||||||
protected Nodes nodes;
|
protected Nodes nodes;
|
||||||
protected Sites sites;
|
protected Sites sites;
|
||||||
|
|
||||||
@@ -358,6 +379,18 @@ public class PeopleImpl implements People
|
|||||||
});
|
});
|
||||||
person = new Person(personNode, nodeProps, enabled);
|
person = new Person(personNode, nodeProps, enabled);
|
||||||
|
|
||||||
|
// Remove the temporary property used to help inline the person description content property.
|
||||||
|
// It may be accessed from the person object (person.getDescription()).
|
||||||
|
nodeProps.remove(Person.PROP_PERSON_DESCRIPTION);
|
||||||
|
|
||||||
|
// Expose properties
|
||||||
|
Map<String, Object> custProps = new HashMap<>();
|
||||||
|
custProps.putAll(nodes.mapFromNodeProperties(nodeProps, new ArrayList<>(), new HashMap<>(), EXCLUDED_PROPS));
|
||||||
|
person.setProperties(custProps);
|
||||||
|
// Expose aspect names
|
||||||
|
Set<QName> aspects = nodeService.getAspects(personNode);
|
||||||
|
person.setAspectNames(nodes.mapFromNodeAspects(aspects));
|
||||||
|
|
||||||
// get avatar information
|
// get avatar information
|
||||||
if (hasAvatar(personNode))
|
if (hasAvatar(personNode))
|
||||||
{
|
{
|
||||||
@@ -405,8 +438,19 @@ public class PeopleImpl implements People
|
|||||||
MutableAuthenticationService mas = (MutableAuthenticationService) authenticationService;
|
MutableAuthenticationService mas = (MutableAuthenticationService) authenticationService;
|
||||||
mas.createAuthentication(person.getUserName(), person.getPassword().toCharArray());
|
mas.createAuthentication(person.getUserName(), person.getPassword().toCharArray());
|
||||||
mas.setAuthenticationEnabled(person.getUserName(), person.isEnabled());
|
mas.setAuthenticationEnabled(person.getUserName(), person.isEnabled());
|
||||||
|
|
||||||
|
// Add custom properties
|
||||||
|
if (person.getProperties() != null)
|
||||||
|
{
|
||||||
|
Map<String, Object> customProps = person.getProperties();
|
||||||
|
props.putAll(nodes.mapToNodeProperties(customProps));
|
||||||
|
}
|
||||||
|
|
||||||
NodeRef nodeRef = personService.createPerson(props);
|
NodeRef nodeRef = personService.createPerson(props);
|
||||||
|
|
||||||
|
// Add custom aspects
|
||||||
|
nodes.addCustomAspects(nodeRef, person.getAspectNames(), EXCLUDED_ASPECTS);
|
||||||
|
|
||||||
// Write the contents of PersonUpdate.getDescription() text to a content file
|
// Write the contents of PersonUpdate.getDescription() text to a content file
|
||||||
// and store the content URL in ContentModel.PROP_PERSONDESC
|
// and store the content URL in ContentModel.PROP_PERSONDESC
|
||||||
if (person.getDescription() != null)
|
if (person.getDescription() != null)
|
||||||
@@ -484,18 +528,28 @@ public class PeopleImpl implements People
|
|||||||
mutableAuthenticationService.setAuthenticationEnabled(personIdToUpdate, person.isEnabled());
|
mutableAuthenticationService.setAuthenticationEnabled(personIdToUpdate, person.isEnabled());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NodeRef personNodeRef = personService.getPerson(personIdToUpdate, false);
|
||||||
if (person.getDescription() != null)
|
if (person.getDescription() != null)
|
||||||
{
|
{
|
||||||
// Remove person description from saved properties
|
// Remove person description from saved properties
|
||||||
properties.remove(ContentModel.PROP_PERSONDESC);
|
properties.remove(ContentModel.PROP_PERSONDESC);
|
||||||
|
|
||||||
// Custom save for person description.
|
// Custom save for person description.
|
||||||
NodeRef personNodeRef = personService.getPerson(personIdToUpdate, false);
|
|
||||||
savePersonDescription(person.getDescription(), personNodeRef);
|
savePersonDescription(person.getDescription(), personNodeRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add custom properties
|
||||||
|
if (person.getProperties() != null)
|
||||||
|
{
|
||||||
|
Map<String, Object> customProps = person.getProperties();
|
||||||
|
properties.putAll(nodes.mapToNodeProperties(customProps));
|
||||||
|
}
|
||||||
|
|
||||||
personService.setPersonProperties(personIdToUpdate, properties, false);
|
personService.setPersonProperties(personIdToUpdate, properties, false);
|
||||||
|
|
||||||
|
// Add custom aspects
|
||||||
|
nodes.addCustomAspects(personNodeRef, person.getAspectNames(), EXCLUDED_ASPECTS);
|
||||||
|
|
||||||
return getPerson(personId);
|
return getPerson(personId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -25,16 +25,17 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.rest.api.model;
|
package org.alfresco.rest.api.model;
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.rest.framework.resource.UniqueId;
|
import org.alfresco.rest.framework.resource.UniqueId;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a user of the system.
|
* Represents a user of the system.
|
||||||
*
|
*
|
||||||
@@ -66,6 +67,8 @@ public class Person
|
|||||||
protected String description;
|
protected String description;
|
||||||
protected Company company;
|
protected Company company;
|
||||||
protected String password;
|
protected String password;
|
||||||
|
protected Map<String, Object> properties;
|
||||||
|
protected List<String> aspectNames;
|
||||||
|
|
||||||
public Person()
|
public Person()
|
||||||
{
|
{
|
||||||
@@ -353,6 +356,26 @@ public class Person
|
|||||||
return this.password;
|
return this.password;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<String, Object> getProperties()
|
||||||
|
{
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProperties(Map<String, Object> properties)
|
||||||
|
{
|
||||||
|
this.properties = properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getAspectNames()
|
||||||
|
{
|
||||||
|
return aspectNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAspectNames(List<String> aspectNames)
|
||||||
|
{
|
||||||
|
this.aspectNames = aspectNames;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
|
@@ -110,26 +110,7 @@ public class PeopleEntityResource implements EntityResourceAction.ReadById<Perso
|
|||||||
}
|
}
|
||||||
|
|
||||||
List<Person> result = new ArrayList<>(1);
|
List<Person> result = new ArrayList<>(1);
|
||||||
Person person = new Person();
|
result.add(people.create(p));
|
||||||
person.setUserName(p.getUserName());
|
|
||||||
person.setFirstName(p.getFirstName());
|
|
||||||
person.setLastName(p.getLastName());
|
|
||||||
person.setDescription(p.getDescription());
|
|
||||||
person.setEmail(p.getEmail());
|
|
||||||
person.setSkypeId(p.getSkypeId());
|
|
||||||
person.setGoogleId(p.getGoogleId());
|
|
||||||
person.setInstantMessageId(p.getInstantMessageId());
|
|
||||||
person.setJobTitle(p.getJobTitle());
|
|
||||||
person.setLocation(p.getLocation());
|
|
||||||
person.setCompany(p.getCompany());
|
|
||||||
person.setMobile(p.getMobile());
|
|
||||||
person.setTelephone(p.getTelephone());
|
|
||||||
person.setUserStatus(p.getUserStatus());
|
|
||||||
person.setEnabled(p.isEnabled());
|
|
||||||
person.setEmailNotificationsEnabled(p.isEmailNotificationsEnabled());
|
|
||||||
person.setPassword(p.getPassword());
|
|
||||||
|
|
||||||
result.add(people.create(person));
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -25,18 +25,13 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.rest.api.tests;
|
package org.alfresco.rest.api.tests;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.*;
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
import static org.junit.Assert.assertNull;
|
|
||||||
import static org.junit.Assert.fail;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.io.Serializable;
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
|
import org.alfresco.model.ContentModel;
|
||||||
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
import org.alfresco.rest.api.tests.RepoService.TestNetwork;
|
import org.alfresco.rest.api.tests.RepoService.TestNetwork;
|
||||||
import org.alfresco.rest.api.tests.client.HttpResponse;
|
import org.alfresco.rest.api.tests.client.HttpResponse;
|
||||||
import org.alfresco.rest.api.tests.client.Pair;
|
import org.alfresco.rest.api.tests.client.Pair;
|
||||||
@@ -47,10 +42,16 @@ import org.alfresco.rest.api.tests.client.RequestContext;
|
|||||||
import org.alfresco.rest.api.tests.client.data.Company;
|
import org.alfresco.rest.api.tests.client.data.Company;
|
||||||
import org.alfresco.rest.api.tests.client.data.JSONAble;
|
import org.alfresco.rest.api.tests.client.data.JSONAble;
|
||||||
import org.alfresco.rest.api.tests.client.data.Person;
|
import org.alfresco.rest.api.tests.client.data.Person;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
|
import org.alfresco.service.cmr.security.PersonService;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.alfresco.util.GUID;
|
import org.alfresco.util.GUID;
|
||||||
import org.apache.commons.httpclient.HttpStatus;
|
import org.apache.commons.httpclient.HttpStatus;
|
||||||
import org.json.simple.JSONObject;
|
import org.json.simple.JSONObject;
|
||||||
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class TestPeople extends EnterpriseTestApi
|
public class TestPeople extends EnterpriseTestApi
|
||||||
@@ -91,6 +92,16 @@ public class TestPeople extends EnterpriseTestApi
|
|||||||
|
|
||||||
account3.createUser();
|
account3.createUser();
|
||||||
account3PersonIt = account3.getPersonIds().iterator();
|
account3PersonIt = account3.getPersonIds().iterator();
|
||||||
|
|
||||||
|
// Capture authentication pre-test, so we can restore it again afterwards.
|
||||||
|
AuthenticationUtil.pushAuthentication();
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown()
|
||||||
|
{
|
||||||
|
// Restore authentication to pre-test state.
|
||||||
|
AuthenticationUtil.popAuthentication();
|
||||||
}
|
}
|
||||||
|
|
||||||
private TestNetwork createNetwork(String networkPrefix)
|
private TestNetwork createNetwork(String networkPrefix)
|
||||||
@@ -425,6 +436,191 @@ public class TestPeople extends EnterpriseTestApi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetPerson_withCustomProps() throws PublicApiException
|
||||||
|
{
|
||||||
|
// Create the person directly using the Java services - we don't want to test
|
||||||
|
// the REST API's "create person" function here, so we're isolating this test from it.
|
||||||
|
PersonService personService = applicationContext.getBean("PersonService", PersonService.class);
|
||||||
|
NodeService nodeService = applicationContext.getBean("NodeService", NodeService.class);
|
||||||
|
Map<QName, Serializable> nodeProps = new HashMap<>();
|
||||||
|
// The cm:titled aspect should be auto-added for the cm:title property
|
||||||
|
nodeProps.put(ContentModel.PROP_TITLE, "A title");
|
||||||
|
|
||||||
|
// These properties should not be present when a person is retrieved
|
||||||
|
// since they are present as top-level fields.
|
||||||
|
nodeProps.put(ContentModel.PROP_USERNAME, "docbrown@"+account1.getId());
|
||||||
|
nodeProps.put(ContentModel.PROP_FIRSTNAME, "Doc");
|
||||||
|
nodeProps.put(ContentModel.PROP_LASTNAME, "Brown");
|
||||||
|
nodeProps.put(ContentModel.PROP_JOBTITLE, "Inventor");
|
||||||
|
nodeProps.put(ContentModel.PROP_LOCATION, "Location");
|
||||||
|
nodeProps.put(ContentModel.PROP_TELEPHONE, "123345");
|
||||||
|
nodeProps.put(ContentModel.PROP_MOBILE, "456456");
|
||||||
|
nodeProps.put(ContentModel.PROP_EMAIL, "doc.brown@example.com");
|
||||||
|
nodeProps.put(ContentModel.PROP_ORGANIZATION, "Acme");
|
||||||
|
nodeProps.put(ContentModel.PROP_COMPANYADDRESS1, "123 Acme Crescent");
|
||||||
|
nodeProps.put(ContentModel.PROP_COMPANYADDRESS2, "Cholsey");
|
||||||
|
nodeProps.put(ContentModel.PROP_COMPANYADDRESS3, "Oxfordshire");
|
||||||
|
nodeProps.put(ContentModel.PROP_COMPANYPOSTCODE, "OX10 1AB");
|
||||||
|
nodeProps.put(ContentModel.PROP_COMPANYTELEPHONE, "098876234");
|
||||||
|
nodeProps.put(ContentModel.PROP_COMPANYFAX, "098234876");
|
||||||
|
nodeProps.put(ContentModel.PROP_COMPANYEMAIL, "info@example.com");
|
||||||
|
nodeProps.put(ContentModel.PROP_SKYPE, "doc.brown");
|
||||||
|
nodeProps.put(ContentModel.PROP_INSTANTMSG, "doc.brown.instmsg");
|
||||||
|
nodeProps.put(ContentModel.PROP_USER_STATUS, "status");
|
||||||
|
nodeProps.put(ContentModel.PROP_USER_STATUS_TIME, new Date());
|
||||||
|
nodeProps.put(ContentModel.PROP_GOOGLEUSERNAME, "doc.brown.google");
|
||||||
|
nodeProps.put(ContentModel.PROP_SIZE_QUOTA, 12345000);
|
||||||
|
nodeProps.put(ContentModel.PROP_SIZE_CURRENT, 1230);
|
||||||
|
nodeProps.put(ContentModel.PROP_EMAIL_FEED_DISABLED, false);
|
||||||
|
// TODO: PROP_PERSON_DESCRIPTION?
|
||||||
|
|
||||||
|
// Namespace that should be filtered
|
||||||
|
nodeProps.put(ContentModel.PROP_SYS_NAME, "name-value");
|
||||||
|
|
||||||
|
AuthenticationUtil.setFullyAuthenticatedUser("admin@"+account1.getId());
|
||||||
|
personService.createPerson(nodeProps);
|
||||||
|
|
||||||
|
// Get the person using the REST API
|
||||||
|
publicApiClient.setRequestContext(new RequestContext(account1.getId(), account1Admin, "admin"));
|
||||||
|
Person person = people.getPerson("docbrown@"+account1.getId());
|
||||||
|
|
||||||
|
// Did we get the correct aspects/properties?
|
||||||
|
assertEquals("docbrown@"+account1.getId(), person.getId());
|
||||||
|
assertEquals("Doc", person.getFirstName());
|
||||||
|
assertEquals("A title", person.getProperties().get("cm:title"));
|
||||||
|
assertTrue(person.getAspectNames().contains("cm:titled"));
|
||||||
|
|
||||||
|
// Properties that are already represented as specific fields in the API response (e.g. firstName, lastName...)
|
||||||
|
// must be filtered from the generic properties datastructure.
|
||||||
|
assertFalse(person.getProperties().containsKey("cm:userName"));
|
||||||
|
assertFalse(person.getProperties().containsKey("cm:firstName"));
|
||||||
|
assertFalse(person.getProperties().containsKey("cm:lastName"));
|
||||||
|
assertFalse(person.getProperties().containsKey("cm:jobtitle"));
|
||||||
|
assertFalse(person.getProperties().containsKey("cm:location"));
|
||||||
|
assertFalse(person.getProperties().containsKey("cm:telephone"));
|
||||||
|
assertFalse(person.getProperties().containsKey("cm:mobile"));
|
||||||
|
assertFalse(person.getProperties().containsKey("cm:email"));
|
||||||
|
assertFalse(person.getProperties().containsKey("cm:organization"));
|
||||||
|
assertFalse(person.getProperties().containsKey("cm:companyaddress1"));
|
||||||
|
assertFalse(person.getProperties().containsKey("cm:companyaddress2"));
|
||||||
|
assertFalse(person.getProperties().containsKey("cm:companyaddress3"));
|
||||||
|
assertFalse(person.getProperties().containsKey("cm:companypostcode"));
|
||||||
|
assertFalse(person.getProperties().containsKey("cm:companytelephone"));
|
||||||
|
assertFalse(person.getProperties().containsKey("cm:companyfax"));
|
||||||
|
assertFalse(person.getProperties().containsKey("cm:companyemail"));
|
||||||
|
assertFalse(person.getProperties().containsKey("cm:skype"));
|
||||||
|
assertFalse(person.getProperties().containsKey("cm:instantmsg"));
|
||||||
|
assertFalse(person.getProperties().containsKey("cm:userStatus"));
|
||||||
|
assertFalse(person.getProperties().containsKey("cm:userStatusTime"));
|
||||||
|
assertFalse(person.getProperties().containsKey("cm:googleusername"));
|
||||||
|
assertFalse(person.getProperties().containsKey("cm:sizeQuota"));
|
||||||
|
assertFalse(person.getProperties().containsKey("cm:sizeCurrent"));
|
||||||
|
assertFalse(person.getProperties().containsKey("cm:emailFeedDisabled"));
|
||||||
|
assertFalse(person.getProperties().containsKey("cm:persondescription"));
|
||||||
|
|
||||||
|
// Check that no properties are present that should have been filtered.
|
||||||
|
for (String key : person.getProperties().keySet())
|
||||||
|
{
|
||||||
|
if (key.startsWith("sys:"))
|
||||||
|
{
|
||||||
|
Object value = person.getProperties().get(key);
|
||||||
|
String keyValueStr = String.format("(key=%s, value=%s)", key, value);
|
||||||
|
fail("Property " + keyValueStr +
|
||||||
|
" found with namespace that should have been excluded.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreatePerson_withCustomProps() throws Exception
|
||||||
|
{
|
||||||
|
publicApiClient.setRequestContext(new RequestContext(account1.getId(), account1Admin, "admin"));
|
||||||
|
Person person = new Person();
|
||||||
|
person.setUserName("jbloggs@"+account1.getId());
|
||||||
|
person.setFirstName("Joe");
|
||||||
|
person.setEmail("jbloggs@"+account1.getId());
|
||||||
|
person.setEnabled(true);
|
||||||
|
person.setPassword("password123");
|
||||||
|
|
||||||
|
Map<String, Object> props = new HashMap<>();
|
||||||
|
props.put("cm:title", "This is a title");
|
||||||
|
person.setProperties(props);
|
||||||
|
|
||||||
|
// Explicitly add an aspect
|
||||||
|
List<String> aspectNames = new ArrayList<>();
|
||||||
|
aspectNames.add("cm:classifiable");
|
||||||
|
person.setAspectNames(aspectNames);
|
||||||
|
|
||||||
|
// REST API call to create person
|
||||||
|
Person retPerson = people.create(person);
|
||||||
|
|
||||||
|
// Check that the response contains the expected aspects and properties
|
||||||
|
assertTrue(retPerson.getAspectNames().contains("cm:titled"));
|
||||||
|
assertTrue(retPerson.getAspectNames().contains("cm:classifiable"));
|
||||||
|
assertEquals("This is a title", retPerson.getProperties().get("cm:title"));
|
||||||
|
|
||||||
|
// Get the NodeRef
|
||||||
|
AuthenticationUtil.setFullyAuthenticatedUser("admin@"+account1.getId());
|
||||||
|
PersonService personService = applicationContext.getBean("PersonService", PersonService.class);
|
||||||
|
NodeRef nodeRef = personService.getPerson("jbloggs@"+account1.getId(), false);
|
||||||
|
|
||||||
|
// Check the node has the properties and aspects we expect
|
||||||
|
NodeService nodeService = applicationContext.getBean("NodeService", NodeService.class);
|
||||||
|
assertTrue(nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TITLED));
|
||||||
|
assertTrue(nodeService.hasAspect(nodeRef, ContentModel.ASPECT_CLASSIFIABLE));
|
||||||
|
|
||||||
|
Map<QName, Serializable> retProps = nodeService.getProperties(nodeRef);
|
||||||
|
assertEquals("This is a title", retProps.get(ContentModel.PROP_TITLE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdatePerson_withCustomProps() throws Exception
|
||||||
|
{
|
||||||
|
publicApiClient.setRequestContext(new RequestContext(account1.getId(), account1Admin, "admin"));
|
||||||
|
Person person = new Person();
|
||||||
|
String personId = "jbloggs2@"+account1.getId();
|
||||||
|
person.setUserName(personId);
|
||||||
|
person.setFirstName("Joe");
|
||||||
|
person.setEmail("jbloggs2@"+account1.getId());
|
||||||
|
person.setEnabled(true);
|
||||||
|
person.setPassword("password123");
|
||||||
|
Map<String, Object> props = new HashMap<>();
|
||||||
|
props.put("cm:title", "Initial title");
|
||||||
|
person.setProperties(props);
|
||||||
|
|
||||||
|
person = people.create(person);
|
||||||
|
assertEquals("Initial title", person.getProperties().get("cm:title"));
|
||||||
|
assertTrue(person.getAspectNames().contains("cm:titled"));
|
||||||
|
|
||||||
|
// Update property
|
||||||
|
person.getProperties().put("cm:title", "Updated title");
|
||||||
|
|
||||||
|
// ID/UserName is not a valid field for update.
|
||||||
|
person.setUserName(null);
|
||||||
|
// TODO: We don't want to attempt to set ownable using the text available?! ...it won't work
|
||||||
|
person.getProperties().remove("cm:owner");
|
||||||
|
person.getAspectNames().clear();
|
||||||
|
person = people.update(personId, person);
|
||||||
|
assertEquals("Updated title", person.getProperties().get("cm:title"));
|
||||||
|
assertTrue(person.getAspectNames().contains("cm:titled"));
|
||||||
|
|
||||||
|
// Remove property
|
||||||
|
person.getProperties().put("cm:title", null);
|
||||||
|
|
||||||
|
// TODO: We don't want to attempt to set ownable using the text available?! ...it won't work
|
||||||
|
person.getProperties().remove("cm:owner");
|
||||||
|
person.getAspectNames().clear();
|
||||||
|
|
||||||
|
person.setUserName(null);
|
||||||
|
person = people.update(personId, person);
|
||||||
|
|
||||||
|
assertFalse(person.getProperties().containsKey("cm:title"));
|
||||||
|
// The aspect will still be there, I don't think we can easily remove the aspect automatically
|
||||||
|
// just because the associated properties have all been removed.
|
||||||
|
assertTrue(person.getAspectNames().contains("cm:titled"));
|
||||||
|
}
|
||||||
|
|
||||||
public static class PersonJSONSerializer implements JSONAble
|
public static class PersonJSONSerializer implements JSONAble
|
||||||
{
|
{
|
||||||
private final Person personUpdate;
|
private final Person personUpdate;
|
||||||
@@ -439,7 +635,10 @@ public class TestPeople extends EnterpriseTestApi
|
|||||||
{
|
{
|
||||||
JSONObject personJson = new JSONObject();
|
JSONObject personJson = new JSONObject();
|
||||||
|
|
||||||
|
if (personUpdate.getUserName() != null)
|
||||||
|
{
|
||||||
personJson.put("id", personUpdate.getUserName());
|
personJson.put("id", personUpdate.getUserName());
|
||||||
|
}
|
||||||
personJson.put("firstName", personUpdate.getFirstName());
|
personJson.put("firstName", personUpdate.getFirstName());
|
||||||
personJson.put("lastName", personUpdate.getLastName());
|
personJson.put("lastName", personUpdate.getLastName());
|
||||||
|
|
||||||
@@ -462,7 +661,8 @@ public class TestPeople extends EnterpriseTestApi
|
|||||||
personJson.put("enabled", personUpdate.isEnabled());
|
personJson.put("enabled", personUpdate.isEnabled());
|
||||||
personJson.put("emailNotificationsEnabled", personUpdate.isEmailNotificationsEnabled());
|
personJson.put("emailNotificationsEnabled", personUpdate.isEmailNotificationsEnabled());
|
||||||
personJson.put("password", personUpdate.getPassword());
|
personJson.put("password", personUpdate.getPassword());
|
||||||
|
personJson.put("properties", personUpdate.getProperties());
|
||||||
|
personJson.put("aspectNames", personUpdate.getAspectNames());
|
||||||
return personJson;
|
return personJson;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1079,9 +1079,14 @@ public class PublicApiClient
|
|||||||
return site;
|
return site;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Person update(String personId, Person person, boolean fullVisibility) throws PublicApiException
|
public Person update(String personId, Person person) throws PublicApiException
|
||||||
{
|
{
|
||||||
HttpResponse response = update("people", person.getId(), null, null, person.toJSON(fullVisibility).toString(), "Failed to update person");
|
return update(personId, person, 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Person update(String personId, Person person, int expectedStatus) throws PublicApiException
|
||||||
|
{
|
||||||
|
HttpResponse response = update("people", personId, null, null, person.toJSON(true).toString(), null, "Failed to update person", expectedStatus);
|
||||||
Person retSite = Person.parsePerson((JSONObject)response.getJsonResponse().get("entry"));
|
Person retSite = Person.parsePerson((JSONObject)response.getJsonResponse().get("entry"));
|
||||||
return retSite;
|
return retSite;
|
||||||
}
|
}
|
||||||
|
@@ -85,7 +85,9 @@ public class Person
|
|||||||
Long quotaUsed,
|
Long quotaUsed,
|
||||||
Boolean emailNotificationsEnabled,
|
Boolean emailNotificationsEnabled,
|
||||||
String description,
|
String description,
|
||||||
org.alfresco.rest.api.model.Company company)
|
org.alfresco.rest.api.model.Company company,
|
||||||
|
Map<String, Object> properties,
|
||||||
|
List<String> aspectNames)
|
||||||
{
|
{
|
||||||
super(userName,
|
super(userName,
|
||||||
enabled,
|
enabled,
|
||||||
@@ -108,6 +110,8 @@ public class Person
|
|||||||
description,
|
description,
|
||||||
company);
|
company);
|
||||||
this.id = userName;
|
this.id = userName;
|
||||||
|
this.properties = properties;
|
||||||
|
this.aspectNames = aspectNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getId()
|
public String getId()
|
||||||
@@ -148,7 +152,10 @@ public class Person
|
|||||||
{
|
{
|
||||||
JSONObject personJson = new JSONObject();
|
JSONObject personJson = new JSONObject();
|
||||||
|
|
||||||
personJson.put("id", getId());
|
if (getUserName() != null)
|
||||||
|
{
|
||||||
|
personJson.put("id", getUserName());
|
||||||
|
}
|
||||||
personJson.put("firstName", getFirstName());
|
personJson.put("firstName", getFirstName());
|
||||||
personJson.put("lastName", getLastName());
|
personJson.put("lastName", getLastName());
|
||||||
|
|
||||||
@@ -161,12 +168,17 @@ public class Person
|
|||||||
personJson.put("instantMessageId", getInstantMessageId());
|
personJson.put("instantMessageId", getInstantMessageId());
|
||||||
personJson.put("jobTitle", getJobTitle());
|
personJson.put("jobTitle", getJobTitle());
|
||||||
personJson.put("location", getLocation());
|
personJson.put("location", getLocation());
|
||||||
|
if (company != null)
|
||||||
|
{
|
||||||
personJson.put("company", new Company(company).toJSON());
|
personJson.put("company", new Company(company).toJSON());
|
||||||
|
}
|
||||||
personJson.put("mobile", getMobile());
|
personJson.put("mobile", getMobile());
|
||||||
personJson.put("telephone", getTelephone());
|
personJson.put("telephone", getTelephone());
|
||||||
personJson.put("userStatus", getUserStatus());
|
personJson.put("userStatus", getUserStatus());
|
||||||
personJson.put("enabled", isEnabled());
|
personJson.put("enabled", isEnabled());
|
||||||
personJson.put("emailNotificationsEnabled", isEmailNotificationsEnabled());
|
personJson.put("emailNotificationsEnabled", isEmailNotificationsEnabled());
|
||||||
|
personJson.put("properties", getProperties());
|
||||||
|
personJson.put("aspectNames", getAspectNames());
|
||||||
}
|
}
|
||||||
return personJson;
|
return personJson;
|
||||||
}
|
}
|
||||||
@@ -214,6 +226,8 @@ public class Person
|
|||||||
String userStatus = (String) jsonObject.get("userStatus");
|
String userStatus = (String) jsonObject.get("userStatus");
|
||||||
Boolean enabled = (Boolean)jsonObject.get("enabled");
|
Boolean enabled = (Boolean)jsonObject.get("enabled");
|
||||||
Boolean emailNotificationsEnabled = (Boolean) jsonObject.get("emailNotificationsEnabled");
|
Boolean emailNotificationsEnabled = (Boolean) jsonObject.get("emailNotificationsEnabled");
|
||||||
|
List<String> aspectNames = (List<String>) jsonObject.get("aspectNames");
|
||||||
|
Map<String, Object> properties = (Map<String, Object>) jsonObject.get("properties");
|
||||||
|
|
||||||
Person person = new Person(
|
Person person = new Person(
|
||||||
userId,
|
userId,
|
||||||
@@ -235,7 +249,9 @@ public class Person
|
|||||||
null, // quotaUsers - not used
|
null, // quotaUsers - not used
|
||||||
emailNotificationsEnabled,
|
emailNotificationsEnabled,
|
||||||
description,
|
description,
|
||||||
company
|
company,
|
||||||
|
properties,
|
||||||
|
aspectNames
|
||||||
);
|
);
|
||||||
return person;
|
return person;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user