synchronizer optimize

This commit is contained in:
MaxKey
2022-03-11 16:08:29 +08:00
parent ea1bf3a9a1
commit be44a579c6
27 changed files with 1100 additions and 192 deletions

View File

@@ -23,8 +23,8 @@ package org.maxkey.authn.support.socialsignon;
import javax.servlet.http.HttpServletRequest;
import org.maxkey.authn.LoginCredential;
import org.maxkey.authn.support.socialsignon.service.SocialsAssociate;
import org.maxkey.constants.ConstsLoginType;
import org.maxkey.entity.SocialsAssociate;
import org.maxkey.entity.SocialsProvider;
import org.maxkey.web.WebContext;
import org.slf4j.Logger;

View File

@@ -24,6 +24,7 @@ import java.util.Date;
import java.util.List;
import org.maxkey.constants.ConstsDatabase;
import org.maxkey.entity.SocialsAssociate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;

View File

@@ -19,6 +19,8 @@ package org.maxkey.authn.support.socialsignon.service;
import java.util.List;
import org.maxkey.entity.SocialsAssociate;
public interface SocialsAssociateService{

View File

@@ -31,6 +31,9 @@ public class Organizations extends JpaBaseEntity implements Serializable {
private static final long serialVersionUID = 5085413816404119803L;
public static final String CLASS_TYPE = "Organization";
public static final String ROOT_ORG_ID = "1";
@Id
@Column
@GeneratedValue(strategy = GenerationType.AUTO, generator = "snowflakeid")
@@ -99,6 +102,14 @@ public class Organizations extends JpaBaseEntity implements Serializable {
private String instId;
private String instName;
String syncId;
String syncName;
String originId;
String originId2;
private int isPrimary = 0;
@@ -392,6 +403,39 @@ public class Organizations extends JpaBaseEntity implements Serializable {
this.instName = instName;
}
public String getSyncId() {
return syncId;
}
public void setSyncId(String syncId) {
this.syncId = syncId;
}
public String getSyncName() {
return syncName;
}
public void setSyncName(String syncName) {
this.syncName = syncName;
}
public String getOriginId() {
return originId;
}
public void setOriginId(String originId) {
this.originId = originId;
}
public String getOriginId2() {
return originId2;
}
public void setOriginId2(String originId2) {
this.originId2 = originId2;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();

View File

@@ -15,7 +15,14 @@
*/
package org.maxkey.authn.support.socialsignon.service;
package org.maxkey.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import org.apache.mybatis.jpa.persistence.JpaBaseEntity;
@@ -23,22 +30,35 @@ import org.apache.mybatis.jpa.persistence.JpaBaseEntity;
*
* @author Crystal.Sea
*/
@Entity
@Table(name = "MXK_SOCIALS_ASSOCIATE")
public class SocialsAssociate extends JpaBaseEntity {
/**
*
*/
private static final long serialVersionUID = 2151179554190800162L;
@Id
@Column
@GeneratedValue(strategy = GenerationType.AUTO,generator = "snowflakeid")
private String id;
@Column
private String provider;
@Column
private String userId;
@Column
private String username;
@Column
private String socialUserId;
@Column
private String socialUserInfo;
private String accessToken;
private String exAttribute;
@Column
private String createdDate;
@Column
private String updatedDate;
@Column
private String instId;
public SocialsAssociate() {}

View File

@@ -0,0 +1,238 @@
/*
* 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.entity;
import java.util.Date;
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.util.DateUtils;
/**
* .
* @author Crystal.Sea
*
*/
@Entity
@Table(name = "MXK_SYNCHRO_RELATED")
public class SynchroRelated extends JpaBaseEntity {
private static final long serialVersionUID = 6993697309055585706L;
@Id
@Column
@GeneratedValue(strategy = GenerationType.AUTO, generator = "snowflakeid")
String id;
@Column
protected String objectId;
@Column
protected String objectName;
@Column
protected String objectDisplayName;
@Column
protected String objectType;
@Column
protected String syncId;
@Column
protected String syncName;
@Column
protected String originId;
@Column
protected String originId2;
@Column
protected String originId3;
@Column
protected String originName;
@Column
protected String instId;
protected String instName;
@Column
protected String syncTime;
public SynchroRelated() {
super();
}
public SynchroRelated(String objectId, String objectName,String objectDisplayName, String objectType, String syncId, String syncName,
String originId, String originName, String originId2, String originId3, String instId) {
super();
this.objectId = objectId;
this.objectName = objectName;
this.objectDisplayName = objectDisplayName;
this.objectType = objectType;
this.syncId = syncId;
this.syncName = syncName;
this.originId = originId;
this.originName = originName;
this.originId2 = originId2;
this.originId3 = originId3;
this.instId = instId;
this.syncTime = DateUtils.formatDateTime(new Date());
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
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 getObjectDisplayName() {
return objectDisplayName;
}
public void setObjectDisplayName(String objectDisplayName) {
this.objectDisplayName = objectDisplayName;
}
public String getObjectType() {
return objectType;
}
public void setObjectType(String objectType) {
this.objectType = objectType;
}
public String getSyncId() {
return syncId;
}
public void setSyncId(String syncId) {
this.syncId = syncId;
}
public String getSyncName() {
return syncName;
}
public void setSyncName(String syncName) {
this.syncName = syncName;
}
public String getOriginId() {
return originId;
}
public void setOriginId(String originId) {
this.originId = originId;
}
public String getOriginName() {
return originName;
}
public void setOriginName(String originName) {
this.originName = originName;
}
public String getOriginId2() {
return originId2;
}
public void setOriginId2(String originId2) {
this.originId2 = originId2;
}
public String getOriginId3() {
return originId3;
}
public void setOriginId3(String originId3) {
this.originId3 = originId3;
}
public String getInstId() {
return instId;
}
public void setInstId(String instId) {
this.instId = instId;
}
public String getInstName() {
return instName;
}
public void setInstName(String instName) {
this.instName = instName;
}
public String getSyncTime() {
return syncTime;
}
public void setSyncTime(String syncTime) {
this.syncTime = syncTime;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("SynchroRelated [id=");
builder.append(id);
builder.append(", objectId=");
builder.append(objectId);
builder.append(", objectName=");
builder.append(objectName);
builder.append(", objectType=");
builder.append(objectType);
builder.append(", syncId=");
builder.append(syncId);
builder.append(", syncName=");
builder.append(syncName);
builder.append(", originId=");
builder.append(originId);
builder.append(", originId2=");
builder.append(originId2);
builder.append(", originId3=");
builder.append(originId3);
builder.append(", instId=");
builder.append(instId);
builder.append(", instName=");
builder.append(instName);
builder.append(", syncTime=");
builder.append(syncTime);
builder.append("]");
return builder.toString();
}
}

View File

@@ -44,6 +44,8 @@ import org.springframework.web.multipart.MultipartFile;
public class UserInfo extends JpaBaseEntity {
private static final long serialVersionUID = 6402443942083382236L;
public static final String CLASS_TYPE = "UserInfo";
public static final String DEFAULT_PASSWORD_SUFFIX = "MaxKey@888";
//
@@ -271,6 +273,14 @@ public class UserInfo extends JpaBaseEntity {
private String instName;
String syncId;
String syncName;
String originId;
String originId2;
List<Organizations> depts;
List<UserInfoAdjoint> adjoints;
@@ -1318,6 +1328,38 @@ public class UserInfo extends JpaBaseEntity {
this.passwordHistory = passwordHistory;
}
public String getSyncId() {
return syncId;
}
public void setSyncId(String syncId) {
this.syncId = syncId;
}
public String getSyncName() {
return syncName;
}
public void setSyncName(String syncName) {
this.syncName = syncName;
}
public String getOriginId() {
return originId;
}
public void setOriginId(String originId) {
this.originId = originId;
}
public String getOriginId2() {
return originId2;
}
public void setOriginId2(String originId2) {
this.originId2 = originId2;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();

View File

@@ -0,0 +1,24 @@
/*
* Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.maxkey.persistence.mapper;
import org.apache.mybatis.jpa.persistence.IJpaBaseMapper;
import org.maxkey.entity.SocialsAssociate;
public interface SocialsAssociateMapper extends IJpaBaseMapper<SocialsAssociate> {
}

View File

@@ -0,0 +1,34 @@
/*
* 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.ibatis.annotations.Update;
import org.apache.mybatis.jpa.persistence.IJpaBaseMapper;
import org.maxkey.entity.SynchroRelated;
/**
* @author Crystal.sea
*
*/
public interface SynchroRelatedMapper extends IJpaBaseMapper<SynchroRelated> {
@Update("update mxk_synchro_related set synctime = #{syncTime} where id= #{id} ")
public int updateSyncTime(SynchroRelated synchroRelated);
}

View File

@@ -68,11 +68,13 @@ public class OrganizationsService extends JpaBaseService<Organizations>{
}
public void saveOrUpdate(Organizations organization) {
if(findOne(" id = ? and instid = ?",
Organizations loadOrg =findOne(" id = ? and instid = ?",
new Object[] { organization.getId().toString(), organization.getInstId() },
new int[] { Types.VARCHAR, Types.VARCHAR }) == null) {
new int[] { Types.VARCHAR, Types.VARCHAR });
if( loadOrg == null) {
insert(organization);
}else {
organization.setId(organization.getId());
update(organization);
}
}

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.SocialsAssociate;
import org.maxkey.persistence.mapper.SocialsAssociateMapper;
import org.springframework.stereotype.Repository;
@Repository
public class SocialsAssociatesService extends JpaBaseService<SocialsAssociate>{
public SocialsAssociatesService() {
super(SocialsAssociateMapper.class);
}
/* (non-Javadoc)
* @see com.connsec.db.service.BaseService#getMapper()
*/
@Override
public SocialsAssociateMapper getMapper() {
return (SocialsAssociateMapper)super.getMapper();
}
}

View File

@@ -0,0 +1,77 @@
/*
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.maxkey.persistence.service;
import java.sql.Types;
import java.util.Date;
import java.util.List;
import org.apache.mybatis.jpa.persistence.JpaBaseService;
import org.maxkey.entity.Organizations;
import org.maxkey.entity.SynchroRelated;
import org.maxkey.entity.Synchronizers;
import org.maxkey.persistence.mapper.SynchroRelatedMapper;
import org.maxkey.util.DateUtils;
import org.springframework.stereotype.Repository;
@Repository
public class SynchroRelatedService extends JpaBaseService<SynchroRelated>{
public SynchroRelatedService() {
super(SynchroRelatedMapper.class);
}
/* (non-Javadoc)
* @see com.connsec.db.service.BaseService#getMapper()
*/
@Override
public SynchroRelatedMapper getMapper() {
return (SynchroRelatedMapper)super.getMapper();
}
public int updateSyncTime(SynchroRelated synchroRelated) {
return getMapper().updateSyncTime(synchroRelated);
}
public List<SynchroRelated> findOrgs(Synchronizers synchronizer) {
return find(
"instid = ? and syncid = ? and objecttype = ? ",
new Object[] { synchronizer.getInstId() ,synchronizer.getId(),Organizations.CLASS_TYPE},
new int[] { Types.VARCHAR,Types.VARCHAR,Types.VARCHAR}
);
}
public SynchroRelated findByOriginId(Synchronizers synchronizer,String originId,String classType) {
return findOne("instid = ? and syncId = ? and originid = ? and objecttype = ? ",
new Object[] { synchronizer.getInstId(),synchronizer.getId(),originId,classType },
new int[] { Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,Types.VARCHAR});
}
public void updateSynchroRelated(Synchronizers synchronizer,SynchroRelated synchroRelated,String classType) {
SynchroRelated loadSynchroRelated =
findByOriginId(
synchronizer,synchroRelated.getOriginId(),classType );
if(loadSynchroRelated == null) {
insert(synchroRelated);
}else {
synchroRelated.setId(loadSynchroRelated.getId());
synchroRelated.setSyncTime(DateUtils.formatDateTime(new Date()));
updateSyncTime(synchroRelated);
}
}
}

View File

@@ -166,11 +166,13 @@ public class UserInfoService extends JpaBaseService<UserInfo> {
public void saveOrUpdate(UserInfo userInfo) {
if(findOne(" username = ? and instid = ?",
UserInfo loadUserInfo = findOne(" username = ? and instid = ?",
new Object[] { userInfo.getUsername(),userInfo.getInstId() },
new int[] { Types.VARCHAR,Types.VARCHAR}) == null) {
new int[] { Types.VARCHAR,Types.VARCHAR});
if(loadUserInfo == null) {
insert(userInfo);
}else {
userInfo.setId(loadUserInfo.getId());
userInfo.setPassword(null);
update(userInfo);
}

View File

@@ -30,6 +30,7 @@ import org.maxkey.constants.ConstsStatus;
import org.maxkey.constants.ldap.OrganizationalUnit;
import org.maxkey.entity.HistorySynchronizer;
import org.maxkey.entity.Organizations;
import org.maxkey.entity.SynchroRelated;
import org.maxkey.persistence.ldap.ActiveDirectoryUtils;
import org.maxkey.persistence.ldap.LdapUtils;
import org.maxkey.synchronizer.AbstractSynchronizerService;
@@ -45,51 +46,13 @@ public class ActiveDirectoryOrganizationService extends AbstractSynchronizerSer
ActiveDirectoryUtils ldapUtils;
public void sync() {
loadOrgsById("1");
loadOrgsByInstId(this.synchronizer.getInstId(),Organizations.ROOT_ORG_ID);
_logger.info("Sync ActiveDirectory Organizations ...");
try {
SearchControls constraints = new SearchControls();
constraints.setSearchScope(ldapUtils.getSearchScope());
String filter = "(&(objectClass=OrganizationalUnit))";
if(StringUtils.isNotBlank(this.getSynchronizer().getFilters())) {
//filter = this.getSynchronizer().getFilters();
}
NamingEnumeration<SearchResult> results =
ldapUtils.getConnection().search(ldapUtils.getBaseDN(), filter, constraints);
ArrayList<Organizations> orgsList = new ArrayList<Organizations>();
ArrayList<Organizations> orgsList = queryActiveDirectory();
int maxLevel = 0;
long recordCount = 0;
while (null != results && results.hasMoreElements()) {
Object obj = results.nextElement();
if (obj instanceof SearchResult) {
SearchResult sr = (SearchResult) obj;
if(sr.getNameInNamespace().contains("OU=Domain Controllers")||StringUtils.isEmpty(sr.getName())) {
_logger.info("Skip '' or 'OU=Domain Controllers' .");
continue;
}
_logger.debug("Sync OrganizationalUnit {} , name [{}] , NameInNamespace [{}]" ,
(++recordCount),sr.getName(),sr.getNameInNamespace());
HashMap<String,Attribute> attributeMap = new HashMap<String,Attribute>();
NamingEnumeration<? extends Attribute> attrs = sr.getAttributes().getAll();
while (null != attrs && attrs.hasMoreElements()) {
Attribute objAttrs = attrs.nextElement();
_logger.trace("attribute {} : {}" ,
objAttrs.getID(),
ActiveDirectoryUtils.getAttrStringValue(objAttrs)
);
attributeMap.put(objAttrs.getID().toLowerCase(), objAttrs);
}
Organizations organization = buildOrganization(attributeMap,sr.getName(),sr.getNameInNamespace());
if(organization != null) {
orgsList.add(organization);
maxLevel = (maxLevel < organization.getLevel()) ? organization.getLevel() : maxLevel ;
}
}
for(Organizations organization : orgsList) {
maxLevel = (maxLevel < organization.getLevel()) ? organization.getLevel() : maxLevel ;
}
for (int level = 2 ; level <= maxLevel ; level++) {
@@ -111,7 +74,24 @@ public class ActiveDirectoryOrganizationService extends AbstractSynchronizerSer
organization.setCodePath(parentOrg.getCodePath()+"/"+organization.getId());
_logger.info("parentNamePath " + parentNamePath+" , namePah " + organization.getNamePath());
organizationsService.saveOrUpdate(organization);
//synchro Related
SynchroRelated synchroRelated =
synchroRelatedService.findByOriginId(
this.synchronizer,organization.getLdapDn(),Organizations.CLASS_TYPE );
if(synchroRelated == null) {
organization.setId(organization.generateId());
organizationsService.insert(organization);
_logger.debug("Organizations : " + organization);
synchroRelated = buildSynchroRelated(organization,organization.getLdapDn(),organization.getName());
}else {
organization.setId(synchroRelated.getObjectId());
organizationsService.update(organization);
}
synchroRelatedService.updateSynchroRelated(
this.synchronizer,synchroRelated,Organizations.CLASS_TYPE);
orgsNamePathMap.put(organization.getNamePath(), organization);
HistorySynchronizer historySynchronizer
@@ -137,6 +117,65 @@ public class ActiveDirectoryOrganizationService extends AbstractSynchronizerSer
}
private ArrayList<Organizations> queryActiveDirectory() throws NamingException {
SearchControls constraints = new SearchControls();
constraints.setSearchScope(ldapUtils.getSearchScope());
String filter = "(&(objectClass=OrganizationalUnit))";
if(StringUtils.isNotBlank(this.getSynchronizer().getFilters())) {
//filter = this.getSynchronizer().getFilters();
}
NamingEnumeration<SearchResult> results =
ldapUtils.getConnection().search(ldapUtils.getBaseDN(), filter, constraints);
ArrayList<Organizations> orgsList = new ArrayList<Organizations>();
long recordCount = 0;
while (null != results && results.hasMoreElements()) {
Object obj = results.nextElement();
if (obj instanceof SearchResult) {
SearchResult sr = (SearchResult) obj;
if(sr.getNameInNamespace().contains("OU=Domain Controllers")||StringUtils.isEmpty(sr.getName())) {
_logger.info("Skip '' or 'OU=Domain Controllers' .");
continue;
}
_logger.debug("Sync OrganizationalUnit {} , name [{}] , NameInNamespace [{}]" ,
(++recordCount),sr.getName(),sr.getNameInNamespace());
HashMap<String,Attribute> attributeMap = new HashMap<String,Attribute>();
NamingEnumeration<? extends Attribute> attrs = sr.getAttributes().getAll();
while (null != attrs && attrs.hasMoreElements()) {
Attribute objAttrs = attrs.nextElement();
_logger.trace("attribute {} : {}" ,
objAttrs.getID(),
ActiveDirectoryUtils.getAttrStringValue(objAttrs)
);
attributeMap.put(objAttrs.getID().toLowerCase(), objAttrs);
}
Organizations organization = buildOrganization(attributeMap,sr.getName(),sr.getNameInNamespace());
if(organization != null) {
orgsList.add(organization);
}
}
}
return orgsList;
}
public SynchroRelated buildSynchroRelated(Organizations organization,String ldapDN,String name) {
return new SynchroRelated(
organization.getId(),
organization.getName(),
organization.getName(),
Organizations.CLASS_TYPE,
synchronizer.getId(),
synchronizer.getName(),
ldapDN,
name,
"",
organization.getParentId(),
synchronizer.getInstId());
}
public Organizations buildOrganization(HashMap<String,Attribute> attributeMap,String name,String nameInNamespace) {
try {
Organizations org = new Organizations();

View File

@@ -27,8 +27,10 @@ import javax.naming.directory.SearchResult;
import org.apache.commons.lang3.StringUtils;
import org.maxkey.constants.ConstsStatus;
import org.maxkey.constants.ldap.ActiveDirectoryUser;
import org.maxkey.crypto.DigestUtils;
import org.maxkey.entity.HistorySynchronizer;
import org.maxkey.entity.Organizations;
import org.maxkey.entity.SynchroRelated;
import org.maxkey.entity.UserInfo;
import org.maxkey.persistence.ldap.ActiveDirectoryUtils;
import org.maxkey.persistence.ldap.LdapUtils;
@@ -46,7 +48,7 @@ public class ActiveDirectoryUsersService extends AbstractSynchronizerService
public void sync() {
_logger.info("Sync ActiveDirectory Users...");
loadOrgsById("1");
loadOrgsByInstId(this.synchronizer.getInstId(),Organizations.ROOT_ORG_ID);
try {
SearchControls constraints = new SearchControls();
constraints.setSearchScope(ldapUtils.getSearchScope());
@@ -79,11 +81,29 @@ public class ActiveDirectoryUsersService extends AbstractSynchronizerService
attributeMap.put(objAttrs.getID().toLowerCase(), objAttrs);
}
String originId = DigestUtils.md5B64(sr.getNameInNamespace());
UserInfo userInfo =buildUserInfo(attributeMap,sr.getName(),sr.getNameInNamespace());
if(userInfo != null) {
userInfo.setPassword(userInfo.getUsername() + UserInfo.DEFAULT_PASSWORD_SUFFIX);
userInfoService.saveOrUpdate(userInfo);
_logger.info("userInfo " + userInfo);
SynchroRelated synchroRelated = new SynchroRelated(
userInfo.getId(),
userInfo.getUsername(),
userInfo.getDisplayName(),
UserInfo.CLASS_TYPE,
synchronizer.getId(),
synchronizer.getName(),
originId,
userInfo.getDisplayName(),
"",
"",
synchronizer.getInstId());
synchroRelatedService.updateSynchroRelated(
this.synchronizer,synchroRelated,UserInfo.CLASS_TYPE);
}
}
}

View File

@@ -17,12 +17,12 @@
package org.maxkey.synchronizer.dingtalk;
import java.util.HashMap;
import java.util.NoSuchElementException;
import java.util.concurrent.LinkedBlockingQueue;
import org.maxkey.constants.ConstsStatus;
import org.maxkey.entity.Organizations;
import org.maxkey.entity.SynchroRelated;
import org.maxkey.synchronizer.AbstractSynchronizerService;
import org.maxkey.synchronizer.ISynchronizerService;
import org.slf4j.Logger;
@@ -30,7 +30,9 @@ import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiV2DepartmentGetRequest;
import com.dingtalk.api.request.OapiV2DepartmentListsubRequest;
import com.dingtalk.api.response.OapiV2DepartmentGetResponse;
import com.dingtalk.api.response.OapiV2DepartmentListsubResponse;
import com.dingtalk.api.response.OapiV2DepartmentListsubResponse.DeptBaseResponse;
import com.taobao.api.ApiException;
@@ -39,24 +41,67 @@ import com.taobao.api.ApiException;
public class DingtalkOrganizationService extends AbstractSynchronizerService implements ISynchronizerService{
final static Logger _logger = LoggerFactory.getLogger(DingtalkOrganizationService.class);
static Long ROOT_DEPT_ID = 1L;
String access_token;
public void sync() {
_logger.info("Sync Dingtalk Organizations ...");
LinkedBlockingQueue<Long> deptsQueue = new LinkedBlockingQueue<Long>();
deptsQueue.add(1L);
HashMap<Long,DeptBaseResponse> deptMap = new HashMap<Long,DeptBaseResponse>();
deptsQueue.add(ROOT_DEPT_ID);
try {
//root
Organizations rootOrganization = organizationsService.get(Organizations.ROOT_ORG_ID);
OapiV2DepartmentGetResponse rootDeptRsp = requestDepartment(access_token,ROOT_DEPT_ID);
_logger.debug("root dept deptId {} , name {} , parentId {}"
,rootDeptRsp.getResult().getDeptId(),
rootDeptRsp.getResult().getName(),
rootDeptRsp.getResult().getParentId());
//root
SynchroRelated rootSynchroRelated = buildSynchroRelated(rootOrganization,
rootDeptRsp.getResult().getDeptId()+"",
rootDeptRsp.getResult().getName(),
rootDeptRsp.getResult().getParentId()+"");
synchroRelatedService.updateSynchroRelated(
this.synchronizer,rootSynchroRelated,Organizations.CLASS_TYPE);
while(deptsQueue.element() != null) {
OapiV2DepartmentListsubResponse rsp = requestDepartmentList(access_token,deptsQueue.poll());
for(DeptBaseResponse dept : rsp.getResult()) {
_logger.info("dept : " + dept.getDeptId()+" "+ dept.getName()+" "+ dept.getParentId());
_logger.debug("dept deptId {} , name {} , parentId {} " ,
dept.getDeptId(),
dept.getName(),
dept.getParentId());
deptsQueue.add(dept.getDeptId());
deptMap.put(dept.getDeptId(), dept);
Organizations organization = buildOrganization(dept,deptMap.get(dept.getParentId()));
organizationsService.saveOrUpdate(organization);
_logger.info("Organizations : " + organization);
//synchro Related
SynchroRelated synchroRelated =
synchroRelatedService.findByOriginId(
this.synchronizer,dept.getDeptId() + "",Organizations.CLASS_TYPE );
Organizations organization = buildOrganization(dept);
if(synchroRelated == null) {
organization.setId(organization.generateId());
organizationsService.insert(organization);
_logger.debug("Organizations : " + organization);
synchroRelated = buildSynchroRelated(organization,
dept.getDeptId() + "",
dept.getName(),
dept.getParentId() + "");
}else {
organization.setId(synchroRelated.getObjectId());
organizationsService.update(organization);
}
synchroRelatedService.updateSynchroRelated(
this.synchronizer,synchroRelated,Organizations.CLASS_TYPE);
_logger.debug("Organizations : " + organization);
}
}
} catch (ApiException e) {
@@ -73,19 +118,48 @@ public class DingtalkOrganizationService extends AbstractSynchronizerService im
req.setDeptId(deptId);
req.setLanguage("zh_CN");
OapiV2DepartmentListsubResponse rspDepts = client.execute(req, access_token);
_logger.info("response : " + rspDepts.getBody());
_logger.trace("response : " + rspDepts.getBody());
return rspDepts;
}
public Organizations buildOrganization(DeptBaseResponse dept,DeptBaseResponse parentDept) {
public OapiV2DepartmentGetResponse requestDepartment(String access_token,Long deptId) throws ApiException {
DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/get");
OapiV2DepartmentGetRequest req = new OapiV2DepartmentGetRequest();
req.setDeptId(deptId);
req.setLanguage("zh_CN");
OapiV2DepartmentGetResponse rspDepts = client.execute(req, access_token);
_logger.trace("response : " + rspDepts.getBody());
return rspDepts;
}
public SynchroRelated buildSynchroRelated(Organizations organization,String deptId,String name,String parentId) {
return new SynchroRelated(
organization.getId(),
organization.getName(),
organization.getName(),
Organizations.CLASS_TYPE,
synchronizer.getId(),
synchronizer.getName(),
deptId+"",
name,
"",
parentId,
synchronizer.getInstId());
}
public Organizations buildOrganization(DeptBaseResponse dept) {
//Parent
SynchroRelated synchroRelatedParent =
synchroRelatedService.findByOriginId(
this.synchronizer,dept.getParentId() + "",Organizations.CLASS_TYPE);
Organizations org = new Organizations();
org.setId(dept.getDeptId()+"");
org.setCode(dept.getDeptId()+"");
org.setName(dept.getName());
org.setParentId(dept.getParentId()+"");
org.setParentCode(dept.getParentId()+"");
if(parentDept != null) {
org.setParentName(parentDept.getName());
if(synchroRelatedParent != null) {
org.setParentId(synchroRelatedParent.getObjectId());
org.setParentName(synchroRelatedParent.getObjectName());
}
org.setInstId(this.synchronizer.getInstId());
org.setStatus(ConstsStatus.ACTIVE);

View File

@@ -17,14 +17,13 @@
package org.maxkey.synchronizer.dingtalk;
import java.sql.Types;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.maxkey.constants.ConstsStatus;
import org.maxkey.entity.Organizations;
import org.maxkey.entity.SynchroRelated;
import org.maxkey.entity.UserInfo;
import org.maxkey.synchronizer.AbstractSynchronizerService;
import org.maxkey.synchronizer.ISynchronizerService;
@@ -46,17 +45,14 @@ public class DingtalkUsersService extends AbstractSynchronizerService implement
public void sync() {
_logger.info("Sync Dingtalk Users...");
try {
List<SynchroRelated> synchroRelateds =
synchroRelatedService.findOrgs(this.synchronizer);
List<Organizations> organizations =
organizationsService.find("instid = ?",
new Object[] { this.synchronizer.getInstId() },
new int[] { Types.VARCHAR});
for(Organizations dept : organizations) {
for(SynchroRelated relatedOrg : synchroRelateds) {
DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/list");
OapiV2UserListRequest req = new OapiV2UserListRequest();
_logger.info("DingTalk deptId : {}" , dept.getCode());
req.setDeptId(Long.parseLong(dept.getCode()));
_logger.debug("DingTalk deptId : {}" , relatedOrg.getOriginId());
req.setDeptId(Long.parseLong(relatedOrg.getOriginId()));
req.setCursor(0L);
req.setSize(100L);
req.setOrderField("modify_desc");
@@ -68,10 +64,28 @@ public class DingtalkUsersService extends AbstractSynchronizerService implement
if(rsp.getErrcode()==0) {
for(ListUserResponse user :rsp.getResult().getList()) {
_logger.debug("name : {} , {} , {}", user.getName(),user.getLoginId(),user.getUserid());
UserInfo userInfo = buildUserInfo(user);
UserInfo userInfo = buildUserInfo(user,relatedOrg);
_logger.trace("userInfo {}" , userInfo);
userInfo.setPassword(userInfo.getUsername() + UserInfo.DEFAULT_PASSWORD_SUFFIX);
userInfoService.saveOrUpdate(userInfo);
SynchroRelated synchroRelated = new SynchroRelated(
userInfo.getId(),
userInfo.getUsername(),
userInfo.getDisplayName(),
UserInfo.CLASS_TYPE,
synchronizer.getId(),
synchronizer.getName(),
user.getUnionid(),
user.getName(),
user.getUserid(),
"",
synchronizer.getInstId());
synchroRelatedService.updateSynchroRelated(
this.synchronizer,synchroRelated,UserInfo.CLASS_TYPE);
socialsAssociate(synchroRelated,"dingtalk");
}
}
}
@@ -83,24 +97,25 @@ public class DingtalkUsersService extends AbstractSynchronizerService implement
}
public UserInfo buildUserInfo(ListUserResponse user) {
public UserInfo buildUserInfo(ListUserResponse user,SynchroRelated relatedOrg) {
UserInfo userInfo = new UserInfo();
userInfo.setUsername(user.getUserid());//閻ц缍嶉崥锟<E5B4A5>
userInfo.setNickName(user.getName());//閻€劍鍩涢崥锟<E5B4A5>
userInfo.setDisplayName(user.getName());//閻€劍鍩涢崥锟<E5B4A5>
userInfo.setFormattedName(user.getName());//閻€劍鍩涢崥锟<E5B4A5>
userInfo.setUsername(user.getUserid());
userInfo.setNickName(user.getName());
userInfo.setDisplayName(user.getName());
userInfo.setFormattedName(user.getName());
userInfo.setEmail(StringUtils.isBlank(user.getEmail())? user.getUserid() +"@maxkey.top":user.getEmail());
userInfo.setEntryDate(new DateTime(user.getHiredDate()).toString(DateTimeFormat.forPattern("yyyy-MM-dd")));
userInfo.setMobile(user.getMobile());//閹靛婧<EE8386>
userInfo.setMobile(user.getMobile());
userInfo.setDepartmentId(user.getDeptIdList().get(0)+"");
userInfo.setDepartmentId(relatedOrg.getObjectId()+"");
userInfo.setDepartment(relatedOrg.getObjectName());
userInfo.setEmployeeNumber(user.getJobNumber());
userInfo.setJobTitle(user.getTitle());//閼卞苯濮<E88BAF>
userInfo.setWorkEmail(user.getOrgEmail());//瀹搞儰缍旈柇顔绘
userInfo.setWorkPhoneNumber(user.getTelephone());//閸忣剙寰冮悽浣冪樈
userInfo.setWorkOfficeName(user.getWorkPlace());//閸旂偛鍙曠<E98D99>癸拷
userInfo.setJobTitle(user.getTitle());
userInfo.setWorkEmail(user.getOrgEmail());
userInfo.setWorkPhoneNumber(user.getTelephone());
userInfo.setWorkOfficeName(user.getWorkPlace());
if(user.getActive()) {
userInfo.setStatus(ConstsStatus.ACTIVE);
}else {

View File

@@ -23,6 +23,7 @@ import java.util.concurrent.LinkedBlockingQueue;
import org.maxkey.constants.ConstsStatus;
import org.maxkey.entity.Organizations;
import org.maxkey.entity.SynchroRelated;
import org.maxkey.synchronizer.AbstractSynchronizerService;
import org.maxkey.synchronizer.ISynchronizerService;
import org.maxkey.synchronizer.feishu.entity.FeishuDepts;
@@ -40,30 +41,55 @@ public class FeishuOrganizationService extends AbstractSynchronizerService imple
String access_token;
static String DEPTS_URL="https://open.feishu.cn/open-apis/contact/v3/departments/%s/children?page_size=50";
static String DEPTS_URL = "https://open.feishu.cn/open-apis/contact/v3/departments/%s/children?page_size=50";
static String ROOT_DEPT_URL = "https://open.feishu.cn/open-apis/contact/v3/departments/%s";
static String ROOT_DEPT_ID = "0";
public void sync() {
_logger.info("Sync Feishu Organizations ...");
LinkedBlockingQueue<String> deptsQueue = new LinkedBlockingQueue<String>();
deptsQueue.add("0");
HashMap<String,FeishuDepts> deptMap = new HashMap<String,FeishuDepts>();
deptsQueue.add(ROOT_DEPT_ID);
//root
FeishuDeptsResponse rspRoot = requestDepartment(ROOT_DEPT_URL,ROOT_DEPT_ID,access_token);
Organizations rootOrganization = organizationsService.get(Organizations.ROOT_ORG_ID);
SynchroRelated rootSynchroRelated = buildSynchroRelated(rootOrganization,rspRoot.getData().getDepartment());
synchroRelatedService.updateSynchroRelated(
this.synchronizer,rootSynchroRelated,Organizations.CLASS_TYPE);
//child
try {
while(deptsQueue.element() != null) {
FeishuDeptsResponse rsp = requestDepartmentList(access_token,deptsQueue.poll());
if(rsp.getCode() == 0 && rsp.getData().getItems() != null) {
for(FeishuDepts dept : rsp.getData().getItems()) {
_logger.info("dept : id {} , Parent {} , Name {} , od {}" ,
_logger.debug("dept : id {} , Parent {} , Name {} , od {}" ,
dept.getDepartment_id(),
dept.getParent_department_id(),
dept.getName(),
dept.getOpen_department_id()
);
deptsQueue.add(dept.getOpen_department_id());
deptMap.put(dept.getOpen_department_id(), dept);
Organizations organization = buildOrganization(dept,deptMap.get(dept.getParent_department_id()));
organizationsService.saveOrUpdate(organization);
_logger.info("Organizations : " + organization);
//synchro Related
SynchroRelated synchroRelated =
synchroRelatedService.findByOriginId(
this.synchronizer,dept.getOpen_department_id(),Organizations.CLASS_TYPE );
Organizations organization = buildOrganization(dept);
if(synchroRelated == null) {
organization.setId(organization.generateId());
organizationsService.insert(organization);
_logger.debug("Organizations : " + organization);
synchroRelated = buildSynchroRelated(organization,dept);
}else {
organization.setId(synchroRelated.getObjectId());
organizationsService.update(organization);
}
synchroRelatedService.updateSynchroRelated(
this.synchronizer,synchroRelated,Organizations.CLASS_TYPE);
}
}
}
@@ -80,21 +106,50 @@ public class FeishuOrganizationService extends AbstractSynchronizerService imple
String responseBody = request.get(String.format(DEPTS_URL, deptId),headers);
FeishuDeptsResponse deptsResponse =JsonUtils.gson2Object(responseBody, FeishuDeptsResponse.class);
_logger.info("response : " + responseBody);
_logger.trace("response : " + responseBody);
return deptsResponse;
}
public Organizations buildOrganization(FeishuDepts dept,FeishuDepts parentDept) {
public FeishuDeptsResponse requestDepartment(String url ,String deptId ,String access_token) {
HttpRequestAdapter request =new HttpRequestAdapter();
HashMap<String,String> headers =new HashMap<String,String>();
headers.put("Authorization", AuthorizationHeaderUtils.createBearer(access_token));
String responseBody = request.get(String.format(url, deptId),headers);
FeishuDeptsResponse deptsResponse =JsonUtils.gson2Object(responseBody, FeishuDeptsResponse.class);
_logger.trace("response : " + responseBody);
return deptsResponse;
}
public SynchroRelated buildSynchroRelated(Organizations org,FeishuDepts dept) {
return new SynchroRelated(
org.getId(),
org.getName(),
org.getName(),
Organizations.CLASS_TYPE,
synchronizer.getId(),
synchronizer.getName(),
dept.getOpen_department_id(),
dept.getName(),
dept.getDepartment_id(),
dept.getParent_department_id(),
synchronizer.getInstId());
}
public Organizations buildOrganization(FeishuDepts dept) {
//Parent
SynchroRelated synchroRelatedParent =
synchroRelatedService.findByOriginId(
this.synchronizer,dept.getParent_department_id(),Organizations.CLASS_TYPE);
Organizations org = new Organizations();
org.setId(dept.getOpen_department_id()+"");
org.setCode(dept.getDepartment_id()+"");
org.setName(dept.getName());
if(parentDept == null) {
org.setParentId("1");
}else {
org.setParentId(parentDept.getOpen_department_id()+"");
}
org.setFullName(dept.getName());
org.setParentId(synchroRelatedParent.getObjectId());
org.setParentName(synchroRelatedParent.getObjectName());
org.setSortIndex(Integer.parseInt(dept.getOrder()));
org.setInstId(this.synchronizer.getInstId());
org.setStatus(ConstsStatus.ACTIVE);

View File

@@ -17,12 +17,11 @@
package org.maxkey.synchronizer.feishu;
import java.sql.Types;
import java.util.HashMap;
import java.util.List;
import org.maxkey.constants.ConstsStatus;
import org.maxkey.entity.Organizations;
import org.maxkey.entity.SynchroRelated;
import org.maxkey.entity.UserInfo;
import org.maxkey.synchronizer.AbstractSynchronizerService;
import org.maxkey.synchronizer.ISynchronizerService;
@@ -46,23 +45,41 @@ public class FeishuUsersService extends AbstractSynchronizerService implements I
public void sync() {
_logger.info("Sync Feishu Users...");
try {
List<Organizations> organizations =
organizationsService.find("instid = ?",
new Object[] { this.synchronizer.getInstId() },
new int[] { Types.VARCHAR});
for(Organizations dept : organizations) {
List<SynchroRelated> synchroRelateds =
synchroRelatedService.findOrgs(this.synchronizer);
for(SynchroRelated relatedOrg : synchroRelateds) {
HttpRequestAdapter request =new HttpRequestAdapter();
HashMap<String,String> headers =new HashMap<String,String>();
headers.put("Authorization", AuthorizationHeaderUtils.createBearer(access_token));
String responseBody = request.get(String.format(USERS_URL,dept.getId()),headers);
String responseBody = request.get(String.format(USERS_URL,relatedOrg.getOriginId()),headers);
FeishuUsersResponse usersResponse =JsonUtils.gson2Object(responseBody, FeishuUsersResponse.class);
_logger.info("response : " + responseBody);
_logger.trace("response : " + responseBody);
if(usersResponse.getCode() == 0 && usersResponse.getData().getItems() != null) {
for(FeishuUsers user : usersResponse.getData().getItems()) {
UserInfo userInfo = buildUserInfo(user);
_logger.info("userInfo : " + userInfo);
for(FeishuUsers feiShuUser : usersResponse.getData().getItems()) {
UserInfo userInfo = buildUserInfo(feiShuUser,relatedOrg);
_logger.debug("userInfo : " + userInfo);
userInfo.setPassword(userInfo.getUsername() + UserInfo.DEFAULT_PASSWORD_SUFFIX);
userInfoService.saveOrUpdate(userInfo);
SynchroRelated synchroRelated = new SynchroRelated(
userInfo.getId(),
userInfo.getUsername(),
userInfo.getDisplayName(),
UserInfo.CLASS_TYPE,
synchronizer.getId(),
synchronizer.getName(),
feiShuUser.getOpen_id(),
feiShuUser.getName(),
feiShuUser.getUser_id(),
feiShuUser.getUnion_id(),
synchronizer.getInstId());
synchroRelatedService.updateSynchroRelated(
this.synchronizer,synchroRelated,UserInfo.CLASS_TYPE);
synchroRelated.setOriginId(feiShuUser.getUnion_id());
socialsAssociate(synchroRelated,"feishu");
}
}
}
@@ -77,8 +94,9 @@ public class FeishuUsersService extends AbstractSynchronizerService implements I
}
public UserInfo buildUserInfo(FeishuUsers user) {
public UserInfo buildUserInfo(FeishuUsers user,SynchroRelated relatedOrg) {
UserInfo userInfo = new UserInfo();
userInfo.setId(userInfo.generateId());
userInfo.setUsername(user.getUser_id());//账号
userInfo.setNickName(user.getNickname());//名字
userInfo.setDisplayName(user.getName());//名字
@@ -89,7 +107,10 @@ public class FeishuUsersService extends AbstractSynchronizerService implements I
userInfo.setEmployeeNumber(user.getEmployee_no());
userInfo.setWorkPhoneNumber(user.getMobile());//工作电话
userInfo.setDepartmentId(user.getDepartment_ids()[0]+"");
userInfo.setDepartmentId(relatedOrg.getObjectId());
userInfo.setDepartment(relatedOrg.getObjectName());
userInfo.setJobTitle(user.getJob_title());//职务
userInfo.setWorkAddressFormatted(user.getWork_station());//工作地点

View File

@@ -26,6 +26,8 @@ public class FeishuDeptsData extends ResponseData {
String page_token;
ArrayList<FeishuDepts> items;
FeishuDepts department;
public boolean isHas_more() {
return has_more;
}
@@ -50,6 +52,14 @@ public class FeishuDeptsData extends ResponseData {
this.items = items;
}
public FeishuDepts getDepartment() {
return department;
}
public void setDepartment(FeishuDepts department) {
this.department = department;
}
public FeishuDeptsData() {
super();
}

View File

@@ -31,6 +31,7 @@ import org.maxkey.constants.ConstsStatus;
import org.maxkey.constants.ldap.OrganizationalUnit;
import org.maxkey.entity.HistorySynchronizer;
import org.maxkey.entity.Organizations;
import org.maxkey.entity.SynchroRelated;
import org.maxkey.persistence.ldap.LdapUtils;
import org.maxkey.synchronizer.AbstractSynchronizerService;
import org.maxkey.synchronizer.ISynchronizerService;
@@ -46,44 +47,12 @@ public class LdapOrganizationService extends AbstractSynchronizerService implem
public void sync() {
_logger.info("Sync Ldap Organizations ...");
loadOrgsById("1");
loadOrgsByInstId(this.synchronizer.getInstId(),Organizations.ROOT_ORG_ID);
try {
SearchControls constraints = new SearchControls();
constraints.setSearchScope(ldapUtils.getSearchScope());
String filter = "(&(objectClass=OrganizationalUnit))";
if(StringUtils.isNotBlank(this.getSynchronizer().getFilters())) {
//filter = this.getSynchronizer().getFilters();
}
NamingEnumeration<SearchResult> results =
ldapUtils.getConnection().search(ldapUtils.getBaseDN(), filter , constraints);
ArrayList<Organizations> orgsList = new ArrayList<Organizations>();
ArrayList<Organizations> orgsList = queryLdap();
int maxLevel = 0;
long recordCount = 0;
while (null != results && results.hasMoreElements()) {
Object obj = results.nextElement();
if (obj instanceof SearchResult) {
SearchResult sr = (SearchResult) obj;
_logger.debug("Sync OrganizationalUnit {} , name [{}] , NameInNamespace [{}]" ,
(++recordCount),sr.getName(),sr.getNameInNamespace());
HashMap<String,Attribute> attributeMap = new HashMap<String,Attribute>();
NamingEnumeration<? extends Attribute> attrs = sr.getAttributes().getAll();
while (null != attrs && attrs.hasMoreElements()) {
Attribute objAttrs = attrs.nextElement();
_logger.trace("attribute {} : {}" ,
objAttrs.getID(),
LdapUtils.getAttrStringValue(objAttrs)
);
attributeMap.put(objAttrs.getID().toLowerCase(), objAttrs);
}
Organizations organization = buildOrganization(attributeMap,sr.getName(),sr.getNameInNamespace());
if(organization != null) {
orgsList.add(organization);
maxLevel = (maxLevel < organization.getLevel()) ? organization.getLevel() : maxLevel ;
}
}
for(Organizations organization : orgsList) {
maxLevel = (maxLevel < organization.getLevel()) ? organization.getLevel() : maxLevel ;
}
for (int level = 2 ; level <= maxLevel ; level++) {
@@ -105,7 +74,24 @@ public class LdapOrganizationService extends AbstractSynchronizerService implem
organization.setCodePath(parentOrg.getCodePath()+"/"+organization.getId());
_logger.info("parentNamePath " + parentNamePath+" , namePah " + organization.getNamePath());
organizationsService.saveOrUpdate(organization);
//synchro Related
SynchroRelated synchroRelated =
synchroRelatedService.findByOriginId(
this.synchronizer,organization.getLdapDn(),Organizations.CLASS_TYPE );
if(synchroRelated == null) {
organization.setId(organization.generateId());
organizationsService.insert(organization);
_logger.debug("Organizations : " + organization);
synchroRelated = buildSynchroRelated(organization,organization.getLdapDn(),organization.getName());
}else {
organization.setId(synchroRelated.getObjectId());
organizationsService.update(organization);
}
synchroRelatedService.updateSynchroRelated(
this.synchronizer,synchroRelated,Organizations.CLASS_TYPE);
orgsNamePathMap.put(organization.getNamePath(), organization);
_logger.info("Organizations " + organization);
@@ -129,6 +115,61 @@ public class LdapOrganizationService extends AbstractSynchronizerService implem
}
private ArrayList<Organizations> queryLdap() throws NamingException {
SearchControls constraints = new SearchControls();
constraints.setSearchScope(ldapUtils.getSearchScope());
String filter = "(&(objectClass=OrganizationalUnit))";
if(StringUtils.isNotBlank(this.getSynchronizer().getFilters())) {
//filter = this.getSynchronizer().getFilters();
}
NamingEnumeration<SearchResult> results =
ldapUtils.getConnection().search(ldapUtils.getBaseDN(), filter , constraints);
ArrayList<Organizations> orgsList = new ArrayList<Organizations>();
long recordCount = 0;
while (null != results && results.hasMoreElements()) {
Object obj = results.nextElement();
if (obj instanceof SearchResult) {
SearchResult sr = (SearchResult) obj;
_logger.debug("Sync OrganizationalUnit {} , name [{}] , NameInNamespace [{}]" ,
(++recordCount),sr.getName(),sr.getNameInNamespace());
HashMap<String,Attribute> attributeMap = new HashMap<String,Attribute>();
NamingEnumeration<? extends Attribute> attrs = sr.getAttributes().getAll();
while (null != attrs && attrs.hasMoreElements()) {
Attribute objAttrs = attrs.nextElement();
_logger.trace("attribute {} : {}" ,
objAttrs.getID(),
LdapUtils.getAttrStringValue(objAttrs)
);
attributeMap.put(objAttrs.getID().toLowerCase(), objAttrs);
}
Organizations organization = buildOrganization(attributeMap,sr.getName(),sr.getNameInNamespace());
if(organization != null) {
orgsList.add(organization);
}
}
}
return orgsList;
}
public SynchroRelated buildSynchroRelated(Organizations organization,String ldapDN,String name) {
return new SynchroRelated(
organization.getId(),
organization.getName(),
organization.getName(),
Organizations.CLASS_TYPE,
synchronizer.getId(),
synchronizer.getName(),
ldapDN,
name,
"",
organization.getParentId(),
synchronizer.getInstId());
}
public Organizations buildOrganization(HashMap<String,Attribute> attributeMap,String name,String nameInNamespace) {
try {
Organizations org = new Organizations();
@@ -158,16 +199,6 @@ public class LdapOrganizationService extends AbstractSynchronizerService implem
org.setInstId(this.synchronizer.getInstId());
org.setStatus(ConstsStatus.ACTIVE);
_logger.info("org " + org);
HistorySynchronizer historySynchronizer =new HistorySynchronizer();
historySynchronizer.setId(historySynchronizer.generateId());
historySynchronizer.setSyncId(this.synchronizer.getId());
historySynchronizer.setSyncName(this.synchronizer.getName());
historySynchronizer.setObjectId(org.getId());
historySynchronizer.setObjectName(org.getName());
historySynchronizer.setObjectType(Organizations.class.getSimpleName());
historySynchronizer.setInstId(synchronizer.getInstId());
historySynchronizer.setResult("success");
this.historySynchronizerService.insert(historySynchronizer);
return org;
} catch (NamingException e) {
_logger.error("NamingException " , e);

View File

@@ -26,8 +26,10 @@ import javax.naming.directory.SearchResult;
import org.apache.commons.lang3.StringUtils;
import org.maxkey.constants.ldap.InetOrgPerson;
import org.maxkey.crypto.DigestUtils;
import org.maxkey.entity.HistorySynchronizer;
import org.maxkey.entity.Organizations;
import org.maxkey.entity.SynchroRelated;
import org.maxkey.entity.UserInfo;
import org.maxkey.persistence.ldap.LdapUtils;
import org.maxkey.synchronizer.AbstractSynchronizerService;
@@ -44,7 +46,7 @@ public class LdapUsersService extends AbstractSynchronizerService implements IS
public void sync() {
_logger.info("Sync Ldap Users ...");
loadOrgsById("1");
loadOrgsByInstId(this.synchronizer.getInstId(),Organizations.ROOT_ORG_ID);
try {
SearchControls constraints = new SearchControls();
constraints.setSearchScope(ldapUtils.getSearchScope());
@@ -71,10 +73,25 @@ public class LdapUsersService extends AbstractSynchronizerService implements IS
);
attributeMap.put(objAttrs.getID(), objAttrs);
}
String originId = DigestUtils.md5B64(sr.getNameInNamespace());
UserInfo userInfo = buildUserInfo(attributeMap,sr.getName(),sr.getNameInNamespace());
userInfo.setPassword(userInfo.getUsername() + UserInfo.DEFAULT_PASSWORD_SUFFIX);
userInfoService.saveOrUpdate(userInfo);
SynchroRelated synchroRelated = new SynchroRelated(
userInfo.getId(),
userInfo.getUsername(),
userInfo.getDisplayName(),
UserInfo.CLASS_TYPE,
synchronizer.getId(),
synchronizer.getName(),
originId,
userInfo.getDisplayName(),
"",
"",
synchronizer.getInstId());
synchroRelatedService.updateSynchroRelated(
this.synchronizer,synchroRelated,UserInfo.CLASS_TYPE);
_logger.info("userInfo " + userInfo);
}
}

View File

@@ -19,6 +19,7 @@ package org.maxkey.synchronizer.workweixin;
import org.maxkey.constants.ConstsStatus;
import org.maxkey.entity.Organizations;
import org.maxkey.entity.SynchroRelated;
import org.maxkey.synchronizer.AbstractSynchronizerService;
import org.maxkey.synchronizer.ISynchronizerService;
import org.maxkey.synchronizer.workweixin.entity.WorkWeixinDepts;
@@ -36,6 +37,7 @@ public class WorkweixinOrganizationService extends AbstractSynchronizerService i
String access_token;
static String DEPTS_URL="https://qyapi.weixin.qq.com/cgi-bin/department/list?access_token=%s";
static long ROOT_DEPT_ID = 1;
public void sync() {
_logger.info("Sync Workweixin Organizations ...");
@@ -44,9 +46,34 @@ public class WorkweixinOrganizationService extends AbstractSynchronizerService i
WorkWeixinDeptsResponse rsp = requestDepartmentList(access_token);
for(WorkWeixinDepts dept : rsp.getDepartment()) {
_logger.info("dept : " + dept.getId()+" "+ dept.getName()+" "+ dept.getParentid());
Organizations organization = buildOrganization(dept);
organizationsService.saveOrUpdate(organization);
_logger.debug("dept : " + dept.getId()+" "+ dept.getName()+" "+ dept.getParentid());
//root
if(dept.getId() == ROOT_DEPT_ID) {
Organizations rootOrganization = organizationsService.get(Organizations.ROOT_ORG_ID);
SynchroRelated rootSynchroRelated = buildSynchroRelated(rootOrganization,dept);
synchroRelatedService.updateSynchroRelated(
this.synchronizer,rootSynchroRelated,Organizations.CLASS_TYPE);
}else {
//synchro Related
SynchroRelated synchroRelated =
synchroRelatedService.findByOriginId(
this.synchronizer,dept.getId() + "",Organizations.CLASS_TYPE );
Organizations organization = buildOrganization(dept);
if(synchroRelated == null) {
organization.setId(organization.generateId());
organizationsService.insert(organization);
_logger.debug("Organizations : " + organization);
synchroRelated = buildSynchroRelated(organization,dept);
}else {
organization.setId(synchroRelated.getObjectId());
organizationsService.update(organization);
}
synchroRelatedService.updateSynchroRelated(
this.synchronizer,synchroRelated,Organizations.CLASS_TYPE);
}
}
} catch (Exception e) {
@@ -55,23 +82,43 @@ public class WorkweixinOrganizationService extends AbstractSynchronizerService i
}
public SynchroRelated buildSynchroRelated(Organizations organization,WorkWeixinDepts dept) {
return new SynchroRelated(
organization.getId(),
organization.getName(),
organization.getName(),
Organizations.CLASS_TYPE,
synchronizer.getId(),
synchronizer.getName(),
dept.getId()+"",
dept.getName(),
"",
dept.getParentid()+"",
synchronizer.getInstId());
}
public WorkWeixinDeptsResponse requestDepartmentList(String access_token) {
HttpRequestAdapter request =new HttpRequestAdapter();
String responseBody = request.get(String.format(DEPTS_URL, access_token));
WorkWeixinDeptsResponse deptsResponse =JsonUtils.gson2Object(responseBody, WorkWeixinDeptsResponse.class);
_logger.info("response : " + responseBody);
_logger.trace("response : " + responseBody);
for(WorkWeixinDepts dept : deptsResponse.getDepartment()) {
_logger.info("WorkWeixinDepts : " + dept);
_logger.debug("WorkWeixinDepts : " + dept);
}
return deptsResponse;
}
public Organizations buildOrganization(WorkWeixinDepts dept) {
//Parent
SynchroRelated synchroRelatedParent =
synchroRelatedService.findByOriginId(
this.synchronizer,dept.getParentid() + "",Organizations.CLASS_TYPE);
Organizations org = new Organizations();
org.setId(dept.getId()+"");
org.setName(dept.getName());
org.setParentId(dept.getParentid()+"");
org.setCode(dept.getId()+"");
org.setParentId(synchroRelatedParent.getObjectId());
org.setParentName(synchroRelatedParent.getObjectName());
org.setSortIndex(dept.getOrder());
org.setInstId(this.synchronizer.getInstId());
org.setStatus(ConstsStatus.ACTIVE);

View File

@@ -17,11 +17,10 @@
package org.maxkey.synchronizer.workweixin;
import java.sql.Types;
import java.util.List;
import org.maxkey.constants.ConstsStatus;
import org.maxkey.entity.Organizations;
import org.maxkey.entity.SynchroRelated;
import org.maxkey.entity.UserInfo;
import org.maxkey.synchronizer.AbstractSynchronizerService;
import org.maxkey.synchronizer.ISynchronizerService;
@@ -44,21 +43,38 @@ public class WorkweixinUsersService extends AbstractSynchronizerService implemen
public void sync() {
_logger.info("Sync Workweixin Users...");
try {
List<Organizations> organizations =
organizationsService.find("instid = ?",
new Object[] { this.synchronizer.getInstId() },
new int[] { Types.VARCHAR});
for(Organizations dept : organizations) {
List<SynchroRelated> synchroRelateds =
synchroRelatedService.findOrgs(this.synchronizer);
for(SynchroRelated relatedOrg : synchroRelateds) {
HttpRequestAdapter request =new HttpRequestAdapter();
String responseBody = request.get(String.format(USERS_URL, access_token,dept.getId()));
String responseBody = request.get(String.format(USERS_URL, access_token,relatedOrg.getOriginId()));
WorkWeixinUsersResponse usersResponse =JsonUtils.gson2Object(responseBody, WorkWeixinUsersResponse.class);
_logger.info("response : " + responseBody);
_logger.trace("response : " + responseBody);
for(WorkWeixinUsers user : usersResponse.getUserlist()) {
UserInfo userInfo = buildUserInfo(user);
_logger.info("userInfo : " + userInfo);
_logger.debug("userInfo : " + userInfo);
userInfo.setPassword(userInfo.getUsername() + UserInfo.DEFAULT_PASSWORD_SUFFIX);
userInfoService.saveOrUpdate(userInfo);
SynchroRelated synchroRelated = new SynchroRelated(
userInfo.getId(),
userInfo.getUsername(),
userInfo.getDisplayName(),
UserInfo.CLASS_TYPE,
synchronizer.getId(),
synchronizer.getName(),
user.getUserid(),
user.getName(),
user.getUserid(),
"",
synchronizer.getInstId());
synchroRelatedService.updateSynchroRelated(
this.synchronizer,synchroRelated,UserInfo.CLASS_TYPE);
socialsAssociate(synchroRelated,"workweixin");
}
}

View File

@@ -17,14 +17,19 @@
package org.maxkey.synchronizer;
import java.sql.Types;
import java.util.HashMap;
import java.util.List;
import org.maxkey.entity.Organizations;
import org.maxkey.entity.SocialsAssociate;
import org.maxkey.entity.SynchroRelated;
import org.maxkey.entity.Synchronizers;
import org.maxkey.persistence.service.HistorySynchronizerService;
import org.maxkey.persistence.service.OrganizationsService;
import org.maxkey.persistence.service.SynchroRelatedService;
import org.maxkey.persistence.service.UserInfoService;
import org.maxkey.persistence.service.SocialsAssociatesService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -35,10 +40,12 @@ public abstract class AbstractSynchronizerService {
@Autowired
protected OrganizationsService organizationsService;
@Autowired
protected UserInfoService userInfoService;
@Autowired
protected SynchroRelatedService synchroRelatedService;
@Autowired
protected SocialsAssociatesService socialsAssociatesService;
@Autowired
protected HistorySynchronizerService historySynchronizerService;
@@ -49,20 +56,20 @@ public abstract class AbstractSynchronizerService {
protected Organizations rootOrganization = null;
public HashMap<String,Organizations> loadOrgsById(String orgId) {
List<Organizations> orgsList = organizationsService.query(null);
if(orgId== null || orgId.equals("")) {
orgId="1";
public HashMap<String,Organizations> loadOrgsByInstId(String instId,String rootOrgId) {
List<Organizations> orgsList = organizationsService.find("instid = '" + instId + "'");
if(rootOrgId== null || rootOrgId.equals("")) {
rootOrgId="1";
}
for(Organizations org : orgsList) {
if(org.getId().equals(orgId) && orgId.equals("1")) {
if(org.getId().equals(rootOrgId) && rootOrgId.equals("1")) {
rootOrganization = org;
rootOrganization.setNamePath("/"+rootOrganization.getName());
rootOrganization.setCodePath("/1");
rootOrganization.setParentId("-1");
rootOrganization.setParentName("");
}else if(org.getId().equals(orgId)){
}else if(org.getId().equals(rootOrgId)){
rootOrganization = org;
}
}
@@ -75,6 +82,26 @@ public abstract class AbstractSynchronizerService {
return orgsNamePathMap;
}
public void socialsAssociate(SynchroRelated synchroRelated,String provider) {
SocialsAssociate socialsAssociate =
socialsAssociatesService.findOne("instid = ? and userid = ? and socialuserid = ? and provider = ? ",
new Object[] {
synchroRelated.getInstId(),
synchroRelated.getObjectId(),
synchroRelated.getOriginId(),
provider
},
new int[] { Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,Types.VARCHAR});
if(socialsAssociate == null) {
socialsAssociate = new SocialsAssociate();
socialsAssociate.setUserId(synchroRelated.getObjectId());
socialsAssociate.setUsername(synchroRelated.getObjectName());
socialsAssociate.setInstId(synchroRelated.getInstId());
socialsAssociate.setProvider(provider);
socialsAssociate.setSocialUserId(synchroRelated.getOriginId());
socialsAssociatesService.insert(socialsAssociate);
}
}
public void push(HashMap<String,Organizations> orgsNamePathMap,
List<Organizations> orgsList,
Organizations parentOrg) {
@@ -141,6 +168,14 @@ public abstract class AbstractSynchronizerService {
public void setHistorySynchronizerService(HistorySynchronizerService historySynchronizerService) {
this.historySynchronizerService = historySynchronizerService;
}
public SynchroRelatedService getSynchroRelatedService() {
return synchroRelatedService;
}
public void setSynchroRelatedService(SynchroRelatedService synchroRelatedService) {
this.synchroRelatedService = synchroRelatedService;
}
}

View File

@@ -21,10 +21,10 @@ import java.util.ArrayList;
import java.util.List;
import org.maxkey.authn.support.socialsignon.service.SocialSignOnProviderService;
import org.maxkey.authn.support.socialsignon.service.SocialsAssociate;
import org.maxkey.authn.support.socialsignon.service.SocialsAssociateService;
import org.maxkey.configuration.ApplicationConfig;
import org.maxkey.entity.Institutions;
import org.maxkey.entity.SocialsAssociate;
import org.maxkey.entity.SocialsProvider;
import org.maxkey.web.WebConstants;
import org.maxkey.web.WebContext;

View File

@@ -3,7 +3,7 @@
<head>
<#include "../layout/header.ftl"/>
<#include "../layout/common.cssjs.ftl"/>
<#setting number_format="#">
<script type="text/javascript">
$(function () {