Browse Source

Email and LDAP store to database

MaxKey 3 years ago
parent
commit
6a00bf4517

+ 251 - 0
maxkey-core/src/main/java/org/maxkey/entity/EmailSenders.java

@@ -0,0 +1,251 @@
+package org.maxkey.entity;
+
+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_EMAIL_SENDERS")
+public class EmailSenders  extends JpaBaseEntity{
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 3689854324601731505L;
+	
+	@Id
+    @Column
+    @GeneratedValue(strategy = GenerationType.AUTO, generator = "snowflakeid")
+    private String id;
+	
+	@Column
+    private String account;
+    
+	@Column
+    private String credentials;
+    
+	@Column
+    private String smtpHost;
+    
+	@Column
+    private Integer port;
+    
+	@Column
+    private int sslSwitch;
+    
+	@Column
+    private String sender;
+	
+	@Column
+    private String encoding;
+	
+	@Column
+    private String protocol;
+	
+    @Column
+    private int status;
+    
+    @Column
+    private String instId;
+    
+    private String instName;
+    
+    @Column
+    private String description;
+    
+    @Column
+    private String createdBy;
+    
+    @Column
+    private String createdDate;
+    
+    @Column
+    private String modifiedBy;
+    
+    @Column
+    private String modifiedDate;
+
+	public EmailSenders() {
+		super();
+	}
+
+	public String getId() {
+		return id;
+	}
+
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	public String getAccount() {
+		return account;
+	}
+
+	public void setAccount(String account) {
+		this.account = account;
+	}
+
+	public String getCredentials() {
+		return credentials;
+	}
+
+	public void setCredentials(String credentials) {
+		this.credentials = credentials;
+	}
+
+	public String getSmtpHost() {
+		return smtpHost;
+	}
+
+	public void setSmtpHost(String smtpHost) {
+		this.smtpHost = smtpHost;
+	}
+
+	public Integer getPort() {
+		return port;
+	}
+
+	public void setPort(Integer port) {
+		this.port = port;
+	}
+
+
+	public int getSslSwitch() {
+		return sslSwitch;
+	}
+
+	public void setSslSwitch(int sslSwitch) {
+		this.sslSwitch = sslSwitch;
+	}
+
+	public String getEncoding() {
+		return encoding;
+	}
+
+	public void setEncoding(String encoding) {
+		this.encoding = encoding;
+	}
+
+	public String getProtocol() {
+		return protocol;
+	}
+
+	public void setProtocol(String protocol) {
+		this.protocol = protocol;
+	}
+
+	public String getSender() {
+		return sender;
+	}
+
+	public void setSender(String sender) {
+		this.sender = sender;
+	}
+
+	public int getStatus() {
+		return status;
+	}
+
+	public void setStatus(int status) {
+		this.status = status;
+	}
+
+	public String getInstId() {
+		return instId;
+	}
+
+	public void setInstId(String instId) {
+		this.instId = instId;
+	}
+
+	public String getInstName() {
+		return instName;
+	}
+
+	public void setInstName(String instName) {
+		this.instName = instName;
+	}
+
+	public String getDescription() {
+		return description;
+	}
+
+	public void setDescription(String description) {
+		this.description = description;
+	}
+
+	public String getCreatedBy() {
+		return createdBy;
+	}
+
+	public void setCreatedBy(String createdBy) {
+		this.createdBy = createdBy;
+	}
+
+	public String getCreatedDate() {
+		return createdDate;
+	}
+
+	public void setCreatedDate(String createdDate) {
+		this.createdDate = createdDate;
+	}
+
+	public String getModifiedBy() {
+		return modifiedBy;
+	}
+
+	public void setModifiedBy(String modifiedBy) {
+		this.modifiedBy = modifiedBy;
+	}
+
+	public String getModifiedDate() {
+		return modifiedDate;
+	}
+
+	public void setModifiedDate(String modifiedDate) {
+		this.modifiedDate = modifiedDate;
+	}
+
+	@Override
+	public String toString() {
+		StringBuilder builder = new StringBuilder();
+		builder.append("EmailSenders [id=");
+		builder.append(id);
+		builder.append(", account=");
+		builder.append(account);
+		builder.append(", credentials=");
+		builder.append(credentials);
+		builder.append(", smtpHost=");
+		builder.append(smtpHost);
+		builder.append(", port=");
+		builder.append(port);
+		builder.append(", sslSwitch=");
+		builder.append(sslSwitch);
+		builder.append(", sender=");
+		builder.append(sender);
+		builder.append(", status=");
+		builder.append(status);
+		builder.append(", instId=");
+		builder.append(instId);
+		builder.append(", instName=");
+		builder.append(instName);
+		builder.append(", description=");
+		builder.append(description);
+		builder.append(", createdBy=");
+		builder.append(createdBy);
+		builder.append(", createdDate=");
+		builder.append(createdDate);
+		builder.append(", modifiedBy=");
+		builder.append(modifiedBy);
+		builder.append(", modifiedDate=");
+		builder.append(modifiedDate);
+		builder.append("]");
+		return builder.toString();
+	}
+       
+}

