package org.quickbundle.project.login;
import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.quickbundle.base.beans.factory.RmBeanFactory;
import org.quickbundle.base.service.RmService;
import org.quickbundle.config.RmClusterConfig;
import org.quickbundle.config.RmConfig;
import org.quickbundle.orgauth.IOrgauthConstants;
import org.quickbundle.orgauth.rmuser.service.IRmUserService;
import org.quickbundle.orgauth.rmuser.util.IRmUserConstants;
import org.quickbundle.orgauth.rmuseronlinerecord.service.IRmUserOnlineRecordService;
import org.quickbundle.orgauth.rmuseronlinerecord.util.IRmUserOnlineRecordConstants;
import org.quickbundle.orgauth.rmuseronlinerecord.vo.RmUserOnlineRecordVo;
import org.quickbundle.orgauth.util.IRmOrgService;
import org.quickbundle.orgauth.util.impl.RmOrgService;
import org.quickbundle.project.IGlobalConstants;
import org.quickbundle.project.RmProjectHelper;
import org.quickbundle.project.common.vo.RmCommonVo;
import org.quickbundle.project.listener.RmGlobalMonitor;
import org.quickbundle.project.listener.RmRequestMonitor;
import org.quickbundle.project.listener.RmSessionListener;
import org.quickbundle.project.login.RmUserVo.RmUserSessionVo;
import org.quickbundle.tools.helper.RmDateHelper;
import org.quickbundle.tools.helper.RmJspHelper;
import org.quickbundle.tools.helper.RmStringHelper;
import org.quickbundle.tools.helper.RmVoHelper;
import org.quickbundle.util.RmOrderCodes;
import org.quickbundle.util.RmSequenceSet;
import org.springframework.jdbc.core.RowMapper;
public class RmLoginService extends RmService implements IRmLoginService {
public IRmUserOnlineRecordService getUserOnlineRecordService() {
return (IRmUserOnlineRecordService) RmBeanFactory.getBean(IRmUserOnlineRecordConstants.SERVICE_KEY); //得到Service对象,受事务控制
}
/**
* 根据login_id查用户
*
* @param login_id
* @return
*/
public List<IRmLoginVo> findUsersByLoginId(String login_id) {
List lvo = null;
//orgauth begin
IRmUserService userService = (IRmUserService)RmBeanFactory.getBean(IRmUserConstants.SERVICE_KEY);
lvo = userService.queryByCondition("login_id='" + login_id + "'", null, -1, -1, true);
//orgauth end
return lvo;
}
/**
* 验证用户登录的合法性; 登录用户公司判断并添加相关信息
*
* @param request
* @param loginVo
* @return 校验异常时,返回异常反馈信息,正常返回null
*/
public String validateLogin(ServletRequest request, IRmLoginVo loginVo){
RmUserVo userVo = (RmUserVo)loginVo;
String loginStr = null;
//orgauth validateLogin begin
if(IOrgauthConstants.UserAdminType.ADMIN.value().equals(loginVo.getAdmin_type())) {
//admin可直接登录
} else{
//扩展用户登录的合理性校验
if(IGlobalConstants.RM_NO.equals(userVo.getLock_status())){
loginStr="该用户被锁定,暂时不能登录,请联系管理员!";
}
}
//orgauth validateLogin end
return loginStr;
}
/**
* 判断这个用户是否已经在线
* @param request
* @param loginVo
* @return 如果未登录,返回null;如果已经登录在线,返回vo信息
*/
public UserUniqueLoginVo checkUniqueLogin(ServletRequest request, IRmLoginVo loginVo) {
RmUserVo userVo = (RmUserVo)loginVo;
UserUniqueLoginVo uniqueLoginVo = new UserUniqueLoginVo();
if(IGlobalConstants.RM_NO.equals(userVo.getLogin_status())) {
return null;
}
//orgauth begin
RmUserOnlineRecordVo onlineRecordVo = getUserOnlineRecordService().findLastLoginRecord(userVo.getId());
if(onlineRecordVo != null) {
//从RmUserOnlineRecord复制信息
uniqueLoginVo.setSession_id(onlineRecordVo.getLogin_sign());
uniqueLoginVo.setLogin_ip(onlineRecordVo.getLogin_ip());
uniqueLoginVo.setLogin_date(onlineRecordVo.getLogin_time());
//从session中继续复制
HttpSession sessionToReplace = RmSessionListener.getSessionById(onlineRecordVo.getLogin_sign());
if(sessionToReplace != null) {
//从loginVo复制信息
uniqueLoginVo.setName(userVo.getName());
uniqueLoginVo.setLogin_id(userVo.getLogin_id());
uniqueLoginVo.setId(userVo.getId());
} else {
// 集群模式下,直接从数据库读取用户信息
if(!RmConfig.getSingleton().isClusterMode() || RmClusterConfig.getSingleton().getSelfId().equals(onlineRecordVo.getCluster_node_id())) {
return null;
}
RmUserSessionVo sessionVo = null;
try {
IRmSessionService remoteSs = RmSessionService.getRemoteSessionService(onlineRecordVo.getCluster_node_id());
if(remoteSs != null) {
sessionVo = remoteSs.findSessionLocal(onlineRecordVo.getLogin_sign());
}
} catch (Exception e) {
// TODO: handle exception
}
if(sessionVo == null) {
return null;
}
//从sessionVo复制信息
uniqueLoginVo.setName(sessionVo.getName());
uniqueLoginVo.setLogin_id(sessionVo.getLogin_id());
uniqueLoginVo.setId(sessionVo.getId());
}
return uniqueLoginVo;
}
//orgauth end
return null;
}
/**
* 执行强制登录(踢出已在线用户,清理在线记录)
* @param request
* @param loginVo
* @return 强制登录是否成功
*/
public boolean executeLoginForce(ServletRequest request, IRmLoginVo loginVo) {
RmUserVo userVo = (RmUserVo)loginVo;
//orgauth begin
String message = "您被IP为" + RmProjectHelper.getIp(request) + "的用户取代登录了,请重新登录。如有帐号异常,请联系管理员。";
if(userVo.getId() == null || userVo.getId().length() == 0) {
return true;
}
//销毁集群下兄弟节点的session
RmUserOnlineRecordVo onlineRecordVo = getUserOnlineRecordService().findLastLoginRecord(userVo.getId());
if(onlineRecordVo != null) {
String cluster_node_id = onlineRecordVo.getCluster_node_id();
String sessionId = onlineRecordVo.getLogin_sign();
//集群模式下,根据cluster_node_id找到某个兄弟节点,其session也要强制取代
if(RmConfig.getSingleton().isClusterMode() && !RmClusterConfig.getSingleton().getSelfId().equals(cluster_node_id)) {
try {
IRmSessionService remoteSs = RmSessionService.getRemoteSessionService(cluster_node_id);
if(remoteSs != null) {
remoteSs.forceLogoutUserLocal(new String[]{sessionId}, message);
}
} catch (Exception e) {
// TODO: handle exception
}
}
HttpSession sessionToReplace = RmSessionListener.getSessionById(sessionId);
if(sessionToReplace != null) {
sessionToReplace.setAttribute(IRmLoginConstants.LOGOUT_TYPE, IRmLoginConstants.LogoutType.FORCE_REPLACE.value());
executeDestroyUserInfo(sessionToReplace);
sessionToReplace.setAttribute(IGlobalConstants.SystemPara.system_message.name(), message);
}
}
//orgauth end
return true;
}
/**
* 成功登录后,初始化登录session信息; 插入用户在线记录,并更新状态为--"已登录"、记录登录时间、IP、登录次数
* 查询出公司、部门、营业厅信息
*
* @param request
* @param loginVo
*/
public void executeInitUserInfo(ServletRequest request, IRmLoginVo loginVo) {
//确保产生session,并往session放入loginVo
HttpSession session = RmJspHelper.getSession(request, true);
RmUserVo userVo = (RmUserVo)loginVo;
//orgauth initUserInfo begin
IRmOrgService orgService = RmOrgService.getInstance();
//定义当前用户所有的party_id
Set<String> sParty_id = new RmSequenceSet<String>();
if(userVo.getId() != null && userVo.getId().length() > 0) {
//放入用户ID
sParty_id.add(userVo.getId());
//所有祖先团体(包含父团体)
List<RmCommonVo> lAncestor = orgService.listAncestor(userVo.getId(),IOrgauthConstants.PartyView.DEFAULT.id());
Set<String> sAncestor_party_id = orgService.listAncestor_party_id(lAncestor);
Set<String> sOwner_party_id = orgService.listOwner_party_id(lAncestor, IOrgauthConstants.OrgTree.COMPANY.value());
//放入所有祖先团体
sParty_id.addAll(sAncestor_party_id);
//取关联角色的团体ID
String sqlRole = "select ROLE_ID from RM_PARTY_ROLE where OWNER_PARTY_ID in(" + RmStringHelper.parseToSQLString(sParty_id.toArray(new String[0])) + ") and (OWNER_ORG_ID in(" + RmStringHelper.parseToSQLStringApos(sAncestor_party_id.toArray(new String[0])) + ") or OWNER_ORG_ID is null or OWNER_ORG_ID='')";
List<String> lRole_id = RmProjectHelper.getCommonServiceInstance().query(sqlRole, new RowMapper() {
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
return rs.getString("ROLE_ID");
}
});
sParty_id.addAll(lRole_id);
//放入userVo
userVo.setParty_id_all(sParty_id.toArray(new String[0]));
userVo.setParty_id_owner(sOwner_party_id.toArray(new String[0]));
}
//取菜单权限
final Map<RmOrderCodes, String> mOrder = new TreeMap<RmOrderCodes, String>();
String sqlMenuList = "select distinct RM_FUNCTION_NODE.TOTAL_CODE, RM_FUNCTION_NODE.NAME, RM_FUNCTION_NODE.ORDER_CODE from RM_FUNCTION_NODE " +
"join RM_AUTHORIZE_RESOURCE on RM_FUNCTION_NODE.TOTAL_CODE=RM_AUTHORIZE_RESOURCE.OLD_RESOURCE_ID " +
"and RM_AUTHORIZE_RESOURCE.AUTHORIZE_ID=" + IOrgauthConstants.Authorize.FUNCTION_NODE.id() + " " +
"left join RM_AUTHORIZE_RESOURCE_RECORD on RM_AUTHORIZE_RESOURCE_RECORD.AUTHORIZE_RESOURCE_ID=RM_AUTHORIZE_RESOURCE.ID " +
"where RM_AUTHORIZE_RESOURCE.DEFAULT_ACCESS='1' or RM_AUTHORIZE_RESOURCE_RECORD.PARTY_ID in(" +
RmStringHelper.parseToSQLString(sParty_id.toArray(new String[0])) + ") ";
// + "order by " + RmSqlHelper.getFunction(RmSqlHelper.Function.SUBSTR, RmConfig.getDatabaseProductName()) +
// "(RM_FUNCTION_NODE.TOTAL_CODE, 1, LENGTH(RM_FUNCTION_NODE.TOTAL_CODE)-3), RM_FUNCTION_NODE.ORDER_CODE";
RmProjectHelper.getCommonServiceInstance().query(sqlMenuList, new RowMapper() {
public Object mapRow(ResultSet rs, int no) throws SQLException {
String totalCode = rs.getString("TOTAL_CODE");
String orderCode = rs.getString("ORDER_CODE");
String parentCode = null;
if(totalCode != null && totalCode.length() >= 3) {
parentCode = totalCode.substring(0, totalCode.length() - 3);
}
mOrder.put(new RmOrderCodes(parentCode, orderCode, totalCode), totalCode);
return null;
}
});
List<String> menuList = new ArrayList<String>();
menuList.addAll(mOrder.values());
userVo.setMenuList(menuList);
//orgauth initUserInfo end
//记住登录时间
userVo.getMAttribute().put(RmUserVo.A_LOGIN_TIME, String.valueOf(System.currentTimeMillis()));
//往session放入loginVo
session.setAttribute(IGlobalConstants.RM_USER_VO, userVo);
//更新用户状态
updateLoginStatus(request, loginVo);
}
/**
* 插入用户在线记录,并更新状态为--"已登录"、记录登录时间、IP、登录次数
* @param request
* @param loginVo
*/
private void updateLoginStatus(ServletRequest request, IRmLoginVo loginVo) {
//orgauth updateLoginStatus begin 插入用户在线记录
IRmUserOnlineRecordService uorService = (IRmUserOnlineRecordService)RmBeanFactory.getBean(IRmUserOnlineRecordConstants.SERVICE_KEY);
RmUserOnlineRecordVo uorVo = new RmUserOnlineRecordVo();
uorVo.setUser_id(loginVo.getId());
uorVo.setCluster_node_id(RmClusterConfig.getSingleton().getSelfId());
uorVo.setLogin_time(RmDateHelper.getSysTimestamp());
uorVo.setLogin_ip(RmProjectHelper.getIp(request));
uorVo.setLogin_uuid(RmGlobalMonitor.uniqueUUID.get());
uorVo.setLogin_sign(RmJspHelper.getSession(request).getId());
RmVoHelper.markCreateStamp((HttpServletRequest)request, uorVo);
uorService.insert(uorVo);
//更新用户状态
Timestamp lastLoginDate = uorVo.getLogin_time();
String lastLoginIp = uorVo.getLogin_ip();
RmProjectHelper.getCommonServiceInstance().doUpdate("update RM_USER set LOGIN_STATUS='1', LAST_LOGIN_DATE=?, LAST_LOGIN_IP=?, LOGIN_SUM=LOGIN_SUM+1 where ID=?", new Object[]{lastLoginDate, lastLoginIp, loginVo.getId()});
{
RmUserVo userVo = (RmUserVo)loginVo;
userVo.setLast_login_date(lastLoginDate);
userVo.setLast_login_ip(lastLoginIp);
userVo.setLogin_sum(userVo.getLogin_sum()+1);
}
//orgauth updateLoginStatus end
}
/**
* 清除登录session信息; 完成用户在线记录,并更新状态为--"未登录"
*
* @param session 要清理的session
*/
public void executeDestroyUserInfo(HttpSession session) {
if(session == null || session.getAttribute(IGlobalConstants.RM_USER_VO) == null
|| IGlobalConstants.RM_YES.equals(session.getAttribute(IGlobalConstants.RM_SSO_TEMP)) ) {
return;
}
RmUserVo vo = (RmUserVo)session.getAttribute(IGlobalConstants.RM_USER_VO);
//orgauth destroy begin 完成用户在线记录
IRmUserOnlineRecordService uorService = (IRmUserOnlineRecordService)RmBeanFactory.getBean(IRmUserOnlineRecordConstants.SERVICE_KEY);
List<RmUserOnlineRecordVo> lUor = uorService.queryByCondition("USER_ID=" + vo.getId() + " and LOGIN_SIGN='" + session.getId() + "' and LOGOUT_TIME is null", "LOGIN_TIME DESC", -1, -1, true);
if(lUor.size() > 0) {
RmUserOnlineRecordVo uorVo = (RmUserOnlineRecordVo)lUor.get(0);
uorVo.setLogout_time(RmDateHelper.getSysTimestamp());
if(session.getAttribute(IRmLoginConstants.LOGOUT_TYPE) != null) { //如果设置了注销类型
uorVo.setLogout_type(session.getAttribute(IRmLoginConstants.LOGOUT_TYPE).toString());
session.removeAttribute(IRmLoginConstants.LOGOUT_TYPE);
} else { //默认是超时退出
uorVo.setLogout_type(IRmLoginConstants.LogoutType.TIMEOUT.value());
}
uorVo.setLast_operation(vo.getMAttribute().get(RmUserVo.A_LAST_OPERATION));
uorVo.setOnline_time(new BigDecimal(uorVo.getLogout_time().getTime() - uorVo.getLogin_time().getTime()));
RmVoHelper.markModifyStamp(RmRequestMonitor.getCurrentThreadRequest(), uorVo);
uorService.update(uorVo);
//更新用户状态
RmProjectHelper.getCommonServiceInstance().doUpdate("update RM_USER SET LOGIN_STATUS='0' where ID=" + vo.getId());
}
//清除登录session信息
session.removeAttribute(IGlobalConstants.RM_USER_VO);
//orgauth destroy end
//system lockRelease begin
//释放用户的所有业务锁
org.quickbundle.modules.lock.RmLockHelper.releaseLock(vo.getId());
//system lockRelease end
}
}