Search in sources :

Example 1 with SoapSession

use of com.zimbra.cs.session.SoapSession in project zm-mailbox by Zimbra.

the class ZimbraSoapContext method beginWaitForNotifications.

public boolean beginWaitForNotifications(Continuation continuation, boolean includeDelegates) throws ServiceException {
    mWaitForNotifications = true;
    continuationResume = new ResumeContinuationListener(continuation);
    Session session = SessionCache.lookup(mSessionInfo.sessionId, mAuthTokenAccountId);
    if (!(session instanceof SoapSession))
        return false;
    SoapSession ss = (SoapSession) session;
    SoapSession.RegisterNotificationResult result = ss.registerNotificationConnection(mSessionInfo.getPushChannel(!includeDelegates));
    switch(result) {
        case NO_NOTIFY:
            return false;
        case DATA_READY:
            return false;
        case BLOCKING:
            return true;
        default:
            return false;
    }
}
Also used : SoapSession(com.zimbra.cs.session.SoapSession) ResumeContinuationListener(com.zimbra.cs.servlet.continuation.ResumeContinuationListener) SoapSession(com.zimbra.cs.session.SoapSession) Session(com.zimbra.cs.session.Session)

Example 2 with SoapSession

use of com.zimbra.cs.session.SoapSession in project zm-mailbox by Zimbra.

the class DocumentHandler method getSession.

/** Fetches a {@link Session} object to persist and manage state between
     *  SOAP requests.  If no appropriate session already exists, a new one
     *  is created if possible.
     *
     * @param zsc The encapsulation of the SOAP request's <tt>&lt;context</tt>
     *            element.
     * @param stype  The type of session needed.
     * @return An in-memory {@link Session} object of the specified type,
     *         referenced by the request's {@link ZimbraSoapContext} object,
     *         or <tt>null</tt>.
     * @see SessionCache#SESSION_SOAP
     * @see SessionCache#SESSION_ADMIN */
protected Session getSession(ZimbraSoapContext zsc, Session.Type stype) {
    if (zsc == null || stype == null || !zsc.isNotificationEnabled()) {
        return null;
    }
    String authAccountId = zsc.getAuthtokenAccountId();
    if (authAccountId == null) {
        return null;
    }
    // if they asked for a SOAP session on a remote host and it's a non-proxied request, we don't notify
    boolean isLocal = zsc.isAuthUserOnLocalhost();
    if (stype == Session.Type.SOAP && !isLocal && !zsc.isSessionProxied()) {
        return null;
    }
    Session s = null;
    // if the caller referenced a session of this type, fetch it from the session cache
    SessionInfo sinfo = zsc.getSessionInfo();
    if (sinfo != null) {
        s = SessionCache.lookup(sinfo.sessionId, authAccountId);
        if (s == null) {
            // purge dangling references from the context's list of referenced sessions
            ZimbraLog.session.info("requested session no longer exists: " + sinfo.sessionId);
            zsc.clearSessionInfo();
        } else if (s.getSessionType() != stype) {
            // only want a session of the appropriate type
            s = null;
        }
    }
    // if there's no valid referenced session, create a new session of the requested type
    if (s == null) {
        try {
            if (stype == Session.Type.SOAP) {
                s = SoapSessionFactory.getInstance().getSoapSession(zsc).register();
            } else if (stype == Session.Type.ADMIN) {
                s = new AdminSession(authAccountId).register();
            }
        } catch (ServiceException e) {
            ZimbraLog.session.info("exception while creating session", e);
        }
        if (s != null) {
            zsc.recordNewSession(s.getSessionId());
        }
    }
    //   (note that if the requested account is remote, getDelegateSession returns null)
    if (s instanceof SoapSession && zsc.isDelegatedRequest()) {
        Session delegate = ((SoapSession) s).getDelegateSession(zsc.getRequestedAccountId());
        if (delegate != null) {
            s = delegate;
        }
    }
    return s;
}
Also used : SoapSession(com.zimbra.cs.session.SoapSession) AccountServiceException(com.zimbra.cs.account.AccountServiceException) ServiceException(com.zimbra.common.service.ServiceException) AdminSession(com.zimbra.cs.session.AdminSession) SessionInfo(com.zimbra.soap.ZimbraSoapContext.SessionInfo) AdminSession(com.zimbra.cs.session.AdminSession) SoapSession(com.zimbra.cs.session.SoapSession) Session(com.zimbra.cs.session.Session)