+ 17 - 17
maxkey-core/src/main/java/org/maxkey/persistence/repository/PasswordPolicyRepository.java

@@ -161,23 +161,23 @@ 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"));
+           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;
        }
 

+ 24 - 0
maxkey-persistence/src/main/java/org/maxkey/persistence/mapper/EmailSendersMapper.java

@@ -0,0 +1,24 @@
+/*
+ * 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.maxkey.persistence.mapper;
+import org.apache.mybatis.jpa.persistence.IJpaBaseMapper;
+import org.maxkey.entity.EmailSenders;
+
+public interface EmailSendersMapper extends IJpaBaseMapper<EmailSenders> {
+
+}

+ 24 - 0
maxkey-persistence/src/main/java/org/maxkey/persistence/mapper/LdapContextMapper.java

@@ -0,0 +1,24 @@
+/*
+ * 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.maxkey.persistence.mapper;
+import org.apache.mybatis.jpa.persistence.IJpaBaseMapper;
+import org.maxkey.entity.LdapContext;
+
+public interface LdapContextMapper extends IJpaBaseMapper<LdapContext> {
+
+}

+ 42 - 0
maxkey-persistence/src/main/java/org/maxkey/persistence/service/EmailSendersService.java

@@ -0,0 +1,42 @@
+/*
+ * 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.maxkey.persistence.service;
+
+import org.apache.mybatis.jpa.persistence.JpaBaseService;
+import org.maxkey.entity.EmailSenders;
+import org.maxkey.persistence.mapper.EmailSendersMapper;
+import org.springframework.stereotype.Repository;
+
+
+@Repository
+public class EmailSendersService  extends JpaBaseService<EmailSenders>{
+	
+	public EmailSendersService() {
+		super(EmailSendersMapper.class);
+	}
+
+	/* (non-Javadoc)
+	 * @see com.connsec.db.service.BaseService#getMapper()
+	 */
+	@Override
+	public EmailSendersMapper getMapper() {
+		return (EmailSendersMapper)super.getMapper();
+	}
+ 
+	 
+}

+ 42 - 0
maxkey-persistence/src/main/java/org/maxkey/persistence/service/LdapContextService.java

@@ -0,0 +1,42 @@
+/*
+ * 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.maxkey.persistence.service;
+
+import org.apache.mybatis.jpa.persistence.JpaBaseService;
+import org.maxkey.entity.LdapContext;
+import org.maxkey.persistence.mapper.LdapContextMapper;
+import org.springframework.stereotype.Repository;
+
+
+@Repository
+public class LdapContextService  extends JpaBaseService<LdapContext>{
+	
+	public LdapContextService() {
+		super(LdapContextMapper.class);
+	}
+
+	/* (non-Javadoc)
+	 * @see com.connsec.db.service.BaseService#getMapper()
+	 */
+	@Override
+	public LdapContextMapper getMapper() {
+		return (LdapContextMapper)super.getMapper();
+	}
+ 
+	 
+}

+ 2 - 0
maxkey-webs/maxkey-web-mgt/src/main/java/org/maxkey/MaxKeyMgtMvcConfig.java

