Search in sources :

Example 16 with Session

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

the class DocumentHandler method updateAuthenticatedAccount.

/** Updates the {@link ZimbraSoapContext} to treat the specified account
     *  as the request's authenticated account.  If the new account differs
     *  from the previously authenticated account, we forget about all other
     *  {@link Session}s.  (Those sessions are not deleted from the cache,
     *  though perhaps that's the right thing to do...)  If requested, also
     *  creates a new Session object associated with the given account.
     *
     * @param zsc         The parsed SOAP header for the auth request.
     * @param authToken   The new auth token created for the user.
     * @param context     The <code>SoapEngine</code>'s request state.
     * @param getSession  Whether to try to generate a new Session.
     * @return A new Session object of the appropriate type, or <tt>null</tt>. */
public Session updateAuthenticatedAccount(ZimbraSoapContext zsc, AuthToken authToken, Map<String, Object> context, boolean getSession) {
    String oldAccountId = zsc.getAuthtokenAccountId();
    String accountId = authToken.getAccountId();
    if (accountId != null && !accountId.equals(oldAccountId)) {
        zsc.clearSessionInfo();
    }
    zsc.setAuthToken(authToken);
    Session session = (getSession ? getSession(zsc) : null);
    if (context != null) {
        context.put(SoapEngine.ZIMBRA_SESSION, session);
    }
    return session;
}
Also used : AdminSession(com.zimbra.cs.session.AdminSession) SoapSession(com.zimbra.cs.session.SoapSession) Session(com.zimbra.cs.session.Session)

Example 17 with Session

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

the class GetSessions method getResult.

public CachedResult getResult(AdminSession adminSession, Type type, boolean refresh, final SortBy sortBy) {
    List<Session> sessions = SessionCache.getActiveSessions(type);
    CachedResult result = (adminSession == null || refresh) ? null : (CachedResult) adminSession.getData(SESSION_KEY);
    if (result != null && result.type == type && result.sortBy == sortBy)
        return result;
    Provisioning prov = Provisioning.getInstance();
    result = new CachedResult();
    result.type = type;
    result.sortBy = sortBy;
    result.sessions = new ArrayList<SessionInfo>(sessions.size());
    for (Session s : sessions) {
        result.sessions.add(new SessionInfo(s, getName(prov, s.getAuthenticatedAccountId())));
    }
    // SORT
    Comparator<SessionInfo> comparator = new Comparator<SessionInfo>() {

        public int compare(SessionInfo a, SessionInfo b) {
            long diff;
            switch(sortBy) {
                case nameAsc:
                    return a.getAccountName().compareToIgnoreCase(b.getAccountName());
                case nameDesc:
                    return -a.getAccountName().compareToIgnoreCase(b.getAccountName());
                case accessedAsc:
                    diff = a.getAccessed() - b.getAccessed();
                    return diff == 0 ? 0 : diff > 0 ? 1 : -1;
                case accessedDesc:
                    diff = a.getAccessed() - b.getAccessed();
                    return diff == 0 ? 0 : diff > 0 ? -1 : 1;
                case createdAsc:
                    diff = a.getAccessed() - b.getAccessed();
                    return diff == 0 ? 0 : diff > 0 ? 1 : -1;
                case createdDesc:
                    diff = a.getAccessed() - b.getAccessed();
                    return diff == 0 ? 0 : diff > 0 ? -1 : 1;
                default:
                    return 0;
            }
        }
    };
    Collections.sort(result.sessions, comparator);
    if (adminSession != null)
        adminSession.setData(SESSION_KEY, result);
    return result;
}
Also used : Provisioning(com.zimbra.cs.account.Provisioning) AdminSession(com.zimbra.cs.session.AdminSession) Session(com.zimbra.cs.session.Session) Comparator(java.util.Comparator)

Example 18 with Session

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

the class ItemAction method forceRemoteSession.