Example 3 with SoapSession

use of com.zimbra.cs.session.SoapSession in project zm-mailbox by Zimbra.

the class GetInfo method handle.

@Override
public Element handle(Element request, Map<String, Object> context) throws ServiceException {
    ZimbraSoapContext zsc = getZimbraSoapContext(context);
    Account account = getRequestedAccount(zsc);
    if (!canAccessAccount(zsc, account)) {
        throw ServiceException.PERM_DENIED("can not access account");
    }
    // figure out the subset of data the caller wants (default to all data)
    String secstr = request.getAttribute(AccountConstants.A_SECTIONS, null);
    Set<Section> sections;
    if (secstr != null) {
        sections = EnumSet.noneOf(Section.class);
        for (String sec : Splitter.on(',').omitEmptyStrings().trimResults().split(secstr)) {
            sections.add(Section.lookup(sec));
        }
    } else {
        sections = EnumSet.allOf(Section.class);
    }
    String rightsStr = request.getAttribute(AccountConstants.A_RIGHTS, null);
    Set<Right> rights = null;
    if (rightsStr != null) {
        RightManager rightMgr = RightManager.getInstance();
        rights = Sets.newHashSet();
        for (String right : Splitter.on(',').omitEmptyStrings().trimResults().split(rightsStr)) {
            rights.add(rightMgr.getUserRight(right));
        }
    }
    Element response = zsc.createElement(AccountConstants.GET_INFO_RESPONSE);
    response.addAttribute(AccountConstants.E_VERSION, BuildInfo.FULL_VERSION, Element.Disposition.CONTENT);
    response.addAttribute(AccountConstants.E_ID, account.getId(), Element.Disposition.CONTENT);
    response.addAttribute(AccountConstants.E_NAME, account.getUnicodeName(), Element.Disposition.CONTENT);
    try {
        response.addAttribute(AccountConstants.E_CRUMB, zsc.getAuthToken().getCrumb(), Element.Disposition.CONTENT);
    } catch (AuthTokenException e) {
        // shouldn't happen
        ZimbraLog.account.warn("can't generate crumb", e);
    }
    long lifetime = zsc.getAuthToken().getExpires() - System.currentTimeMillis();
    response.addAttribute(AccountConstants.E_LIFETIME, lifetime, Element.Disposition.CONTENT);
    Provisioning prov = Provisioning.getInstance();
    // bug 53770, return if the request is using a delegated authtoken issued to an admin account
    AuthToken authToken = zsc.getAuthToken();
    if (authToken.isDelegatedAuth()) {
        Account admin = prov.get(AccountBy.id, authToken.getAdminAccountId());
        if (admin != null) {
            boolean isAdmin = AdminAccessControl.isAdequateAdminAccount(admin);
            if (isAdmin) {
                response.addAttribute(AccountConstants.E_ADMIN_DELEGATED, true, Element.Disposition.CONTENT);
            }
        }
    }
    try {
        Server server = prov.getLocalServer();
        if (server != null) {
            response.addAttribute(AccountConstants.A_DOCUMENT_SIZE_LIMIT, server.getFileUploadMaxSize());
        }
        Config config = prov.getConfig();
        if (config != null) {
            long maxAttachSize = config.getMtaMaxMessageSize();
            if (maxAttachSize == 0) {
                maxAttachSize = -1;
            /* means unlimited */
            }
            response.addAttribute(AccountConstants.A_ATTACHMENT_SIZE_LIMIT, maxAttachSize);
        }
    } catch (ServiceException e) {
    }
    if (sections.contains(Section.MBOX) && Provisioning.onLocalServer(account)) {
        response.addAttribute(AccountConstants.E_REST, UserServlet.getRestUrl(account), Element.Disposition.CONTENT);
        try {
            Mailbox mbox = getRequestedMailbox(zsc);
            response.addAttribute(AccountConstants.E_QUOTA_USED, mbox.getSize(), Element.Disposition.CONTENT);
            Session s = (Session) context.get(SoapEngine.ZIMBRA_SESSION);
            if (s instanceof SoapSession) {
                // we have a valid session; get the stats on this session
                response.addAttribute(AccountConstants.E_PREVIOUS_SESSION, ((SoapSession) s).getPreviousSessionTime(), Element.Disposition.CONTENT);
                response.addAttribute(AccountConstants.E_LAST_ACCESS, ((SoapSession) s).getLastWriteAccessTime(), Element.Disposition.CONTENT);
                response.addAttribute(AccountConstants.E_RECENT_MSGS, ((SoapSession) s).getRecentMessageCount(), Element.Disposition.CONTENT);
            } else {
                // we have no session; calculate the stats from the mailbox and the other SOAP sessions
                long lastAccess = mbox.getLastSoapAccessTime();
                response.addAttribute(AccountConstants.E_PREVIOUS_SESSION, lastAccess, Element.Disposition.CONTENT);
                response.addAttribute(AccountConstants.E_LAST_ACCESS, lastAccess, Element.Disposition.CONTENT);
                response.addAttribute(AccountConstants.E_RECENT_MSGS, mbox.getRecentMessageCount(), Element.Disposition.CONTENT);
            }
        } catch (ServiceException e) {
        }
    }
    doCos(account, response);
    Map<String, Object> attrMap = account.getUnicodeAttrs();
    Locale locale = Provisioning.getInstance().getLocale(account);
    if (sections.contains(Section.PREFS)) {
        Element prefs = response.addUniqueElement(AccountConstants.E_PREFS);
        GetPrefs.doPrefs(account, prefs, attrMap, null);
    }
    if (sections.contains(Section.ATTRS)) {
        Element attrs = response.addUniqueElement(AccountConstants.E_ATTRS);
        doAttrs(account, locale.toString(), attrs, attrMap);
    }
    if (sections.contains(Section.ZIMLETS)) {
        Element zimlets = response.addUniqueElement(AccountConstants.E_ZIMLETS);
        doZimlets(zimlets, account);
    }
    if (sections.contains(Section.PROPS)) {
        Element props = response.addUniqueElement(AccountConstants.E_PROPERTIES);
        doProperties(props, account);
    }
    if (sections.contains(Section.IDENTS)) {
        Element ids = response.addUniqueElement(AccountConstants.E_IDENTITIES);
        doIdentities(ids, account);
    }
    if (sections.contains(Section.SIGS)) {
        Element sigs = response.addUniqueElement(AccountConstants.E_SIGNATURES);
        doSignatures(sigs, account);
    }
    if (sections.contains(Section.DSRCS)) {
        Element ds = response.addUniqueElement(AccountConstants.E_DATA_SOURCES);
        doDataSources(ds, account);
    }
    if (sections.contains(Section.CHILDREN)) {
        Element ca = response.addUniqueElement(AccountConstants.E_CHILD_ACCOUNTS);
        doChildAccounts(ca, account, zsc.getAuthToken());
    }
    if (rights != null && !rights.isEmpty()) {
        Element eRights = response.addUniqueElement(AccountConstants.E_RIGHTS);
        doDiscoverRights(eRights, account, rights);
    }
    GetAccountInfo.addUrls(response, account);
    for (GetInfoExt extension : extensions) {
        extension.handle(zsc, response);
    }
    return response;
}
Also used : Locale(java.util.Locale) Account(com.zimbra.cs.account.Account) Server(com.zimbra.cs.account.Server) RightManager(com.zimbra.cs.account.accesscontrol.RightManager) Config(com.zimbra.cs.account.Config) Element(com.zimbra.common.soap.Element) Right(com.zimbra.cs.account.accesscontrol.Right) Provisioning(com.zimbra.cs.account.Provisioning) SoapSession(com.zimbra.cs.session.SoapSession) ServiceException(com.zimbra.common.service.ServiceException) Mailbox(com.zimbra.cs.mailbox.Mailbox) ZimbraSoapContext(com.zimbra.soap.ZimbraSoapContext) AuthTokenException(com.zimbra.cs.account.AuthTokenException) AuthToken(com.zimbra.cs.account.AuthToken) SoapSession(com.zimbra.cs.session.SoapSession) Session(com.zimbra.cs.session.Session)

