AccessChecker.javaCentral access control contract — 275 lines, 30+ methods. Described as "helper methods for evaluation of user and group access." Every page, every REST controller, every DAO calls this interface (via the static singleton) before performing protected operations. Implemented by AccessCheckerImpl (853 lines).
Method categories:
isUserMemberOfAdminGroup(), checkIsLoggedInUserMemberOfAdminGroup(), isLoggedInUserMemberOfAdminGroup() — variants with/without exception throwing, for both explicit user and context userisRestrictedUser(), isDemoUser(), checkRestrictedOrDemoUser() — demo user is detected by username "demo" (static helper on line 76 compares username), restricted user is a database flag. These checks prevent demo/restricted users from performing write operationsisUserMemberOfGroup(user, throwException, groups...) — checks against ProjectForgeGroup constants (ADMIN, FINANCE, HR, etc.). Varargs groups parameter means "at least one of" — user must be in any of the specified groupshasRight(), hasLoggedInUserRight(), checkUserRight() — evaluates registered UserRight instances by IUserRightId with demanded UserRightValue (TRUE/FALSE/INHERIT). Multiple values via varargs — "at least one must match"hasAccess(user, rightId, obj, oldObj, operationType, throwException), hasInsertAccess(), hasReadAccess(), hasWriteAccess() — the core entity-level permissions. When throwException=true, the check becomes mandatory — denial throws AccessExceptionhasPermission(user, taskId, accessType, operationType, throwException) — checks task-level access via the WBS task tree's group permissionsuserEquals(), userEqualsToContextUser(), areUsersInSameGroup() — utility methods for common user identity/similarity checkshasHistoryAccess(), hasLoggedInUserHistoryAccess() — whether the user can view an entity's change historyDesign pattern — throwException parameter: Many methods have a boolean throwException variant. When true, denial throws AccessException; when false, returns boolean. This allows callers to check access without exception handling overhead when they just need a yes/no answer, and get an automatic exception with i18n message when failure must abort the operation.
Exception hierarchy in method prefixes: check* methods (e.g. checkIsLoggedInUserMemberOfAdminGroup()) are void and always throw on failure. has* methods return boolean and only throw if throwException=true.