Search in sources :

Example 51 with SoapHttpTransport

use of com.zimbra.common.soap.SoapHttpTransport in project zm-mailbox by Zimbra.

the class FolderACL method getEffectivePermissionsRemote.

private Short getEffectivePermissionsRemote() throws ServiceException {
    Element request = new XMLElement(MailConstants.GET_EFFECTIVE_FOLDER_PERMS_REQUEST);
    ItemId iid = new ItemId(mShareTarget.getAccountId(), mShareTarget.getFolderId());
    request.addElement(MailConstants.E_FOLDER).addAttribute(MailConstants.A_FOLDER, iid.toString((Account) null));
    Server server = Provisioning.getInstance().getServer(mShareTarget.getAccount());
    String url = URLUtil.getSoapURL(server, false);
    SoapHttpTransport transport = new SoapHttpTransport(url);
    AuthToken authToken = null;
    if (mOctxt != null)
        authToken = AuthToken.getCsrfUnsecuredAuthToken(mOctxt.getAuthToken());
    if (authToken == null)
        authToken = AuthProvider.getAuthToken(GuestAccount.ANONYMOUS_ACCT);
    transport.setAuthToken(authToken.toZAuthToken());
    transport.setTargetAcctId(mShareTarget.getAccountId());
    Short perms = null;
    try {
        Element response = transport.invoke(request);
        Element eFolder = response.getElement(MailConstants.E_FOLDER);
        String permsStr = eFolder.getAttribute(MailConstants.A_RIGHTS);
        perms = Short.valueOf(ACL.stringToRights(permsStr));
    } catch (ServiceException e) {
        ZimbraLog.misc.warn("cannot get effective perms from server " + server.getName(), e);
    } catch (IOException e) {
        ZimbraLog.misc.warn("cannot get effective perms from server " + server.getName(), e);
    } finally {
        transport.shutdown();
    }
    return perms;
}
Also used : GuestAccount(com.zimbra.cs.account.GuestAccount) Account(com.zimbra.cs.account.Account) Server(com.zimbra.cs.account.Server) AccountServiceException(com.zimbra.cs.account.AccountServiceException) ServiceException(com.zimbra.common.service.ServiceException) XMLElement(com.zimbra.common.soap.Element.XMLElement) Element(com.zimbra.common.soap.Element) AuthToken(com.zimbra.cs.account.AuthToken) SoapHttpTransport(com.zimbra.common.soap.SoapHttpTransport) IOException(java.io.IOException) XMLElement(com.zimbra.common.soap.Element.XMLElement) ItemId(com.zimbra.cs.service.util.ItemId)

Example 52 with SoapHttpTransport

use of com.zimbra.common.soap.SoapHttpTransport in project zm-mailbox by Zimbra.

the class ItemActionHelper method executeRemote.

