/** Test case where the current user has both the namespace and the appropriate permissions. */ @Test public void checkPermissionAssertNoExceptionWhenHasPermissions() throws Exception { // Mock a join point of the method call // mockMethod("foo"); JoinPoint joinPoint = mock(JoinPoint.class); MethodSignature methodSignature = mock(MethodSignature.class); Method method = NamespaceSecurityAdviceTest.class.getDeclaredMethod("mockMethod", String.class); when(methodSignature.getParameterNames()).thenReturn(new String[] {"namespace"}); when(methodSignature.getMethod()).thenReturn(method); when(joinPoint.getSignature()).thenReturn(methodSignature); when(joinPoint.getArgs()).thenReturn(new Object[] {"foo"}); String userId = "userId"; ApplicationUser applicationUser = new ApplicationUser(getClass()); applicationUser.setUserId(userId); applicationUser.setNamespaceAuthorizations(new HashSet<>()); applicationUser .getNamespaceAuthorizations() .add(new NamespaceAuthorization("foo", Arrays.asList(NamespacePermissionEnum.READ))); SecurityContextHolder.getContext() .setAuthentication( new TestingAuthenticationToken( new SecurityUserWrapper( userId, "", false, false, false, false, Arrays.asList(), applicationUser), null)); try { namespaceSecurityAdvice.checkPermission(joinPoint); } catch (AccessDeniedException e) { fail(); } }
/** * Asserts that the namespace security advice is enabled. Try calling a secured method with a mock * user in the context with invalid permissions. The expectation is that the method call fails * with AccessDeniedException if the advice is enabled. */ @Test public void assertAdviceEnabled() { // put a fake user with no permissions into the security context // the security context is cleared on the after() method of this test suite String username = "******"; Class<?> generatedByClass = getClass(); ApplicationUser applicationUser = new ApplicationUser(generatedByClass); applicationUser.setUserId(username); applicationUser.setNamespaceAuthorizations(Collections.emptySet()); SecurityContextHolder.getContext() .setAuthentication( new TestingAuthenticationToken( new SecurityUserWrapper( username, "password", false, false, false, false, Collections.emptyList(), applicationUser), null)); try { businessObjectDefinitionService.createBusinessObjectDefinition( new BusinessObjectDefinitionCreateRequest( NAMESPACE, BDEF_NAME, DATA_PROVIDER_NAME, null, null, null)); fail(); } catch (Exception e) { assertEquals(AccessDeniedException.class, e.getClass()); } }
@Test public void checkPermissionAssertErrorWhenAnnotationFieldRefersToNonString() throws Exception { // Mock a join point of the method call // mockMethod(1); JoinPoint joinPoint = mock(JoinPoint.class); MethodSignature methodSignature = mock(MethodSignature.class); Method method = NamespaceSecurityAdviceTest.class.getDeclaredMethod("mockMethod", Integer.class); when(methodSignature.getParameterNames()).thenReturn(new String[] {"aNumber"}); when(methodSignature.getMethod()).thenReturn(method); when(joinPoint.getSignature()).thenReturn(methodSignature); when(joinPoint.getArgs()).thenReturn(new Object[] {1}); String userId = "userId"; ApplicationUser applicationUser = new ApplicationUser(getClass()); applicationUser.setUserId(userId); applicationUser.setNamespaceAuthorizations(new HashSet<>()); SecurityContextHolder.getContext() .setAuthentication( new TestingAuthenticationToken( new SecurityUserWrapper( userId, "", false, false, false, false, Arrays.asList(), applicationUser), null)); try { namespaceSecurityAdvice.checkPermission(joinPoint); fail(); } catch (Exception e) { assertEquals(IllegalStateException.class, e.getClass()); assertEquals( "Object must be of type class java.lang.String or interface java.util.Collection. Actual object.class = class java.lang.Integer", e.getMessage()); } }
@Test public void checkPermissionAssertAccessDeniedWhenComplexCaseAndUserHasWrongPermission() throws Exception { // Mock a join point of the method call // mockMethod(request); JoinPoint joinPoint = mock(JoinPoint.class); MethodSignature methodSignature = mock(MethodSignature.class); Method method = NamespaceSecurityAdviceTest.class.getDeclaredMethod( "mockMethod", BusinessObjectDataNotificationRegistrationCreateRequest.class); when(methodSignature.getParameterNames()).thenReturn(new String[] {"request"}); when(methodSignature.getMethod()).thenReturn(method); when(joinPoint.getSignature()).thenReturn(methodSignature); BusinessObjectDataNotificationRegistrationCreateRequest request = new BusinessObjectDataNotificationRegistrationCreateRequest(); request.setBusinessObjectDataNotificationRegistrationKey( new NotificationRegistrationKey("ns1", null)); request.setBusinessObjectDataNotificationFilter( new BusinessObjectDataNotificationFilter("ns2", null, null, null, null, null, null, null)); request.setJobActions( Arrays.asList(new JobAction("ns3", null, null), new JobAction("ns4", null, null))); when(joinPoint.getArgs()).thenReturn(new Object[] {request}); String userId = "userId"; ApplicationUser applicationUser = new ApplicationUser(getClass()); applicationUser.setUserId(userId); applicationUser.setNamespaceAuthorizations(new HashSet<>()); applicationUser .getNamespaceAuthorizations() .add(new NamespaceAuthorization("ns1", Arrays.asList(NamespacePermissionEnum.WRITE))); applicationUser .getNamespaceAuthorizations() .add(new NamespaceAuthorization("ns2", Arrays.asList(NamespacePermissionEnum.READ))); applicationUser .getNamespaceAuthorizations() .add(new NamespaceAuthorization("ns3", Arrays.asList(NamespacePermissionEnum.EXECUTE))); // User does not have the expected EXECUTE permission on ns4 applicationUser .getNamespaceAuthorizations() .add(new NamespaceAuthorization("ns4", Arrays.asList(NamespacePermissionEnum.READ))); SecurityContextHolder.getContext() .setAuthentication( new TestingAuthenticationToken( new SecurityUserWrapper( userId, "", false, false, false, false, Arrays.asList(), applicationUser), null)); try { namespaceSecurityAdvice.checkPermission(joinPoint); fail(); } catch (Exception e) { assertEquals(AccessDeniedException.class, e.getClass()); assertEquals( String.format( "User \"%s\" does not have \"[EXECUTE]\" permission(s) to the namespace \"ns4\"", userId), e.getMessage()); } }
@Test public void checkPermissionAssertAccessDeniedWhenUserRequiresMultiplePermissionsButIsMissingOne() throws Exception { // Mock a join point of the method call // mockMethodMultiplePermissions("foo"); JoinPoint joinPoint = mock(JoinPoint.class); MethodSignature methodSignature = mock(MethodSignature.class); Method method = NamespaceSecurityAdviceTest.class.getDeclaredMethod( "mockMethodMultiplePermissions", String.class); when(methodSignature.getMethod()).thenReturn(method); when(methodSignature.getParameterNames()).thenReturn(new String[] {"namespace"}); when(joinPoint.getSignature()).thenReturn(methodSignature); when(joinPoint.getArgs()).thenReturn(new Object[] {"foo"}); String userId = "userId"; ApplicationUser applicationUser = new ApplicationUser(getClass()); applicationUser.setUserId(userId); applicationUser.setNamespaceAuthorizations(new HashSet<>()); // User requires both READ and WRITE, but only has READ applicationUser .getNamespaceAuthorizations() .add(new NamespaceAuthorization("foo", Arrays.asList(NamespacePermissionEnum.READ))); SecurityContextHolder.getContext() .setAuthentication( new TestingAuthenticationToken( new SecurityUserWrapper( userId, "", false, false, false, false, Arrays.asList(), applicationUser), null)); try { namespaceSecurityAdvice.checkPermission(joinPoint); fail(); } catch (Exception e) { assertEquals(AccessDeniedException.class, e.getClass()); assertEquals( String.format( "User \"%s\" does not have \"[READ, WRITE]\" permission(s) to the namespace \"foo\"", userId), e.getMessage()); } }
@Test public void checkPermissionAssertMultipleAccessDeniedExceptionsAreGatheredIntoSingleMessageWhenMultipleAnnotations() throws Exception { // Mock a join point of the method call // mockMethodMultipleAnnotations("namespace1", "namespace2"); JoinPoint joinPoint = mock(JoinPoint.class); MethodSignature methodSignature = mock(MethodSignature.class); Method method = NamespaceSecurityAdviceTest.class.getDeclaredMethod( "mockMethodMultipleAnnotations", String.class, String.class); when(methodSignature.getParameterNames()).thenReturn(new String[] {"namespace1", "namespace2"}); when(methodSignature.getMethod()).thenReturn(method); when(joinPoint.getSignature()).thenReturn(methodSignature); when(joinPoint.getArgs()).thenReturn(new Object[] {"foo", "bar"}); String userId = "userId"; ApplicationUser applicationUser = new ApplicationUser(getClass()); applicationUser.setUserId(userId); applicationUser.setNamespaceAuthorizations(new HashSet<>()); // User has no permissions SecurityContextHolder.getContext() .setAuthentication( new TestingAuthenticationToken( new SecurityUserWrapper( userId, "", false, false, false, false, Arrays.asList(), applicationUser), null)); try { namespaceSecurityAdvice.checkPermission(joinPoint); fail(); } catch (Exception e) { assertEquals(AccessDeniedException.class, e.getClass()); assertEquals( String.format( "User \"%s\" does not have \"[READ]\" permission(s) to the namespace \"foo\"%n" + "User \"%s\" does not have \"[WRITE]\" permission(s) to the namespace \"bar\"", userId, userId), e.getMessage()); } }