private Account forceRemoteSession(ZimbraSoapContext zsc, Map<String, Object> context, OperationContext octxt, String op, Element action) throws ServiceException {
    // only proxying notification from the user's home-server master session
    if (!zsc.isNotificationEnabled()) {
        return null;
    }
    Session session = (Session) context.get(SoapEngine.ZIMBRA_SESSION);
    if (session instanceof SoapSession.DelegateSession) {
        session = ((SoapSession.DelegateSession) session).getParentSession();
    }
    if (!(session instanceof SoapSession) || session.getMailbox() == null) {
        return null;
    }
    SoapSession ss = (SoapSession) session;
    // only have to worry about operations where things can get created in other mailboxes (regular notification works for all other cases)
    if (!op.equals(OP_MOVE) && !op.equals(OP_COPY) && !op.equals(OP_SPAM) && !op.equals(OP_RENAME) && !op.equals(OP_UPDATE)) {
        return null;
    }
    String folderStr = action.getAttribute(MailConstants.A_FOLDER, null);
    if (folderStr == null) {
        return null;
    }
    // recursively dereference mountpoints to find ultimate target folder
    ItemId iidFolder = new ItemId(folderStr, zsc), iidRequested = iidFolder;
    Account owner = null;
    int hopCount = 0;
    ZAuthToken zat = null;
    while (hopCount < ZimbraSoapContext.MAX_HOP_COUNT) {
        owner = Provisioning.getInstance().getAccountById(iidFolder.getAccountId());
        if (Provisioning.onLocalServer(owner)) {
            try {
                Mailbox mbox = MailboxManager.getInstance().getMailboxByAccount(owner);
                Folder folder = mbox.getFolderById(octxt, iidFolder.getId());
                if (!(folder instanceof Mountpoint))
                    break;
                iidFolder = ((Mountpoint) folder).getTarget();
            } catch (ServiceException e) {
                // could be a PERM_DENIED, could be something else -- this is not the right place to fail, however
                break;
            }
        } else {
            if (zat == null) {
                AuthToken at = AuthToken.getCsrfUnsecuredAuthToken(zsc.getAuthToken());
                String pxyAuthToken = at.getProxyAuthToken();
                zat = pxyAuthToken == null ? at.toZAuthToken() : new ZAuthToken(pxyAuthToken);
            }
            ZMailbox.Options zoptions = new ZMailbox.Options(zat, AccountUtil.getSoapUri(owner));
            zoptions.setNoSession(true);
            zoptions.setTargetAccount(owner.getId());
            zoptions.setTargetAccountBy(Key.AccountBy.id);
            ZMailbox zmbx = ZMailbox.getMailbox(zoptions);
            ZFolder zfolder = zmbx.getFolderById(iidFolder.toString(zsc.getAuthtokenAccountId()));
            if (!(zfolder instanceof ZMountpoint))
                break;
            iidFolder = new ItemId(((ZMountpoint) zfolder).getCanonicalRemoteId(), zsc.getAuthtokenAccountId());
        }
        hopCount++;
    }
    if (hopCount >= ZimbraSoapContext.MAX_HOP_COUNT) {
        throw MailServiceException.TOO_MANY_HOPS(iidRequested);
    }
    // avoid dereferencing the mountpoint again later on
    action.addAttribute(MailConstants.A_FOLDER, iidFolder.toString());
    // fault in a session to listen in on the target folder's mailbox
    if (iidFolder.belongsTo(session.getAuthenticatedAccountId())) {
        return null;
    } else if (iidFolder.isLocal()) {
        ss.getDelegateSession(iidFolder.getAccountId());
        return null;
    } else {
        try {
            proxyRequest(zsc.createElement(MailConstants.NO_OP_REQUEST), context, owner.getId());
            return owner;
        } catch (ServiceException e) {
            return null;
        }
    }
}
Also used : ZMountpoint(com.zimbra.client.ZMountpoint) Account(com.zimbra.cs.account.Account) ImapFolder(com.zimbra.cs.datasource.imap.ImapFolder) ZFolder(com.zimbra.client.ZFolder) Folder(com.zimbra.cs.mailbox.Folder) ItemId(com.zimbra.cs.service.util.ItemId) ZAuthToken(com.zimbra.common.auth.ZAuthToken) TargetConstraint(com.zimbra.cs.mailbox.MailItem.TargetConstraint) ZMountpoint(com.zimbra.client.ZMountpoint) Mountpoint(com.zimbra.cs.mailbox.Mountpoint) SoapSession(com.zimbra.cs.session.SoapSession) ZMailbox(com.zimbra.client.ZMailbox) Mailbox(com.zimbra.cs.mailbox.Mailbox) ZMailbox(com.zimbra.client.ZMailbox) ServiceException(com.zimbra.common.service.ServiceException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) AuthToken(com.zimbra.cs.account.AuthToken) ZAuthToken(com.zimbra.common.auth.ZAuthToken) ZFolder(com.zimbra.client.ZFolder) ZMountpoint(com.zimbra.client.ZMountpoint) Mountpoint(com.zimbra.cs.mailbox.Mountpoint) SoapSession(com.zimbra.cs.session.SoapSession) Session(com.zimbra.cs.session.Session)

