/*
* Copyright (c) 2008-2016 Computer Network Information Center (CNIC), Chinese Academy of Sciences.
*
* This file is part of Duckling project.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package cn.vlabs.umt.services.user.service.impl;
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.log4j.Logger;
import cn.vlabs.umt.common.util.CommonUtils;
import cn.vlabs.umt.services.account.CoreMailAuthenticateResult;
import cn.vlabs.umt.services.account.ICoreMailClient;
import cn.vlabs.umt.services.user.Credential;
import cn.vlabs.umt.services.user.LoginService;
import cn.vlabs.umt.services.user.bean.AppSecret;
import cn.vlabs.umt.services.user.bean.BindInfo;
import cn.vlabs.umt.services.user.bean.CookieCredential;
import cn.vlabs.umt.services.user.bean.CoreMailUserInfo;
import cn.vlabs.umt.services.user.bean.LoginInfo;
import cn.vlabs.umt.services.user.bean.LoginNameInfo;
import cn.vlabs.umt.services.user.bean.OauthClientBean;
import cn.vlabs.umt.services.user.bean.OauthCredential;
import cn.vlabs.umt.services.user.bean.ThirdPartyCredential;
import cn.vlabs.umt.services.user.bean.TokenLoginCredential;
import cn.vlabs.umt.services.user.bean.User;
import cn.vlabs.umt.services.user.bean.UsernamePasswordCredential;
import cn.vlabs.umt.services.user.dao.IUserDAO;
import cn.vlabs.umt.services.user.dao.IUserLoginNameDAO;
import cn.vlabs.umt.services.user.service.IAppSecretService;
import cn.vlabs.umt.services.user.service.IOauthClientService;
import cn.vlabs.umt.services.user.service.ITransform;
public class PasswordLogin implements LoginService {
private static final Logger LOGGER=Logger.getLogger(PasswordLogin.class);
private static Pattern smallLetterPattern = Pattern.compile("^[a-z]{8,50}$");
private static Pattern bigLetterPattern=Pattern.compile("^[A-Z]{8,50}$");
private static Pattern numberPattern=Pattern.compile("^[0-9]{8,50}$");
private boolean isPasswordWeak(String password){
if(CommonUtils.isNull(password)){
return true;
}
password=CommonUtils.trim(password);
if(password.length()>50||password.length()<8){
return true;
}
Matcher sMatcher = smallLetterPattern.matcher(password);
if(sMatcher.find()){
return true;
}
Matcher bMatcher = bigLetterPattern.matcher(password);
if(bMatcher.find()){
return true;
}
Matcher nMatcher = numberPattern.matcher(password);
if(nMatcher.find()){
return true;
}
return false;
}
@Override
public boolean passwordRight(Credential cred) {
return loginAndReturnPasswordType(cred).getUser()!=null;
}
public PasswordLogin(){
coreMailClient=ICoreMailClient.getInstance();
}
private LoginInfo doWebLoginCredential(TokenLoginCredential cred){
LoginInfo info=new LoginInfo();
if(cred==null||cred.getToken()==null){
return info;
}
User umtUser=userDAO.getUserByUid(cred.getToken().getUid());
if(umtUser==null){
return info;
}
info.setPasswordType(cred.getToken().getPasswordType());
/*info.setPasswordType(LoginInfo.TYPE_WEB_LOGIN);*/
info.setUser(umtUser);
info.setLoginNameInfo(loginNameDAO.getALoginNameInfo(umtUser.getId(),umtUser.getCstnetId()));
return info;
}
public LoginInfo loginOauthAndReturnPasswordType(OauthCredential cred) {
return null;
}
private LoginInfo doThirdPartyPasswordCredential(ThirdPartyCredential cred){
LoginInfo info=new LoginInfo();
if(cred==null){
return info;
}
User umtUser=loginNameDAO.getUserByLoginName(cred.getUsername());
if(umtUser==null){
return info;
}
if(BindInfo.TYPE_SINA.equals(cred.getAuthBy())){
info.setPasswordType(LoginInfo.TYPE_THIRD_PARTY_SINA);
}else if(BindInfo.TYPE_QQ.equals(cred.getAuthBy())){
info.setPasswordType(LoginInfo.TYPE_THIRD_PARTY_QQ);
}else if(BindInfo.TYPE_CASHQ_SSO.equals(cred.getAuthBy())){
info.setPasswordType(LoginInfo.TYPE_THIRD_PARTY_CAS_HQ);
}else if(BindInfo.TYPE_UAF.equals(cred.getAuthBy())){
info.setPasswordType(LoginInfo.TYPE_THIRD_PARTY_UAF);
}else if(BindInfo.TYPE_CAS_GEO.equals(cred.getAuthBy())){
info.setPasswordType(LoginInfo.TYPE_THIRD_PARTY_CAS_GEO);
}else{
info.setPasswordType(cred.getAuthBy());
}
info.setUser(umtUser);
info.setLoginNameInfo(loginNameDAO.getALoginNameInfo(umtUser.getId(),cred.getUsername()));
return info;
}
@Override
public boolean coreMailPasswordRight(UsernamePasswordCredential cred) {
return coreMailClient.authenticate(cred.getUsername(),cred.getPassword()).isSuccess();
}
@Override
public boolean umtPasswrdRight(UsernamePasswordCredential cred) {
boolean flag= false;
User umtUser=loginNameDAO.getUserByLoginName(cred.getUsername());
if(umtUser!=null&& transform.transform(cred.getPassword()).equals(umtUser.getPassword())){
flag=true;
}
return flag;
}
private boolean validateCoreMailUser(CoreMailUserInfo userInfo,LoginInfo info){
if(userInfo.isExpired()){
info.setValidateResult(LoginInfo.VALIDATE_RESULT_USER_EXPIRED);
return false;
}
if(CoreMailUserInfo.STATUS_LOCK.equals(userInfo.getStatus())){
info.setValidateResult(LoginInfo.VALIDATE_RESULT_USER_LOCKED);
return false;
}
if(CoreMailUserInfo.STATUS_STOP.equals(userInfo.getStatus())){
info.setValidateResult(LoginInfo.VALIDATE_RESULT_USER_STOP);
return false;
}
return true;
}
@Override
public boolean oauthPasswordRight(OauthCredential cred) {
return !CommonUtils.isNull(doOauthCredential(cred).getPasswordType());
}
private LoginInfo doOauthCredential(OauthCredential cred){
LoginInfo info=new LoginInfo();
if(cred==null){
return info;
}
OauthClientBean ocb=oauthClientService.findByClientId(cred.getClientId());
if(ocb==null||!"yes".equals(ocb.getEnableAppPwd())){
LOGGER.info("oauth:the clientId ["+cred.getClientId()+"] for oauth, disable app secret or not found");
return info;
}
User user=loginNameDAO.getUserByLoginName(cred.getUserName());
if(user==null){
LOGGER.info("oauth:can't found user["+cred.getUserName()+"]");
return info;
}
if(User.ACCOUNT_STATUS_LOCKED.equals( user.getAccountStatus())){
LOGGER.info("oauth: user["+cred.getUserName()+"]is locked!!!");
info.setValidateResult(LoginInfo.VALIDATE_RESULT_USER_LOCKED);
return info;
}
AppSecret appSecret=appSecretService.findAppSecretByUidAndAppId(cred.getClientId(),user.getId());
if(appSecret==null){
LOGGER.info("oauth:this user"+cred.getUserName()+" not have secret!");
return info;
}
if(!transform.transform(CommonUtils.trim(cred.getPassword())).equals(appSecret.getSecret())){
LOGGER.info("oauth:passwordError["+cred.getUserName()+"]");
return info;
}
info.setLoginNameInfo(loginNameDAO.getALoginNameInfo(user.getId(),cred.getUserName()));
info.setPasswordType("oauth."+cred.getClientId());
info.setValidateResult("true");
info.setUser(user);
return info;
}
private LoginInfo doUsernamePasswordCredential(UsernamePasswordCredential cred){
LoginInfo info=new LoginInfo();
if(cred==null){
return info;
}
LOGGER.info("validate user["+cred.getUsername()+"] start!");
UsernamePasswordCredential ucred=(UsernamePasswordCredential)cred;
String password = transform.transform(ucred.getPassword());
User umtUser=loginNameDAO.getUserByLoginName(cred.getUsername());
boolean isUmtUser=(umtUser!=null);
//如果是umt用户且已经锁定,直接滚粗
if(isUmtUser&&(User.ACCOUNT_STATUS_LOCKED.equals(umtUser.getAccountStatus()))){
LOGGER.info("user ["+cred.getUsername()+"] is locked! but he want login");
info.setValidateResult(LoginInfo.VALIDATE_RESULT_USER_LOCKED);
return info;
}
boolean isUmtPasswordRight=password.equals(isUmtUser?umtUser.getPassword():"");
CoreMailAuthenticateResult coreMailResult=coreMailClient.authenticate(isUmtUser?umtUser.getCstnetId():ucred.getUsername(),ucred.getPassword());
boolean isMailUser=coreMailResult.isValidUserName();
boolean isMailPasswordRight=(isMailUser&&coreMailResult.isSuccess());
LoginNameInfo loginNameInfo=null;
if(isUmtUser){
loginNameInfo=loginNameDAO.getALoginNameInfo(umtUser.getId(), ucred.getUsername());
}
//如果用户欲登陆的信息是,辅助账号,且是未验证的,那就没有必要继续下去了
if(isUmtUser&&loginNameInfo.isTmpAndSecondary()){
return info;
}
//mail验证通过,但是以前umt未存在的用户
if(isMailPasswordRight&&(!isUmtUser)){
if(!validateCoreMailUser(coreMailResult.getCoreMailInfo(),info)){
return info;
}
if(loginNameDAO.isUsed(ucred.getUsername())){
User tmpUser=loginNameDAO.getUserByLoginName(ucred.getUsername());
info.setUser(tmpUser);
info.setLoginNameInfo(loginNameDAO.getALoginNameInfo(tmpUser.getId(),tmpUser.getCstnetId()));
}else{
User user=coreMailResult.getCoreMailInfo().getUser();
user.setId(userDAO.create(user));
if(user.getId()>0){
int infoId=loginNameDAO.createLoginName(user.getCstnetId(), user.getId(), LoginNameInfo.LOGINNAME_TYPE_PRIMARY,LoginNameInfo.STATUS_ACTIVE);
info.setLoginNameInfo(loginNameDAO.getLoginNameInfoById(infoId));
info.setUser(user);
}
}
info.setPasswordType(LoginInfo.TYPE_CORE_MAIL);
info.setWeak(isPasswordWeak(cred.getPassword()));
info.setValidateResult(LoginInfo.VALIDATE_RESULT_SUCCESS);
return info;
}
//即是umt用户,也是mail用户,但是用mail密码登陆成功
else if(isMailPasswordRight&&(isUmtUser)){
if(!validateCoreMailUser(coreMailResult.getCoreMailInfo(),info)){
return info;
}
if(!User.USER_TYPE_CORE_MAIL.equals(umtUser.getType())){
umtUser.setType(User.USER_TYPE_MAIL_AND_UMT);
userDAO.updateValueByColumn(new int[]{umtUser.getId()}, "type",User.USER_TYPE_MAIL_AND_UMT );
}
info.setUser(umtUser);
info.setPasswordType(LoginInfo.TYPE_CORE_MAIL);
info.setLoginNameInfo(loginNameInfo);
info.setWeak(isPasswordWeak(cred.getPassword()));
info.setValidateResult(LoginInfo.VALIDATE_RESULT_SUCCESS);
return info;
}
//umt验证通过,但是mail未存在的用户
else if(isUmtPasswordRight&&(!isMailUser)){
info.setUser(umtUser);
info.setPasswordType(LoginInfo.TYPE_UMT);
info.setLoginNameInfo(loginNameInfo);
info.setValidateResult(LoginInfo.VALIDATE_RESULT_SUCCESS);
return info;
}
//即是umt用户,也是mail用户,但是用umt密码登陆成功
else if(isUmtPasswordRight&&(isMailUser)){
if(User.USER_TYPE_CORE_MAIL.equals(umtUser.getType())&&!CommonUtils.isNull(umtUser.getPassword())){
//他authby为coreMail,且密码不为空,代表用户已经过合并
return info;
}
if(User.USER_TYPE_UMT.equals(umtUser.getType())){
umtUser.setType(User.USER_TYPE_MAIL_AND_UMT);
userDAO.updateValueByColumn(new int[]{umtUser.getId()}, "type",User.USER_TYPE_MAIL_AND_UMT);
}
info.setUser(umtUser);
info.setLoginNameInfo(loginNameInfo);
info.setPasswordType(LoginInfo.TYPE_UMT);
info.setValidateResult(LoginInfo.VALIDATE_RESULT_SUCCESS);
return info;
}else{
return info;
}
}
@Override
public LoginInfo loginAndReturnPasswordType(Credential cred) {
if(cred==null){
return new LoginInfo();
}
if (cred instanceof UsernamePasswordCredential){
return doUsernamePasswordCredential((UsernamePasswordCredential)cred);
}else if(cred instanceof ThirdPartyCredential){
return doThirdPartyPasswordCredential((ThirdPartyCredential)cred);
}else if(cred instanceof CookieCredential){
return doCookieCredential((CookieCredential)cred);
}else if(cred instanceof TokenLoginCredential){
return doWebLoginCredential((TokenLoginCredential)cred);
}else if(cred instanceof OauthCredential){
return doOauthCredential((OauthCredential)cred);
}
return new LoginInfo();
}
/**
* @param cred
* @return
*/
private LoginInfo doCookieCredential(CookieCredential cred) {
LoginInfo info=new LoginInfo();
String value=cred.getCookieValue();
String ip=cred.getIp();
if(CommonUtils.isNull(value)||CommonUtils.isNull(ip)){
LOGGER.debug("cookie log is error:["+value+","+ip+"]");
return info;
}
String[] infos=value.split("/");
if(CommonUtils.isNull(infos)||(infos.length!=3&&infos.length!=4)){
LOGGER.debug("cookie value is error:["+Arrays.toString(infos)+"]");
return info;
}
String cookieIp=infos[1];
if(!ip.equals(cookieIp)){
LOGGER.debug("cookie ip error! expect:"+ip+",but is:"+cookieIp);
return info;
}
String cstnetId=infos[0];
User umtUser=loginNameDAO.getUserByLoginName(cstnetId);
if(umtUser==null){
LOGGER.error("cookie error,umtUser is null by loginname="+cstnetId);
return info;
}
info.setUser(umtUser);
info.setPasswordType(infos[2]);
info.setLoginNameInfo(loginNameDAO.getALoginNameInfo(umtUser.getId(), cstnetId));
return info;
}
public void setTransform(ITransform transform){
this.transform=transform;
}
private ITransform transform;
private IUserDAO userDAO;
private IUserLoginNameDAO loginNameDAO;
private IOauthClientService oauthClientService;
private IAppSecretService appSecretService;
public void setAppSecretService(IAppSecretService appSecretService) {
this.appSecretService = appSecretService;
}
/**
* CoreMail用户验证服务类
**/
private ICoreMailClient coreMailClient;
public void setOauthClientService(IOauthClientService oauthClientService) {
this.oauthClientService = oauthClientService;
}
public void setLoginNameDAO(IUserLoginNameDAO loginNameDAO) {
this.loginNameDAO = loginNameDAO;
}
public void setUserDAO(IUserDAO userDAO){
this.userDAO=userDAO;
}
}