Search in sources :

Example 11 with ACL

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);
    }
}
Also used : ServiceException(com.zimbra.common.service.ServiceException) ACL(com.zimbra.cs.mailbox.ACL) ScheduledTask(com.zimbra.cs.mailbox.ScheduledTask) Date(java.util.Date)

Example 12 with ACL

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;
}
Also used : NamedEntry(com.zimbra.cs.account.NamedEntry) Element(com.zimbra.common.soap.Element) ACL(com.zimbra.cs.mailbox.ACL) OperationContextData(com.zimbra.cs.mailbox.OperationContextData)

Example 13 with ACL

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;
}
Also used : Element(com.zimbra.common.soap.Element) ACL(com.zimbra.cs.mailbox.ACL)

Example 14 with 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);
}
Also used : OperationContext(com.zimbra.cs.mailbox.OperationContext) Group(com.zimbra.cs.account.Group) ItemIdFormatter(com.zimbra.cs.service.util.ItemIdFormatter) Element(com.zimbra.common.soap.Element) ACL(com.zimbra.cs.mailbox.ACL) MailTarget(com.zimbra.cs.account.MailTarget) ItemId(com.zimbra.cs.service.util.ItemId) RetentionPolicy(com.zimbra.soap.mail.type.RetentionPolicy) NamedEntry(com.zimbra.cs.account.NamedEntry) Mailbox(com.zimbra.cs.mailbox.Mailbox) AccountServiceException(com.zimbra.cs.account.AccountServiceException) ServiceException(com.zimbra.common.service.ServiceException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) ZimbraSoapContext(com.zimbra.soap.ZimbraSoapContext) Domain(com.zimbra.cs.account.Domain)

Example 15 with ACL

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;
}
Also used : OperationContext(com.zimbra.cs.mailbox.OperationContext) ItemIdFormatter(com.zimbra.cs.service.util.ItemIdFormatter) Element(com.zimbra.common.soap.Element) Color(com.zimbra.common.mailbox.Color) ACL(com.zimbra.cs.mailbox.ACL) Folder(com.zimbra.cs.mailbox.Folder) ItemId(com.zimbra.cs.service.util.ItemId) Mailbox(com.zimbra.cs.mailbox.Mailbox) ServiceException(com.zimbra.common.service.ServiceException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) ZimbraSoapContext(com.zimbra.soap.ZimbraSoapContext)

Aggregations

ACL (com.zimbra.cs.mailbox.ACL)15 Mailbox (com.zimbra.cs.mailbox.Mailbox)9 ServiceException (com.zimbra.common.service.ServiceException)6 Folder (com.zimbra.cs.mailbox.Folder)5 MailServiceException (com.zimbra.cs.mailbox.MailServiceException)5 Element (com.zimbra.common.soap.Element)4 MailItem (com.zimbra.cs.mailbox.MailItem)4 ZMailbox (com.zimbra.client.ZMailbox)3 OperationContext (com.zimbra.cs.mailbox.OperationContext)3 Account (com.zimbra.cs.account.Account)2 NamedEntry (com.zimbra.cs.account.NamedEntry)2 Ace (com.zimbra.cs.dav.property.Acl.Ace)2 Grant (com.zimbra.cs.mailbox.ACL.Grant)2 Mountpoint (com.zimbra.cs.mailbox.Mountpoint)2 ItemId (com.zimbra.cs.service.util.ItemId)2 ItemIdFormatter (com.zimbra.cs.service.util.ItemIdFormatter)2 ZimbraSoapContext (com.zimbra.soap.ZimbraSoapContext)2 ArrayList (java.util.ArrayList)2 Date (java.util.Date)2 HashSet (java.util.HashSet)2