Example 19 with Session

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

the class ImapSessionManager method duplicateExistingSession.

private static List<ImapMessage> duplicateExistingSession(int folderId, List<Session> sessionList) {
    for (Session session : sessionList) {
        ImapSession i4listener = (ImapSession) session;
        if (i4listener.getFolderId() == folderId) {
            //   FIXME: may want to prefer loaded folders over paged-out folders
            synchronized (i4listener) {
                ImapFolder i4selected;
                try {
                    i4selected = i4listener.getImapFolder();
                } catch (ImapSessionClosedException e) {
                    return null;
                }
                if (i4selected == null) {
                    // cache miss
                    return null;
                }
                // found a matching session, so just copy its contents!
                ZimbraLog.imap.info("copying message data from existing session: %s", i4listener.getPath());
                final List<ImapMessage> i4list = new ArrayList<ImapMessage>(i4selected.getSize());
                i4selected.traverse(new Function<ImapMessage, Void>() {

                    @Override
                    public Void apply(ImapMessage i4msg) {
                        if (!i4msg.isExpunged()) {
                            i4list.add(new ImapMessage(i4msg));
                        }
                        return null;
                    }
                });
                // XXX: watch out for deadlock between this and the SessionCache
                if (!i4listener.isInteractive()) {
                    i4listener.unregister();
                }
                return i4list;
            }
        }
    }
    return null;
}
Also used : ArrayList(java.util.ArrayList) Session(com.zimbra.cs.session.Session)

Example 20 with Session

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

the class ImapSessionManager method openFolder.

