public Element handle(Element request, Map<String, Object> context) throws ServiceException {

    ZimbraSoapContext zsc = getZimbraSoapContext(context);
    Provisioning prov = Provisioning.getInstance();

    String id = request.getAttribute(AdminConstants.E_ID);

    DistributionList distributionList = prov.get(DistributionListBy.id, id);
    if (distributionList == null) throw AccountServiceException.NO_SUCH_DISTRIBUTION_LIST(id);

    checkDistributionListRight(zsc, distributionList, Admin.R_deleteDistributionList);

    prov.deleteDistributionList(distributionList.getId());

    ZimbraLog.security.info(
        ZimbraLog.encodeAttrs(
            new String[] {
              "cmd",
              "DeleteDistributionList",
              "name",
              distributionList.getName(),
              "id",
              distributionList.getId()
            }));

    Element response = zsc.createElement(AdminConstants.DELETE_DISTRIBUTION_LIST_RESPONSE);
    return response;
  }
Exemple #2
0
  public Element handle(Element request, Map<String, Object> context) throws ServiceException {

    ZimbraSoapContext zsc = getZimbraSoapContext(context);
    Provisioning prov = Provisioning.getInstance();

    String id = request.getAttribute(AdminConstants.E_ID);

    Domain domain = prov.get(DomainBy.id, id);
    if (domain == null) throw AccountServiceException.NO_SUCH_DOMAIN(id);

    if (domain.isShutdown())
      throw ServiceException.PERM_DENIED(
          "can not access domain, domain is in " + domain.getDomainStatusAsString() + " status");

    checkRight(zsc, context, domain, Admin.R_deleteDomain);

    String name = domain.getName();

    prov.deleteDomain(id);

    ZimbraLog.security.info(
        ZimbraLog.encodeAttrs(new String[] {"cmd", "DeleteDomain", "name", name, "id", id}));

    Element response = zsc.createElement(AdminConstants.DELETE_DOMAIN_RESPONSE);
    return response;
  }
  @Override
  public Element handle(Element request, Map<String, Object> context) throws ServiceException {
    ZimbraSoapContext zsc = getZimbraSoapContext(context);

    Element mreq = request.getElement(AdminConstants.E_MAILBOX);
    String accountId = mreq.getAttribute(AdminConstants.A_ACCOUNTID);

    Provisioning prov = Provisioning.getInstance();
    Account account = prov.get(AccountBy.id, accountId, zsc.getAuthToken());
    if (account == null) {
      throw AccountServiceException.NO_SUCH_ACCOUNT(accountId);
    }
    checkAdminLoginAsRight(zsc, prov, account);

    Mailbox mbox = MailboxManager.getInstance().getMailboxByAccount(account, false);
    if (mbox == null) {
      throw MailServiceException.NO_SUCH_MBOX(accountId);
    }

    mbox.recalculateFolderAndTagCounts();

    Element response = zsc.createElement(AdminConstants.RECALCULATE_MAILBOX_COUNTS_RESPONSE);
    response
        .addElement(AdminConstants.E_MAILBOX)
        .addAttribute(AdminConstants.A_ACCOUNTID, accountId)
        .addAttribute(AdminConstants.A_QUOTA_USED, mbox.getSize());
    return response;
  }
  @Override
  public Element handle(Element request, Map<String, Object> context) throws ServiceException {
    ZimbraSoapContext zsc = getZimbraSoapContext(context);
    Mailbox mbox = getRequestedMailbox(zsc);

    String browseBy = request.getAttribute(MailConstants.A_BROWSE_BY);
    BrowseBy parsedBrowseBy = BrowseBy.valueOf(browseBy.toLowerCase());
    String regex = request.getAttribute(MailConstants.A_REGEX, "").toLowerCase();
    int max = (int) (request.getAttributeLong(MailConstants.A_MAX_TO_RETURN, 0));

    List<BrowseTerm> terms;
    try {
      terms = mbox.browse(getOperationContext(zsc, context), parsedBrowseBy, regex, max);
    } catch (IOException e) {
      throw ServiceException.FAILURE("Failed to browse terms", e);
    }

    Element response = zsc.createElement(MailConstants.BROWSE_RESPONSE);

    for (BrowseTerm term : terms) {
      if (term instanceof DomainBrowseTerm) {
        DomainBrowseTerm domain = (DomainBrowseTerm) term;
        Element e = response.addElement(MailConstants.E_BROWSE_DATA).setText(domain.getText());
        String flags = domain.getHeaderFlags();
        if (!flags.isEmpty()) {
          e.addAttribute(MailConstants.A_BROWSE_DOMAIN_HEADER, flags);
        }
        e.addAttribute(MailConstants.A_FREQUENCY, domain.getFreq());
      } else {
        Element e = response.addElement(MailConstants.E_BROWSE_DATA).setText(term.getText());
        e.addAttribute(MailConstants.A_FREQUENCY, term.getFreq());
      }
    }
    return response;
  }
Exemple #5
0
  @Override
  public Element handle(Element request, Map<String, Object> context) throws ServiceException {
    ZimbraSoapContext zsc = getZimbraSoapContext(context);
    Mailbox mbox = getRequestedMailbox(zsc);
    OperationContext octxt = getOperationContext(zsc, context);
    ItemIdFormatter ifmt = new ItemIdFormatter(zsc);

    Element meta = request.getElement(MailConstants.E_METADATA);
    String section = meta.getAttribute(MailConstants.A_SECTION);
    section = section.trim();
    if (section.length() == 0 || section.length() > 36)
      throw ServiceException.INVALID_REQUEST(
          "invalid length for custom metadata section name", null);

    CustomMetadata custom = new CustomMetadata(section);
    for (Element.KeyValuePair kvp : meta.listKeyValuePairs())
      custom.put(kvp.getKey(), kvp.getValue());

    ItemId iid = new ItemId(request.getAttribute(MailConstants.A_ID), zsc);
    mbox.setCustomData(octxt, iid.getId(), MailItem.Type.UNKNOWN, custom);

    Element response = zsc.createElement(MailConstants.SET_METADATA_RESPONSE);
    response.addAttribute(MailConstants.A_ID, ifmt.formatItemId(iid));
    return response;
  }
Exemple #6
0
  public Element handle(Element request, Map<String, Object> context) throws ServiceException {

    ZimbraSoapContext zsc = getZimbraSoapContext(context);
    Provisioning prov = Provisioning.getInstance();

    boolean applyConfig = request.getAttributeBool(AdminConstants.A_APPLY_CONFIG, true);
    Set<String> reqAttrs = getReqAttrs(request, AttributeClass.server);

    Element d = request.getElement(AdminConstants.E_SERVER);
    String method = d.getAttribute(AdminConstants.A_BY);
    String name = d.getText();

    if (name == null || name.equals(""))
      throw ServiceException.INVALID_REQUEST("must specify a value for a server", null);

    Server server = prov.get(ServerBy.fromString(method), name);

    if (server == null) throw AccountServiceException.NO_SUCH_SERVER(name);

    AdminAccessControl aac = checkRight(zsc, context, server, AdminRight.PR_ALWAYS_ALLOW);

    // reload the server
    prov.reload(server);

    Element response = zsc.createElement(AdminConstants.GET_SERVER_RESPONSE);
    encodeServer(response, server, applyConfig, reqAttrs, aac.getAttrRightChecker(server));

    return response;
  }
