Search in sources :

Example 6 with ShareInfoData

use of com.zimbra.cs.account.ShareInfoData in project zm-mailbox by Zimbra.

the class SendShareNotification method getShareInfoData.

private ShareInfoData getShareInfoData(ZimbraSoapContext zsc, Map<String, Object> context, Account ownerAcct, OperationContext octxt, byte granteeType, String granteeEmail, String granteeId, String granteeDisplayName, MailItem item, boolean revoke) throws ServiceException {
    MatchingGrant matchingGrant;
    Mountpoint mpt = item instanceof Mountpoint ? (Mountpoint) item : null;
    // see if the share specified in the request is real
    if (Provisioning.onLocalServer(ownerAcct)) {
        matchingGrant = getMatchingGrantLocal(octxt, item, granteeType, granteeId, ownerAcct);
    } else {
        matchingGrant = getMatchingGrantRemote(zsc, context, granteeType, granteeId, ownerAcct, mpt == null ? item.getId() : mpt.getRemoteId());
    }
    if (!revoke && matchingGrant == null) {
        throw ServiceException.INVALID_REQUEST("no matching grant", null);
    }
    //
    // all is well, setup our ShareInfoData object
    //
    ShareInfoData sid = new ShareInfoData();
    sid.setOwnerAcctId(ownerAcct.getId());
    sid.setOwnerAcctEmail(ownerAcct.getName());
    sid.setOwnerAcctDisplayName(ownerAcct.getDisplayName());
    // folder id/uuid used for mounting
    sid.setItemId(mpt == null ? item.getId() : mpt.getRemoteId());
    sid.setItemUuid(mpt == null ? item.getUuid() : mpt.getRemoteUuid());
    //
    // just a display name for the shared folder for the grantee to see.
    // the mountpoint will be created using the folder id.
    //
    // if user2 is sharing with user3 a mountpoint that belongs to user1,
    // we should show user3 the folder(mountpoint) name in user2's mailbox,
    // not the folder name in user1's mailbox.
    String path = (item instanceof Folder) ? ((Folder) item).getPath() : item.getName();
    sid.setPath(path);
    sid.setFolderDefaultView((item instanceof Folder) ? ((Folder) item).getDefaultView() : item.getType());
    // grantee
    sid.setGranteeType(granteeType);
    sid.setGranteeId(granteeId);
    sid.setGranteeName(granteeEmail);
    sid.setGranteeDisplayName(granteeDisplayName);
    if (revoke) {
        sid.setGranteeName(granteeEmail);
        return sid;
    }
    // rights
    sid.setRights(matchingGrant.getGrantedRights());
    // if the grantee is a guest, set URL and password
    if (granteeType == ACL.GRANTEE_GUEST) {
        String url = UserServlet.getRestUrl(ownerAcct) + path;
        // hmm, for mountpoint this should be the path in the owner's mailbox  TODO
        sid.setUrl(url);
        sid.setGuestPassword(matchingGrant.getPassword());
    }
    return sid;
}
Also used : ShareInfoData(com.zimbra.cs.account.ShareInfoData) Folder(com.zimbra.cs.mailbox.Folder) Mountpoint(com.zimbra.cs.mailbox.Mountpoint)

Example 7 with ShareInfoData

use of com.zimbra.cs.account.ShareInfoData in project zm-mailbox by Zimbra.

the class SendShareNotification method sendNotificationEmailToGroupGrantees.