private void executeRemote() throws ServiceException, IOException {
    Account target = Provisioning.getInstance().get(Key.AccountBy.id, mIidFolder.getAccountId());
    AuthToken at = getAuthToken();
    String pxyAuthToken = Provisioning.onLocalServer(target) ? null : at.getProxyAuthToken();
    ZAuthToken zat = null;
    if (pxyAuthToken == null) {
        zat = at.toZAuthToken();
        zat.resetProxyAuthToken();
    } else {
        zat = new ZAuthToken(pxyAuthToken);
    }
    ZMailbox.Options zoptions = new ZMailbox.Options(zat, AccountUtil.getSoapUri(target));
    zoptions.setNoSession(true);
    zoptions.setTargetAccount(target.getId());
    zoptions.setTargetAccountBy(Key.AccountBy.id);
    ZMailbox zmbx = ZMailbox.getMailbox(zoptions);
    // check for mountpoints before going any further...
    ZFolder zfolder = zmbx.getFolderById(mIidFolder.toString(mAuthenticatedAccount));
    if (zfolder instanceof ZMountpoint) {
        ItemId iidTarget = new ItemId(((ZMountpoint) zfolder).getCanonicalRemoteId(), mAuthenticatedAccount.getId());
        if (!mIidFolder.equals(iidTarget)) {
            mIidFolder = iidTarget;
            if (++mHopCount > com.zimbra.soap.ZimbraSoapContext.MAX_HOP_COUNT)
                throw MailServiceException.TOO_MANY_HOPS(mIidRequestedFolder);
            schedule();
            return;
        }
    }
    boolean deleteOriginal = mOperation != Op.COPY;
    String folderStr = mIidFolder.toString();
    mCreatedIds = new ArrayList<String>(itemIds.length);
    boolean toSpam = mIidFolder.getId() == Mailbox.ID_FOLDER_SPAM;
    boolean toMailbox = !toSpam && mIidFolder.getId() != Mailbox.ID_FOLDER_TRASH;
    for (MailItem item : mMailbox.getItemById(mOpCtxt, itemIds, type)) {
        if (item == null) {
            continue;
        }
        List<Message> msgs = null;
        if (item instanceof Conversation) {
            msgs = mMailbox.getMessagesByConversation(mOpCtxt, item.getId(), SortBy.DATE_ASC, -1);
        }
        if (deleteOriginal) {
            if (msgs != null) {
                // determine which of the conversation's component messages are actually able to be moved
                boolean permDenied = false;
                for (Iterator<Message> it = msgs.iterator(); it.hasNext(); ) {
                    Message msg = it.next();
                    if (!TargetConstraint.checkItem(mTargetConstraint, msg)) {
                        it.remove();
                    } else if (!canDelete(msg)) {
                        it.remove();
                        permDenied = true;
                    }
                }
                // stop here if no messages would be moved...
                if (msgs.isEmpty()) {
                    if (permDenied) {
                        throw ServiceException.PERM_DENIED("cannot delete any messages in " + item.getType() + " " + item.getId());
                    }
                    // all messages were excluded by the TargetConstraint, so there's no failure...
                    continue;
                }
            } else {
                if (!canDelete(item)) {
                    throw ServiceException.PERM_DENIED("cannot delete existing copy of " + item.getType() + " " + item.getId());
                }
            }
        }
        boolean fromSpam = item.inSpam();
        if ((fromSpam && toMailbox) || (!fromSpam && toSpam)) {
            try {
                Folder dest = mMailbox.getFolderById(mOpCtxt, mIidFolder.getId());
                SpamReport report = new SpamReport(toSpam, "remote " + mOperation, dest.getPath());
                Folder source = mMailbox.getFolderById(mOpCtxt, item.getFolderId());
                report.setSourceFolderPath(source.getPath());
                report.setDestAccountName(target.getName());
                SpamHandler.getInstance().handle(mOpCtxt, mMailbox, item.getId(), item.getType(), report);
            } catch (OutOfMemoryError e) {
                Zimbra.halt("out of memory", e);
            } catch (Throwable t) {
                ZimbraLog.mailop.info("could not train spam filter: " + new ItemId(item).toString(), t);
            }
        }
        // since we can't apply tags to a remote object, hardwiring "tags" to null below...
        String flags = (mOperation == Op.UPDATE && mFlags != null ? mFlags : item.getFlagString());
        String name = ((mOperation == Op.RENAME || mOperation == Op.UPDATE) && mName != null ? mName : item.getName());
        String createdId = null;
        InputStream in = null;
        switch(item.getType()) {
            case CONTACT:
                Contact ct = (Contact) item;
                Map<String, ZMailbox.ZAttachmentInfo> attachments = new HashMap<String, ZMailbox.ZAttachmentInfo>();
                for (Contact.Attachment att : ct.getAttachments()) {
                    String attachmentId = zmbx.uploadAttachment(att.getFilename(), att.getContent(), att.getContentType(), 0);
                    ZMailbox.ZAttachmentInfo info = new ZMailbox.ZAttachmentInfo().setAttachmentId(attachmentId);
                    attachments.put(att.getName(), info);
                }
                Map<String, String> fields = ct.getFields();
                Map<String, String> members = new HashMap<String, String>();
                for (String key : fields.keySet()) {
                    if (ContactConstants.A_groupMember.equals(key)) {
                        String memberEncoded = fields.get(key);
                        ContactGroup group = ContactGroup.init(memberEncoded);
                        for (Member m : group.getMembers()) {
                            members.put(m.getValue(), m.getType().getSoapEncoded());
                        }
                        break;
                    }
                }
                fields.remove(ContactConstants.A_groupMember);
                ZContact contact = zmbx.createContact(folderStr, null, fields, attachments, members);
                createdId = contact.getId();
                mCreatedIds.add(createdId);
                break;
            case MESSAGE:
                try {
                    in = StoreManager.getInstance().getContent(item.getBlob());
                    createdId = zmbx.addMessage(folderStr, flags, null, item.getDate(), in, item.getSize(), true);
                } finally {
                    ByteUtil.closeStream(in);
                }
                mCreatedIds.add(createdId);
                break;
            case VIRTUAL_CONVERSATION:
            case CONVERSATION:
                for (Message msg : msgs) {
                    flags = (mOperation == Op.UPDATE && mFlags != null ? mFlags : msg.getFlagString());
                    try {
                        in = StoreManager.getInstance().getContent(msg.getBlob());
                        createdId = zmbx.addMessage(folderStr, flags, null, msg.getDate(), in, msg.getSize(), true);
                    } finally {
                        ByteUtil.closeStream(in);
                    }
                    mCreatedIds.add(createdId);
                }
                break;
            case DOCUMENT:
                Document doc = (Document) item;
                SoapHttpTransport transport = new SoapHttpTransport(zoptions.getUri());
                try {
                    in = StoreManager.getInstance().getContent(doc.getBlob());
                    String uploadId = zmbx.uploadContentAsStream(name, in, doc.getContentType(), doc.getSize(), 4000, true);
                    // instead of using convenience method from ZMailbox
                    // we need to hand marshall the request and set the
                    // response protocol explicitly to what was requested
                    // from the client.
                    Element req = new XMLElement(MailConstants.SAVE_DOCUMENT_REQUEST);
                    Element edoc = req.addUniqueElement(MailConstants.E_DOC);
                    edoc.addAttribute(MailConstants.A_NAME, name);
                    edoc.addAttribute(MailConstants.A_FOLDER, folderStr);
                    edoc.addAttribute(MailConstants.A_FLAGS, flags);
                    Element upload = edoc.addElement(MailConstants.E_UPLOAD);
                    upload.addAttribute(MailConstants.A_ID, uploadId);
                    transport.setResponseProtocol(mResponseProtocol);
                    transport.setAuthToken(zat);
                    Element response = transport.invoke(req);
                    createdId = response.getElement(MailConstants.E_DOC).getAttribute(MailConstants.A_ID);
                } finally {
                    ByteUtil.closeStream(in);
                    transport.shutdown();
                }
                mCreatedIds.add(createdId);
                break;
            case APPOINTMENT:
            case TASK:
                CalendarItem cal = (CalendarItem) item;
                // private calendar item may not be moved by non-owner unless permission was granted
                if (!cal.isPublic()) {
                    boolean asAdmin = mOpCtxt != null ? mOpCtxt.isUsingAdminPrivileges() : false;
                    if (!cal.allowPrivateAccess(mAuthenticatedAccount, asAdmin))
                        throw ServiceException.PERM_DENIED("you do not have permission to move/copy a private calendar item from the current folder/mailbox");
                }
                // Move the item to remote mailbox using SetAppointmentRequest/SetTaskRequest.
                QName qname = (item.getType() == MailItem.Type.TASK ? MailConstants.SET_TASK_REQUEST : MailConstants.SET_APPOINTMENT_REQUEST);
                Element request = new Element.XMLElement(qname).addAttribute(MailConstants.A_FOLDER, folderStr).addAttribute(MailConstants.A_FLAGS, flags);
                ToXML.encodeAlarmTimes(request, cal);
                Invite invDefault = cal.getDefaultInviteOrNull();
                // Takeover as organizer if we're doing a MOVE and source mailbox is the organizer.
                // Don't takeover in a COPY operation.
                boolean takeoverAsOrganizer = false;
                boolean blockMove = false;
                if (Op.MOVE.equals(mOperation)) {
                    Invite inv = invDefault;
                    if (inv == null) {
                        // no default invite; let's use the first invite
                        Invite[] invs = cal.getInvites();
                        if (invs != null && invs.length > 0)
                            inv = invs[0];
                    }
                    takeoverAsOrganizer = inv != null && inv.isOrganizer();
                    blockMove = takeoverAsOrganizer && inv.hasOtherAttendees();
                }
                if (blockMove) {
                    throw MailServiceException.INVALID_REQUEST("This operation requires change of organizer and it is not permitted", null);
                }
                if (invDefault != null) {
                    addCalendarPart(request.addUniqueElement(MailConstants.A_DEFAULT), cal, invDefault, zmbx, target, takeoverAsOrganizer);
                }
                for (Invite inv : cal.getInvites()) {
                    if (inv == null || inv == invDefault)
                        continue;
                    String elem = inv.isCancel() ? MailConstants.E_CAL_CANCEL : MailConstants.E_CAL_EXCEPT;
                    addCalendarPart(request.addElement(elem), cal, inv, zmbx, target, takeoverAsOrganizer);
                }
                ToXML.encodeCalendarReplies(request, cal);
                createdId = zmbx.invoke(request).getAttribute(MailConstants.A_CAL_ID);
                mCreatedIds.add(createdId);
                break;
            default:
                throw MailServiceException.CANNOT_COPY(item.getId());
        }
        try {
            if (deleteOriginal && !mIdFormatter.formatItemId(item).equals(createdId)) {
                if (msgs == null) {
                    mMailbox.delete(mOpCtxt, item.getId(), item.getType());
                } else {
                    for (Message msg : msgs) mMailbox.delete(mOpCtxt, msg.getId(), msg.getType());
                }
            }
        } catch (ServiceException e) {
            if (e.getCode() != ServiceException.PERM_DENIED)
                throw e;
            // something funky happened permissions-wise between the getEffectivePermissions check and here...
            ZimbraLog.misc.info("could not delete original item " + item.getId() + "; treating operation as a copy instead");
        }
    }
}
Also used : ZMountpoint(com.zimbra.client.ZMountpoint) Account(com.zimbra.cs.account.Account) Message(com.zimbra.cs.mailbox.Message) MimeMessage(javax.mail.internet.MimeMessage) HashMap(java.util.HashMap) Element(com.zimbra.common.soap.Element) XMLElement(com.zimbra.common.soap.Element.XMLElement) Conversation(com.zimbra.cs.mailbox.Conversation) Folder(com.zimbra.cs.mailbox.Folder) ZFolder(com.zimbra.client.ZFolder) Document(com.zimbra.cs.mailbox.Document) XMLElement(com.zimbra.common.soap.Element.XMLElement) ZAuthToken(com.zimbra.common.auth.ZAuthToken) ItemId(com.zimbra.cs.service.util.ItemId) CalendarItem(com.zimbra.cs.mailbox.CalendarItem) ZMailbox(com.zimbra.client.ZMailbox) ZFolder(com.zimbra.client.ZFolder) SoapHttpTransport(com.zimbra.common.soap.SoapHttpTransport) Member(com.zimbra.cs.mailbox.ContactGroup.Member) InputStream(java.io.InputStream) QName(org.dom4j.QName) ZContact(com.zimbra.client.ZContact) Contact(com.zimbra.cs.mailbox.Contact) MailItem(com.zimbra.cs.mailbox.MailItem) ServiceException(com.zimbra.common.service.ServiceException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) SpamReport(com.zimbra.cs.service.util.SpamHandler.SpamReport) AuthToken(com.zimbra.cs.account.AuthToken) ZAuthToken(com.zimbra.common.auth.ZAuthToken) ContactGroup(com.zimbra.cs.mailbox.ContactGroup) Invite(com.zimbra.cs.mailbox.calendar.Invite) ZContact(com.zimbra.client.ZContact)