@@ -131,6 +131,8 @@ public class MaxKeyMgtMvcConfig implements WebMvcConfigurer {
                 .addPathPatterns("/accountsstrategy/**")
                 .addPathPatterns("/institutions/**")
                 .addPathPatterns("/localization/**")
+                .addPathPatterns("/ldapcontext/**")
+                .addPathPatterns("/emailsenders/**")
                 
                 ;
         

+ 92 - 0
maxkey-webs/maxkey-web-mgt/src/main/java/org/maxkey/web/contorller/EmailSendersController.java

@@ -0,0 +1,92 @@
+/*
+ * 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.maxkey.web.contorller;
+
+import org.apache.commons.lang3.StringUtils;
+import org.maxkey.constants.ConstantsOperateMessage;
+import org.maxkey.crypto.password.PasswordReciprocal;
+import org.maxkey.entity.EmailSenders;
+import org.maxkey.persistence.service.EmailSendersService;
+import org.maxkey.web.WebContext;
+import org.maxkey.web.message.Message;
+import org.maxkey.web.message.MessageType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.servlet.ModelAndView;
+
+@Controller
+@RequestMapping(value={"/emailsenders"})
+public class EmailSendersController {
+
+
+		final static Logger _logger = LoggerFactory.getLogger(EmailSendersController.class);
+		
+		@Autowired
+		private EmailSendersService emailSendersService;
+		
+		/**
+		 * 读取
+		 * @return
+		 */
+		@RequestMapping(value={"/forward"})
+		public ModelAndView forward(){
+			EmailSenders emailSenders = emailSendersService.get(WebContext.getUserInfo().getInstId());
+			if(emailSenders != null && StringUtils.isNotBlank(emailSenders.getCredentials())) {
+				emailSenders.setCredentials(PasswordReciprocal.getInstance().decoder(emailSenders.getCredentials()));
+			}else {
+				emailSenders =new EmailSenders();
+				emailSenders.setProtocol("smtp");
+				emailSenders.setEncoding("utf-8");
+			}
+			return new ModelAndView("emailsenders/updateEmailSenders","model",emailSenders);	
+		}
+		
+		/**
+		 * 更新
+		 * @param emailSenders
+		 * @return
+		 */
+		@RequestMapping(value={"/update"})
+		@ResponseBody
+		public Message update(@ModelAttribute("emailSenders") EmailSenders emailSenders,BindingResult result) {
+			_logger.debug("update emailSenders : "+emailSenders);
+			emailSenders.setInstId(WebContext.getUserInfo().getInstId());
+			emailSenders.setCredentials(PasswordReciprocal.getInstance().encode(emailSenders.getCredentials()));
+			boolean updateResult = false;
+			if(StringUtils.isBlank(emailSenders.getId())) {
+				emailSenders.setId(emailSenders.getInstId());
+				updateResult = emailSendersService.insert(emailSenders);
+			}else {
+				updateResult = emailSendersService.update(emailSenders);
+			}
+			
+			if(updateResult) {
+				return new Message(WebContext.getI18nValue(ConstantsOperateMessage.UPDATE_SUCCESS),MessageType.success);
+			} else {
+				return new Message(WebContext.getI18nValue(ConstantsOperateMessage.UPDATE_ERROR),MessageType.error);
+			}
+		}
+		
+
+}

+ 87 - 0
maxkey-webs/maxkey-web-mgt/src/main/java/org/maxkey/web/contorller/LdapContextController.java

@@ -0,0 +1,87 @@
+/*
+ * 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.maxkey.web.contorller;
+
+import org.apache.commons.lang3.StringUtils;
+import org.maxkey.constants.ConstantsOperateMessage;
+import org.maxkey.crypto.password.PasswordReciprocal;
+import org.maxkey.entity.LdapContext;
+import org.maxkey.persistence.service.LdapContextService;
+import org.maxkey.web.WebContext;
+import org.maxkey.web.message.Message;
+import org.maxkey.web.message.MessageType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.servlet.ModelAndView;
+
+@Controller
+@RequestMapping(value={"/ldapcontext"})
+public class LdapContextController {
+
+
+		final static Logger _logger = LoggerFactory.getLogger(LdapContextController.class);
+		
+		@Autowired
+		private LdapContextService ldapContextService;
+		
+		/**
+		 * 读取
+		 * @return
+		 */
+		@RequestMapping(value={"/forward"})
+		public ModelAndView forward(){
+			LdapContext ldapContext = ldapContextService.get(WebContext.getUserInfo().getInstId());
+			if(ldapContext != null && StringUtils.isNoneBlank(ldapContext.getCredentials())) {
+				ldapContext.setCredentials(PasswordReciprocal.getInstance().decoder(ldapContext.getCredentials()));
+			}
+			return new ModelAndView("ldapcontext/updateLdapContext","model",ldapContext);
+		}
+		
+		/**
+		 * 更新
+		 * @param sysConfig
+		 * @return
+		 */
+		@RequestMapping(value={"/update"})
+		@ResponseBody
+		public Message update(@ModelAttribute("ldapContext") LdapContext ldapContext,BindingResult result) {
+			_logger.debug("update ldapContext : "+ldapContext);
+			ldapContext.setCredentials(PasswordReciprocal.getInstance().encode(ldapContext.getCredentials()));
+			ldapContext.setInstId(WebContext.getUserInfo().getInstId());
+			boolean updateResult = false;
+			if(StringUtils.isBlank(ldapContext.getId())) {
+				ldapContext.setId(ldapContext.getInstId());
+				updateResult = ldapContextService.insert(ldapContext);
+			}else {
+				updateResult = ldapContextService.update(ldapContext);
+			}
+			if(updateResult) {
+				return new Message(WebContext.getI18nValue(ConstantsOperateMessage.UPDATE_SUCCESS),MessageType.success);
+			} else {
+				return new Message(WebContext.getI18nValue(ConstantsOperateMessage.UPDATE_ERROR),MessageType.error);
+			}
+		}
+		
+
+}

