package com.yifu.cloud.plus.v1.yifu.common.ldap.util;

import javax.naming.AuthenticationException;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.Control;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
import java.util.Hashtable;

/**
 * 用户登陆认证,LDAP跨域认证，通过LDAP对用户进行更新
 *
 */
public class LdapCheck {
	private static LdapContext ctx = null;
	private static Control[] connCtls = null;

	/**** 定义LDAP的基本连接信息 ******/
	// LDAP的连接地址（ldap://ip:port/）port默认为389
	private static String URL = "192.168.1.65";
	//port
	private static String port = "389";
	// LDAP的根DN
	private static String BASEDN = "dc=worfu,dc=com";
	// LDAP的连接账号（身份认证管理平台添加的应用账号，应用账号格式：uid=?,ou=?,dc=????）
	private static String PRINCIPAL = "cn=admin,dc=worfu,dc=com";
	// LDAP的连接账号的密码（身份认证管理平台添加的应用账号的密码）
	private static String PASSWORD = "yifu123456!";

	// 校验用户名密码的方法
	public static boolean authenticate(String usr, String pwd) {
		boolean valide = false;
		if (pwd == null || pwd == "")
			return false;
		if (ctx == null) {
			getCtx();
		}
		String userDN = getUserDN(usr);
		if ("".equals(userDN) || userDN == null) {
			return false;
		}
		try {
			ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, userDN);
			ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, pwd);
			ctx.reconnect(connCtls);
			valide = true;
			closeCtx();
		} catch (AuthenticationException e) {
			System.out.println(userDN + " is not authenticated");
			System.out.println(e.toString());
			valide = false;
		} catch (NamingException e) {
			System.out.println(userDN + " is not authenticated");
			valide = false;
		}
		return valide;
	}

	public static void getCtx() {
		if (ctx != null) {
			return;
		}
		Hashtable<String, String> env = new Hashtable<String, String>();
		env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
		env.put(Context.PROVIDER_URL, URL + ":" + port + BASEDN);
		env.put(Context.SECURITY_AUTHENTICATION, "simple");
		env.put(Context.SECURITY_PRINCIPAL, PRINCIPAL);
		env.put(Context.SECURITY_CREDENTIALS, PASSWORD);
		try {
			// 链接ldap
			ctx = new InitialLdapContext(env, connCtls);
		} catch (AuthenticationException e) {
			System.out.println("Authentication faild: " + e.toString());
		} catch (Exception e) {
			System.out.println("Something wrong while authenticating: " + e.toString());
		}
	}

	public static void closeCtx() {
		try {
			if (ctx != null)
				ctx.close();
		} catch (NamingException ex) {

		}
	}

	public static String getUserDN(String uid) {
		String userDN = "";
		try {
			SearchControls constraints = new SearchControls();
			constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
			NamingEnumeration<?> en = ctx.search("", "uid=" + uid, constraints);
			if (en == null) {
				System.out.println("Have no NamingEnumeration.");
			}
			if (!en.hasMoreElements()) {
				System.out.println("Have no element.");
			}
			while (en != null && en.hasMoreElements()) {
				Object obj = en.nextElement();
				if (obj instanceof SearchResult) {
					SearchResult si = (SearchResult) obj;
					userDN += si.getName();
					userDN += "," + BASEDN;
				} else {
					System.out.println(obj);
				}
				System.out.println();
			}
		} catch (Exception e) {
			System.out.println("Exception in search():" + e);
		}

		return userDN;
	}
}