Example 53 with SoapHttpTransport

use of com.zimbra.common.soap.SoapHttpTransport in project zm-mailbox by Zimbra.

the class GalSyncAccountUtil method deleteGalSyncAccount.

private Element deleteGalSyncAccount(String name, String id) throws ServiceException, IOException {
    mTransport = null;
    try {
        mTransport = new SoapHttpTransport(mAdminURL);
        auth();
        mTransport.setAuthToken(mAuth);
        XMLElement req = new XMLElement(AdminConstants.DELETE_GAL_SYNC_ACCOUNT_REQUEST);
        Element acct = req.addElement(AdminConstants.E_ACCOUNT);
        String account;
        AccountBy by;
        if (name == null) {
            by = AccountBy.id;
            account = id;
        } else {
            by = AccountBy.name;
            account = name;
        }
        acct.addAttribute(AdminConstants.A_BY, by.name());
        acct.setText(account);
        return mTransport.invokeWithoutSession(req);
    } finally {
        if (mTransport != null)
            mTransport.shutdown();
    }
}
Also used : XMLElement(com.zimbra.common.soap.Element.XMLElement) Element(com.zimbra.common.soap.Element) SoapHttpTransport(com.zimbra.common.soap.SoapHttpTransport) XMLElement(com.zimbra.common.soap.Element.XMLElement) AccountBy(com.zimbra.common.account.Key.AccountBy)

