package eu.dnetlib.simplesso;

import java.util.Collection;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;

import eu.dnetlib.simplesso.SimpleSSOAuthenticator.AuthPayload;

public class SimpleSSOAuthenticationProvider implements AuthenticationProvider {

	private static final Log log = LogFactory.getLog(SimpleSSOAuthenticationProvider.class); // NOPMD by marko on 11/24/08 5:02 PM

	private SimpleSSOAuthenticator authenticator;

	private SimpleSSOAuthenticationRoleBuilder rolesBuilder;

	@Override
	public Authentication authenticate(final Authentication auth) throws AuthenticationException {
		log.debug("SSO authenticating " + auth);

		if (auth.isAuthenticated()) {
			log.debug("already authenticated, trusting " + auth);
			return auth;
		}

		if (auth instanceof SimpleSSOAuthenticationToken) {
			SimpleSSOAuthenticationToken reqAuth = (SimpleSSOAuthenticationToken) auth;

			AuthPayload payload = authenticator.decodeToken(reqAuth.getToken());

			if (payload == null) return null;

			Collection<GrantedAuthority> grantedAuthorities = rolesBuilder.buildAuthorities(payload.getRoles());

			SimpleSSOAuthenticationToken res = new SimpleSSOAuthenticationToken(reqAuth.getToken(), grantedAuthorities);
			res.setUid(payload.getUid());
			return res;
		} else {
			log.warn("not handling " + auth);
		}
		return null;
	}

	@Override
	public boolean supports(@SuppressWarnings("rawtypes") final Class arg0) {
		return true;
	}

	@Required
	public void setAuthenticator(final SimpleSSOAuthenticator authenticator) {
		this.authenticator = authenticator;
	}

	public SimpleSSOAuthenticationRoleBuilder getRolesBuilder() {
		return rolesBuilder;
	}

	public void setRolesBuilder(final SimpleSSOAuthenticationRoleBuilder rolesBuilder) {
		this.rolesBuilder = rolesBuilder;
	}

	public SimpleSSOAuthenticator getAuthenticator() {
		return authenticator;
	}

}
