Search in sources :

Example 16 with MethodInvocation

use of org.aopalliance.intercept.MethodInvocation in project records-management by Alfresco.

the class RMMethodSecurityInterceptor method beforeInvocation.

/**
 * @see net.sf.acegisecurity.intercept.AbstractSecurityInterceptor#beforeInvocation(java.lang.Object)
 */
@Override
protected InterceptorStatusToken beforeInvocation(Object object) {
    InterceptorStatusToken result = null;
    try {
        // clear the capability report information
        RMMethodSecurityInterceptor.CAPABILITIES.remove();
        RMMethodSecurityInterceptor.IS_RM_SECURITY_CHECK.remove();
        RMMethodSecurityInterceptor.MESSAGES.remove();
        // before invocation (where method security check takes place)
        result = super.beforeInvocation(object);
    } catch (AccessDeniedException exception) {
        if (LOGGER.isDebugEnabled()) {
            MethodInvocation mi = (MethodInvocation) object;
            StringBuilder methodDetails = new StringBuilder("\n");
            if (RMMethodSecurityInterceptor.IS_RM_SECURITY_CHECK.get()) {
                methodDetails.append("RM method security check was performed.\n");
            } else {
                methodDetails.append("Standard DM method security check was performed.\n");
            }
            boolean first = true;
            methodDetails.append("Failed on method:  ").append(mi.getMethod().getName()).append("(");
            for (Object arg : mi.getArguments()) {
                if (first) {
                    first = false;
                } else {
                    methodDetails.append(", ");
                }
                if (arg != null) {
                    methodDetails.append(arg.toString());
                } else {
                    methodDetails.append("null");
                }
            }
            methodDetails.append(")\n");
            List<String> messages = RMMethodSecurityInterceptor.MESSAGES.get();
            for (String message : messages) {
                methodDetails.append(message).append("\n");
            }
            String failureReport = getFailureReport();
            if (failureReport == null) {
                // rethrow with additional information
                throw new AccessDeniedException(exception.getMessage() + methodDetails, exception);
            } else {
                // rethrow with additional information
                throw new AccessDeniedException(exception.getMessage() + methodDetails + getFailureReport(), exception);
            }
        } else {
            throw exception;
        }
    }
    return result;
}
Also used : AccessDeniedException(net.sf.acegisecurity.AccessDeniedException) InterceptorStatusToken(net.sf.acegisecurity.intercept.InterceptorStatusToken) MethodInvocation(org.aopalliance.intercept.MethodInvocation) ArrayList(java.util.ArrayList) List(java.util.List)

Example 17 with MethodInvocation

use of org.aopalliance.intercept.MethodInvocation in project records-management by Alfresco.

the class RMEntryVoterUnitTest method invalidPolicy.

/**
 * Given that we have provided an invalid policy
 * When I evaluate the voter
 * Then an AlfrescoRuntimeException is thrown
 */
@Test
public void invalidPolicy() throws Exception {
    // given I am providing an invalid policy for a method
    MethodInvocation mockedMethodInvocation = createMethodInvoation("myTestMethod", NodeRef.class);
    net.sf.acegisecurity.ConfigAttributeDefinition mockedConfigDef = createConfigDefinition("RM.invalid");
    // I expect an Alfresco Runtime Exception
    exception.expect(AlfrescoRuntimeException.class);
    // call vote
    entryVoter.vote(mockedAuthentication, mockedMethodInvocation, mockedConfigDef);
}
Also used : MethodInvocation(org.aopalliance.intercept.MethodInvocation) Test(org.junit.Test) BaseUnitTest(org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest)

Example 18 with MethodInvocation

use of org.aopalliance.intercept.MethodInvocation in project records-management by Alfresco.

the class RMEntryVoterUnitTest method validPolicy.

/**
 * Given that I have provided a valid policy
 * When I evaluate the voter
 * Then the corresponding policy will be evaluated
 */
@Test
public void validPolicy() throws Exception {
    // valid policy
    when(mockedPolicy.getName()).thenReturn(POLICY_NAME);
    entryVoter.registerPolicy(mockedPolicy);
    // mock calling details
    MethodInvocation mockedMethodInvocation = createMethodInvoation("myTestMethod", NodeRef.class);
    net.sf.acegisecurity.ConfigAttributeDefinition mockedConfigDef = createConfigDefinition("RM." + POLICY_NAME);
    // call vote
    entryVoter.vote(mockedAuthentication, mockedMethodInvocation, mockedConfigDef);
    // verify that the policy was executed
    verify(mockedPolicy, times(1)).evaluate(eq(mockedMethodInvocation), any(Class[].class), any(ConfigAttributeDefinition.class));
}
Also used : ConfigAttributeDefinition(org.alfresco.module.org_alfresco_module_rm.capability.policy.ConfigAttributeDefinition) MethodInvocation(org.aopalliance.intercept.MethodInvocation) Test(org.junit.Test) BaseUnitTest(org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest)

