use of com.zimbra.cs.service.admin.AdminDocumentHandler in project zm-mailbox by Zimbra.
the class TestServerEnumeration method testModifyCalresSufficientPermissions.
@Test
public void testModifyCalresSufficientPermissions() throws Exception {
List<AdminRight> relatedRights = new ArrayList<AdminRight>();
List<String> notes = new ArrayList<String>();
AdminDocumentHandler handler = new ModifyCalendarResource();
handler.docRights(relatedRights, notes);
createDelegatedAdmin(relatedRights);
grantRightToAdmin(adminSoapProv, com.zimbra.soap.type.TargetType.fromString(com.zimbra.cs.account.accesscontrol.TargetType.calresource.toString()), MY_CALRES, DELEGATED_ADMIN_NAME, Admin.R_modifyCalendarResource.getName());
grantRightToAdmin(adminSoapProv, com.zimbra.soap.type.TargetType.fromString(com.zimbra.cs.account.accesscontrol.TargetType.global.toString()), null, DELEGATED_ADMIN_NAME, Admin.R_listServer.getName());
adminSoapProv.flushCache(CacheEntryType.acl, null);
ModifyCalendarResourceRequest req = new ModifyCalendarResourceRequest(myCalRes.getId());
req.addAttr(new Attr(Provisioning.A_zimbraMailHost, NON_EXISTING_SERVER));
req.addAttr(new Attr(Provisioning.A_description, "test description"));
try {
delegatedSoapProv.invokeJaxb(req);
fail("should have caught an exception");
} catch (SoapFaultException e) {
assertEquals("should be getting 'no such server' response", AccountServiceException.NO_SUCH_SERVER, e.getCode());
}
}
use of com.zimbra.cs.service.admin.AdminDocumentHandler in project zm-mailbox by Zimbra.
the class TestServerEnumeration method testModifyAccount.
@Test
public void testModifyAccount() throws Exception {
List<AdminRight> relatedRights = new ArrayList<AdminRight>();
List<String> notes = new ArrayList<String>();
AdminDocumentHandler handler = new ModifyAccount();
handler.docRights(relatedRights, notes);
createDelegatedAdmin(relatedRights);
grantRightToAdmin(adminSoapProv, com.zimbra.soap.type.TargetType.fromString(com.zimbra.cs.account.accesscontrol.TargetType.account.toString()), MY_USER, DELEGATED_ADMIN_NAME, Admin.R_modifyAccount.getName());
adminSoapProv.flushCache(CacheEntryType.acl, null);
ModifyAccountRequest req = new ModifyAccountRequest(myUser.getId());
req.addAttr(new Attr(Provisioning.A_zimbraMailHost, NON_EXISTING_SERVER));
req.addAttr(new Attr(Provisioning.A_description, "test description"));
try {
delegatedSoapProv.invokeJaxb(req);
fail("should have caught an exception");
} catch (SoapFaultException e) {
assertEquals("should be getting 'Permission Denied' response", ServiceException.PERM_DENIED, e.getCode());
}
}
use of com.zimbra.cs.service.admin.AdminDocumentHandler in project zm-mailbox by Zimbra.
the class TestServerEnumeration method testModifyAccountSufficientPermissions.
@Test
public void testModifyAccountSufficientPermissions() throws Exception {
List<AdminRight> relatedRights = new ArrayList<AdminRight>();
List<String> notes = new ArrayList<String>();
AdminDocumentHandler handler = new ModifyAccount();
handler.docRights(relatedRights, notes);
createDelegatedAdmin(relatedRights);
grantRightToAdmin(adminSoapProv, com.zimbra.soap.type.TargetType.fromString(com.zimbra.cs.account.accesscontrol.TargetType.account.toString()), MY_USER, DELEGATED_ADMIN_NAME, Admin.R_modifyAccount.getName());
grantRightToAdmin(adminSoapProv, com.zimbra.soap.type.TargetType.fromString(com.zimbra.cs.account.accesscontrol.TargetType.global.toString()), null, DELEGATED_ADMIN_NAME, Admin.R_listServer.getName());
adminSoapProv.flushCache(CacheEntryType.acl, null);
ModifyAccountRequest req = new ModifyAccountRequest(myUser.getId());
req.addAttr(new Attr(Provisioning.A_zimbraMailHost, NON_EXISTING_SERVER));
req.addAttr(new Attr(Provisioning.A_description, "test description"));
try {
delegatedSoapProv.invokeJaxb(req);
fail("should have caught an exception");
} catch (SoapFaultException e) {
assertEquals("should be getting 'no such server' response", AccountServiceException.NO_SUCH_SERVER, e.getCode());
}
}
use of com.zimbra.cs.service.admin.AdminDocumentHandler in project zm-mailbox by Zimbra.
the class DocumentDispatcher method registerHandler.
public void registerHandler(QName qname, DocumentHandler handler) {
if (handler instanceof AdminDocumentHandler) {
if (!(includeList == null) && !includeList.isEmpty() && !includeList.contains(String.format("%s::%s", qname.getNamespaceURI(), qname.getQualifiedName()))) {
ZimbraLog.soap.debug("skipping %s::%s", qname.getNamespaceURI(), qname.getQualifiedName());
return;
}
ZimbraLog.soap.debug("Registering %s::%s", qname.getNamespaceURI(), qname.getQualifiedName());
}
handlers.put(qname, handler);
QName respQName = responses.get(qname);
if (respQName == null) {
String reqName = qname.getName();
String respName;
if (reqName.endsWith(REQUEST_SUFFIX)) {
respName = reqName.substring(0, reqName.length() - REQUEST_SUFFIX.length()) + RESPONSE_SUFFIX;
} else {
respName = reqName + RESPONSE_SUFFIX;
}
respQName = new QName(respName, qname.getNamespace());
responses.put(qname, respQName);
}
handler.setResponseQName(respQName);
}
use of com.zimbra.cs.service.admin.AdminDocumentHandler in project zm-mailbox by Zimbra.
the class SoapEngine method dispatchRequest.
/**
* Handles individual requests, either direct or from a batch
*/
Element dispatchRequest(DocumentHandler handler, Element soapReqElem, Map<String, Object> context, ZimbraSoapContext zsc) {
long startTime = System.currentTimeMillis();
SoapProtocol soapProto = zsc.getResponseProtocol();
if (soapReqElem == null) {
return soapFault(soapProto, "cannot dispatch request", ServiceException.INVALID_REQUEST("no document specified", null));
}
if (handler == null) {
return soapFault(soapProto, "cannot dispatch request", ServiceException.UNKNOWN_DOCUMENT(soapReqElem.getQualifiedName(), null));
}
if (RedoLogProvider.getInstance().isSlave() && !handler.isReadOnly()) {
return soapFault(soapProto, "cannot dispatch request", ServiceException.NON_READONLY_OPERATION_DENIED());
}
AuthToken at = zsc.getAuthToken();
boolean needsAuth = handler.needsAuth(context);
boolean needsAdminAuth = handler.needsAdminAuth(context);
if ((needsAuth || needsAdminAuth) && at == null) {
return soapFault(soapProto, "cannot dispatch request", ServiceException.AUTH_REQUIRED());
}
Element response = null;
SoapTransport.setVia(zsc.getNextVia());
try {
Provisioning prov = Provisioning.getInstance();
if (!prov.getLocalServer().getBooleanAttr(Provisioning.A_zimbraUserServicesEnabled, true) && !(handler instanceof AdminDocumentHandler)) {
return soapFault(soapProto, "cannot dispatch request", ServiceException.TEMPORARILY_UNAVAILABLE());
}
if (needsAdminAuth) {
AdminAccessControl aac = AdminAccessControl.getAdminAccessControl(at);
if (!aac.isSufficientAdminForSoap(context, handler)) {
return soapFault(soapProto, "cannot dispatch request", ServiceException.PERM_DENIED("need adequate admin token"));
}
}
String acctId = null;
boolean isGuestAccount = true;
boolean delegatedAuth = false;
if (at != null) {
acctId = at.getAccountId();
isGuestAccount = acctId.equals(GuestAccount.GUID_PUBLIC);
delegatedAuth = at.isDelegatedAuth();
}
if (!isGuestAccount) {
Account acct = null;
if (needsAuth || needsAdminAuth) {
try {
acct = AuthProvider.validateAuthToken(prov, at, false);
} catch (ServiceException e) {
return soapFault(soapProto, null, e);
}
// also, make sure that the target account (if any) is active
if (zsc.isDelegatedRequest() && !handler.isAdminCommand()) {
Account target = DocumentHandler.getRequestedAccount(zsc);
// treat the account as inactive if (a) it doesn't exist, (b) it's in maintenance mode, or (c) we're non-admins and it's not "active"
boolean inactive = target == null || Provisioning.ACCOUNT_STATUS_MAINTENANCE.equals(target.getAccountStatus(prov));
if (!inactive && (!at.isAdmin() || !AccessManager.getInstance().canAccessAccount(at, target))) {
inactive = !target.getAccountStatus(prov).equals(Provisioning.ACCOUNT_STATUS_ACTIVE);
}
if (inactive) {
return soapFault(soapProto, "target account is not active", AccountServiceException.ACCOUNT_INACTIVE(target == null ? zsc.getRequestedAccountId() : target.getName()));
}
}
}
// fault in a session for this handler (if necessary) before executing the command
context.put(ZIMBRA_SESSION, handler.getSession(zsc));
// try to proxy the request if necessary (don't proxy commands that don't require auth)
if ((needsAuth || needsAdminAuth) && acct != null) {
response = handler.proxyIfNecessary(soapReqElem, context);
}
}
// if no proxy, execute the request locally
if (response == null) {
if (delegatedAuth) {
handler.logAuditAccess(at.getAdminAccountId(), acctId, acctId);
}
response = handler.handle(soapReqElem, context);
ZimbraPerf.SOAP_TRACKER.addStat(getStatName(soapReqElem), startTime);
long duration = System.currentTimeMillis() - startTime;
if (LC.zimbra_slow_logging_enabled.booleanValue() && duration > LC.zimbra_slow_logging_threshold.longValue() && !soapReqElem.getQName().getName().equals(MailConstants.SYNC_REQUEST.getName())) {
ZimbraLog.soap.warn("Slow SOAP request (start=" + startTime + "):\n" + soapReqElem.prettyPrint(true));
ZimbraLog.soap.warn("Slow SOAP response (time=" + duration + "):\n" + response.prettyPrint());
}
}
} catch (SoapFaultException e) {
response = e.getFault() != null ? e.getFault().detach() : soapProto.soapFault(ServiceException.FAILURE(e.toString(), e));
if (!e.isSourceLocal()) {
LOG.debug("handler exception", e);
}
} catch (AuthFailedServiceException e) {
HttpServletRequest httpReq = (HttpServletRequest) context.get(SoapServlet.SERVLET_REQUEST);
httpReq.setAttribute(ZimbraInvalidLoginFilter.AUTH_FAILED, Boolean.TRUE);
String clientIp = (String) context.get(SoapEngine.REQUEST_IP);
httpReq.setAttribute(SoapEngine.REQUEST_IP, clientIp);
response = soapProto.soapFault(e);
if (LOG.isDebugEnabled()) {
LOG.debug("handler exception: %s%s", e.getMessage(), e.getReason(", %s"), e);
} else {
// Don't log stack trace for auth failures, since they commonly happen
LOG.info("handler exception: %s%s", e.getMessage(), e.getReason(", %s"));
}
} catch (ServiceException e) {
response = soapFault(soapProto, "handler exception", e);
// XXX: if the session was new, do we want to delete it?
} catch (Throwable e) {
// don't interfere with Jetty Continuations -- pass the exception on up
if (e.getClass().getName().equals("org.eclipse.jetty.continuation.ContinuationThrowable")) {
throw (Error) e;
}
// TODO: better exception stack traces during develope?
response = soapProto.soapFault(ServiceException.FAILURE(e.toString(), e));
if (e instanceof OutOfMemoryError) {
Zimbra.halt("handler exception", e);
}
LOG.warn("handler exception", e);
// XXX: if the session was new, do we want to delete it?
} finally {
SoapTransport.clearVia();
}
return response;
}
Aggregations