Search in sources :

Example 76 with NamedEntry

use of com.zimbra.cs.account.NamedEntry 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 77 with NamedEntry

use of com.zimbra.cs.account.NamedEntry in project zm-mailbox by Zimbra.

the class FolderAction method lookupGranteeByName.

static NamedEntry lookupGranteeByName(String name, byte type, ZimbraSoapContext zsc) throws ServiceException {
    if (type == ACL.GRANTEE_AUTHUSER || type == ACL.GRANTEE_PUBLIC || type == ACL.GRANTEE_GUEST || type == ACL.GRANTEE_KEY)
        return null;
    Provisioning prov = Provisioning.getInstance();
    // for addresses, default to the authenticated user's domain
    if ((type == ACL.GRANTEE_USER || type == ACL.GRANTEE_GROUP) && name.indexOf('@') == -1) {
        Account authacct = prov.get(AccountBy.id, zsc.getAuthtokenAccountId(), zsc.getAuthToken());
        String authname = (authacct == null ? null : authacct.getName());
        if (authacct != null)
            name += authname.substring(authname.indexOf('@'));
    }
    NamedEntry nentry = null;
    if (name != null)
        switch(type) {
            case ACL.GRANTEE_COS:
                nentry = prov.get(Key.CosBy.name, name);
                break;
            case ACL.GRANTEE_DOMAIN:
                nentry = prov.get(Key.DomainBy.name, name);
                break;
            case ACL.GRANTEE_USER:
                nentry = lookupEmailAddress(name);
                break;
            case ACL.GRANTEE_GROUP:
                nentry = prov.getGroup(Key.DistributionListBy.name, name);
                break;
        }
    if (nentry != null)
        return nentry;
    switch(type) {
        case ACL.GRANTEE_COS:
            throw AccountServiceException.NO_SUCH_COS(name);
        case ACL.GRANTEE_DOMAIN:
            throw AccountServiceException.NO_SUCH_DOMAIN(name);
        case ACL.GRANTEE_USER:
            throw AccountServiceException.NO_SUCH_ACCOUNT(name);
        case ACL.GRANTEE_GROUP:
            throw AccountServiceException.NO_SUCH_DISTRIBUTION_LIST(name);
        default:
            throw ServiceException.FAILURE("LDAP entry not found for " + name + " : " + type, null);
    }
}
Also used : GuestAccount(com.zimbra.cs.account.GuestAccount) Account(com.zimbra.cs.account.Account) NamedEntry(com.zimbra.cs.account.NamedEntry) Provisioning(com.zimbra.cs.account.Provisioning)

Example 78 with NamedEntry

use of com.zimbra.cs.account.NamedEntry in project zm-mailbox by Zimbra.

the class FolderAction method lookupEmailAddress.

public static NamedEntry lookupEmailAddress(String name) throws ServiceException {
    if (name.indexOf('<') > 0) {
        InternetAddress addr = new InternetAddress(name);
        name = addr.getAddress();
    }
    Provisioning prov = Provisioning.getInstance();
    NamedEntry nentry = prov.get(AccountBy.name, name);
    if (nentry == null) {
        nentry = prov.getGroup(Key.DistributionListBy.name, name);
    }
    return nentry;
}
Also used : NamedEntry(com.zimbra.cs.account.NamedEntry) InternetAddress(com.zimbra.common.mime.InternetAddress) Provisioning(com.zimbra.cs.account.Provisioning)

Example 79 with NamedEntry

use of com.zimbra.cs.account.NamedEntry in project zm-mailbox by Zimbra.

the class FolderAction method revokeOrphanGrants.

private void revokeOrphanGrants(OperationContext octxt, Mailbox mbox, ItemId iid, String granteeId, byte gtype) throws ServiceException {
    // check if the grantee still exists
    SearchDirectoryOptions opts = new SearchDirectoryOptions();
    if (gtype == ACL.GRANTEE_USER) {
        opts.addType(SearchDirectoryOptions.ObjectType.accounts);
        opts.addType(SearchDirectoryOptions.ObjectType.resources);
    } else if (gtype == ACL.GRANTEE_GROUP) {
        opts.addType(SearchDirectoryOptions.ObjectType.distributionlists);
    } else if (gtype == ACL.GRANTEE_COS) {
        opts.addType(SearchDirectoryOptions.ObjectType.coses);
    } else if (gtype == ACL.GRANTEE_DOMAIN) {
        opts.addType(SearchDirectoryOptions.ObjectType.domains);
    } else {
        throw ServiceException.INVALID_REQUEST("invalid grantee type for revokeOrphanGrants", null);
    }
    String query = "(" + Provisioning.A_zimbraId + "=" + granteeId + ")";
    opts.setFilterString(FilterId.SEARCH_GRANTEE, query);
    // search the grantee on LDAP master
    opts.setOnMaster(true);
    List<NamedEntry> entries = Provisioning.getInstance().searchDirectory(opts);
    if (entries.size() != 0) {
        throw ServiceException.INVALID_REQUEST("grantee " + granteeId + " exists", null);
    }
    // the grantee indeed does not exist, revoke all grants granted to the grantee
    // in this folder and all subfolders
    FolderNode rootNode = mbox.getFolderTree(octxt, iid, true);
    revokeOrphanGrants(octxt, mbox, rootNode, granteeId, gtype);
}
Also used : SearchDirectoryOptions(com.zimbra.cs.account.SearchDirectoryOptions) NamedEntry(com.zimbra.cs.account.NamedEntry) FolderNode(com.zimbra.cs.mailbox.Mailbox.FolderNode)