Example 19 with MethodInvocation

use of org.aopalliance.intercept.MethodInvocation in project records-management by Alfresco.

the class RMEntryVoterUnitTest method alreadyVoting.

/**
 * Given that the system is already voting
 * When I vote
 * Then access granted
 */
@Test
public void alreadyVoting() throws Exception {
    // indicate already voting
    when(mockedTransactionalResourceHelper.isResourcePresent("voting")).thenReturn(true);
    // given I am providing an invalid policy for a method
    MethodInvocation mockedMethodInvocation = createMethodInvoation("myTestMethod", NodeRef.class);
    net.sf.acegisecurity.ConfigAttributeDefinition mockedConfigDef = createConfigDefinition("RM.invalid");
    // call vote
    assertEquals(AccessDecisionVoter.ACCESS_GRANTED, entryVoter.vote(mockedAuthentication, mockedMethodInvocation, mockedConfigDef));
}
Also used : MethodInvocation(org.aopalliance.intercept.MethodInvocation) Test(org.junit.Test) BaseUnitTest(org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest)

Example 20 with MethodInvocation

use of org.aopalliance.intercept.MethodInvocation in project records-management by Alfresco.

the class RMEntryVoter method vote.

/**
 * @see net.sf.acegisecurity.vote.AccessDecisionVoter#vote(net.sf.acegisecurity.Authentication, java.lang.Object, net.sf.acegisecurity.ConfigAttributeDefinition)
 */
