OrganizationPermissionsFilter extends CheMethodInvokerFilter { @Override protected void filter(GenericResourceMethod genericMethodResource, Object[] arguments) throws ApiException { final String methodName = genericMethodResource.getMethod().getName(); final Subject currentSubject = EnvironmentContext.getCurrent().getSubject(); String action; String organizationId; switch (methodName) { case CREATE_METHOD: final OrganizationDto organization = (OrganizationDto) arguments[0]; if (organization.getParent() != null) { organizationId = organization.getParent(); action = OrganizationDomain.MANAGE_SUBORGANIZATIONS; break; } return; case UPDATE_METHOD: organizationId = ((String) arguments[0]); action = OrganizationDomain.UPDATE; break; case REMOVE_METHOD: organizationId = ((String) arguments[0]); action = OrganizationDomain.DELETE; break; case GET_BY_PARENT_METHOD: organizationId = ((String) arguments[0]); action = OrganizationDomain.MANAGE_SUBORGANIZATIONS; if (superPrivilegesChecker.hasSuperPrivileges()) { return; } break; case GET_ORGANIZATIONS_METHOD: final String userId = (String) arguments[0]; if (userId != null && !userId.equals(currentSubject.getUserId()) && !superPrivilegesChecker.hasSuperPrivileges()) { throw new ForbiddenException("The user is able to specify only his own id"); } return; case GET_BY_ID_METHOD: case FIND_METHOD: return; default: throw new ForbiddenException("The user does not have permission to perform this operation"); } final Organization organization = manager.getById(organizationId); final String parentOrganizationId = organization.getParent(); if (parentOrganizationId != null && (OrganizationDomain.UPDATE.equals(action) || OrganizationDomain.DELETE.equals(action))) { if (currentSubject.hasPermission( OrganizationDomain.DOMAIN_ID, parentOrganizationId, MANAGE_SUBORGANIZATIONS)) { return; } } if (!currentSubject.hasPermission(DOMAIN_ID, organizationId, action)) { throw new ForbiddenException( "The user does not have permission to " + action + " organization with id '" + organizationId + "'"); } }    }
@Test public void shouldTestThatAllPublicMethodsAreCoveredByPermissionsFilter() throws Exception { final List<String> collect = Stream.of(OrganizationService.class.getDeclaredMethods()) .filter(method -> Modifier.isPublic(method.getModifiers())) .map(Method::getName) .collect(Collectors.toList()); assertEquals(collect.size(), 7); assertTrue(collect.contains(OrganizationPermissionsFilter.CREATE_METHOD)); assertTrue(collect.contains(OrganizationPermissionsFilter.UPDATE_METHOD)); assertTrue(collect.contains(OrganizationPermissionsFilter.REMOVE_METHOD)); assertTrue(collect.contains(OrganizationPermissionsFilter.GET_BY_PARENT_METHOD)); assertTrue(collect.contains(OrganizationPermissionsFilter.GET_ORGANIZATIONS_METHOD)); assertTrue(collect.contains(OrganizationPermissionsFilter.GET_BY_ID_METHOD)); assertTrue(collect.contains(OrganizationPermissionsFilter.FIND_METHOD)); }
@Test( expectedExceptions = ForbiddenException.class, expectedExceptionsMessageRegExp = "The user does not have permission to perform this operation") public void shouldThrowForbiddenExceptionWhenRequestedUnknownMethod() throws Exception { final GenericResourceMethod mock = mock(GenericResourceMethod.class); Method injectLinks = OrganizationService.class.getMethod("getServiceDescriptor"); when(mock.getMethod()).thenReturn(injectLinks); permissionsFilter.filter(mock, new Object[] {}); }