+ 23 - 1
maxkey-webs/maxkey-web-mgt/src/main/resources/messages/message.properties

@@ -513,6 +513,26 @@ institutions.postalcode=\u90AE\u7F16
 localization.property=\u5C5E\u6027
 localization.langZh=\u4E2D\u6587
 localization.langEn=\u82F1\u6587
+
+ldapcontext.product=\u4EA7\u54C1
+ldapcontext.providerUrl=\u5730\u5740
+ldapcontext.principal=\u8D26\u53F7
+ldapcontext.credentials=\u51ED\u8BC1
+ldapcontext.filters=\u8FC7\u6EE4\u5668
+ldapcontext.basedn=\u57FA\u672CDN
+ldapcontext.msadDomain=Active Directory\u57DF
+ldapcontext.sslSwitch=SSL
+ldapcontext.trustStore=\u8BC1\u4E66
+ldapcontext.trustStorePassword=\u8BC1\u4E66\u5BC6\u94A5
+#emailsenders
+emailsenders.account=\u8D26\u53F7
+emailsenders.credentials=\u51ED\u8BC1
+emailsenders.smtpHost=SMTP\u5730\u5740
+emailsenders.port=\u7AEF\u53E3
+emailsenders.sslSwitch=SSL
+emailsenders.sender=\u53D1\u9001\u4EBA
+emailsenders.encoding=\u9ED8\u8BA4\u7F16\u7801
+emailsenders.protocol=\u534F\u8BAE
 #button
 button.text.action=\u8BBF\u95EE
 button.text.visit=\u8BBF\u95EE
@@ -636,4 +656,6 @@ navs.adapters=\u9002\u914D\u5668\u6CE8\u518C
 navs.notices=\u901A\u77E5\u516C\u544A
 navs.institutions=\u673A\u6784\u914D\u7F6E
 navs.socials.provider=\u793E\u4EA4\u670D\u52A1
-navs.synchronizers=\u540C\u6B65\u5668\u7BA1\u7406
+navs.synchronizers=\u540C\u6B65\u5668\u7BA1\u7406
+navs.ldapcontext=LDAP\u914D\u7F6E
+navs.emailsenders=\u7535\u5B50\u90AE\u7BB1

+ 23 - 1
maxkey-webs/maxkey-web-mgt/src/main/resources/messages/message_en.properties

@@ -522,6 +522,26 @@ institutions.postalcode=postalcode
 localization.property=Property
 localization.langZh=Chinese
 localization.langEn=English
+
+ldapcontext.product=Product
+ldapcontext.providerUrl=ProviderUrl
+ldapcontext.principal=Principal
+ldapcontext.credentials=Credentials
+ldapcontext.filters=Filters
+ldapcontext.basedn=Base DN
+ldapcontext.msadDomain=Active Directory Domain
+ldapcontext.sslSwitch=SSL
+ldapcontext.trustStore=TrustStore
+ldapcontext.trustStorePassword=TrustStorePassword
+
+emailsenders.account=Account
+emailsenders.credentials=Credentials
+emailsenders.smtpHost=SMTPHost
+emailsenders.port=Port
+emailsenders.sslSwitch=SSL
+emailsenders.sender=Sender
+emailsenders.encoding=Encoding
+emailsenders.protocol=Protocol
  
 button.text.action=Action
 button.text.visit=Visit
@@ -645,4 +665,6 @@ navs.adapters=Adapters
 navs.notices=Notices
 navs.institutions=Institutions
 navs.socials.provider=SocialsProvider
-navs.synchronizers=Synchronizers
+navs.synchronizers=Synchronizers
+navs.ldapcontext=LdapContext
+navs.emailsenders=Email

+ 23 - 1
maxkey-webs/maxkey-web-mgt/src/main/resources/messages/message_zh_CN.properties

@@ -513,6 +513,26 @@ institutions.postalcode=\u90AE\u7F16
 localization.property=\u5C5E\u6027
 localization.langZh=\u4E2D\u6587
 localization.langEn=\u82F1\u6587