Example 54 with SoapHttpTransport

use of com.zimbra.common.soap.SoapHttpTransport in project zm-mailbox by Zimbra.

the class GalSyncAccountUtil method createGalSyncAccount.

private Element createGalSyncAccount(String accountName, String dsName, String domain, String type, String folder, String pollingInterval, String mailHost) throws ServiceException, IOException {
    mTransport = null;
    try {
        mTransport = new SoapHttpTransport(mAdminURL);
        auth();
        mTransport.setAuthToken(mAuth);
        XMLElement req = new XMLElement(AdminConstants.CREATE_GAL_SYNC_ACCOUNT_REQUEST);
        req.addAttribute(AdminConstants.A_NAME, dsName);
        req.addAttribute(AdminConstants.A_DOMAIN, domain);
        req.addAttribute(AdminConstants.A_TYPE, type);
        if (folder != null)
            req.addAttribute(AdminConstants.E_FOLDER, folder);
        req.addAttribute(AdminConstants.A_SERVER, mailHost);
        Element acct = req.addElement(AdminConstants.E_ACCOUNT);
        acct.addAttribute(AdminConstants.A_BY, AccountBy.name.name());
        acct.setText(accountName);
        if (pollingInterval != null)
            req.addElement(AdminConstants.E_A).addAttribute(AdminConstants.A_N, Provisioning.A_zimbraDataSourcePollingInterval).setText(pollingInterval);
        return mTransport.invokeWithoutSession(req);
    } finally {
        if (mTransport != null)
            mTransport.shutdown();
    }
}
Also used : XMLElement(com.zimbra.common.soap.Element.XMLElement) Element(com.zimbra.common.soap.Element) SoapHttpTransport(com.zimbra.common.soap.SoapHttpTransport) XMLElement(com.zimbra.common.soap.Element.XMLElement)