Exemple #7
0
  /* (non-Javadoc)
   * @see com.zimbra.soap.DocumentHandler#handle(org.dom4j.Element, java.util.Map)
   */
  public Element handle(Element request, Map<String, Object> context) throws ServiceException {
    ZimbraSoapContext zsc = getZimbraSoapContext(context);

    Element a = request.getElement(AdminConstants.E_ACCOUNT);
    String key = a.getAttribute(AdminConstants.A_BY);
    String value = a.getText();

    Provisioning prov = Provisioning.getInstance();
    Account account = prov.get(AccountBy.fromString(key), value, zsc.getAuthToken());

    if (account == null) throw AccountServiceException.NO_SUCH_ACCOUNT(value);

    if (account.isCalendarResource()) {
      // need a CalendarResource instance for RightChecker
      CalendarResource resource = prov.get(CalendarResourceBy.id, account.getId());
      checkCalendarResourceRight(zsc, resource, Admin.R_getCalendarResourceInfo);
    } else checkAccountRight(zsc, account, Admin.R_getAccountInfo);

    Element response = zsc.createElement(AdminConstants.GET_ACCOUNT_INFO_RESPONSE);
    response.addElement(AdminConstants.E_NAME).setText(account.getName());
    addAttr(response, Provisioning.A_zimbraId, account.getId());
    addAttr(
        response, Provisioning.A_zimbraMailHost, account.getAttr(Provisioning.A_zimbraMailHost));

    doCos(account, response);
    addUrls(response, account);

    return response;
  }
  public Element handle(Element request, Map<String, Object> context) throws ServiceException {
    ZimbraSoapContext zc = getZimbraSoapContext(context);
    Server server = Provisioning.getInstance().getLocalServer();
    Element response = zc.createElement(MailConstants.GET_SPELL_DICTIONARIES_RESPONSE);

    for (String dictionary : server.getSpellAvailableDictionary()) {
      response.addElement(MailConstants.E_DICTIONARY).setText(dictionary);
    }

    return response;
  }
  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");

    Element response = zsc.createElement(AccountConstants.GET_AVAILABLE_CSV_FORMATS_RESPONSE);
    for (String format : ContactCSV.getAllFormatNames())
      response.addElement(AccountConstants.E_CSV).addAttribute(AccountConstants.A_NAME, format);
    return response;
  }
Exemple #10
0
  public Element handle(Element request, Map<String, Object> context) throws ServiceException {
    ZimbraSoapContext zsc = getZimbraSoapContext(context);
    Account account = getRequestedAccount(zsc);

    if (!canModifyOptions(zsc, account))
      throw ServiceException.PERM_DENIED("can not modify options");

    HashMap<String, Object> prefs = new HashMap<String, Object>();
    Map<String, Set<String>> name2uniqueAttrValues = new HashMap<String, Set<String>>();
    for (KeyValuePair kvp :
        request.listKeyValuePairs(AccountConstants.E_PREF, AccountConstants.A_NAME)) {
      String name = kvp.getKey(), value = kvp.getValue();
      char ch = name.length() > 0 ? name.charAt(0) : 0;
      int offset = ch == '+' || ch == '-' ? 1 : 0;
      if (!name.startsWith(PREF_PREFIX, offset))
        throw ServiceException.INVALID_REQUEST("pref name must start with " + PREF_PREFIX, null);

      AttributeInfo attrInfo =
          AttributeManager.getInstance().getAttributeInfo(name.substring(offset));
      if (attrInfo == null) {
        throw ServiceException.INVALID_REQUEST("no such attribute: " + name, null);
      }
      if (attrInfo.isCaseInsensitive()) {
        String valueLowerCase = Strings.nullToEmpty(value).toLowerCase();
        if (name2uniqueAttrValues.get(name) == null) {
          Set<String> set = new HashSet<String>();
          set.add(valueLowerCase);
          name2uniqueAttrValues.put(name, set);
          StringUtil.addToMultiMap(prefs, name, value);
        } else {
          Set<String> set = name2uniqueAttrValues.get(name);
          if (set.add(valueLowerCase)) {
            StringUtil.addToMultiMap(prefs, name, value);
          }
        }
      } else {
        StringUtil.addToMultiMap(prefs, name, value);
      }
    }

    if (prefs.containsKey(Provisioning.A_zimbraPrefMailForwardingAddress)) {
      if (!account.getBooleanAttr(Provisioning.A_zimbraFeatureMailForwardingEnabled, false))
        throw ServiceException.PERM_DENIED("forwarding not enabled");
    }

    // call modifyAttrs and pass true to checkImmutable
    Provisioning.getInstance().modifyAttrs(account, prefs, true, zsc.getAuthToken());

    Element response = zsc.createElement(AccountConstants.MODIFY_PREFS_RESPONSE);
    return response;
  }
  @Override
  public Element handle(Element request, Map<String, Object> context) throws ServiceException {

    ZimbraSoapContext zsc = getZimbraSoapContext(context);
    String action = request.getAttribute(AdminConstants.A_ACTION).toLowerCase();
    Element content = request.getElement(MailConstants.E_CONTENT);
    String aid = content.getAttribute(MailConstants.A_ATTACHMENT_ID, null);
    boolean flushCache = request.getAttributeBool(AdminConstants.A_FLUSH, false);
    boolean synchronous = request.getAttributeBool(AdminConstants.A_SYNCHRONOUS, false);
    if (action.equals(AdminConstants.A_STATUS)) {
      // just print the status
    } else if (action.equals(AdminConstants.A_DEPLOYALL)) {

      for (Server server : Provisioning.getInstance().getAllServers()) {
        checkRight(zsc, context, server, Admin.R_deployZimlet);
      }

      deploy(zsc, aid, zsc.getRawAuthToken(), flushCache, synchronous);
      if (flushCache) {
        if (ZimbraLog.misc.isDebugEnabled()) {
          ZimbraLog.misc.debug("DeployZimlet: flushing zimlet cache");
        }
        checkRight(zsc, context, Provisioning.getInstance().getLocalServer(), Admin.R_flushCache);
        FlushCache.sendFlushRequest(context, "/service", "/zimlet/res/all.js");
      }

    } else if (action.equals(AdminConstants.A_DEPLOYLOCAL)) {

      Server localServer = Provisioning.getInstance().getLocalServer();
      checkRight(zsc, context, localServer, Admin.R_deployZimlet);

      deploy(zsc, aid, null, false, synchronous);

      if (flushCache) {
        if (ZimbraLog.misc.isDebugEnabled()) {
          ZimbraLog.misc.debug("DeployZimlet: flushing zimlet cache");
        }
        checkRight(zsc, context, localServer, Admin.R_flushCache);
        FlushCache.sendFlushRequest(context, "/service", "/zimlet/res/all.js");
      }
    } else {
      throw ServiceException.INVALID_REQUEST("invalid action " + action, null);
    }
    Element response = zsc.createElement(AdminConstants.DEPLOY_ZIMLET_RESPONSE);
    Progress progress = (Progress) mProgressMap.get(aid);
    if (progress != null) progress.writeResponse(response);
    return response;
  }
