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><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;
}
use of com.zimbra.soap.ZimbraSoapContext.SessionInfo in project zm-mailbox by Zimbra.
the class SoapEngine method generateResponseHeader.
/** Creates a <tt><context></tt> element for the SOAP Header containing
* session information and change notifications.<p>
*
* Sessions -- those passed in the SOAP request <tt><context></tt>
* block and those created during the course of processing the request -- are
* listed:<p>
* <tt><sessionId [type="admin"] id="12">12</sessionId></tt>
*
* @return A new <tt><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;
}
}
Aggregations