package com.uas.sso;

import java.util.logging.Logger;

import javax.servlet.http.HttpServletRequest;

import com.uas.sso.common.IpHelper;
import com.uas.sso.common.encrypt.RSA;
import com.uas.sso.common.util.RandomUtil;
import com.uas.sso.exception.SSOException;

/**
 * <p>
 * SSO 跨域信任 Token
 * </p>
 * 
 */
public class AuthToken extends Token {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private static final Logger logger = Logger.getLogger(AuthToken.class.getName());

	/* 32 uuid */
	private String uuid;

	/* ras sign */
	private String sign;

	/* 预留 */
	private String data;

	protected AuthToken() {
		/* 保护 */
	}

	/**
	 * 有参构造函数
	 * 
	 * @param request
	 * @param privateKey
	 *            RSA 私钥（业务系统）
	 */
	public AuthToken(HttpServletRequest request, String privateKey) {
		this.uuid = RandomUtil.get32UUID();
		this.setIp(IpHelper.getIpAddr(request));
		this.sign(privateKey);
		this.setApp(SSOConfig.getInstance().getAppName());
	}

	/**
	 * 生成签名字节数组
	 * 
	 * @return byte[]
	 */
	public byte[] signByte() {
		StringBuffer sb = new StringBuffer(getUuid());
		sb.append("-").append(this.getIp());
		return sb.toString().getBytes();
	}

	/**
	 * 设置签名 rsaSign
	 * 
	 * @param privateKey
	 *            RSA 私钥（签名）
	 */
	public void sign(String privateKey) {
		try {
			this.sign = RSA.sign(signByte(), privateKey);
		} catch (Exception e) {
			logger.severe("sign error.");
			e.printStackTrace();
			throw new SSOException(" AuthToken RSA sign error. ");
		}
	}

	/**
	 * 验证 AuthToken 签名是否合法
	 * 
	 * @param publicKey
	 *            RSA 公钥（验证签名）
	 * @return
	 */
	public AuthToken verify(String publicKey) {
		try {
			/**
			 * RSA 验证摘要 是否合法
			 */
			if (RSA.verify(signByte(), publicKey, getSign())) {
				return this;
			}
		} catch (Exception e) {
			logger.severe("verify error.");
			e.printStackTrace();
			throw new SSOException(" AuthToken RSA verify error. ");
		}
		return null;
	}

	public String getUuid() {
		return uuid;
	}

	public void setUuid(String uuid) {
		this.uuid = uuid;
	}

	public String getSign() {
		return sign;
	}

	public void setSign(String sign) {
		this.sign = sign;
	}

	public String getData() {
		return data;
	}

	public void setData(String data) {
		this.data = data;
	}

}