Example 55 with SoapHttpTransport

use of com.zimbra.common.soap.SoapHttpTransport in project zm-mailbox by Zimbra.

the class GalSearchControl method proxyGalAccountSearch.

private boolean proxyGalAccountSearch(Account galSyncAcct, boolean sync) throws IOException, ServiceException {
    try {
        Provisioning prov = Provisioning.getInstance();
        String serverUrl = URLUtil.getAdminURL(prov.getServerByName(galSyncAcct.getMailHost()));
        SoapHttpTransport transport = new SoapHttpTransport(serverUrl);
        AuthToken auth = mParams.getAuthToken();
        transport.setAuthToken((auth == null) ? AuthProvider.getAdminAuthToken().toZAuthToken() : auth.toZAuthToken());
        ZimbraSoapContext zsc = mParams.getSoapContext();
        if (zsc != null) {
            transport.setResponseProtocol(zsc.getResponseProtocol());
            String requestedAcctId = zsc.getRequestedAccountId();
            String authTokenAcctId = zsc.getAuthtokenAccountId();
            if (requestedAcctId != null && !requestedAcctId.equalsIgnoreCase(authTokenAcctId))
                transport.setTargetAcctId(requestedAcctId);
        }
        Element req = mParams.getRequest();
        if (req == null) {
            req = Element.create(mParams.getProxyProtocol(), AccountConstants.SEARCH_GAL_REQUEST);
            req.addAttribute(AccountConstants.A_TYPE, mParams.getType().toString());
            req.addAttribute(AccountConstants.A_LIMIT, mParams.getLimit());
            req.addAttribute(AccountConstants.A_NAME, mParams.getQuery());
            req.addAttribute(AccountConstants.A_REF, mParams.getSearchEntryByDn());
        }
        req.addAttribute(AccountConstants.A_GAL_ACCOUNT_ID, galSyncAcct.getId());
        req.addAttribute(AccountConstants.A_GAL_ACCOUNT_PROXIED, true);
        if (sync && mParams.getGalSyncToken() != null) {
            req.addAttribute(MailConstants.A_TOKEN, mParams.getGalSyncToken().toString());
            ZimbraLog.gal.debug("setting token for proxied request %s", mParams.getGalSyncToken().toString());
        }
        Element resp = transport.invokeWithoutSession(req.detach());
        GalSearchResultCallback callback = mParams.getResultCallback();
        if (callback.passThruProxiedGalAcctResponse()) {
            callback.handleProxiedResponse(resp);
            return true;
        }
        Iterator<Element> iter = resp.elementIterator(MailConstants.E_CONTACT);
        while (iter.hasNext()) callback.handleElement(iter.next());
        iter = resp.elementIterator(MailConstants.E_DELETED);
        while (iter.hasNext()) callback.handleElement(iter.next());
        String newTokenStr = resp.getAttribute(MailConstants.A_TOKEN, null);
        if (newTokenStr != null) {
            GalSyncToken newToken = new GalSyncToken(newTokenStr);
            ZimbraLog.gal.debug("computing new sync token for proxied account " + galSyncAcct.getId() + ": " + newToken);
            callback.setNewToken(newToken);
        }
        boolean hasMore = resp.getAttributeBool(MailConstants.A_QUERY_MORE, false);
        callback.setHasMoreResult(hasMore);
        if (hasMore && !sync) {
            callback.setSortBy(resp.getAttribute(MailConstants.A_SORTBY));
            callback.setQueryOffset((int) resp.getAttributeLong(MailConstants.A_QUERY_OFFSET));
        }
    } catch (SoapFaultException e) {
        GalSearchResultCallback callback = mParams.getResultCallback();
        if (callback.passThruProxiedGalAcctResponse()) {
            Element fault = e.getFault();
            callback.handleProxiedResponse(fault);
            // return true so we do *not* fallback to do the ldap search.
            return true;
        } else {
            ZimbraLog.gal.warn("remote search on GalSync account failed for " + galSyncAcct.getName(), e);
            return false;
        }
    }
    return true;
}
Also used : ZimbraSoapContext(com.zimbra.soap.ZimbraSoapContext) Element(com.zimbra.common.soap.Element) AuthToken(com.zimbra.cs.account.AuthToken) SoapHttpTransport(com.zimbra.common.soap.SoapHttpTransport) Provisioning(com.zimbra.cs.account.Provisioning) SoapFaultException(com.zimbra.common.soap.SoapFaultException)

