use of com.zimbra.cs.service.UserServletException in project zm-mailbox by Zimbra.
the class OctopusPatchFormatter method saveCallback.
// Formatter API
@Override
public void saveCallback(UserServletContext context, String contentType, Folder folder, String filename) throws IOException, ServiceException, UserServletException {
log.info("Uploading patch for " + filename);
if (filename == null) {
throw new UserServletException(HttpServletResponse.SC_BAD_REQUEST, "Missing filename");
}
MailItem item = null;
Mailbox mbox = folder.getMailbox();
try {
item = mbox.getItemByPath(context.opContext, filename, folder.getId());
if (!(item instanceof Document))
throw new UserServletException(HttpServletResponse.SC_BAD_REQUEST, "cannot overwrite existing object at that path");
} catch (NoSuchItemException e) {
log.debug("No document found at " + filename + "(folder id=" + folder.getId() + "; will create new one");
}
PatchInputStream pis = null;
PatchStore.IncomingPatch ip = null;
try {
ip = patchStore.createIncomingPatch(context.targetAccount.getId());
int defaultFileId = 0;
int defaultVersion = 0;
if (item != null) {
defaultFileId = item.getId();
defaultVersion = item.getVersion();
}
pis = PatchInputStream.create(context.getRequestInputStream(), // the current (target) user's view
context.targetMailbox, context.opContext, defaultFileId, defaultVersion, ip.getOutputStream(), ip.getManifest());
String creator = context.getAuthAccount() == null ? null : context.getAuthAccount().getName();
if (contentType == null) {
contentType = MimeDetect.getMimeDetect().detect(filename);
if (contentType == null)
contentType = MimeConstants.CT_APPLICATION_OCTET_STREAM;
}
log.debug("Storing blob");
Blob blob = StoreManager.getInstance().storeIncoming(pis);
log.debug("Creating parsed document; filename=" + filename + ", contentType=" + contentType + ", creator=" + creator);
ParsedDocument pd = new ParsedDocument(blob, filename, contentType, System.currentTimeMillis(), creator, context.req.getHeader("X-Zimbra-Description"), true);
log.debug("Parsed document created " + filename);
// scan upload for viruses
StringBuffer info = new StringBuffer();
UploadScanner.Result result = UploadScanner.acceptStream(pis, info);
if (result == UploadScanner.REJECT)
throw MailServiceException.UPLOAD_REJECTED(filename, info.toString());
if (result == UploadScanner.ERROR)
throw MailServiceException.SCAN_ERROR(filename);
if (item == null) {
log.debug("Creating new document " + filename);
item = mbox.createDocument(context.opContext, folder.getId(), pd, MailItem.Type.DOCUMENT, 0);
} else {
log.debug("Creating new version of the document " + filename + ", current version: " + item.getVersion());
item = mbox.addDocumentRevision(context.opContext, item.getId(), pd);
}
patchStore.acceptPatch(ip, item.getId(), item.getVersion());
NativeFormatter.sendZimbraHeaders(context, context.resp, item);
} catch (PatchException e) {
log.error("Patch upload failed: " + e);
patchStore.rejectPatch(ip);
throw new UserServletException(HttpServletResponse.SC_CONFLICT, "patch cannot be applied, try uploading whole file", e);
} finally {
try {
pis.close();
} catch (Exception e) {
log.error("Exception during PatchInputStream close, ignored: " + e);
}
}
}
use of com.zimbra.cs.service.UserServletException in project zm-mailbox by Zimbra.
the class NativeFormatter method handleDocument.
private void handleDocument(UserServletContext context, Document doc) throws IOException, ServiceException, ServletException {
String v = context.params.get(UserServlet.QP_VERSION);
int version = v != null ? Integer.parseInt(v) : -1;
String contentType = doc.getContentType();
doc = (version > 0 ? (Document) doc.getMailbox().getItemRevision(context.opContext, doc.getId(), doc.getType(), version) : doc);
InputStream is = doc.getContentStream();
if (HTML_VIEW.equals(context.getView()) && !(contentType != null && contentType.startsWith(MimeConstants.CT_TEXT_HTML))) {
if (ExtensionUtil.getExtension("convertd") != null) {
// If the requested view is html, but the requested content is not, use convertd extension when deployed
handleConversion(context, is, doc.getName(), doc.getContentType(), doc.getDigest(), doc.getSize());
} else {
// either an error page, or page invoking an error callback handler can be shown
try {
updateClient(context, new ConversionUnsupportedException(String.format("Native format cannot be displayed inline: %s", contentType)));
} catch (UserServletException e) {
throw new ServletException(e.getLocalizedMessage(), e);
}
}
} else {
String defaultCharset = context.targetAccount.getAttr(Provisioning.A_zimbraPrefMailDefaultCharset, null);
boolean neuter = doc.getAccount().getBooleanAttr(Provisioning.A_zimbraNotebookSanitizeHtml, true);
if (neuter)
sendbackOriginalDoc(is, contentType, defaultCharset, doc.getName(), null, doc.getSize(), context.req, context.resp);
else
sendbackBinaryData(context.req, context.resp, is, contentType, null, doc.getName(), doc.getSize());
}
}
use of com.zimbra.cs.service.UserServletException in project zm-mailbox by Zimbra.
the class UserServletUtil method getAccount.
// public synchronized static void addFormatter(Formatter f) {
// mFormatters.put(f.getType(), f);
// for (String mimeType : f.getDefaultMimeTypes())
// mDefaultFormatters.put(mimeType, f);
// }
//
// public Formatter getFormatter(String type) {
// return mFormatters.get(type);
// }
public static void getAccount(UserServletContext context) throws IOException, ServletException, UserServletException {
try {
boolean isAdminRequest = AuthUtil.isAdminRequest(context.req);
// check cookie or access key
if (context.cookieAuthAllowed() || AuthProvider.allowAccessKeyAuth(context.req, context.getServlet())) {
try {
AuthToken at = AuthProvider.getAuthToken(context.req, isAdminRequest);
if (at != null) {
if (at.isZimbraUser()) {
if (!at.isRegistered()) {
throw new UserServletException(HttpServletResponse.SC_UNAUTHORIZED, L10nUtil.getMessage(MsgKey.errMustAuthenticate, context.req));
}
try {
context.setAuthAccount(AuthProvider.validateAuthToken(Provisioning.getInstance(), at, false));
} catch (ServiceException e) {
throw new UserServletException(HttpServletResponse.SC_UNAUTHORIZED, L10nUtil.getMessage(MsgKey.errMustAuthenticate, context.req));
}
context.cookieAuthHappened = true;
context.authToken = at;
return;
} else {
if (at.isExpired()) {
throw new UserServletException(HttpServletResponse.SC_UNAUTHORIZED, L10nUtil.getMessage(MsgKey.errMustAuthenticate, context.req));
}
context.setAuthAccount(new GuestAccount(at));
// pretend that we basic authed
context.basicAuthHappened = true;
context.authToken = at;
return;
}
}
} catch (AuthTokenException e) {
// bug 35917: malformed auth token means auth failure
throw new UserServletException(HttpServletResponse.SC_UNAUTHORIZED, L10nUtil.getMessage(MsgKey.errMustAuthenticate, context.req));
}
}
// check query string
if (context.queryParamAuthAllowed()) {
String auth = context.params.get(ZimbraServlet.QP_ZAUTHTOKEN);
if (auth == null)
// not sure who uses this parameter; zauthtoken is preferred
auth = context.params.get(UserServlet.QP_AUTHTOKEN);
if (auth != null) {
try {
// Only supported by ZimbraAuthProvider
AuthToken at = AuthProvider.getAuthToken(auth);
try {
context.setAuthAccount(AuthProvider.validateAuthToken(Provisioning.getInstance(), at, false));
context.qpAuthHappened = true;
context.authToken = at;
return;
} catch (ServiceException e) {
throw new UserServletException(HttpServletResponse.SC_UNAUTHORIZED, L10nUtil.getMessage(MsgKey.errMustAuthenticate, context.req));
}
} catch (AuthTokenException e) {
// bug 35917: malformed auth token means auth failure
throw new UserServletException(HttpServletResponse.SC_UNAUTHORIZED, L10nUtil.getMessage(MsgKey.errMustAuthenticate, context.req));
}
}
}
// fallback to basic auth
if (context.basicAuthAllowed()) {
context.setAuthAccount(AuthUtil.basicAuthRequest(context.req, context.resp, context.servlet, false));
if (context.getAuthAccount() != null) {
context.basicAuthHappened = true;
context.authToken = AuthProvider.getAuthToken(context.getAuthAccount(), isAdminRequest);
// send cookie back if need be.
if (context.setCookie()) {
boolean secureCookie = context.req.getScheme().equals("https");
context.authToken.encode(context.resp, isAdminRequest, secureCookie);
}
}
// always return
return;
}
// there is no credential at this point. assume anonymous public access and continue.
} catch (ServiceException e) {
throw new ServletException(e);
}
}
use of com.zimbra.cs.service.UserServletException in project zm-mailbox by Zimbra.
the class ArchiveFormatter method formatCallback.
@Override
public void formatCallback(UserServletContext context) throws IOException, ServiceException, UserServletException {
// Disable the jetty timeout
disableJettyTimeout(context);
HashMap<Integer, Integer> cnts = new HashMap<Integer, Integer>();
int dot;
HashMap<Integer, String> fldrs = new HashMap<Integer, String>();
String emptyname = context.params.get("emptyname");
String ext = "." + getType();
String filename = context.params.get("filename");
String lock = context.params.get("lock");
String query = context.getQueryString();
Set<String> names = new HashSet<String>(4096);
Set<MailItem.Type> sysTypes = EnumSet.of(MailItem.Type.FOLDER, MailItem.Type.SEARCHFOLDER, MailItem.Type.TAG, MailItem.Type.FLAG, MailItem.Type.MOUNTPOINT);
Set<MailItem.Type> searchTypes = EnumSet.of(MailItem.Type.MESSAGE, MailItem.Type.CONTACT, MailItem.Type.DOCUMENT, MailItem.Type.WIKI, MailItem.Type.APPOINTMENT, MailItem.Type.TASK, MailItem.Type.CHAT, MailItem.Type.NOTE);
ArchiveOutputStream aos = null;
String types = context.getTypesString();
MailboxMaintenance maintenance = null;
try {
if (filename == null || filename.equals("")) {
Date date = new Date();
DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT);
SimpleDateFormat sdf = new SimpleDateFormat(".H-m-s");
if (context.hasPart()) {
filename = "attachments";
} else {
filename = context.targetMailbox.getAccountId() + '.' + df.format(date).replace('/', '-') + sdf.format(date);
}
} else if ((dot = filename.lastIndexOf('.')) != -1) {
String userProvidedExtension = filename.substring(dot + 1);
if (BLE.contains(userProvidedExtension.toUpperCase())) {
filename = filename.substring(0, dot);
}
}
if (!filename.endsWith(ext)) {
filename += ext;
}
if (emptyname != null && !emptyname.equals("") && !emptyname.endsWith(ext)) {
emptyname += ext;
}
context.resp.addHeader("Content-Disposition", HttpUtil.createContentDisposition(context.req, Part.ATTACHMENT, filename));
if (ext.equals(".tar")) {
context.resp.setContentType("application/x-tar");
} else if (ext.equals(".tgz")) {
context.resp.setContentType("application/x-compressed-tar");
} else if (ext.equals(".zip")) {
context.resp.setContentType("application/zip");
}
if (!Strings.isNullOrEmpty(types)) {
try {
searchTypes = MailItem.Type.setOf(types);
} catch (IllegalArgumentException e) {
throw MailServiceException.INVALID_TYPE(e.getMessage());
}
sysTypes.clear();
// do not include conversations even when requested
// (to be compatible with 7.1.4 and later. bug 67407)
searchTypes.remove(MailItem.Type.CONVERSATION);
}
if (lock != null && (lock.equals("1") || lock.equals("t") || lock.equals("true"))) {
maintenance = MailboxManager.getInstance().beginMaintenance(context.targetMailbox.getAccountId(), context.targetMailbox.getId());
}
Charset charset = context.getCharset();
CharsetEncoder encoder = charset.newEncoder();
if (context.requestedItems != null) {
try {
for (UserServletContext.Item item : context.requestedItems) aos = saveItem(context, item.mailItem, fldrs, cnts, item.versioned, aos, encoder, names);
} catch (Exception e) {
warn(e);
}
} else if (context.target != null && !(context.target instanceof Folder)) {
try {
aos = saveItem(context, context.target, fldrs, cnts, false, aos, encoder, names);
} catch (Exception e) {
warn(e);
}
} else {
ZimbraQueryResults results = null;
boolean saveTargetFolder = false;
if (context.target instanceof Folder) {
Folder f = (Folder) context.target;
if (f.getId() != Mailbox.ID_FOLDER_USER_ROOT) {
saveTargetFolder = true;
query = "under:\"" + f.getPath() + "\"" + (query == null ? "" : " " + query);
}
}
int maxDays = context.targetAccount.getIntAttr(Provisioning.A_zimbraExportMaxDays, 0);
if (maxDays > 0) {
if (context.getStartTime() == TIME_UNSPECIFIED || context.getEndTime() == TIME_UNSPECIFIED || context.getEndTime() == 0) {
ZimbraLog.misc.warn("Export rejected. start and end param must be set. end param must be non-zero");
throw new ExportPeriodNotSpecifiedException(maxDays);
} else if (context.getEndTime() - context.getStartTime() > maxDays * Constants.MILLIS_PER_DAY) {
long requestDays = (long) Math.ceil((double) (context.getEndTime() - context.getStartTime()) / Constants.MILLIS_PER_DAY);
ZimbraLog.misc.warn("Export rejected. Specified period %d days is longer than zimbraExportMaxDays %d days.", requestDays, maxDays);
throw new ExportPeriodTooLongException(requestDays, maxDays);
}
}
String taskQuery = query;
if (query == null) {
query = "";
}
String calendarQuery = query;
if (context.getStartTime() != TIME_UNSPECIFIED) {
query = query + " after:" + context.getStartTime();
calendarQuery = calendarQuery + " appt-start:>=" + context.getStartTime();
}
if (context.getEndTime() != TIME_UNSPECIFIED) {
query = query + " before:" + context.getEndTime();
calendarQuery = calendarQuery + " appt-end:<" + context.getEndTime();
}
if (query == null || query.equals("")) {
SortPath sp = new SortPath();
for (MailItem.Type type : sysTypes) {
List<MailItem> items = context.targetMailbox.getItemList(context.opContext, type);
Collections.sort(items, sp);
for (MailItem item : items) {
aos = saveItem(context, item, fldrs, cnts, false, aos, encoder, names);
}
}
query = "is:local";
}
Map<Set<MailItem.Type>, String> typesMap = new HashMap<Set<MailItem.Type>, String>();
typesMap.put(searchTypes, query);
if (context.getStartTime() != TIME_UNSPECIFIED || context.getEndTime() != TIME_UNSPECIFIED) {
if (searchTypes.contains(MailItem.Type.APPOINTMENT)) {
searchTypes.remove(MailItem.Type.APPOINTMENT);
Set<MailItem.Type> calendarTypes = new HashSet<MailItem.Type>();
calendarTypes.add(MailItem.Type.APPOINTMENT);
typesMap.put(calendarTypes, calendarQuery);
}
if (searchTypes.contains(MailItem.Type.TASK)) {
searchTypes.remove(MailItem.Type.TASK);
Set<MailItem.Type> taskTypes = new HashSet<MailItem.Type>();
taskTypes.add(MailItem.Type.TASK);
typesMap.put(taskTypes, (StringUtil.isNullOrEmpty(taskQuery)) ? "is:local" : taskQuery);
}
}
for (Map.Entry<Set<MailItem.Type>, String> entry : typesMap.entrySet()) {
results = context.targetMailbox.index.search(context.opContext, entry.getValue(), entry.getKey(), SortBy.NONE, LC.zimbra_archive_formatter_search_chunk_size.intValue());
try {
while (results.hasNext()) {
if (saveTargetFolder) {
saveTargetFolder = false;
aos = saveItem(context, context.target, fldrs, cnts, false, aos, encoder, names);
}
aos = saveItem(context, results.getNext().getMailItem(), fldrs, cnts, false, aos, encoder, names);
}
Closeables.closeQuietly(results);
results = null;
} catch (Exception e) {
warn(e);
} finally {
Closeables.closeQuietly(results);
}
}
}
if (aos == null) {
if (emptyname == null) {
context.resp.setHeader("Content-Disposition", null);
throw new UserServletException(HttpServletResponse.SC_NO_CONTENT, "No data found");
}
context.resp.setHeader("Content-Disposition", HttpUtil.createContentDisposition(context.req, Part.ATTACHMENT, emptyname));
aos = getOutputStream(context, UTF8);
}
} finally {
if (maintenance != null) {
MailboxManager.getInstance().endMaintenance(maintenance, true, true);
}
if (aos != null) {
try {
aos.close();
} catch (Exception e) {
}
}
}
}
use of com.zimbra.cs.service.UserServletException in project zm-mailbox by Zimbra.
the class IfbFormatter method formatCallback.
@Override
public void formatCallback(UserServletContext context) throws IOException, ServiceException, UserServletException {
context.resp.setCharacterEncoding("UTF-8");
context.resp.setContentType(MimeConstants.CT_TEXT_CALENDAR);
long rangeStart = context.getStartTime();
long rangeEnd = context.getEndTime();
if (rangeEnd < rangeStart)
throw new UserServletException(HttpServletResponse.SC_BAD_REQUEST, "End time must be after Start time");
long days = (rangeEnd - rangeStart) / Constants.MILLIS_PER_DAY;
long maxDays = LC.calendar_freebusy_max_days.longValueWithinRange(0, 36600);
if (days > maxDays)
throw new UserServletException(HttpServletResponse.SC_BAD_REQUEST, "Requested range is too large (Maximum " + maxDays + " days)");
String acctName = null;
FreeBusy fb = null;
if (context.targetMailbox != null) {
String exuid = context.params.get(UserServlet.QP_EXUID);
Appointment exAppt = null;
if (exuid != null) {
CalendarItem ci = context.targetMailbox.getCalendarItemByUid(context.opContext, exuid);
if (ci instanceof Appointment)
exAppt = (Appointment) ci;
}
acctName = context.targetMailbox.getAccount().getName();
fb = context.targetMailbox.getFreeBusy(context.opContext, acctName, rangeStart, rangeEnd, context.getFreeBusyCalendar(), exAppt);
} else {
// Unknown mailbox. Fake an always-free response, to avoid harvest attacks.
acctName = fixupAccountName(context.accountPath);
fb = FreeBusy.emptyFreeBusy(acctName, rangeStart, rangeEnd);
}
String fbFormat = context.params.get(UserServlet.QP_FBFORMAT);
String fbMsg;
if ("event".equalsIgnoreCase(fbFormat)) {
fbMsg = fb.toVCalendarAsVEvents();
} else {
String url = context.req.getRequestURL() + "?" + context.req.getQueryString();
fbMsg = fb.toVCalendar(FreeBusy.Method.PUBLISH, acctName, null, url);
}
context.resp.getOutputStream().write(fbMsg.getBytes("UTF-8"));
}
Aggregations