+
+ldapcontext.product=\u4EA7\u54C1
+ldapcontext.providerUrl=\u5730\u5740
+ldapcontext.principal=\u8D26\u53F7
+ldapcontext.credentials=\u51ED\u8BC1
+ldapcontext.filters=\u8FC7\u6EE4\u5668
+ldapcontext.basedn=\u57FA\u672CDN
+ldapcontext.msadDomain=Active Directory\u57DF
+ldapcontext.sslSwitch=SSL
+ldapcontext.trustStore=\u8BC1\u4E66
+ldapcontext.trustStorePassword=\u8BC1\u4E66\u5BC6\u94A5
+#emailsenders
+emailsenders.account=\u8D26\u53F7
+emailsenders.credentials=\u51ED\u8BC1
+emailsenders.smtpHost=SMTP\u5730\u5740
+emailsenders.port=\u7AEF\u53E3
+emailsenders.sslSwitch=SSL
+emailsenders.sender=\u53D1\u9001\u4EBA
+emailsenders.encoding=\u9ED8\u8BA4\u7F16\u7801
+emailsenders.protocol=\u534F\u8BAE
 #button
 button.text.action=\u8BBF\u95EE
 button.text.visit=\u8BBF\u95EE
@@ -636,4 +656,6 @@ navs.adapters=\u9002\u914D\u5668\u6CE8\u518C
 navs.notices=\u901A\u77E5\u516C\u544A
 navs.institutions=\u673A\u6784\u914D\u7F6E
 navs.socials.provider=\u793E\u4EA4\u670D\u52A1
-navs.synchronizers=\u540C\u6B65\u5668\u7BA1\u7406
+navs.synchronizers=\u540C\u6B65\u5668\u7BA1\u7406
+navs.ldapcontext=LDAP\u914D\u7F6E
+navs.emailsenders=\u7535\u5B50\u90AE\u7BB1

+ 187 - 0
maxkey-webs/maxkey-web-mgt/src/main/resources/templates/views/emailsenders/updateEmailSenders.ftl

