Search in sources :

Example 1 with SessionInfo

use of com.zimbra.soap.ZimbraSoapContext.SessionInfo 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 2 with SessionInfo

use of com.zimbra.soap.ZimbraSoapContext.SessionInfo 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)

Aggregations

ServiceException (com.zimbra.common.service.ServiceException)2 AccountServiceException (com.zimbra.cs.account.AccountServiceException)2 Session (com.zimbra.cs.session.Session)2 SoapSession (com.zimbra.cs.session.SoapSession)2 SessionInfo (com.zimbra.soap.ZimbraSoapContext.SessionInfo)2 Element (com.zimbra.common.soap.Element)1 AuthFailedServiceException (com.zimbra.cs.account.AccountServiceException.AuthFailedServiceException)1 Mailbox (com.zimbra.cs.mailbox.Mailbox)1 AdminSession (com.zimbra.cs.session.AdminSession)1