/*
 * @(#)AuthenticationAuthority.java
 *
 * Copyright (C) 2007 Infocity Inc. All Rights Reserved.
 */
package info.dragonlady.sso.authority;

import info.dragonlady.sso.util.AssertionGenerator;

import org.opensaml.SAMLAssertion;
import org.opensaml.SAMLAuthenticationQuery;
import org.opensaml.SAMLException;
import org.opensaml.SAMLRequest;
import org.opensaml.SAMLResponse;
import org.opensaml.SAMLSubject;

/**
 * 認証オーソリティ抽象クラス。
 * 
 * @author Hiroshi.Ebata(INFOCITY)
 * @version $Revision: 1.0 $ $Date: 2007/04/25 15:18:19 $
 */
public abstract class AuthenticationAuthority implements SAMLAuthority {

	/* (non-Javadoc)
	 * @see info.dragonlady.sso.authority.SAMLAuthority#query(org.opensaml.SAMLRequest)
	 */
	public final SAMLResponse query(SAMLRequest request) throws AuthorityException {
		try {
			SAMLResponse response = new SAMLResponse(request.getId(), null, null, null);
			SAMLException samlException = null;
			String authId = null;
			String confirmationMethod = null;
			String confirmationData = null;
			String authMethod = null;
			try {
				SAMLAuthenticationQuery query = (SAMLAuthenticationQuery)request.getQuery();
				SAMLSubject subject = query.getSubject();
				authId = subject.getNameIdentifier().getName();
				confirmationMethod = subject.getConfirmationMethods().next().toString();
				confirmationData = subject.getConfirmationData().getTextContent();
				authMethod = query.getAuthMethod();
			} catch(Exception e) {
				// TODO
				samlException = new SAMLException(SAMLException.REQUESTER, "", e);
			}

			if(samlException == null) {
				try {
					if(authenticate(authId, confirmationMethod, confirmationData)) {
						SAMLAssertion assertion = AssertionGenerator.generateAuthenticationAssertion(authId, confirmationMethod, authMethod);
						response.addAssertion(assertion);
						// TODO
						samlException = new SAMLException(SAMLException.SUCCESS, "");
					} else {
						// TODO
						samlException = new SAMLException(SAMLException.RESPONDER, "");
					}
				} catch(Exception e) {
					// TODO
					samlException = new SAMLException(SAMLException.RESPONDER, "", e);
				}
			}
			response.setStatus(samlException);
			return response;
		} catch(Exception e) {
			// TODO
			throw new AuthorityException(e);
		}
	}

	/**
	 * 認証処理。
	 * 
	 * @param authId 認証ID
	 * @param confirmationMethod 確認方法
	 * @param confirmationData 確認データ
	 * @return boolean true：認証OK／false：認証NG
	 * @throws AuthorityException
	 */
	protected abstract boolean authenticate(
			String authId,
			String confirmationMethod,
			Object confirmationData) throws AuthorityException;

}