@@ -0,0 +1,187 @@
+<!DOCTYPE HTML>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<#include  "../layout/header.ftl"/>
+	<#include  "../layout/common.cssjs.ftl"/>
+</head>
+<body> 
+<div class="app header-default side-nav-dark">
+<div class="layout">
+	<div class="header navbar">
+		<#include  "../layout/top.ftl"/>
+	</div>
+	
+	<div class="col-md-3 sidebar-nav side-nav" >
+ 		<#include  "../layout/sidenav.ftl"/>
+	</div>
+	<div class="page-container">
+	
+	<div class="main-content">
+		<div class="container-fluid">
+			<div class="breadcrumb-wrapper row">
+				<div class="col-12 col-lg-3 col-md-6">
+					<h4 class="page-title"><@locale code="navs.emailsenders"/></h4>
+				</div>
+				<div class="col-12 col-lg-9 col-md-6">
+					<ol class="breadcrumb float-right">
+						<li><a href="<@base/>/main"><@locale code="navs.home"/></a></li>
+						<li class="inactive">/ <@locale code="navs.conf"/></li>
+						<li class="active">/ <@locale code="navs.emailsenders"/></li>
+					</ol>
+				</div>
+			</div>
+		</div>
+		<div class="container-fluid">
+			<div class="content-wrapper row">
+			<div class="col-12 grid-margin">
+				<div class="card">
+					<div class="card-header border-bottom">
+						<h4 class="card-title"><@locale code="navs.emailsenders"/></h4>
+					</div>
+					<div class="card-body">
+								<form  method="post" type="label" validate="true" action="<@base/>/emailsenders/update" id="actionForm"   class="needs-validation" novalidate>
+									<div class="row mb-3">
+										<div class="col-md-6">
+											<div class="form-group row">
+												<label class="col-sm-3 col-form-label"><@locale code="common.text.id" />:</label>
+												<div class="col-sm-9">
+													<input class="form-control" readonly id="id" name="id" type="text" value="${model.id!}"/>
+						   							
+												</div>
+											</div>
+										</div>
+										<div class="col-md-6">
+											<div class="form-group row">
+												<label class="col-sm-3 col-form-label"><@locale code="common.text.status" />:</label>
+												<div class="col-sm-9">
+													<select id="status" name="status"  class="form-control  form-select">
+                                                        <option value="0" <#if 0==model.status>selected</#if> ><@locale code="common.text.status.disabled" /></option>
+                                                        <option value="1" <#if 1==model.status>selected</#if> ><@locale code="common.text.status.enabled" /></option>
+                                                    </select>
+												</div>
+											</div>
+										</div>
+									</div>
+                                    <div class="row mb-3">
+                                        <div class="col-md-6">
+                                            <div class="form-group row">
+                                                <label class="col-sm-3 col-form-label"><@locale code="emailsenders.smtpHost" />:</label>
+                                                <div class="col-sm-9">
+                                                    <input  required="" class="form-control" type="text" id="smtpHost" name="smtpHost"  value="${model.smtpHost!}" />
+                                                    
+                                                </div>
+                                                
+                                            </div>
+                                        </div>
+                                        <div class="col-md-6">
+                                            <div class="form-group row">
+                                                <label class="col-sm-3 col-form-label"><@locale code="emailsenders.port" />:</label>
+                                                <div class="col-sm-9">
+                                                    <input  required="" class="form-control" type="text" id="port" name="port" value="${model.port!}" />
+                                                </div>
+                                            </div>
+                                        </div>
+                                    </div>
+									<div class="row mb-3">
+                                        <div class="col-md-6">
+                                            <div class="form-group row">
+                                                <label class="col-sm-3 col-form-label"><@locale code="emailsenders.account" />:</label>
+                                                <div class="col-sm-9">
+                                                    <input  required="" class="form-control" type="text" id="account" name="account"  value="${model.account!}" />
+                                                    
+                                                </div>
+                                                
+                                            </div>
+                                        </div>
+                                        <div class="col-md-6">
+                                            <div class="form-group row">
+                                                <label class="col-sm-3 col-form-label"><@locale code="emailsenders.credentials" />:</label>
+                                                <div class="col-sm-9">
+                                                    <input  required="" class="form-control" type="password" id="credentials" name="credentials" value="${model.credentials!}" />
+                                                </div>
+                                            </div>
+                                        </div>
+                                    </div>
+                                    <div class="row mb-3">
+                                        <div class="col-md-6">
+                                            <div class="form-group row">
+                                                <label class="col-sm-3 col-form-label"><@locale code="emailsenders.protocol" />:</label>
+                                                <div class="col-sm-9">
+                                                    <input  required="" class="form-control" type="text" id="protocol" name="protocol"  value="${model.protocol!}" />
+                                                    
+                                                </div>
+                                                
+                                            </div>
+                                        </div>
+                                        <div class="col-md-6">
+                                            <div class="form-group row">
+                                                <label class="col-sm-3 col-form-label"><@locale code="emailsenders.encoding" />:</label>
+                                                <div class="col-sm-9">
+                                                    <input  required="" class="form-control" type="text" id="encoding" name="encoding" value="${model.encoding!}" />
+                                                </div>
+                                            </div>
+                                        </div>
+                                    </div>
+									<div class="row mb-3">
+										<div class="col-md-6">
+											<div class="form-group row">
+												<label class="col-sm-3 col-form-label"><@locale code="emailsenders.sender" />:</label>
+												<div class="col-sm-9">
+													<input   class="form-control" type="text" id="sender" name="sender" value="${model.sender!}"/>
+												</div>
+											</div>
+										</div>
+										<div class="col-md-6">
+											<div class="form-group row">
+												<label class="col-sm-3"><@locale code="emailsenders.sslSwitch" />:</label>
+												<div class="col-sm-9">
+												    <select id="sslSwitch" name="sslSwitch"  class="form-control  form-select">
+                                                        <option value="0" <#if 0==model.sslSwitch>selected</#if> ><@locale code="common.text.no" /></option>
+                                                        <option value="1" <#if 1==model.sslSwitch>selected</#if> ><@locale code="common.text.yes" /></option>
+                                                    </select>
+												</div>
+											</div>
+										</div>
+									</div>
+									
+                                    <div class="row mb-3">
+                                        <div class="col-md-12">
+                                            <div class="form-group row">
+                                                <div class="col-sm-2">
+                                                    <label class="col-form-label"><@locale code="common.text.description" />:</label>
+                                                </div>
+                                                <div class="col-sm-10">
+                                                    <input   class="form-control" type="text" id="description" name="description"  value="${model.description!}" />
+                                                </div>
+                                            </div>
+                                        </div>
+                                    </div>
+									<div class="row">
+										<div class="col-md-4"></div>
+										<div class="col-md-4">
+										      <input   class="form-control" type="hidden" id="status" name="status"  value="1" />
+											<button type="submit" class="button btn-primary btn btn-common btn-block mr-3"    id="submitBtn" ><@locale code="button.text.save" /></button>
+										</div>
+										<div class="col-md-4"></div>
+									</div>
+									
+								</form>
+							</div>
+						</div>
+					</div>
+				</div>
+					<footer class="content-footer">
+		<#include  "../layout/footer.ftl"/>
+	</footer>
+
+	</div>
+	
+	</div>
+</div>
+
+<div id="preloader">
+<div class="loader" id="loader-1"></div>
+</div>
+
+</body>
+</html>