Example 4 with SoapSession

use of com.zimbra.cs.session.SoapSession in project zm-mailbox by Zimbra.

the class SoapEngine method generateResponseHeader.

/** Creates a <tt>&lt;context></tt> element for the SOAP Header containing
     *  session information and change notifications.<p>
     *
     *  Sessions -- those passed in the SOAP request <tt>&lt;context></tt>
     *  block and those created during the course of processing the request -- are
     *  listed:<p>
     *     <tt>&lt;sessionId [type="admin"] id="12">12&lt;/sessionId></tt>
     *
     * @return A new <tt>&lt;context></tt> {@link Element}, or <tt>null</tt>
     *         if there is no relevant information to encapsulate. */
private Element generateResponseHeader(ZimbraSoapContext zsc) {
    String authAccountId = zsc.getAuthtokenAccountId();
    String requestedAccountId = zsc.getRequestedAccountId();
    Element ctxt = zsc.createElement(HeaderConstants.CONTEXT);
    boolean requiresChangeHeader = requestedAccountId != null;
    try {
        SessionInfo sinfo = zsc.getSessionInfo();
        Session session = sinfo == null ? null : SessionCache.lookup(sinfo.sessionId, authAccountId);
        if (session != null) {
            // session ID is valid, so ping it back to the client:
            ZimbraSoapContext.encodeSession(ctxt, session.getSessionId(), session.getSessionType());
            if (session instanceof SoapSession) {
                SoapSession soap = (SoapSession) session;
                if (session.getTargetAccountId().equals(requestedAccountId)) {
                    requiresChangeHeader = false;
                }
                // put <refresh> blocks back for any newly-created SoapSession objects
                if (sinfo.created || soap.requiresRefresh(sinfo.sequence)) {
                    ZimbraLog.session.debug("returning refresh block; reason=%s", sinfo.created ? "new session" : "sequence-based");
                    soap.putRefresh(ctxt, zsc);
                }
                // put <notify> blocks back for any SoapSession objects
                soap.putNotifications(ctxt, zsc, sinfo.sequence);
                // add any extension headers
                SoapContextExtension.addExtensionHeaders(ctxt, zsc, soap);
            }
        }
        // so encode it here as a last resort
        if (requiresChangeHeader) {
            try {
                String explicitAcct = requestedAccountId.equals(authAccountId) ? null : requestedAccountId;
                // send the <change> block
                // <change token="555" [acct="4f778920-1a84-11da-b804-6b188d2a20c4"]/>
                Mailbox mbox = DocumentHandler.getRequestedMailbox(zsc, false);
                if (mbox != null) {
                    ctxt.addUniqueElement(HeaderConstants.E_CHANGE).addAttribute(HeaderConstants.A_CHANGE_ID, mbox.getLastChangeID()).addAttribute(HeaderConstants.A_ACCOUNT_ID, explicitAcct);
                }
            } catch (ServiceException e) {
            // eat error for right now
            }
        }
        return ctxt;
    } catch (ServiceException e) {
        ZimbraLog.session.info("ServiceException while putting soap session refresh data", e);
        return null;
    }
}
Also used : SoapSession(com.zimbra.cs.session.SoapSession) Mailbox(com.zimbra.cs.mailbox.Mailbox) AccountServiceException(com.zimbra.cs.account.AccountServiceException) ServiceException(com.zimbra.common.service.ServiceException) AuthFailedServiceException(com.zimbra.cs.account.AccountServiceException.AuthFailedServiceException) Element(com.zimbra.common.soap.Element) SessionInfo(com.zimbra.soap.ZimbraSoapContext.SessionInfo) SoapSession(com.zimbra.cs.session.SoapSession) Session(com.zimbra.cs.session.Session)