@SuppressWarnings("rawtypes")
public int vote(Authentication authentication, Object object, net.sf.acegisecurity.ConfigAttributeDefinition config) {
    // logging
    RMMethodSecurityInterceptor.isRMSecurityChecked(true);
    MethodInvocation mi = (MethodInvocation) object;
    if (transactionalResourceHelper.isResourcePresent("voting")) {
        if (logger.isDebugEnabled()) {
            logger.debug(" .. grant access already voting: " + mi.getMethod().getDeclaringClass().getName() + "." + mi.getMethod().getName());
        }
        return AccessDecisionVoter.ACCESS_GRANTED;
    }
    if (logger.isDebugEnabled()) {
        logger.debug("Method: " + mi.getMethod().getDeclaringClass().getName() + "." + mi.getMethod().getName());
    }
    alfrescoTransactionSupport.bindResource("voting", true);
    try {
        // The system user can do anything
        if (authenticationUtil.isRunAsUserTheSystemUser()) {
            if (logger.isDebugEnabled()) {
                logger.debug("Access granted for the system user");
            }
            return AccessDecisionVoter.ACCESS_GRANTED;
        }
        List<ConfigAttributeDefinition> supportedDefinitions = extractSupportedDefinitions(config);
        // No RM definitions so we do not vote
        if (supportedDefinitions.size() == 0) {
            return AccessDecisionVoter.ACCESS_ABSTAIN;
        }
        // check we have an instance of a method invocation
        if (!(object instanceof MethodInvocation)) {
            // we expect a method invocation
            throw new AlfrescoRuntimeException("Passed object is not an instance of MethodInvocation as expected.");
        }
        // get information about the method
        MethodInvocation invocation = (MethodInvocation) object;
        Method method = invocation.getMethod();
        Class[] params = method.getParameterTypes();
        for (ConfigAttributeDefinition cad : supportedDefinitions) {
            // Whatever is found first takes precedence
            if (cad.getTypeString().equals(ConfigAttributeDefinition.RM_DENY)) {
                // log message
                RMMethodSecurityInterceptor.addMessage("RM_DENY: check that a security policy has been set for this method");
                return AccessDecisionVoter.ACCESS_DENIED;
            } else if (cad.getTypeString().equals(ConfigAttributeDefinition.RM_ABSTAIN)) {
                return AccessDecisionVoter.ACCESS_ABSTAIN;
            } else if (cad.getTypeString().equals(ConfigAttributeDefinition.RM_ALLOW)) {
                return AccessDecisionVoter.ACCESS_GRANTED;
            } else // It is distinguished from RM_ALLOW so query may have additional behaviour in the future
            if (cad.getTypeString().equals(ConfigAttributeDefinition.RM_QUERY)) {
                return AccessDecisionVoter.ACCESS_GRANTED;
            } else // These entries effectively abstain
            if (((cad.getParameters().get(0) != null) && (cad.getParameters().get(0) >= invocation.getArguments().length)) || ((cad.getParameters().get(1) != null) && (cad.getParameters().get(1) >= invocation.getArguments().length))) {
                continue;
            } else if (cad.getTypeString().equals(ConfigAttributeDefinition.RM_CAP)) {
                switch(checkCapability(invocation, params, cad)) {
                    case AccessDecisionVoter.ACCESS_DENIED:
                        {
                            return AccessDecisionVoter.ACCESS_DENIED;
                        }
                    case AccessDecisionVoter.ACCESS_ABSTAIN:
                        {
                            if (logger.isDebugEnabled()) {
                                if (logger.isTraceEnabled()) {
                                    logger.trace("Capability " + cad.getRequired() + " abstained for " + invocation.getMethod(), new IllegalStateException());
                                } else {
                                    logger.debug("Capability " + cad.getRequired() + " abstained for " + invocation.getMethod());
                                }
                            }
                            // abstain denies
                            return AccessDecisionVoter.ACCESS_DENIED;
                        }
                    case AccessDecisionVoter.ACCESS_GRANTED:
                        {
                            break;
                        }
                }
            } else if (cad.getTypeString().equals(ConfigAttributeDefinition.RM)) {
                switch(checkPolicy(invocation, params, cad)) {
                    case AccessDecisionVoter.ACCESS_DENIED:
                        {
                            // log message
                            RMMethodSecurityInterceptor.addMessage("Policy " + cad.getPolicyName() + " denied.");
                            return AccessDecisionVoter.ACCESS_DENIED;
                        }
                    case AccessDecisionVoter.ACCESS_ABSTAIN:
                        {
                            if (logger.isDebugEnabled()) {
                                if (logger.isTraceEnabled()) {
                                    logger.trace("Policy " + cad.getPolicyName() + " abstained for " + invocation.getMethod(), new IllegalStateException());
                                } else {
                                    logger.debug("Policy " + cad.getPolicyName() + " abstained for " + invocation.getMethod());
                                }
                            }
                            // abstain denies
                            return AccessDecisionVoter.ACCESS_DENIED;
                        }
                    case AccessDecisionVoter.ACCESS_GRANTED:
                        {
                            break;
                        }
                }
            }
        }
    } finally {
        alfrescoTransactionSupport.unbindResource("voting");
    }
    // all voted to allow
    return AccessDecisionVoter.ACCESS_GRANTED;
}
Also used : ConfigAttributeDefinition(org.alfresco.module.org_alfresco_module_rm.capability.policy.ConfigAttributeDefinition) AlfrescoRuntimeException(org.alfresco.error.AlfrescoRuntimeException) MethodInvocation(org.aopalliance.intercept.MethodInvocation) Method(java.lang.reflect.Method)

Aggregations

MethodInvocation (org.aopalliance.intercept.MethodInvocation)117 Test (org.junit.jupiter.api.Test)50 Test (org.junit.Test)35 MethodInterceptor (org.aopalliance.intercept.MethodInterceptor)25 SimpleMethodInvocation (org.springframework.security.util.SimpleMethodInvocation)22 Method (java.lang.reflect.Method)21 ArrayList (java.util.ArrayList)11 Log (org.apache.commons.logging.Log)11 Authentication (org.springframework.security.core.Authentication)10 EvaluationContext (org.springframework.expression.EvaluationContext)9 Expression (org.springframework.expression.Expression)9 OAuth2Authentication (org.springframework.security.oauth2.provider.OAuth2Authentication)9 List (java.util.List)7 Assertions.assertThatIllegalArgumentException (org.assertj.core.api.Assertions.assertThatIllegalArgumentException)7 ArgumentMatchers.anyString (org.mockito.ArgumentMatchers.anyString)7 MyThrowsHandler (org.springframework.aop.testfixture.advice.MyThrowsHandler)7 OAuth2Request (org.springframework.security.oauth2.provider.OAuth2Request)7 RemoteInvocation (org.springframework.remoting.support.RemoteInvocation)6 ITestBean (org.springframework.beans.testfixture.beans.ITestBean)5 Promise (ratpack.exec.Promise)5