diff --git a/maxkey-authentications/maxkey-authentication-core/src/main/java/org/maxkey/authn/realm/activedirectory/ActiveDirectoryAuthenticationRealm.java b/maxkey-authentications/maxkey-authentication-core/src/main/java/org/maxkey/authn/realm/activedirectory/ActiveDirectoryAuthenticationRealm.java index be4a2a7da50baf288685b6c8f8b2c56548c66360..e391b50288cc7bf96bd56545131d557e6823e53f 100644 --- a/maxkey-authentications/maxkey-authentication-core/src/main/java/org/maxkey/authn/realm/activedirectory/ActiveDirectoryAuthenticationRealm.java +++ b/maxkey-authentications/maxkey-authentication-core/src/main/java/org/maxkey/authn/realm/activedirectory/ActiveDirectoryAuthenticationRealm.java @@ -64,9 +64,6 @@ public class ActiveDirectoryAuthenticationRealm extends AbstractAuthenticationRe return true; } } - if(!isAuthenticated){ - throw new BadCredentialsException(WebContext.getI18nValue("login.error.password")); - } return false; } diff --git a/maxkey-authentications/maxkey-authentication-core/src/main/java/org/maxkey/authn/realm/jdbc/JdbcAuthenticationRealm.java b/maxkey-authentications/maxkey-authentication-core/src/main/java/org/maxkey/authn/realm/jdbc/JdbcAuthenticationRealm.java index d8978573ebf30b333386469ad24b4a062681b1e9..27c78f1cf5fb6b74e1d52010cc9a36c644d2e5fc 100644 --- a/maxkey-authentications/maxkey-authentication-core/src/main/java/org/maxkey/authn/realm/jdbc/JdbcAuthenticationRealm.java +++ b/maxkey-authentications/maxkey-authentication-core/src/main/java/org/maxkey/authn/realm/jdbc/JdbcAuthenticationRealm.java @@ -120,7 +120,17 @@ public class JdbcAuthenticationRealm extends AbstractAuthenticationRealm { if (!passwordMatches) { passwordPolicyValidator.plusBadPasswordCount(userInfo); insertLoginHistory(userInfo, ConstantsLoginType.LOCAL, "", "xe00000004", "password error"); - throw new BadCredentialsException(WebContext.getI18nValue("login.error.password")); + + if(userInfo.getBadPasswordCount()>=(passwordPolicyValidator.getPasswordPolicy().getAttempts()/2)) { + throw new BadCredentialsException( + WebContext.getI18nValue("login.error.password.attempts", + new Object[]{ + userInfo.getBadPasswordCount() + 1, + passwordPolicyValidator.getPasswordPolicy().getAttempts(), + passwordPolicyValidator.getPasswordPolicy().getDuration()})); + }else { + throw new BadCredentialsException(WebContext.getI18nValue("login.error.password")); + } } return passwordMatches; } diff --git a/maxkey-authentications/maxkey-authentication-core/src/main/java/org/maxkey/authn/realm/ldap/LdapAuthenticationRealm.java b/maxkey-authentications/maxkey-authentication-core/src/main/java/org/maxkey/authn/realm/ldap/LdapAuthenticationRealm.java index e3da505f2b3c4f75ab362ed81aafa247754bf977..a35cde81f148692166e19460bd7860ed78b422aa 100644 --- a/maxkey-authentications/maxkey-authentication-core/src/main/java/org/maxkey/authn/realm/ldap/LdapAuthenticationRealm.java +++ b/maxkey-authentications/maxkey-authentication-core/src/main/java/org/maxkey/authn/realm/ldap/LdapAuthenticationRealm.java @@ -63,9 +63,6 @@ public class LdapAuthenticationRealm extends AbstractAuthenticationRealm{ return true; } } - if(!isAuthenticated){ - throw new BadCredentialsException(WebContext.getI18nValue("login.error.password")); - } return false; } diff --git a/maxkey-core/src/main/java/org/maxkey/entity/Accounts.java b/maxkey-core/src/main/java/org/maxkey/entity/Accounts.java index 9844a2eeb6aa3e4ca922a1635361a81ddbc865f7..9aea473fdb9704f62aec961ec013125f24effa86 100644 --- a/maxkey-core/src/main/java/org/maxkey/entity/Accounts.java +++ b/maxkey-core/src/main/java/org/maxkey/entity/Accounts.java @@ -18,6 +18,9 @@ package org.maxkey.entity; import java.io.Serializable; +import java.util.HashMap; +import java.util.List; + import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; @@ -68,6 +71,8 @@ public class Accounts extends JpaBaseEntity implements Serializable { private int status; UserInfo userInfo; + + private HashMap orgCast =new HashMap(); public Accounts() { super(); @@ -186,6 +191,20 @@ public class Accounts extends JpaBaseEntity implements Serializable { public void setStatus(int status) { this.status = status; } + + public HashMap getOrgCast() { + return orgCast; + } + + public void setOrgCast(HashMap orgCast) { + this.orgCast = orgCast; + } + + public void setOrgCast(List listOrgCast) { + for(OrganizationsCast cast : listOrgCast) { + this.orgCast.put(cast.getProvider(), cast); + } + } @Override public String toString() { diff --git a/maxkey-core/src/main/java/org/maxkey/entity/Organizations.java b/maxkey-core/src/main/java/org/maxkey/entity/Organizations.java index dbc3a1ff4b6571c3b672f2a30e93f935a2df2849..a37fd7cfcfd567af38c2dcbed9c157812772c120 100644 --- a/maxkey-core/src/main/java/org/maxkey/entity/Organizations.java +++ b/maxkey-core/src/main/java/org/maxkey/entity/Organizations.java @@ -83,14 +83,12 @@ public class Organizations extends JpaBaseEntity implements Serializable { private String ldapDn; @Column private String description; - - private int status; - @Column - private String extId; @Column - private String extParentId; + private int status; private int isPrimary = 0; + + private boolean reorgNamePath; public Organizations() { // @@ -308,22 +306,6 @@ public class Organizations extends JpaBaseEntity implements Serializable { this.status = status; } - public String getExtId() { - return extId; - } - - public void setExtId(String extId) { - this.extId = extId; - } - - public String getExtParentId() { - return extParentId; - } - - public void setExtParentId(String extParentId) { - this.extParentId = extParentId; - } - public int getIsPrimary() { return isPrimary; } @@ -332,68 +314,76 @@ public class Organizations extends JpaBaseEntity implements Serializable { this.isPrimary = isPrimary; } + public boolean isReorgNamePath() { + return reorgNamePath; + } + + public void setReorgNamePath(boolean reorgNamePath) { + this.reorgNamePath = reorgNamePath; + } + @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("Organizations [id="); - builder.append(id); - builder.append(", code="); - builder.append(code); - builder.append(", name="); - builder.append(name); - builder.append(", fullName="); - builder.append(fullName); - builder.append(", parentId="); - builder.append(parentId); - builder.append(", parentName="); - builder.append(parentName); - builder.append(", type="); - builder.append(type); - builder.append(", codePath="); - builder.append(codePath); - builder.append(", namePath="); - builder.append(namePath); - builder.append(", level="); - builder.append(level); - builder.append(", hasChild="); - builder.append(hasChild); - builder.append(", division="); - builder.append(division); - builder.append(", country="); - builder.append(country); - builder.append(", region="); - builder.append(region); - builder.append(", locality="); - builder.append(locality); - builder.append(", street="); - builder.append(street); - builder.append(", address="); - builder.append(address); - builder.append(", contact="); - builder.append(contact); - builder.append(", postalCode="); - builder.append(postalCode); - builder.append(", phone="); - builder.append(phone); - builder.append(", fax="); - builder.append(fax); - builder.append(", email="); - builder.append(email); - builder.append(", sortIndex="); - builder.append(sortIndex); - builder.append(", ldapDn="); - builder.append(ldapDn); - builder.append(", description="); - builder.append(description); - builder.append(", status="); - builder.append(status); - builder.append(", extId="); - builder.append(extId); - builder.append(", extParentId="); - builder.append(extParentId); - builder.append("]"); - return builder.toString(); - } + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("Organizations [id="); + builder.append(id); + builder.append(", code="); + builder.append(code); + builder.append(", name="); + builder.append(name); + builder.append(", fullName="); + builder.append(fullName); + builder.append(", parentId="); + builder.append(parentId); + builder.append(", parentName="); + builder.append(parentName); + builder.append(", type="); + builder.append(type); + builder.append(", codePath="); + builder.append(codePath); + builder.append(", namePath="); + builder.append(namePath); + builder.append(", level="); + builder.append(level); + builder.append(", hasChild="); + builder.append(hasChild); + builder.append(", division="); + builder.append(division); + builder.append(", country="); + builder.append(country); + builder.append(", region="); + builder.append(region); + builder.append(", locality="); + builder.append(locality); + builder.append(", street="); + builder.append(street); + builder.append(", address="); + builder.append(address); + builder.append(", contact="); + builder.append(contact); + builder.append(", postalCode="); + builder.append(postalCode); + builder.append(", phone="); + builder.append(phone); + builder.append(", fax="); + builder.append(fax); + builder.append(", email="); + builder.append(email); + builder.append(", sortIndex="); + builder.append(sortIndex); + builder.append(", ldapDn="); + builder.append(ldapDn); + builder.append(", description="); + builder.append(description); + builder.append(", status="); + builder.append(status); + builder.append(", isPrimary="); + builder.append(isPrimary); + builder.append(", reorgNamePath="); + builder.append(reorgNamePath); + builder.append("]"); + return builder.toString(); + } diff --git a/maxkey-core/src/main/java/org/maxkey/entity/OrganizationsCast.java b/maxkey-core/src/main/java/org/maxkey/entity/OrganizationsCast.java new file mode 100644 index 0000000000000000000000000000000000000000..645b1fc2c0924b7b4b324ba5035adffe24c2d389 --- /dev/null +++ b/maxkey-core/src/main/java/org/maxkey/entity/OrganizationsCast.java @@ -0,0 +1,219 @@ +/* + * 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.maxkey.entity; + +import java.io.Serializable; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import org.apache.mybatis.jpa.persistence.JpaBaseEntity; +@Entity +@Table(name = "MXK_ORGANIZATIONS_CAST") +public class OrganizationsCast extends JpaBaseEntity implements Serializable { + + + /** + * + */ + private static final long serialVersionUID = 5166920258761620856L; + @Id + @Column + @GeneratedValue(strategy = GenerationType.AUTO, generator = "snowflakeid") + private String id; + @Column + private String code; + @Column + private String name; + @Column + private String fullName; + @Column + private String parentId; + @Column + private String parentName; + @Column + private String codePath; + @Column + private String namePath; + + @Column + private long sortIndex; + @Column + private int status; + @Column + private String provider; + + @Column + private String orgId; + @Column + private String orgParentId; + + //重组标志 + boolean reorgNamePath; + + + public OrganizationsCast() { + // + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getFullName() { + return fullName; + } + + public void setFullName(String fullName) { + this.fullName = fullName; + } + + public String getParentId() { + return parentId; + } + + public void setParentId(String parentId) { + this.parentId = parentId; + } + + public String getParentName() { + return parentName; + } + + public void setParentName(String parentName) { + this.parentName = parentName; + } + + public String getCodePath() { + return codePath; + } + + public void setCodePath(String codePath) { + this.codePath = codePath; + } + + public String getNamePath() { + return namePath; + } + + public void setNamePath(String namePath) { + this.namePath = namePath; + } + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + + public String getOrgId() { + return orgId; + } + + public void setOrgId(String orgId) { + this.orgId = orgId; + } + + public String getOrgParentId() { + return orgParentId; + } + + public void setOrgParentId(String orgParentId) { + this.orgParentId = orgParentId; + } + + public long getSortIndex() { + return sortIndex; + } + + public void setSortIndex(long sortIndex) { + this.sortIndex = sortIndex; + } + + public String getProvider() { + return provider; + } + + public void setProvider(String provider) { + this.provider = provider; + } + + public boolean isReorgNamePath() { + return reorgNamePath; + } + + public void setReorgNamePath(boolean reorgNamePath) { + this.reorgNamePath = reorgNamePath; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("OrganizationsMapper [id="); + builder.append(id); + builder.append(", code="); + builder.append(code); + builder.append(", name="); + builder.append(name); + builder.append(", fullName="); + builder.append(fullName); + builder.append(", parentId="); + builder.append(parentId); + builder.append(", parentName="); + builder.append(parentName); + builder.append(", codePath="); + builder.append(codePath); + builder.append(", namePath="); + builder.append(namePath); + builder.append(", status="); + builder.append(status); + builder.append(", orgId="); + builder.append(orgId); + builder.append(", orgParentId="); + builder.append(orgParentId); + builder.append("]"); + return builder.toString(); + } + + + +} diff --git a/maxkey-core/src/main/java/org/maxkey/persistence/db/PasswordPolicyValidator.java b/maxkey-core/src/main/java/org/maxkey/persistence/db/PasswordPolicyValidator.java index 81adb9dff890be8b9d2be4bbc020f362f751e6b7..a8b089a07a9a15256c90e8c266378613b3b97c09 100644 --- a/maxkey-core/src/main/java/org/maxkey/persistence/db/PasswordPolicyValidator.java +++ b/maxkey-core/src/main/java/org/maxkey/persistence/db/PasswordPolicyValidator.java @@ -261,7 +261,7 @@ public class PasswordPolicyValidator { lockUser(userInfo); throw new BadCredentialsException( WebContext.getI18nValue("login.error.attempts", - new Object[]{userInfo.getUsername(),userInfo.getBadPasswordCount()}) + new Object[]{userInfo.getBadPasswordCount(),passwordPolicy.getDuration()}) ); } } @@ -404,7 +404,8 @@ public class PasswordPolicyValidator { public void plusBadPasswordCount(UserInfo userInfo) { if (userInfo != null && StringUtils.isNotEmpty(userInfo.getId())) { - setBadPasswordCount(userInfo.getId(),userInfo.getBadPasswordCount() + 1); + userInfo.setBadPasswordCount(userInfo.getBadPasswordCount() + 1); + setBadPasswordCount(userInfo.getId(),userInfo.getBadPasswordCount()); } } diff --git a/maxkey-core/src/main/java/org/maxkey/web/HttpRequestAdapter.java b/maxkey-core/src/main/java/org/maxkey/web/HttpRequestAdapter.java index a11690c5fa286604ecae340bf9ac6aac770f7d33..9490db9e306aec08b21a30592d443671e4b85951 100644 --- a/maxkey-core/src/main/java/org/maxkey/web/HttpRequestAdapter.java +++ b/maxkey-core/src/main/java/org/maxkey/web/HttpRequestAdapter.java @@ -33,10 +33,12 @@ import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; +import org.maxkey.util.JsonUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @@ -45,6 +47,20 @@ import org.springframework.stereotype.Component; public class HttpRequestAdapter { private static final Logger _logger = LoggerFactory.getLogger(HttpRequestAdapter.class); + private String mediaType = MediaType.FORM; + + public static class MediaType{ + public static String JSON = "JSON"; + public static String XML = "XML"; + public static String FORM = "FORM"; + } + + public HttpRequestAdapter(){} + + public HttpRequestAdapter(String mediaType){ + this.mediaType = mediaType; + } + public String post(String url,Map parameterMap) { HashMap headers = new HashMap(); headers.put("Content-Type", "application/x-www-form-urlencoded"); @@ -78,26 +94,33 @@ public class HttpRequestAdapter { // 封装post请求参数 if (null != parameterMap && parameterMap.size() > 0) { - List nvps = new ArrayList(); - // 通过map集成entrySet方法获取entity - Set> entrySet = parameterMap.entrySet(); - // 循环遍历,获取迭代器 - Iterator> iterator = entrySet.iterator(); - while (iterator.hasNext()) { - Entry mapEntry = iterator.next(); - _logger.debug("Name " + mapEntry.getKey() + " , Value " +mapEntry.getValue()); - nvps.add(new BasicNameValuePair(mapEntry.getKey(), mapEntry.getValue().toString())); - } + if(mediaType.equals(MediaType.FORM)) { + List nvps = new ArrayList(); + // 通过map集成entrySet方法获取entity + Set> entrySet = parameterMap.entrySet(); + // 循环遍历,获取迭代器 + Iterator> iterator = entrySet.iterator(); + while (iterator.hasNext()) { + Entry mapEntry = iterator.next(); + _logger.debug("Name " + mapEntry.getKey() + " , Value " +mapEntry.getValue()); + nvps.add(new BasicNameValuePair(mapEntry.getKey(), mapEntry.getValue().toString())); + } + + // 为httpPost设置封装好的请求参数 + try { + httpPost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8")); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + }else if(mediaType.equals(MediaType.JSON)) { + String jsonString = JsonUtils.gson2Json(parameterMap); + StringEntity stringEntity =new StringEntity(jsonString, "UTF-8"); + stringEntity.setContentType("text/json"); + httpPost.setEntity(stringEntity); - // 为httpPost设置封装好的请求参数 - try { - httpPost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8")); - } catch (UnsupportedEncodingException e) { - e.printStackTrace(); + } - _logger.debug("Post Message \n" + - httpPost.getEntity().toString() - ); + _logger.debug("Post Message \n{} ", httpPost.getEntity().toString()); } @@ -107,9 +130,9 @@ public class HttpRequestAdapter { // 从响应对象中获取响应内容 HttpEntity entity = httpResponse.getEntity(); String content = EntityUtils.toString(entity); - _logger.debug("Http Response StatusCode " + - httpResponse.getStatusLine().getStatusCode()+ - " , Content " + content + _logger.debug("Http Response StatusCode {} , Content {}", + httpResponse.getStatusLine().getStatusCode(), + content ); return content; } catch (Exception e) { @@ -172,9 +195,9 @@ public class HttpRequestAdapter { // 从响应对象中获取响应内容 HttpEntity entity = httpResponse.getEntity(); String content = EntityUtils.toString(entity); - _logger.debug("Http Response StatusCode " + - httpResponse.getStatusLine().getStatusCode()+ - " , Content " + content + _logger.debug("Http Response StatusCode {} , Content {}", + httpResponse.getStatusLine().getStatusCode(), + content ); return content; } catch (Exception e) { diff --git a/maxkey-core/src/main/resources/messages/passwordpolicy_message.properties b/maxkey-core/src/main/resources/messages/passwordpolicy_message.properties index 59bc09b85028c9e171d101bde53dcbb600c79b08..69570ac5a5fb8757e9db0719f6e61e743e19c4f3 100644 --- a/maxkey-core/src/main/resources/messages/passwordpolicy_message.properties +++ b/maxkey-core/src/main/resources/messages/passwordpolicy_message.properties @@ -33,16 +33,16 @@ PasswordPolicy.CONFIRMPASSWORD_NOT_MATCH=\u65b0\u5bc6\u7801\u4e0e\u786e\u8ba4\u5 PasswordPolicy.OLD_PASSWORD_MATCH=\u65b0\u5bc6\u7801\u4e0d\u80fd\u4e0e\u65e7\u5bc6\u7801\u4e00\u81f4. #\u7528\u6237\u767b\u5f55\u9519\u8bef\u63d0\u9192 -login.error.attempts={0}\u5c1d\u8bd5\u767b\u9646{1}\u6b21\u6570\u8fbe\u5230\u6700\u5927\u9650\u5236\uff0c\u8bf7\u7a0d\u540e\u518d\u767b\u9646. +login.error.attempts=\u767B\u5F55\u9519\u8BEF\u8fbe\u6700\u5927\u9650\u5236{0}\u6b21,\u8bf7{1}\u5C0F\u65F6\u540e\u91CD\u8BD5. login.error.locked=\u7528\u6237\u88ab\u9501\u5b9a. login.error.inactive=\u7528\u6237\u975e\u6d3b\u52a8\u72b6\u6001. login.error.password=\u7528\u6237\u540D\u6216\u5bc6\u7801\u65e0\u6548. +login.error.password.attempts=\u767B\u5F55\u5931\u8D25{0}\u6B21, \u5931\u8D25{1}\u6B21\u5C06\u9501\u5B9A{2}\u5C0F\u65F6. login.error.username=\u7528\u6237\u540D\u6216\u5bc6\u7801\u65e0\u6548. login.error.username.null=\u7528\u6237\u540d\u4e0d\u80fd\u4e3a\u7a7a. login.error.email.null=\u767b\u5f55\u90ae\u7bb1\u4e0d\u80fd\u4e3a\u7a7a. login.error.password.null=\u5bc6\u7801\u4e0d\u80fd\u4e3a\u7a7a. -login.error.captcha=\u9a8c\u8bc1\u7801\u9519\u8bef\uff0c\u8bf7\u91cd\u65b0\u767b\u9646. +login.error.captcha=\u9a8c\u8bc1\u7801\u9519\u8bef\uff0c\u8bf7\u91cd\u65b0\u767B\u5F55. login.error.authtype=\u767b\u5f55\u8ba4\u8bc1\u7c7b\u578b\u9519\u8bef. login.error.session=\u767b\u5f55\u4f1a\u8bdd\u5931\u6548\uff0c\u8bf7\u91cd\u65b0\u767b\u9646. -login.error.social=\u793e\u4ea4\u8d26\u53f7\u6388\u6743\u5931\u8d25\uff0c\u8bf7\u91cd\u8bd5. - +login.error.social=\u793e\u4ea4\u8d26\u53f7\u6388\u6743\u5931\u8d25\uff0c\u8bf7\u91cd\u8bd5. \ No newline at end of file diff --git a/maxkey-core/src/main/resources/messages/passwordpolicy_message_en.properties b/maxkey-core/src/main/resources/messages/passwordpolicy_message_en.properties index 8e3ff85c28651001ed235bfdf7978edb46d4cac9..4de646dd0815b317384b26d56ed709ce28506b3b 100644 --- a/maxkey-core/src/main/resources/messages/passwordpolicy_message_en.properties +++ b/maxkey-core/src/main/resources/messages/passwordpolicy_message_en.properties @@ -33,10 +33,11 @@ PasswordPolicy.CONFIRMPASSWORD_NOT_MATCH=new password not match confirm password PasswordPolicy.OLD_PASSWORD_MATCH=new password match old password. #for user login -login.error.attempts={0} login attempts the maximum number of {1} times, please login later. +login.error.attempts=login attempts the maximum {0} times, please login {1} hours later. login.error.locked=The user is locked. login.error.inactive=User inactive state. login.error.password=Invalid username or password. +login.error.password.attempts=login fail {0} times, fail {1} times will lock {2} hours. login.error.username=Invalid username or password. login.error.username.null=username cannot be empty. login.error.email.null=email cannot be empty. diff --git a/maxkey-core/src/main/resources/messages/passwordpolicy_message_zh_CN.properties b/maxkey-core/src/main/resources/messages/passwordpolicy_message_zh_CN.properties index 40eefb0904571747a8da3ab2a284ea3a70a0c3da..69570ac5a5fb8757e9db0719f6e61e743e19c4f3 100644 --- a/maxkey-core/src/main/resources/messages/passwordpolicy_message_zh_CN.properties +++ b/maxkey-core/src/main/resources/messages/passwordpolicy_message_zh_CN.properties @@ -33,15 +33,16 @@ PasswordPolicy.CONFIRMPASSWORD_NOT_MATCH=\u65b0\u5bc6\u7801\u4e0e\u786e\u8ba4\u5 PasswordPolicy.OLD_PASSWORD_MATCH=\u65b0\u5bc6\u7801\u4e0d\u80fd\u4e0e\u65e7\u5bc6\u7801\u4e00\u81f4. #\u7528\u6237\u767b\u5f55\u9519\u8bef\u63d0\u9192 -login.error.attempts={0}\u5c1d\u8bd5\u767b\u9646{1}\u6b21\u6570\u8fbe\u5230\u6700\u5927\u9650\u5236\uff0c\u8bf7\u7a0d\u540e\u518d\u767b\u9646. +login.error.attempts=\u767B\u5F55\u9519\u8BEF\u8fbe\u6700\u5927\u9650\u5236{0}\u6b21,\u8bf7{1}\u5C0F\u65F6\u540e\u91CD\u8BD5. login.error.locked=\u7528\u6237\u88ab\u9501\u5b9a. login.error.inactive=\u7528\u6237\u975e\u6d3b\u52a8\u72b6\u6001. login.error.password=\u7528\u6237\u540D\u6216\u5bc6\u7801\u65e0\u6548. +login.error.password.attempts=\u767B\u5F55\u5931\u8D25{0}\u6B21, \u5931\u8D25{1}\u6B21\u5C06\u9501\u5B9A{2}\u5C0F\u65F6. login.error.username=\u7528\u6237\u540D\u6216\u5bc6\u7801\u65e0\u6548. login.error.username.null=\u7528\u6237\u540d\u4e0d\u80fd\u4e3a\u7a7a. login.error.email.null=\u767b\u5f55\u90ae\u7bb1\u4e0d\u80fd\u4e3a\u7a7a. login.error.password.null=\u5bc6\u7801\u4e0d\u80fd\u4e3a\u7a7a. -login.error.captcha=\u9a8c\u8bc1\u7801\u9519\u8bef\uff0c\u8bf7\u91cd\u65b0\u767b\u9646. +login.error.captcha=\u9a8c\u8bc1\u7801\u9519\u8bef\uff0c\u8bf7\u91cd\u65b0\u767B\u5F55. login.error.authtype=\u767b\u5f55\u8ba4\u8bc1\u7c7b\u578b\u9519\u8bef. login.error.session=\u767b\u5f55\u4f1a\u8bdd\u5931\u6548\uff0c\u8bf7\u91cd\u65b0\u767b\u9646. login.error.social=\u793e\u4ea4\u8d26\u53f7\u6388\u6743\u5931\u8d25\uff0c\u8bf7\u91cd\u8bd5. \ No newline at end of file diff --git a/maxkey-identitys/maxkey-synchronizers-dingding/src/main/java/org/maxkey/synchronizer/dingding/DingdingOrganizationService.java b/maxkey-identitys/maxkey-synchronizers-dingding/src/main/java/org/maxkey/synchronizer/dingding/DingdingOrganizationService.java index 6d9b563a564212670f3c98193f39577598b96e45..2e4d8f975aaa99b4b53eaac69f68f11504597da4 100644 --- a/maxkey-identitys/maxkey-synchronizers-dingding/src/main/java/org/maxkey/synchronizer/dingding/DingdingOrganizationService.java +++ b/maxkey-identitys/maxkey-synchronizers-dingding/src/main/java/org/maxkey/synchronizer/dingding/DingdingOrganizationService.java @@ -78,8 +78,6 @@ public class DingdingOrganizationService implements ISynchronizerService{ org.setId(dept.getDeptId()+""); org.setName(dept.getName()); org.setParentId(dept.getParentId()+""); - org.setExtId(dept.getDeptId()+""); - org.setExtParentId(dept.getParentId()+""); return org; } diff --git a/maxkey-identitys/maxkey-synchronizers-reorgdept/build.gradle b/maxkey-identitys/maxkey-synchronizers-reorgdept/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..0d8de414f1aedd1eafb3d6266470d9a04feae7ff --- /dev/null +++ b/maxkey-identitys/maxkey-synchronizers-reorgdept/build.gradle @@ -0,0 +1,14 @@ +description = "maxkey-synchronizers-reorgdept" + +apply plugin: 'java' + +dependencies { + //local jars + implementation fileTree(dir: '../maxkey-lib/*/', include: '*.jar') + + implementation project(":maxkey-common") + implementation project(":maxkey-core") + implementation project(":maxkey-persistence") + implementation project(":maxkey-identitys:maxkey-synchronizers") + +} \ No newline at end of file diff --git a/maxkey-identitys/maxkey-synchronizers-reorgdept/src/main/java/org/maxkey/synchronizer/reorg/ReorgDeptSynchronizerService.java b/maxkey-identitys/maxkey-synchronizers-reorgdept/src/main/java/org/maxkey/synchronizer/reorg/ReorgDeptSynchronizerService.java new file mode 100644 index 0000000000000000000000000000000000000000..ac43fc32bd27c7bb2f7614ddf3db4414d8b718e1 --- /dev/null +++ b/maxkey-identitys/maxkey-synchronizers-reorgdept/src/main/java/org/maxkey/synchronizer/reorg/ReorgDeptSynchronizerService.java @@ -0,0 +1,59 @@ +/* + * Copyright [2021] [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.maxkey.synchronizer.reorg; + +import org.maxkey.entity.Synchronizers; +import org.maxkey.synchronizer.ISynchronizerService; +import org.maxkey.synchronizer.workweixin.service.ReorgDeptService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class ReorgDeptSynchronizerService implements ISynchronizerService { + final static Logger _logger = LoggerFactory.getLogger(ReorgDeptSynchronizerService.class); + Synchronizers synchronizer; + + @Autowired + ReorgDeptService reorgDeptService; + + + public ReorgDeptSynchronizerService() { + super(); + } + + public void sync() throws Exception { + _logger.info("Sync ..."); + reorgDeptService.sync(); + + } + + + + public void setReorgDeptService(ReorgDeptService reorgDeptService) { + this.reorgDeptService = reorgDeptService; + } + + @Override + public void setSynchronizer(Synchronizers synchronizer) { + this.synchronizer = synchronizer; + + } + +} diff --git a/maxkey-identitys/maxkey-synchronizers-reorgdept/src/main/java/org/maxkey/synchronizer/workweixin/service/ReorgDeptService.java b/maxkey-identitys/maxkey-synchronizers-reorgdept/src/main/java/org/maxkey/synchronizer/workweixin/service/ReorgDeptService.java new file mode 100644 index 0000000000000000000000000000000000000000..d560c95c14877767b8bda6063706e8c81eec9e27 --- /dev/null +++ b/maxkey-identitys/maxkey-synchronizers-reorgdept/src/main/java/org/maxkey/synchronizer/workweixin/service/ReorgDeptService.java @@ -0,0 +1,121 @@ +/* + * Copyright [2021] [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.maxkey.synchronizer.workweixin.service; + +import java.util.HashMap; +import java.util.List; + +import org.maxkey.constants.ConstantsStatus; +import org.maxkey.entity.Organizations; +import org.maxkey.entity.Synchronizers; +import org.maxkey.persistence.service.OrganizationsService; +import org.maxkey.synchronizer.ISynchronizerService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class ReorgDeptService implements ISynchronizerService{ + final static Logger _logger = LoggerFactory.getLogger(ReorgDeptService.class); + + @Autowired + OrganizationsService organizationsService; + + + String rootParentOrgId = "-1"; + + public void sync() { + _logger.info("Sync Organizations ..."); + + try { + long responseCount =0; + HashMaporgCastMap =new HashMap(); + List listOrg = organizationsService.findAll(); + + buildNamePath(orgCastMap,listOrg); + + for(Organizations org :listOrg) { + _logger.info("Dept "+(++responseCount)+" : " + org); + org.setStatus(ConstantsStatus.ACTIVE); + organizationsService.update(org); + } + + + } catch (Exception e) { + e.printStackTrace(); + } + + } + + + + /** + * Reorganization name path & code path + * @param orgCastMap + * @param listOrgCast + */ + public void buildNamePath(HashMaporgMap, + List listOrg) { + Organizations tempOrg = null; + //root org + for(int i=0;ilistOrg.size()); + } + + public OrganizationsService getOrganizationsService() { + return organizationsService; + } + + public void setOrganizationsService(OrganizationsService organizationsService) { + this.organizationsService = organizationsService; + } + + @Override + public void setSynchronizer(Synchronizers synchronizer) { + + + } + +} diff --git a/maxkey-persistence/src/main/java/org/maxkey/persistence/mapper/OrganizationsCastMapper.java b/maxkey-persistence/src/main/java/org/maxkey/persistence/mapper/OrganizationsCastMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..bedebb7414148c61e8a61e5759fad237e089e1d6 --- /dev/null +++ b/maxkey-persistence/src/main/java/org/maxkey/persistence/mapper/OrganizationsCastMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright [2021] [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.maxkey.persistence.mapper; +import java.util.List; + +import org.apache.mybatis.jpa.persistence.IJpaBaseMapper; +import org.maxkey.entity.Organizations; +import org.maxkey.entity.OrganizationsCast; + +public interface OrganizationsCastMapper extends IJpaBaseMapper { + + public List queryOrgs(Organizations organization); + + + public long updateCast(OrganizationsCast organizationsCast); +} diff --git a/maxkey-persistence/src/main/java/org/maxkey/persistence/service/AccountsService.java b/maxkey-persistence/src/main/java/org/maxkey/persistence/service/AccountsService.java index 87e3b5b1fc8fc87c3b7f3ab120fe480fe8eae4ed..e8aa76ea69477aa06262c63c5f3bb888efea4aa0 100644 --- a/maxkey-persistence/src/main/java/org/maxkey/persistence/service/AccountsService.java +++ b/maxkey-persistence/src/main/java/org/maxkey/persistence/service/AccountsService.java @@ -24,6 +24,7 @@ import org.maxkey.constants.ConstantsStatus; import org.maxkey.crypto.ReciprocalUtils; import org.maxkey.entity.Accounts; import org.maxkey.entity.AccountsStrategy; +import org.maxkey.entity.OrganizationsCast; import org.maxkey.entity.UserInfo; import org.maxkey.persistence.kafka.KafkaIdentityAction; import org.maxkey.persistence.kafka.KafkaIdentityTopic; @@ -45,6 +46,9 @@ public class AccountsService extends JpaBaseService{ @Autowired AccountsStrategyService accountsStrategyService; + @Autowired + OrganizationsCastService organizationsCastService; + public AccountsService() { super(AccountsMapper.class); } @@ -64,6 +68,10 @@ public class AccountsService extends JpaBaseService{ if(kafkaPersistService.getApplicationConfig().isKafkaSupport()) { UserInfo loadUserInfo = userInfoService.loadUserRelated(account.getUserId()); account.setUserInfo(loadUserInfo); + OrganizationsCast cast = new OrganizationsCast(); + cast.setProvider(account.getAppId()); + cast.setOrgId(loadUserInfo.getDepartmentId()); + account.setOrgCast(organizationsCastService.query(cast)); kafkaPersistService.send( KafkaIdentityTopic.ACCOUNT_TOPIC, account, @@ -80,6 +88,10 @@ public class AccountsService extends JpaBaseService{ if(kafkaPersistService.getApplicationConfig().isKafkaSupport()) { UserInfo loadUserInfo = userInfoService.loadUserRelated(account.getUserId()); account.setUserInfo(loadUserInfo); + OrganizationsCast cast = new OrganizationsCast(); + cast.setProvider(account.getAppId()); + cast.setOrgId(loadUserInfo.getDepartmentId()); + account.setOrgCast(organizationsCastService.query(cast)); kafkaPersistService.send( KafkaIdentityTopic.ACCOUNT_TOPIC, account, diff --git a/maxkey-persistence/src/main/java/org/maxkey/persistence/service/OrganizationsCastService.java b/maxkey-persistence/src/main/java/org/maxkey/persistence/service/OrganizationsCastService.java new file mode 100644 index 0000000000000000000000000000000000000000..8345da6830d9bd247f3a9d9eb0b17d8e366111e5 --- /dev/null +++ b/maxkey-persistence/src/main/java/org/maxkey/persistence/service/OrganizationsCastService.java @@ -0,0 +1,51 @@ +/* + * Copyright [2021] [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.maxkey.persistence.service; + +import org.apache.mybatis.jpa.persistence.JpaBaseService; +import org.maxkey.entity.OrganizationsCast; +import org.maxkey.persistence.mapper.OrganizationsCastMapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Repository; + + +@Repository +public class OrganizationsCastService extends JpaBaseService{ + + final static Logger _logger = LoggerFactory.getLogger(OrganizationsCastService.class); + + + public OrganizationsCastService() { + super(OrganizationsCastMapper.class); + } + + /* (non-Javadoc) + * @see com.connsec.db.service.BaseService#getMapper() + */ + @Override + public OrganizationsCastMapper getMapper() { + // TODO Auto-generated method stub + return (OrganizationsCastMapper)super.getMapper(); + } + + public boolean updateCast(OrganizationsCast organizationsCast) { + return getMapper().updateCast(organizationsCast) > 0; + } + +} diff --git a/maxkey-persistence/src/main/java/org/maxkey/persistence/service/UserInfoService.java b/maxkey-persistence/src/main/java/org/maxkey/persistence/service/UserInfoService.java index c464ccd8d7581c3723f640335628263679daa730..3e8edf65e2e2e2f1e75f742eced2df83a82a3408 100644 --- a/maxkey-persistence/src/main/java/org/maxkey/persistence/service/UserInfoService.java +++ b/maxkey-persistence/src/main/java/org/maxkey/persistence/service/UserInfoService.java @@ -40,6 +40,7 @@ import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.maxkey.constants.ConstantsStatus; import org.maxkey.crypto.ReciprocalUtils; import org.maxkey.crypto.password.PasswordReciprocal; +import org.maxkey.entity.Accounts; import org.maxkey.entity.ChangePassword; import org.maxkey.entity.UserInfo; import org.maxkey.persistence.db.PasswordPolicyValidator; @@ -81,6 +82,8 @@ public class UserInfoService extends JpaBaseService { @Autowired protected JdbcTemplate jdbcTemplate; + + AccountsService accountsService; public UserInfoService() { super(UserInfoMapper.class); @@ -116,11 +119,13 @@ public class UserInfoService extends JpaBaseService { if (super.update(userInfo)) { if(kafkaPersistService.getApplicationConfig().isKafkaSupport()) { UserInfo loadUserInfo = loadUserRelated(userInfo.getId()); + accountUpdate(loadUserInfo); kafkaPersistService.send( KafkaIdentityTopic.USERINFO_TOPIC, loadUserInfo, KafkaIdentityAction.UPDATE_ACTION); } + changePasswordProvisioning(userInfo); return true; } @@ -138,10 +143,27 @@ public class UserInfoService extends JpaBaseService { KafkaIdentityTopic.USERINFO_TOPIC, loadUserInfo, KafkaIdentityAction.DELETE_ACTION); + accountUpdate(loadUserInfo); return true; } return false; } + + //更新账号状态 + public void accountUpdate(UserInfo userInfo) { + if(userInfo.getStatus() != ConstantsStatus.ACTIVE) { + if(accountsService==null) { + accountsService = + (AccountsService)WebContext.getBean("accountsService"); + } + Accounts queryAcount =new Accounts(); + queryAcount.setUserId(userInfo.getId()); + for (Accounts acount : accountsService.query(queryAcount)) { + acount.setStatus(ConstantsStatus.INACTIVE); + accountsService.update(acount); + } + } + } public UserInfo loadUserRelated(String userId) { UserInfo loadUserInfo =this.get(userId); diff --git a/maxkey-webs/maxkey-web-mgt/build.gradle b/maxkey-webs/maxkey-web-mgt/build.gradle index 3f21e823ee7f3576f703a6f0426533fb34205b53..141704fa084ab61180a1ad76b2831e0694d8552f 100644 --- a/maxkey-webs/maxkey-web-mgt/build.gradle +++ b/maxkey-webs/maxkey-web-mgt/build.gradle @@ -19,6 +19,7 @@ dependencies { implementation project(":maxkey-identitys:maxkey-identity-scim") implementation project(":maxkey-identitys:maxkey-identity-rest") implementation project(":maxkey-identitys:maxkey-synchronizers") + implementation project(":maxkey-identitys:maxkey-synchronizers-reorgdept") implementation project(":maxkey-identitys:maxkey-synchronizers-activedirectory") implementation project(":maxkey-identitys:maxkey-synchronizers-ldap") implementation project(":maxkey-identitys:maxkey-synchronizers-workweixin") diff --git a/maxkey-webs/maxkey-web-mgt/src/main/resources/templates/views/accounts/accountsAdd.ftl b/maxkey-webs/maxkey-web-mgt/src/main/resources/templates/views/accounts/accountsAdd.ftl index ea14eeb8b4458498ef13e0c22e624627e68e1091..4f9362f5139b66c8299283fa5da479e719522e5c 100644 --- a/maxkey-webs/maxkey-web-mgt/src/main/resources/templates/views/accounts/accountsAdd.ftl +++ b/maxkey-webs/maxkey-web-mgt/src/main/resources/templates/views/accounts/accountsAdd.ftl @@ -51,7 +51,7 @@ " wurl="<@base/>/userinfo/select" wwidth="800" - wheight="500" + wheight="620" target="window"/> @@ -75,7 +75,7 @@ " wurl="<@base/>/apps/select" wwidth="800" - wheight="500" + wheight="620" target="window"/> diff --git a/maxkey-webs/maxkey-web-mgt/src/main/resources/templates/views/apps/selectAppsList.ftl b/maxkey-webs/maxkey-web-mgt/src/main/resources/templates/views/apps/selectAppsList.ftl index 92165dbf91f5df5ccbf36d7d87415870d894cd2e..00e008413989e47aaebe67a9a35009b57d771427 100644 --- a/maxkey-webs/maxkey-web-mgt/src/main/resources/templates/views/apps/selectAppsList.ftl +++ b/maxkey-webs/maxkey-web-mgt/src/main/resources/templates/views/apps/selectAppsList.ftl @@ -24,60 +24,54 @@ -
+
-
<@locale code="apps.name"/>: +
- - "> - +
-
- " /> +
+ "> + " />
- -
- -
- - - - - - - - - - - - - - -
Id<@locale code="apps.icon"/><@locale code="apps.name"/><@locale code="apps.protocol"/><@locale code="apps.category"/><@locale code="apps.vendor"/><@locale code="log.loginhistory.loginUrl"/>
-
+ + + + + + + + + + + + + + +
Id<@locale code="apps.icon"/><@locale code="apps.name"/><@locale code="apps.protocol"/><@locale code="apps.category"/><@locale code="apps.vendor"/><@locale code="log.loginhistory.loginUrl"/>
\ No newline at end of file diff --git a/maxkey-webs/maxkey-web-mgt/src/main/resources/templates/views/userinfo/userinfoSelect.ftl b/maxkey-webs/maxkey-web-mgt/src/main/resources/templates/views/userinfo/userinfoSelect.ftl index 33e4153485b5408e7626839839fe0761941268eb..8debbab6447c9b664eb9365bc588f522b31c4056 100644 --- a/maxkey-webs/maxkey-web-mgt/src/main/resources/templates/views/userinfo/userinfoSelect.ftl +++ b/maxkey-webs/maxkey-web-mgt/src/main/resources/templates/views/userinfo/userinfoSelect.ftl @@ -149,20 +149,35 @@
- - " > + + + + + + +
+ <@locale code="userinfo.username"/>: + +
+ + +
+
+
+ "> + " > +
+
+
- -
+
+