Exemple #12
0
  private static void searchRemoteAccountCalendars(
      Element parent,
      SearchParams params,
      ZimbraSoapContext zsc,
      Account authAcct,
      Map<String, List<Integer>> accountFolders)
      throws ServiceException {
    String nominalTargetAcctId = null; // mail service soap requests want to see a target account
    StringBuilder queryStr = new StringBuilder();
    for (Map.Entry<String, List<Integer>> entry : accountFolders.entrySet()) {
      String acctId = entry.getKey();
      if (nominalTargetAcctId == null) nominalTargetAcctId = acctId;
      ItemIdFormatter ifmt = new ItemIdFormatter(authAcct.getId(), acctId, false);
      List<Integer> folderIds = entry.getValue();
      for (int folderId : folderIds) {
        if (queryStr.length() > 0) queryStr.append(" OR ");
        // must quote the qualified folder id
        queryStr.append("inid:\"").append(ifmt.formatItemId(folderId)).append("\"");
      }
    }
    Element req = zsc.createElement(MailConstants.SEARCH_REQUEST);
    req.addAttribute(MailConstants.A_SEARCH_TYPES, MailItem.Type.toString(params.getTypes()));
    if (params.getSortBy() != null) {
      req.addAttribute(MailConstants.A_SORTBY, params.getSortBy().toString());
    }
    req.addAttribute(MailConstants.A_QUERY_OFFSET, params.getOffset());
    if (params.getLimit() != 0) req.addAttribute(MailConstants.A_QUERY_LIMIT, params.getLimit());
    req.addAttribute(MailConstants.A_CAL_EXPAND_INST_START, params.getCalItemExpandStart());
    req.addAttribute(MailConstants.A_CAL_EXPAND_INST_END, params.getCalItemExpandEnd());
    req.addAttribute(MailConstants.E_QUERY, queryStr.toString(), Element.Disposition.CONTENT);

    Account target = Provisioning.getInstance().get(Key.AccountBy.id, nominalTargetAcctId);
    String pxyAuthToken = zsc.getAuthToken().getProxyAuthToken();
    ZAuthToken zat = pxyAuthToken == null ? zsc.getRawAuthToken() : new ZAuthToken(pxyAuthToken);
    ZMailbox.Options zoptions = new ZMailbox.Options(zat, AccountUtil.getSoapUri(target));
    zoptions.setTargetAccount(nominalTargetAcctId);
    zoptions.setTargetAccountBy(AccountBy.id);
    zoptions.setNoSession(true);
    ZMailbox zmbx = ZMailbox.getMailbox(zoptions);

    Element resp = zmbx.invoke(req);
    for (Element hit : resp.listElements()) {
      hit.detach();
      parent.addElement(hit);
    }
  }
  @Override
  public Element handle(Element request, Map<String, Object> context) throws ServiceException {
    ZimbraSoapContext zsc = getZimbraSoapContext(context);

    Element mreq = request.getElement(AdminConstants.E_MAILBOX);
    String accountId = mreq.getAttribute(AdminConstants.A_ACCOUNTID);

    Account account = Provisioning.getInstance().get(AccountBy.id, accountId, zsc.getAuthToken());
    if (account == null) {
      // Note: isDomainAdminOnly *always* returns false for pure ACL based AccessManager
      if (isDomainAdminOnly(zsc)) {
        throw ServiceException.PERM_DENIED(
            "account doesn't exist, unable to determine authorization");
      }

      // still need to check right, since we don't have an account, the
      // last resort is checking the global grant.  Do this for now until
      // there is complain.
      checkRight(zsc, context, null, Admin.R_deleteAccount);

      ZimbraLog.account.warn(
          "DeleteMailbox: account doesn't exist: " + accountId + " (still deleting mailbox)");

    } else {
      checkAccountRight(zsc, account, Admin.R_deleteAccount);
    }

    Mailbox mbox = MailboxManager.getInstance().getMailboxByAccountId(accountId, false);
    int mailboxId = -1;
    if (mbox != null) {
      mailboxId = mbox.getId();
      mbox.deleteMailbox();
    }

    String idString =
        (mbox == null) ? "<no mailbox for account " + accountId + ">" : Integer.toString(mailboxId);
    ZimbraLog.security.info(
        ZimbraLog.encodeAttrs(new String[] {"cmd", "DeleteMailbox", "id", idString}));

    Element response = zsc.createElement(AdminConstants.DELETE_MAILBOX_RESPONSE);
    if (mbox != null)
      response
          .addElement(AdminConstants.E_MAILBOX)
          .addAttribute(AdminConstants.A_MAILBOXID, mailboxId);
    return response;
  }
  @Override
  public Element handle(Element request, Map<String, Object> context) throws ServiceException {
    ZimbraSoapContext zsc = getZimbraSoapContext(context);
    Mailbox mbox = getRequestedMailbox(zsc);
    OperationContext octxt = getOperationContext(zsc, context);
    ItemIdFormatter ifmt = new ItemIdFormatter(zsc);

    Element doc = request.getElement(MailConstants.E_DOC);
    String id = doc.getAttribute(MailConstants.A_ID);
    int version = (int) doc.getAttributeLong(MailConstants.A_VERSION, -1);
    int count = (int) doc.getAttributeLong(MailConstants.A_COUNT, 1);

    Element response = zsc.createElement(MailConstants.LIST_DOCUMENT_REVISIONS_RESPONSE);

    Document item;

    ItemId iid = new ItemId(id, zsc);
    item = mbox.getDocumentById(octxt, iid.getId());

    if (version < 0) {
      version = item.getVersion();
    }
    MailItem.Type type = item.getType();
    HashSet<Account> accounts = new HashSet<Account>();
    Provisioning prov = Provisioning.getInstance();
    while (version > 0 && count > 0) {
      item = (Document) mbox.getItemRevision(octxt, iid.getId(), type, version);
      if (item != null) {
        ToXML.encodeDocument(response, ifmt, octxt, item);
        Account a = prov.getAccountByName(item.getCreator());
        if (a != null) accounts.add(a);
      }
      version--;
      count--;
    }
    for (Account a : accounts) {
      Element user = response.addElement(MailConstants.A_USER);
      user.addAttribute(MailConstants.A_ID, a.getId());
      user.addAttribute(MailConstants.A_EMAIL, a.getName());
      user.addAttribute(MailConstants.A_NAME, a.getDisplayName());
    }

    return response;
  }
Exemple #15
0
  @Override
  public Element handle(Element request, Map<String, Object> context) throws ServiceException {
    ZimbraSoapContext zsc = getZimbraSoapContext(context);
    Mailbox mbox = getRequestedMailbox(zsc);
    Account account = getRequestedAccount(zsc);
    OperationContext octxt = getOperationContext(zsc, context);

    SearchRequest req = JaxbUtil.elementToJaxb(request);
    if (Objects.firstNonNull(req.getWarmup(), false)) {
      mbox.index.getIndexStore().warmup();
      return zsc.createElement(MailConstants.SEARCH_RESPONSE);
    }

    SearchParams params = SearchParams.parse(req, zsc, account.getPrefMailInitialSearch());
    if (params.getLocale() == null) {
      params.setLocale(mbox.getAccount().getLocale());
    }
    if (params.inDumpster() && params.getTypes().contains(MailItem.Type.CONVERSATION)) {
      throw ServiceException.INVALID_REQUEST("cannot search for conversations in dumpster", null);
    }

    if (LC.calendar_cache_enabled.booleanValue()) {
      List<String> apptFolderIds = getFolderIdListIfSimpleAppointmentsQuery(params, zsc);
      if (apptFolderIds != null) {
        Account authAcct = getAuthenticatedAccount(zsc);
        Element response = zsc.createElement(MailConstants.SEARCH_RESPONSE);
        runSimpleAppointmentQuery(response, params, octxt, zsc, authAcct, mbox, apptFolderIds);
        return response;
      }
    }

    ZimbraQueryResults results = mbox.index.search(zsc.getResponseProtocol(), octxt, params);
    try {
      // create the XML response Element
      Element response = zsc.createElement(MailConstants.SEARCH_RESPONSE);
      // must use results.getSortBy() because the results might have ignored our sortBy
      // request and used something else...
      response.addAttribute(MailConstants.A_SORTBY, results.getSortBy().toString());
      putHits(zsc, octxt, response, results, params);
      return response;
    } finally {
      Closeables.closeQuietly(results);
    }
  }