private void sendNotificationEmailToGroupGrantees(OperationContext octxt, Mailbox mbox, Account authAccount, Account ownerAccount, Collection<ShareInfoData> sids, String notes, Action action) throws ServiceException, MessagingException {
    Provisioning prov = Provisioning.getInstance();
    for (ShareInfoData sid : sids) {
        String granteeId = sid.getGranteeId();
        Group group = prov.getGroupBasic(DistributionListBy.id, granteeId);
        if (group == null) {
            // huh?  grantee type is GROUP but the group cannot be found by id.
            // just log a warning and do not send.
            // This is not likely to happen because validateRequest had already
            // checked existance of the grantee.
            sLog.warn("Group not found for sending share notificaiton to: " + granteeId + "(" + sid.getGranteeNotifName() + ")" + ", share notification not sent");
            continue;
        }
        /*
             * send to group members
             */
        GroupMemberEmailAddrs addrs = prov.getMemberAddrs(group);
        if (addrs.groupAddr() != null) {
            // just send to the group's address, no treatment needed for recipients
            sendNotificationEmail(octxt, mbox, authAccount, ownerAccount, sid, notes, action, null, null);
        } else {
            // send one common notif email to all internal members,
            if (addrs.internalAddrs() != null) {
                sendNotificationEmail(octxt, mbox, authAccount, ownerAccount, sid, notes, action, addrs.internalAddrs(), null);
            }
            // send one personalized notif email to each external member
            Collection<String> extMembers = addrs.externalAddrs();
            if (extMembers != null) {
                if (extMembers.size() <= DebugConfig.sendGroupShareNotificationSynchronouslyThreshold) {
                    // send synchronously
                    sendNotificationEmailToGroupExternalMembers(octxt, mbox, authAccount, ownerAccount, sid, notes, action, extMembers);
                } else {
                    // send asynchronously in a separate thread to avoid holding up the request
                    sendNotificationEmailToGroupExternalMembersAsync(octxt, mbox, authAccount, ownerAccount, sid, notes, action, extMembers);
                }
            }
        }
    }
}
Also used : Group(com.zimbra.cs.account.Group) GroupMemberEmailAddrs(com.zimbra.cs.account.Provisioning.GroupMemberEmailAddrs) ShareInfoData(com.zimbra.cs.account.ShareInfoData) Provisioning(com.zimbra.cs.account.Provisioning)

Example 8 with ShareInfoData

use of com.zimbra.cs.account.ShareInfoData in project zm-mailbox by Zimbra.

the class ExternalUserProvServlet method provisionVirtualAccountAndRedirect.

