package com.norteksoft.acs.base.utils;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import javax.naming.AuthenticationException;
import javax.naming.Context;
import javax.naming.NameNotFoundException;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.Control;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.SessionFactory;
import com.norteksoft.acs.base.orm.hibernate.SimpleHibernateTemplate;
import com.norteksoft.acs.entity.organization.Department;
import com.norteksoft.acs.entity.organization.DepartmentUser;
import com.norteksoft.acs.entity.organization.User;
import com.norteksoft.acs.entity.organization.UserInfo;
import com.norteksoft.acs.entity.sysSetting.LdapType;
import com.norteksoft.acs.entity.sysSetting.ServerConfig;
import com.norteksoft.product.util.ContextUtils;
public class Ldaper {
private static Log log = LogFactory.getLog(Ldaper.class);
protected static SessionFactory sessionFactory;
private static SimpleHibernateTemplate<ServerConfig, Long> serverConfigDao;
private static String message = "";
static {
init();
}
private Ldaper() {
}
private static void init() {
sessionFactory = getSessionFactory();
serverConfigDao = new SimpleHibernateTemplate<ServerConfig, Long>(sessionFactory, ServerConfig.class);
}
protected static SessionFactory getSessionFactory() {
sessionFactory = (SessionFactory)ContextUtils.getBean("sessionFactory");
return sessionFactory;
}
/**
* 判断是否启动了LDAP集成
* @return
*/
public static boolean isStartedAboutLdap(){
ServerConfig serverConfig = (ServerConfig)serverConfigDao
.findUnique("FROM ServerConfig s WHERE s.companyId=?", ContextUtils.getCompanyId());
if(serverConfig!=null && serverConfig.getLdapInvocation()==true){
return true;
}
return false;
}
/**
* 修改用户信息.
*
* @param attrs
* Attributes 需要修改的用户属性.
* @param userDN
* String 用户DN
* @return
*/
public static String modify(String userDN,String key,String value,String userName) {
LdapContext ctx = null;
log.debug("***进入modify方法 ***");
log.debug("参数为[userDN= "+userDN+";key="+key+";value="+value+";userName="+userName+"]");
try {
log.debug("***正在获取LdapContext链接 ***");
ctx = getConnectionFromPool();
log.debug("*** 获取LdapContext链接成功 ***");
Attributes attrs = new BasicAttributes(true);
attrs.put(key, value);
ctx.modifyAttributes(userDN, DirContext.REPLACE_ATTRIBUTE, attrs);
log.debug("***修改LDAP用户成功***");
} catch (NamingException e) {
log.debug("***修改LDAP失败:"+e.getMessage()+"****"+e.getStackTrace());
log.debug("***修改LDAP用户["+e.getRemainingName()+"]失败***");
return userName;
}finally {
if (ctx != null) {
try {
ctx.close();
} catch (NamingException e) {
e.printStackTrace();
}
ctx = null;
}
}
log.debug("***退出modify方法 ***");
return "";
}
/**
* 从连接池中获取一个连接.
*
* @return LdapContext
* @throws NamingException
*/
public static LdapContext getConnectionFromPool(){
Long companyId = ContextUtils.getCompanyId();
ServerConfig serverConfig = (ServerConfig)serverConfigDao.findUnique("FROM ServerConfig s WHERE s.companyId=?", companyId);
log.debug("*** 公司Ldap服务配置 *** ServerConfig: [ldapUrl="+serverConfig.getLdapUrl()+";ldapUSerName="+serverConfig.getLdapUsername()+";ldapPassword="+serverConfig.getLdapPassword()+"]");
Properties env = new Properties();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, serverConfig.getLdapUrl());
env.put(Context.SECURITY_AUTHENTICATION, "simple");
if(serverConfig.getLdapType() == LdapType.APACHE){
env.put(Context.SECURITY_PRINCIPAL, "UID="+serverConfig.getLdapUsername()+",OU=system");
}else if(serverConfig.getLdapType() == LdapType.DOMINO){
env.put(Context.SECURITY_PRINCIPAL, "CN="+serverConfig.getLdapUsername());
}else if(serverConfig.getLdapType() == LdapType.WINDOWS_AD){
env.put(Context.SECURITY_PRINCIPAL, serverConfig.getLdapUsername());
}
env.put(Context.SECURITY_CREDENTIALS, serverConfig.getLdapPassword());
env.put("com.sun.jndi.ldap.connect.pool", "true");
env.put("java.naming.referral", "follow");
try {
return new InitialLdapContext(env, null);
} catch (NamingException e) {
log.debug("*** 初始化LdapContext异常 ***", e);
}
return null;
}
/**
* 校验用户登录.
*
* @param userDn
* String
* @param password
* String
* @return boolean
*/
public static boolean authenticate(String userDn, String password) {
LdapContext ctx = null;
try {
Control[] connCtls = new Control[] {};
ctx = getConnectionFromPool();
ctx.getRequestControls();
ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, userDn);
ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, password);
ctx.reconnect(connCtls);
return true;
} catch (AuthenticationException e) {
return false;
} catch (NamingException e) {
return false;
} finally {
if (ctx != null) {
try {
ctx.close();
} catch (NamingException e) {
e.printStackTrace();
}
}
}
}
/**
* 添加&修改部门(dc)
* @param department
* @param add(true:新建,false:修改)
* @return
*/
public static String addGroup(Department department,boolean isCreate){
LdapContext ctx = null;
try {
ctx = getConnectionFromPool();
StringBuilder groupDN = new StringBuilder();
groupDN = getGroupDn(department, groupDN);
groupDN.append(",o=");
groupDN.append(department.getCompany().getCode());
groupDN = groupDN.deleteCharAt(0);
Attributes attrs = new BasicAttributes(true);
if(isCreate){
attrs.put("objectClass", "dominoOrganizationalUnit");
attrs.put("FullName",department.getName());
ctx.createSubcontext(groupDN.toString(), attrs);
}else{
attrs.put("cn",department.getName());
ctx.modifyAttributes(groupDN.toString(), DirContext.REPLACE_ATTRIBUTE, attrs);
}
} catch (NameNotFoundException e) {
log.debug(" Can't find "+department.getName());
return department.getName();
} catch (NamingException e) {
e.printStackTrace();
} finally {
if (ctx != null) {
try {
ctx.close();
} catch (NamingException e) {
e.printStackTrace();
}
ctx = null;
}
}
return "";
}
private static StringBuilder getGroupDn(Department department,StringBuilder groupDN){
groupDN.append(",ou=");
groupDN.append(department.getName());
if(department.getParent() != null){
getGroupDn(department.getParent(),groupDN);
}
return groupDN;
}
/**
* 删除部门.
*
*/
public static String delDepartment(Department department) {
LdapContext ctx = null;
StringBuilder searchBase = new StringBuilder();
searchBase = getGroupDn(department, searchBase);
searchBase.append(",o=");
searchBase.append(department.getCompany().getCode());
searchBase = searchBase.deleteCharAt(0);
ctx = getConnectionFromPool();
recursion(searchBase.toString(), ctx, "o="+department.getCompany().getCode(),department.getName());
return message;
}
/**
* 逐层删除操作
* @param rootBase
* @param ctx
* @param baseCode
*/
private static void recursion(String rootBase, LdapContext ctx,String baseCode,String departmentName){
try {
String url = rootBase;
NamingEnumeration<SearchResult> results = ctx.search(url, null);
String currentUrl = null;
if(!results.hasMore()){
ctx.destroySubcontext(url);
}else{
while(results.hasMore()){
SearchResult result = results.next();
currentUrl = result.getName()+","+url;
Attributes attrs = result.getAttributes();
if(attrs.get("objectClass").toString().indexOf("dominoPerson") > -1){
String userDN = ("cn="+attrs.get("cn")).replaceAll("cn: ", "");
ctx.createSubcontext(userDN+","+baseCode, attrs);
ctx.destroySubcontext(currentUrl);
}else{
recursion(currentUrl,ctx,baseCode,departmentName);
}
}
ctx.destroySubcontext(url);
}
}catch (NamingException e) {
message = departmentName;
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 修改用户名或密码s
* @param user
* @param companyCode
* @param departments
* @param flag(true:改名,false:改密码)
* @param cn
* @return
*/
public static String modifyUser(User user, String companyCode,
List<Department> departments, boolean flag,String userName){
String key = null;
String value = null;
if(flag){
key = "uid";
value = user.getLoginName();
}else{
key = "userPassword";
value = user.getPassword();
}
if(departments.isEmpty()){
log.debug("*** 用户没有部门,直接加入公司 ***");
StringBuilder userDN = new StringBuilder("cn=");
userDN.append(userName);
userDN.append(",o=");
userDN.append(companyCode);
message = modify(userDN.toString(), key, value,user.getLoginName());
}else{
log.debug("*** 用户已加入[" + departments.size() + "]个部门 ***");
for(Department d:departments){
StringBuilder userDN = new StringBuilder("cn=");
userDN.append(userName);
userDN = getGroupDn(d, userDN);
userDN.append(",o=");
userDN.append(companyCode);
message = modify(userDN.toString(), key, value,user.getLoginName());
}
}
return message;
}
/**
* 添加用户
* @param user
* @return
*/
public static String addUser(UserInfo userInfo,String companyCode,String trueName) {
User user = userInfo.getUser();
LdapContext ctx = null;
StringBuilder userDN = new StringBuilder("cn=");
userDN.append(user.getLoginName());
userDN.append(",o=");
userDN.append(companyCode);
try {
ctx = getConnectionFromPool();
Attributes attrs = new BasicAttributes(true);
attrs.put("objectClass", "dominoPerson");
attrs.put("userPassword", user.getPassword());
attrs.put("sn", trueName);
attrs.put("uid",user.getLoginName());
String email = user.getEmail();
if(!StringUtils.isEmpty(email)){
attrs.put("mail",email);
}
ctx.createSubcontext(userDN.toString(), attrs);
} catch(NameNotFoundException e){
log.debug(" Can't find "+user.getLoginName());
return user.getLoginName();
} catch (NamingException e) {
e.printStackTrace();
} finally {
if (ctx != null) {
try {
ctx.close();
} catch (NamingException e) {
e.printStackTrace();
}
ctx = null;
}
}
return "";
}
/**
* 删除用户.
*
* @param userDN
* String 用户DN
* @return
*/
@SuppressWarnings("unchecked")
public static String delUser(User user,String companyCode) {
LdapContext ctx = null;
try {
ctx = getConnectionFromPool();
Set<DepartmentUser> sets = user.getDepartmentUsers();
Iterator it = sets.iterator();
if(it.hasNext()){
while(it.hasNext()){
DepartmentUser departmentToUser = (DepartmentUser)it.next();
Department department = departmentToUser.getDepartment();
StringBuilder userDN = new StringBuilder("cn="+user.getLoginName());
userDN = getGroupDn(department,userDN);
ctx.destroySubcontext(userDN.toString());
}
}else{
StringBuilder userDN = new StringBuilder("cn="+user.getLoginName());
userDN.append(",o="+companyCode);
ctx.destroySubcontext(userDN.toString());
}
} catch (NameNotFoundException e) {
return user.getLoginName();
} catch (NamingException e) {
log.debug("delUser has a exception named NamingException");
} finally {
if (ctx != null) {
try {
ctx.close();
} catch (NamingException e) {
e.printStackTrace();
}
ctx = null;
}
}
return "";
}
/**
* 部门增加/移除用户
* @param department
* @param users
* @param flag(true:增加,false:移除)
* @return
*/
public static String addUsersInDepartment(Department department,List<User> users,boolean flag){
LdapContext ctx = null;
try {
ctx = getConnectionFromPool();
for(User u:users){
StringBuilder oldUserDN = new StringBuilder("CN="+u.getLoginName());
oldUserDN.append(",O="+department.getCompany().getCode());
StringBuilder userDN = new StringBuilder("cn="+u.getLoginName());
userDN = getGroupDn(department,userDN);
userDN.append(",o="+department.getCompany().getCode());
NamingEnumeration<SearchResult> results = ctx.search("o="+department.getCompany().getCode(), null);
if(flag){
boolean exsit = false;
while(results.hasMore()){
SearchResult result = results.next();
Attributes attrs = result.getAttributes();
if(attrs.get("cn")!=null){
String cn = attrs.get("cn").toString().replaceAll("cn: ", "");
if(cn.equals(u.getLoginName())){
ctx.createSubcontext(userDN.toString(), attrs);
ctx.destroySubcontext(oldUserDN.toString());
exsit = true;
}
}
}
if(!exsit){
Attributes attrs = new BasicAttributes(true);
attrs.put("objectClass", "dominoPerson");
attrs.put("userPassword", u.getPassword());
attrs.put("sn", u.getLoginName());
attrs.put("uid",u.getLoginName());
ctx.createSubcontext(userDN.toString(), attrs);
}
}else{
ctx.destroySubcontext(userDN.toString());
boolean exsit = false;
while(results.hasMore()){
SearchResult result = results.next();
Attributes attrs = result.getAttributes();
if(attrs.get("cn")!=null){
String cn = attrs.get("cn").toString().replaceAll("cn: ", "");
if(cn.equals(u.getLoginName())){
exsit = true;
}
}
}
if(!exsit){
Attributes attrs = new BasicAttributes(true);
attrs.put("objectClass", "dominoPerson");
attrs.put("userPassword", u.getPassword());
attrs.put("sn", u.getLoginName());
attrs.put("uid",u.getLoginName());
ctx.createSubcontext(oldUserDN.toString(), attrs);
}
}
}
} catch (NameNotFoundException e) {
return department.getName();
} catch (NamingException e) {
log.debug("addUsersInDepartment has a exception named NamingException");
} finally {
if (ctx != null) {
try {
ctx.close();
} catch (NamingException e) {
e.printStackTrace();
}
ctx = null;
}
}
return "";
}
}