Exemple #16
0
  public Element handle(Element request, Map<String, Object> context) throws ServiceException {
    ZimbraSoapContext zsc = getZimbraSoapContext(context);
    Mailbox mbox = getRequestedMailbox(zsc);
    OperationContext octxt = getOperationContext(zsc, context);
    ItemIdFormatter ifmt = new ItemIdFormatter(zsc);

    Element t = request.getElement(MailConstants.E_SEARCH);
    ItemId iid = new ItemId(t.getAttribute(MailConstants.A_ID), zsc);
    String query = t.getAttribute(MailConstants.A_QUERY);
    String types = t.getAttribute(MailConstants.A_SEARCH_TYPES, null);
    String sort = t.getAttribute(MailConstants.A_SORTBY, null);

    mbox.modifySearchFolder(octxt, iid.getId(), query, types, sort);
    SearchFolder search = mbox.getSearchFolderById(octxt, iid.getId());

    Element response = zsc.createElement(MailConstants.MODIFY_SEARCH_FOLDER_RESPONSE);
    ToXML.encodeSearchFolder(response, ifmt, search);
    return response;
  }
  private void deploy(
      ZimbraSoapContext lc, String aid, ZAuthToken auth, boolean flushCache, boolean synchronous)
      throws ServiceException {
    Upload up = FileUploadServlet.fetchUpload(lc.getAuthtokenAccountId(), aid, lc.getAuthToken());
    if (up == null) throw MailServiceException.NO_SUCH_UPLOAD(aid);

    Progress pr = new Progress((auth != null));
    mProgressMap.put(aid, pr);
    Runnable action = new DeployThread(up, pr, auth, flushCache);
    Thread t = new Thread(action);
    t.start();
    if (synchronous) {
      try {
        t.join(DEPLOY_TIMEOUT);
      } catch (InterruptedException e) {
        ZimbraLog.zimlet.warn("error while deploying Zimlet", e);
      }
    }
  }
  @Override
  protected Element proxyIfNecessary(Element request, Map<String, Object> context)
      throws ServiceException {
    // if we've explicitly been told to execute here, don't proxy
    ZimbraSoapContext zsc = getZimbraSoapContext(context);
    if (zsc.getProxyTarget() != null) return null;

    // check whether we need to proxy to the home server of a target account
    Provisioning prov = Provisioning.getInstance();
    String[] xpath = getProxiedAccountPath();
    String acctId = (xpath != null ? getXPath(request, xpath) : null);
    if (acctId != null) {
      Account acct = getAccount(prov, AccountBy.id, acctId, zsc.getAuthToken());
      if (acct != null && !Provisioning.onLocalServer(acct))
        return proxyRequest(request, context, acctId);
    }

    return null;
  }
  public Element handle(Element request, Map<String, Object> context) throws ServiceException {
    ZimbraSoapContext zsc = getZimbraSoapContext(context);
    if (!AccessControlUtil.isGlobalAdmin(getAuthenticatedAccount(zsc))) {
      throw ServiceException.PERM_DENIED("only global admin is allowed");
    }

    Map<String, Long> domainAggrQuotaUsed = new HashMap<String, Long>();

    SearchAccountsOptions searchOpts = new SearchAccountsOptions();
    searchOpts.setIncludeType(IncludeType.ACCOUNTS_ONLY);
    searchOpts.setMakeObjectOpt(MakeObjectOpt.NO_DEFAULTS);

    Provisioning prov = Provisioning.getInstance();
    List<NamedEntry> accounts = prov.searchAccountsOnServer(prov.getLocalServer(), searchOpts);
    Map<String, Long> acctQuotaUsed = MailboxManager.getInstance().getMailboxSizes(accounts);
    for (NamedEntry ne : accounts) {
      if (!(ne instanceof Account)) {
        continue;
      }
      Account acct = (Account) ne;
      Long acctQuota = acctQuotaUsed.get(acct.getId());
      if (acctQuota == null) {
        acctQuota = 0L;
      }
      String domainId = acct.getDomainId();
      if (domainId == null) {
        continue;
      }
      Long aggrQuota = domainAggrQuotaUsed.get(domainId);
      domainAggrQuotaUsed.put(domainId, aggrQuota == null ? acctQuota : aggrQuota + acctQuota);
    }

    Element response = zsc.createElement(AdminConstants.GET_AGGR_QUOTA_USAGE_ON_SERVER_RESPONSE);
    for (String domainId : domainAggrQuotaUsed.keySet()) {
      Domain domain = prov.getDomainById(domainId);
      Element domainElt = response.addElement(AdminConstants.E_DOMAIN);
      domainElt.addAttribute(AdminConstants.A_NAME, domain.getName());
      domainElt.addAttribute(AdminConstants.A_ID, domainId);
      domainElt.addAttribute(AdminConstants.A_QUOTA_USED, domainAggrQuotaUsed.get(domainId));
    }
    return response;
  }
  public Element handle(Element request, Map<String, Object> context) throws ServiceException {

    ZimbraSoapContext zsc = getZimbraSoapContext(context);
    Provisioning prov = Provisioning.getInstance();

    boolean applyConfig = request.getAttributeBool(AdminConstants.A_APPLY_CONFIG, true);
    List domains = prov.getAllDomains();

    AdminAccessControl aac = AdminAccessControl.getAdminAccessControl(zsc);

    Element response = zsc.createElement(AdminConstants.GET_ALL_DOMAINS_RESPONSE);
    for (Iterator it = domains.iterator(); it.hasNext(); ) {
      Domain domain = (Domain) it.next();

      if (aac.hasRightsToList(domain, Admin.R_listDomain, null))
        GetDomain.encodeDomain(
            response, domain, applyConfig, null, aac.getAttrRightChecker(domain));
    }

    return response;
  }
  @Override
  public Element handle(Element request, Map<String, Object> context) throws ServiceException {
    ZimbraSoapContext zsc = getZimbraSoapContext(context);
    Mailbox mbox = getRequestedMailbox(zsc);
    OperationContext octxt = getOperationContext(zsc, context);

    ExportContactsRequest req = JaxbUtil.elementToJaxb(request);
    String folder = req.getFolderId();
    ItemId iidFolder = folder == null ? null : new ItemId(folder, zsc);

    String ct = req.getContentType();
    if (ct == null) throw ServiceException.INVALID_REQUEST("content type missing", null);
    if (!ct.equals("csv"))
      throw ServiceException.INVALID_REQUEST("unsupported content type: " + ct, null);

    String format = req.getCsvFormat();
    String locale = req.getCsvLocale();
    String separator = req.getCsvDelimiter();
    Character sepChar = null;
    if ((separator != null) && (separator.length() > 0)) sepChar = separator.charAt(0);

    List<Contact> contacts = mbox.getContactList(octxt, iidFolder != null ? iidFolder.getId() : -1);

    StringBuilder sb = new StringBuilder();
    if (contacts == null) contacts = new ArrayList<Contact>();

    try {
      ContactCSV contactCSV = new ContactCSV(mbox, octxt);
      contactCSV.toCSV(format, locale, sepChar, contacts.iterator(), sb);
    } catch (ContactCSV.ParseException e) {
      throw MailServiceException.UNABLE_TO_EXPORT_CONTACTS(e.getMessage(), e);
    }

    ExportContactsResponse resp = new ExportContactsResponse(sb.toString());
    return zsc.jaxbToElement(resp);
  }