private static void provisionVirtualAccountAndRedirect(HttpServletRequest req, HttpServletResponse resp, String displayName, String password, String grantorId, String extUserEmail) throws ServletException {
    Provisioning prov = Provisioning.getInstance();
    try {
        Account owner = prov.getAccountById(grantorId);
        Domain domain = prov.getDomain(owner);
        Account grantee = prov.getAccountByName(mapExtEmailToAcctName(extUserEmail, domain));
        if (grantee != null) {
            throw new ServletException("invalid request: account already exists");
        }
        // search all shares accessible to the external user
        SearchAccountsOptions searchOpts = new SearchAccountsOptions(domain, new String[] { Provisioning.A_zimbraId, Provisioning.A_displayName, Provisioning.A_zimbraSharedItem });
        // get all groups extUserEmail belongs to
        GuestAccount guestAcct = new GuestAccount(extUserEmail, null);
        List<String> groupIds = prov.getGroupMembership(guestAcct, false).groupIds();
        List<String> grantees = Lists.newArrayList(extUserEmail);
        grantees.addAll(groupIds);
        searchOpts.setFilter(ZLdapFilterFactory.getInstance().accountsByGrants(grantees, false, false));
        List<NamedEntry> accounts = prov.searchDirectory(searchOpts);
        if (accounts.isEmpty()) {
            throw new ServletException("no shares discovered");
        }
        // create external account
        Map<String, Object> attrs = new HashMap<String, Object>();
        attrs.put(Provisioning.A_zimbraIsExternalVirtualAccount, ProvisioningConstants.TRUE);
        attrs.put(Provisioning.A_zimbraExternalUserMailAddress, extUserEmail);
        attrs.put(Provisioning.A_zimbraMailHost, prov.getLocalServer().getServiceHostname());
        if (!StringUtil.isNullOrEmpty(displayName)) {
            attrs.put(Provisioning.A_displayName, displayName);
        }
        attrs.put(Provisioning.A_zimbraHideInGal, ProvisioningConstants.TRUE);
        attrs.put(Provisioning.A_zimbraMailStatus, Provisioning.MailStatus.disabled.toString());
        if (!StringUtil.isNullOrEmpty(password)) {
            attrs.put(Provisioning.A_zimbraVirtualAccountInitialPasswordSet, ProvisioningConstants.TRUE);
        }
        grantee = prov.createAccount(mapExtEmailToAcctName(extUserEmail, domain), password, attrs);
        // create external account mailbox
        Mailbox granteeMbox;
        try {
            granteeMbox = MailboxManager.getInstance().getMailboxByAccount(grantee);
        } catch (ServiceException e) {
            // mailbox creation failed; delete the account also so that it is a clean state before
            // the next attempt
            prov.deleteAccount(grantee.getId());
            throw e;
        }
        // create mountpoints
        Set<MailItem.Type> viewTypes = new HashSet<MailItem.Type>();
        for (NamedEntry ne : accounts) {
            Account account = (Account) ne;
            String[] sharedItems = account.getSharedItem();
            for (String sharedItem : sharedItems) {
                ShareInfoData shareData = AclPushSerializer.deserialize(sharedItem);
                if (!granteeMatchesShare(shareData, grantee)) {
                    continue;
                }
                String sharedFolderPath = shareData.getPath();
                String mountpointName = getMountpointName(account, grantee, sharedFolderPath);
                MailItem.Type viewType = shareData.getFolderDefaultViewCode();
                Mountpoint mtpt = granteeMbox.createMountpoint(null, getMptParentFolderId(viewType, prov), mountpointName, account.getId(), shareData.getItemId(), shareData.getItemUuid(), viewType, 0, MailItem.DEFAULT_COLOR, false);
                if (viewType == MailItem.Type.APPOINTMENT) {
                    // make sure that the mountpoint is checked in the UI by default
                    granteeMbox.alterTag(null, mtpt.getId(), mtpt.getType(), Flag.FlagInfo.CHECKED, true, null);
                }
                viewTypes.add(viewType);
            }
        }
        enableAppFeatures(grantee, viewTypes);
        setCookieAndRedirect(req, resp, grantee);
    } catch (Exception e) {
        throw new ServletException(e);
    }
}
Also used : GuestAccount(com.zimbra.cs.account.GuestAccount) Account(com.zimbra.cs.account.Account) SearchAccountsOptions(com.zimbra.cs.account.SearchAccountsOptions) GuestAccount(com.zimbra.cs.account.GuestAccount) HashMap(java.util.HashMap) ShareInfoData(com.zimbra.cs.account.ShareInfoData) Provisioning(com.zimbra.cs.account.Provisioning) ServletException(javax.servlet.ServletException) ServiceException(com.zimbra.common.service.ServiceException) IOException(java.io.IOException) AuthTokenException(com.zimbra.cs.account.AuthTokenException) ServletException(javax.servlet.ServletException) NamedEntry(com.zimbra.cs.account.NamedEntry) MailItem(com.zimbra.cs.mailbox.MailItem) Mailbox(com.zimbra.cs.mailbox.Mailbox) ZMailbox(com.zimbra.client.ZMailbox) ServiceException(com.zimbra.common.service.ServiceException) Domain(com.zimbra.cs.account.Domain) ZMountpoint(com.zimbra.client.ZMountpoint) Mountpoint(com.zimbra.cs.mailbox.Mountpoint) HashSet(java.util.HashSet)

Example 9 with ShareInfoData

use of com.zimbra.cs.account.ShareInfoData in project zm-mailbox by Zimbra.