Example 80 with NamedEntry

use of com.zimbra.cs.account.NamedEntry in project zm-mailbox by Zimbra.

the class CheckPermission method handle.

public Element handle(Element request, Map<String, Object> context) throws ServiceException {
    ZimbraSoapContext zsc = getZimbraSoapContext(context);
    Provisioning prov = Provisioning.getInstance();
    Element eTarget = request.getElement(MailConstants.E_TARGET);
    String targetType = eTarget.getAttribute(MailConstants.A_TARGET_TYPE);
    TargetType tt = TargetType.fromCode(targetType);
    String targetBy = eTarget.getAttribute(MailConstants.A_TARGET_BY);
    String targetValue = eTarget.getText();
    NamedEntry entry = null;
    Element response = zsc.createElement(MailConstants.CHECK_PERMISSION_RESPONSE);
    if (TargetType.account == tt) {
        AccountBy acctBy = AccountBy.fromString(targetBy);
        entry = prov.get(acctBy, targetValue, zsc.getAuthToken());
        if (entry == null && acctBy == AccountBy.id) {
            throw AccountServiceException.NO_SUCH_ACCOUNT(targetValue);
        }
    // otherwise, the target could be an external user, let it fall through
    // to return the default permission.
    } else if (TargetType.calresource == tt) {
        Key.CalendarResourceBy crBy = Key.CalendarResourceBy.fromString(targetBy);
        entry = prov.get(crBy, targetValue);
        if (entry == null && crBy == Key.CalendarResourceBy.id) {
            throw AccountServiceException.NO_SUCH_CALENDAR_RESOURCE(targetValue);
        }
    } else if (TargetType.dl == tt) {
        Key.DistributionListBy dlBy = Key.DistributionListBy.fromString(targetBy);
        entry = prov.getGroupBasic(dlBy, targetValue);
        if (entry == null && dlBy == Key.DistributionListBy.id) {
            throw AccountServiceException.NO_SUCH_CALENDAR_RESOURCE(targetValue);
        }
    } else {
        throw ServiceException.INVALID_REQUEST("invalid target type: " + targetType, null);
    }
    List<UserRight> rights = new ArrayList<UserRight>();
    for (Element eRight : request.listElements(MailConstants.E_RIGHT)) {
        UserRight r = RightManager.getInstance().getUserRight(eRight.getText());
        rights.add(r);
    }
    boolean finalResult = true;
    AccessManager am = AccessManager.getInstance();
    for (UserRight right : rights) {
        boolean allow = am.canDo(zsc.getAuthToken(), entry, right, false);
        if (allow && DiscoverRights.isDelegatedSendRight(right) && TargetBy.name.name().equals(targetBy)) {
            allow = AccountUtil.isAllowedSendAddress(entry, targetValue);
        }
        response.addElement(MailConstants.E_RIGHT).addAttribute(MailConstants.A_ALLOW, allow).setText(right.getName());
        finalResult = finalResult & allow;
    }
    return returnResponse(response, finalResult);
}
Also used : AccessManager(com.zimbra.cs.account.AccessManager) UserRight(com.zimbra.cs.account.accesscontrol.UserRight) Element(com.zimbra.common.soap.Element) ArrayList(java.util.ArrayList) Provisioning(com.zimbra.cs.account.Provisioning) AccountBy(com.zimbra.common.account.Key.AccountBy) NamedEntry(com.zimbra.cs.account.NamedEntry) ZimbraSoapContext(com.zimbra.soap.ZimbraSoapContext) TargetType(com.zimbra.cs.account.accesscontrol.TargetType) Key(com.zimbra.common.account.Key)

Aggregations

NamedEntry (com.zimbra.cs.account.NamedEntry)109 Account (com.zimbra.cs.account.Account)51 ServiceException (com.zimbra.common.service.ServiceException)26 Domain (com.zimbra.cs.account.Domain)24 Provisioning (com.zimbra.cs.account.Provisioning)23 AccountServiceException (com.zimbra.cs.account.AccountServiceException)19 ProvTest (com.zimbra.qa.unittest.prov.ProvTest)19 DistributionList (com.zimbra.cs.account.DistributionList)18 SearchDirectoryOptions (com.zimbra.cs.account.SearchDirectoryOptions)18 HashSet (java.util.HashSet)17 Entry (com.zimbra.cs.account.Entry)15 HashMap (java.util.HashMap)15 Element (com.zimbra.common.soap.Element)14 Group (com.zimbra.cs.account.Group)14 SearchAccountsOptions (com.zimbra.cs.account.SearchAccountsOptions)12 GuestAccount (com.zimbra.cs.account.GuestAccount)8 MailTarget (com.zimbra.cs.account.MailTarget)8 LdapDomain (com.zimbra.cs.account.ldap.entry.LdapDomain)8 AccessManager (com.zimbra.cs.account.AccessManager)7 DynamicGroup (com.zimbra.cs.account.DynamicGroup)7