Exemple #22
0
  public Element handle(Element request, Map<String, Object> context) throws ServiceException {
    ZimbraSoapContext zsc = getZimbraSoapContext(context);

    Element a = request.getElement(AdminConstants.E_ACCOUNT);
    String key = a.getAttribute(AdminConstants.A_BY);
    String value = a.getText();

    long lifetime =
        request.getAttributeLong(AdminConstants.A_DURATION, DEFAULT_AUTH_LIFETIME) * 1000;

    Provisioning prov = Provisioning.getInstance();

    Account account = null;

    if (key.equals(BY_NAME)) {
      account = prov.get(AccountBy.name, value, zsc.getAuthToken());
    } else if (key.equals(BY_ID)) {
      account = prov.get(AccountBy.id, value, zsc.getAuthToken());
    } else {
      throw ServiceException.INVALID_REQUEST("unknown value for by: " + key, null);
    }

    if (account == null) throw AccountServiceException.NO_SUCH_ACCOUNT(value);

    checkAdminLoginAsRight(zsc, prov, account);

    ZimbraLog.security.info(
        ZimbraLog.encodeAttrs(
            new String[] {
              "cmd", "DelegateAuth", "accountId", account.getId(), "accountName", account.getName()
            }));

    Element response = zsc.createElement(AdminConstants.DELEGATE_AUTH_RESPONSE);
    long maxLifetime =
        account.getTimeInterval(
            Provisioning.A_zimbraAuthTokenLifetime, DEFAULT_AUTH_LIFETIME * 1000);

    // take the min of requested lifetime vs maxLifetime
    long expires = System.currentTimeMillis() + Math.min(lifetime, maxLifetime);
    String token;
    Account adminAcct = prov.get(AccountBy.id, zsc.getAuthtokenAccountId(), zsc.getAuthToken());
    if (adminAcct == null)
      throw AccountServiceException.NO_SUCH_ACCOUNT(zsc.getAuthtokenAccountId());

    AuthToken at = AuthProvider.getAuthToken(account, expires, false, adminAcct);
    at.encodeAuthResp(response, true);
    response.addAttribute(AdminConstants.E_LIFETIME, lifetime, Element.Disposition.CONTENT);
    return response;
  }
Exemple #23
0
  @Override
  public Element handle(Element request, Map<String, Object> context) throws ServiceException {
    if (true) throw WikiServiceException.ERROR("Deprecated");
    ZimbraSoapContext zsc = getZimbraSoapContext(context);
    OperationContext octxt = getOperationContext(zsc, context);

    Element msgElem = request.getElement(MailConstants.E_WIKIWORD);
    String subject = msgElem.getAttribute(MailConstants.A_NAME, null);
    String id = msgElem.getAttribute(MailConstants.A_ID, null);
    int ver = (int) msgElem.getAttributeLong(MailConstants.A_VERSION, 0);
    int itemId;
    if (id == null) {
      itemId = 0;
    } else {
      ItemId iid = new ItemId(id, zsc);
      itemId = iid.getId();
    }

    ItemId fid = getRequestedFolder(request, zsc);
    ByteArrayInputStream is = null;
    try {
      byte[] rawData = msgElem.getText().getBytes("UTF-8");
      is = new ByteArrayInputStream(rawData);
    } catch (IOException ioe) {
      throw ServiceException.FAILURE("can't get the content", ioe);
    }
    Mailbox mbox = MailboxManager.getInstance().getMailboxByAccountId(zsc.getRequestedAccountId());
    Document wikiItem = null;
    WikiPage.WikiContext ctxt = new WikiPage.WikiContext(octxt, zsc.getAuthToken());
    if (itemId == 0) {
      // create a new page
      wikiItem =
          mbox.createDocument(
              octxt,
              fid.getId(),
              subject,
              WikiItem.WIKI_CONTENT_TYPE,
              getAuthor(zsc),
              null,
              true,
              is,
              MailItem.TYPE_WIKI);
    } else {
      // add a new revision
      WikiPage oldPage = WikiPage.findPage(ctxt, zsc.getRequestedAccountId(), itemId);
      if (oldPage == null)
        throw new WikiServiceException.NoSuchWikiException("page id=" + id + " not found");
      if (oldPage.getLastVersion() != ver) {
        throw MailServiceException.MODIFY_CONFLICT(
            new Argument(MailConstants.A_NAME, subject, Argument.Type.STR),
            new Argument(MailConstants.A_ID, oldPage.getId(), Argument.Type.IID),
            new Argument(MailConstants.A_VERSION, oldPage.getLastVersion(), Argument.Type.NUM));
      }
      wikiItem = mbox.addDocumentRevision(octxt, itemId, getAuthor(zsc), subject, null, true, is);
    }

    Element response = zsc.createElement(MailConstants.SAVE_WIKI_RESPONSE);
    Element m = response.addElement(MailConstants.E_WIKIWORD);
    m.addAttribute(MailConstants.A_ID, new ItemIdFormatter(zsc).formatItemId(wikiItem));
    m.addAttribute(MailConstants.A_VERSION, wikiItem.getVersion());
    return response;
  }
