Commit fd8e1535 authored by Brian Long's avatar Brian Long
Browse files

added IfAuthorized(s) annotation

parent d679d7ef
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
package com.inteligr8.alfresco.annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * This annotation tells the framework to only execute the annotated method if
 * the ACS authenticated user is authorized.
 * 
 * @see com.inteligr8.alfresco.annotations.Authorizable
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Repeatable(IfAuthorizeds.class)
public @interface IfAuthorized {
	
	/**
	 * The authorities (users and/or user groups) to constrain for the
	 * authorization context.  Only one authority needs to match.  To
	 * require multiple authorities, use multiple @IfAuthorized
	 * annotations.
	 * 
	 * @return An array of ACS authorities; empty means any authenticated user.
	 */
	String[] value() default "";

}
+14 −0
Original line number Diff line number Diff line
package com.inteligr8.alfresco.annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface IfAuthorizeds {
	
	IfAuthorized[] value();

}
+92 −0
Original line number Diff line number Diff line
package com.inteligr8.alfresco.annotations.aspect;

import java.lang.reflect.Method;
import java.util.Set;

import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.util.collections.CollectionUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.extensions.webscripts.Description.RequiredAuthentication;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.http.HttpStatus;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.server.ResponseStatusException;

import com.inteligr8.alfresco.annotations.IfAuthorized;
import com.inteligr8.alfresco.annotations.context.WebScriptContext;

import net.sf.acegisecurity.GrantedAuthority;

/**
 * This aspect implements the IfAuthorized annotation.
 * 
 * @see com.inteligr8.alfresco.annotations.IfAuthorized
 */
@Aspect
public class IfAuthorizedAspect {
	
	private final Logger logger = LoggerFactory.getLogger(this.getClass());
	
	@Autowired(required = false)
	private WebScriptContext wscontext;
	
	@Autowired(required = false)
	private WebApplicationContext wacontext;
	
	@Pointcut("@annotation(com.inteligr8.alfresco.annotations.IfAuthorized) && execution(* *(..))")
	public void isIfAuthorizedAnnotated() {
	}

	@Around("isIfAuthorizedAnnotated()")
	public Object ifAuthorized(ProceedingJoinPoint joinPoint) throws Throwable {
		this.logger.trace("ifAuthorized({})", joinPoint);
		
		if (this.wscontext != null && !RequiredAuthentication.user.equals(this.wscontext.getWebscript().getDescription().getRequiredAuthentication()))
			return joinPoint.proceed();
		
		if (!(joinPoint.getSignature() instanceof MethodSignature))
			throw new IllegalStateException("The @IfAuthorized annotation must be on methods and methods have signatures");
		
		MethodSignature methodSig = (MethodSignature) joinPoint.getSignature();
		Method method = methodSig.getMethod();
		IfAuthorized[] ifauths = method.getAnnotationsByType(IfAuthorized.class);
		for (IfAuthorized ifauth : ifauths) {
			if (ifauth.value() != null && ifauth.value().length > 0) {
				if (!this.isAuthorized(ifauth.value()))
					return this.unauthorized();
			}
		}
		
		return joinPoint.proceed();
	}
	
	protected boolean isAuthorized(String[] permittedAuthorities) {
		Set<String> permittedAuthoritiesSet = CollectionUtils.asSet(permittedAuthorities);
		
		GrantedAuthority[] authenticatedAuthorities = AuthenticationUtil.getFullAuthentication().getAuthorities();
		for (GrantedAuthority auth : authenticatedAuthorities) {
			if (permittedAuthoritiesSet.contains(auth.getAuthority()))
				return true;
		}
		
		return false;
	}
	
	protected Object unauthorized() {
		if (this.wscontext != null) {
			throw new WebScriptException(HttpStatus.FORBIDDEN.value(), "The authenticated user is not authorized to use this resource");
		} else if (this.wacontext != null) {
			throw new ResponseStatusException(HttpStatus.FORBIDDEN, "The authenticated user is not authorized to use this resource");
		} else {
			return null;
		}
	}

}
+1 −0
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@
		<aspect name="com.inteligr8.alfresco.annotations.aspect.ThreadedAspect" />
		<aspect name="com.inteligr8.alfresco.annotations.aspect.AsyncAspect" />
		<aspect name="com.inteligr8.alfresco.annotations.aspect.AuthorizedAspect" />
		<aspect name="com.inteligr8.alfresco.annotations.aspect.IfAuthorizedAspect" />
		
		<aspect name="com.inteligr8.alfresco.annotations.aspect.JobLockAspect" />
		<aspect name="com.inteligr8.alfresco.annotations.aspect.OperableNodeAspect" />