Example 5 with SoapSession

use of com.zimbra.cs.session.SoapSession in project zm-mailbox by Zimbra.

the class CrossServerNotification method getHandler.

@Override
public MessageHandler getHandler() {
    return new MessageHandler() {

        @Override
        public void handle(Message m, String clientId) {
            if (!(m instanceof CrossServerNotification)) {
                return;
            }
            CrossServerNotification message = (CrossServerNotification) m;
            Collection<Session> sessions = SessionCache.getSoapSessions(m.getRecipientAccountId());
            if (sessions == null) {
                log.warn("no active sessions for account %s", m.getRecipientAccountId());
                return;
            }
            RemoteNotifications soapNtfn = null, jsonNtfn = null;
            try {
                org.dom4j.Document dom = org.dom4j.DocumentHelper.parseText(message.getPayload());
                soapNtfn = new RemoteNotifications(Element.convertDOM(dom.getRootElement(), XMLElement.mFactory));
                jsonNtfn = new RemoteNotifications(Element.convertDOM(dom.getRootElement(), JSONElement.mFactory));
            } catch (DocumentException e) {
                log.warn("cannot parse notification from %s", clientId, e);
                return;
            }
            for (Session session : sessions) {
                log.debug("notifying session %s", session.toString());
                SoapSession ss = (SoapSession) session;
                SoapProtocol responseProtocol = ss.getResponseProtocol();
                if (responseProtocol == SoapProtocol.Soap11 || responseProtocol == SoapProtocol.Soap12) {
                    ss.addRemoteNotifications(soapNtfn);
                } else if (responseProtocol == SoapProtocol.SoapJS) {
                    ss.addRemoteNotifications(jsonNtfn);
                }
                ss.forcePush();
            }
        }
    };
}
Also used : SoapSession(com.zimbra.cs.session.SoapSession) RemoteNotifications(com.zimbra.cs.session.SoapSession.RemoteNotifications) DocumentException(org.dom4j.DocumentException) SoapProtocol(com.zimbra.common.soap.SoapProtocol) SoapSession(com.zimbra.cs.session.SoapSession) Session(com.zimbra.cs.session.Session)