the class ExternalUserProvServlet method doGet.

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String param = req.getParameter("p");
    if (param == null) {
        throw new ServletException("request missing param");
    }
    Map<Object, Object> tokenMap = validatePrelimToken(param);
    Map<String, String> reqHeaders = new HashMap<String, String>();
    String ownerId = (String) tokenMap.get("aid");
    String folderId = (String) tokenMap.get("fid");
    String extUserEmail = (String) tokenMap.get("email");
    Provisioning prov = Provisioning.getInstance();
    Account grantee;
    try {
        Account owner = prov.getAccountById(ownerId);
        Domain domain = prov.getDomain(owner);
        grantee = prov.getAccountByName(mapExtEmailToAcctName(extUserEmail, domain));
        if (grantee == null) {
            // external virtual account not created yet
            if (prov.isOctopus() && DebugConfig.skipVirtualAccountRegistrationPage) {
                // provision using 'null' password and display name
                // UI will ask the user to set these post provisioning
                provisionVirtualAccountAndRedirect(req, resp, null, null, ownerId, extUserEmail);
            } else {
                resp.addCookie(new Cookie("ZM_PRELIM_AUTH_TOKEN", param));
                req.setAttribute("extuseremail", extUserEmail);
                if (WebClientServiceUtil.isServerInSplitMode()) {
                    reqHeaders.put("extuseremail", extUserEmail);
                    reqHeaders.put("ZM_PRELIM_AUTH_TOKEN", param);
                    String htmlresp = WebClientServiceUtil.sendServiceRequestToOneRandomUiNode(EXT_USER_PROV_ON_UI_NODE, reqHeaders);
                    resp.getWriter().print(htmlresp);
                } else {
                    ServletContext context = getServletContext().getContext("/zimbra");
                    if (context != null) {
                        RequestDispatcher dispatcher = context.getRequestDispatcher(PUBLIC_EXTUSERPROV_JSP);
                        dispatcher.forward(req, resp);
                    } else {
                        logger.warn("Could not access servlet context url /zimbra");
                        throw ServiceException.TEMPORARILY_UNAVAILABLE();
                    }
                }
            }
        } else {
            // create a new mountpoint in the external user's mailbox if not already created
            String[] sharedItems = owner.getSharedItem();
            int sharedFolderId = Integer.valueOf(folderId);
            String sharedFolderPath = null;
            MailItem.Type sharedFolderView = null;
            for (String sharedItem : sharedItems) {
                ShareInfoData sid = AclPushSerializer.deserialize(sharedItem);
                if (sid.getItemId() == sharedFolderId && extUserEmail.equalsIgnoreCase(sid.getGranteeId())) {
                    sharedFolderPath = sid.getPath();
                    sharedFolderView = sid.getFolderDefaultViewCode();
                    break;
                }
            }
            if (sharedFolderPath == null) {
                throw new ServletException("share not found");
            }
            String mountpointName = getMountpointName(owner, grantee, sharedFolderPath);
            ZMailbox.Options options = new ZMailbox.Options();
            options.setNoSession(true);
            options.setAuthToken(AuthProvider.getAuthToken(grantee).toZAuthToken());
            options.setUri(AccountUtil.getSoapUri(grantee));
            ZMailbox zMailbox = new ZMailbox(options);
            ZMountpoint zMtpt = null;
            try {
                zMtpt = zMailbox.createMountpoint(String.valueOf(getMptParentFolderId(sharedFolderView, prov)), mountpointName, ZFolder.View.fromString(sharedFolderView.toString()), ZFolder.Color.DEFAULTCOLOR, null, ZMailbox.OwnerBy.BY_ID, ownerId, ZMailbox.SharedItemBy.BY_ID, folderId, false);
            } catch (ServiceException e) {
                logger.debug("Error in attempting to create mountpoint. Probably it already exists.", e);
            }
            if (zMtpt != null) {
                if (sharedFolderView == MailItem.Type.APPOINTMENT) {
                    // make sure that the mountpoint is checked in the UI by default
                    FolderActionSelector actionSelector = new FolderActionSelector(zMtpt.getId(), "check");
                    FolderActionRequest actionRequest = new FolderActionRequest(actionSelector);
                    try {
                        zMailbox.invokeJaxb(actionRequest);
                    } catch (ServiceException e) {
                        logger.warn("Error in invoking check action on calendar mountpoint", e);
                    }
                }
                HashSet<MailItem.Type> types = new HashSet<MailItem.Type>();
                types.add(sharedFolderView);
                enableAppFeatures(grantee, types);
            }
            // check if the external user is already logged-in
            String zAuthTokenCookie = null;
            javax.servlet.http.Cookie[] cookies = req.getCookies();
            if (cookies != null) {
                for (Cookie cookie : cookies) {
                    if (cookie.getName().equals("ZM_AUTH_TOKEN")) {
                        zAuthTokenCookie = cookie.getValue();
                        break;
                    }
                }
            }
            AuthToken zAuthToken = null;
            if (zAuthTokenCookie != null) {
                try {
                    zAuthToken = AuthProvider.getAuthToken(zAuthTokenCookie);
                } catch (AuthTokenException ignored) {
                // auth token is not valid
                }
            }
            if (zAuthToken != null && !zAuthToken.isExpired() && zAuthToken.isRegistered() && grantee.getId().equals(zAuthToken.getAccountId())) {
                // external virtual account already logged-in
                resp.sendRedirect("/");
            } else if (prov.isOctopus() && !grantee.isVirtualAccountInitialPasswordSet() && DebugConfig.skipVirtualAccountRegistrationPage) {
                // seems like the virtual user did not set his password during his last visit, after an account was
                // provisioned for him
                setCookieAndRedirect(req, resp, grantee);
            } else {
                req.setAttribute("virtualacctdomain", domain.getName());
                if (WebClientServiceUtil.isServerInSplitMode()) {
                    reqHeaders.put("virtualacctdomain", domain.getName());
                    String htmlresp = WebClientServiceUtil.sendServiceRequestToOneRandomUiNode(PUBLIC_LOGIN_ON_UI_NODE, reqHeaders);
                    resp.getWriter().print(htmlresp);
                } else {
                    RequestDispatcher dispatcher = getServletContext().getContext("/zimbra").getRequestDispatcher(PUBLIC_LOGIN_JSP);
                    dispatcher.forward(req, resp);
                }
            }
        }
    } catch (ServiceException e) {
        throw new ServletException(e);
    }
}
Also used : ZMountpoint(com.zimbra.client.ZMountpoint) GuestAccount(com.zimbra.cs.account.GuestAccount) Account(com.zimbra.cs.account.Account) SearchAccountsOptions(com.zimbra.cs.account.SearchAccountsOptions) HashMap(java.util.HashMap) Provisioning(com.zimbra.cs.account.Provisioning) ServletException(javax.servlet.ServletException) FolderActionSelector(com.zimbra.soap.mail.type.FolderActionSelector) ZMailbox(com.zimbra.client.ZMailbox) ServletContext(javax.servlet.ServletContext) HashSet(java.util.HashSet) Cookie(javax.servlet.http.Cookie) ShareInfoData(com.zimbra.cs.account.ShareInfoData) RequestDispatcher(javax.servlet.RequestDispatcher) ZMountpoint(com.zimbra.client.ZMountpoint) Mountpoint(com.zimbra.cs.mailbox.Mountpoint) MailItem(com.zimbra.cs.mailbox.MailItem) ServiceException(com.zimbra.common.service.ServiceException) FolderActionRequest(com.zimbra.soap.mail.message.FolderActionRequest) AuthTokenException(com.zimbra.cs.account.AuthTokenException) AuthToken(com.zimbra.cs.account.AuthToken) Domain(com.zimbra.cs.account.Domain)

