功能模块化,调整通用模块为starter

maxkey-starter:maxkey-starter-captcha
maxkey-starter:maxkey-starter-ip2location
maxkey-starter:maxkey-starter-otp
maxkey-starter:maxkey-starter-sms
maxkey-starter:maxkey-starter-web
This commit is contained in:
shimingxy
2024-07-12 12:02:50 +08:00
parent 5dd0c6dc96
commit e1ac754186
100 changed files with 91 additions and 96 deletions
@@ -0,0 +1,104 @@
/*
* Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
*
* 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 org.dromara.maxkey.persistence.repository;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import org.dromara.maxkey.entity.Institutions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
public class InstitutionsRepository {
private static Logger _logger = LoggerFactory.getLogger(InstitutionsRepository.class);
private static final String SELECT_STATEMENT =
"select * from mxk_institutions where id = ? or domain = ? or consoledomain = ?" ;
private static final String DEFAULT_INSTID = "1";
protected static final Cache<String, Institutions> institutionsStore =
Caffeine.newBuilder()
.expireAfterWrite(60, TimeUnit.MINUTES)
.build();
//id domain mapping
protected static final ConcurrentHashMap<String,String> mapper = new ConcurrentHashMap<String,String>();
protected JdbcTemplate jdbcTemplate;
public InstitutionsRepository(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public Institutions get(String instIdOrDomain) {
_logger.trace(" instId {}" , instIdOrDomain);
Institutions inst = getByInstIdOrDomain(instIdOrDomain);
if(inst == null) {//use default inst
inst = getByInstIdOrDomain(DEFAULT_INSTID);
institutionsStore.put(instIdOrDomain, inst);
}
return inst;
}
private Institutions getByInstIdOrDomain(String instIdOrDomain) {
_logger.trace(" instId {}" , instIdOrDomain);
Institutions inst = institutionsStore.getIfPresent(mapper.get(instIdOrDomain)==null ? DEFAULT_INSTID : mapper.get(instIdOrDomain) );
if(inst == null) {
List<Institutions> institutions =
jdbcTemplate.query(SELECT_STATEMENT,new InstitutionsRowMapper(),instIdOrDomain,instIdOrDomain,instIdOrDomain);
if (institutions != null && institutions.size() > 0) {
inst = institutions.get(0);
}
if(inst != null ) {
institutionsStore.put(inst.getDomain(), inst);
institutionsStore.put(inst.getConsoleDomain(), inst);
mapper.put(inst.getId(), inst.getDomain());
}
}
return inst;
}
public class InstitutionsRowMapper implements RowMapper<Institutions> {
@Override
public Institutions mapRow(ResultSet rs, int rowNum) throws SQLException {
Institutions institution = new Institutions();
institution.setId(rs.getString("id"));
institution.setName(rs.getString("name"));
institution.setFullName(rs.getString("fullname"));
institution.setLogo(rs.getString("logo"));
institution.setDomain(rs.getString("domain"));
institution.setFrontTitle(rs.getString("fronttitle"));
institution.setConsoleDomain(rs.getString("consoledomain"));
institution.setConsoleTitle(rs.getString("consoletitle"));
institution.setCaptcha(rs.getString("captcha"));
institution.setDefaultUri(rs.getString("defaultUri"));
return institution;
}
}
}
@@ -0,0 +1,156 @@
/*
* Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
*
* 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 org.dromara.maxkey.persistence.repository;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
import org.dromara.maxkey.constants.ConstsTimeInterval;
import org.dromara.maxkey.entity.Localization;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
public class LocalizationRepository {
private static Logger _logger = LoggerFactory.getLogger(LocalizationRepository.class);
private static final String INSERT_STATEMENT ="insert into mxk_localization (id, property,langzh,langen,status,description,instid)values(?,?,?,?,?,?,?)";
private static final String UPDATE_STATEMENT ="update mxk_localization set langzh = ? , langen =? where id = ?";
private static final String DELETE_STATEMENT ="delete from mxk_localization where id = ?";
private static final String SELECT_STATEMENT ="select * from mxk_localization where ( id = ? ) or (property = ? and instid = ?)";
private static final Pattern PATTERN_HTML = Pattern.compile("<[^>]+>", Pattern.CASE_INSENSITIVE);
protected InstitutionsRepository institutionService;
JdbcTemplate jdbcTemplate;
protected static final Cache<String, String> localizationStore =
Caffeine.newBuilder()
.expireAfterWrite(ConstsTimeInterval.ONE_HOUR, TimeUnit.SECONDS)
.build();
public LocalizationRepository() {
}
public String getLocale(String code,String htmlTag,Locale locale,String inst) {
String message = "";
htmlTag = (htmlTag == null ||htmlTag.equalsIgnoreCase("true")) ? "tag" : "rtag";
if(code.equals("global.logo")) {
message = institutionService.get(inst).getLogo();
}else if(code.equals("global.title")) {
message = getFromStore(code, htmlTag, locale, inst);
if(message == null) {
message = institutionService.get(inst).getFrontTitle();
}
}else if(code.equals("global.consoleTitle")) {
message = getFromStore(code, htmlTag, locale, inst);
if(message == null) {
message = institutionService.get(inst).getConsoleTitle();
}
}else {
message = getFromStore(code, htmlTag, locale, inst);
}
if(htmlTag.equalsIgnoreCase("rtag")) {
message = clearHTMLToString(message);
}
_logger.trace("{} = {}" , code , message);
return message == null ? "" : message;
}
public String clearHTMLToString(String message) {
return PATTERN_HTML.matcher(message).replaceAll("");
}
public String getFromStore(String code,String htmlTag,Locale locale,String inst) {
String message = localizationStore.getIfPresent(code+"_"+locale.getLanguage()+"_"+inst);
if(message != null) return message;
Localization localization = get(code,inst);
if(localization != null) {
localizationStore.put(code+"_en_"+inst, localization.getLangEn());
localizationStore.put(code+"_zh_"+inst, localization.getLangZh());
if(locale.getLanguage().equals("en")) {
message = localization.getLangEn();
}else {
message = localization.getLangZh();
}
if(message != null) return message;
}
return message;
}
public void setInstitutionService(InstitutionsRepository institutionService) {
this.institutionService = institutionService;
}
public boolean insert(Localization localization) {
return jdbcTemplate.update(INSERT_STATEMENT,
new Object[] {localization.getId(),localization.getProperty(),
localization.getLangZh(),localization.getLangEn(),
localization.getStatus(),localization.getDescription(),
localization.getInstId()},
new int[] {Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.INTEGER,
Types.VARCHAR, Types.VARCHAR,}) > 0;
}
public boolean update(Localization localization) {
jdbcTemplate.update(UPDATE_STATEMENT,localization.getLangZh(),localization.getLangEn(),localization.getId());
return true;
}
public boolean remove(String id) {
return jdbcTemplate.update(DELETE_STATEMENT,id) > 0;
}
public Localization get(String property,String instId) {
_logger.debug("load property from database , property {} ,instId {}",property, instId);
List<Localization> localizations =
jdbcTemplate.query(
SELECT_STATEMENT,new LocalizationRowMapper(),property,property,instId);
return (localizations==null || localizations.size()==0) ? null : localizations.get(0);
}
public LocalizationRepository(JdbcTemplate jdbcTemplate,InstitutionsRepository institutionService) {
super();
this.institutionService = institutionService;
this.jdbcTemplate = jdbcTemplate;
}
public class LocalizationRowMapper implements RowMapper<Localization> {
@Override
public Localization mapRow(ResultSet rs, int rowNum) throws SQLException {
Localization localization = new Localization();
localization.setId(rs.getString("id"));
localization.setProperty(rs.getString("property"));
localization.setLangZh(rs.getString("langzh"));
localization.setLangEn(rs.getString("langen"));
localization.setStatus(rs.getInt("status"));
localization.setDescription(rs.getString("description"));
localization.setInstId(rs.getString("instid"));
return localization;
}
}
}
@@ -0,0 +1,133 @@
/*
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
*
* 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 org.dromara.maxkey.persistence.repository;
import java.sql.Types;
import org.dromara.maxkey.entity.HistoryLogin;
import org.dromara.maxkey.web.WebContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
public class LoginHistoryRepository {
private static Logger logger = LoggerFactory.getLogger(LoginHistoryRepository.class);
private static final String HISTORY_LOGIN_INSERT_STATEMENT = """
insert into mxk_history_login
( id ,
sessionid ,
userid ,
username ,
displayname ,
logintype ,
message ,
code ,
provider ,
sourceip ,
country ,
province ,
city ,
location ,
browser ,
platform ,
application ,
loginurl ,
sessionstatus ,
instid)
values( ? , ? , ? , ? , ? , ? , ? , ? , ?, ? , ? , ? , ?, ?, ? , ? , ?, ? , ? , ?)
""";
protected JdbcTemplate jdbcTemplate;
public LoginHistoryRepository(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public void login(HistoryLogin historyLogin) {
historyLogin.setId(WebContext.genId());
historyLogin.setLoginUrl(WebContext.getRequest().getRequestURI());
//Thread insert
new Thread(new HistoryLoginRunnable(jdbcTemplate,historyLogin)).start();
}
public class HistoryLoginRunnable implements Runnable{
JdbcTemplate jdbcTemplate;
HistoryLogin historyLogin;
public HistoryLoginRunnable(JdbcTemplate jdbcTemplate, HistoryLogin historyLogin) {
super();
this.jdbcTemplate = jdbcTemplate;
this.historyLogin = historyLogin;
}
@Override
public void run() {
logger.debug("History Login {}" , historyLogin);
jdbcTemplate.update(HISTORY_LOGIN_INSERT_STATEMENT,
new Object[] {
historyLogin.getId(),
historyLogin.getSessionId(),
historyLogin.getUserId(),
historyLogin.getUsername(),
historyLogin.getDisplayName(),
historyLogin.getLoginType(),
historyLogin.getMessage(),
historyLogin.getCode(),
historyLogin.getProvider(),
historyLogin.getSourceIp(),
historyLogin.getCountry(),
historyLogin.getProvince(),
historyLogin.getCity(),
historyLogin.getLocation(),
historyLogin.getBrowser(),
historyLogin.getPlatform(),
"Browser",
historyLogin.getLoginUrl(),
historyLogin.getSessionStatus(),
historyLogin.getInstId()
},
new int[] {
Types.VARCHAR,
Types.VARCHAR,
Types.VARCHAR,
Types.VARCHAR,
Types.VARCHAR,
Types.VARCHAR,
Types.VARCHAR,
Types.VARCHAR,
Types.VARCHAR,
Types.VARCHAR,
Types.VARCHAR,
Types.VARCHAR,
Types.VARCHAR,
Types.VARCHAR,
Types.VARCHAR,
Types.VARCHAR,
Types.VARCHAR,
Types.VARCHAR,
Types.INTEGER,
Types.VARCHAR
});
}
}
}
@@ -0,0 +1,381 @@
/*
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
*
* 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 org.dromara.maxkey.persistence.repository;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.dromara.maxkey.constants.ConstsRoles;
import org.dromara.maxkey.constants.ConstsStatus;
import org.dromara.maxkey.entity.Groups;
import org.dromara.maxkey.entity.UserInfo;
import org.dromara.maxkey.util.StrUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
public class LoginRepository {
private static final Logger _logger = LoggerFactory.getLogger(LoginRepository.class);
private static final String LOCK_USER_UPDATE_STATEMENT = "update mxk_userinfo set islocked = ? , unlocktime = ? where id = ?";
private static final String UNLOCK_USER_UPDATE_STATEMENT = "update mxk_userinfo set islocked = ? , unlocktime = ? where id = ?";
private static final String BADPASSWORDCOUNT_UPDATE_STATEMENT = "update mxk_userinfo set badpasswordcount = ? , badpasswordtime = ? where id = ?";
private static final String BADPASSWORDCOUNT_RESET_UPDATE_STATEMENT = "update mxk_userinfo set badpasswordcount = ? , islocked = ? ,unlocktime = ? where id = ?";
private static final String LOGIN_USERINFO_UPDATE_STATEMENT = "update mxk_userinfo set lastlogintime = ? , lastloginip = ? , logincount = ?, online = "
+ UserInfo.ONLINE.ONLINE + " where id = ?";
private static final String GROUPS_SELECT_STATEMENT = "select distinct g.id,g.groupcode,g.groupname from mxk_userinfo u,mxk_groups g,mxk_group_member gm where u.id = ? and u.id=gm.memberid and gm.groupid=g.id ";
private static final String DEFAULT_USERINFO_SELECT_STATEMENT = "select * from mxk_userinfo where username = ? ";
private static final String DEFAULT_USERINFO_SELECT_STATEMENT_USERNAME_MOBILE = "select * from mxk_userinfo where (username = ? or mobile = ?)";
private static final String DEFAULT_USERINFO_SELECT_STATEMENT_USERNAME_MOBILE_EMAIL = "select * from mxk_userinfo where (username = ? or mobile = ? or email = ?) ";
private static final String DEFAULT_MYAPPS_SELECT_STATEMENT = "select distinct app.id,app.appname from mxk_apps app,mxk_group_permissions gp,mxk_groups g where app.id=gp.appid and app.status = 1 and gp.groupid=g.id and g.id in(%s)";
protected JdbcTemplate jdbcTemplate;
/**
* 1 (USERNAME) 2 (USERNAME | MOBILE) 3 (USERNAME | MOBILE | EMAIL)
*/
public static int LOGIN_ATTRIBUTE_TYPE = 2;
public LoginRepository(){
}
public LoginRepository(JdbcTemplate jdbcTemplate){
this.jdbcTemplate=jdbcTemplate;
}
public UserInfo find(String username, String password) {
List<UserInfo> listUserInfo = null ;
if( LOGIN_ATTRIBUTE_TYPE == 1) {
listUserInfo = findByUsername(username,password);
}else if( LOGIN_ATTRIBUTE_TYPE == 2) {
listUserInfo = findByUsernameOrMobile(username,password);
}else if( LOGIN_ATTRIBUTE_TYPE == 3) {
listUserInfo = findByUsernameOrMobileOrEmail(username,password);
}
_logger.debug("load UserInfo : {}" , listUserInfo);
return (CollectionUtils.isNotEmpty(listUserInfo))? listUserInfo.get(0) : null;
}
public List<UserInfo> findByUsername(String username, String password) {
return jdbcTemplate.query(
DEFAULT_USERINFO_SELECT_STATEMENT,
new UserInfoRowMapper(),
username
);
}
public List<UserInfo> findByUsernameOrMobile(String username, String password) {
return jdbcTemplate.query(
DEFAULT_USERINFO_SELECT_STATEMENT_USERNAME_MOBILE,
new UserInfoRowMapper(),
username,username
);
}
public List<UserInfo> findByUsernameOrMobileOrEmail(String username, String password) {
return jdbcTemplate.query(
DEFAULT_USERINFO_SELECT_STATEMENT_USERNAME_MOBILE_EMAIL,
new UserInfoRowMapper(),
username,username,username
);
}
/**
* 閿佸畾鐢ㄦ埛锛歩slock锛�1 鐢ㄦ埛瑙i攣 2 鐢ㄦ埛閿佸畾
*
* @param userInfo
*/
public void updateLock(UserInfo userInfo) {
try {
if (userInfo != null && StringUtils.isNotEmpty(userInfo.getId())) {
jdbcTemplate.update(LOCK_USER_UPDATE_STATEMENT,
new Object[] { ConstsStatus.LOCK, new Date(), userInfo.getId() },
new int[] { Types.VARCHAR, Types.TIMESTAMP, Types.VARCHAR });
userInfo.setIsLocked(ConstsStatus.LOCK);
}
} catch (Exception e) {
_logger.error("lockUser Exception",e);
}
}
/**
* 閿佸畾鐢ㄦ埛锛歩slock锛�1 鐢ㄦ埛瑙i攣 2 鐢ㄦ埛閿佸畾
*
* @param userInfo
*/
public void updateUnlock(UserInfo userInfo) {
try {
if (userInfo != null && StringUtils.isNotEmpty(userInfo.getId())) {
jdbcTemplate.update(UNLOCK_USER_UPDATE_STATEMENT,
new Object[] { ConstsStatus.ACTIVE, new Date(), userInfo.getId() },
new int[] { Types.VARCHAR, Types.TIMESTAMP, Types.VARCHAR });
userInfo.setIsLocked(ConstsStatus.ACTIVE);
}
} catch (Exception e) {
_logger.error("unlockUser Exception",e);
}
}
/**
* reset BadPasswordCount And Lockout
*
* @param userInfo
*/
public void updateLockout(UserInfo userInfo) {
try {
if (userInfo != null && StringUtils.isNotEmpty(userInfo.getId())) {
jdbcTemplate.update(BADPASSWORDCOUNT_RESET_UPDATE_STATEMENT,
new Object[] { 0, ConstsStatus.ACTIVE, new Date(), userInfo.getId() },
new int[] { Types.INTEGER, Types.INTEGER, Types.TIMESTAMP, Types.VARCHAR });
userInfo.setIsLocked(ConstsStatus.ACTIVE);
}
} catch (Exception e) {
_logger.error("resetBadPasswordCountAndLockout Exception",e);
}
}
/**
* if login password is error ,BadPasswordCount++ and set bad date
*
* @param userInfo
*/
public void updateBadPasswordCount(UserInfo userInfo) {
try {
if (userInfo != null && StringUtils.isNotEmpty(userInfo.getId())) {
int badPasswordCount = userInfo.getBadPasswordCount() + 1;
userInfo.setBadPasswordCount(badPasswordCount);
jdbcTemplate.update(BADPASSWORDCOUNT_UPDATE_STATEMENT,
new Object[] { badPasswordCount, new Date(), userInfo.getId() },
new int[] { Types.INTEGER, Types.TIMESTAMP, Types.VARCHAR });
}
} catch (Exception e) {
e.printStackTrace();
_logger.error(e.getMessage());
}
}
public List<GrantedAuthority> queryAuthorizedApps(List<GrantedAuthority> grantedAuthoritys) {
String grantedAuthorityString="'ROLE_ALL_USER'";
for(GrantedAuthority grantedAuthority : grantedAuthoritys) {
grantedAuthorityString += ",'"+ grantedAuthority.getAuthority()+"'";
}
ArrayList<GrantedAuthority> listAuthorizedApps = (ArrayList<GrantedAuthority>) jdbcTemplate.query(
String.format(DEFAULT_MYAPPS_SELECT_STATEMENT, grantedAuthorityString),
new RowMapper<GrantedAuthority>() {
public GrantedAuthority mapRow(ResultSet rs, int rowNum) throws SQLException {
return new SimpleGrantedAuthority(rs.getString("id"));
}
});
_logger.debug("list Authorized Apps {}" , listAuthorizedApps);
return listAuthorizedApps;
}
public List<Groups> queryGroups(UserInfo userInfo) {
List<Groups> listRoles = jdbcTemplate.query(GROUPS_SELECT_STATEMENT, new RowMapper<Groups>() {
public Groups mapRow(ResultSet rs, int rowNum) throws SQLException {
return new Groups(rs.getString("id"), rs.getString("groupcode"),rs.getString("groupname"), 0);
}
}, userInfo.getId());
_logger.debug("list Roles {}" , listRoles);
return listRoles;
}
/**
* grant Authority by userinfo
*
* @param userInfo
* @return ArrayList<GrantedAuthority>
*/
public List<GrantedAuthority> grantAuthority(UserInfo userInfo) {
// query Groups for user
List<Groups> listGroups = queryGroups(userInfo);
//set default groups
ArrayList<GrantedAuthority> grantedAuthority = new ArrayList<>();
grantedAuthority.add(ConstsRoles.ROLE_USER);
grantedAuthority.add(ConstsRoles.ROLE_ALL_USER);
grantedAuthority.add(ConstsRoles.ROLE_ORDINARY_USER);
for (Groups group : listGroups) {
grantedAuthority.add(new SimpleGrantedAuthority(group.getId()));
if(group.getGroupCode().startsWith("ROLE_")
&& !grantedAuthority.contains(new SimpleGrantedAuthority(group.getGroupCode()))) {
grantedAuthority.add(new SimpleGrantedAuthority(group.getGroupCode()));
}
}
_logger.debug("Authority : {}" , grantedAuthority);
return grantedAuthority;
}
public void updateLastLogin(UserInfo userInfo) {
jdbcTemplate.update(LOGIN_USERINFO_UPDATE_STATEMENT,
new Object[] {
userInfo.getLastLoginTime(),
userInfo.getLastLoginIp(),
userInfo.getLoginCount() + 1,
userInfo.getId()
},
new int[] { Types.TIMESTAMP, Types.VARCHAR, Types.INTEGER, Types.VARCHAR });
}
public class UserInfoRowMapper implements RowMapper<UserInfo> {
@Override
public UserInfo mapRow(ResultSet rs, int rowNum) throws SQLException {
UserInfo userInfo = new UserInfo();
userInfo.setId(rs.getString("id"));
userInfo.setUsername(rs.getString("username"));
userInfo.setPassword(rs.getString("password"));
userInfo.setSharedSecret(rs.getString("sharedsecret"));
userInfo.setSharedCounter(rs.getString("sharedcounter"));
userInfo.setDecipherable(rs.getString("decipherable"));
userInfo.setWindowsAccount(rs.getString("windowsaccount"));
userInfo.setUserType(rs.getString("usertype"));
userInfo.setDisplayName(rs.getString("displayname"));
userInfo.setNickName(rs.getString("nickname"));
userInfo.setNameZhSpell(rs.getString("namezhspell"));// nameZHSpell
userInfo.setNameZhShortSpell(rs.getString("namezhshortspell"));// nameZHSpell
userInfo.setGivenName(rs.getString("givenname"));
userInfo.setMiddleName(rs.getString("middlename"));
userInfo.setFamilyName(rs.getString("familyname"));
userInfo.setHonorificPrefix(rs.getString("honorificprefix"));
userInfo.setHonorificSuffix(rs.getString("honorificsuffix"));
userInfo.setFormattedName(rs.getString("formattedname"));
userInfo.setGender(rs.getInt("gender"));
userInfo.setBirthDate(rs.getString("birthdate"));
userInfo.setPicture(rs.getBytes("picture"));
userInfo.setMarried(rs.getInt("married"));
userInfo.setIdType(rs.getInt("idtype"));
userInfo.setIdCardNo(rs.getString("idcardno"));
userInfo.setWebSite(rs.getString("website"));
userInfo.setAuthnType(rs.getInt("authntype"));
userInfo.setMobile(rs.getString("mobile"));
userInfo.setMobileVerified(rs.getInt("mobileverified"));
userInfo.setEmail(rs.getString("email"));
userInfo.setEmailVerified(rs.getInt("emailverified"));
userInfo.setPasswordQuestion(rs.getString("passwordquestion"));
userInfo.setPasswordAnswer(rs.getString("passwordanswer"));
userInfo.setAppLoginAuthnType(rs.getInt("apploginauthntype"));
userInfo.setAppLoginPassword(rs.getString("apploginpassword"));
userInfo.setProtectedApps(rs.getString("protectedapps"));
userInfo.setPasswordLastSetTime(rs.getTimestamp("passwordlastsettime"));
userInfo.setPasswordSetType(rs.getInt("passwordsettype"));
userInfo.setBadPasswordCount(rs.getInt("badpasswordcount"));
userInfo.setBadPasswordTime(rs.getTimestamp("badpasswordtime"));
userInfo.setUnLockTime(rs.getTimestamp("unlocktime"));
userInfo.setIsLocked(rs.getInt("islocked"));
userInfo.setLastLoginTime(rs.getTimestamp("lastlogintime"));
userInfo.setLastLoginIp(rs.getString("lastloginip"));
userInfo.setLastLogoffTime(rs.getTimestamp("lastlogofftime"));
userInfo.setLoginCount(rs.getInt("logincount"));
userInfo.setRegionHistory(rs.getString("regionhistory"));
userInfo.setPasswordHistory(rs.getString("passwordhistory"));
userInfo.setTimeZone(rs.getString("timezone"));
userInfo.setLocale(rs.getString("locale"));
userInfo.setPreferredLanguage(rs.getString("preferredlanguage"));
userInfo.setWorkEmail(rs.getString("workemail"));
userInfo.setWorkPhoneNumber(rs.getString("workphonenumber"));
userInfo.setWorkCountry(rs.getString("workcountry"));
userInfo.setWorkRegion(rs.getString("workregion"));
userInfo.setWorkLocality(rs.getString("worklocality"));
userInfo.setWorkStreetAddress(rs.getString("workstreetaddress"));
userInfo.setWorkAddressFormatted(rs.getString("workaddressformatted"));
userInfo.setWorkPostalCode(rs.getString("workpostalcode"));
userInfo.setWorkFax(rs.getString("workfax"));
userInfo.setHomeEmail(rs.getString("homeemail"));
userInfo.setHomePhoneNumber(rs.getString("homephonenumber"));
userInfo.setHomeCountry(rs.getString("homecountry"));
userInfo.setHomeRegion(rs.getString("homeregion"));
userInfo.setHomeLocality(rs.getString("homelocality"));
userInfo.setHomeStreetAddress(rs.getString("homestreetaddress"));
userInfo.setHomeAddressFormatted(rs.getString("homeaddressformatted"));
userInfo.setHomePostalCode(rs.getString("homepostalcode"));
userInfo.setHomeFax(rs.getString("homefax"));
userInfo.setEmployeeNumber(rs.getString("employeenumber"));
userInfo.setDivision(rs.getString("division"));
userInfo.setCostCenter(rs.getString("costcenter"));
userInfo.setOrganization(rs.getString("organization"));
userInfo.setDepartmentId(rs.getString("departmentid"));
userInfo.setDepartment(rs.getString("department"));
userInfo.setJobTitle(rs.getString("jobtitle"));
userInfo.setJobLevel(rs.getString("joblevel"));
userInfo.setManagerId(rs.getString("managerid"));
userInfo.setManager(rs.getString("manager"));
userInfo.setAssistantId(rs.getString("assistantid"));
userInfo.setAssistant(rs.getString("assistant"));
userInfo.setEntryDate(rs.getString("entrydate"));//
userInfo.setQuitDate(rs.getString("quitdate"));
userInfo.setStartWorkDate(rs.getString("startworkdate"));// STARTWORKDATE
userInfo.setExtraAttribute(rs.getString("extraattribute"));
userInfo.setCreatedBy(rs.getString("createdby"));
userInfo.setCreatedDate(rs.getTimestamp("createddate"));
userInfo.setModifiedBy(rs.getString("modifiedby"));
userInfo.setModifiedDate(rs.getTimestamp("modifieddate"));
userInfo.setStatus(rs.getInt("status"));
userInfo.setGridList(rs.getInt("gridlist"));
userInfo.setDescription(rs.getString("description"));
userInfo.setTheme(rs.getString("theme"));
userInfo.setInstId(rs.getString("instid"));
if (userInfo.getTheme() == null || userInfo.getTheme().equalsIgnoreCase("")) {
userInfo.setTheme("default");
}
return userInfo;
}
}
}
@@ -0,0 +1,72 @@
/*
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
*
* 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 org.dromara.maxkey.persistence.repository;
import java.util.Locale;
import org.passay.MessageResolver;
import org.passay.PropertiesMessageResolver;
import org.passay.RuleResultDetail;
import org.springframework.context.MessageSource;
import org.springframework.context.NoSuchMessageException;
import org.springframework.context.support.MessageSourceAccessor;
public class PasswordPolicyMessageResolver implements MessageResolver{
/** A accessor for Spring's {@link MessageSource} */
private final MessageSourceAccessor messageSourceAccessor;
/** The {@link MessageResolver} for fallback */
private final MessageResolver fallbackMessageResolver = new PropertiesMessageResolver();
/**
* Create a new instance with the locale associated with the current thread.
* @param messageSource a message source managed by spring
*/
public PasswordPolicyMessageResolver(final MessageSource messageSource)
{
this.messageSourceAccessor = new MessageSourceAccessor(messageSource);
}
/**
* Create a new instance with the specified locale.
* @param messageSource a message source managed by spring
* @param locale the locale to use for message access
*/
public PasswordPolicyMessageResolver(final MessageSource messageSource, final Locale locale)
{
this.messageSourceAccessor = new MessageSourceAccessor(messageSource, locale);
}
/**
* Resolves the message for the supplied rule result detail using Spring's {@link MessageSource}.
* (If the message can't retrieve from a {@link MessageSource}, return default message provided by passay)
* @param detail rule result detail
* @return message for the detail error code
*/
@Override
public String resolve(final RuleResultDetail detail)
{
try {
return this.messageSourceAccessor.getMessage("PasswordPolicy."+detail.getErrorCode(), detail.getValues());
} catch (NoSuchMessageException e) {
return this.fallbackMessageResolver.resolve(detail);
}
}
}
@@ -0,0 +1,186 @@
/*
* Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
*
* 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 org.dromara.maxkey.persistence.repository;
import java.io.InputStreamReader;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
import org.dromara.maxkey.constants.ConstsProperties;
import org.dromara.maxkey.entity.PasswordPolicy;
import org.passay.CharacterOccurrencesRule;
import org.passay.CharacterRule;
import org.passay.DictionaryRule;
import org.passay.EnglishCharacterData;
import org.passay.EnglishSequenceData;
import org.passay.IllegalSequenceRule;
import org.passay.LengthRule;
import org.passay.Rule;
import org.passay.UsernameRule;
import org.passay.WhitespaceRule;
import org.passay.dictionary.Dictionary;
import org.passay.dictionary.DictionaryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
public class PasswordPolicyRepository {
private static Logger _logger = LoggerFactory.getLogger(PasswordPolicyRepository.class);
//Dictionary topWeakPassword Source
public static final String topWeakPasswordPropertySource =
"classpath:/top_weak_password.txt";
//Cache PasswordPolicy in memory ONE_HOUR
protected static final Cache<String, PasswordPolicy> passwordPolicyStore =
Caffeine.newBuilder()
.expireAfterWrite(60, TimeUnit.MINUTES)
.build();
protected PasswordPolicy passwordPolicy;
protected JdbcTemplate jdbcTemplate;
ArrayList <Rule> passwordPolicyRuleList;
private static final String PASSWORD_POLICY_KEY = "PASSWORD_POLICY_KEY";
private static final String PASSWORD_POLICY_SELECT_STATEMENT = "select * from mxk_password_policy ";
public PasswordPolicyRepository(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
/**
* init PasswordPolicy and load Rules
* @return
*/
public PasswordPolicy getPasswordPolicy() {
passwordPolicy = passwordPolicyStore.getIfPresent(PASSWORD_POLICY_KEY);
if (passwordPolicy == null) {
passwordPolicy = jdbcTemplate.queryForObject(PASSWORD_POLICY_SELECT_STATEMENT,
new PasswordPolicyRowMapper());
_logger.debug("query PasswordPolicy : " + passwordPolicy);
passwordPolicyStore.put(PASSWORD_POLICY_KEY,passwordPolicy);
//RandomPasswordLength =(MaxLength +MinLength)/2
passwordPolicy.setRandomPasswordLength(
Math.round(
(
passwordPolicy.getMaxLength() +
passwordPolicy.getMinLength()
)/2
)
);
passwordPolicyRuleList = new ArrayList<Rule>();
passwordPolicyRuleList.add(new WhitespaceRule());
passwordPolicyRuleList.add(new LengthRule(passwordPolicy.getMinLength(), passwordPolicy.getMaxLength()));
if(passwordPolicy.getUpperCase()>0) {
passwordPolicyRuleList.add(new CharacterRule(EnglishCharacterData.UpperCase, passwordPolicy.getUpperCase()));
}
if(passwordPolicy.getLowerCase()>0) {
passwordPolicyRuleList.add(new CharacterRule(EnglishCharacterData.LowerCase, passwordPolicy.getLowerCase()));
}
if(passwordPolicy.getDigits()>0) {
passwordPolicyRuleList.add(new CharacterRule(EnglishCharacterData.Digit, passwordPolicy.getDigits()));
}
if(passwordPolicy.getSpecialChar()>0) {
passwordPolicyRuleList.add(new CharacterRule(EnglishCharacterData.Special, passwordPolicy.getSpecialChar()));
}
if(passwordPolicy.getUsername()>0) {
passwordPolicyRuleList.add(new UsernameRule());
}
if(passwordPolicy.getOccurances()>0) {
passwordPolicyRuleList.add(new CharacterOccurrencesRule(passwordPolicy.getOccurances()));
}
if(passwordPolicy.getAlphabetical()>0) {
passwordPolicyRuleList.add(new IllegalSequenceRule(EnglishSequenceData.Alphabetical, 4, false));
}
if(passwordPolicy.getNumerical()>0) {
passwordPolicyRuleList.add(new IllegalSequenceRule(EnglishSequenceData.Numerical, 4, false));
}
if(passwordPolicy.getQwerty()>0) {
passwordPolicyRuleList.add(new IllegalSequenceRule(EnglishSequenceData.USQwerty, 4, false));
}
if(passwordPolicy.getDictionary()>0 ) {
try {
ClassPathResource dictFile=
new ClassPathResource(
ConstsProperties.classPathResource(topWeakPasswordPropertySource));
Dictionary dictionary =new DictionaryBuilder().addReader(new InputStreamReader(dictFile.getInputStream())).build();
passwordPolicyRuleList.add(new DictionaryRule(dictionary));
}catch(Exception e) {
e.printStackTrace();
}
}
}
return passwordPolicy;
}
public ArrayList<Rule> getPasswordPolicyRuleList() {
getPasswordPolicy();
return passwordPolicyRuleList;
}
public class PasswordPolicyRowMapper implements RowMapper<PasswordPolicy> {
@Override
public PasswordPolicy mapRow(ResultSet rs, int rowNum) throws SQLException {
PasswordPolicy passwordPolicy = new PasswordPolicy();
passwordPolicy.setId(rs.getString("id"));
passwordPolicy.setMinLength(rs.getInt("minlength"));
passwordPolicy.setMaxLength(rs.getInt("maxlength"));
passwordPolicy.setLowerCase(rs.getInt("lowercase"));
passwordPolicy.setUpperCase(rs.getInt("uppercase"));
passwordPolicy.setDigits(rs.getInt("digits"));
passwordPolicy.setSpecialChar(rs.getInt("specialchar"));
passwordPolicy.setAttempts(rs.getInt("attempts"));
passwordPolicy.setDuration(rs.getInt("duration"));
passwordPolicy.setExpiration(rs.getInt("expiration"));
passwordPolicy.setUsername(rs.getInt("username"));
passwordPolicy.setHistory(rs.getInt("history"));
passwordPolicy.setDictionary(rs.getInt("dictionary"));
passwordPolicy.setAlphabetical(rs.getInt("alphabetical"));
passwordPolicy.setNumerical(rs.getInt("numerical"));
passwordPolicy.setQwerty(rs.getInt("qwerty"));
passwordPolicy.setOccurances(rs.getInt("occurances"));
return passwordPolicy;
}
}
}
@@ -0,0 +1,320 @@
/*
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
*
* 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 org.dromara.maxkey.persistence.repository;
import java.sql.Types;
import java.util.Date;
import org.apache.commons.lang3.StringUtils;
import org.dromara.maxkey.constants.ConstsPasswordSetType;
import org.dromara.maxkey.constants.ConstsStatus;
import org.dromara.maxkey.crypto.password.PasswordGen;
import org.dromara.maxkey.entity.ChangePassword;
import org.dromara.maxkey.entity.PasswordPolicy;
import org.dromara.maxkey.entity.UserInfo;
import org.dromara.maxkey.web.WebConstants;
import org.dromara.maxkey.web.WebContext;
import org.joda.time.DateTime;
import org.joda.time.Duration;
import org.passay.PasswordData;
import org.passay.PasswordValidator;
import org.passay.RuleResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.MessageSource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.authentication.BadCredentialsException;
public class PasswordPolicyValidator {
private static Logger _logger = LoggerFactory.getLogger(PasswordPolicyValidator.class);
PasswordPolicyRepository passwordPolicyRepository;
protected JdbcTemplate jdbcTemplate;
MessageSource messageSource;
public static final String PASSWORD_POLICY_VALIDATE_RESULT = "PASSWORD_POLICY_SESSION_VALIDATE_RESULT_KEY";
private static final String LOCK_USER_UPDATE_STATEMENT = "update mxk_userinfo set islocked = ? , unlocktime = ? where id = ?";
private static final String UNLOCK_USER_UPDATE_STATEMENT = "update mxk_userinfo set islocked = ? , unlocktime = ? where id = ?";
private static final String BADPASSWORDCOUNT_UPDATE_STATEMENT = "update mxk_userinfo set badpasswordcount = ? , badpasswordtime = ? where id = ?";
private static final String BADPASSWORDCOUNT_RESET_UPDATE_STATEMENT = "update mxk_userinfo set badpasswordcount = ? , islocked = ? ,unlocktime = ? where id = ?";
public PasswordPolicyValidator() {
}
public PasswordPolicyValidator(JdbcTemplate jdbcTemplate,MessageSource messageSource) {
this.messageSource=messageSource;
this.jdbcTemplate = jdbcTemplate;
this.passwordPolicyRepository = new PasswordPolicyRepository(jdbcTemplate);
}
/**
* static validator .
* @param userInfo
* @return boolean
*/
public boolean validator(ChangePassword changePassword) {
String password = changePassword.getPassword();
String username = changePassword.getUsername();
if(password.equals("") || password==null){
_logger.debug("password is Empty ");
return false;
}
PasswordValidator validator = new PasswordValidator(
new PasswordPolicyMessageResolver(messageSource),passwordPolicyRepository.getPasswordPolicyRuleList());
RuleResult result = validator.validate(new PasswordData(username,password));
if (result.isValid()) {
_logger.debug("Password is valid");
return true;
} else {
_logger.debug("Invalid password:");
String passwordPolicyMessage = "";
for (String msg : validator.getMessages(result)) {
passwordPolicyMessage = passwordPolicyMessage + msg + "<br>";
_logger.debug("Rule Message {}" , msg);
}
WebContext.setAttribute(PasswordPolicyValidator.PASSWORD_POLICY_VALIDATE_RESULT, passwordPolicyMessage);
return false;
}
}
/**
* dynamic passwordPolicy Valid for user login.
* @param userInfo
* @return boolean
*/
public boolean passwordPolicyValid(UserInfo userInfo) {
PasswordPolicy passwordPolicy = passwordPolicyRepository.getPasswordPolicy();
DateTime currentdateTime = new DateTime();
/*
* check login attempts fail times
*/
if (userInfo.getBadPasswordCount() >= passwordPolicy.getAttempts() && userInfo.getBadPasswordTime() != null) {
_logger.debug("login Attempts is {} , bad Password Time {}" , userInfo.getBadPasswordCount(),userInfo.getBadPasswordTime());
Duration duration = new Duration(new DateTime(userInfo.getBadPasswordTime()), currentdateTime);
int intDuration = Integer.parseInt(duration.getStandardMinutes() + "");
_logger.debug("bad Password duration {} , " +
"password policy Duration {} , "+
"validate result {}" ,
intDuration,
passwordPolicy.getDuration(),
(intDuration > passwordPolicy.getDuration())
);
//auto unlock attempts when intDuration >= set Duration
if(intDuration >= passwordPolicy.getDuration()) {
_logger.debug("resetAttempts ...");
resetAttempts(userInfo);
}else {
lockUser(userInfo);
throw new BadCredentialsException(
WebContext.getI18nValue("login.error.attempts",
new Object[]{userInfo.getBadPasswordCount(),passwordPolicy.getDuration()})
);
}
}
//locked
if(userInfo.getIsLocked()==ConstsStatus.LOCK) {
throw new BadCredentialsException(
userInfo.getUsername()+ " "+
WebContext.getI18nValue("login.error.locked")
);
}
// inactive
if(userInfo.getStatus()!=ConstsStatus.ACTIVE) {
throw new BadCredentialsException(
userInfo.getUsername()+
WebContext.getI18nValue("login.error.inactive")
);
}
return true;
}
public void applyPasswordPolicy(UserInfo userInfo) {
PasswordPolicy passwordPolicy = passwordPolicyRepository.getPasswordPolicy();
DateTime currentdateTime = new DateTime();
//initial password need change
if(userInfo.getLoginCount()<=0) {
WebContext.getSession().setAttribute(WebConstants.CURRENT_USER_PASSWORD_SET_TYPE,
ConstsPasswordSetType.INITIAL_PASSWORD);
}
if (userInfo.getPasswordSetType() != ConstsPasswordSetType.PASSWORD_NORMAL) {
WebContext.getSession().setAttribute(WebConstants.CURRENT_USER_PASSWORD_SET_TYPE,
userInfo.getPasswordSetType());
return;
} else {
WebContext.getSession().setAttribute(WebConstants.CURRENT_USER_PASSWORD_SET_TYPE,
ConstsPasswordSetType.PASSWORD_NORMAL);
}
/*
* check password is Expired,Expiration is Expired date ,if Expiration equals 0,not need check
*
*/
if (passwordPolicy.getExpiration() > 0 && userInfo.getPasswordLastSetTime() != null) {
_logger.info("last password set date {}" , userInfo.getPasswordLastSetTime());
Duration duration = new Duration(new DateTime(userInfo.getPasswordLastSetTime()), currentdateTime);
int intDuration = Integer.parseInt(duration.getStandardDays() + "");
_logger.debug("password Last Set duration day {} , " +
"password policy Expiration {} , " +
"validate result {}",
intDuration,
passwordPolicy.getExpiration(),
intDuration <= passwordPolicy.getExpiration()
);
if (intDuration > passwordPolicy.getExpiration()) {
WebContext.getSession().setAttribute(WebConstants.CURRENT_USER_PASSWORD_SET_TYPE,
ConstsPasswordSetType.PASSWORD_EXPIRED);
}
}
resetBadPasswordCount(userInfo);
}
/**
* lockUser
*
* @param userInfo
*/
public void lockUser(UserInfo userInfo) {
try {
if (userInfo != null && StringUtils.isNotEmpty(userInfo.getId())) {
if(userInfo.getIsLocked() == ConstsStatus.ACTIVE) {
jdbcTemplate.update(LOCK_USER_UPDATE_STATEMENT,
new Object[] { ConstsStatus.LOCK, new Date(), userInfo.getId() },
new int[] { Types.VARCHAR, Types.TIMESTAMP, Types.VARCHAR });
userInfo.setIsLocked(ConstsStatus.LOCK);
}
}
} catch (Exception e) {
_logger.error("lockUser Exception",e);
}
}
/**
* unlockUser
*
* @param userInfo
*/
public void unlockUser(UserInfo userInfo) {
try {
if (userInfo != null && StringUtils.isNotEmpty(userInfo.getId())) {
jdbcTemplate.update(UNLOCK_USER_UPDATE_STATEMENT,
new Object[] { ConstsStatus.ACTIVE, new Date(), userInfo.getId() },
new int[] { Types.VARCHAR, Types.TIMESTAMP, Types.VARCHAR });
userInfo.setIsLocked(ConstsStatus.ACTIVE);
}
} catch (Exception e) {
_logger.error("unlockUser Exception",e);
}
}
/**
* reset BadPasswordCount And Lockout
*
* @param userInfo
*/
public void resetAttempts(UserInfo userInfo) {
try {
if (userInfo != null && StringUtils.isNotEmpty(userInfo.getId())) {
jdbcTemplate.update(BADPASSWORDCOUNT_RESET_UPDATE_STATEMENT,
new Object[] { 0, ConstsStatus.ACTIVE, new Date(), userInfo.getId() },
new int[] { Types.INTEGER, Types.INTEGER, Types.TIMESTAMP, Types.VARCHAR });
userInfo.setIsLocked(ConstsStatus.ACTIVE);
userInfo.setBadPasswordCount(0);
}
} catch (Exception e) {
_logger.error("resetAttempts Exception",e);
}
}
/**
* if login password is error ,BadPasswordCount++ and set bad date
*
* @param userInfo
*/
private void setBadPasswordCount(String userId,int badPasswordCount) {
try {
jdbcTemplate.update(BADPASSWORDCOUNT_UPDATE_STATEMENT,
new Object[] { badPasswordCount, new Date(), userId },
new int[] { Types.INTEGER, Types.TIMESTAMP, Types.VARCHAR });
} catch (Exception e) {
_logger.error("setBadPasswordCount Exception",e);
}
}
public void plusBadPasswordCount(UserInfo userInfo) {
if (userInfo != null && StringUtils.isNotEmpty(userInfo.getId())) {
userInfo.setBadPasswordCount(userInfo.getBadPasswordCount() + 1);
setBadPasswordCount(userInfo.getId(),userInfo.getBadPasswordCount());
PasswordPolicy passwordPolicy = passwordPolicyRepository.getPasswordPolicy();
if(userInfo.getBadPasswordCount() >= passwordPolicy.getAttempts()) {
_logger.debug("Bad Password Count {} , Max Attempts {}",
userInfo.getBadPasswordCount() + 1,passwordPolicy.getAttempts());
this.lockUser(userInfo);
}
}
}
public void resetBadPasswordCount(UserInfo userInfo) {
if (userInfo != null && StringUtils.isNotEmpty(userInfo.getId())) {
if(userInfo.getBadPasswordCount()>0) {
setBadPasswordCount(userInfo.getId(),0);
}
}
}
public String generateRandomPassword() {
PasswordPolicy passwordPolicy = passwordPolicyRepository.getPasswordPolicy();
PasswordGen passwordGen = new PasswordGen(
passwordPolicy.getRandomPasswordLength()
);
return passwordGen.gen(
passwordPolicy.getLowerCase(),
passwordPolicy.getUpperCase(),
passwordPolicy.getDigits(),
passwordPolicy.getSpecialChar());
}
public PasswordPolicyRepository getPasswordPolicyRepository() {
return passwordPolicyRepository;
}
}