use of com.zimbra.cs.mailbox.acl.FolderACL in project zm-mailbox by Zimbra.
the class InviteFallback method doCheckRight.
//
// allow the invite right if the authed user has admin folder right on the default calendar folder
// (calendar folder in which the appointment is to be updated when the owner of the calendar receives
// an invite)
//
protected Boolean doCheckRight(Account authedAcct, Entry target, boolean asAdmin) throws ServiceException {
// Don't do anything unless running inside the server
if (!Zimbra.started())
return null;
if (!(target instanceof Account))
return null;
Account targetAcct = (Account) target;
OperationContext octxt = new OperationContext(authedAcct, asAdmin);
int defaultCalendarfolderId = Mailbox.ID_FOLDER_CALENDAR;
FolderACL folderACL = new FolderACL(octxt, targetAcct, defaultCalendarfolderId, Boolean.FALSE);
// bug 42146
// admin rights (granted by UI): rwidxa
// manager rights (granted by UI): rwidx
//
// don't need the action right - it's for accepting/denying invites on behave of the invitee
// don't need the admin right - it's for granting/revoking rights on the owner's folder
//
// don't worry about the private right: we are checking if the authed user can invite(public/private)
// the target user, the authed user is composing the invite and he sees what's in his invite anyway.
//
short rightsNeeded = ACL.RIGHT_READ | ACL.RIGHT_WRITE | ACL.RIGHT_INSERT | ACL.RIGHT_DELETE;
boolean hasRights = folderACL.canAccess(rightsNeeded);
if (hasRights)
return Boolean.TRUE;
else
return null;
}
use of com.zimbra.cs.mailbox.acl.FolderACL in project zm-mailbox by Zimbra.
the class TestFolderACLCache method doTest.
/*
* To test remote: hardcode FolderACL.ShareTarget.onLocalServer() to return false.
* make sure you change it back after testing
*/
private void doTest(Account authedAcct, String ownerAcctId, int targetFolderId, short expectedEffectivePermissions, short needRightsForCanAccessTest, boolean expectedCanAccess) throws ServiceException {
OperationContext octxt;
if (authedAcct == null)
octxt = null;
else
octxt = new OperationContext(authedAcct);
FolderACL folderAcl = new FolderACL(octxt, ownerAcctId, targetFolderId);
short effectivePermissions = folderAcl.getEffectivePermissions();
boolean canAccess = folderAcl.canAccess(needRightsForCanAccessTest);
boolean good = false;
// mask out the create folder right, it is an internal right, which is returned
// by getEffectivePermissions if owner is on local server but not returned if
// the owner is remote.
//
// The diff is not a real bug and can be ignored
short actual = effectivePermissions;
short expected = expectedEffectivePermissions;
if (actual == -1)
actual = ACL.stringToRights(ACL.rightsToString(actual));
if (expected == -1)
expected = ACL.stringToRights(ACL.rightsToString(expected));
Assert.assertEquals(expected, actual);
Assert.assertEquals(expectedCanAccess, canAccess);
good = true;
ZimbraLog.test.debug("Test %s:authedAcct='%s' targetFolderId='%s' %s\n effectivePermissions: %s (expected: %s)\n" + " canAccess: %s (expected: %s)", testName, authedAcct, targetFolderId, (!good ? "***FAILED***" : ""), formatRights(effectivePermissions), formatRights(expectedEffectivePermissions), canAccess, expectedCanAccess);
}
use of com.zimbra.cs.mailbox.acl.FolderACL in project zm-mailbox by Zimbra.
the class CalSummaryCache method getCalendarSummary.
// get summary for all appts/tasks in a calendar folder
public CalendarDataResult getCalendarSummary(OperationContext octxt, String targetAcctId, int folderId, MailItem.Type type, long rangeStart, long rangeEnd, boolean computeSubRange) throws ServiceException {
if (rangeStart > rangeEnd)
throw ServiceException.INVALID_REQUEST("End time must be after Start time", null);
Account targetAcct = Provisioning.getInstance().get(AccountBy.id, targetAcctId);
if (targetAcct == null)
return null;
boolean targetAcctOnLocalServer = Provisioning.onLocalServer(targetAcct);
CalendarDataResult result = new CalendarDataResult();
if (!LC.calendar_cache_enabled.booleanValue()) {
ZimbraPerf.COUNTER_CALENDAR_CACHE_HIT.increment(0);
ZimbraPerf.COUNTER_CALENDAR_CACHE_MEM_HIT.increment(0);
if (!targetAcctOnLocalServer)
return null;
Mailbox mbox = MailboxManager.getInstance().getMailboxByAccount(targetAcct);
Folder folder = mbox.getFolderById(octxt, folderId);
Account authAcct = octxt != null ? octxt.getAuthenticatedUser() : null;
boolean asAdmin = octxt != null ? octxt.isUsingAdminPrivileges() : false;
result.allowPrivateAccess = CalendarItem.allowPrivateAccess(folder, authAcct, asAdmin);
result.data = reloadCalendarOverRangeWithFolderScan(octxt, mbox, folderId, type, rangeStart, rangeEnd, null);
if (ZimbraLog.calendar.isDebugEnabled()) {
ZimbraLog.calendar.debug("Calendar Summary for %s reloaded (no cache) - %s items private=%s", folder.getName(), result.data.getNumItems(), result.allowPrivateAccess);
}
return result;
}
// Check if we have read permission.
short perms;
try {
FolderACL facl = new FolderACL(octxt, targetAcctId, folderId);
perms = facl.getEffectivePermissions();
} catch (ServiceException se) {
ZimbraLog.calendar.warn("Problem discovering ACLs for folder %s:%s", targetAcctId, folderId, se);
throw ServiceException.PERM_DENIED("problem determining whether you have sufficient permissions on folder " + targetAcctId + ":" + folderId + " (" + se.getMessage() + ")");
}
if ((short) (perms & ACL.RIGHT_READ) != ACL.RIGHT_READ)
throw ServiceException.PERM_DENIED("you do not have sufficient permissions on folder " + targetAcctId + ":" + folderId);
result.allowPrivateAccess = (short) (perms & ACL.RIGHT_PRIVATE) == ACL.RIGHT_PRIVATE;
// Look up from memcached.
CalSummaryKey key = new CalSummaryKey(targetAcctId, folderId);
CalendarData calData = mMemcachedCache.getForRange(key, rangeStart, rangeEnd);
if (calData != null) {
ZimbraPerf.COUNTER_CALENDAR_CACHE_HIT.increment(1);
ZimbraPerf.COUNTER_CALENDAR_CACHE_MEM_HIT.increment(1);
result.data = calData;
if (ZimbraLog.calendar.isDebugEnabled()) {
ZimbraLog.calendar.debug("Calendar Summary for %s:%s reloaded (memcached) - %s items private=%s", targetAcctId, folderId, result.data.getNumItems(), result.allowPrivateAccess);
}
return result;
}
// If not found in memcached and account is not on local server, we're done.
if (!targetAcctOnLocalServer) {
if (ZimbraLog.calendar.isDebugEnabled()) {
ZimbraLog.calendar.debug("Calendar Summary - ignoring non-local %s:%s", targetAcctId, folderId);
}
return null;
}
int lruSize = 0;
CacheLevel dataFrom = CacheLevel.Memory;
boolean incrementalUpdate = sMaxStaleItems > 0;
Mailbox mbox = MailboxManager.getInstance().getMailboxByAccountId(targetAcctId);
// ACL check occurs here.
Folder folder = mbox.getFolderById(octxt, folderId);
// All subsequent mailbox access is done as owner to avoid permission errors.
OperationContext ownerOctxt = new OperationContext(targetAcct);
int currentModSeq = folder.getImapMODSEQ();
// Lookup from heap LRU.
synchronized (mSummaryCache) {
if (mLRUCapacity > 0) {
calData = mSummaryCache.get(key);
lruSize = mSummaryCache.size();
}
}
if (calData != null) {
// Sanity check: Cached data can't be newer than the backend data.
if (calData.getModSeq() > currentModSeq) {
calData = null;
} else {
dataFrom = CacheLevel.Memory;
// Data loaded from heap LRU supports incremental update for stale items.
incrementalUpdate = sMaxStaleItems > 0;
}
}
if (calData == null) {
// Load from file.
try {
calData = FileStore.loadCalendarData(mbox.getId(), folderId, currentModSeq);
if (calData != null) {
// If data is up to date, add to LRU.
if (calData.getModSeq() == currentModSeq) {
if (mLRUCapacity > 0) {
synchronized (mSummaryCache) {
mSummaryCache.put(key, calData);
lruSize = mSummaryCache.size();
}
}
} else {
// Data loaded from file doesn't have stale items list. It can't be refreshed incrementally.
incrementalUpdate = false;
}
dataFrom = CacheLevel.File;
}
} catch (ServiceException e) {
ZimbraLog.calendar.warn("Error loading cached calendar summary", e);
}
}
CalendarData reusableCalData = null;
Pair<Long, Long> defaultRange = null;
if (calData != null) {
if (calData.getModSeq() != currentModSeq || calData.getNumStaleItems() > 0) {
// current data's range covers the requested range.
if (rangeStart >= calData.getRangeStart() && rangeEnd <= calData.getRangeEnd())
reusableCalData = calData;
// force recompute further down
calData = null;
} else if (rangeStart < calData.getRangeStart() || rangeEnd > calData.getRangeEnd()) {
// Requested range is not within cached range. Recompute cached range in the hope
// that the new range will cover the requested range.
defaultRange = Util.getMonthsRange(System.currentTimeMillis(), sRangeMonthFrom, sRangeNumMonths);
if (calData.getRangeStart() != defaultRange.getFirst() || calData.getRangeEnd() != defaultRange.getSecond()) {
calData = null;
}
}
}
// Recompute data if we must, and add to cache.
if (calData == null) {
if (defaultRange == null)
defaultRange = Util.getMonthsRange(System.currentTimeMillis(), sRangeMonthFrom, sRangeNumMonths);
calData = reloadCalendarOverRange(ownerOctxt, mbox, folderId, type, defaultRange.getFirst(), defaultRange.getSecond(), reusableCalData, incrementalUpdate);
synchronized (mSummaryCache) {
if (mLRUCapacity > 0) {
mSummaryCache.put(key, calData);
lruSize = mSummaryCache.size();
}
}
dataFrom = CacheLevel.Miss;
try {
// persist it
FileStore.saveCalendarData(mbox.getId(), calData);
} catch (ServiceException e) {
ZimbraLog.calendar.warn("Error persisting calendar summary cache", e);
}
}
assert (calData != null);
// Put data in memcached if it didn't come from memcached.
if (!CacheLevel.Memcached.equals(dataFrom))
mMemcachedCache.put(key, calData);
if (rangeStart >= calData.getRangeStart() && rangeEnd <= calData.getRangeEnd()) {
// Requested range is within cached range.
if (computeSubRange) {
result.data = calData.getSubRange(rangeStart, rangeEnd);
} else {
result.data = calData;
}
} else {
// Requested range is outside the currently cached range.
dataFrom = CacheLevel.Miss;
result.data = reloadCalendarOverRange(ownerOctxt, mbox, folderId, type, rangeStart, rangeEnd, reusableCalData, incrementalUpdate);
}
// COUNTER_CALENDAR_CACHE_MEM_HIT - A hit is a successful lookup from memory only.
switch(dataFrom) {
case Memory:
case Memcached:
ZimbraPerf.COUNTER_CALENDAR_CACHE_HIT.increment(1);
ZimbraPerf.COUNTER_CALENDAR_CACHE_MEM_HIT.increment(1);
break;
case File:
ZimbraPerf.COUNTER_CALENDAR_CACHE_HIT.increment(1);
ZimbraPerf.COUNTER_CALENDAR_CACHE_MEM_HIT.increment(0);
break;
case Miss:
default:
ZimbraPerf.COUNTER_CALENDAR_CACHE_HIT.increment(0);
ZimbraPerf.COUNTER_CALENDAR_CACHE_MEM_HIT.increment(0);
break;
}
ZimbraPerf.COUNTER_CALENDAR_CACHE_LRU_SIZE.increment(lruSize);
if (ZimbraLog.calendar.isDebugEnabled()) {
ZimbraLog.calendar.debug("Calendar Summary for %s:%s reloaded (dataFrom=%s) - %s items private=%s", targetAcctId, folderId, dataFrom, (result.data == null) ? 0 : result.data.getNumItems(), result.allowPrivateAccess);
}
return result;
}
Aggregations