Example 10 with ShareInfoData

use of com.zimbra.cs.account.ShareInfoData in project zm-mailbox by Zimbra.

the class SendShareNotification method validateRequest.

private Collection<ShareInfoData> validateRequest(ZimbraSoapContext zsc, Map<String, Object> context, OperationContext octxt, Mailbox mbox, Element request) throws ServiceException {
    Element eShare = request.getOptionalElement(MailConstants.E_SHARE);
    if (eShare != null) {
        return Arrays.asList(validateShareRecipient(zsc, context, octxt, mbox, eShare));
    }
    String action = request.getAttribute(MailConstants.A_ACTION, null);
    ArrayList<ShareInfoData> shareInfos = new ArrayList<ShareInfoData>();
    SendShareNotificationRequest req = JaxbUtil.elementToJaxb(request);
    ItemId iid = new ItemId(req.getItem().getId(), zsc);
    MailItem item = mbox.getItemById(octxt, iid.getId(), MailItem.Type.UNKNOWN);
    Provisioning prov = Provisioning.getInstance();
    Account account = getRequestedAccount(zsc);
    if (item instanceof Mountpoint) {
        Mountpoint mp = (Mountpoint) item;
        account = prov.get(AccountBy.id, mp.getOwnerId());
    }
    for (EmailAddrInfo email : req.getEmailAddresses()) {
        // add the non-existing grantee as type GRANTEE_GUEST for share notification.
        // for revoke notifications return the non-existing grantees only
        Pair<NamedEntry, String> grantee;
        boolean guestGrantee = false;
        byte granteeType = ACL.GRANTEE_USER;
        String granteeId = null;
        String granteeEmail = email.getAddress();
        String granteeDisplayName = null;
        try {
            grantee = getGrantee(zsc, granteeType, granteeId, granteeEmail);
            NamedEntry entry = grantee.getFirst();
            if (entry instanceof MailTarget) {
                Domain domain = prov.getDomain(account);
                String granteeDomainName = ((MailTarget) entry).getDomainName();
                if (domain.isInternalSharingCrossDomainEnabled() || domain.getName().equals(granteeDomainName) || Sets.newHashSet(domain.getInternalSharingDomain()).contains(granteeDomainName)) {
                    if (entry instanceof Group) {
                        granteeType = ACL.GRANTEE_GROUP;
                    }
                    granteeId = entry.getId();
                    granteeDisplayName = grantee.getSecond();
                } else {
                    guestGrantee = true;
                }
            }
        } catch (ServiceException e) {
            if (!e.getCode().equals(MailServiceException.NO_SUCH_GRANTEE)) {
                throw e;
            }
            guestGrantee = true;
        }
        if (guestGrantee) {
            granteeType = ACL.GRANTEE_GUEST;
            // if guest, granteeId is the same as granteeEmail
            granteeId = granteeEmail;
        }
        shareInfos.add(getShareInfoData(zsc, context, account, octxt, granteeType, granteeEmail, granteeId, granteeDisplayName, item, REVOKE.equals(action)));
    }
    return shareInfos;
}
Also used : Account(com.zimbra.cs.account.Account) Group(com.zimbra.cs.account.Group) Element(com.zimbra.common.soap.Element) ShareInfoData(com.zimbra.cs.account.ShareInfoData) ArrayList(java.util.ArrayList) MailTarget(com.zimbra.cs.account.MailTarget) ItemId(com.zimbra.cs.service.util.ItemId) Provisioning(com.zimbra.cs.account.Provisioning) NamedEntry(com.zimbra.cs.account.NamedEntry) MailItem(com.zimbra.cs.mailbox.MailItem) ServiceException(com.zimbra.common.service.ServiceException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) EmailAddrInfo(com.zimbra.soap.mail.type.EmailAddrInfo) SendShareNotificationRequest(com.zimbra.soap.mail.message.SendShareNotificationRequest) Domain(com.zimbra.cs.account.Domain) Mountpoint(com.zimbra.cs.mailbox.Mountpoint)