Exemple #24
0
 public Element handleNetworkRequest(Element document, Map context)
     throws ServiceException
 {
     Element backup;
     String method;
     String bkupTarget;
     String label;
     Element response;
     Log.backup.info("Backup request started");
     ZimbraSoapContext lc = getZimbraSoapContext(context);
     checkRights(lc, context);
     backup = document.getElement("backup");
     method = backup.getAttribute("method");
     bkupTarget = backup.getAttribute("target", null);
     label = backup.getAttribute("label", null);
     response = lc.createElement(BackupService.BACKUP_RESPONSE);
     BackupManager mgr;
     BackupTarget backupTarget;
     boolean sync;
     boolean sentReportEmail;
     ServiceException error;
     mgr = BackupManager.getInstance();
     if(bkupTarget != null && "incremental".equals(method))
         throw ServiceException.FAILURE("Custom backup target is not allowed for incremental backup", null);
     backupTarget = mgr.getBackupTarget(bkupTarget, true);
     if("abort".equals(method))
     {
         BackupSet bak = backupTarget.getBackupSet(label);
         bak.abortFullBackup();
         break MISSING_BLOCK_LABEL_852;
     }
     if("delete".equals(method))
     {
         String val = backup.getAttribute("before");
         long cutoffTime = getCutoffTime(val, backupTarget);
         mgr.deleteBackups(backupTarget, cutoffTime);
         break MISSING_BLOCK_LABEL_852;
     }
     sync = backup.getAttributeBool("sync", false);
     sentReportEmail = false;
     error = null;
     BackupParams params;
     List syncBackups;
     BackupSet fullBak;
     BackupSet incrBak;
     params = new BackupParams();
     params.sync = sync;
     parseComponentIncludeExcludeAttrs(backup, params);
     Element fcOptsElem = backup.getOptionalElement("fileCopier");
     if(fcOptsElem != null)
         params.fcOpts = ParseXML.parseFileCopierOptions(fcOptsElem);
     syncBackups = new ArrayList();
     fullBak = null;
     incrBak = null;
     int size;
     try
     {
         com.zimbra.cs.backup.BackupManager.BackupMode backupMode = mgr.getBackupMode();
         boolean autoGroupedMode = com.zimbra.cs.backup.BackupManager.BackupMode.AUTO_GROUPED.equals(backupMode);
         if("full".equals(method))
         {
             params.zip = backup.getAttributeBool("zip", true);
             params.zipStore = backup.getAttributeBool("zipStore", true);
             List acctElems = backup.listElements("account");
             if(acctElems.size() > 0)
             {
                 params.redologs = false;
                 List acctNames = parseAccountNames(acctElems);
                 boolean all = acctNames.size() == 1 && "all".equals(acctNames.get(0));
                 if(all)
                 {
                     if(!sync)
                         fullBak = mgr.startBackupFull(backupTarget, params);
                     else
                         fullBak = mgr.backupFull(backupTarget, params, syncBackups);
                 } else
                 {
                     com.zimbra.cs.account.Account accounts[] = mgr.lookupAccounts(acctNames, com.zimbra.cs.account.Provisioning.AccountBy.name, backupTarget);
                     if(!sync)
                         fullBak = mgr.startBackupFull(accounts, backupTarget, params);
                     else
                         fullBak = mgr.backupFull(accounts, backupTarget, params, syncBackups);
                 }
             } else
             if(autoGroupedMode)
             {
                 if(backupTarget.isCustom())
                     throw ServiceException.FAILURE("Custom backup target is not allowed for auto-grouped backup", null);
                 params.redologs = true;
                 com.zimbra.cs.account.Account accounts[] = mgr.lookupAccountsByOldestBackup(backupTarget);
                 if(accounts == null || accounts.length == 0)
                     throw BackupServiceException.AUTO_GROUPED_BACKUP_TOO_SOON();
                 if(!sync)
                     fullBak = mgr.startBackupFull(accounts, backupTarget, params);
                 else
                     fullBak = mgr.backupFull(accounts, backupTarget, params, syncBackups);
             } else
             {
                 throw ServiceException.INVALID_REQUEST("Missing account list", null);
             }
         } else
         if("incremental".equals(method))
         {
             params.zip = backup.getAttributeBool("zip", true);
             params.zipStore = backup.getAttributeBool("zipStore", true);
             BackupSet baks[] = mgr.backupIncremental(backupTarget, params, syncBackups);
             incrBak = baks[0];
             fullBak = baks[1];
         } else
         {
             throw ServiceException.INVALID_REQUEST((new StringBuilder()).append("Invalid backup method: ").append(method).toString(), null);
         }
     }
     catch(IOException e)
     {
         throw ServiceException.FAILURE(e.getMessage(), e);
     }
     size = syncBackups.size();
     if(size > 0)
     {
         BackupSet baks[] = new BackupSet[size];
         syncBackups.toArray(baks);
         mgr.sendReportEmail(baks);
         sentReportEmail = true;
     }
     break MISSING_BLOCK_LABEL_756;
     Exception exception;
     exception;
     int size = syncBackups.size();
     if(size > 0)
     {
         BackupSet baks[] = new BackupSet[size];
         syncBackups.toArray(baks);
         mgr.sendReportEmail(baks);
         sentReportEmail = true;
     }
     throw exception;
     Element body = response.addElement("backup");
     if(fullBak != null)
         body.addAttribute("label", fullBak.getLabel());
     if(incrBak != null)
         body.addAttribute("incr-label", incrBak.getLabel());
     if(error != null && !sentReportEmail)
         mgr.sendErrorReportEmail(error);
     break MISSING_BLOCK_LABEL_852;
     ServiceException e;
     e;
     error = e;
     throw e;
     Exception exception1;
     exception1;
     if(error != null && !sentReportEmail)
         mgr.sendErrorReportEmail(error);
     throw exception1;
     Log.backup.info("Backup request finished");
     return response;
     IOException e;
     e;
     throw ServiceException.FAILURE(e.getMessage(), e);
 }
  /**
   * Collects data about external IMAP accounts from XML
   *
   * @param is
   * @return ExternalIMAPAccount list of account data containers
   * @throws DocumentException
   * @throws IOException
   * @throws ServiceException
   */
  private Map<accountState, List<ExternalIMAPAccount>> parseExternalIMAPAccounts(
      org.dom4j.Element root, ZimbraSoapContext zsc)
      throws DocumentException, IOException, ServiceException {
    List<ExternalIMAPAccount> idleAccts = new ArrayList<ExternalIMAPAccount>();
    List<ExternalIMAPAccount> runningAccts = new ArrayList<ExternalIMAPAccount>();
    List<ExternalIMAPAccount> finishedAccts = new ArrayList<ExternalIMAPAccount>();
    Map<accountState, List<ExternalIMAPAccount>> accts =
        new HashMap<accountState, List<ExternalIMAPAccount>>();
    Provisioning prov = Provisioning.getInstance();

    for (Iterator userIter = root.elementIterator(AdminExtConstants.E_User); userIter.hasNext(); ) {
      org.dom4j.Element elUser = (org.dom4j.Element) userIter.next();
      String userEmail = "";
      String userLogin = "";
      String userPassword = "";

      for (Iterator userPropsIter = elUser.elementIterator(); userPropsIter.hasNext(); ) {
        org.dom4j.Element el = (org.dom4j.Element) userPropsIter.next();
        /*
         * We support <ExchangeMail> element for compatibility with
         * desktop based Exchange Migration utility <RemoteEmailAddress>
         * takes prevalence over <ExchangeMail> element
         */
        if (AdminExtConstants.E_ExchangeMail.equalsIgnoreCase(el.getName())) {
          userEmail = el.getTextTrim();
        }
        if (AdminExtConstants.E_remoteEmail.equalsIgnoreCase(el.getName())) {
          userEmail = el.getTextTrim();
        }
        if (AdminExtConstants.E_remoteIMAPLogin.equalsIgnoreCase(el.getName())) {
          userLogin = el.getTextTrim();
        }
        if (AdminExtConstants.E_remoteIMAPPassword.equalsIgnoreCase(el.getName())) {
          userPassword = el.getTextTrim();
        }
      }

      Account localAccount = null;
      try {
        localAccount = prov.get(AccountBy.name, userEmail, zsc.getAuthToken());
      } catch (ServiceException se) {
        ZimbraLog.gal.warn("error looking up account", se);
      }

      if (localAccount == null) {
        throw AccountServiceException.NO_SUCH_ACCOUNT(userEmail);
      }
      checkAdminLoginAsRight(zsc, prov, localAccount);

      if (userLogin.length() == 0) {
        userLogin = userEmail;
      }
      // Check if an import is running on this account already
      boolean isRunning = false;
      boolean hasRun = false;
      List<DataSource> sources = Provisioning.getInstance().getAllDataSources(localAccount);
      for (DataSource ds : sources) {
        if (ZimbraBulkProvisionExt.IMAP_IMPORT_DS_NAME.equalsIgnoreCase(ds.getName())
            && ds.getType() == DataSourceType.imap
            && ds.isImportOnly()
            && "1".equalsIgnoreCase(ds.getAttr(Provisioning.A_zimbraDataSourceFolderId))) {
          ImportStatus importStatus = DataSourceManager.getImportStatus(localAccount, ds);
          if (!isRunning) {
            synchronized (importStatus) {
              isRunning = importStatus.isRunning();
              hasRun = importStatus.hasRun();
            }
          }

          if (!hasRun) {
            synchronized (importStatus) {
              hasRun = importStatus.hasRun();
            }
          }

          if (!isRunning) {
            runningAccts.add(
                new ExternalIMAPAccount(userEmail, userLogin, userPassword, localAccount));
            break;
          } else if (hasRun) {
            finishedAccts.add(
                new ExternalIMAPAccount(userEmail, userLogin, userPassword, localAccount));
            break;
          }
        }
      }
      if (!isRunning && !hasRun) {
        idleAccts.add(new ExternalIMAPAccount(userEmail, userLogin, userPassword, localAccount));
      }
    }
    accts.put(accountState.idle, idleAccts);
    accts.put(accountState.running, runningAccts);
    accts.put(accountState.finished, finishedAccts);
    return accts;
  }