Aggregations

SoapSession (com.zimbra.cs.session.SoapSession)8 Session (com.zimbra.cs.session.Session)7 ServiceException (com.zimbra.common.service.ServiceException)4 Element (com.zimbra.common.soap.Element)3 Mailbox (com.zimbra.cs.mailbox.Mailbox)3 ZFolder (com.zimbra.client.ZFolder)2 Account (com.zimbra.cs.account.Account)2 AccountServiceException (com.zimbra.cs.account.AccountServiceException)2 AuthToken (com.zimbra.cs.account.AuthToken)2 Server (com.zimbra.cs.account.Server)2 TargetConstraint (com.zimbra.cs.mailbox.MailItem.TargetConstraint)2 SessionInfo (com.zimbra.soap.ZimbraSoapContext.SessionInfo)2 ZMailbox (com.zimbra.client.ZMailbox)1 ZMountpoint (com.zimbra.client.ZMountpoint)1 ZAuthToken (com.zimbra.common.auth.ZAuthToken)1 SoapProtocol (com.zimbra.common.soap.SoapProtocol)1 AuthFailedServiceException (com.zimbra.cs.account.AccountServiceException.AuthFailedServiceException)1 AuthTokenException (com.zimbra.cs.account.AuthTokenException)1 Config (com.zimbra.cs.account.Config)1 Provisioning (com.zimbra.cs.account.Provisioning)1