package sgc.portal.security;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import sgc.portal.SgcPortalAttributes;
import sgc.portal.security.annotation.Secured;
import sgc.portal.security.annotation.SecurityPolicy;

/**
 * <pre>
 * 클라이언트가 요청한 URL에 해당하는 메서드가 실행될 경우
 * 해당 메서드가 인증된 사용자만 접근해야 하는지 등을 판단한다.
 * </pre>
 *
 * @author YongSang
 */
public class SecurityDecisionMaker extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        if (!(handler instanceof HandlerMethod)) {
            request.setAttribute(SgcPortalAttributes.SECURITY_POLICY, SecurityPolicy.NONE);
            return true;
        }
        SecurityPolicy policy = determinePolicy((HandlerMethod) handler);
        request.setAttribute(SgcPortalAttributes.SECURITY_POLICY, policy);
        return true;
    }

    private SecurityPolicy determinePolicy(HandlerMethod handlerMethod) {
        SecurityPolicy policy = SecurityPolicy.PROTECTED;
        Secured securedMethod = handlerMethod.getMethod().getAnnotation(Secured.class);
        if (securedMethod != null) {
            return securedMethod.policy();
        }

        Secured securedBean = handlerMethod.getBeanType().getAnnotation(Secured.class);
        if (securedBean != null) {
            return securedBean.policy();
        }
        return policy;
    }
}