Exemple #26
0
 public AuthToken getAuthToken() {
   if (mSoapContext == null) return null;
   else return mSoapContext.getAuthToken();
 }
Exemple #27
0
 public Account getAuthAccount() throws ServiceException {
   if (mSoapContext == null) return getAccount();
   else return Provisioning.getInstance().get(AccountBy.id, mSoapContext.getAuthtokenAccountId());
 }
 @Override
 public Element handle(Element req, Map<String, Object> ctx) throws ServiceException {
   ZimbraSoapContext zsc = getZimbraSoapContext(ctx);
   return zsc.jaxbToElement(handle((SetCurrentVolumeRequest) JaxbUtil.elementToJaxb(req), ctx));
 }
  public Element handle(Element request, Map<String, Object> context) throws ServiceException {
    ZimbraSoapContext zsc = getZimbraSoapContext(context);
    Server localServer = Provisioning.getInstance().getLocalServer();
    checkRight(zsc, context, localServer, Admin.R_createMigrationTask);
    String op = request.getAttribute(AdminExtConstants.A_op);
    Element response = zsc.createElement(AdminExtConstants.BULK_IMAP_DATA_IMPORT_RESPONSE);
    Map<accountState, List<ExternalIMAPAccount>> IMAPAccounts = null;
    String IMAPhost = null,
        IMAPport = null,
        adminLogin = null,
        adminPassword = null,
        connectionType = null,
        sourceServerType = null;
    String sourceType = request.getElement(AdminExtConstants.A_sourceType).getTextTrim();
    String indexBatchSize = ZimbraBulkProvisionExt.DEFAULT_INDEX_BATCH_SIZE;
    boolean useAdminLogin = false;
    if (sourceType.equalsIgnoreCase(AdminFileDownload.FILE_FORMAT_BULK_XML)) {
      String aid = request.getElement(AdminExtConstants.E_attachmentID).getTextTrim();
      ZimbraLog.extensions.debug("Uploaded XML file id = " + aid);
      FileUploadServlet.Upload up =
          FileUploadServlet.fetchUpload(zsc.getAuthtokenAccountId(), aid, zsc.getAuthToken());
      if (up == null) {
        throw ServiceException.FAILURE(
            "Uploaded XML file with id " + aid + " was not found.", null);
      }

      try {
        SAXReader reader = new SAXReader();
        Document doc = reader.read(up.getInputStream());
        org.dom4j.Element root = doc.getRootElement();

        if (!root.getName().equals(AdminExtConstants.E_ZCSImport)) {
          throw new DocumentException(
              "Bulk provisioning XML file's root element must be " + AdminExtConstants.E_ZCSImport);
        }
        Iterator rootIter = root.elementIterator(AdminExtConstants.E_ImportUsers);
        if (!rootIter.hasNext()) {
          throw new DocumentException(
              "Cannot find element "
                  + AdminExtConstants.E_ImportUsers
                  + " in uploaded bulk provisioning XML file");
        }
        org.dom4j.Element elImportUsers = (org.dom4j.Element) rootIter.next();

        IMAPAccounts = parseExternalIMAPAccounts(elImportUsers, zsc);

        Iterator connectionTypeIter = root.elementIterator(AdminExtConstants.E_connectionType);
        if (connectionTypeIter.hasNext()) {
          org.dom4j.Element elConnectionType = (org.dom4j.Element) connectionTypeIter.next();
          connectionType = elConnectionType.getTextTrim();
        }
        Iterator sourceServerTypeIter = root.elementIterator(AdminExtConstants.E_sourceServerType);
        if (sourceServerTypeIter.hasNext()) {
          org.dom4j.Element elSourceServerType = (org.dom4j.Element) sourceServerTypeIter.next();
          sourceServerType = elSourceServerType.getTextTrim();
        }
        Iterator IMAPHostIter = root.elementIterator(AdminExtConstants.E_IMAPHost);
        if (IMAPHostIter.hasNext()) {
          org.dom4j.Element elIMAPHost = (org.dom4j.Element) IMAPHostIter.next();
          IMAPhost = elIMAPHost.getTextTrim();
        }

        Iterator IMAPPortIter = root.elementIterator(AdminExtConstants.E_IMAPPort);
        if (IMAPPortIter.hasNext()) {
          org.dom4j.Element elIMAPPort = (org.dom4j.Element) IMAPPortIter.next();
          IMAPport = elIMAPPort.getTextTrim();
        }

        Iterator IndexBatchSizeIter = root.elementIterator(AdminExtConstants.E_indexBatchSize);
        if (IndexBatchSizeIter.hasNext()) {
          org.dom4j.Element elIxBatchSize = (org.dom4j.Element) IndexBatchSizeIter.next();
          indexBatchSize = elIxBatchSize.getTextTrim();
        }

        Iterator useAdminLoginIter = root.elementIterator(AdminExtConstants.E_useAdminLogin);
        if (useAdminLoginIter.hasNext()) {
          org.dom4j.Element elUseAdminLogin = (org.dom4j.Element) useAdminLoginIter.next();
          useAdminLogin = "******".equalsIgnoreCase(elUseAdminLogin.getTextTrim());
          if (useAdminLogin) {
            Iterator adminLoginIter = root.elementIterator(AdminExtConstants.E_IMAPAdminLogin);
            if (adminLoginIter.hasNext()) {
              org.dom4j.Element elAdminLogin = (org.dom4j.Element) adminLoginIter.next();
              adminLogin = elAdminLogin.getTextTrim();
            }

            Iterator adminPassIter = root.elementIterator(AdminExtConstants.E_IMAPAdminPassword);
            if (adminPassIter.hasNext()) {
              org.dom4j.Element elAdminPassword = (org.dom4j.Element) adminPassIter.next();
              adminPassword = elAdminPassword.getTextTrim();
            }
          }
        }

      } catch (DocumentException e) {
        throw ServiceException.FAILURE(
            "Bulk provisioning failed to read uploaded XML document.", e);
      } catch (IOException e) {
        throw ServiceException.FAILURE(
            "Bulk provisioning failed to read uploaded XML document.", e);
      }
    } else if (sourceType.equalsIgnoreCase(ZimbraBulkProvisionExt.FILE_FORMAT_ZIMBRA)) {
      IMAPAccounts = getZimbraAccounts(request, zsc);
    } else {
      throw ServiceException.INVALID_REQUEST(
          String.format(
              "Invalid value of %s parameter: %s. Allowed values: %s, %s",
              AdminExtConstants.A_sourceType,
              sourceType,
              ZimbraBulkProvisionExt.FILE_FORMAT_ZIMBRA,
              AdminFileDownload.FILE_FORMAT_BULK_XML),
          null);
    }

    /*
     * Process the list of accounts. Find existing datasources and check their states.
     */
    int numIdleAccounts = 0;
    int numRunningAccounts = 0;
    int numFinishedAccounts = 0;
    List<ExternalIMAPAccount> idleAccounts = null;
    if (IMAPAccounts.containsKey(accountState.idle)) {
      idleAccounts = IMAPAccounts.get(accountState.idle);
      if (idleAccounts != null) {
        numIdleAccounts = idleAccounts.size();
      }
    }
    List<ExternalIMAPAccount> runningAccounts;
    if (IMAPAccounts.containsKey(accountState.running)) {
      runningAccounts = IMAPAccounts.get(accountState.running);
      if (runningAccounts != null) {
        Element elRunningAccounts = response.addElement(AdminExtConstants.E_runningAccounts);
        numRunningAccounts = runningAccounts.size();
        Iterator<ExternalIMAPAccount> accountsIter = runningAccounts.iterator();
        while (accountsIter.hasNext()) {
          ExternalIMAPAccount acct = accountsIter.next();
          Element elAccount = elRunningAccounts.addElement(AdminConstants.E_ACCOUNT);
          elAccount.addAttribute(AdminConstants.A_NAME, acct.getAccount().getName());
          elAccount.addAttribute(AdminConstants.A_ID, acct.getAccount().getId());
        }
      }
    }

    if (IMAPAccounts.containsKey(accountState.finished)) {
      List accounts = IMAPAccounts.get(accountState.finished);
      if (accounts != null) {
        numFinishedAccounts = accounts.size();
      }
    }

    /*
     * Check for overwritten options
     */
    Element elConnectionType = request.getOptionalElement(AdminExtConstants.E_connectionType);
    if (elConnectionType != null) {
      connectionType = elConnectionType.getTextTrim();
    }
    Element elSourceServerType = request.getOptionalElement(AdminExtConstants.E_sourceServerType);
    if (elSourceServerType != null) {
      sourceServerType = elSourceServerType.getTextTrim();
    }
    Element elIMAPHost = request.getOptionalElement(AdminExtConstants.E_IMAPHost);
    if (elIMAPHost != null) {
      IMAPhost = elIMAPHost.getTextTrim();
    }

    Element elIMAPPort = request.getOptionalElement(AdminExtConstants.E_IMAPPort);
    if (elIMAPPort != null) {
      IMAPport = elIMAPPort.getTextTrim();
    }

    Element elBatchSize = request.getOptionalElement(AdminExtConstants.E_indexBatchSize);
    if (elBatchSize != null) {
      indexBatchSize = elBatchSize.getTextTrim();
    }

    Element elUseAdminLogin = request.getOptionalElement(AdminExtConstants.E_useAdminLogin);
    if (elUseAdminLogin != null) {
      useAdminLogin = "******".equalsIgnoreCase(elUseAdminLogin.getTextTrim());
    }

    if (useAdminLogin) {
      Element elAdminLogin = request.getOptionalElement(AdminExtConstants.E_IMAPAdminLogin);
      if (elAdminLogin != null) {
        adminLogin = elAdminLogin.getTextTrim();
      }
      Element elAdminPassword = request.getOptionalElement(AdminExtConstants.E_IMAPAdminPassword);
      if (elAdminPassword != null) {
        adminPassword = elAdminPassword.getTextTrim();
      }
    }

    if (ZimbraBulkProvisionExt.OP_PREVIEW.equalsIgnoreCase(op)) {
      /*
       * Do not start the import. Just generate a preview. We will count
       * idle and non-idle accounts.
       */
      response
          .addElement(AdminExtConstants.E_totalCount)
          .setText(Integer.toString(numIdleAccounts + numRunningAccounts + numFinishedAccounts));
      response.addElement(AdminExtConstants.E_idleCount).setText(Integer.toString(numIdleAccounts));
      response
          .addElement(AdminExtConstants.E_runningCount)
          .setText(Integer.toString(numRunningAccounts));
      response
          .addElement(AdminExtConstants.E_finishedCount)
          .setText(Integer.toString(numFinishedAccounts));

      response.addElement(AdminExtConstants.E_connectionType).setText(connectionType);
      response.addElement(AdminExtConstants.E_IMAPHost).setText(IMAPhost);
      response.addElement(AdminExtConstants.E_IMAPPort).setText(IMAPport);
      response.addElement(AdminExtConstants.E_indexBatchSize).setText(indexBatchSize);
      if (useAdminLogin) {
        response.addElement(AdminExtConstants.E_useAdminLogin).setText("1");
        response.addElement(AdminExtConstants.E_IMAPAdminLogin).setText(adminLogin);
        response.addElement(AdminExtConstants.E_IMAPAdminPassword).setText(adminPassword);
      } else {
        response.addElement(AdminExtConstants.E_useAdminLogin).setText("0");
      }
    } else if (ZimbraBulkProvisionExt.OP_START_IMPORT.equalsIgnoreCase(op)) {
      if (idleAccounts == null) {
        throw ServiceException.INVALID_REQUEST(
            "None of the specified accounts are available to start import right now.", null);
      }
      if (IMAPhost == null) {
        throw ServiceException.INVALID_REQUEST("Must specify IMAP server address!", null);
      }

      if (IMAPport == null) {
        throw ServiceException.INVALID_REQUEST("Must specify IMAP server port number!", null);
      }

      if (useAdminLogin) {
        /*
         * We must have admin login/password if we are going to connect
         * to IMAP server with admin credentials
         */
        if (adminPassword == null || adminLogin == null) {
          throw ServiceException.INVALID_REQUEST(
              "Must specify admin credentials in order to log in as admin to IMAP server if "
                  + AdminExtConstants.E_useAdminLogin
                  + " option is selected!",
              null);
        }
      }
      /*
       * Create the import queue
       */
      Queue<HashMap<taskKeys, String>> queue =
          BulkIMAPImportTaskManager.createQueue(zsc.getAuthtokenAccountId());
      Queue<HashMap<taskKeys, String>> runningQ =
          BulkIMAPImportTaskManager.createRunningQueue(zsc.getAuthtokenAccountId());
      Iterator<ExternalIMAPAccount> idleAccIter = idleAccounts.iterator();
      try {
        int size = Integer.parseInt(indexBatchSize);
        if (size <= 0) indexBatchSize = ZimbraBulkProvisionExt.DEFAULT_INDEX_BATCH_SIZE;
      } catch (Exception e) {
        indexBatchSize = ZimbraBulkProvisionExt.DEFAULT_INDEX_BATCH_SIZE;
      }
      while (idleAccIter.hasNext()) {
        ExternalIMAPAccount acct = idleAccIter.next();
        HashMap<taskKeys, String> task = new HashMap<taskKeys, String>();
        String dataSourceID =
            createIMAPDataSource(
                    acct.getAccount(),
                    IMAPhost,
                    IMAPport,
                    connectionType,
                    sourceServerType,
                    acct.getUserEmail(),
                    useAdminLogin ? adminLogin : acct.getUserLogin(),
                    useAdminLogin ? adminPassword : acct.getUserPassword(),
                    indexBatchSize,
                    useAdminLogin)
                .getId();
        String acctID = acct.getAccount().getId();
        task.put(taskKeys.accountID, acctID);
        task.put(taskKeys.dataSourceID, dataSourceID);

        synchronized (queue) {
          queue.add(task);
        }
        synchronized (runningQ) {
          runningQ.add(task);
        }
      }
      /*
       * Start the import process
       */
      BulkIMAPImportTaskManager.startImport(zsc.getAuthtokenAccountId());
    } else if (ZimbraBulkProvisionExt.OP_DISMISS_IMPORT.equalsIgnoreCase(op)) {

    }
    return response;
  }