+ 13 - 0
maxkey-webs/maxkey-web-mgt/src/main/resources/templates/views/layout/sidenav.ftl

@@ -142,6 +142,19 @@
              </a>
            </li>
            <li>
+             <a class="side-nav-menu" href="<@base />/ldapcontext/forward/">
+                <@locale code="navs.ldapcontext"/>
+                 <span class="fa fa-fw fa-balance-scale"></span>
+             </a>
+           </li>
+           <li>
+             <a class="side-nav-menu" href="<@base />/emailsenders/forward/">
+                <@locale code="navs.emailsenders"/>
+                 <span class="fa fa-fw fa-balance-scale"></span>
+             </a>
+           </li>
+           
+           <li>
              <a class="side-nav-menu" href="<@base />/config/passwordpolicy/forward/">
                 <@locale code="navs.conf.passwordpolicy"/>
                  <span class="fa fa-fw fa-balance-scale"></span>

+ 193 - 0
maxkey-webs/maxkey-web-mgt/src/main/resources/templates/views/ldapcontext/updateLdapContext.ftl

@@ -0,0 +1,193 @@
+<!DOCTYPE HTML>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<#include  "../layout/header.ftl"/>
+	<#include  "../layout/common.cssjs.ftl"/>
+</head>
+<body> 
+<div class="app header-default side-nav-dark">
+<div class="layout">
+	<div class="header navbar">
+		<#include  "../layout/top.ftl"/>
+	</div>
+	
+	<div class="col-md-3 sidebar-nav side-nav" >
+ 		<#include  "../layout/sidenav.ftl"/>
+	</div>
+	<div class="page-container">
+	
+	<div class="main-content">
+		<div class="container-fluid">
+			<div class="breadcrumb-wrapper row">
+				<div class="col-12 col-lg-3 col-md-6">
+					<h4 class="page-title"><@locale code="navs.ldapcontext"/></h4>
+				</div>
+				<div class="col-12 col-lg-9 col-md-6">
+					<ol class="breadcrumb float-right">
+						<li><a href="<@base/>/main"><@locale code="navs.home"/></a></li>
+						<li class="inactive">/ <@locale code="navs.conf"/></li>
+						<li class="active">/ <@locale code="navs.ldapcontext"/></li>
+					</ol>
+				</div>
+			</div>
+		</div>
+		<div class="container-fluid">
+			<div class="content-wrapper row">
+			<div class="col-12 grid-margin">
+				<div class="card">
+					<div class="card-header border-bottom">
+						<h4 class="card-title"><@locale code="navs.ldapcontext"/></h4>
+					</div>
+					<div class="card-body">
+								<form  method="post" type="label" validate="true" action="<@base/>/ldapcontext/update" id="actionForm"   class="needs-validation" novalidate>
+									<div class="row mb-3">
+										<div class="col-md-6">
+											<div class="form-group row">
+												<label class="col-sm-3 col-form-label"><@locale code="ldapcontext.product" />:</label>
+												<div class="col-sm-9">
+													<input id="id" name="id" type="hidden" value="${model.id!}"/>
+						   							<select id="product" name="product"  class="form-control form-select">
+                                                        <option value="ActiveDirectory" <#if 'ActiveDirectory'==model.product>selected</#if> >Active Directory</option>
+                                                        <option value="OpenLDAP"        <#if 'OpenLDAP'==model.product       >selected</#if> >OpenLDAP</option>
+                                                        <option value="StandardLDAP"    <#if 'StandardLDAP'==model.product   >selected</#if> >StandardLDAP</option>
+                                                    </select>
+												</div>
+											</div>
+										</div>
+										<div class="col-md-6">
+											<div class="form-group row">
+												<label class="col-sm-3 col-form-label"><@locale code="common.text.status" />:</label>
+												<div class="col-sm-9">
+													<select id="status" name="status"  class="form-control  form-select">
+                                                        <option value="0" <#if 0==model.status>selected</#if> ><@locale code="common.text.status.disabled" /></option>
+                                                        <option value="1" <#if 1==model.status>selected</#if> ><@locale code="common.text.status.enabled" /></option>
+                                                    </select>
+												</div>
+											</div>
+										</div>
+									</div>
+									<div class="row mb-3">
+                                            <label class="col-md-2 col-form-label"><@locale code="ldapcontext.providerUrl" />:</label>
+                                            <div class="col-md-10">
+                                                <input required=""  class="form-control" type="text" id="providerUrl" name="providerUrl" value="${model.providerUrl!}" />
+                                            </div>
+                                    </div>
+									<div class="row mb-3">
+                                        <div class="col-md-6">
+                                            <div class="form-group row">
+                                                <label class="col-sm-3 col-form-label"><@locale code="ldapcontext.principal" />:</label>
+                                                <div class="col-sm-9">
+                                                    <input  required="" class="form-control" type="text" id="principal" name="principal"  value="${model.principal!}" />
+                                                    
+                                                </div>
+                                                
+                                            </div>
+                                        </div>
+                                        <div class="col-md-6">
+                                            <div class="form-group row">
+                                                <label class="col-sm-3 col-form-label"><@locale code="ldapcontext.credentials" />:</label>
+                                                <div class="col-sm-9">
+                                                    <input  required="" class="form-control" type="password" id="credentials" name="credentials" value="${model.credentials!}" />
+                                                </div>
+                                            </div>
+                                        </div>
+                                    </div>
+									<div class="row mb-3">
+										<div class="col-md-6">
+											<div class="form-group row">
+												<label class="col-sm-3 col-form-label"><@locale code="ldapcontext.filters" />:</label>
+												<div class="col-sm-9">
+													<input  required="" class="form-control" type="text" id="filters" name="filters"  value="${model.filters!}" />
+												</div>
+											</div>
+										</div>
+										<div class="col-md-6">
+											<div class="form-group row">
+												<label class="col-sm-3 col-form-label"><@locale code="ldapcontext.basedn" />:</label>
+												<div class="col-sm-9">
+													<input  required="" class="form-control" type="text" id="basedn" name="basedn" value="${model.basedn!}" />
+												</div>
+											</div>
+										</div>
+									</div>
+									<div class="row mb-3">
+										<div class="col-md-6">
+											<div class="form-group row">
+												<label class="col-sm-3 col-form-label"><@locale code="ldapcontext.msadDomain" />:</label>
+												<div class="col-sm-9">
+													<input   class="form-control" type="text" id="msadDomain" name="msadDomain" value="${model.msadDomain!}"/>
+												</div>
+											</div>
+										</div>
+										<div class="col-md-6">
+											<div class="form-group row">
+												<label class="col-sm-3"><@locale code="ldapcontext.sslSwitch" />:</label>
+												<div class="col-sm-9">
+												    <select id="sslSwitch" name="sslSwitch"  class="form-control  form-select">
+                                                        <option value="0" <#if '0'==model.sslSwitch>selected</#if> ><@locale code="common.text.no" /></option>
+                                                        <option value="1" <#if '1'==model.sslSwitch>selected</#if> ><@locale code="common.text.yes" /></option>
+                                                    </select>
+												</div>
+											</div>
+										</div>
+									</div>
+									<div class="row mb-3">
+										<div class="col-md-6">
+											<div class="form-group row">
+												<label class="col-sm-3 col-form-label"><@locale code="ldapcontext.trustStore" />:</label>
+												<div class="col-sm-9">
+													<input   class="form-control" type="text" id="trustStore" name="trustStore" value="${model.trustStore!}" />
+												</div>
+											</div>
+										</div>
+										
+										<div class="col-md-6">
+											<div class="form-group row">
+                                                <label class="col-sm-3 col-form-label"><@locale code="ldapcontext.trustStorePassword" />:</label>
+                                                <div class="col-sm-9">
+                                                    <input   class="form-control" type="text" id="trustStorePassword" name="trustStorePassword" value="${model.trustStorePassword!}" />
+                                                </div>
+                                            </div>
+										</div>
+									</div>
+                                    <div class="row mb-3">
+                                        <div class="col-md-12">
+                                            <div class="form-group row">
+                                                <div class="col-sm-2">
+                                                    <label class="col-form-label"><@locale code="common.text.description" />:</label>
+                                                </div>
+                                                <div class="col-sm-10">
+                                                    <input   class="form-control" type="text" id="description" name="description"  value="${model.description!}" />
+                                                </div>
+                                            </div>
+                                        </div>
+                                    </div>
+									<div class="row">
+										<div class="col-md-4"></div>
+										<div class="col-md-4">
+										      <input   class="form-control" type="hidden" id="status" name="status"  value="1" />
+											<button type="submit" class="button btn-primary btn btn-common btn-block mr-3"    id="submitBtn" ><@locale code="button.text.save" /></button>
+										</div>
+										<div class="col-md-4"></div>
+									</div>
+									
+								</form>
+							</div>
+						</div>
+					</div>
+				</div>
+					<footer class="content-footer">
+		<#include  "../layout/footer.ftl"/>
+	</footer>
+
+	</div>
+	
+	</div>
+</div>
+
+<div id="preloader">
+<div class="loader" id="loader-1"></div>
+</div>
+
+</body>
+</html>