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:
Matt Ward
2016-11-17 15:00:17 +00:00
parent 434ca4b824
commit c14aedf7d1
8 changed files with 414 additions and 92 deletions

View File

@@ -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
*/ */

View File

@@ -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)

View File

@@ -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);
} }

View File

@@ -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()
{ {

View File

@@ -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;
} }

View File

@@ -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;
} }
} }

View File

@@ -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;
} }

View File

@@ -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;
} }