Aggregations

ShareInfoData (com.zimbra.cs.account.ShareInfoData)13 Account (com.zimbra.cs.account.Account)6 Provisioning (com.zimbra.cs.account.Provisioning)5 ServiceException (com.zimbra.common.service.ServiceException)4 MailItem (com.zimbra.cs.mailbox.MailItem)4 Mountpoint (com.zimbra.cs.mailbox.Mountpoint)4 Element (com.zimbra.common.soap.Element)3 Domain (com.zimbra.cs.account.Domain)3 GuestAccount (com.zimbra.cs.account.GuestAccount)3 Mailbox (com.zimbra.cs.mailbox.Mailbox)3 HashMap (java.util.HashMap)3 HashSet (java.util.HashSet)3 ZMailbox (com.zimbra.client.ZMailbox)2 ZMountpoint (com.zimbra.client.ZMountpoint)2 AuthTokenException (com.zimbra.cs.account.AuthTokenException)2 Group (com.zimbra.cs.account.Group)2 NamedEntry (com.zimbra.cs.account.NamedEntry)2 SearchAccountsOptions (com.zimbra.cs.account.SearchAccountsOptions)2 Folder (com.zimbra.cs.mailbox.Folder)2 MailServiceException (com.zimbra.cs.mailbox.MailServiceException)2