mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-14 17:58:59 +00:00
Merge branch 'feature/REPO-1851_get_avatar' into 'develop'
Avatars: retrieve, update and delete See merge request !23
This commit is contained in:
@@ -25,15 +25,18 @@
|
||||
*/
|
||||
package org.alfresco.rest.api;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.rest.api.model.PasswordReset;
|
||||
import org.alfresco.rest.api.model.Person;
|
||||
import org.alfresco.rest.framework.resource.content.BasicContentInfo;
|
||||
import org.alfresco.rest.framework.resource.content.BinaryResource;
|
||||
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
|
||||
import org.alfresco.rest.framework.resource.parameters.Parameters;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.security.NoSuchPersonException;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface People
|
||||
{
|
||||
String DEFAULT_USER = "-me-";
|
||||
@@ -102,4 +105,28 @@ public interface People
|
||||
* @param passwordReset the password reset details
|
||||
*/
|
||||
void resetPassword(String personId, PasswordReset passwordReset);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param personId
|
||||
* @param parameters
|
||||
* @return
|
||||
*/
|
||||
BinaryResource downloadAvatarContent(String personId, Parameters parameters);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param personId
|
||||
* @param contentInfo
|
||||
* @param stream
|
||||
* @param parameters
|
||||
* @return
|
||||
*/
|
||||
Person uploadAvatarContent(String personId, BasicContentInfo contentInfo, InputStream stream, Parameters parameters);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param personId
|
||||
*/
|
||||
void deleteAvatarContent(String personId);
|
||||
}
|
||||
|
@@ -70,6 +70,16 @@ public interface Renditions
|
||||
*/
|
||||
void createRendition(String nodeId, Rendition rendition, Parameters parameters);
|
||||
|
||||
/**
|
||||
* Creates a rendition for the given node - either async r sync
|
||||
*
|
||||
* @param nodeId
|
||||
* @param rendition
|
||||
* @param executeAsync
|
||||
* @param parameters
|
||||
*/
|
||||
void createRendition(String nodeId, Rendition rendition, boolean executeAsync, Parameters parameters);
|
||||
|
||||
/**
|
||||
* Downloads rendition.
|
||||
*
|
||||
|
@@ -37,18 +37,25 @@ import org.alfresco.repo.security.authentication.ResetPasswordServiceImpl.ResetP
|
||||
import org.alfresco.repo.security.authentication.ResetPasswordServiceImpl.ResetPasswordWorkflowInvalidUserException;
|
||||
import org.alfresco.rest.api.Nodes;
|
||||
import org.alfresco.rest.api.People;
|
||||
import org.alfresco.rest.api.Renditions;
|
||||
import org.alfresco.rest.api.Sites;
|
||||
import org.alfresco.rest.api.model.Node;
|
||||
import org.alfresco.rest.api.model.PasswordReset;
|
||||
import org.alfresco.rest.api.model.Person;
|
||||
import org.alfresco.rest.api.model.Rendition;
|
||||
import org.alfresco.rest.framework.core.exceptions.ConstraintViolatedException;
|
||||
import org.alfresco.rest.framework.core.exceptions.DisabledServiceException;
|
||||
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
|
||||
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
|
||||
import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException;
|
||||
import org.alfresco.rest.framework.resource.content.BasicContentInfo;
|
||||
import org.alfresco.rest.framework.resource.content.BinaryResource;
|
||||
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
|
||||
import org.alfresco.rest.framework.resource.parameters.Paging;
|
||||
import org.alfresco.rest.framework.resource.parameters.Parameters;
|
||||
import org.alfresco.rest.framework.resource.parameters.SortColumn;
|
||||
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.ContentData;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.ContentService;
|
||||
@@ -65,6 +72,7 @@ import org.alfresco.util.Pair;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.AbstractList;
|
||||
import java.util.ArrayList;
|
||||
@@ -97,9 +105,9 @@ public class PeopleImpl implements People
|
||||
PermissionService.GROUP_PREFIX,
|
||||
PermissionService.ROLE_PREFIX
|
||||
};
|
||||
|
||||
protected Nodes nodes;
|
||||
protected Sites sites;
|
||||
|
||||
protected SiteService siteService;
|
||||
protected NodeService nodeService;
|
||||
protected PersonService personService;
|
||||
@@ -109,6 +117,7 @@ public class PeopleImpl implements People
|
||||
protected ContentService contentService;
|
||||
protected ThumbnailService thumbnailService;
|
||||
protected ResetPasswordService resetPasswordService;
|
||||
protected Renditions renditions;
|
||||
|
||||
private final static Map<String, QName> sort_params_to_qnames;
|
||||
static
|
||||
@@ -175,6 +184,12 @@ public class PeopleImpl implements People
|
||||
this.resetPasswordService = resetPasswordService;
|
||||
}
|
||||
|
||||
public void setRenditions(Renditions renditions)
|
||||
{
|
||||
this.renditions = renditions;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validate, perform -me- substitution and canonicalize the person ID.
|
||||
*
|
||||
@@ -257,46 +272,22 @@ public class PeopleImpl implements People
|
||||
|
||||
public boolean hasAvatar(NodeRef personNodeRef)
|
||||
{
|
||||
if(personNodeRef != null)
|
||||
{
|
||||
List<AssociationRef> avatorAssocs = nodeService.getTargetAssocs(personNodeRef, ContentModel.ASSOC_AVATAR);
|
||||
return(avatorAssocs.size() > 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return (getAvatarOriginal(personNodeRef) != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NodeRef getAvatar(String personId)
|
||||
{
|
||||
NodeRef avatar = null;
|
||||
|
||||
personId = validatePerson(personId);
|
||||
NodeRef personNode = personService.getPerson(personId);
|
||||
if(personNode != null)
|
||||
{
|
||||
List<AssociationRef> avatorAssocs = nodeService.getTargetAssocs(personNode, ContentModel.ASSOC_AVATAR);
|
||||
if(avatorAssocs.size() > 0)
|
||||
{
|
||||
AssociationRef ref = avatorAssocs.get(0);
|
||||
NodeRef thumbnailNodeRef = thumbnailService.getThumbnailByName(ref.getTargetRef(), ContentModel.PROP_CONTENT, "avatar");
|
||||
if(thumbnailNodeRef != null)
|
||||
{
|
||||
avatar = thumbnailNodeRef;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new EntityNotFoundException("avatar");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new EntityNotFoundException("avatar");
|
||||
}
|
||||
NodeRef avatarOrig = getAvatarOriginal(personNode);
|
||||
avatar = thumbnailService.getThumbnailByName(avatarOrig, ContentModel.PROP_CONTENT, "avatar");
|
||||
}
|
||||
else
|
||||
|
||||
if (avatar == null)
|
||||
{
|
||||
throw new EntityNotFoundException(personId);
|
||||
}
|
||||
@@ -304,6 +295,111 @@ public class PeopleImpl implements People
|
||||
return avatar;
|
||||
}
|
||||
|
||||
private NodeRef getAvatarOriginal(NodeRef personNode)
|
||||
{
|
||||
NodeRef avatarOrigNodeRef = null;
|
||||
List<ChildAssociationRef> avatarChildAssocs = nodeService.getChildAssocs(personNode, Collections.singleton(ContentModel.ASSOC_PREFERENCE_IMAGE));
|
||||
if (avatarChildAssocs.size() > 0)
|
||||
{
|
||||
ChildAssociationRef ref = avatarChildAssocs.get(0);
|
||||
avatarOrigNodeRef = ref.getChildRef();
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO do we still need this ? - backward compatible with JSF web-client avatar
|
||||
List<AssociationRef> avatorAssocs = nodeService.getTargetAssocs(personNode, ContentModel.ASSOC_AVATAR);
|
||||
if (avatorAssocs.size() > 0)
|
||||
{
|
||||
AssociationRef ref = avatorAssocs.get(0);
|
||||
avatarOrigNodeRef = ref.getTargetRef();
|
||||
}
|
||||
}
|
||||
return avatarOrigNodeRef;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BinaryResource downloadAvatarContent(String personId, Parameters parameters)
|
||||
{
|
||||
personId = validatePerson(personId);
|
||||
NodeRef personNode = personService.getPerson(personId);
|
||||
NodeRef avatarNodeRef = getAvatarOriginal(personNode);
|
||||
|
||||
return renditions.getContent(avatarNodeRef, "avatar", parameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Person uploadAvatarContent(String personId, BasicContentInfo contentInfo, InputStream stream, Parameters parameters)
|
||||
{
|
||||
if (!thumbnailService.getThumbnailsEnabled())
|
||||
{
|
||||
throw new DisabledServiceException("Thumbnail generation has been disabled.");
|
||||
}
|
||||
|
||||
personId = validatePerson(personId);
|
||||
checkCurrentUserOrAdmin(personId);
|
||||
|
||||
NodeRef personNode = personService.getPerson(personId);
|
||||
NodeRef avatarOrigNodeRef = getAvatarOriginal(personNode);
|
||||
|
||||
if (avatarOrigNodeRef != null)
|
||||
{
|
||||
deleteAvatar(avatarOrigNodeRef);
|
||||
}
|
||||
|
||||
QName origAvatarQName = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "origAvatar");
|
||||
nodeService.addAspect(personNode, ContentModel.ASPECT_PREFERENCES, null);
|
||||
ChildAssociationRef assoc = nodeService.createNode(personNode, ContentModel.ASSOC_PREFERENCE_IMAGE, origAvatarQName,
|
||||
ContentModel.TYPE_CONTENT);
|
||||
NodeRef avatar = assoc.getChildRef();
|
||||
String avatarOriginalNodeId = avatar.getId();
|
||||
|
||||
// TODO do we still need this ? - backward compatible with JSF web-client avatar
|
||||
nodeService.createAssociation(personNode, avatar, ContentModel.ASSOC_AVATAR);
|
||||
|
||||
Node n = nodes.updateContent(avatarOriginalNodeId, contentInfo, stream, parameters);
|
||||
String mimeType = n.getContent().getMimeType();
|
||||
|
||||
if (mimeType.indexOf("image/") != 0)
|
||||
{
|
||||
throw new InvalidArgumentException(
|
||||
"Uploaded content must be an image (content type determined to be '"+mimeType+"')");
|
||||
}
|
||||
|
||||
// create thumbnail synchronously
|
||||
Rendition avatarR = new Rendition();
|
||||
avatarR.setId("avatar");
|
||||
renditions.createRendition(avatarOriginalNodeId, avatarR, false, parameters);
|
||||
|
||||
List<String> include = Arrays.asList(
|
||||
PARAM_INCLUDE_ASPECTNAMES,
|
||||
PARAM_INCLUDE_PROPERTIES);
|
||||
|
||||
return getPersonWithProperties(personId, include);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteAvatarContent(String personId)
|
||||
{
|
||||
personId = validatePerson(personId);
|
||||
checkCurrentUserOrAdmin(personId);
|
||||
|
||||
NodeRef personNode = personService.getPerson(personId);
|
||||
NodeRef avatarOrigNodeRef = getAvatarOriginal(personNode);
|
||||
if (avatarOrigNodeRef != null)
|
||||
{
|
||||
deleteAvatar(avatarOrigNodeRef);
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteAvatar(NodeRef avatarOrigNodeRef)
|
||||
{
|
||||
// Set as temporary to permanently delete node (instead of archiving)
|
||||
nodeService.addAspect(avatarOrigNodeRef, ContentModel.ASPECT_TEMPORARY, null);
|
||||
|
||||
nodeService.deleteNode(avatarOrigNodeRef);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a full representation of a person.
|
||||
*
|
||||
@@ -612,14 +708,8 @@ public class PeopleImpl implements People
|
||||
personId = validatePerson(personId);
|
||||
validateUpdatePersonData(person);
|
||||
|
||||
boolean isAdmin = isAdminAuthority();
|
||||
|
||||
String currentUserId = AuthenticationUtil.getFullyAuthenticatedUser();
|
||||
if (!isAdmin && !currentUserId.equalsIgnoreCase(personId))
|
||||
{
|
||||
// The user is not an admin user and is not attempting to update *their own* details.
|
||||
throw new PermissionDeniedException();
|
||||
}
|
||||
// Check if user updating *their own* details or is an admin
|
||||
boolean isAdmin = checkCurrentUserOrAdmin(personId);
|
||||
|
||||
final String personIdToUpdate = validatePerson(personId);
|
||||
final Map<QName, Serializable> properties = person.toProperties();
|
||||
@@ -675,6 +765,19 @@ public class PeopleImpl implements People
|
||||
return getPerson(personId);
|
||||
}
|
||||
|
||||
private boolean checkCurrentUserOrAdmin(String personId)
|
||||
{
|
||||
boolean isAdmin = isAdminAuthority();
|
||||
|
||||
String currentUserId = AuthenticationUtil.getFullyAuthenticatedUser();
|
||||
if (!isAdmin && !currentUserId.equalsIgnoreCase(personId))
|
||||
{
|
||||
throw new PermissionDeniedException();
|
||||
}
|
||||
|
||||
return isAdmin;
|
||||
}
|
||||
|
||||
private void validateUpdatePersonData(Person person)
|
||||
{
|
||||
validateNamespaces(person.getAspectNames(), person.getProperties());
|
||||
|
@@ -260,6 +260,12 @@ public class RenditionsImpl implements Renditions, ResourceLoaderAware
|
||||
|
||||
@Override
|
||||
public void createRendition(String nodeId, Rendition rendition, Parameters parameters)
|
||||
{
|
||||
createRendition(nodeId, rendition, true, parameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createRendition(String nodeId, Rendition rendition, boolean executeAsync, Parameters parameters)
|
||||
{
|
||||
// If thumbnail generation has been configured off, then don't bother.
|
||||
if (!thumbnailService.getThumbnailsEnabled())
|
||||
@@ -292,8 +298,9 @@ public class RenditionsImpl implements Renditions, ResourceLoaderAware
|
||||
}
|
||||
|
||||
Action action = ThumbnailHelper.createCreateThumbnailAction(thumbnailDefinition, serviceRegistry);
|
||||
// Queue async creation of thumbnail
|
||||
actionService.executeAction(action, sourceNodeRef, true, true);
|
||||
|
||||
// Create thumbnail - or else queue for async creation
|
||||
actionService.executeAction(action, sourceNodeRef, true, executeAsync);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -324,7 +331,15 @@ public class RenditionsImpl implements Renditions, ResourceLoaderAware
|
||||
{
|
||||
throw new NotFoundException("Thumbnail was not found for [" + renditionId + ']');
|
||||
}
|
||||
String sourceNodeMimeType = getMimeType(sourceNodeRef);
|
||||
String sourceNodeMimeType = null;
|
||||
try
|
||||
{
|
||||
sourceNodeMimeType = (sourceNodeRef != null ? getMimeType(sourceNodeRef) : null);
|
||||
}
|
||||
catch (InvalidArgumentException e)
|
||||
{
|
||||
// No content for node, e.g. ASSOC_AVATAR rather than ASSOC_PREFERENCE_IMAGE
|
||||
}
|
||||
// resource based on the content's mimeType and rendition id
|
||||
String phPath = scriptThumbnailService.getMimeAwarePlaceHolderResourcePath(renditionId, sourceNodeMimeType);
|
||||
if (phPath == null)
|
||||
@@ -388,6 +403,11 @@ public class RenditionsImpl implements Renditions, ResourceLoaderAware
|
||||
|
||||
protected NodeRef getRenditionByName(NodeRef nodeRef, String renditionId, Parameters parameters)
|
||||
{
|
||||
if (nodeRef == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (StringUtils.isEmpty(renditionId))
|
||||
{
|
||||
throw new InvalidArgumentException("renditionId can't be null or empty.");
|
||||
|
@@ -25,19 +25,30 @@
|
||||
*/
|
||||
package org.alfresco.rest.api.people;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.rest.api.People;
|
||||
import org.alfresco.rest.api.model.Client;
|
||||
import org.alfresco.rest.api.model.PasswordReset;
|
||||
import org.alfresco.rest.api.model.Person;
|
||||
import org.alfresco.rest.framework.BinaryProperties;
|
||||
import org.alfresco.rest.framework.Operation;
|
||||
import org.alfresco.rest.framework.WebApiDescription;
|
||||
import org.alfresco.rest.framework.WebApiNoAuth;
|
||||
import org.alfresco.rest.framework.WebApiParam;
|
||||
import org.alfresco.rest.framework.core.ResourceParameter;
|
||||
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
|
||||
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
|
||||
import org.alfresco.rest.framework.resource.EntityResource;
|
||||
import org.alfresco.rest.framework.resource.actions.interfaces.BinaryResourceAction;
|
||||
import org.alfresco.rest.framework.resource.actions.interfaces.EntityResourceAction;
|
||||
import org.alfresco.rest.framework.resource.content.BasicContentInfo;
|
||||
import org.alfresco.rest.framework.resource.content.BinaryResource;
|
||||
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
|
||||
import org.alfresco.rest.framework.resource.parameters.Parameters;
|
||||
import org.alfresco.rest.framework.webscripts.WithResponse;
|
||||
@@ -46,10 +57,6 @@ import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* An implementation of an Entity Resource for a Person
|
||||
*
|
||||
@@ -57,7 +64,10 @@ import java.util.List;
|
||||
* @author Gethin James
|
||||
*/
|
||||
@EntityResource(name="people", title = "People")
|
||||
public class PeopleEntityResource implements EntityResourceAction.ReadById<Person>, EntityResourceAction.Create<Person>, EntityResourceAction.Update<Person>,EntityResourceAction.Read<Person>, InitializingBean
|
||||
public class PeopleEntityResource implements EntityResourceAction.ReadById<Person>, EntityResourceAction.Create<Person>,
|
||||
EntityResourceAction.Update<Person>,EntityResourceAction.Read<Person>,
|
||||
|
||||
BinaryResourceAction.Read, BinaryResourceAction.Update<Person>, BinaryResourceAction.Delete, InitializingBean
|
||||
{
|
||||
private static Log logger = LogFactory.getLog(PeopleEntityResource.class);
|
||||
|
||||
@@ -169,4 +179,54 @@ public class PeopleEntityResource implements EntityResourceAction.ReadById<Perso
|
||||
{
|
||||
people.resetPassword(personId, passwordReset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Download avatar image content
|
||||
*
|
||||
* @param personId
|
||||
* @param parameters {@link Parameters}
|
||||
* @return
|
||||
* @throws EntityNotFoundException
|
||||
*/
|
||||
@Override
|
||||
@WebApiDescription(title = "Download avatar", description = "Download avatar")
|
||||
@BinaryProperties({"avatar"})
|
||||
public BinaryResource readProperty(String personId, Parameters parameters) throws EntityNotFoundException
|
||||
{
|
||||
return people.downloadAvatarContent(personId, parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload avatar image content
|
||||
*
|
||||
* @param personId
|
||||
* @param contentInfo Basic information about the content stream
|
||||
* @param stream An inputstream
|
||||
* @param parameters
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@WebApiDescription(title = "Upload avatar", description = "Upload avatar")
|
||||
@BinaryProperties({"avatar"})
|
||||
public Person updateProperty(String personId, BasicContentInfo contentInfo, InputStream stream, Parameters parameters)
|
||||
{
|
||||
return people.uploadAvatarContent(personId, contentInfo, stream, parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete avatar image content
|
||||
*
|
||||
* @param personId
|
||||
* @param parameters
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@WebApiDescription(title = "Delete avatar image", description = "Delete avatar image")
|
||||
@BinaryProperties({ "avatar" })
|
||||
public void deleteProperty(String personId, Parameters parameters)
|
||||
{
|
||||
people.deleteAvatarContent(personId);
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -667,6 +667,7 @@
|
||||
<bean id="people" class="org.alfresco.rest.api.impl.PeopleImpl">
|
||||
<property name="nodes" ref="Nodes" />
|
||||
<property name="sites" ref="sites" />
|
||||
<property name="renditions" ref="Renditions" />
|
||||
<property name="siteService" ref="SiteService" />
|
||||
<property name="nodeService" ref="NodeService" />
|
||||
<property name="personService" ref="PersonService" />
|
||||
|
@@ -26,12 +26,15 @@
|
||||
package org.alfresco.rest.api.tests;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.content.ContentLimitProvider;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.security.authentication.ResetPasswordServiceImpl;
|
||||
import org.alfresco.rest.api.Renditions;
|
||||
import org.alfresco.rest.api.model.Client;
|
||||
import org.alfresco.rest.api.model.LoginTicket;
|
||||
import org.alfresco.rest.api.model.LoginTicketResponse;
|
||||
import org.alfresco.rest.api.model.PasswordReset;
|
||||
import org.alfresco.rest.api.model.Rendition;
|
||||
import org.alfresco.rest.api.tests.RepoService.TestNetwork;
|
||||
import org.alfresco.rest.api.tests.client.HttpResponse;
|
||||
import org.alfresco.rest.api.tests.client.Pair;
|
||||
@@ -42,21 +45,32 @@ 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.JSONAble;
|
||||
import org.alfresco.rest.api.tests.client.data.Person;
|
||||
import org.alfresco.util.email.EmailUtil;
|
||||
import org.alfresco.rest.api.tests.util.RestApiUtil;
|
||||
import org.alfresco.service.cmr.preference.PreferenceService;
|
||||
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.ContentService;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.security.MutableAuthenticationService;
|
||||
import org.alfresco.service.cmr.security.PersonService;
|
||||
import org.alfresco.service.cmr.thumbnail.ThumbnailService;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.GUID;
|
||||
import org.alfresco.util.email.EmailUtil;
|
||||
import org.apache.commons.httpclient.HttpStatus;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
import javax.mail.internet.MimeMessage;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -69,8 +83,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.mail.internet.MimeMessage;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.alfresco.repo.security.authentication.ResetPasswordServiceImplTest.getWorkflowIdAndKeyFromUrl;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
@@ -1920,6 +1933,360 @@ public class TestPeople extends AbstractBaseApiTest
|
||||
return URL_PEOPLE + '/' + userId + "/reset-password";
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void retrieveAvatar() throws Exception
|
||||
{
|
||||
final String person1 = account1PersonIt.next();
|
||||
publicApiClient.setRequestContext(new RequestContext(account1.getId(), person1));
|
||||
AuthenticationUtil.setFullyAuthenticatedUser(person1);
|
||||
NodeRef person1Ref = personService.getPerson(person1, false);
|
||||
|
||||
// No avatar, but valid person
|
||||
{
|
||||
deleteAvatarDirect(person1Ref);
|
||||
assertNotNull(people.getPerson(person1)); // Pre-condition of test case
|
||||
people.getAvatar(person1, false, 404);
|
||||
}
|
||||
|
||||
// No avatar, but person exists and placeholder requested
|
||||
{
|
||||
assertNotNull(people.getPerson(person1)); // Pre-condition of test case
|
||||
people.getAvatar(person1, true, 200);
|
||||
}
|
||||
|
||||
// Non-existent person
|
||||
{
|
||||
String nonPerson = "i-do-not-exist";
|
||||
people.getPerson(nonPerson, 404); // Pre-condition of test case
|
||||
people.getAvatar(nonPerson, false, 404);
|
||||
}
|
||||
|
||||
// Placeholder requested, but non-existent person
|
||||
{
|
||||
String nonPerson = "i-do-not-exist";
|
||||
people.getPerson(nonPerson, 404); // Pre-condition of test case
|
||||
people.getAvatar(nonPerson, true, 404);
|
||||
}
|
||||
|
||||
// Avatar exists
|
||||
{
|
||||
// Create avatar - direct (i.e. not using the API, so that tests for get avatar can be separated from upload)
|
||||
// There's no significance to the image being used here, it was the most suitable I could find.
|
||||
ClassPathResource thumbRes = new ClassPathResource("test.jpg");
|
||||
deleteAvatarDirect(person1Ref);
|
||||
createAvatarDirect(person1Ref, thumbRes.getFile());
|
||||
|
||||
// Get avatar - API call
|
||||
people.getAvatar(person1, false, 200);
|
||||
}
|
||||
|
||||
// -me- alias
|
||||
{
|
||||
people.getAvatar("-me-", false, 200);
|
||||
}
|
||||
|
||||
// If-Modified-Since behaviour
|
||||
{
|
||||
HttpResponse response = people.getAvatar(person1, false, 200);
|
||||
Map<String, String> responseHeaders = response.getHeaders();
|
||||
|
||||
// Test 304 response
|
||||
String lastModified = responseHeaders.get(LAST_MODIFIED_HEADER);
|
||||
assertNotNull(lastModified);
|
||||
|
||||
// Has it been modified since the time it was last modified - no!
|
||||
people.getAvatar(person1, lastModified, 304);
|
||||
|
||||
// Create an updated avatar
|
||||
waitMillis(2000); // ensure time has passed between updates
|
||||
ClassPathResource thumbRes = new ClassPathResource("publicapi/upload/quick.jpg");
|
||||
deleteAvatarDirect(person1Ref);
|
||||
createAvatarDirect(person1Ref, thumbRes.getFile());
|
||||
|
||||
people.getAvatar(person1, lastModified, 200);
|
||||
}
|
||||
|
||||
// Attachment param
|
||||
{
|
||||
// No attachment parameter (default true)
|
||||
Boolean attachmentParam = null;
|
||||
HttpResponse response = people.getAvatar(person1, attachmentParam, false, null, 200);
|
||||
Map<String, String> responseHeaders = response.getHeaders();
|
||||
String contentDisposition = responseHeaders.get("Content-Disposition");
|
||||
assertNotNull(contentDisposition);
|
||||
assertTrue(contentDisposition.startsWith("attachment;"));
|
||||
|
||||
// attachment=true
|
||||
attachmentParam = true;
|
||||
response = people.getAvatar(person1, attachmentParam, false, null, 200);
|
||||
responseHeaders = response.getHeaders();
|
||||
contentDisposition = responseHeaders.get("Content-Disposition");
|
||||
assertNotNull(contentDisposition);
|
||||
assertTrue(contentDisposition.startsWith("attachment;"));
|
||||
|
||||
// attachment=false
|
||||
attachmentParam = false;
|
||||
response = people.getAvatar(person1, attachmentParam, false, null, 200);
|
||||
responseHeaders = response.getHeaders();
|
||||
contentDisposition = responseHeaders.get("Content-Disposition");
|
||||
assertNull(contentDisposition);
|
||||
}
|
||||
}
|
||||
|
||||
private void waitMillis(int requiredDelay)
|
||||
{
|
||||
long startTime = System.currentTimeMillis();
|
||||
long currTime = startTime;
|
||||
while (currTime < (startTime + requiredDelay))
|
||||
{
|
||||
try
|
||||
{
|
||||
Thread.sleep(requiredDelay);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
System.out.println(":>>> " + e.getMessage());
|
||||
}
|
||||
finally
|
||||
{
|
||||
currTime = System.currentTimeMillis();
|
||||
System.out.println(":>>> waited "+(currTime-startTime) + "ms");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteAvatarDirect(NodeRef personRef)
|
||||
{
|
||||
|
||||
List<ChildAssociationRef> assocs = nodeService.getChildAssocs(personRef).
|
||||
stream().
|
||||
filter(x -> x.getTypeQName().equals(ContentModel.ASSOC_PREFERENCE_IMAGE)).
|
||||
collect(Collectors.toList());
|
||||
if (assocs.size() > 0)
|
||||
{
|
||||
nodeService.deleteNode(assocs.get(0).getChildRef());
|
||||
}
|
||||
|
||||
// remove old association if it exists
|
||||
List<AssociationRef> refs = nodeService.getTargetAssocs(personRef, ContentModel.ASSOC_AVATAR);
|
||||
if (refs.size() == 1)
|
||||
{
|
||||
NodeRef existingRef = refs.get(0).getTargetRef();
|
||||
nodeService.removeAssociation(
|
||||
personRef, existingRef, ContentModel.ASSOC_AVATAR);
|
||||
}
|
||||
|
||||
if (assocs.size() > 1 || refs.size() > 1)
|
||||
{
|
||||
fail(String.format("Pref images: %d, Avatar assocs: %d", assocs.size(), refs.size()));
|
||||
}
|
||||
}
|
||||
|
||||
private NodeRef createAvatarDirect(NodeRef personRef, File avatarFile)
|
||||
{
|
||||
// create new avatar node
|
||||
nodeService.addAspect(personRef, ContentModel.ASPECT_PREFERENCES, null);
|
||||
ChildAssociationRef assoc = nodeService.createNode(
|
||||
personRef,
|
||||
ContentModel.ASSOC_PREFERENCE_IMAGE,
|
||||
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "origAvatar"),
|
||||
ContentModel.TYPE_CONTENT);
|
||||
final NodeRef avatarRef = assoc.getChildRef();
|
||||
|
||||
// JSF client compatibility?
|
||||
nodeService.createAssociation(personRef, avatarRef, ContentModel.ASSOC_AVATAR);
|
||||
|
||||
// upload the avatar content
|
||||
ContentService contentService = applicationContext.getBean("ContentService", ContentService.class);
|
||||
ContentWriter writer = contentService.getWriter(avatarRef, ContentModel.PROP_CONTENT, true);
|
||||
writer.guessMimetype(avatarFile.getName());
|
||||
writer.putContent(avatarFile);
|
||||
|
||||
Rendition avatarR = new Rendition();
|
||||
avatarR.setId("avatar");
|
||||
Renditions renditions = applicationContext.getBean("Renditions", Renditions.class);
|
||||
renditions.createRendition(avatarRef.getId(), avatarR, false, null);
|
||||
|
||||
return avatarRef;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateAvatar() throws PublicApiException, IOException
|
||||
{
|
||||
final String person1 = account1PersonIt.next();
|
||||
final String person2 = account1PersonIt.next();
|
||||
|
||||
publicApiClient.setRequestContext(new RequestContext(account1.getId(), person2));
|
||||
|
||||
AuthenticationUtil.setFullyAuthenticatedUser(person2);
|
||||
|
||||
// Update allowed when no existing avatar
|
||||
{
|
||||
// Pre-condition: no avatar exists
|
||||
NodeRef personRef = personService.getPerson(person2, false);
|
||||
deleteAvatarDirect(personRef);
|
||||
people.getAvatar(person2, false, 404);
|
||||
|
||||
// TODO: What do we expect the 200 response body to be? Currently it's the person JSON - doesn't seem right.
|
||||
ClassPathResource avatar = new ClassPathResource("publicapi/upload/quick.jpg");
|
||||
HttpResponse response = people.updateAvatar(person2, avatar.getFile(), 200);
|
||||
|
||||
// TODO: ideally, this should be a "direct" retrieval to isolate update from get
|
||||
people.getAvatar(person2, false, 200);
|
||||
}
|
||||
|
||||
// Update existing avatar
|
||||
{
|
||||
// Pre-condition: avatar exists
|
||||
people.getAvatar(person2, false, 200);
|
||||
|
||||
ClassPathResource avatar = new ClassPathResource("test.jpg");
|
||||
HttpResponse response = people.updateAvatar(person2, avatar.getFile(), 200);
|
||||
people.getAvatar(person2, false, 200);
|
||||
|
||||
// -me- alias
|
||||
people.updateAvatar(person2, avatar.getFile(), 200);
|
||||
people.getAvatar("-me-", false, 200);
|
||||
}
|
||||
|
||||
// 400: invalid user ID
|
||||
{
|
||||
ClassPathResource avatar = new ClassPathResource("publicapi/upload/quick.jpg");
|
||||
people.updateAvatar("joe@@bloggs.example.com", avatar.getFile(), 404);
|
||||
}
|
||||
|
||||
// 401: authentication failure
|
||||
{
|
||||
publicApiClient.setRequestContext(new RequestContext(account1.getId(), account1Admin, "Wr0ngP4ssw0rd!"));
|
||||
ClassPathResource avatar = new ClassPathResource("publicapi/upload/quick.jpg");
|
||||
people.updateAvatar(account1Admin, avatar.getFile(), 401);
|
||||
}
|
||||
|
||||
// 403: permission denied
|
||||
{
|
||||
publicApiClient.setRequestContext(new RequestContext(account1.getId(), person1));
|
||||
ClassPathResource avatar = new ClassPathResource("publicapi/upload/quick.jpg");
|
||||
people.updateAvatar(person2, avatar.getFile(), 403);
|
||||
|
||||
// Person can update themself
|
||||
people.updateAvatar(person1, avatar.getFile(), 200);
|
||||
|
||||
// Admin can update someone else
|
||||
publicApiClient.setRequestContext(new RequestContext(account1.getId(), account1Admin, "admin"));
|
||||
people.updateAvatar(person1, avatar.getFile(), 200);
|
||||
}
|
||||
|
||||
// 404: non-existent person
|
||||
{
|
||||
publicApiClient.setRequestContext(new RequestContext(account1.getId(), person1));
|
||||
// Pre-condition: non-existent person
|
||||
String nonPerson = "joebloggs@"+account1.getId();
|
||||
people.getPerson(nonPerson, 404);
|
||||
|
||||
ClassPathResource avatar = new ClassPathResource("publicapi/upload/quick.jpg");
|
||||
people.updateAvatar(nonPerson, avatar.getFile(), 404);
|
||||
}
|
||||
|
||||
// 413: content exceeds individual file size limit
|
||||
{
|
||||
// Test content size limit
|
||||
final ContentLimitProvider.SimpleFixedLimitProvider limitProvider = applicationContext.
|
||||
getBean("defaultContentLimitProvider", ContentLimitProvider.SimpleFixedLimitProvider.class);
|
||||
final long defaultSizeLimit = limitProvider.getSizeLimit();
|
||||
limitProvider.setSizeLimitString("20000"); //20 KB
|
||||
|
||||
try
|
||||
{
|
||||
ClassPathResource avatar = new ClassPathResource("publicapi/upload/quick.jpg"); // ~26K
|
||||
people.updateAvatar(person1, avatar.getFile(), 413);
|
||||
}
|
||||
finally
|
||||
{
|
||||
limitProvider.setSizeLimitString(Long.toString(defaultSizeLimit));
|
||||
}
|
||||
}
|
||||
|
||||
// 501: thumbnails disabled
|
||||
{
|
||||
ThumbnailService thumbnailService = applicationContext.getBean("thumbnailService", ThumbnailService.class);
|
||||
// Disable thumbnail generation
|
||||
thumbnailService.setThumbnailsEnabled(false);
|
||||
try
|
||||
{
|
||||
ClassPathResource avatar = new ClassPathResource("publicapi/upload/quick.jpg");
|
||||
people.updateAvatar(person1, avatar.getFile(), 501);
|
||||
}
|
||||
finally
|
||||
{
|
||||
thumbnailService.setThumbnailsEnabled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void removeAvatar() throws IOException, PublicApiException{
|
||||
|
||||
final String person1 = account1PersonIt.next();
|
||||
final String person2 = account1PersonIt.next();
|
||||
|
||||
publicApiClient.setRequestContext(new RequestContext(account1.getId(), person1));
|
||||
|
||||
// Avatar exists
|
||||
{
|
||||
AuthenticationUtil.setFullyAuthenticatedUser("admin@"+account1.getId());
|
||||
|
||||
// Create avatar - direct (i.e. not using the API, so that tests for get avatar can be separated from upload)
|
||||
// There's no significance to the image being used here, it was the most suitable I could find.
|
||||
ClassPathResource thumbRes = new ClassPathResource("publicapi/upload/quick.jpg");
|
||||
NodeRef personRef = personService.getPerson(person1, false);
|
||||
deleteAvatarDirect(personRef);
|
||||
createAvatarDirect(personRef, thumbRes.getFile());
|
||||
|
||||
// Get avatar - API call
|
||||
people.getAvatar(person1, false, 200);
|
||||
|
||||
//remove avatar avatar exists
|
||||
people.deleteAvatarImage(person1,204);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Non-existent person
|
||||
{
|
||||
String nonPerson = "i-do-not-exist";
|
||||
people.getPerson(nonPerson, 404); // Pre-condition of test case
|
||||
people.deleteAvatarImage(nonPerson, 404);
|
||||
}
|
||||
|
||||
//Authentication failed 401
|
||||
{
|
||||
setRequestContext(account1.getId(), networkAdmin, "wrongPassword");
|
||||
people.deleteAvatarImage(person1,HttpServletResponse.SC_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
//No permission
|
||||
{
|
||||
publicApiClient.setRequestContext(new RequestContext(account1.getId(), person1));
|
||||
|
||||
AuthenticationUtil.setFullyAuthenticatedUser("admin@"+account1.getId());
|
||||
|
||||
// Create avatar - direct (i.e. not using the API, so that tests for get avatar can be separated from upload)
|
||||
// There's no significance to the image being used here, it was the most suitable I could find.
|
||||
ClassPathResource thumbRes = new ClassPathResource("test.jpg");
|
||||
NodeRef personRef = personService.getPerson(person1, false);
|
||||
deleteAvatarDirect(personRef);
|
||||
createAvatarDirect(personRef, thumbRes.getFile());
|
||||
|
||||
people.deleteAvatarImage(person2, 403);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getScope()
|
||||
{
|
||||
|
@@ -27,6 +27,7 @@ package org.alfresco.rest.api.tests.client;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Serializable;
|
||||
@@ -47,7 +48,6 @@ import org.alfresco.rest.api.tests.client.data.AuditEntry;
|
||||
import org.alfresco.rest.api.model.SiteUpdate;
|
||||
import org.alfresco.rest.api.tests.TestPeople;
|
||||
import org.alfresco.rest.api.tests.TestSites;
|
||||
import org.alfresco.rest.api.tests.client.PublicApiClient.ListResponse;
|
||||
import org.alfresco.rest.api.tests.client.PublicApiHttpClient.BinaryPayload;
|
||||
import org.alfresco.rest.api.tests.client.PublicApiHttpClient.RequestBuilder;
|
||||
import org.alfresco.rest.api.tests.client.data.Activities;
|
||||
@@ -546,15 +546,20 @@ public class PublicApiClient
|
||||
return response;
|
||||
}
|
||||
|
||||
public HttpResponse get(String scope, String entityCollectionName, Object entityId, String relationCollectionName, Object relationshipEntityId, Map<String, String> params) throws IOException
|
||||
public HttpResponse get(String scope, String entityCollectionName, Object entityId, String relationCollectionName, Object relationshipEntityId, Map<String, String> params, Map<String, String> headers) throws IOException
|
||||
{
|
||||
HttpResponse response = client.get(getRequestContext(), scope, entityCollectionName, entityId, relationCollectionName, relationshipEntityId, params);
|
||||
HttpResponse response = client.get(getRequestContext(), scope, entityCollectionName, entityId, relationCollectionName, relationshipEntityId, params, headers);
|
||||
|
||||
logger.debug(response.toString());
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
public HttpResponse get(String scope, String entityCollectionName, Object entityId, String relationCollectionName, Object relationshipEntityId, Map<String, String> params) throws IOException
|
||||
{
|
||||
return get(scope, entityCollectionName, entityId, relationCollectionName, relationshipEntityId, params, null);
|
||||
}
|
||||
|
||||
public HttpResponse getWithPassword(String scope, String password, String entityCollectionName, Object entityId, String relationCollectionName, Object relationshipEntityId, Map<String, String> params) throws IOException
|
||||
{
|
||||
HttpResponse response = client.get(getRequestContext(), scope, password, entityCollectionName, entityId, relationCollectionName, relationshipEntityId, params);
|
||||
@@ -728,6 +733,21 @@ public class PublicApiClient
|
||||
}
|
||||
}
|
||||
|
||||
public HttpResponse getSingle(String entityCollectionName, String entityId, String relationCollectionName, String relationId, Map<String, String> params,
|
||||
Map<String, String> headers, String errorMessage, int expectedStatus) throws PublicApiException
|
||||
{
|
||||
try
|
||||
{
|
||||
HttpResponse response = get("public", entityCollectionName, entityId, relationCollectionName, relationId, params, headers);
|
||||
checkStatus(errorMessage, expectedStatus, response);
|
||||
return response;
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new PublicApiException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public HttpResponse getSingle(String entityCollectionName, String entityId, String relationCollectionName, String relationId, Map<String, String> params,
|
||||
String errorMessage, int expectedStatus) throws PublicApiException
|
||||
{
|
||||
@@ -1305,6 +1325,59 @@ public class PublicApiClient
|
||||
{
|
||||
remove("people", personId, "activities", String.valueOf(activity.getId()), "Failed to remove activity");
|
||||
}
|
||||
|
||||
public HttpResponse getAvatar(String personId, boolean placeholder, int expectedStatus) throws PublicApiException
|
||||
{
|
||||
return getAvatar(personId, null, placeholder, null, expectedStatus);
|
||||
}
|
||||
|
||||
public HttpResponse getAvatar(String personId, String ifModifiedSince, int expectedStatus) throws PublicApiException
|
||||
{
|
||||
return getAvatar(personId, null, false, ifModifiedSince, expectedStatus);
|
||||
}
|
||||
|
||||
public HttpResponse getAvatar(String personId, Boolean attachment, boolean placeholder, String ifModifiedSince, int expectedStatus) throws PublicApiException
|
||||
{
|
||||
// Binary response expected
|
||||
Map<String, String> params = new HashMap<>();
|
||||
params.put("placeholder", Boolean.toString(placeholder));
|
||||
// Optional attachment parameter
|
||||
if (attachment != null)
|
||||
{
|
||||
params.put("attachment", attachment.toString());
|
||||
}
|
||||
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
if (ifModifiedSince != null)
|
||||
{
|
||||
headers.put("If-Modified-Since", ifModifiedSince);
|
||||
}
|
||||
|
||||
HttpResponse response = getSingle("people", personId, "avatar", null, params, headers, "Failed to get avatar", expectedStatus);
|
||||
checkStatus("Unexpected response", expectedStatus, response);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
public HttpResponse updateAvatar(String personId, File avatar, int expectedStatus) throws PublicApiException
|
||||
{
|
||||
try
|
||||
{
|
||||
Map<String, String> params = new HashMap<>();
|
||||
BinaryPayload payload = new BinaryPayload(avatar);
|
||||
HttpResponse response = client.putBinary(getRequestContext(), "public", 1, "people", personId, "avatar", null, payload, params);
|
||||
checkStatus("Unexpected status", expectedStatus, response);
|
||||
return response;
|
||||
}
|
||||
catch(IOException e)
|
||||
{
|
||||
throw new PublicApiException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteAvatarImage(String personId, int expectedStatus) throws PublicApiException{
|
||||
remove("people", personId, "avatar", null, null, "Failed to remove avatar image", expectedStatus);
|
||||
}
|
||||
}
|
||||
|
||||
public class Comments extends AbstractProxy
|
||||
|
@@ -34,6 +34,7 @@ import java.io.OutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
@@ -312,17 +313,34 @@ public class PublicApiHttpClient
|
||||
public HttpResponse get(final RequestContext rq, String scope, final String entityCollectionName, final Object entityId,
|
||||
final String relationCollectionName, final Object relationshipEntityId, Map<String, String> params) throws IOException
|
||||
{
|
||||
return get(rq, scope, 1, entityCollectionName, entityId, relationCollectionName, relationshipEntityId, params);
|
||||
return get(rq, scope, 1, entityCollectionName, entityId, relationCollectionName, relationshipEntityId, params, null);
|
||||
}
|
||||
|
||||
public HttpResponse get(final RequestContext rq, String scope, final String entityCollectionName, final Object entityId,
|
||||
final String relationCollectionName, final Object relationshipEntityId, Map<String, String> params, Map<String, String> headers) throws IOException
|
||||
{
|
||||
return get(rq, scope, 1, entityCollectionName, entityId, relationCollectionName, relationshipEntityId, params, headers);
|
||||
}
|
||||
|
||||
public HttpResponse get(final RequestContext rq, final String scope, final int version, final String entityCollectionName, final Object entityId,
|
||||
final String relationCollectionName, final Object relationshipEntityId, Map<String, String> params) throws IOException
|
||||
final String relationCollectionName, final Object relationshipEntityId, Map<String, String> params, Map<String, String> headers) throws IOException
|
||||
{
|
||||
if (headers == null)
|
||||
{
|
||||
headers = Collections.emptyMap();
|
||||
}
|
||||
|
||||
RestApiEndpoint endpoint = new RestApiEndpoint(rq.getNetworkId(), scope, version, entityCollectionName, entityId, relationCollectionName,
|
||||
relationshipEntityId, params);
|
||||
String url = endpoint.getUrl();
|
||||
|
||||
GetMethod req = new GetMethod(url);
|
||||
|
||||
for (Entry<String, String> header : headers.entrySet())
|
||||
{
|
||||
req.addRequestHeader(header.getKey(), header.getValue());
|
||||
}
|
||||
|
||||
return submitRequest(req, rq);
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Remote API
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2017 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.rest.api.tests.client.data;
|
||||
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class Avatar implements Serializable, ExpectedComparison
|
||||
{
|
||||
@Override
|
||||
public void expected(Object other)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public static Avatar parseAvatar(JSONObject entry)
|
||||
{
|
||||
return new Avatar();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user