use of com.zimbra.cs.mailbox.ACL in project zm-mailbox by Zimbra.
the class ShareExpirationListener method scheduleExpireAccessOpIfReq.
static void scheduleExpireAccessOpIfReq(MailItem item) {
// first cancel any existing task for this item
try {
ExpireGrantsTask.cancel(item.getMailboxId(), item.getId());
} catch (ServiceException e) {
ZimbraLog.scheduler.warn("Error in canceling existing ExpireGrantsTask for (id=%s,mailboxId=%s)", item.getId(), item.getMailboxId(), e);
return;
}
ACL acl = item.getACL();
if (acl == null) {
return;
}
// 0 indicates never expires
long nextExpiry = 0;
for (ACL.Grant grant : acl.getGrants()) {
long expiry = grant.getEffectiveExpiry(acl);
if (expiry != 0) {
nextExpiry = nextExpiry == 0 ? expiry : expiry < nextExpiry ? expiry : nextExpiry;
}
}
if (nextExpiry == 0) {
// there isn't any grant that's going to expire
return;
}
ScheduledTask task = new ExpireGrantsTask();
task.setMailboxId(item.getMailboxId());
// schedule after a minute of the next expiry time
task.setExecTime(new Date(nextExpiry + Constants.MILLIS_PER_MINUTE));
task.setProperty(ExpireGrantsTask.ITEM_ID_PROP_NAME, Integer.toString(item.getId()));
try {
ScheduledTaskManager.schedule(task);
} catch (ServiceException e) {
ZimbraLog.scheduler.warn("Error in scheduling task %s", task.toString(), e);
}
}
use of com.zimbra.cs.mailbox.ACL in project zm-mailbox by Zimbra.
the class ToXML method encodeACL.
// encode mailbox ACL
public static Element encodeACL(OperationContext octxt, Element parent, ACL acl, boolean exposeAclAccessKey) {
Element eACL = parent.addUniqueElement(MailConstants.E_ACL);
if (acl == null) {
return eACL;
}
if (acl.getInternalGrantExpiry() != 0) {
eACL.addAttribute(MailConstants.A_INTERNAL_GRANT_EXPIRY, acl.getInternalGrantExpiry());
}
if (acl.getGuestGrantExpiry() != 0) {
eACL.addAttribute(MailConstants.A_GUEST_GRANT_EXPIRY, acl.getGuestGrantExpiry());
}
boolean needDispName = OperationContextData.getNeedGranteeName(octxt);
for (ACL.Grant grant : acl.getGrants()) {
String name = null;
byte granteeType = grant.getGranteeType();
if (needDispName) {
//
// Get name of the grantee
//
// 1. try getting the name from the Grant, the name is set on the Grant
// if we are in the path of proxying sharing in ZD
name = grant.getGranteeName();
if (name == null) {
// 2. (for bug 35079), see if the name is already resolved in the in the OperationContextData
OperationContextData.GranteeNames granteeNames = OperationContextData.getGranteeNames(octxt);
if (granteeNames != null) {
name = granteeNames.getNameById(grant.getGranteeId(), granteeType);
}
// this *may* lead to a LDAP search if the id is not in cache
if (name == null) {
NamedEntry nentry = FolderAction.lookupGranteeByZimbraId(grant.getGranteeId(), granteeType);
if (nentry != null) {
name = nentry.getName();
}
}
}
}
Element eGrant = eACL.addNonUniqueElement(MailConstants.E_GRANT);
eGrant.addAttribute(MailConstants.A_ZIMBRA_ID, grant.getGranteeId()).addAttribute(MailConstants.A_GRANT_TYPE, ACL.typeToString(granteeType)).addAttribute(MailConstants.A_RIGHTS, ACL.rightsToString(grant.getGrantedRights()));
if (grant.getExpiry() != 0) {
eGrant.addAttribute(MailConstants.A_EXPIRY, grant.getExpiry());
}
if (needDispName) {
// refer to the same object
if (OperationContextData.GranteeNames.INVALID_GRANT == name) {
eGrant.addAttribute(MailConstants.A_INVALID, true);
eGrant.addAttribute(MailConstants.A_DISPLAY, OperationContextData.GranteeNames.EMPTY_NAME);
} else {
eGrant.addAttribute(MailConstants.A_DISPLAY, name);
}
}
if (granteeType == ACL.GRANTEE_KEY) {
if (exposeAclAccessKey) {
eGrant.addAttribute(MailConstants.A_ACCESSKEY, grant.getPassword());
}
} else {
eGrant.addAttribute(MailConstants.A_PASSWORD, grant.getPassword());
}
}
return eACL;
}
use of com.zimbra.cs.mailbox.ACL in project zm-mailbox by Zimbra.
the class FolderAction method parseACL.
static ACL parseACL(Element eAcl, MailItem.Type folderType, Account account) throws ServiceException {
if (eAcl == null)
return null;
long internalGrantExpiry = validateGrantExpiry(eAcl.getAttribute(MailConstants.A_INTERNAL_GRANT_EXPIRY, null), AccountUtil.getMaxInternalShareLifetime(account, folderType));
long guestGrantExpiry = validateGrantExpiry(eAcl.getAttribute(MailConstants.A_GUEST_GRANT_EXPIRY, null), AccountUtil.getMaxExternalShareLifetime(account, folderType));
ACL acl = new ACL(internalGrantExpiry, guestGrantExpiry);
for (Element grant : eAcl.listElements(MailConstants.E_GRANT)) {
String zid = grant.getAttribute(MailConstants.A_ZIMBRA_ID);
byte gtype = ACL.stringToType(grant.getAttribute(MailConstants.A_GRANT_TYPE));
short rights = ACL.stringToRights(grant.getAttribute(MailConstants.A_RIGHTS));
long expiry = gtype == ACL.GRANTEE_PUBLIC ? validateGrantExpiry(grant.getAttribute(MailConstants.A_EXPIRY, null), AccountUtil.getMaxPublicShareLifetime(account, folderType)) : grant.getAttributeLong(MailConstants.A_EXPIRY, 0);
String secret = null;
if (gtype == ACL.GRANTEE_KEY) {
secret = grant.getAttribute(MailConstants.A_ACCESSKEY, null);
} else if (gtype == ACL.GRANTEE_GUEST) {
secret = grant.getAttribute(MailConstants.A_ARGS, null);
// bug 30891 for 5.0.x
if (secret == null) {
secret = grant.getAttribute(MailConstants.A_PASSWORD, null);
}
}
acl.grantAccess(zid, gtype, rights, secret, expiry);
}
return acl;
}
use of com.zimbra.cs.mailbox.ACL in project zm-mailbox by Zimbra.
the class FolderAction method handleFolder.
private String handleFolder(Map<String, Object> context, Element request, String operation, Element result) throws ServiceException {
Element action = request.getElement(MailConstants.E_ACTION);
ZimbraSoapContext zsc = getZimbraSoapContext(context);
Mailbox mbox = getRequestedMailbox(zsc);
OperationContext octxt = getOperationContext(zsc, context);
ItemIdFormatter ifmt = new ItemIdFormatter(zsc);
ItemId iid = new ItemId(action.getAttribute(MailConstants.A_ID), zsc);
if (operation.equals(OP_EMPTY)) {
boolean subfolders = action.getAttributeBool(MailConstants.A_RECURSIVE, true);
mbox.emptyFolder(octxt, iid.getId(), subfolders);
// empty trash means also to purge all IMAP \Deleted messages
if (iid.getId() == Mailbox.ID_FOLDER_TRASH)
mbox.purgeImapDeleted(octxt);
} else if (operation.equals(OP_REFRESH)) {
mbox.synchronizeFolder(octxt, iid.getId());
} else if (operation.equals(OP_IMPORT)) {
String url = action.getAttribute(MailConstants.A_URL);
mbox.importFeed(octxt, iid.getId(), url, false);
} else if (operation.equals(OP_FREEBUSY)) {
boolean fb = action.getAttributeBool(MailConstants.A_EXCLUDE_FREEBUSY, false);
mbox.alterTag(octxt, iid.getId(), MailItem.Type.FOLDER, Flag.FlagInfo.EXCLUDE_FREEBUSY, fb, null);
FreeBusyProvider.mailboxChanged(zsc.getRequestedAccountId());
} else if (operation.equals(OP_CHECK) || operation.equals(OP_UNCHECK)) {
mbox.alterTag(octxt, iid.getId(), MailItem.Type.FOLDER, Flag.FlagInfo.CHECKED, operation.equals(OP_CHECK), null);
} else if (operation.equals(OP_SET_URL)) {
String url = action.getAttribute(MailConstants.A_URL, "");
mbox.setFolderUrl(octxt, iid.getId(), url);
if (!url.equals("")) {
mbox.synchronizeFolder(octxt, iid.getId());
}
if (action.getAttribute(MailConstants.A_EXCLUDE_FREEBUSY, null) != null) {
boolean fb = action.getAttributeBool(MailConstants.A_EXCLUDE_FREEBUSY, false);
mbox.alterTag(octxt, iid.getId(), MailItem.Type.FOLDER, Flag.FlagInfo.EXCLUDE_FREEBUSY, fb, null);
}
} else if (operation.equals(OP_REVOKE)) {
String zid = action.getAttribute(MailConstants.A_ZIMBRA_ID);
mbox.revokeAccess(octxt, iid.getId(), zid);
} else if (operation.equals(OP_GRANT)) {
Element grant = action.getElement(MailConstants.E_GRANT);
short rights = ACL.stringToRights(grant.getAttribute(MailConstants.A_RIGHTS));
byte gtype = ACL.stringToType(grant.getAttribute(MailConstants.A_GRANT_TYPE));
String zid = grant.getAttribute(MailConstants.A_ZIMBRA_ID, null);
long expiry = grant.getAttributeLong(MailConstants.A_EXPIRY, 0);
String secret = null;
NamedEntry nentry = null;
if (gtype == ACL.GRANTEE_AUTHUSER) {
zid = GuestAccount.GUID_AUTHUSER;
} else if (gtype == ACL.GRANTEE_PUBLIC) {
zid = GuestAccount.GUID_PUBLIC;
expiry = validateGrantExpiry(grant.getAttribute(MailConstants.A_EXPIRY, null), AccountUtil.getMaxPublicShareLifetime(mbox.getAccount(), mbox.getFolderById(octxt, iid.getId()).getDefaultView()));
} else if (gtype == ACL.GRANTEE_GUEST) {
zid = grant.getAttribute(MailConstants.A_DISPLAY);
if (zid == null || zid.indexOf('@') < 0)
throw ServiceException.INVALID_REQUEST("invalid guest id or password", null);
// first make sure they didn't accidentally specify "guest" instead of "usr"
boolean guestGrantee = true;
try {
nentry = lookupGranteeByName(zid, ACL.GRANTEE_USER, zsc);
if (nentry instanceof MailTarget) {
Domain domain = Provisioning.getInstance().getDomain(mbox.getAccount());
String granteeDomainName = ((MailTarget) nentry).getDomainName();
if (domain.isInternalSharingCrossDomainEnabled() || domain.getName().equals(granteeDomainName) || Sets.newHashSet(domain.getInternalSharingDomain()).contains(granteeDomainName)) {
guestGrantee = false;
zid = nentry.getId();
gtype = nentry instanceof Group ? ACL.GRANTEE_GROUP : ACL.GRANTEE_USER;
}
}
} catch (ServiceException e) {
// this is the normal path, where lookupGranteeByName throws account.NO_SUCH_USER
}
if (guestGrantee) {
secret = grant.getAttribute(MailConstants.A_ARGS, null);
// password is no longer required for external sharing
if (secret == null) {
secret = grant.getAttribute(MailConstants.A_PASSWORD, null);
}
}
} else if (gtype == ACL.GRANTEE_KEY) {
zid = grant.getAttribute(MailConstants.A_DISPLAY);
// unlike guest, we do not require the display name to be an email address
// unlike guest, we do not fixup grantee type for key grantees if they specify an internal user
// get the optional accesskey
secret = grant.getAttribute(MailConstants.A_ACCESSKEY, null);
} else if (zid != null) {
nentry = lookupGranteeByZimbraId(zid, gtype);
} else {
try {
nentry = lookupGranteeByName(grant.getAttribute(MailConstants.A_DISPLAY), gtype, zsc);
zid = nentry.getId();
// make sure they didn't accidentally specify "usr" instead of "grp"
if (gtype == ACL.GRANTEE_USER && nentry instanceof Group) {
gtype = ACL.GRANTEE_GROUP;
}
} catch (ServiceException e) {
if (AccountServiceException.NO_SUCH_ACCOUNT.equals(e.getCode())) {
// looks like the case of an internal user not provisioned yet
// we'll treat it as external sharing
gtype = ACL.GRANTEE_GUEST;
zid = grant.getAttribute(MailConstants.A_DISPLAY);
} else {
throw e;
}
}
}
ACL.Grant g = mbox.grantAccess(octxt, iid.getId(), zid, gtype, rights, secret, expiry);
// kinda hacky -- return the zimbra id and name of the grantee in the response
result.addAttribute(MailConstants.A_ZIMBRA_ID, zid);
if (nentry != null)
result.addAttribute(MailConstants.A_DISPLAY, nentry.getName());
else if (gtype == ACL.GRANTEE_GUEST || gtype == ACL.GRANTEE_KEY)
result.addAttribute(MailConstants.A_DISPLAY, zid);
if (gtype == ACL.GRANTEE_KEY)
result.addAttribute(MailConstants.A_ACCESSKEY, g.getPassword());
} else if (operation.equals(OP_REVOKEORPHANGRANTS)) {
String zid = action.getAttribute(MailConstants.A_ZIMBRA_ID);
byte gtype = ACL.stringToType(action.getAttribute(MailConstants.A_GRANT_TYPE));
revokeOrphanGrants(octxt, mbox, iid, zid, gtype);
} else if (operation.equals(OP_UPDATE)) {
// duplicating code from ItemAction.java for now...
String newName = action.getAttribute(MailConstants.A_NAME, null);
String folderId = action.getAttribute(MailConstants.A_FOLDER, null);
ItemId iidFolder = new ItemId(folderId == null ? "-1" : folderId, zsc);
if (!iidFolder.belongsTo(mbox)) {
throw ServiceException.INVALID_REQUEST("cannot move folder between mailboxes", null);
} else if (folderId != null && iidFolder.getId() <= 0) {
throw MailServiceException.NO_SUCH_FOLDER(iidFolder.getId());
}
String flags = action.getAttribute(MailConstants.A_FLAGS, null);
byte color = (byte) action.getAttributeLong(MailConstants.A_COLOR, -1);
String view = action.getAttribute(MailConstants.A_DEFAULT_VIEW, null);
Element eAcl = action.getOptionalElement(MailConstants.E_ACL);
ACL acl = null;
if (eAcl != null) {
acl = parseACL(eAcl, view == null ? mbox.getFolderById(octxt, iid.getId()).getDefaultView() : MailItem.Type.of(view), mbox.getAccount());
}
if (color >= 0) {
mbox.setColor(octxt, iid.getId(), MailItem.Type.FOLDER, color);
}
if (acl != null) {
mbox.setPermissions(octxt, iid.getId(), acl);
}
if (flags != null) {
mbox.setTags(octxt, iid.getId(), MailItem.Type.FOLDER, Flag.toBitmask(flags), null, null);
}
if (view != null) {
mbox.setFolderDefaultView(octxt, iid.getId(), MailItem.Type.of(view));
}
if (newName != null) {
mbox.rename(octxt, iid.getId(), MailItem.Type.FOLDER, newName, iidFolder.getId());
} else if (iidFolder.getId() > 0) {
mbox.move(octxt, iid.getId(), MailItem.Type.FOLDER, iidFolder.getId(), null);
}
} else if (operation.equals(OP_SYNCON) || operation.equals(OP_SYNCOFF)) {
mbox.alterTag(octxt, iid.getId(), MailItem.Type.FOLDER, Flag.FlagInfo.SYNC, operation.equals(OP_SYNCON), null);
} else if (operation.equals(OP_RETENTIONPOLICY)) {
mbox.setRetentionPolicy(octxt, iid.getId(), MailItem.Type.FOLDER, new RetentionPolicy(action.getElement(MailConstants.E_RETENTION_POLICY)));
} else if (operation.equals(OP_DISABLE_ACTIVESYNC) || operation.equals(OP_ENABLE_ACTIVESYNC)) {
mbox.setActiveSyncDisabled(octxt, iid.getId(), operation.equals(OP_DISABLE_ACTIVESYNC));
} else if (operation.equals(OP_WEBOFFLINESYNCDAYS)) {
mbox.setFolderWebOfflineSyncDays(octxt, iid.getId(), action.getAttributeInt(MailConstants.A_NUM_DAYS));
} else {
throw ServiceException.INVALID_REQUEST("unknown operation: " + operation, null);
}
return ifmt.formatItemId(iid);
}
use of com.zimbra.cs.mailbox.ACL in project zm-mailbox by Zimbra.
the class CreateFolder method handle.
@Override
public Element handle(Element request, Map<String, Object> context) throws ServiceException {
ZimbraSoapContext zsc = getZimbraSoapContext(context);
Mailbox mbox = getRequestedMailbox(zsc);
OperationContext octxt = getOperationContext(zsc, context);
ItemIdFormatter ifmt = new ItemIdFormatter(zsc);
Element t = request.getElement(MailConstants.E_FOLDER);
String name = t.getAttribute(MailConstants.A_NAME);
String view = t.getAttribute(MailConstants.A_DEFAULT_VIEW, null);
String flags = t.getAttribute(MailConstants.A_FLAGS, null);
byte color = (byte) t.getAttributeLong(MailConstants.A_COLOR, MailItem.DEFAULT_COLOR);
String rgb = t.getAttribute(MailConstants.A_RGB, null);
String url = t.getAttribute(MailConstants.A_URL, null);
String folderId = t.getAttribute(MailConstants.A_FOLDER, null);
ItemId iidParent = folderId != null ? new ItemId(folderId, zsc) : null;
boolean fetchIfExists = t.getAttributeBool(MailConstants.A_FETCH_IF_EXISTS, false);
boolean syncToUrl = t.getAttributeBool(MailConstants.A_SYNC, true);
ACL acl = FolderAction.parseACL(t.getOptionalElement(MailConstants.E_ACL), MailItem.Type.of(view), mbox.getAccount());
Folder folder;
boolean alreadyExisted = false;
try {
Folder.FolderOptions fopt = new Folder.FolderOptions();
fopt.setColor(rgb != null ? new Color(rgb) : new Color(color)).setUrl(url);
fopt.setDefaultView(MailItem.Type.of(view)).setFlags(Flag.toBitmask(flags));
if (iidParent != null) {
folder = mbox.createFolder(octxt, name, iidParent.getId(), fopt);
} else {
folder = mbox.createFolder(octxt, name, fopt);
}
if (!folder.getUrl().equals("") && syncToUrl) {
try {
mbox.synchronizeFolder(octxt, folder.getId());
} catch (ServiceException e) {
// if the synchronization fails, roll back the folder create
rollbackFolder(folder);
throw e;
} catch (RuntimeException e) {
// if the synchronization fails, roll back the folder create
rollbackFolder(folder);
throw ServiceException.FAILURE("could not synchronize with remote feed", e);
}
}
} catch (ServiceException se) {
if (se.getCode() == MailServiceException.ALREADY_EXISTS && fetchIfExists) {
if (iidParent != null) {
folder = mbox.getFolderByName(octxt, iidParent.getId(), name);
} else {
folder = mbox.getFolderByPath(octxt, name);
}
alreadyExisted = true;
} else {
throw se;
}
}
// set the folder ACL as a separate operation, when appropriate
if (acl != null && !alreadyExisted) {
try {
mbox.setPermissions(octxt, folder.getId(), acl);
} catch (ServiceException e) {
try {
// roll back folder creation
mbox.delete(null, folder.getId(), MailItem.Type.FOLDER);
} catch (ServiceException nse) {
ZimbraLog.soap.warn("error ignored while rolling back folder create", nse);
}
throw e;
}
}
Element response = zsc.createElement(MailConstants.CREATE_FOLDER_RESPONSE);
if (folder != null)
ToXML.encodeFolder(response, ifmt, octxt, folder);
return response;
}
Aggregations