Aggregations

SoapHttpTransport (com.zimbra.common.soap.SoapHttpTransport)69 Element (com.zimbra.common.soap.Element)54 Test (org.junit.Test)32 SoapFaultException (com.zimbra.common.soap.SoapFaultException)16 ServiceException (com.zimbra.common.service.ServiceException)13 Account (com.zimbra.cs.account.Account)13 DeployZimletRequest (com.zimbra.soap.admin.message.DeployZimletRequest)13 AuthRequest (com.zimbra.soap.account.message.AuthRequest)12 AttachmentIdAttrib (com.zimbra.soap.admin.type.AttachmentIdAttrib)12 XMLElement (com.zimbra.common.soap.Element.XMLElement)11 AuthToken (com.zimbra.cs.account.AuthToken)10 ZAuthToken (com.zimbra.common.auth.ZAuthToken)8 AuthResponse (com.zimbra.soap.account.message.AuthResponse)8 IOException (java.io.IOException)8 ZMailbox (com.zimbra.client.ZMailbox)7 ZimbraAuthToken (com.zimbra.cs.account.ZimbraAuthToken)6 AccountSelector (com.zimbra.soap.type.AccountSelector)6 HashMap (java.util.HashMap)5 Domain (com.zimbra.cs.account.Domain)4 Server (com.zimbra.cs.account.Server)4