Pair<ImapSession, InitialFolderValues> openFolder(ImapPath path, byte params, ImapHandler handler) throws ServiceException {
    ZimbraLog.imap.debug("opening folder: %s", path);
    if (!path.isSelectable()) {
        throw ServiceException.PERM_DENIED("cannot select folder: " + path);
    }
    if ((params & ImapFolder.SELECT_CONDSTORE) != 0) {
        handler.activateExtension(ImapExtension.CONDSTORE);
    }
    Folder folder = (Folder) path.getFolder();
    int folderId = folder.getId();
    Mailbox mbox = folder.getMailbox();
    // don't have a session when the folder is loaded...
    OperationContext octxt = handler.getCredentials().getContext();
    mbox.beginTrackingImap();
    List<ImapMessage> i4list = null;
    // *always* recalculate the contents of search folders
    if (folder instanceof SearchFolder) {
        i4list = loadVirtualFolder(octxt, (SearchFolder) folder);
    }
    mbox.lock.lock();
    try {
        // need mInitialRecent to be set *before* loading the folder so we can determine what's \Recent
        folder = mbox.getFolderById(octxt, folderId);
        int recentCutoff = folder.getImapRECENTCutoff();
        if (i4list == null) {
            List<Session> listeners = mbox.getListeners(Session.Type.IMAP);
            // first option is to duplicate an existing registered session
            //   (could try to just activate an inactive session, but this logic is simpler for now)
            i4list = duplicateExistingSession(folderId, listeners);
            // no matching session means we next check for serialized folder data
            if (i4list == null) {
                i4list = duplicateSerializedFolder(folder);
            } else if (CONSISTENCY_CHECK) {
                Collections.sort(i4list);
            //sort only if using list from duplicated session which may be out of order
            //if loaded from serialized folder order _should_ already be OK since no changes have occurred
            }
            // do the consistency check, if requested
            if (CONSISTENCY_CHECK) {
                i4list = consistencyCheck(i4list, mbox, octxt, folder);
            }
            // no matching serialized session means we have to go to the DB to get the messages
            if (i4list == null) {
                i4list = mbox.openImapFolder(octxt, folderId);
            }
        }
        Collections.sort(i4list);
        // check messages for imapUid <= 0 and assign new IMAP IDs if necessary
        renumberMessages(octxt, mbox, i4list);
        ImapFolder i4folder = new ImapFolder(path, params, handler);
        // don't rely on the <code>Folder</code> object being updated in place
        folder = mbox.getFolderById(octxt, folderId);
        // can't set these until *after* loading the folder because UID renumbering affects them
        InitialFolderValues initial = new InitialFolderValues(folder);
        for (ImapMessage i4msg : i4list) {
            i4folder.cache(i4msg, i4msg.imapUid > recentCutoff);
            if (initial.firstUnread == -1 && (i4msg.flags & Flag.BITMASK_UNREAD) != 0) {
                initial.firstUnread = i4msg.sequence;
            }
        }
        i4folder.setInitialSize();
        ZimbraLog.imap.debug("Folder with id=%s added message list %s", folderId, i4list);
        ImapSession session = null;
        try {
            session = new ImapSession(i4folder, handler);
            session.register();
            sessions.put(session, session);
            return new Pair<ImapSession, InitialFolderValues>(session, initial);
        } catch (ServiceException e) {
            if (session != null) {
                session.unregister();
            }
            throw e;
        }
    } finally {
        mbox.lock.release();
    }
}
Also used : OperationContext(com.zimbra.cs.mailbox.OperationContext) SearchFolder(com.zimbra.cs.mailbox.SearchFolder) SearchFolder(com.zimbra.cs.mailbox.SearchFolder) Folder(com.zimbra.cs.mailbox.Folder) Mailbox(com.zimbra.cs.mailbox.Mailbox) ServiceException(com.zimbra.common.service.ServiceException) Session(com.zimbra.cs.session.Session) Pair(com.zimbra.common.util.Pair)

Aggregations

Session (com.zimbra.cs.session.Session)21 SoapSession (com.zimbra.cs.session.SoapSession)11 ServiceException (com.zimbra.common.service.ServiceException)9 Element (com.zimbra.common.soap.Element)7 Mailbox (com.zimbra.cs.mailbox.Mailbox)5 AccountServiceException (com.zimbra.cs.account.AccountServiceException)4 Server (com.zimbra.cs.account.Server)4 AdminSession (com.zimbra.cs.session.AdminSession)4 AuthToken (com.zimbra.cs.account.AuthToken)3 Provisioning (com.zimbra.cs.account.Provisioning)3 DbSession (com.zimbra.cs.db.DbSession)3 ZFolder (com.zimbra.client.ZFolder)2 Account (com.zimbra.cs.account.Account)2 AuthTokenException (com.zimbra.cs.account.AuthTokenException)2 Folder (com.zimbra.cs.mailbox.Folder)2 TargetConstraint (com.zimbra.cs.mailbox.MailItem.TargetConstraint)2 ZimbraSoapContext (com.zimbra.soap.ZimbraSoapContext)2 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 HttpServletRequest (javax.servlet.http.HttpServletRequest)2