use of org.alfresco.service.cmr.email.EmailMessageException in project alfresco-repository by Alfresco.
the class EmailServiceImpl method processMessage.
/**
* Process the message. Method is called after filtering by sender's address.
* @param delivery - who gets the message and who is it from (may be different from the contents of the message)
* @param nodeRef Addressed node (target node).
* @param message Email message
* @throws EmailMessageException Any exception occured inside the method will be converted and thrown as <code>EmailMessageException</code>
*/
private void processMessage(final EmailDelivery delivery, final NodeRef nodeRef, final EmailMessage message) {
if (!emailInboundEnabled) {
throw new EmailMessageException(ERR_INBOUND_EMAIL_DISABLED);
}
try {
// Get the username for the process using the system account
final RetryingTransactionCallback<String> getUsernameCallback = new RetryingTransactionCallback<String>() {
public String execute() throws Throwable {
String userName = null;
userName = getUsername(delivery.getFrom());
if (userName == null) {
if (logger.isDebugEnabled()) {
logger.debug("unable to find user for from: " + delivery.getFrom() + ",trying message.from next");
}
userName = getUsername(message.getFrom());
}
if (logger.isDebugEnabled()) {
logger.debug("userName = : " + userName);
}
if (userName == null) {
if (unknownUser.isEmpty()) {
if (logger.isDebugEnabled()) {
logger.debug("unable to find user for from: " + message.getFrom());
}
throw new EmailMessageException(ERR_UNKNOWN_SOURCE_ADDRESS, message.getFrom());
} else {
if (logger.isDebugEnabled()) {
logger.debug("unable to find user for from - return anonymous: ");
}
userName = unknownUser;
}
}
// Ensure that the user is part of the Email Contributors group
if (userName == null || !isEmailContributeUser(userName)) {
throw new EmailMessageException(ERR_USER_NOT_EMAIL_CONTRIBUTOR, userName);
}
return userName;
}
};
RunAsWork<String> getUsernameRunAsWork = new RunAsWork<String>() {
public String doWork() throws Exception {
return retryingTransactionHelper.doInTransaction(getUsernameCallback, false);
}
};
String username;
if (delivery.getAuth() != null) {
// The user has authenticated.
username = delivery.getAuth();
logger.debug("user has already authenticated as:" + username);
} else {
// Need to faff with old message stuff.
username = AuthenticationUtil.runAs(getUsernameRunAsWork, AuthenticationUtil.SYSTEM_USER_NAME);
}
// Process the message using the username's account
final RetryingTransactionCallback<Object> processMessageCallback = new RetryingTransactionCallback<Object>() {
public Object execute() throws Throwable {
// String recipient = message.getTo();
String recipient = delivery.getRecipient();
NodeRef targetNodeRef = null;
if (nodeRef == null) {
targetNodeRef = getTargetNode(recipient);
} else {
targetNodeRef = nodeRef;
}
EmailMessageHandler messageHandler = getMessageHandler(targetNodeRef);
try {
messageHandler.processMessage(targetNodeRef, message);
} catch (DuplicateChildNodeNameException e) {
throw new ConcurrencyFailureException(e.getMessage());
}
return null;
}
};
RunAsWork<Object> processMessageRunAsWork = new RunAsWork<Object>() {
public Object doWork() throws Exception {
return retryingTransactionHelper.doInTransaction(processMessageCallback, false);
}
};
AuthenticationUtil.runAs(processMessageRunAsWork, username);
} catch (EmailMessageException e) {
// These are email-specific errors
throw e;
} catch (AccessDeniedException e) {
throw new EmailMessageException(ERR_ACCESS_DENIED, delivery.getFrom(), delivery.getRecipient());
} catch (IntegrityException e) {
throw new EmailMessageException(ERR_INVALID_SUBJECT);
} catch (Throwable e) {
throw new AlfrescoRuntimeException("Email message processing failed", e);
}
}
use of org.alfresco.service.cmr.email.EmailMessageException in project alfresco-repository by Alfresco.
the class EmailServiceImpl method getUsername.
/**
* Authenticate in Alfresco repository by sender's e-mail address.
*
* @param from Sender's email address
* @return User name or null if the user does not exist.
* @throws EmailMessageException Exception will be thrown if authentication is failed.
*/
private String getUsername(String from) {
String userName = null;
if (from == null || from.length() == 0) {
return null;
}
if (logger.isDebugEnabled()) {
logger.debug("getUsername from: " + from);
}
StoreRef storeRef = new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "SpacesStore");
String query = "TYPE:cm\\:person AND =@cm\\:email:\"" + from + "\"";
ResultSet resultSet = searchService.query(storeRef, SearchService.LANGUAGE_FTS_ALFRESCO, query);
try {
if (resultSet == null || resultSet.length() == 0) {
return null;
}
if (resultSet.length() > 1) {
if (logger.isWarnEnabled()) {
logger.warn("found more as one result for email '" + from + "'. The first will be used");
}
}
NodeRef userNode = resultSet.getNodeRef(0);
if (nodeService.exists(userNode)) {
userName = DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(userNode, ContentModel.PROP_USERNAME));
if (logger.isDebugEnabled()) {
logger.debug("found username: " + userName);
}
} else {
// The Lucene index returned a dead result
throw new EmailMessageException(ERR_UNKNOWN_SOURCE_ADDRESS, from);
}
} finally {
if (resultSet != null) {
resultSet.close();
}
}
return userName;
}
use of org.alfresco.service.cmr.email.EmailMessageException in project alfresco-repository by Alfresco.
the class EmailServiceImpl method getTargetNode.
/**
* Method determines target node by recipient e-mail address.
*
* @param recipient An e-mail address of a recipient
* @return Reference to the target node
* @throws EmailMessageException is thrown if the target node couldn't be determined by some reasons.
*/
private NodeRef getTargetNode(String recipient) {
if (logger.isDebugEnabled()) {
logger.debug("getTarget node for" + recipient);
}
if (recipient == null || recipient.length() == 0) {
throw new EmailMessageException(ERR_INVALID_NODE_ADDRESS, recipient);
}
String[] parts = recipient.split("@");
if (parts.length != 2) {
throw new EmailMessageException(ERR_INVALID_NODE_ADDRESS, recipient);
}
String alias = parts[0];
/*
* First lookup via the attributes service
*
* Then lookup by search service - may be old data prior to attributes service
*
* Then see if we can find a node by dbid
*/
// Lookup via the attributes service
NodeRef ref = (NodeRef) getAttributeService().getAttribute(AliasableAspect.ALIASABLE_ATTRIBUTE_KEY_1, AliasableAspect.ALIASABLE_ATTRIBUTE_KEY_2, AliasableAspect.normaliseAlias(alias));
if (ref != null) {
if (logger.isDebugEnabled()) {
logger.debug("found email alias via attribute service alias =" + alias);
}
return ref;
}
// Ok, alias wasn't found, let's try to interpret recipient address as 'node-bdid' value
try {
Long nodeId = Long.parseLong(parts[0]);
// Get recipient by system account
NodeRef byNodeId = AuthenticationUtil.runAsSystem(() -> nodeService.getNodeRef(nodeId));
if (byNodeId != null) {
if (logger.isDebugEnabled()) {
logger.debug("found email alias via node service =" + alias);
}
return byNodeId;
}
} catch (NumberFormatException ne) {
}
throw new EmailMessageException(ERR_INVALID_NODE_ADDRESS, recipient);
}
Aggregations