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;
}
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);
}
}
}
}
}
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);
}
}
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);
}
}
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;
}
Aggregations