new version provision

This commit is contained in:
MaxKey 2022-09-13 11:09:18 +08:00
parent 9e230e20c5
commit 8e5fc93d13
43 changed files with 1711 additions and 425 deletions

View File

@ -17,6 +17,8 @@
package org.maxkey.util; package org.maxkey.util;
import java.util.HashMap;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.maxkey.crypto.Base64Utils; import org.maxkey.crypto.Base64Utils;
@ -90,4 +92,10 @@ public class AuthorizationHeaderUtils {
return null; return null;
} }
public static HashMap<String,String> authorization(String authorization) {
HashMap<String,String> authorizationMap = new HashMap<String,String>();
authorizationMap.put(HEADER_Authorization, authorization);
return authorizationMap;
}
} }

View File

@ -67,8 +67,8 @@ public class ApplicationConfig {
@Value("${server.servlet.session.timeout:1800}") @Value("${server.servlet.session.timeout:1800}")
private int sessionTimeout; private int sessionTimeout;
@Value("${maxkey.server.message.queue:none}") @Value("${maxkey.server.provision:false}")
private String messageQueue; private boolean provision;
@Value("${maxkey.notices.visible:false}") @Value("${maxkey.notices.visible:false}")
private boolean noticesVisible; private boolean noticesVisible;
@ -192,19 +192,19 @@ public class ApplicationConfig {
this.defaultUri = defaultUri; this.defaultUri = defaultUri;
} }
public String getMessageQueue() { public boolean isProvision() {
return messageQueue; return provision;
} }
public boolean isMessageQueueSupport() { public void setProvision(boolean provision) {
if(StringUtils.isBlank(messageQueue)||messageQueue.equalsIgnoreCase("none")) { this.provision = provision;
return false; }
public boolean isProvisionSupport() {
if(provision) {
return true;
} }
return true; return false;
}
public void setMessageQueue(String messageQueue) {
this.messageQueue = messageQueue;
} }
public String getMgtUri() { public String getMgtUri() {
@ -262,8 +262,8 @@ public class ApplicationConfig {
builder.append(mgtUri); builder.append(mgtUri);
builder.append(", port="); builder.append(", port=");
builder.append(port); builder.append(port);
builder.append(", kafkaSupport="); builder.append(", provision=");
builder.append(messageQueue); builder.append(provision);
builder.append(", maxKeyUri="); builder.append(", maxKeyUri=");
builder.append(authzUri); builder.append(authzUri);
builder.append("]"); builder.append("]");

View File

@ -0,0 +1,210 @@
/*
* 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.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;
import org.maxkey.pretty.impl.JsonPretty;
@Entity
@Table(name = "MXK_CONNECTORS")
public class Connectors extends JpaBaseEntity implements Serializable {
private static final long serialVersionUID = 4660258495864814777L;
@Id
@Column
@GeneratedValue(strategy = GenerationType.AUTO, generator = "snowflakeid")
String id;
@Column
String connName;
@Column
String scheduler;
@Column
int justInTime;
@Column
String providerUrl;
@Column
String principal;
@Column
String credentials;
@Column
String filters;
@Column
String description;
@Column
String createdBy;
@Column
String createdDate;
@Column
String modifiedBy;
@Column
String modifiedDate;
@Column
String status;
@Column
private String instId;
private String instName;
public Connectors() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getConnName() {
return connName;
}
public void setConnName(String connName) {
this.connName = connName;
}
public int getJustInTime() {
return justInTime;
}
public void setJustInTime(int justInTime) {
this.justInTime = justInTime;
}
public String getScheduler() {
return scheduler;
}
public void setScheduler(String scheduler) {
this.scheduler = scheduler;
}
public String getProviderUrl() {
return providerUrl;
}
public void setProviderUrl(String providerUrl) {
this.providerUrl = providerUrl;
}
public String getPrincipal() {
return principal;
}
public void setPrincipal(String principal) {
this.principal = principal;
}
public String getCredentials() {
return credentials;
}
public void setCredentials(String credentials) {
this.credentials = credentials;
}
public String getFilters() {
return filters;
}
public void setFilters(String filters) {
this.filters = filters;
}
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;
}
public String getStatus() {
return status;
}
public void setStatus(String 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 Connectors(String id) {
this.id = id;
}
@Override
public String toString() {
return new JsonPretty().format(this);
}
}

View File

@ -14,7 +14,6 @@
* limitations under the License. * limitations under the License.
*/ */
package org.maxkey.entity; package org.maxkey.entity;
import java.io.Serializable; import java.io.Serializable;
@ -30,208 +29,176 @@ import org.apache.mybatis.jpa.persistence.JpaBaseEntity;
@Entity @Entity
@Table(name = "MXK_HISTORY_CONNECTOR") @Table(name = "MXK_HISTORY_CONNECTOR")
public class HistoryConnector extends JpaBaseEntity implements Serializable{ public class HistoryConnector extends JpaBaseEntity implements Serializable {
/**
*
*/
private static final long serialVersionUID = 3465459057253994386L;
/** @Id
* @Column
*/ @GeneratedValue(strategy = GenerationType.AUTO, generator = "snowflakeid")
private static final long serialVersionUID = 3465459057253994386L; String id;
@Id @Column
@Column String conName;
@GeneratedValue(strategy=GenerationType.AUTO,generator="snowflakeid")
String id;
@Column @Column
String conName; String topic;
@Column @Column
String conType; String actionType;
@Column @Column
String conAction; String sourceId;
@Column @Column
String sourceId; String sourceName;
@Column @Column
String sourceName; String objectId;
@Column @Column
String objectId; String objectName;
@Column @Column
String objectName; String description;
@Column String syncTime;
String description;
@Column
String result;
String syncTime; String startDate;
@Column String endDate;
String result;
String startDate;
String endDate;
@Column @Column
private String instId; private String instId;
private String instName; private String instName;
public String getId() { public String getId() {
return id; return id;
}
public void setId(String id) {
this.id = id;
}
public String getConName() {
return conName;
}
public void setConName(String conName) {
this.conName = conName;
}
public String getConType() {
return conType;
}
public void setConType(String conType) {
this.conType = conType;
}
public String getSourceId() {
return sourceId;
}
public void setSourceId(String sourceId) {
this.sourceId = sourceId;
}
public String getSourceName() {
return sourceName;
}
public void setSourceName(String sourceName) {
this.sourceName = sourceName;
}
public String getObjectId() {
return objectId;
}
public void setObjectId(String objectId) {
this.objectId = objectId;
}
public String getObjectName() {
return objectName;
}
public void setObjectName(String objectName) {
this.objectName = objectName;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getSyncTime() {
return syncTime;
}
public void setSyncTime(String syncTime) {
this.syncTime = syncTime;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
public String getStartDate() {
return startDate;
}
public void setStartDate(String startDate) {
this.startDate = startDate;
}
public String getEndDate() {
return endDate;
}
public void setEndDate(String endDate) {
this.endDate = endDate;
}
public String getConAction() {
return conAction;
} }
public void setId(String id) {
public void setConAction(String conAction) { this.id = id;
this.conAction = conAction;
} }
public String getConName() {
return conName;
}
public void setConName(String conName) {
this.conName = conName;
}
public String getSourceId() {
return sourceId;
}
public void setSourceId(String sourceId) {
this.sourceId = sourceId;
}
public String getSourceName() {
return sourceName;
}
public void setSourceName(String sourceName) {
this.sourceName = sourceName;
}
public String getObjectId() {
return objectId;
}
public void setObjectId(String objectId) {
this.objectId = objectId;
}
public String getObjectName() {
return objectName;
}
public void setObjectName(String objectName) {
this.objectName = objectName;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getSyncTime() {
return syncTime;
}
public void setSyncTime(String syncTime) {
this.syncTime = syncTime;
}
public String getResult() {
return result;
}
public String getTopic() {
return topic;
}
public void setTopic(String topic) {
this.topic = topic;
}
public String getActionType() {
return actionType;
}
public void setActionType(String actionType) {
this.actionType = actionType;
}
public void setResult(String result) {
this.result = result;
}
public String getStartDate() {
return startDate;
}
public void setStartDate(String startDate) {
this.startDate = startDate;
}
public String getEndDate() {
return endDate;
}
public void setEndDate(String endDate) {
this.endDate = endDate;
}
public String getInstId() { public String getInstId() {
return instId; return instId;
} }
public void setInstId(String instId) { public void setInstId(String instId) {
this.instId = instId; this.instId = instId;
} }
public String getInstName() { public String getInstName() {
return instName; return instName;
} }
public void setInstName(String instName) { public void setInstName(String instName) {
this.instName = instName; this.instName = instName;
} }
@Override @Override
public String toString() { public String toString() {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
@ -239,10 +206,10 @@ public class HistoryConnector extends JpaBaseEntity implements Serializable{
builder.append(id); builder.append(id);
builder.append(", conName="); builder.append(", conName=");
builder.append(conName); builder.append(conName);
builder.append(", conType="); builder.append(", topic=");
builder.append(conType); builder.append(topic);
builder.append(", conAction="); builder.append(", actionType=");
builder.append(conAction); builder.append(actionType);
builder.append(", sourceId="); builder.append(", sourceId=");
builder.append(sourceId); builder.append(sourceId);
builder.append(", sourceName="); builder.append(", sourceName=");
@ -261,9 +228,12 @@ public class HistoryConnector extends JpaBaseEntity implements Serializable{
builder.append(startDate); builder.append(startDate);
builder.append(", endDate="); builder.append(", endDate=");
builder.append(endDate); builder.append(endDate);
builder.append(", instId=");
builder.append(instId);
builder.append(", instName=");
builder.append(instName);
builder.append("]"); builder.append("]");
return builder.toString(); return builder.toString();
} }
} }

View File

@ -157,6 +157,69 @@ public class HttpRequestAdapter {
return null; return null;
} }
public String postJson(String url,String jsonString,HashMap<String,String> headers) {
// 创建httpClient实例
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse httpResponse = null;
// 创建httpPost远程连接实例
HttpPost httpPost = new HttpPost(url);
// 配置请求参数实例
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000)// 设置连接主机服务超时时间
.setConnectionRequestTimeout(35000)// 设置连接请求超时时间
.setSocketTimeout(60000)// 设置读取数据连接超时时间
.build();
// 为httpPost实例设置配置
httpPost.setConfig(requestConfig);
// 设置请求头
if (null != headers && headers.size() > 0) {
Set<Entry<String, String>> entrySet = headers.entrySet();
// 循环遍历获取迭代器
Iterator<Entry<String, String>> iterator = entrySet.iterator();
while (iterator.hasNext()) {
Entry<String, String> mapEntry = iterator.next();
_logger.trace("Name " + mapEntry.getKey() + " , Value " +mapEntry.getValue());
httpPost.addHeader(mapEntry.getKey(), mapEntry.getValue());
}
}
// 封装post请求参数
StringEntity stringEntity =new StringEntity(jsonString, "UTF-8");
stringEntity.setContentType("application/json");
httpPost.setEntity(stringEntity);
try {
// httpClient对象执行post请求,并返回响应参数对象
httpResponse = httpClient.execute(httpPost);
// 从响应对象中获取响应内容
HttpEntity entity = httpResponse.getEntity();
String content = EntityUtils.toString(entity);
_logger.debug("Http Response StatusCode {} , Content {}",
httpResponse.getStatusLine().getStatusCode(),
content
);
return content;
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭资源
if (null != httpResponse) {
try {
httpResponse.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != httpClient) {
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
public String get(String url) { public String get(String url) {
HashMap<String,String> headers = new HashMap<String,String>(); HashMap<String,String> headers = new HashMap<String,String>();

View File

@ -0,0 +1,33 @@
/*
* 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.Connectors;
/**
* @author Crystal.sea
*
*/
public interface ConnectorsMapper extends IJpaBaseMapper<Connectors> {
}

View File

@ -71,7 +71,7 @@ public class AccountsService extends JpaBaseService<Accounts>{
public boolean insert(Accounts account) { public boolean insert(Accounts account) {
if (super.insert(account)) { if (super.insert(account)) {
if(mqPersistService.getApplicationConfig().isMessageQueueSupport()) { if(mqPersistService.getApplicationConfig().isProvisionSupport()) {
UserInfo loadUserInfo = userInfoService.findUserRelated(account.getUserId()); UserInfo loadUserInfo = userInfoService.findUserRelated(account.getUserId());
account.setUserInfo(loadUserInfo); account.setUserInfo(loadUserInfo);
OrganizationsCast cast = new OrganizationsCast(); OrganizationsCast cast = new OrganizationsCast();
@ -91,7 +91,7 @@ public class AccountsService extends JpaBaseService<Accounts>{
public boolean update(Accounts account) { public boolean update(Accounts account) {
if (super.update(account)) { if (super.update(account)) {
if(mqPersistService.getApplicationConfig().isMessageQueueSupport()) { if(mqPersistService.getApplicationConfig().isProvisionSupport()) {
UserInfo loadUserInfo = userInfoService.findUserRelated(account.getUserId()); UserInfo loadUserInfo = userInfoService.findUserRelated(account.getUserId());
account.setUserInfo(loadUserInfo); account.setUserInfo(loadUserInfo);
OrganizationsCast cast = new OrganizationsCast(); OrganizationsCast cast = new OrganizationsCast();
@ -116,7 +116,7 @@ public class AccountsService extends JpaBaseService<Accounts>{
Accounts account = this.get(id); Accounts account = this.get(id);
if (super.remove(id)) { if (super.remove(id)) {
UserInfo loadUserInfo = null; UserInfo loadUserInfo = null;
if(mqPersistService.getApplicationConfig().isMessageQueueSupport()) { if(mqPersistService.getApplicationConfig().isProvisionSupport()) {
loadUserInfo = userInfoService.findUserRelated(account.getUserId()); loadUserInfo = userInfoService.findUserRelated(account.getUserId());
account.setUserInfo(loadUserInfo); account.setUserInfo(loadUserInfo);
mqPersistService.send( mqPersistService.send(

View File

@ -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.Connectors;
import org.maxkey.persistence.mapper.ConnectorsMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Repository;
@Repository
public class ConnectorsService extends JpaBaseService<Connectors>{
final static Logger _logger = LoggerFactory.getLogger(ConnectorsService.class);
public ConnectorsService() {
super(ConnectorsMapper.class);
}
/* (non-Javadoc)
* @see com.connsec.db.service.BaseService#getMapper()
*/
@Override
public ConnectorsMapper getMapper() {
return (ConnectorsMapper)super.getMapper();
}
}

View File

@ -75,7 +75,7 @@ public class UserInfoService extends JpaBaseService<UserInfo> {
public boolean insert(UserInfo userInfo) { public boolean insert(UserInfo userInfo) {
this.passwordEncoder(userInfo); this.passwordEncoder(userInfo);
if (super.insert(userInfo)) { if (super.insert(userInfo)) {
if(messageQueueService.getApplicationConfig().isMessageQueueSupport()) { if(messageQueueService.getApplicationConfig().isProvisionSupport()) {
UserInfo loadUserInfo = findUserRelated(userInfo.getId()); UserInfo loadUserInfo = findUserRelated(userInfo.getId());
messageQueueService.send( messageQueueService.send(
ProvisionTopic.USERINFO_TOPIC, ProvisionTopic.USERINFO_TOPIC,
@ -92,7 +92,7 @@ public class UserInfoService extends JpaBaseService<UserInfo> {
public boolean update(UserInfo userInfo) { public boolean update(UserInfo userInfo) {
ChangePassword changePassword = this.passwordEncoder(userInfo); ChangePassword changePassword = this.passwordEncoder(userInfo);
if (super.update(userInfo)) { if (super.update(userInfo)) {
if(messageQueueService.getApplicationConfig().isMessageQueueSupport()) { if(messageQueueService.getApplicationConfig().isProvisionSupport()) {
UserInfo loadUserInfo = findUserRelated(userInfo.getId()); UserInfo loadUserInfo = findUserRelated(userInfo.getId());
accountUpdate(loadUserInfo); accountUpdate(loadUserInfo);
messageQueueService.send( messageQueueService.send(
@ -110,7 +110,7 @@ public class UserInfoService extends JpaBaseService<UserInfo> {
public boolean delete(UserInfo userInfo) { public boolean delete(UserInfo userInfo) {
UserInfo loadUserInfo = null; UserInfo loadUserInfo = null;
if(messageQueueService.getApplicationConfig().isMessageQueueSupport()) { if(messageQueueService.getApplicationConfig().isProvisionSupport()) {
loadUserInfo = findUserRelated(userInfo.getId()); loadUserInfo = findUserRelated(userInfo.getId());
} }

View File

@ -25,6 +25,7 @@ public class ProvisionMessage {
String sendTime; String sendTime;
String content; String content;
int connected; int connected;
int instId;
Object sourceObject; Object sourceObject;
@ -60,7 +61,7 @@ public class ProvisionMessage {
this.id = id; this.id = id;
} }
public Object getContent() { public String getContent() {
return content; return content;
} }
@ -84,6 +85,14 @@ public class ProvisionMessage {
this.sourceObject = sourceObject; this.sourceObject = sourceObject;
} }
public int getInstId() {
return instId;
}
public void setInstId(int instId) {
this.instId = instId;
}
public ProvisionMessage() { public ProvisionMessage() {
} }

View File

@ -46,7 +46,7 @@ public class ProvisionService {
*/ */
public void send(String topic,Object content,String actionType) { public void send(String topic,Object content,String actionType) {
//maxkey.server.message.queue , if not none //maxkey.server.message.queue , if not none
if(applicationConfig.isMessageQueueSupport()) { if(applicationConfig.isProvisionSupport()) {
ProvisionMessage message = ProvisionMessage message =
new ProvisionMessage( new ProvisionMessage(
UUID.randomUUID().toString(), //message id as uuid UUID.randomUUID().toString(), //message id as uuid
@ -58,7 +58,7 @@ public class ProvisionService {
); );
//sand msg to provision topic //sand msg to provision topic
Thread thread = null; Thread thread = null;
if(applicationConfig.getMessageQueue().equalsIgnoreCase("provision")) { if(applicationConfig.isProvisionSupport()) {
_logger.trace("message..."); _logger.trace("message...");
thread = new ProvisioningThread(jdbcTemplate,message); thread = new ProvisioningThread(jdbcTemplate,message);
thread.start(); thread.start();

View File

@ -0,0 +1,205 @@
package org.maxkey.provision.thread;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import org.apache.mybatis.jpa.query.Query;
import org.maxkey.crypto.password.PasswordReciprocal;
import org.maxkey.entity.ChangePassword;
import org.maxkey.entity.Connectors;
import org.maxkey.entity.Message;
import org.maxkey.entity.Organizations;
import org.maxkey.entity.UserInfo;
import org.maxkey.persistence.service.ConnectorsService;
import org.maxkey.provision.ProvisionAction;
import org.maxkey.provision.ProvisionMessage;
import org.maxkey.provision.ProvisionTopic;
import org.maxkey.util.AuthorizationHeaderUtils;
import org.maxkey.util.DateUtils;
import org.maxkey.util.JsonUtils;
import org.maxkey.util.ObjectTransformer;
import org.maxkey.web.HttpRequestAdapter;
import org.maxkey.web.WebContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
public class ProvisioningRunner {
private static final Logger _logger = LoggerFactory.getLogger(ProvisioningRunner.class);
static final String PROVISION_SELECT_STATEMENT = "select * from mxk_history_provisions where connected = 0 order by sendtime asc limit 500";
static final String PROVISION_UPDATE_STATEMENT = "update mxk_history_provisions set connected = connected + 1 where id = ?";
static final String PROVISION_LOG_INSERT_STATEMENT = "insert into mxk_history_connector(id,conname,topic,actiontype,sourceid,sourcename,synctime,result,instid) values (? , ? , ? , ? , ? , ? , ? , ? , ? )";
JdbcTemplate jdbcTemplate;
ConnectorsService connectorsService;
public ProvisioningRunner(ConnectorsService connectorsService,JdbcTemplate jdbcTemplate) {
this.connectorsService = connectorsService;
this.jdbcTemplate = jdbcTemplate;
}
public void provisions() {
List<Connectors> listConnectors = connectorsService.query(new Query().eq("status", 1).eq("justintime", 1));
List<ProvisionMessage> listProvisionMessage = jdbcTemplate.query(PROVISION_SELECT_STATEMENT, new ProvisionMessageRowMapper());
for(ProvisionMessage msg : listProvisionMessage) {
for(Connectors connector: listConnectors) {
provision(msg,connector);
}
}
}
public void provision(ProvisionMessage provisionMessage,Connectors connector) {
if(Integer.parseInt(connector.getInstId()) == provisionMessage.getInstId()) {
String url = connector.getProviderUrl();
if(!url.endsWith("/")) {
url = url + "/";
}
String resultMessage = "";
String objectId = "";
String objectName = "";
if(provisionMessage.getTopic().equalsIgnoreCase(ProvisionTopic.USERINFO_TOPIC)) {
UserInfo user = (UserInfo)ObjectTransformer.deserialize(provisionMessage.getContent());
user.setPassword(null);
user.setDecipherable(null);
objectId = user.getId();
objectName = user.getDisplayName()+"("+user.getUsername()+")";
resultMessage = provisionUser(user,url,provisionMessage.getActionType(),connector);
provisionLog( connector.getConnName(),
"Users",
provisionMessage.getActionType(),
objectId,
objectName,
resultMessage,
provisionMessage.getInstId()
);
}else if(provisionMessage.getTopic().equalsIgnoreCase(ProvisionTopic.PASSWORD_TOPIC)) {
ChangePassword changePassword = (ChangePassword)ObjectTransformer.deserialize(provisionMessage.getContent());
objectId = changePassword.getUserId();
objectName = changePassword.getDisplayName()+"("+changePassword.getUsername()+")";
resultMessage = provisionChangePassword(changePassword,url,provisionMessage.getActionType(),connector);
provisionLog( connector.getConnName(),
"Password",
provisionMessage.getActionType(),
objectId,
objectName,
resultMessage,
provisionMessage.getInstId()
);
}else if(provisionMessage.getTopic().equalsIgnoreCase(ProvisionTopic.ORG_TOPIC)) {
Organizations organization = (Organizations)ObjectTransformer.deserialize(provisionMessage.getContent());
objectId = organization.getId();
objectName = organization.getOrgName();
resultMessage = provisionOrganization(organization,url,provisionMessage.getActionType(),connector);
provisionLog( connector.getConnName(),
"Organizations",
provisionMessage.getActionType(),
objectId,
objectName,
resultMessage,
provisionMessage.getInstId()
);
}
jdbcTemplate.update(PROVISION_UPDATE_STATEMENT,provisionMessage.getId());
}
}
public void provisionLog(String conName,String topic,String actionType,String sourceId,String sourceName,String resultMessage,int instid) {
Message<?> resultMsg = JsonUtils.json2Object(resultMessage, Message.class);
String result = "success";
if(resultMsg == null || resultMsg.getCode() != 0) {
result = "fail";
}
jdbcTemplate.update(PROVISION_LOG_INSERT_STATEMENT,
WebContext.genId(),
conName,
topic,
actionType.replace("_ACTION", "").toLowerCase(),
sourceId,
sourceName,
DateUtils.getCurrentDateTimeAsString(),
result,
instid
);
}
public String getActionType(String actionType) {
if(actionType.equalsIgnoreCase(ProvisionAction.CREATE_ACTION)) {
return "create";
}else if(actionType.equalsIgnoreCase(ProvisionAction.UPDATE_ACTION)) {
return "update";
}else if(actionType.equalsIgnoreCase(ProvisionAction.DELETE_ACTION)) {
return "delete";
}
return "";
}
String provisionUser(UserInfo user,String baseUrl,String actionType,Connectors connector){
baseUrl = baseUrl + "Users/" + getActionType(actionType);
_logger.debug("URL {} ", baseUrl);
HashMap<String,String> authorizationMap = AuthorizationHeaderUtils.authorization(
AuthorizationHeaderUtils.createBasic(
connector.getPrincipal(),
PasswordReciprocal.getInstance().decoder(connector.getCredentials()))
);
return new HttpRequestAdapter().postJson( baseUrl,
JsonUtils.gson2Json(user),
authorizationMap
);
}
String provisionOrganization(Organizations organizations,String baseUrl,String actionType,Connectors connector){
baseUrl = baseUrl + "Organizations/"+ getActionType(actionType);
_logger.debug("URL {} ", baseUrl);
HashMap<String,String> authorizationMap = AuthorizationHeaderUtils.authorization(
AuthorizationHeaderUtils.createBasic(
connector.getPrincipal(),
PasswordReciprocal.getInstance().decoder(connector.getCredentials()))
);
return new HttpRequestAdapter().postJson( baseUrl,
JsonUtils.gson2Json(organizations),
authorizationMap
);
}
String provisionChangePassword(ChangePassword changePassword,String baseUrl,String actionType,Connectors connector){
baseUrl = baseUrl + "Users/changePassword";
_logger.debug("URL {} ", baseUrl);
HashMap<String,String> authorizationMap = AuthorizationHeaderUtils.authorization(
AuthorizationHeaderUtils.createBasic(
connector.getPrincipal(),
PasswordReciprocal.getInstance().decoder(connector.getCredentials()))
);
return new HttpRequestAdapter().postJson( baseUrl,
JsonUtils.gson2Json(changePassword),
authorizationMap
);
}
public class ProvisionMessageRowMapper implements RowMapper<ProvisionMessage> {
@Override
public ProvisionMessage mapRow(ResultSet rs, int rowNum) throws SQLException {
ProvisionMessage msg = new ProvisionMessage();
msg.setId(rs.getString("id"));
msg.setActionType(rs.getString("actiontype"));
msg.setTopic(rs.getString("topic"));
msg.setContent(rs.getString("content"));
msg.setConnected(rs.getInt("connected"));
msg.setInstId(rs.getInt("instid"));
return msg;
}
}
}

View File

@ -0,0 +1,23 @@
package org.maxkey.provision.thread;
public class ProvisioningRunnerThread extends Thread{
ProvisioningRunner runner;
public ProvisioningRunnerThread(ProvisioningRunner runner) {
super();
this.runner = runner;
}
@Override
public void run() {
while(true) {
try {
Thread.sleep(60 * 1000);
runner.provisions();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

View File

@ -21,6 +21,7 @@ import java.sql.Types;
import org.maxkey.pretty.impl.JsonPretty; import org.maxkey.pretty.impl.JsonPretty;
import org.maxkey.provision.ProvisionMessage; import org.maxkey.provision.ProvisionMessage;
import org.maxkey.util.JsonUtils;
import org.maxkey.util.ObjectTransformer; import org.maxkey.util.ObjectTransformer;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -33,7 +34,7 @@ import org.springframework.jdbc.core.JdbcTemplate;
public class ProvisioningThread extends Thread{ public class ProvisioningThread extends Thread{
private static final Logger _logger = LoggerFactory.getLogger(ProvisioningThread.class); private static final Logger _logger = LoggerFactory.getLogger(ProvisioningThread.class);
static final String PROVISION_INSERT_STATEMENT = "insert into mxk_history_provisions(`id`,`topic`,`actiontype`,`content`,`sendtime`,`connected`) values (? , ? , ? , ? , ? , ? )"; static final String PROVISION_INSERT_STATEMENT = "insert into mxk_history_provisions(id,topic,actiontype,content,sendtime,connected,instid) values (? , ? , ? , ? , ? , ? , ? )";
JdbcTemplate jdbcTemplate; JdbcTemplate jdbcTemplate;
@ -49,15 +50,31 @@ public class ProvisioningThread extends Thread{
public void run() { public void run() {
_logger.debug("send message \n{}" ,new JsonPretty().jacksonFormat(msg.getSourceObject())); _logger.debug("send message \n{}" ,new JsonPretty().jacksonFormat(msg.getSourceObject()));
msg.setContent(ObjectTransformer.serialize((Serializable)msg.getSourceObject())); msg.setContent(ObjectTransformer.serialize((Serializable)msg.getSourceObject()));
Inst inst = JsonUtils.gson2Object(JsonUtils.gson2Json(msg.getSourceObject()), Inst.class);
jdbcTemplate.update(PROVISION_INSERT_STATEMENT, jdbcTemplate.update(PROVISION_INSERT_STATEMENT,
new Object[] { new Object[] {
msg.getId(), msg.getTopic(), msg.getActionType(), msg.getContent(), msg.getId(), msg.getTopic(), msg.getActionType(), msg.getContent(),
msg.getSendTime(),msg.getConnected() msg.getSendTime(),msg.getConnected(),inst.getInstId()
}, },
new int[] { new int[] {
Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,
Types.TINYINT Types.TINYINT,Types.TINYINT
}); });
_logger.debug("send to Message Queue finished ."); _logger.debug("send to Message Queue finished .");
} }
class Inst{
int instId;
public int getInstId() {
return instId;
}
public void setInstId(int instId) {
this.instId = instId;
}
public Inst() {}
}
} }

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.maxkey.persistence.mapper.ConnectorsMapper">
<sql id="where_statement">
<if test="id != null and id != ''">
and id = #{id}
</if>
<if test="connName != null and connName != ''">
and connname like '%${connName}%'
</if>
</sql>
<select id="queryPageResults" parameterType="Connectors" resultType="Connectors">
select
*
from
mxk_connectors
where
instid = #{instId}
<include refid="where_statement"/>
</select>
</mapper>

View File

@ -11,10 +11,6 @@
and conName = #{conName} and conName = #{conName}
</if> </if>
<if test="conType != null and conType != ''">
and conType = #{conType}
</if>
<if test="sourceId != null and sourceId != ''"> <if test="sourceId != null and sourceId != ''">
and sourceId = #{sourceId} and sourceId = #{sourceId}
</if> </if>

View File

@ -0,0 +1,66 @@
/*
* 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.
*/
import format from 'date-fns/format';
import { BaseEntity } from './BaseEntity';
export class Connectors extends BaseEntity {
connName!: String;
justInTime!: Number;
filters!: String;
scheduler!: String;
providerUrl!: String;
principal!: String;
credentials!: String;
switch_justInTime: boolean = true;
constructor() {
super();
this.status = 1;
this.justInTime = 1;
}
override init(data: any): void {
Object.assign(this, data);
if (this.status == 1) {
this.switch_status = true;
} else {
this.switch_status = false;
}
if (this.justInTime == 1) {
this.switch_justInTime = true;
} else {
this.switch_justInTime = false;
}
}
override trans(): void {
if (this.switch_status) {
this.status = 1;
} else {
this.status = 0;
}
if (this.switch_justInTime) {
this.justInTime = 1;
} else {
this.justInTime = 0;
}
}
}

View File

@ -5,23 +5,19 @@
<div nz-row [nzGutter]="{ xs: 8, sm: 8, md: 8, lg: 24, xl: 48, xxl: 48 }"> <div nz-row [nzGutter]="{ xs: 8, sm: 8, md: 8, lg: 24, xl: 48, xxl: 48 }">
<div nz-col nzMd="8" nzSm="24"> <div nz-col nzMd="8" nzSm="24">
<nz-form-item> <nz-form-item>
<nz-form-label nzFor="username">{{ 'mxk.users.username' | i18n }}</nz-form-label> <nz-form-label nzFor="conName">{{ 'mxk.history.connector.conName' | i18n }}</nz-form-label>
<nz-form-control> <nz-form-control>
<input nz-input [(ngModel)]="query.params.username" [ngModelOptions]="{ standalone: true }" name="username" id="username" /> <input nz-input [(ngModel)]="query.params.conName" [ngModelOptions]="{ standalone: true }" name="conName"
id="conName" />
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
</div> </div>
<div nz-col nzMd="8" nzSm="24"> <div nz-col nzMd="8" nzSm="24">
<nz-form-item> <nz-form-item>
<nz-form-label nzFor="displayName">{{ 'mxk.users.displayName' | i18n }}</nz-form-label> <nz-form-label nzFor="sourceName">{{ 'mxk.history.connector.sourceName' | i18n }}</nz-form-label>
<nz-form-control> <nz-form-control>
<input <input nz-input [(ngModel)]="query.params.sourceName" [ngModelOptions]="{ standalone: true }"
nz-input id="sourceName" name="sourceName" />
[(ngModel)]="query.params.displayName"
[ngModelOptions]="{ standalone: true }"
id="displayName"
name="displayName"
/>
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
</div> </div>
@ -29,13 +25,8 @@
<nz-form-item> <nz-form-item>
<nz-form-label nzFor="employeeNumber">{{ 'mxk.users.employeeNumber' | i18n }}</nz-form-label> <nz-form-label nzFor="employeeNumber">{{ 'mxk.users.employeeNumber' | i18n }}</nz-form-label>
<nz-form-control> <nz-form-control>
<input <input nz-input [(ngModel)]="query.params.employeeNumber" [ngModelOptions]="{ standalone: true }"
nz-input id="employeeNumber" name="employeeNumber" />
[(ngModel)]="query.params.employeeNumber"
[ngModelOptions]="{ standalone: true }"
id="employeeNumber"
name="employeeNumber"
/>
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
</div> </div>
@ -43,14 +34,9 @@
<nz-form-item> <nz-form-item>
<nz-form-label nzFor="startDatePicker">{{ 'mxk.text.startDate' | i18n }}</nz-form-label> <nz-form-label nzFor="startDatePicker">{{ 'mxk.text.startDate' | i18n }}</nz-form-label>
<nz-form-control> <nz-form-control>
<nz-date-picker <nz-date-picker nzShowTime nzFormat="yyyy-MM-dd HH:mm:ss" [(ngModel)]="query.params.startDatePicker"
nzShowTime [ngModelOptions]="{ standalone: true }" name="startDatePicker" nzPlaceHolder="startDatePicker">
nzFormat="yyyy-MM-dd HH:mm:ss" </nz-date-picker>
[(ngModel)]="query.params.startDatePicker"
[ngModelOptions]="{ standalone: true }"
name="startDatePicker"
nzPlaceHolder="startDatePicker"
></nz-date-picker>
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
</div> </div>
@ -58,54 +44,37 @@
<nz-form-item> <nz-form-item>
<nz-form-label nzFor="endDatePicker">{{ 'mxk.text.endDate' | i18n }}</nz-form-label> <nz-form-label nzFor="endDatePicker">{{ 'mxk.text.endDate' | i18n }}</nz-form-label>
<nz-form-control> <nz-form-control>
<nz-date-picker <nz-date-picker nzShowTime nzFormat="yyyy-MM-dd HH:mm:ss" [(ngModel)]="query.params.endDatePicker"
nzShowTime [ngModelOptions]="{ standalone: true }" name="endDatePicker" nzPlaceHolder="endDatePicker">
nzFormat="yyyy-MM-dd HH:mm:ss" </nz-date-picker>
[(ngModel)]="query.params.endDatePicker"
[ngModelOptions]="{ standalone: true }"
name="endDatePicker"
nzPlaceHolder="endDatePicker"
></nz-date-picker>
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
</div> </div>
<div nz-col [nzSpan]="query.expandForm ? 24 : 8" [class.text-right]="query.expandForm"> <div nz-col [nzSpan]="query.expandForm ? 24 : 8" [class.text-right]="query.expandForm">
<button nz-button type="submit" [nzType]="'primary'" [nzLoading]="query.submitLoading">{{ 'mxk.text.query' | i18n }}</button> <button nz-button type="submit" [nzType]="'primary'" [nzLoading]="query.submitLoading">{{ 'mxk.text.query' |
i18n }}</button>
<button nz-button type="reset" (click)="onReset()" class="mx-sm">{{ 'mxk.text.reset' | i18n }}</button> <button nz-button type="reset" (click)="onReset()" class="mx-sm">{{ 'mxk.text.reset' | i18n }}</button>
<button nz-button (click)="query.expandForm = !query.expandForm" class="mx-sm"> <button nz-button (click)="query.expandForm = !query.expandForm" class="mx-sm">
{{ query.expandForm ? ('mxk.text.collapse' | i18n) : ('mxk.text.expand' | i18n) }}</button {{ query.expandForm ? ('mxk.text.collapse' | i18n) : ('mxk.text.expand' | i18n) }}</button>
>
</div> </div>
</div> </div>
</form> </form>
</nz-card> </nz-card>
<nz-card> <nz-card>
<nz-table <nz-table #dynamicTable nzTableLayout="auto" nzSize="small" nzShowSizeChanger [nzBordered]="true"
#dynamicTable [nzData]="query.results.rows" [nzFrontPagination]="false" [nzTotal]="query.results.records"
nzTableLayout="auto" [nzPageSizeOptions]="query.params.pageSizeOptions" [nzPageSize]="query.params.pageSize"
nzSize="small" [nzPageIndex]="query.params.pageNumber" [nzLoading]="this.query.tableLoading"
nzShowSizeChanger (nzQueryParams)="onQueryParamsChange($event)">
[nzBordered]="true"
[nzData]="query.results.rows"
[nzFrontPagination]="false"
[nzTotal]="query.results.records"
[nzPageSizeOptions]="query.params.pageSizeOptions"
[nzPageSize]="query.params.pageSize"
[nzPageIndex]="query.params.pageNumber"
[nzLoading]="this.query.tableLoading"
(nzQueryParams)="onQueryParamsChange($event)"
[nzScroll]="{ x: '100%', y: '100%' }"
>
<thead> <thead>
<tr> <tr>
<th nzAlign="center">{{ 'mxk.history.connector.id' | i18n }}</th> <th nzAlign="center">{{ 'mxk.history.connector.id' | i18n }}</th>
<th nzAlign="center">{{ 'mxk.history.connector.conName' | i18n }}</th> <th nzAlign="center">{{ 'mxk.history.connector.conName' | i18n }}</th>
<th nzAlign="center">{{ 'mxk.history.connector.conType' | i18n }}</th> <th nzAlign="center">{{ 'mxk.history.connector.topic' | i18n }}</th>
<th nzAlign="center">{{ 'mxk.history.connector.actionType' | i18n }}</th>
<th nzAlign="center">{{ 'mxk.history.connector.sourceId' | i18n }}</th> <th nzAlign="center">{{ 'mxk.history.connector.sourceId' | i18n }}</th>
<th nzAlign="center">{{ 'mxk.history.connector.sourceName' | i18n }}</th> <th nzAlign="center">{{ 'mxk.history.connector.sourceName' | i18n }}</th>
<th nzAlign="center">{{ 'mxk.history.connector.objectId' | i18n }}</th>
<th nzAlign="center">{{ 'mxk.history.connector.objectName' | i18n }}</th>
<th nzAlign="center">{{ 'mxk.history.connector.syncTime' | i18n }}</th> <th nzAlign="center">{{ 'mxk.history.connector.syncTime' | i18n }}</th>
<th nzAlign="center">{{ 'mxk.history.connector.result' | i18n }}</th> <th nzAlign="center">{{ 'mxk.history.connector.result' | i18n }}</th>
</tr> </tr>
@ -116,11 +85,10 @@
<span>{{ data.id }}</span> <span>{{ data.id }}</span>
</td> </td>
<td nzAlign="left">{{ data.conName }}</td> <td nzAlign="left">{{ data.conName }}</td>
<td nzAlign="left">{{ data.conType }}</td> <td nzAlign="left">{{ data.topic }}</td>
<td nzAlign="left">{{ data.actionType }}</td>
<td nzAlign="left">{{ data.sourceId }}</td> <td nzAlign="left">{{ data.sourceId }}</td>
<td nzAlign="left">{{ data.syncName }}</td>
<td nzAlign="left">{{ data.sourceName }}</td> <td nzAlign="left">{{ data.sourceName }}</td>
<td nzAlign="left">{{ data.objectName }}</td>
<td nzAlign="left">{{ data.syncTime }}</td> <td nzAlign="left">{{ data.syncTime }}</td>
<td nzAlign="left">{{ data.result }}</td> <td nzAlign="left">{{ data.result }}</td>
</tr> </tr>

View File

@ -14,7 +14,6 @@
* limitations under the License. * limitations under the License.
*/ */
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@angular/core'; import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { _HttpClient } from '@delon/theme'; import { _HttpClient } from '@delon/theme';
@ -33,8 +32,8 @@ import { HistoryService } from '../../../service/history.service';
export class AuditConnectorComponent implements OnInit { export class AuditConnectorComponent implements OnInit {
query: { query: {
params: { params: {
username: String; conName: String;
displayName: String; sourceName: String;
employeeNumber: String; employeeNumber: String;
startDate: String; startDate: String;
endDate: String; endDate: String;
@ -53,8 +52,8 @@ export class AuditConnectorComponent implements OnInit {
tableLoading: boolean; tableLoading: boolean;
} = { } = {
params: { params: {
username: '', conName: '',
displayName: '', sourceName: '',
employeeNumber: '', employeeNumber: '',
startDate: '', startDate: '',
endDate: '', endDate: '',

View File

@ -7,7 +7,8 @@
<nz-form-item> <nz-form-item>
<nz-form-label nzFor="username">{{ 'mxk.users.username' | i18n }}</nz-form-label> <nz-form-label nzFor="username">{{ 'mxk.users.username' | i18n }}</nz-form-label>
<nz-form-control> <nz-form-control>
<input nz-input [(ngModel)]="query.params.username" [ngModelOptions]="{ standalone: true }" name="username" id="username" /> <input nz-input [(ngModel)]="query.params.username" [ngModelOptions]="{ standalone: true }" name="username"
id="username" />
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
</div> </div>
@ -15,13 +16,8 @@
<nz-form-item> <nz-form-item>
<nz-form-label nzFor="displayName">{{ 'mxk.users.displayName' | i18n }}</nz-form-label> <nz-form-label nzFor="displayName">{{ 'mxk.users.displayName' | i18n }}</nz-form-label>
<nz-form-control> <nz-form-control>
<input <input nz-input [(ngModel)]="query.params.displayName" [ngModelOptions]="{ standalone: true }"
nz-input id="displayName" name="displayName" />
[(ngModel)]="query.params.displayName"
[ngModelOptions]="{ standalone: true }"
id="displayName"
name="displayName"
/>
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
</div> </div>
@ -29,13 +25,8 @@
<nz-form-item> <nz-form-item>
<nz-form-label nzFor="employeeNumber">{{ 'mxk.users.employeeNumber' | i18n }}</nz-form-label> <nz-form-label nzFor="employeeNumber">{{ 'mxk.users.employeeNumber' | i18n }}</nz-form-label>
<nz-form-control> <nz-form-control>
<input <input nz-input [(ngModel)]="query.params.employeeNumber" [ngModelOptions]="{ standalone: true }"
nz-input id="employeeNumber" name="employeeNumber" />
[(ngModel)]="query.params.employeeNumber"
[ngModelOptions]="{ standalone: true }"
id="employeeNumber"
name="employeeNumber"
/>
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
</div> </div>
@ -43,14 +34,9 @@
<nz-form-item> <nz-form-item>
<nz-form-label nzFor="startDatePicker">{{ 'mxk.text.startDate' | i18n }}</nz-form-label> <nz-form-label nzFor="startDatePicker">{{ 'mxk.text.startDate' | i18n }}</nz-form-label>
<nz-form-control> <nz-form-control>
<nz-date-picker <nz-date-picker nzShowTime nzFormat="yyyy-MM-dd HH:mm:ss" [(ngModel)]="query.params.startDatePicker"
nzShowTime [ngModelOptions]="{ standalone: true }" name="startDatePicker" nzPlaceHolder="startDatePicker">
nzFormat="yyyy-MM-dd HH:mm:ss" </nz-date-picker>
[(ngModel)]="query.params.startDatePicker"
[ngModelOptions]="{ standalone: true }"
name="startDatePicker"
nzPlaceHolder="startDatePicker"
></nz-date-picker>
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
</div> </div>
@ -58,45 +44,29 @@
<nz-form-item> <nz-form-item>
<nz-form-label nzFor="endDatePicker">{{ 'mxk.text.endDate' | i18n }}</nz-form-label> <nz-form-label nzFor="endDatePicker">{{ 'mxk.text.endDate' | i18n }}</nz-form-label>
<nz-form-control> <nz-form-control>
<nz-date-picker <nz-date-picker nzShowTime nzFormat="yyyy-MM-dd HH:mm:ss" [(ngModel)]="query.params.endDatePicker"
nzShowTime [ngModelOptions]="{ standalone: true }" name="endDatePicker" nzPlaceHolder="endDatePicker">
nzFormat="yyyy-MM-dd HH:mm:ss" </nz-date-picker>
[(ngModel)]="query.params.endDatePicker"
[ngModelOptions]="{ standalone: true }"
name="endDatePicker"
nzPlaceHolder="endDatePicker"
></nz-date-picker>
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
</div> </div>
<div nz-col [nzSpan]="query.expandForm ? 24 : 8" [class.text-right]="query.expandForm"> <div nz-col [nzSpan]="query.expandForm ? 24 : 8" [class.text-right]="query.expandForm">
<button nz-button type="submit" [nzType]="'primary'" [nzLoading]="query.submitLoading">{{ 'mxk.text.query' | i18n }}</button> <button nz-button type="submit" [nzType]="'primary'" [nzLoading]="query.submitLoading">{{ 'mxk.text.query' |
i18n }}</button>
<button nz-button type="reset" (click)="onReset()" class="mx-sm">{{ 'mxk.text.reset' | i18n }}</button> <button nz-button type="reset" (click)="onReset()" class="mx-sm">{{ 'mxk.text.reset' | i18n }}</button>
<button nz-button (click)="query.expandForm = !query.expandForm" class="mx-sm"> <button nz-button (click)="query.expandForm = !query.expandForm" class="mx-sm">
{{ query.expandForm ? ('mxk.text.collapse' | i18n) : ('mxk.text.expand' | i18n) }}</button {{ query.expandForm ? ('mxk.text.collapse' | i18n) : ('mxk.text.expand' | i18n) }}</button>
>
</div> </div>
</div> </div>
</form> </form>
</nz-card> </nz-card>
<nz-card> <nz-card>
<nz-table <nz-table #dynamicTable nzTableLayout="auto" nzSize="small" nzShowSizeChanger [nzBordered]="true"
#dynamicTable [nzData]="query.results.rows" [nzFrontPagination]="false" [nzTotal]="query.results.records"
nzTableLayout="auto" [nzPageSizeOptions]="query.params.pageSizeOptions" [nzPageSize]="query.params.pageSize"
nzSize="small" [nzPageIndex]="query.params.pageNumber" [nzLoading]="this.query.tableLoading"
nzShowSizeChanger (nzQueryParams)="onQueryParamsChange($event)">
[nzBordered]="true"
[nzData]="query.results.rows"
[nzFrontPagination]="false"
[nzTotal]="query.results.records"
[nzPageSizeOptions]="query.params.pageSizeOptions"
[nzPageSize]="query.params.pageSize"
[nzPageIndex]="query.params.pageNumber"
[nzLoading]="this.query.tableLoading"
(nzQueryParams)="onQueryParamsChange($event)"
[nzScroll]="{ x: '100%', y: '100%' }"
>
<thead> <thead>
<tr> <tr>
<th nzAlign="center">{{ 'mxk.history.login.sessionId' | i18n }}</th> <th nzAlign="center">{{ 'mxk.history.login.sessionId' | i18n }}</th>

View File

@ -5,23 +5,19 @@
<div nz-row [nzGutter]="{ xs: 8, sm: 8, md: 8, lg: 24, xl: 48, xxl: 48 }"> <div nz-row [nzGutter]="{ xs: 8, sm: 8, md: 8, lg: 24, xl: 48, xxl: 48 }">
<div nz-col nzMd="8" nzSm="24"> <div nz-col nzMd="8" nzSm="24">
<nz-form-item> <nz-form-item>
<nz-form-label nzFor="username">{{ 'mxk.users.username' | i18n }}</nz-form-label> <nz-form-label nzFor="syncName">{{ 'mxk.history.synchronizer.syncName' | i18n }}</nz-form-label>
<nz-form-control> <nz-form-control>
<input nz-input [(ngModel)]="query.params.username" [ngModelOptions]="{ standalone: true }" name="username" id="username" /> <input nz-input [(ngModel)]="query.params.syncName" [ngModelOptions]="{ standalone: true }" name="syncName"
id="syncName" />
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
</div> </div>
<div nz-col nzMd="8" nzSm="24"> <div nz-col nzMd="8" nzSm="24">
<nz-form-item> <nz-form-item>
<nz-form-label nzFor="displayName">{{ 'mxk.users.displayName' | i18n }}</nz-form-label> <nz-form-label nzFor="objectName">{{ 'mxk.history.synchronizer.objectName' | i18n }}</nz-form-label>
<nz-form-control> <nz-form-control>
<input <input nz-input [(ngModel)]="query.params.objectName" [ngModelOptions]="{ standalone: true }"
nz-input id="objectName" name="objectName" />
[(ngModel)]="query.params.displayName"
[ngModelOptions]="{ standalone: true }"
id="displayName"
name="displayName"
/>
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
</div> </div>
@ -29,13 +25,8 @@
<nz-form-item> <nz-form-item>
<nz-form-label nzFor="employeeNumber">{{ 'mxk.users.employeeNumber' | i18n }}</nz-form-label> <nz-form-label nzFor="employeeNumber">{{ 'mxk.users.employeeNumber' | i18n }}</nz-form-label>
<nz-form-control> <nz-form-control>
<input <input nz-input [(ngModel)]="query.params.employeeNumber" [ngModelOptions]="{ standalone: true }"
nz-input id="employeeNumber" name="employeeNumber" />
[(ngModel)]="query.params.employeeNumber"
[ngModelOptions]="{ standalone: true }"
id="employeeNumber"
name="employeeNumber"
/>
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
</div> </div>
@ -43,14 +34,9 @@
<nz-form-item> <nz-form-item>
<nz-form-label nzFor="startDatePicker">{{ 'mxk.text.startDate' | i18n }}</nz-form-label> <nz-form-label nzFor="startDatePicker">{{ 'mxk.text.startDate' | i18n }}</nz-form-label>
<nz-form-control> <nz-form-control>
<nz-date-picker <nz-date-picker nzShowTime nzFormat="yyyy-MM-dd HH:mm:ss" [(ngModel)]="query.params.startDatePicker"
nzShowTime [ngModelOptions]="{ standalone: true }" name="startDatePicker" nzPlaceHolder="startDatePicker">
nzFormat="yyyy-MM-dd HH:mm:ss" </nz-date-picker>
[(ngModel)]="query.params.startDatePicker"
[ngModelOptions]="{ standalone: true }"
name="startDatePicker"
nzPlaceHolder="startDatePicker"
></nz-date-picker>
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
</div> </div>
@ -58,45 +44,29 @@
<nz-form-item> <nz-form-item>
<nz-form-label nzFor="endDatePicker">{{ 'mxk.text.endDate' | i18n }}</nz-form-label> <nz-form-label nzFor="endDatePicker">{{ 'mxk.text.endDate' | i18n }}</nz-form-label>
<nz-form-control> <nz-form-control>
<nz-date-picker <nz-date-picker nzShowTime nzFormat="yyyy-MM-dd HH:mm:ss" [(ngModel)]="query.params.endDatePicker"
nzShowTime [ngModelOptions]="{ standalone: true }" name="endDatePicker" nzPlaceHolder="endDatePicker">
nzFormat="yyyy-MM-dd HH:mm:ss" </nz-date-picker>
[(ngModel)]="query.params.endDatePicker"
[ngModelOptions]="{ standalone: true }"
name="endDatePicker"
nzPlaceHolder="endDatePicker"
></nz-date-picker>
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
</div> </div>
<div nz-col [nzSpan]="query.expandForm ? 24 : 8" [class.text-right]="query.expandForm"> <div nz-col [nzSpan]="query.expandForm ? 24 : 8" [class.text-right]="query.expandForm">
<button nz-button type="submit" [nzType]="'primary'" [nzLoading]="query.submitLoading">{{ 'mxk.text.query' | i18n }}</button> <button nz-button type="submit" [nzType]="'primary'" [nzLoading]="query.submitLoading">{{ 'mxk.text.query' |
i18n }}</button>
<button nz-button type="reset" (click)="onReset()" class="mx-sm">{{ 'mxk.text.reset' | i18n }}</button> <button nz-button type="reset" (click)="onReset()" class="mx-sm">{{ 'mxk.text.reset' | i18n }}</button>
<button nz-button (click)="query.expandForm = !query.expandForm" class="mx-sm"> <button nz-button (click)="query.expandForm = !query.expandForm" class="mx-sm">
{{ query.expandForm ? ('mxk.text.collapse' | i18n) : ('mxk.text.expand' | i18n) }}</button {{ query.expandForm ? ('mxk.text.collapse' | i18n) : ('mxk.text.expand' | i18n) }}</button>
>
</div> </div>
</div> </div>
</form> </form>
</nz-card> </nz-card>
<nz-card> <nz-card>
<nz-table <nz-table #dynamicTable nzTableLayout="auto" nzSize="small" nzShowSizeChanger [nzBordered]="true"
#dynamicTable [nzData]="query.results.rows" [nzFrontPagination]="false" [nzTotal]="query.results.records"
nzTableLayout="auto" [nzPageSizeOptions]="query.params.pageSizeOptions" [nzPageSize]="query.params.pageSize"
nzSize="small" [nzPageIndex]="query.params.pageNumber" [nzLoading]="this.query.tableLoading"
nzShowSizeChanger (nzQueryParams)="onQueryParamsChange($event)">
[nzBordered]="true"
[nzData]="query.results.rows"
[nzFrontPagination]="false"
[nzTotal]="query.results.records"
[nzPageSizeOptions]="query.params.pageSizeOptions"
[nzPageSize]="query.params.pageSize"
[nzPageIndex]="query.params.pageNumber"
[nzLoading]="this.query.tableLoading"
(nzQueryParams)="onQueryParamsChange($event)"
[nzScroll]="{ x: '100%', y: '100%' }"
>
<thead> <thead>
<tr> <tr>
<th nzAlign="center">{{ 'mxk.history.synchronizer.syncId' | i18n }}</th> <th nzAlign="center">{{ 'mxk.history.synchronizer.syncId' | i18n }}</th>

View File

@ -14,7 +14,6 @@
* limitations under the License. * limitations under the License.
*/ */
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@angular/core'; import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { _HttpClient } from '@delon/theme'; import { _HttpClient } from '@delon/theme';
@ -33,8 +32,8 @@ import { HistoryService } from '../../../service/history.service';
export class AuditSynchronizerComponent implements OnInit { export class AuditSynchronizerComponent implements OnInit {
query: { query: {
params: { params: {
username: String; syncName: String;
displayName: String; objectName: String;
employeeNumber: String; employeeNumber: String;
startDate: String; startDate: String;
endDate: String; endDate: String;
@ -53,8 +52,8 @@ export class AuditSynchronizerComponent implements OnInit {
tableLoading: boolean; tableLoading: boolean;
} = { } = {
params: { params: {
username: '', syncName: '',
displayName: '', objectName: '',
employeeNumber: '', employeeNumber: '',
startDate: '', startDate: '',
endDate: '', endDate: '',

View File

@ -14,7 +14,6 @@
* limitations under the License. * limitations under the License.
*/ */
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
@ -34,6 +33,8 @@ import { SelectAccountsStrategyComponent } from './accounts-strategy/select-acco
import { AdapterEditerComponent } from './adapters/adapter-editer/adapter-editer.component'; import { AdapterEditerComponent } from './adapters/adapter-editer/adapter-editer.component';
import { AdaptersComponent } from './adapters/adapters.component'; import { AdaptersComponent } from './adapters/adapters.component';
import { SelectAdaptersComponent } from './adapters/select-adapters/select-adapters.component'; import { SelectAdaptersComponent } from './adapters/select-adapters/select-adapters.component';
import { ConnectorEditerComponent } from './connectors/connector-editer/connector-editer.component';
import { ConnectorsComponent } from './connectors/connectors.component';
import { EmailSendersComponent } from './email-senders/email-senders.component'; import { EmailSendersComponent } from './email-senders/email-senders.component';
import { InstitutionsComponent } from './institutions/institutions.component'; import { InstitutionsComponent } from './institutions/institutions.component';
import { LdapContextComponent } from './ldap-context/ldap-context.component'; import { LdapContextComponent } from './ldap-context/ldap-context.component';
@ -74,6 +75,10 @@ const routes: Routes = [
path: 'synchronizers', path: 'synchronizers',
component: SynchronizersComponent component: SynchronizersComponent
}, },
{
path: 'connectors',
component: ConnectorsComponent
},
{ {
path: 'accountsstrategys', path: 'accountsstrategys',
component: AccountsStrategyComponent component: AccountsStrategyComponent
@ -108,7 +113,9 @@ const COMPONENTS = [PasswordPolicyComponent, EmailSendersComponent, LdapContextC
InstitutionsComponent, InstitutionsComponent,
NoticesComponent, NoticesComponent,
SelectAccountsStrategyComponent, SelectAccountsStrategyComponent,
SelectAdaptersComponent SelectAdaptersComponent,
ConnectorsComponent,
ConnectorEditerComponent
], ],
imports: [SharedModule, CommonModule, RouterModule.forChild(routes)], imports: [SharedModule, CommonModule, RouterModule.forChild(routes)],
exports: [RouterModule] exports: [RouterModule]

View File

@ -0,0 +1,81 @@
<div *nzModalTitle> {{ isEdit ? ('mxk.text.edit' | i18n) : ('mxk.text.add' | i18n) }} </div>
<div>
<form nz-form [formGroup]="formGroup" (ngSubmit)="onSubmit($event)" se-container="1">
<nz-form-item>
<nz-form-label [nzMd]="6" nzFor="id">{{ 'mxk.text.id' | i18n }}</nz-form-label>
<nz-form-control [nzMd]="18" nzErrorTip="The input is not valid id!">
<input [(ngModel)]="form.model.id" disabled="{{ isEdit }}" [ngModelOptions]="{ standalone: true }"
nz-input name="id" id="id" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label [nzMd]="6" nzFor="id">{{ 'mxk.connectors.connName' | i18n }}</nz-form-label>
<nz-form-control [nzMd]="18" nzErrorTip="The input is not valid connName!">
<input [(ngModel)]="form.model.connName" [ngModelOptions]="{ standalone: true }" nz-input
name="connName" id="connName" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label [nzSm]="6" [nzXs]="24" nzRequired nzFor="justInTime">{{ 'mxk.connectors.justInTime' | i18n }}
</nz-form-label>
<nz-form-control [nzSm]="14" [nzXs]="24" nzErrorTip="The input is not valid justInTime!">
<nz-switch [(ngModel)]="form.model.switch_justInTime" [ngModelOptions]="{ standalone: true }"
name="justInTime" [nzCheckedChildren]="checkedTemplateJustInTime"
[nzUnCheckedChildren]="unCheckedTemplateJustInTime">
</nz-switch>
<ng-template #checkedTemplateJustInTime><i nz-icon nzType="check"></i></ng-template>
<ng-template #unCheckedTemplateJustInTime><i nz-icon nzType="close"></i></ng-template>
</nz-form-control>
</nz-form-item>
<nz-form-item *ngIf="!form.model.switch_justInTime">
<nz-form-label [nzSm]="6" [nzXs]="24" nzFor="scheduler">{{ 'mxk.connectors.scheduler' | i18n }}
</nz-form-label>
<nz-form-control [nzSm]="18" [nzMd]="18" [nzXs]="36" [nzXl]="48" nzErrorTip="The input is not valid icon!">
<input [(ngModel)]="form.model.scheduler" [ngModelOptions]="{ standalone: true }" nz-input
name="scheduler" placeholder="0 0 12 * * ?" id="scheduler" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label [nzSm]="6" [nzXs]="24" nzRequired nzFor="providerUrl">{{ 'mxk.connectors.providerUrl' | i18n
}} </nz-form-label>
<nz-form-control [nzSm]="18" [nzMd]="18" [nzXs]="36" [nzXl]="48"
nzErrorTip="The input is not valid providerUrl!">
<input [(ngModel)]="form.model.providerUrl" [ngModelOptions]="{ standalone: true }" nz-input
name="providerUrl" id="providerUrl" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label [nzSm]="6" [nzXs]="24" nzRequired nzFor="principal">{{ 'mxk.connectors.principal' | i18n }}
</nz-form-label>
<nz-form-control [nzSm]="18" [nzMd]="18" [nzXs]="36" [nzXl]="48"
nzErrorTip="The input is not valid principal!">
<input [(ngModel)]="form.model.principal" [ngModelOptions]="{ standalone: true }" nz-input
name="principal" id="principal" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label [nzSm]="6" [nzXs]="24" nzRequired nzFor="credentials">{{ 'mxk.connectors.credentials' | i18n
}} </nz-form-label>
<nz-form-control [nzSm]="18" [nzMd]="18" [nzXs]="36" [nzXl]="48"
nzErrorTip="The input is not valid credentials!">
<input type="password" [(ngModel)]="form.model.credentials" [ngModelOptions]="{ standalone: true }"
nz-input name="credentials" id="credentials" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label [nzSm]="6" [nzXs]="24" nzRequired nzFor="status">{{ 'mxk.text.status' | i18n }}
</nz-form-label>
<nz-form-control [nzSm]="14" [nzXs]="24" nzErrorTip="The input is not valid status!">
<nz-switch [(ngModel)]="form.model.switch_status" [ngModelOptions]="{ standalone: true }" name="status"
[nzCheckedChildren]="checkedTemplate" [nzUnCheckedChildren]="unCheckedTemplate"></nz-switch>
<ng-template #checkedTemplate><i nz-icon nzType="check"></i></ng-template>
<ng-template #unCheckedTemplate><i nz-icon nzType="close"></i></ng-template>
</nz-form-control>
</nz-form-item>
</form>
</div>
<div *nzModalFooter>
<button nz-button nzType="default" (click)="onClose($event)">{{ 'mxk.text.close' | i18n }}</button>
<button nz-button nzType="primary" (click)="onSubmit($event)">{{ 'mxk.text.submit' | i18n }}</button>
</div>

View File

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ConnectorEditerComponent } from './connector-editer.component';
describe('ConnectorEditerComponent', () => {
let component: ConnectorEditerComponent;
let fixture: ComponentFixture<ConnectorEditerComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ ConnectorEditerComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(ConnectorEditerComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,91 @@
/*
* 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.
*/
import { Component, ChangeDetectorRef, Input, OnInit, Inject } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { I18NService } from '@core';
import { _HttpClient, ALAIN_I18N_TOKEN, SettingsService } from '@delon/theme';
import format from 'date-fns/format';
import { NzMessageService } from 'ng-zorro-antd/message';
import { NzModalRef, NzModalService } from 'ng-zorro-antd/modal';
import { Connectors } from '../../../../entity/Connectors';
import { ConnectorsService } from '../../../../service/connectors.service';
@Component({
selector: 'app-connector-editer',
templateUrl: './connector-editer.component.html',
styleUrls: ['./connector-editer.component.less'],
styles: [
`
nz-form-item {
width: 100%;
}
`
]
})
export class ConnectorEditerComponent implements OnInit {
@Input() id?: String;
@Input() isEdit?: boolean;
form: {
submitting: boolean;
model: Connectors;
} = {
submitting: false,
model: new Connectors()
};
formGroup: FormGroup = new FormGroup({});
constructor(
private modalRef: NzModalRef,
private connectorsService: ConnectorsService,
private fb: FormBuilder,
private msg: NzMessageService,
@Inject(ALAIN_I18N_TOKEN) private i18n: I18NService,
private cdr: ChangeDetectorRef
) { }
ngOnInit(): void {
if (this.isEdit) {
this.connectorsService.get(`${this.id}`).subscribe(res => {
this.form.model.init(res.data);
this.cdr.detectChanges();
});
}
}
onClose(e: MouseEvent): void {
e.preventDefault();
this.modalRef.destroy({ refresh: false });
}
onSubmit(e: MouseEvent): void {
e.preventDefault();
this.form.submitting = true;
this.form.model.trans();
(this.isEdit ? this.connectorsService.update(this.form.model) : this.connectorsService.add(this.form.model)).subscribe(res => {
if (res.code == 0) {
this.msg.success(this.i18n.fanyi(this.isEdit ? 'mxk.alert.update.success' : 'mxk.alert.add.success'));
} else {
this.msg.error(this.i18n.fanyi(this.isEdit ? 'mxk.alert.update.error' : 'mxk.alert.add.error'));
}
this.form.submitting = false;
this.modalRef.destroy({ refresh: true });
this.cdr.detectChanges();
});
}
}

View File

@ -0,0 +1,75 @@
<page-header> </page-header>
<nz-card [nzBordered]="false">
<form nz-form [nzLayout]="'inline'" (ngSubmit)="onSearch()" class="search__form">
<div nz-row [nzGutter]="{ xs: 8, sm: 8, md: 8, lg: 24, xl: 48, xxl: 48 }">
<div nz-col nzMd="16" nzSm="24">
<nz-form-item>
<nz-form-label nzFor="connName">{{ 'mxk.connectors.connName' | i18n }}</nz-form-label>
<nz-form-control>
<input nz-input [(ngModel)]="query.params.connName" [ngModelOptions]="{ standalone: true }"
name="connName" placeholder="" id="connName" />
</nz-form-control>
</nz-form-item>
</div>
<div nz-col [nzSpan]="query.expandForm ? 24 : 8" [class.text-right]="query.expandForm">
<button nz-button type="submit" [nzType]="'primary'" [nzLoading]="query.submitLoading">{{
'mxk.text.query' | i18n }}</button>
<button nz-button type="reset" (click)="onReset()" class="mx-sm" style="display: none">{{
'mxk.text.reset' | i18n }}</button>
<button nz-button (click)="query.expandForm = !query.expandForm" class="mx-sm" style="display: none">
{{ query.expandForm ? ('mxk.text.collapse' | i18n) : ('mxk.text.expand' | i18n) }}</button>
</div>
</div>
</form>
</nz-card>
<nz-card>
<div nz-col [nzSpan]="24" class="table-list-toolbar">
<button nz-button type="button" [nzType]="'primary'" (click)="onAdd($event)">{{ 'mxk.text.add' | i18n
}}</button>
<button nz-button type="button" (click)="onBatchDelete($event)" [nzType]="'primary'" nzDanger class="mx-sm">{{
'mxk.text.delete' | i18n
}}</button>
</div>
<nz-table #dynamicTable nzTableLayout="auto" nzSize="small" nzBordered nzShowSizeChanger
[nzData]="query.results.rows" [nzFrontPagination]="false" [nzTotal]="query.results.records"
[nzPageSizeOptions]="query.params.pageSizeOptions" [nzPageSize]="query.params.pageSize"
[nzPageIndex]="query.params.pageNumber" [nzLoading]="this.query.tableLoading"
(nzQueryParams)="onQueryParamsChange($event)" nzWidth="100%">
<thead>
<tr>
<th [nzChecked]="query.checked" [nzIndeterminate]="query.indeterminate"
(nzCheckedChange)="onTableAllChecked($event)"></th>
<th nzAlign="center" style="display: none">Id</th>
<th nzAlign="center">{{ 'mxk.connectors.connName' | i18n }}</th>
<th nzAlign="center">{{ 'mxk.connectors.justInTime' | i18n }}</th>
<th nzAlign="center">{{ 'mxk.text.status' | i18n }}</th>
<th nzAlign="center"><a>{{ 'mxk.text.action' | i18n }}</a></th>
</tr>
</thead>
<tbody>
<tr *ngFor="let data of query.results.rows">
<td [nzChecked]="query.tableCheckedId.has(data.id)" [nzDisabled]="data.disabled"
(nzCheckedChange)="onTableItemChecked(data.id, $event)"></td>
<td nzAlign="left" style="display: none">
<span>{{ data.id }}</span>
</td>
<td nzAlign="left"> {{ data.connName }}</td>
<td nzAlign="center" *ngIf="data.justInTime == 1">{{ 'mxk.text.yes' | i18n }}</td>
<td nzAlign="center" *ngIf="data.justInTime == 0">{{ 'mxk.text.no' | i18n }}</td>
<td nzAlign="center"> <i *ngIf="data.status == 1" nz-icon nzType="check-circle" nzTheme="fill"
style="color: green"></i></td>
<td nzAlign="left" nzBreakWord="false">
<div nz-col>
<button nz-button type="button" (click)="onEdit($event, data.id)" style="float: left">{{
'mxk.text.edit' | i18n }}</button>
<button nz-button type="button" (click)="onDelete($event, data.id)" nzDanger>{{
'mxk.text.delete' | i18n }}</button>
</div>
</td>
</tr>
</tbody>
</nz-table>
</nz-card>

View File

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ConnectorsComponent } from './connectors.component';
describe('ConnectorsComponent', () => {
let component: ConnectorsComponent;
let fixture: ComponentFixture<ConnectorsComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ ConnectorsComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(ConnectorsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,203 @@
import { ChangeDetectionStrategy, ViewContainerRef, ChangeDetectorRef, Component, OnInit, Inject } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { I18NService } from '@core';
import { _HttpClient, ALAIN_I18N_TOKEN, SettingsService } from '@delon/theme';
import { format, addDays } from 'date-fns';
import { NzSafeAny } from 'ng-zorro-antd/core/types';
import { NzMessageService } from 'ng-zorro-antd/message';
import { NzModalRef, NzModalService } from 'ng-zorro-antd/modal';
import { NzTableQueryParams } from 'ng-zorro-antd/table';
import { ConnectorsService } from '../../../service/connectors.service';
import { set2String } from '../../../shared/index';
import { ConnectorEditerComponent } from './connector-editer/connector-editer.component';
@Component({
selector: 'app-connectors',
templateUrl: './connectors.component.html',
styleUrls: ['./connectors.component.less']
})
export class ConnectorsComponent implements OnInit {
query: {
params: {
connName: String;
displayName: String;
protocol: String;
startDate: String;
endDate: String;
startDatePicker: Date;
endDatePicker: Date;
pageSize: number;
pageNumber: number;
pageSizeOptions: number[];
};
results: {
records: number;
rows: NzSafeAny[];
};
expandForm: Boolean;
submitLoading: boolean;
tableLoading: boolean;
tableCheckedId: Set<String>;
indeterminate: boolean;
checked: boolean;
} = {
params: {
connName: '',
displayName: '',
protocol: '',
startDate: '',
endDate: '',
startDatePicker: addDays(new Date(), -30),
endDatePicker: new Date(),
pageSize: 10,
pageNumber: 1,
pageSizeOptions: [10, 20, 50]
},
results: {
records: 0,
rows: []
},
expandForm: false,
submitLoading: false,
tableLoading: false,
tableCheckedId: new Set<String>(),
indeterminate: false,
checked: false
};
constructor(
private modalService: NzModalService,
private connectorsService: ConnectorsService,
private viewContainerRef: ViewContainerRef,
private fb: FormBuilder,
private msg: NzMessageService,
@Inject(ALAIN_I18N_TOKEN) private i18n: I18NService,
private cdr: ChangeDetectorRef
) { }
ngOnInit(): void {
this.fetch();
}
onQueryParamsChange(tableQueryParams: NzTableQueryParams): void {
this.query.params.pageNumber = tableQueryParams.pageIndex;
this.query.params.pageSize = tableQueryParams.pageSize;
this.fetch();
}
onSearch(): void {
this.fetch();
}
onReset(): void { }
onBatchDelete(e: MouseEvent): void {
e.preventDefault();
this.connectorsService.delete(set2String(this.query.tableCheckedId)).subscribe(res => {
if (res.code == 0) {
this.msg.success(this.i18n.fanyi('mxk.alert.delete.success'));
this.fetch();
} else {
this.msg.error(this.i18n.fanyi('mxk.alert.delete.error'));
}
this.cdr.detectChanges();
});
}
onAdd(e: MouseEvent): void {
e.preventDefault();
const modal = this.modalService.create({
nzContent: ConnectorEditerComponent,
nzViewContainerRef: this.viewContainerRef,
nzComponentParams: {
isEdit: false,
id: ''
},
nzOnOk: () => new Promise(resolve => setTimeout(resolve, 1000))
});
// Return a result when closed
modal.afterClose.subscribe(result => {
if (result.refresh) {
this.fetch();
}
});
}
onEdit(e: MouseEvent, editId: String): void {
e.preventDefault();
const modal = this.modalService.create({
nzContent: ConnectorEditerComponent,
nzViewContainerRef: this.viewContainerRef,
nzComponentParams: {
isEdit: true,
id: editId
},
nzOnOk: () => new Promise(resolve => setTimeout(resolve, 1000))
});
// Return a result when closed
modal.afterClose.subscribe(result => {
if (result.refresh) {
this.fetch();
}
});
}
onDelete(e: MouseEvent, deleteId: String): void {
e.preventDefault();
this.connectorsService.delete(deleteId).subscribe(res => {
if (res.code == 0) {
this.msg.success(this.i18n.fanyi('mxk.alert.delete.success'));
this.fetch();
} else {
this.msg.error(this.i18n.fanyi('mxk.alert.delete.error'));
}
this.cdr.detectChanges();
});
}
fetch(): void {
this.query.submitLoading = true;
this.query.tableLoading = true;
this.query.indeterminate = false;
this.query.checked = false;
this.query.tableCheckedId.clear();
if (this.query.expandForm) {
this.query.params.endDate = format(this.query.params.endDatePicker, 'yyyy-MM-dd HH:mm:ss');
this.query.params.startDate = format(this.query.params.startDatePicker, 'yyyy-MM-dd HH:mm:ss');
} else {
this.query.params.endDate = '';
this.query.params.startDate = '';
}
this.connectorsService.fetch(this.query.params).subscribe(res => {
this.query.results = res.data;
this.query.submitLoading = false;
this.query.tableLoading = false;
this.cdr.detectChanges();
});
}
updateTableCheckedSet(id: String, checked: boolean): void {
if (checked) {
this.query.tableCheckedId.add(id);
} else {
this.query.tableCheckedId.delete(id);
}
}
refreshTableCheckedStatus(): void {
const listOfEnabledData = this.query.results.rows.filter(({ disabled }) => !disabled);
this.query.checked = listOfEnabledData.every(({ id }) => this.query.tableCheckedId.has(id));
this.query.indeterminate = listOfEnabledData.some(({ id }) => this.query.tableCheckedId.has(id)) && !this.query.checked;
}
onTableItemChecked(id: String, checked: boolean): void {
this.updateTableCheckedSet(id, checked);
this.refreshTableCheckedStatus();
}
onTableAllChecked(checked: boolean): void {
this.query.results.rows.filter(({ disabled }) => !disabled).forEach(({ id }) => this.updateTableCheckedSet(id, checked));
this.refreshTableCheckedStatus();
}
}

View File

@ -0,0 +1,33 @@
/*
* 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.
*/
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { NzSafeAny } from 'ng-zorro-antd/core/types';
import { Observable } from 'rxjs';
import { Connectors } from '../entity/Connectors';
import { Message } from '../entity/Message';
import { BaseService } from './base.service';
@Injectable({
providedIn: 'root'
})
export class ConnectorsService extends BaseService<Connectors> {
constructor(private _httpClient: HttpClient) {
super(_httpClient, '/config/connectors');
}
}

View File

@ -14,7 +14,6 @@
* limitations under the License. * limitations under the License.
*/ */
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { NzSafeAny } from 'ng-zorro-antd/core/types'; import { NzSafeAny } from 'ng-zorro-antd/core/types';

View File

@ -117,13 +117,6 @@
"icon": "anticon-idcard", "icon": "anticon-idcard",
"children": [] "children": []
}, },
{
"text": "社交服务",
"i18n": "mxk.menu.config.socialsproviders",
"link": "/config/socialsproviders",
"icon": "anticon-comment",
"children": []
},
{ {
"text": "同步器管理", "text": "同步器管理",
"i18n": "mxk.menu.config.synchronizers", "i18n": "mxk.menu.config.synchronizers",
@ -131,6 +124,20 @@
"icon": "anticon-partition", "icon": "anticon-partition",
"children": [] "children": []
}, },
{
"text": "连接器管理",
"i18n": "mxk.menu.config.connectors",
"link": "/config/connectors",
"icon": "anticon-api",
"children": []
},
{
"text": "社交服务",
"i18n": "mxk.menu.config.socialsproviders",
"link": "/config/socialsproviders",
"icon": "anticon-comment",
"children": []
},
{ {
"text": "LDAP配置", "text": "LDAP配置",
"i18n": "mxk.menu.config.ldapcontext", "i18n": "mxk.menu.config.ldapcontext",
@ -188,6 +195,13 @@
"icon": "anticon-audit", "icon": "anticon-audit",
"children": [] "children": []
}, },
{
"text": "连接器日志",
"i18n": "mxk.menu.audit.connector",
"link": "/audit/audit-connector",
"icon": "anticon-audit",
"children": []
},
{ {
"text": "管理日志", "text": "管理日志",
"i18n": "mxk.menu.audit.operate", "i18n": "mxk.menu.audit.operate",

View File

@ -45,6 +45,7 @@
"accountsstrategys": "Strategys", "accountsstrategys": "Strategys",
"socialsproviders": "Socials", "socialsproviders": "Socials",
"synchronizers": "Synchronizers", "synchronizers": "Synchronizers",
"connectors":"Connectors",
"adapters": "Adapters", "adapters": "Adapters",
"notices": "Notices", "notices": "Notices",
"ldapcontext": "LDAP", "ldapcontext": "LDAP",
@ -537,6 +538,15 @@
"resumeTime": "Join Time", "resumeTime": "Join Time",
"suspendTime": "Suspend Time" "suspendTime": "Suspend Time"
}, },
"connectors": {
"connName": "Name",
"scheduler": "Scheduler",
"justInTime":"JustInTime",
"providerUrl": "ProviderUrl",
"principal": "Principal",
"credentials": "Credentials",
"filters": "Filters"
},
"password": { "password": {
"id": "Id", "id": "Id",
"displayName": "DisplayName", "displayName": "DisplayName",
@ -610,7 +620,8 @@
"connector.id": "Id", "connector.id": "Id",
"connector.conName": "Connector", "connector.conName": "Connector",
"connector.conType": "Type", "connector.topic": "Topic",
"connector.actionType": "ActionType",
"connector.sourceId": "SourceId", "connector.sourceId": "SourceId",
"connector.sourceName": "SourceName", "connector.sourceName": "SourceName",
"connector.objectId": "ObjectId", "connector.objectId": "ObjectId",

View File

@ -45,6 +45,7 @@
"accountsstrategys": "账号策略", "accountsstrategys": "账号策略",
"socialsproviders": "社交服务", "socialsproviders": "社交服务",
"synchronizers": "同步器管理", "synchronizers": "同步器管理",
"connectors":"连接器管理",
"adapters": "适配器注册", "adapters": "适配器注册",
"notices": "通知公告", "notices": "通知公告",
"ldapcontext": "LDAP配置", "ldapcontext": "LDAP配置",
@ -535,6 +536,15 @@
"resumeTime": "执行时间", "resumeTime": "执行时间",
"suspendTime": "挂起时间" "suspendTime": "挂起时间"
}, },
"connectors": {
"connName": "名称",
"scheduler": "定时任务",
"justInTime":"实时同步",
"providerUrl": "地址",
"principal": "账号",
"credentials": "凭证",
"filters": "过滤条件"
},
"password": { "password": {
"id": "用户编码", "id": "用户编码",
"displayName": "姓名", "displayName": "姓名",
@ -608,7 +618,8 @@
"connector.id": "编号", "connector.id": "编号",
"connector.conName": "连接器", "connector.conName": "连接器",
"connector.conType": "类型", "connector.topic": "主题",
"connector.actionType": "操作",
"connector.sourceId": "源编码", "connector.sourceId": "源编码",
"connector.sourceName": "源名称", "connector.sourceName": "源名称",
"connector.objectId": "对象编号", "connector.objectId": "对象编号",

View File

@ -46,6 +46,7 @@
"accountsstrategys": "賬號策略", "accountsstrategys": "賬號策略",
"socialsproviders": "社交服務", "socialsproviders": "社交服務",
"synchronizers": "同步器管理", "synchronizers": "同步器管理",
"connectors":"連接器管理",
"adapters": "適配器註冊", "adapters": "適配器註冊",
"notices": "通知公告", "notices": "通知公告",
"ldapcontext": "LDAP配置", "ldapcontext": "LDAP配置",
@ -536,6 +537,15 @@
"resumeTime": "執行時間", "resumeTime": "執行時間",
"suspendTime": "掛起時間" "suspendTime": "掛起時間"
}, },
"connectors": {
"connName": "名稱",
"scheduler": "定時任務",
"justInTime":"實时同步",
"providerUrl": "地址",
"principal": "賬號",
"credentials": "憑證",
"filters": "過濾條件"
},
"password": { "password": {
"id": "用戶編碼", "id": "用戶編碼",
"displayName": "姓名", "displayName": "姓名",
@ -609,7 +619,8 @@
"connector.id": "編號", "connector.id": "編號",
"connector.conName": "連接器", "connector.conName": "連接器",
"connector.conType": "類型", "connector.topic": "主題",
"connector.actionType": "操作",
"connector.sourceId": "源編碼", "connector.sourceId": "源編碼",
"connector.sourceName": "源名稱", "connector.sourceName": "源名稱",
"connector.objectId": "對象編號", "connector.objectId": "對象編號",

View File

@ -106,7 +106,7 @@ public class MaxKeyMvcConfig implements WebMvcConfigurer {
//addPathPatterns 用于添加拦截规则 先把所有路径都加入拦截 再一个个排除 //addPathPatterns 用于添加拦截规则 先把所有路径都加入拦截 再一个个排除
//excludePathPatterns 表示改路径不用拦截 //excludePathPatterns 表示改路径不用拦截
_logger.debug("add HttpKerberosEntryPoint"); _logger.debug("add Http Kerberos Entry Point");
registry.addInterceptor(new HttpKerberosEntryPoint( registry.addInterceptor(new HttpKerberosEntryPoint(
authenticationProvider,kerberosService,applicationConfig,true)) authenticationProvider,kerberosService,applicationConfig,true))
.addPathPatterns("/login"); .addPathPatterns("/login");
@ -115,13 +115,13 @@ public class MaxKeyMvcConfig implements WebMvcConfigurer {
if(httpHeaderEnable) { if(httpHeaderEnable) {
registry.addInterceptor(new HttpHeaderEntryPoint(httpHeaderName,httpHeaderEnable)) registry.addInterceptor(new HttpHeaderEntryPoint(httpHeaderName,httpHeaderEnable))
.addPathPatterns("/*"); .addPathPatterns("/*");
_logger.debug("add HttpHeaderEntryPoint"); _logger.debug("add Http Header Entry Point");
} }
if(basicEnable) { if(basicEnable) {
registry.addInterceptor(new BasicEntryPoint(basicEnable)) registry.addInterceptor(new BasicEntryPoint(basicEnable))
.addPathPatterns("/*"); .addPathPatterns("/*");
_logger.debug("add BasicEntryPoint"); _logger.debug("add Basic Entry Point");
} }
//for frontend //for frontend

View File

@ -44,8 +44,8 @@ maxkey.server.authz.uri =${maxkey.server.name}:${server.
maxkey.server.frontend.uri =/maxkey maxkey.server.frontend.uri =/maxkey
#InMemory 0 , Redis 2 #InMemory 0 , Redis 2
maxkey.server.persistence =${SERVER_PERSISTENCE:0} maxkey.server.persistence =${SERVER_PERSISTENCE:0}
#identity none, provision #identity true,false
maxkey.server.message.queue =${SERVER_MESSAGE_QUEUE:none} maxkey.server.provision =${SERVER_PROVISION:false}
#issuer name #issuer name
maxkey.app.issuer =CN=ConSec,CN=COM,CN=SH maxkey.app.issuer =CN=ConSec,CN=COM,CN=SH
#must > jwt expire * 2 #must > jwt expire * 2

View File

@ -18,11 +18,15 @@
package org.maxkey; package org.maxkey;
import org.maxkey.authn.session.SessionManager; import org.maxkey.authn.session.SessionManager;
import org.maxkey.configuration.ApplicationConfig;
import org.maxkey.listener.DynamicRolesListenerAdapter; import org.maxkey.listener.DynamicRolesListenerAdapter;
import org.maxkey.listener.ListenerAdapter; import org.maxkey.listener.ListenerAdapter;
import org.maxkey.listener.ListenerParameter; import org.maxkey.listener.ListenerParameter;
import org.maxkey.listener.SessionListenerAdapter; import org.maxkey.listener.SessionListenerAdapter;
import org.maxkey.persistence.service.ConnectorsService;
import org.maxkey.persistence.service.RolesService; import org.maxkey.persistence.service.RolesService;
import org.maxkey.provision.thread.ProvisioningRunner;
import org.maxkey.provision.thread.ProvisioningRunnerThread;
import org.quartz.Scheduler; import org.quartz.Scheduler;
import org.quartz.SchedulerException; import org.quartz.SchedulerException;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -31,6 +35,7 @@ import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
@Configuration @Configuration
public class MaxKeyMgtListenerConfig implements InitializingBean { public class MaxKeyMgtListenerConfig implements InitializingBean {
@ -69,6 +74,23 @@ public class MaxKeyMgtListenerConfig implements InitializingBean {
return "dynamicRolesListenerAdapter"; return "dynamicRolesListenerAdapter";
} }
@Bean
public String provisioningRunnerThread(
ConnectorsService connectorsService,
JdbcTemplate jdbcTemplate,
ApplicationConfig applicationConfig
) throws SchedulerException {
if(applicationConfig.isProvisionSupport()) {
ProvisioningRunner runner = new ProvisioningRunner(connectorsService,jdbcTemplate);
ProvisioningRunnerThread runnerThread = new ProvisioningRunnerThread(runner);
runnerThread.start();
_logger.debug("provisioning Runner Thread .");
}else {
_logger.debug("not need init provisioning Runner Thread .");
}
return "provisioningRunnerThread";
}
@Override @Override
public void afterPropertiesSet() throws Exception { public void afterPropertiesSet() throws Exception {

View File

@ -84,7 +84,7 @@ public class MaxKeyMgtMvcConfig implements WebMvcConfigurer {
public void addInterceptors(InterceptorRegistry registry) { public void addInterceptors(InterceptorRegistry registry) {
//addPathPatterns 用于添加拦截规则 先把所有路径都加入拦截 再一个个排除 //addPathPatterns 用于添加拦截规则 先把所有路径都加入拦截 再一个个排除
//excludePathPatterns 表示改路径不用拦截 //excludePathPatterns 表示改路径不用拦截
_logger.debug("add HttpJwtEntryPoint"); _logger.debug("add Interceptors");
permissionInterceptor.setMgmt(true); permissionInterceptor.setMgmt(true);
@ -118,7 +118,7 @@ public class MaxKeyMgtMvcConfig implements WebMvcConfigurer {
.addPathPatterns("/logout/**") .addPathPatterns("/logout/**")
; ;
_logger.debug("add PermissionAdapter"); _logger.debug("add Permission Adapter");
registry.addInterceptor(historyLogsAdapter) registry.addInterceptor(historyLogsAdapter)
.addPathPatterns("/userinfo/**") .addPathPatterns("/userinfo/**")
@ -131,7 +131,7 @@ public class MaxKeyMgtMvcConfig implements WebMvcConfigurer {
.addPathPatterns("/apps/**") .addPathPatterns("/apps/**")
.addPathPatterns("/approles/**") .addPathPatterns("/approles/**")
; ;
_logger.debug("add HistoryLogsAdapter"); _logger.debug("add History Logs Adapter");
/* /*
* api * api
@ -144,7 +144,7 @@ public class MaxKeyMgtMvcConfig implements WebMvcConfigurer {
.addPathPatterns("/api/idm/scim/**") .addPathPatterns("/api/idm/scim/**")
; ;
_logger.debug("add RestApiPermissionAdapter"); _logger.debug("add Rest Api Permission Adapter");
} }

View File

@ -0,0 +1,105 @@
/*
* 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.config.contorller;
import org.apache.commons.lang3.StringUtils;
import org.apache.mybatis.jpa.persistence.JpaPageResults;
import org.maxkey.authn.annotation.CurrentUser;
import org.maxkey.crypto.password.PasswordReciprocal;
import org.maxkey.entity.Connectors;
import org.maxkey.entity.Message;
import org.maxkey.entity.UserInfo;
import org.maxkey.persistence.service.ConnectorsService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping(value={"/config/connectors"})
public class ConnectorsController {
final static Logger _logger = LoggerFactory.getLogger(ConnectorsController.class);
@Autowired
ConnectorsService connectorsService;
@RequestMapping(value = { "/fetch" }, produces = {MediaType.APPLICATION_JSON_VALUE})
@ResponseBody
public ResponseEntity<?> fetch(Connectors connector,@CurrentUser UserInfo currentUser) {
_logger.debug(""+connector);
connector.setInstId(currentUser.getInstId());
return new Message<JpaPageResults<Connectors>>(
connectorsService.queryPageResults(connector)).buildResponse();
}
@RequestMapping(value = { "/get/{id}" }, produces = {MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<?> get(@PathVariable("id") String id) {
Connectors connector = connectorsService.get(id);
if(StringUtils.isNotBlank(connector.getCredentials())) {
connector.setCredentials(PasswordReciprocal.getInstance().decoder(connector.getCredentials()));
}
return new Message<Connectors>(connector).buildResponse();
}
@ResponseBody
@RequestMapping(value={"/add"}, produces = {MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<?> insert(@RequestBody Connectors connector,@CurrentUser UserInfo currentUser) {
_logger.debug("-Add :" + connector);
connector.setInstId(currentUser.getInstId());
if(StringUtils.isNotBlank(connector.getCredentials())) {
connector.setCredentials(PasswordReciprocal.getInstance().encode(connector.getCredentials()));
}
if (connectorsService.insert(connector)) {
return new Message<Connectors>(Message.SUCCESS).buildResponse();
} else {
return new Message<Connectors>(Message.FAIL).buildResponse();
}
}
@ResponseBody
@RequestMapping(value={"/update"}, produces = {MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<?> update(@RequestBody Connectors connector,@CurrentUser UserInfo currentUser) {
_logger.debug("-update :" + connector);
connector.setInstId(currentUser.getInstId());
connector.setCredentials(PasswordReciprocal.getInstance().encode(connector.getCredentials()));
if (connectorsService.update(connector)) {
return new Message<Connectors>(Message.SUCCESS).buildResponse();
} else {
return new Message<Connectors>(Message.FAIL).buildResponse();
}
}
@ResponseBody
@RequestMapping(value={"/delete"}, produces = {MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<?> delete(@RequestParam("ids") String ids,@CurrentUser UserInfo currentUser) {
_logger.debug("-delete ids : {} " , ids);
if (connectorsService.deleteBatch(ids)) {
return new Message<Connectors>(Message.SUCCESS).buildResponse();
} else {
return new Message<Connectors>(Message.FAIL).buildResponse();
}
}
}

View File

@ -33,8 +33,8 @@ maxkey.server.mgt.uri =${maxkey.server.uri}
maxkey.server.authz.uri =https://${maxkey.server.domain}/maxkey maxkey.server.authz.uri =https://${maxkey.server.domain}/maxkey
#InMemory 0 , Redis 2 #InMemory 0 , Redis 2
maxkey.server.persistence =0 maxkey.server.persistence =0
#identity none, provision #identity true,false
maxkey.server.message.queue =${SERVER_MESSAGE_QUEUE:none} maxkey.server.provision =${SERVER_PROVISION:false}
maxkey.session.timeout =${SERVER_SESSION_TIMEOUT:1800} maxkey.session.timeout =${SERVER_SESSION_TIMEOUT:1800}