diff --git a/.checkstyle b/.checkstyle
index 19a2e7322..578ce7a58 100644
--- a/.checkstyle
+++ b/.checkstyle
@@ -2,6 +2,6 @@
-
+
diff --git a/build.gradle b/build.gradle
index 745a237c2..6806793f8 100644
--- a/build.gradle
+++ b/build.gradle
@@ -31,11 +31,15 @@ allprojects {
compileJava.options.encoding = 'UTF-8'
eclipse {
+
jdt {
File f = file('.settings/org.eclipse.core.resources.prefs')
f.write('eclipse.preferences.version=1\n')
f.append('encoding/=UTF-8') //use UTF-8
- }/*
+ }
+ /**/
+
+ /*
wtp {
facet {
facet name: 'jst.web', type: Facet.FacetType.fixed
@@ -174,7 +178,7 @@ subprojects {
//compile group: 'org.springframework', name: 'spring-jcl', version: "${springVersion}"
compile group: 'org.springframework', name: 'spring-jdbc', version: "${springVersion}"
//compile group: 'org.springframework', name: 'spring-jms', version: "${springVersion}"
- //compile group: 'org.springframework', name: 'spring-messaging', version: "${springVersion}"
+ compile group: 'org.springframework', name: 'spring-messaging', version: "${springVersion}"
//compile group: 'org.springframework', name: 'spring-orm', version: "${springVersion}"
compile group: 'org.springframework', name: 'spring-oxm', version: "${springVersion}"
compile group: 'org.springframework', name: 'spring-tx', version: "${springVersion}"
@@ -183,6 +187,15 @@ subprojects {
compile group: 'org.springframework', name: 'spring-webmvc', version: "${springVersion}"
//compile group: 'org.springframework', name: 'spring-websocket', version: "${springVersion}"
testCompile group: 'org.springframework', name: 'spring-test', version: "${springVersion}"
+
+ // https://mvnrepository.com/artifact/org.apache.kafka/kafka-clients
+ compile group: 'org.apache.kafka', name: 'kafka-clients', version: '2.5.0'
+ // https://mvnrepository.com/artifact/org.springframework.kafka/spring-kafka
+ compile group: 'org.springframework.kafka', name: 'spring-kafka', version: '2.5.2.RELEASE'
+ // https://mvnrepository.com/artifact/org.springframework.retry/spring-retry
+ compile group: 'org.springframework.retry', name: 'spring-retry', version: '1.3.0'
+
+
//spring-security
compile group: 'org.springframework.security', name: 'spring-security-core', version: "${springSecurityVersion}"
compile group: 'org.springframework.security', name: 'spring-security-web', version: "${springSecurityVersion}"
diff --git a/maxkey-connectors/.classpath b/maxkey-connectors/.classpath
new file mode 100644
index 000000000..eb19361b5
--- /dev/null
+++ b/maxkey-connectors/.classpath
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/maxkey-connectors/.project b/maxkey-connectors/.project
new file mode 100644
index 000000000..a5cb9f4f0
--- /dev/null
+++ b/maxkey-connectors/.project
@@ -0,0 +1,28 @@
+
+
+ maxkey-connectors
+ Project maxkey-connectors created by Buildship.
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.buildship.core.gradleprojectbuilder
+
+
+
+
+ org.springframework.ide.eclipse.boot.validation.springbootbuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.eclipse.buildship.core.gradleprojectnature
+
+
diff --git a/maxkey-connectors/maxkey-connector-activedirectory/.classpath b/maxkey-connectors/maxkey-connector-activedirectory/.classpath
new file mode 100644
index 000000000..eca1d9e92
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-activedirectory/.classpath
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/maxkey-connectors/maxkey-connector-activedirectory/.project b/maxkey-connectors/maxkey-connector-activedirectory/.project
new file mode 100644
index 000000000..4e5ff56cb
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-activedirectory/.project
@@ -0,0 +1,41 @@
+
+
+ maxkey-connector-activedirectory
+ Project maxkey-connectors-activedirectory created by Buildship.
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.wst.common.project.facet.core.builder
+
+
+
+
+ org.eclipse.wst.validation.validationbuilder
+
+
+
+
+ org.eclipse.buildship.core.gradleprojectbuilder
+
+
+
+
+ org.springframework.ide.eclipse.boot.validation.springbootbuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.eclipse.wst.common.project.facet.core.nature
+ org.eclipse.wst.common.modulecore.ModuleCoreNature
+ org.eclipse.jem.workbench.JavaEMFNature
+ org.eclipse.buildship.core.gradleprojectnature
+
+
diff --git a/maxkey-connectors/maxkey-connector-activedirectory/.settings/org.eclipse.buildship.core.prefs b/maxkey-connectors/maxkey-connector-activedirectory/.settings/org.eclipse.buildship.core.prefs
new file mode 100644
index 000000000..62e3e7e80
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-activedirectory/.settings/org.eclipse.buildship.core.prefs
@@ -0,0 +1,2 @@
+connection.project.dir=../..
+eclipse.preferences.version=1
diff --git a/maxkey-connectors/maxkey-connector-activedirectory/.settings/org.eclipse.core.resources.prefs b/maxkey-connectors/maxkey-connector-activedirectory/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 000000000..896a9a53a
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-activedirectory/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/=UTF-8
\ No newline at end of file
diff --git a/maxkey-connectors/maxkey-connector-activedirectory/.settings/org.eclipse.jdt.core.prefs b/maxkey-connectors/maxkey-connector-activedirectory/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..8f838df8f
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-activedirectory/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,14 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.builder.cleanOutputFolder=clean
+org.eclipse.jdt.core.builder.duplicateResourceTask=warning
+org.eclipse.jdt.core.builder.invalidClasspath=abort
+org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore
+org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch
+org.eclipse.jdt.core.circularClasspath=warning
+org.eclipse.jdt.core.classpath.exclusionPatterns=enabled
+org.eclipse.jdt.core.classpath.mainOnlyProjectHasTestOnlyDependency=error
+org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled
+org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource=error
+org.eclipse.jdt.core.compiler.maxProblemPerUnit=100
+org.eclipse.jdt.core.incompatibleJDKLevel=ignore
+org.eclipse.jdt.core.incompleteClasspath=error
diff --git a/maxkey-connectors/maxkey-connector-activedirectory/.settings/org.eclipse.jdt.launching.prefs b/maxkey-connectors/maxkey-connector-activedirectory/.settings/org.eclipse.jdt.launching.prefs
new file mode 100644
index 000000000..f8a131b56
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-activedirectory/.settings/org.eclipse.jdt.launching.prefs
@@ -0,0 +1,3 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.launching.PREF_COMPILER_COMPLIANCE_DOES_NOT_MATCH_JRE=warning
+org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=warning
diff --git a/maxkey-connectors/maxkey-connector-activedirectory/.settings/org.eclipse.wst.common.component b/maxkey-connectors/maxkey-connector-activedirectory/.settings/org.eclipse.wst.common.component
new file mode 100644
index 000000000..0378cad10
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-activedirectory/.settings/org.eclipse.wst.common.component
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+ uses
+
+
+ uses
+
+
+ uses
+
+
+ uses
+
+
+ uses
+
+
+
diff --git a/maxkey-connectors/maxkey-connector-activedirectory/.settings/org.eclipse.wst.common.project.facet.core.xml b/maxkey-connectors/maxkey-connector-activedirectory/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..509bad92c
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-activedirectory/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/maxkey-connectors/maxkey-connector-activedirectory/.settings/org.springframework.ide.eclipse.prefs b/maxkey-connectors/maxkey-connector-activedirectory/.settings/org.springframework.ide.eclipse.prefs
new file mode 100644
index 000000000..a12794d68
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-activedirectory/.settings/org.springframework.ide.eclipse.prefs
@@ -0,0 +1,2 @@
+boot.validation.initialized=true
+eclipse.preferences.version=1
diff --git a/maxkey-connectors/maxkey-connector-activedirectory/build.gradle b/maxkey-connectors/maxkey-connector-activedirectory/build.gradle
new file mode 100644
index 000000000..dfac86e67
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-activedirectory/build.gradle
@@ -0,0 +1,17 @@
+description = "maxkey-connector-activedirectory"
+
+apply plugin: 'java'
+apply plugin: 'eclipse-wtp'
+
+
+dependencies {
+ //local jars
+ compile fileTree(dir: '../maxkey-lib/*/', include: '*.jar')
+
+ compile project(":maxkey-core")
+ compile project(":maxkey-dao")
+ compile project(":maxkey-client-sdk")
+ compile project(":maxkey-connectors:maxkey-connector-base")
+ compile project(":maxkey-identitys:maxkey-identity-kafka")
+
+}
\ No newline at end of file
diff --git a/maxkey-connectors/maxkey-connector-activedirectory/src/main/java/org/maxkey/connector/ActivedirectoryConsumerApplication.java b/maxkey-connectors/maxkey-connector-activedirectory/src/main/java/org/maxkey/connector/ActivedirectoryConsumerApplication.java
new file mode 100644
index 000000000..6fbec6be7
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-activedirectory/src/main/java/org/maxkey/connector/ActivedirectoryConsumerApplication.java
@@ -0,0 +1,56 @@
+package org.maxkey.connector;
+
+import org.maxkey.constants.ConstantsProperties;
+import org.maxkey.persistence.ldap.ActiveDirectoryUtils;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+
+@Configuration
+@PropertySource(ConstantsProperties.applicationPropertySource)
+@SpringBootApplication
+@ComponentScan(basePackages = {
+ "org.maxkey.connector",
+ "org.maxkey.connector.receiver",
+ "org.maxkey.connector.activedirectory"
+ })
+public class ActivedirectoryConsumerApplication {
+
+ public static void main(String[] args) {
+ ConfigurableApplicationContext context = SpringApplication.run(ActivedirectoryConsumerApplication.class, args);
+
+ }
+
+ //@Bean(name = "activeDirectoryUtils")
+ public ActiveDirectoryUtils getLdapConnection(
+ @Value("${config.connector.activedirectory.providerUrl}") String providerUrl,
+ @Value("${config.connector.activedirectory.principal}") String principal,
+ @Value("${config.connector.activedirectory.credentials}") String credentials,
+ @Value("${config.connector.activedirectory.baseDN}") String baseDn,
+ @Value("${config.connector.activedirectory.domain}") String domain,
+ @Value("${config.connector.activedirectory.trustStore}") String trustStore,
+ @Value("${config.connector.activedirectory.trustStore.password}") String trustStorePassword
+ )throws Exception{
+ ActiveDirectoryUtils ldapUtils=new ActiveDirectoryUtils(
+ providerUrl,
+ principal,
+ credentials,
+ baseDn,
+ domain);
+
+ ldapUtils.setTrustStore(trustStore);
+ ldapUtils.setTrustStorePassword(trustStorePassword);
+ ldapUtils.setSsl(true);
+
+ if(ldapUtils.openConnection()==null){
+ throw new Exception("connection to Ldap Error.");
+ }
+ return ldapUtils;
+ }
+
+}
diff --git a/maxkey-connectors/maxkey-connector-activedirectory/src/main/java/org/maxkey/connector/activedirectory/Group2Activedirectory.java b/maxkey-connectors/maxkey-connector-activedirectory/src/main/java/org/maxkey/connector/activedirectory/Group2Activedirectory.java
new file mode 100644
index 000000000..2990e65c3
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-activedirectory/src/main/java/org/maxkey/connector/activedirectory/Group2Activedirectory.java
@@ -0,0 +1,181 @@
+package org.maxkey.connector.activedirectory;
+
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttribute;
+import javax.naming.directory.BasicAttributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.ModificationItem;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+
+import org.maxkey.connector.GroupConnector;
+import org.maxkey.domain.GroupMember;
+import org.maxkey.domain.Groups;
+import org.maxkey.persistence.ldap.ActiveDirectoryUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+@Component(value = "groupConnector")
+public class Group2Activedirectory extends GroupConnector {
+ private final static Logger logger = LoggerFactory.getLogger(Group2Activedirectory.class);
+
+ ActiveDirectoryUtils ldapUtils;
+
+ public Group2Activedirectory() {
+ // TODO Auto-generated constructor stub
+ }
+ @Override
+ public boolean create(Groups group) throws Exception{
+ logger.info("create");
+ try {
+ Attributes attributes = new BasicAttributes();
+ Attribute objectClass = new BasicAttribute("objectClass");
+ objectClass.add("top");
+ objectClass.add("group");
+ attributes.put(objectClass);
+
+ attributes.put(new BasicAttribute("cn",group.getName()));
+ attributes.put(new BasicAttribute("member","CN=dummy,"+ldapUtils.getBaseDN()));
+
+ String dn="cn="+group.getName()+",cn=groups,"+ldapUtils.getBaseDN();
+
+ ldapUtils.getCtx().createSubcontext(dn, attributes);
+ ldapUtils.close();
+ } catch (NamingException e) {
+ e.printStackTrace();
+ }
+ return true;
+ }
+
+ @Override
+ public boolean update(Groups group) throws Exception{
+ logger.info("update");
+ try {
+ SearchControls constraints = new SearchControls();
+ constraints.setSearchScope(ldapUtils.getSearchScope());
+ NamingEnumeration results = ldapUtils.getConnection()
+ .search(ldapUtils.getBaseDN(), "(cn="+group.getName()+")", constraints);
+ String oldDn="";
+ String rdn="";
+ if (results == null || !results.hasMore()) {
+ return create(group);
+ }else{
+ SearchResult sr = (SearchResult) results.next();
+ oldDn =sr.getNameInNamespace();
+ String[] dnSplit=oldDn.split(",");
+ rdn=oldDn.substring(oldDn.indexOf(","), oldDn.length());
+
+ String groupName=dnSplit[0].split("=")[1];
+ if(group.getName()!=groupName){
+ String newDn="cn="+group.getName()+","+rdn;
+ ldapUtils.getCtx().rename(oldDn, newDn);
+ ModificationItem[] modificationItems = new ModificationItem[1];
+ modificationItems[0]=new ModificationItem(DirContext.REMOVE_ATTRIBUTE,new BasicAttribute("cn",groupName));
+ ldapUtils.getCtx().modifyAttributes(newDn, modificationItems);
+ }
+ }
+
+ ldapUtils.close();
+ } catch (NamingException e) {
+ e.printStackTrace();
+ }
+ return true;
+ }
+
+ @Override
+ public boolean delete(Groups group) throws Exception {
+ logger.info("delete");
+ try {
+ String dn="cn="+group.getName()+",cn=groups,"+ldapUtils.getBaseDN();
+ ldapUtils.getCtx().destroySubcontext(dn);
+ ldapUtils.close();
+ } catch (NamingException e) {
+ e.printStackTrace();
+ }
+ return true;
+ }
+
+ @Override
+ public boolean addMember(GroupMember groupMember) throws Exception {
+ try {
+ SearchControls constraints = new SearchControls();
+ constraints.setSearchScope(ldapUtils.getSearchScope());
+ NamingEnumeration results = ldapUtils.getConnection()
+ .search(ldapUtils.getBaseDN(), "(cn="+groupMember.getGroupName()+")", constraints);
+ if (results == null || !results.hasMore()) {
+ Groups group =new Groups();
+ group.setName(groupMember.getGroupName());
+ return create(group);
+ }
+
+
+ String uniqueMember="";
+ SearchControls memberSearchControls = new SearchControls();
+ logger.debug("user Search : "+"(sAMAccountName="+groupMember.getMemberName()+")");
+ memberSearchControls.setSearchScope(ldapUtils.getSearchScope());
+ NamingEnumeration memberResults = ldapUtils.getConnection()
+ .search(ldapUtils.getBaseDN(), "(sAMAccountName="+groupMember.getMemberName()+")", memberSearchControls);
+ if (memberResults == null || !memberResults.hasMore()) {
+
+ }else{
+ SearchResult memberSr = (SearchResult) memberResults.next();
+ uniqueMember =memberSr.getNameInNamespace();
+ logger.debug("uniqueMember : "+uniqueMember);
+ ModificationItem[] modificationItems = new ModificationItem[1];
+ modificationItems[0]=new ModificationItem(DirContext.ADD_ATTRIBUTE,new BasicAttribute("member",uniqueMember));
+
+ String dn="cn="+groupMember.getGroupName()+",cn=groups,"+ldapUtils.getBaseDN();
+
+ ldapUtils.getCtx().modifyAttributes(dn, modificationItems);
+ }
+
+
+ ldapUtils.close();
+ } catch (NamingException e) {
+ e.printStackTrace();
+ }
+ return true;
+ }
+
+ @Override
+ public boolean deleteMember(GroupMember groupMember) throws Exception{
+ try {
+ SearchControls constraints = new SearchControls();
+ constraints.setSearchScope(ldapUtils.getSearchScope());
+ NamingEnumeration results = ldapUtils.getConnection()
+ .search(ldapUtils.getBaseDN(), "(cn="+groupMember.getGroupName()+")", constraints);
+ if (results == null || !results.hasMore()) {
+ return true;
+ }
+
+ String uniqueMember="";
+ SearchControls memberSearchControls = new SearchControls();
+ memberSearchControls.setSearchScope(ldapUtils.getSearchScope());
+ NamingEnumeration memberResults = ldapUtils.getConnection()
+ .search(ldapUtils.getBaseDN(), "(sAMAccountName="+groupMember.getMemberName()+")", memberSearchControls);
+ if (memberResults == null || !memberResults.hasMore()) {
+
+ }else{
+ SearchResult memberSr = (SearchResult) memberResults.next();
+ uniqueMember =memberSr.getNameInNamespace();
+ logger.debug("uniqueMember : "+uniqueMember);
+ ModificationItem[] modificationItems = new ModificationItem[1];
+ modificationItems[0]=new ModificationItem(DirContext.REMOVE_ATTRIBUTE,new BasicAttribute("member",uniqueMember));
+
+ String dn="cn="+groupMember.getGroupName()+",cn=groups,"+ldapUtils.getBaseDN();
+
+ ldapUtils.getCtx().modifyAttributes(dn, modificationItems);
+ }
+
+ ldapUtils.close();
+ } catch (NamingException e) {
+ e.printStackTrace();
+ }
+ return true;
+ }
+
+}
diff --git a/maxkey-connectors/maxkey-connector-activedirectory/src/main/java/org/maxkey/connector/activedirectory/Organization2Activedirectory.java b/maxkey-connectors/maxkey-connector-activedirectory/src/main/java/org/maxkey/connector/activedirectory/Organization2Activedirectory.java
new file mode 100644
index 000000000..2ffe3f127
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-activedirectory/src/main/java/org/maxkey/connector/activedirectory/Organization2Activedirectory.java
@@ -0,0 +1,124 @@
+package org.maxkey.connector.activedirectory;
+
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttribute;
+import javax.naming.directory.BasicAttributes;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+
+import org.maxkey.connector.OrganizationConnector;
+import org.maxkey.domain.Organizations;
+import org.maxkey.persistence.ldap.ActiveDirectoryUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+@Component(value = "organizationConnector")
+public class Organization2Activedirectory extends OrganizationConnector{
+ private final static Logger logger = LoggerFactory.getLogger(Organization2Activedirectory.class);
+
+ ActiveDirectoryUtils ldapUtils;
+
+ public Organization2Activedirectory() {
+ // TODO Auto-generated constructor stub
+ }
+
+ @Override
+ public boolean create(Organizations organization) throws Exception {
+ try {
+ SearchControls constraints = new SearchControls();
+ constraints.setSearchScope(ldapUtils.getSearchScope());
+ NamingEnumeration results = ldapUtils.getConnection()
+ .search(ldapUtils.getBaseDN(), "(&(objectClass=organizationalUnit)(description="+organization.getpId()+"))", constraints);
+ String rdn="";
+ if (results == null || !results.hasMore()) {
+ rdn=ldapUtils.getBaseDN();
+ }else{
+ SearchResult sr = (SearchResult) results.next();
+ rdn =sr.getNameInNamespace();
+ }
+
+ Attributes attributes = new BasicAttributes();
+ attributes.put(new BasicAttribute("objectClass","organizationalUnit"));
+ attributes.put(new BasicAttribute("ou",organization.getName()));
+ //attributes.put(new BasicAttribute("name",organization.getName()));
+ //attributes.put(new BasicAttribute("id",organization.getId()));
+ //attributes.put(new BasicAttribute("porgname",organization.getpName()));
+ //attributes.put(new BasicAttribute("porgid",organization.getpId()));
+ attributes.put(new BasicAttribute("description",organization.getId()));
+
+ String dn="ou="+organization.getName()+","+rdn;
+
+ ldapUtils.getCtx().createSubcontext(dn, attributes);
+ ldapUtils.close();
+
+ } catch (NamingException e) {
+ e.printStackTrace();
+ }
+ return super.create(organization);
+ }
+
+ @Override
+ public boolean update(Organizations organization) throws Exception{
+ try {
+ SearchControls constraints = new SearchControls();
+ constraints.setSearchScope(ldapUtils.getSearchScope());
+ NamingEnumeration results = ldapUtils.getConnection()
+ .search(ldapUtils.getBaseDN(), "(&(objectClass=organizationalUnit)(description="+organization.getId()+"))", constraints);
+ String oldDn="";
+ String rdn="";
+ if (results == null || !results.hasMore()) {
+ return create(organization);
+ }else{
+ SearchResult sr = (SearchResult) results.next();
+ oldDn =sr.getNameInNamespace();
+ String[] dnSplit=oldDn.split(",");
+ rdn=oldDn.substring(oldDn.indexOf(",")+1, oldDn.length());
+
+ String ouName=dnSplit[0].split("=")[1];
+ if(organization.getName()!=ouName){
+ String newDn="ou="+organization.getName()+","+rdn;
+ logger.debug("oldDn : "+oldDn);
+ logger.debug("newDn : "+newDn);
+ ldapUtils.getCtx().rename(oldDn, newDn);
+
+ //ModificationItem[] modificationItems = new ModificationItem[1];
+ //modificationItems[0]=new ModificationItem(DirContext.REMOVE_ATTRIBUTE,new BasicAttribute("ou",ouName));
+ //modificationItems[0]=new ModificationItem(DirContext.REPLACE_ATTRIBUTE,new BasicAttribute("name",organization.getName()));
+ //ldapUtils.getCtx().modifyAttributes(newDn, modificationItems);
+ }
+ }
+
+ ldapUtils.close();
+ } catch (NamingException e) {
+ e.printStackTrace();
+ }
+ return super.update(organization);
+ }
+
+ @Override
+ public boolean delete(Organizations organization) throws Exception {
+ try {
+ SearchControls constraints = new SearchControls();
+ constraints.setSearchScope(ldapUtils.getSearchScope());
+ NamingEnumeration results = ldapUtils.getConnection()
+ .search(ldapUtils.getBaseDN(), "(&(objectClass=organizationalUnit)(description="+organization.getId()+"))", constraints);
+ String dn="";
+ if (results == null || !results.hasMore()) {
+
+ }else{
+ SearchResult sr = (SearchResult) results.next();
+ dn =sr.getNameInNamespace();
+ ldapUtils.getCtx().destroySubcontext(dn);
+ }
+
+ ldapUtils.close();
+ } catch (NamingException e) {
+ e.printStackTrace();
+ }
+ return super.delete(organization);
+ }
+
+}
diff --git a/maxkey-connectors/maxkey-connector-activedirectory/src/main/java/org/maxkey/connector/activedirectory/Password2Activedirectory.java b/maxkey-connectors/maxkey-connector-activedirectory/src/main/java/org/maxkey/connector/activedirectory/Password2Activedirectory.java
new file mode 100644
index 000000000..02203f061
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-activedirectory/src/main/java/org/maxkey/connector/activedirectory/Password2Activedirectory.java
@@ -0,0 +1,86 @@
+package org.maxkey.connector.activedirectory;
+
+import java.io.UnsupportedEncodingException;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.BasicAttribute;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.ModificationItem;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+
+import org.maxkey.connector.PasswordConnector;
+import org.maxkey.crypto.ReciprocalUtils;
+import org.maxkey.domain.UserInfo;
+import org.maxkey.persistence.ldap.ActiveDirectoryUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+@Component(value = "passwordConnector")
+public class Password2Activedirectory extends PasswordConnector{
+ private final static Logger logger = LoggerFactory.getLogger(Password2Activedirectory.class);
+ ActiveDirectoryUtils ldapUtils;
+ /**
+ * userAccountControl鍊煎緱璇存槑
+ * http://support.microsoft.com/zh-cn/kb/305144
+ * 灞炴�ф爣蹇� 鍗佸叚杩涘埗鍊� 鍗佽繘鍒跺��
+ SCRIPT 0x0001 1
+ ACCOUNTDISABLE 0x0002 2
+ HOMEDIR_REQUIRED 0x0008 8
+ LOCKOUT 0x0010 16
+ PASSWD_NOTREQD 0x0020 32
+ PASSWD_CANT_CHANGE 0x0040 64
+ ENCRYPTED_TEXT_PWD_ALLOWED 0x0080 128
+ TEMP_DUPLICATE_ACCOUNT 0x0100 256
+ NORMAL_ACCOUNT 0x0200 512
+ INTERDOMAIN_TRUST_ACCOUNT 0x0800 2048
+ WORKSTATION_TRUST_ACCOUNT 0x1000 4096
+ SERVER_TRUST_ACCOUNT 0x2000 8192
+ DONT_EXPIRE_PASSWORD 0x10000 65536
+ MNS_LOGON_ACCOUNT 0x20000 131072
+ SMARTCARD_REQUIRED 0x40000 262144
+ TRUSTED_FOR_DELEGATION 0x80000 524288
+ NOT_DELEGATED 0x100000 1048576
+ USE_DES_KEY_ONLY 0x200000 2097152
+ DONT_REQ_PREAUTH 0x400000 4194304
+ PASSWORD_EXPIRED 0x800000 8388608
+ TRUSTED_TO_AUTH_FOR_DELEGATION 0x1000000 16777216
+ */
+ public Password2Activedirectory() {
+
+ }
+
+ @Override
+ public boolean sync(UserInfo userInfo) throws Exception{
+ try {
+ String dn=null;
+ SearchControls searchControls = new SearchControls();
+ searchControls.setSearchScope(ldapUtils.getSearchScope());
+ NamingEnumeration results = ldapUtils.getConnection()
+ .search(ldapUtils.getBaseDN(), "(sAMAccountName="+userInfo.getUsername()+")", searchControls);
+ if (results == null || !results.hasMore()) {
+
+ }else{
+ SearchResult sr = (SearchResult) results.next();
+ dn =sr.getNameInNamespace();
+ ModificationItem[] modificationItems = new ModificationItem[1];
+ logger.info("decipherable : "+userInfo.getDecipherable());
+ String password=ReciprocalUtils.decoder(userInfo.getDecipherable());
+ //modificationItems[0]=new ModificationItem(DirContext.REPLACE_ATTRIBUTE,new BasicAttribute("userPassword",password));
+ modificationItems[0]=new ModificationItem(DirContext.REPLACE_ATTRIBUTE,new BasicAttribute("unicodePwd",("\"" + password + "\"").getBytes("UTF-16LE")));
+
+ ldapUtils.getCtx().modifyAttributes(dn, modificationItems);
+ }
+
+ ldapUtils.close();
+ } catch (NamingException e) {
+ e.printStackTrace();
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }
+ return true;
+ }
+
+
+}
diff --git a/maxkey-connectors/maxkey-connector-activedirectory/src/main/java/org/maxkey/connector/activedirectory/UserInfo2Activedirectory.java b/maxkey-connectors/maxkey-connector-activedirectory/src/main/java/org/maxkey/connector/activedirectory/UserInfo2Activedirectory.java
new file mode 100644
index 000000000..fc7e71f4d
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-activedirectory/src/main/java/org/maxkey/connector/activedirectory/UserInfo2Activedirectory.java
@@ -0,0 +1,271 @@
+package org.maxkey.connector.activedirectory;
+
+import java.io.UnsupportedEncodingException;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttribute;
+import javax.naming.directory.BasicAttributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.ModificationItem;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+
+import org.maxkey.connector.UserInfoConnector;
+import org.maxkey.crypto.ReciprocalUtils;
+import org.maxkey.domain.UserInfo;
+import org.maxkey.persistence.ldap.ActiveDirectoryUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+@Component(value = "userInfoConnector")
+public class UserInfo2Activedirectory extends UserInfoConnector{
+ private final static Logger logger = LoggerFactory.getLogger(UserInfo2Activedirectory.class);
+ ActiveDirectoryUtils ldapUtils;
+ /**
+ * userAccountControl值得说明
+ * http://support.microsoft.com/zh-cn/kb/305144
+ * 属�?�标�? 十六进制�? 十进制�??
+ SCRIPT 0x0001 1
+ ACCOUNTDISABLE 0x0002 2
+ HOMEDIR_REQUIRED 0x0008 8
+ LOCKOUT 0x0010 16
+ PASSWD_NOTREQD 0x0020 32
+ PASSWD_CANT_CHANGE 0x0040 64
+ ENCRYPTED_TEXT_PWD_ALLOWED 0x0080 128
+ TEMP_DUPLICATE_ACCOUNT 0x0100 256
+ NORMAL_ACCOUNT 0x0200 512
+ INTERDOMAIN_TRUST_ACCOUNT 0x0800 2048
+ WORKSTATION_TRUST_ACCOUNT 0x1000 4096
+ SERVER_TRUST_ACCOUNT 0x2000 8192
+ DONT_EXPIRE_PASSWORD 0x10000 65536
+ MNS_LOGON_ACCOUNT 0x20000 131072
+ SMARTCARD_REQUIRED 0x40000 262144
+ TRUSTED_FOR_DELEGATION 0x80000 524288
+ NOT_DELEGATED 0x100000 1048576
+ USE_DES_KEY_ONLY 0x200000 2097152
+ DONT_REQ_PREAUTH 0x400000 4194304
+ PASSWORD_EXPIRED 0x800000 8388608
+ TRUSTED_TO_AUTH_FOR_DELEGATION 0x1000000 16777216
+ */
+ public UserInfo2Activedirectory() {
+
+ }
+
+ @Override
+ public boolean create(UserInfo userInfo) throws Exception{
+ try {
+ Attributes attributes = new BasicAttributes();
+ Attribute objectClass = new BasicAttribute("objectClass");
+ objectClass.add("top");
+ objectClass.add("person");
+ objectClass.add("organizationalPerson");
+ objectClass.add("user");
+ attributes.put(objectClass);
+ attributes.put(new BasicAttribute("sAMAccountName",userInfo.getUsername()));
+ logger.debug("decipherable : "+userInfo.getDecipherable());
+ String password=ReciprocalUtils.decoder(userInfo.getDecipherable());
+
+ attributes.put(new BasicAttribute("unicodePwd",("\"" + password + "\"").getBytes("UTF-16LE")));
+ //attributes.put(new BasicAttribute("cn",userInfo.getDisplayName()));
+ attributes.put(new BasicAttribute("cn",userInfo.getUsername()));
+ attributes.put(new BasicAttribute("displayName",userInfo.getDisplayName()));
+ attributes.put(new BasicAttribute("givenName",userInfo.getGivenName()));
+ attributes.put(new BasicAttribute("sn",userInfo.getFamilyName()));
+
+ attributes.put(new BasicAttribute("mobile",userInfo.getWorkPhoneNumber()==null?"00000000000":userInfo.getWorkPhoneNumber()));
+ attributes.put(new BasicAttribute("mail",userInfo.getWorkEmail()==null?"email@default.com":userInfo.getWorkEmail()));
+
+ attributes.put(new BasicAttribute("employeeNumber",userInfo.getEmployeeNumber()==null?"0":userInfo.getEmployeeNumber()));
+ attributes.put(new BasicAttribute("ou",userInfo.getDepartment()==null?"default":userInfo.getDepartment()));
+ String managerDn="CN=dummy,"+ldapUtils.getBaseDN();
+ if(userInfo.getManagerId()==null||userInfo.getManagerId().equals("")){
+ logger.debug("manager is null.");
+ }else{
+ UserInfo queryManager=new UserInfo();
+ queryManager.setId(userInfo.getManagerId());
+ UserInfo manager=loadUser(queryManager);
+ SearchControls managerSearchControls = new SearchControls();
+ managerSearchControls.setSearchScope(ldapUtils.getSearchScope());
+ logger.debug("managerResults : "+ldapUtils.getBaseDN());
+ logger.debug("filter : "+"(sAMAccountName="+manager.getUsername()+")");
+ logger.debug("managerSearchControls : "+managerSearchControls);
+ NamingEnumeration managerResults = ldapUtils.getConnection()
+ .search(ldapUtils.getBaseDN(), "(sAMAccountName="+manager.getUsername()+")", managerSearchControls);
+ if (managerResults == null || !managerResults.hasMore()) {
+
+ }else{
+ SearchResult managerSr = (SearchResult) managerResults.next();
+ managerDn =managerSr.getNameInNamespace();
+ }
+ }
+
+ attributes.put(new BasicAttribute("manager",managerDn));
+
+ attributes.put(new BasicAttribute("department",userInfo.getDepartment()==null?"default":userInfo.getDepartment()));
+ attributes.put(new BasicAttribute("departmentNumber",userInfo.getDepartmentId()==null?"default":userInfo.getDepartmentId()));
+ attributes.put(new BasicAttribute("title",userInfo.getJobTitle()==null?"default":userInfo.getJobTitle()));
+
+ //for kerberos login
+ attributes.put(new BasicAttribute("servicePrincipalName",this.properties.getProperty("servicePrincipalName")));
+ attributes.put(new BasicAttribute("userPrincipalName",userInfo.getUsername()+"@"+this.properties.getProperty("domain")));
+
+ attributes.put(new BasicAttribute("userAccountControl",Integer.toString(66048)));
+ String rdn="";
+ if(userInfo.getDepartmentId()!=null&&
+ !userInfo.getDepartmentId().equals("")){
+ //get organization dn
+ SearchControls searchControls = new SearchControls();
+ searchControls.setSearchScope(ldapUtils.getSearchScope());
+ logger.debug("managerResults : "+ldapUtils.getBaseDN());
+ logger.debug("filter : "+"(&(objectClass=organizationalUnit)(description="+userInfo.getDepartmentId()+"))");
+ logger.debug("searchControls : "+searchControls);
+ NamingEnumeration results = ldapUtils.getConnection()
+ .search(ldapUtils.getBaseDN(), "(&(objectClass=organizationalUnit)(description="+userInfo.getDepartmentId()+"))", searchControls);
+
+ if (results == null || !results.hasMore()) {
+ rdn=ldapUtils.getBaseDN();
+ }else{
+ SearchResult sr = (SearchResult) results.next();
+ rdn =sr.getNameInNamespace();
+ }
+ }else{
+ rdn=ldapUtils.getBaseDN();
+ }
+
+ //String dn="CN="+userInfo.getDisplayName()+","+rdn;
+ String dn="CN="+userInfo.getUsername()+","+rdn;
+
+ logger.debug("dn : "+dn);
+ ldapUtils.getCtx().createSubcontext(dn, attributes);
+ ldapUtils.close();
+ super.create(userInfo);
+ } catch (NamingException e) {
+ e.printStackTrace();
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }
+ return true;
+ }
+
+ @Override
+ public boolean update(UserInfo userInfo) throws Exception{
+ try {
+ String dn=null;
+ SearchControls searchControls = new SearchControls();
+ searchControls.setSearchScope(ldapUtils.getSearchScope());
+ NamingEnumeration results = ldapUtils.getConnection()
+ .search(ldapUtils.getBaseDN(), "(sAMAccountName="+userInfo.getUsername()+")", searchControls);
+ if (results == null || !results.hasMore()) {
+ return create(loadUser(userInfo));
+ }
+
+ SearchResult sr = (SearchResult) results.next();
+ dn =sr.getNameInNamespace();
+
+ ModificationItem[] modificationItems = new ModificationItem[8];
+ //modificationItems[0]=new ModificationItem(DirContext.REPLACE_ATTRIBUTE,new BasicAttribute("displayName",userInfo.getDisplayName()));
+ //modificationItems[1]=new ModificationItem(DirContext.REPLACE_ATTRIBUTE,new BasicAttribute("cn",userInfo.getDisplayName()));
+ //modificationItems[2]=new ModificationItem(DirContext.REPLACE_ATTRIBUTE,new BasicAttribute("givenName",userInfo.getGivenName()));
+ //modificationItems[3]=new ModificationItem(DirContext.REPLACE_ATTRIBUTE,new BasicAttribute("sn",userInfo.getFamilyName()));
+
+ modificationItems[0]=new ModificationItem(DirContext.REPLACE_ATTRIBUTE,new BasicAttribute("mobile",userInfo.getWorkPhoneNumber()==null?"00000000000":userInfo.getWorkPhoneNumber()));
+ modificationItems[1]=new ModificationItem(DirContext.REPLACE_ATTRIBUTE,new BasicAttribute("mail",userInfo.getWorkEmail()==null?"email@default.com":userInfo.getWorkEmail()));
+
+ modificationItems[2]=new ModificationItem(DirContext.REPLACE_ATTRIBUTE,new BasicAttribute("employeeNumber",userInfo.getEmployeeNumber()==null?"default":userInfo.getEmployeeNumber()));
+ modificationItems[3]=new ModificationItem(DirContext.REPLACE_ATTRIBUTE,new BasicAttribute("ou",userInfo.getDepartment()==null?"default":userInfo.getDepartment()));
+
+ modificationItems[4]=new ModificationItem(DirContext.REPLACE_ATTRIBUTE,new BasicAttribute("department",userInfo.getDepartmentId()==null?"default":userInfo.getDepartment()));
+ modificationItems[5]=new ModificationItem(DirContext.REPLACE_ATTRIBUTE,new BasicAttribute("departmentNumber",userInfo.getDepartmentId()==null?"default":userInfo.getDepartmentId()));
+ modificationItems[6]=new ModificationItem(DirContext.REPLACE_ATTRIBUTE,new BasicAttribute("title",userInfo.getJobTitle()==null?"default":userInfo.getJobTitle()));
+
+ String managerDn="CN=dummy,"+ldapUtils.getBaseDN();
+ if(userInfo.getManagerId()==null||userInfo.getManagerId().equals("")){
+
+ }else{
+ UserInfo queryManager=new UserInfo();
+ queryManager.setId(userInfo.getManagerId());
+ UserInfo manager=loadUser(queryManager);
+ SearchControls managerSearchControls = new SearchControls();
+ managerSearchControls.setSearchScope(ldapUtils.getSearchScope());
+ NamingEnumeration managerResults = ldapUtils.getConnection()
+ .search(ldapUtils.getBaseDN(), "(sAMAccountName="+manager.getUsername()+")", managerSearchControls);
+ if (managerResults == null || !managerResults.hasMore()) {
+
+ }else{
+ SearchResult managerSr = (SearchResult) managerResults.next();
+ managerDn =managerSr.getNameInNamespace();
+ }
+ }
+
+ modificationItems[7]=new ModificationItem(DirContext.REPLACE_ATTRIBUTE,new BasicAttribute("manager",managerDn));
+
+
+ ldapUtils.getCtx().modifyAttributes(dn, modificationItems);
+
+ if(userInfo.getDepartmentId()!=null&&
+ !userInfo.getDepartmentId().equals("")){
+ //get organization dn
+ SearchControls orgSearchControls = new SearchControls();
+ orgSearchControls.setSearchScope(ldapUtils.getSearchScope());
+ NamingEnumeration orgResults = ldapUtils.getConnection()
+ .search(ldapUtils.getBaseDN(), "(&(objectClass=organizationalUnit)(description="+userInfo.getDepartmentId()+"))", orgSearchControls);
+ String orgRdn="";
+ if (orgResults == null || !orgResults.hasMore()) {
+ orgRdn=ldapUtils.getBaseDN();
+ }else{
+ SearchResult orgSearchResult = (SearchResult) orgResults.next();
+ orgRdn =orgSearchResult.getNameInNamespace();
+ }
+
+ //String newDn="CN="+userInfo.getDisplayName()+","+orgRdn;
+ String newDn="CN="+userInfo.getUsername()+","+orgRdn;
+
+ if(!dn.equals(newDn)){
+ logger.debug("oldDn : "+dn);
+ logger.debug("newDn : "+newDn);
+ ldapUtils.getCtx().rename(dn, newDn);
+ }
+ }
+
+ ldapUtils.close();
+ } catch (NamingException e) {
+ e.printStackTrace();
+ }
+ return true;
+ }
+
+ @Override
+ public boolean delete(UserInfo userInfo) throws Exception{
+ try {
+ String dn=null;
+ SearchControls searchControls = new SearchControls();
+ searchControls.setSearchScope(ldapUtils.getSearchScope());
+ NamingEnumeration results = ldapUtils.getConnection()
+ .search(ldapUtils.getBaseDN(), "(sAMAccountName="+userInfo.getUsername()+")", searchControls);
+ if (results == null || !results.hasMore()) {
+
+ }else{
+ SearchResult sr = (SearchResult) results.next();
+ dn =sr.getNameInNamespace();
+ logger.debug("delete dn : "+dn);
+ ldapUtils.getCtx().destroySubcontext(dn);
+ }
+
+ ldapUtils.close();
+ super.delete(userInfo);
+ } catch (NamingException e) {
+ e.printStackTrace();
+ }
+ return true;
+ }
+
+
+ public UserInfo loadUser(UserInfo UserInfo) {
+ return null;
+ }
+
+
+}
diff --git a/maxkey-connectors/maxkey-connector-activedirectory/src/main/resources/application.properties b/maxkey-connectors/maxkey-connector-activedirectory/src/main/resources/application.properties
new file mode 100644
index 000000000..45cd2b6ac
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-activedirectory/src/main/resources/application.properties
@@ -0,0 +1,48 @@
+#spring.profiles.active=dev
+#application
+application.title=MaxKey-Connector-ActiveDirectory
+application.name=MaxKey-Connector-ActiveDirectory
+application.formatted-version=v2.0.0 GA
+#server port
+server.port=9602
+#datasource
+spring.datasource.username=root
+spring.datasource.password=maxkey
+spring.datasource.url=jdbc:mysql://localhost/maxkey?autoReconnect=true&characterEncoding=UTF-8
+spring.datasource.driver-class-name=com.mysql.jdbc.Driver
+spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
+
+spring.kafka.bootstrap-servers=localhost:9092
+###########【初始化消费者配置】###########
+# 默认的消费组ID
+spring.kafka.consumer.properties.group.id=defaultConsumerGroup
+# 是否自动提交offset
+spring.kafka.consumer.enable-auto-commit=true
+# 提交offset延时(接收到消息后多久提交offset)
+spring.kafka.consumer.auto.commit.interval.ms=1000
+# 当kafka中没有初始offset或offset超出范围时将自动重置offset
+# earliest:重置为分区中最小的offset;
+# latest:重置为分区中最新的offset(消费分区中新产生的数据);
+# none:只要有一个分区不存在已提交的offset,就抛出异常;
+spring.kafka.consumer.auto-offset-reset=latest
+# 消费会话超时时间(超过这个时间consumer没有发送心跳,就会触发rebalance操作)
+spring.kafka.consumer.properties.session.timeout.ms=120000
+# 消费请求超时时间
+spring.kafka.consumer.properties.request.timeout.ms=180000
+# Kafka提供的序列化和反序列化类
+spring.kafka.consumer.key-deserializer=org.apache.kafka.common.serialization.StringDeserializer
+spring.kafka.consumer.value-deserializer=org.apache.kafka.common.serialization.StringDeserializer
+# 消费端监听的topic不存在时,项目启动会报错(关掉)
+spring.kafka.listener.missing-topics-fatal=false
+# 设置批量消费
+# spring.kafka.listener.type=batch
+# 批量消费每次最多消费多少条消息
+# spring.kafka.consumer.max-poll-records=50
+
+config.connector.activedirectory.providerUrl=ldap://
+config.connector.activedirectory.principal=maxkey
+config.connector.activedirectory.credentials=maxkey
+config.connector.activedirectory.baseDN=dc=maxkey,dc=top
+config.connector.activedirectory.domain=MAXKEY
+config.connector.activedirectory.trustStore=maxkey
+config.connector.activedirectory.trustStore.password=maxkey
\ No newline at end of file
diff --git a/maxkey-connectors/maxkey-connector-base/.classpath b/maxkey-connectors/maxkey-connector-base/.classpath
new file mode 100644
index 000000000..eca1d9e92
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-base/.classpath
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/maxkey-connectors/maxkey-connector-base/.project b/maxkey-connectors/maxkey-connector-base/.project
new file mode 100644
index 000000000..17871f197
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-base/.project
@@ -0,0 +1,41 @@
+
+
+ maxkey-connector-base
+ Project maxkey-connectors-base created by Buildship.
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.wst.common.project.facet.core.builder
+
+
+
+
+ org.eclipse.wst.validation.validationbuilder
+
+
+
+
+ org.eclipse.buildship.core.gradleprojectbuilder
+
+
+
+
+ org.springframework.ide.eclipse.boot.validation.springbootbuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.eclipse.wst.common.project.facet.core.nature
+ org.eclipse.wst.common.modulecore.ModuleCoreNature
+ org.eclipse.jem.workbench.JavaEMFNature
+ org.eclipse.buildship.core.gradleprojectnature
+
+
diff --git a/maxkey-connectors/maxkey-connector-base/.settings/org.eclipse.buildship.core.prefs b/maxkey-connectors/maxkey-connector-base/.settings/org.eclipse.buildship.core.prefs
new file mode 100644
index 000000000..62e3e7e80
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-base/.settings/org.eclipse.buildship.core.prefs
@@ -0,0 +1,2 @@
+connection.project.dir=../..
+eclipse.preferences.version=1
diff --git a/maxkey-connectors/maxkey-connector-base/.settings/org.eclipse.core.resources.prefs b/maxkey-connectors/maxkey-connector-base/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 000000000..896a9a53a
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-base/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/=UTF-8
\ No newline at end of file
diff --git a/maxkey-connectors/maxkey-connector-base/.settings/org.eclipse.jdt.core.prefs b/maxkey-connectors/maxkey-connector-base/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..8f838df8f
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-base/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,14 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.builder.cleanOutputFolder=clean
+org.eclipse.jdt.core.builder.duplicateResourceTask=warning
+org.eclipse.jdt.core.builder.invalidClasspath=abort
+org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore
+org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch
+org.eclipse.jdt.core.circularClasspath=warning
+org.eclipse.jdt.core.classpath.exclusionPatterns=enabled
+org.eclipse.jdt.core.classpath.mainOnlyProjectHasTestOnlyDependency=error
+org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled
+org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource=error
+org.eclipse.jdt.core.compiler.maxProblemPerUnit=100
+org.eclipse.jdt.core.incompatibleJDKLevel=ignore
+org.eclipse.jdt.core.incompleteClasspath=error
diff --git a/maxkey-connectors/maxkey-connector-base/.settings/org.eclipse.jdt.launching.prefs b/maxkey-connectors/maxkey-connector-base/.settings/org.eclipse.jdt.launching.prefs
new file mode 100644
index 000000000..f8a131b56
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-base/.settings/org.eclipse.jdt.launching.prefs
@@ -0,0 +1,3 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.launching.PREF_COMPILER_COMPLIANCE_DOES_NOT_MATCH_JRE=warning
+org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=warning
diff --git a/maxkey-connectors/maxkey-connector-base/.settings/org.eclipse.wst.common.component b/maxkey-connectors/maxkey-connector-base/.settings/org.eclipse.wst.common.component
new file mode 100644
index 000000000..15251077e
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-base/.settings/org.eclipse.wst.common.component
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+ uses
+
+
+ uses
+
+
+ uses
+
+
+ uses
+
+
+
diff --git a/maxkey-connectors/maxkey-connector-base/.settings/org.eclipse.wst.common.project.facet.core.xml b/maxkey-connectors/maxkey-connector-base/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..509bad92c
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-base/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/maxkey-connectors/maxkey-connector-base/.settings/org.springframework.ide.eclipse.prefs b/maxkey-connectors/maxkey-connector-base/.settings/org.springframework.ide.eclipse.prefs
new file mode 100644
index 000000000..a12794d68
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-base/.settings/org.springframework.ide.eclipse.prefs
@@ -0,0 +1,2 @@
+boot.validation.initialized=true
+eclipse.preferences.version=1
diff --git a/maxkey-connectors/maxkey-connector-base/build.gradle b/maxkey-connectors/maxkey-connector-base/build.gradle
new file mode 100644
index 000000000..817503184
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-base/build.gradle
@@ -0,0 +1,16 @@
+description = "maxkey-connector-base"
+
+apply plugin: 'java'
+apply plugin: 'eclipse-wtp'
+
+
+dependencies {
+ //local jars
+ compile fileTree(dir: '../maxkey-lib/*/', include: '*.jar')
+
+ compile project(":maxkey-core")
+ compile project(":maxkey-dao")
+ compile project(":maxkey-client-sdk")
+ compile project(":maxkey-identitys:maxkey-identity-kafka")
+
+}
\ No newline at end of file
diff --git a/maxkey-connectors/maxkey-connector-base/src/main/java/org/maxkey/connector/AbstractConnector.java b/maxkey-connectors/maxkey-connector-base/src/main/java/org/maxkey/connector/AbstractConnector.java
new file mode 100644
index 000000000..ac7aa500d
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-base/src/main/java/org/maxkey/connector/AbstractConnector.java
@@ -0,0 +1,53 @@
+package org.maxkey.connector;
+
+import java.util.Properties;
+
+import org.springframework.jdbc.core.JdbcTemplate;
+
+
+public abstract class AbstractConnector{
+
+
+ public static class CONNECTOR_TYPE{
+ public static int USERINFO_TYPE=1;
+ public static int ORG_TYPE=2;
+ public static int GROUP_TYPE=3;
+ public static int PASSWORD_TYPE=4;
+ }
+
+ protected Properties properties;
+
+ protected JdbcTemplate jdbcTemplate;
+
+ public boolean create(T entity) throws Exception{
+ return true;
+ }
+
+ public boolean update(T entity) throws Exception{
+ return true;
+ }
+
+ public boolean delete(T entity) throws Exception{
+ return true;
+ }
+
+ public Properties getProperties() {
+ return properties;
+ }
+
+ public void setProperties(Properties properties) {
+ this.properties = properties;
+ }
+
+ public JdbcTemplate getJdbcTemplate() {
+ return jdbcTemplate;
+ }
+
+ public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
+ this.jdbcTemplate = jdbcTemplate;
+ }
+
+
+
+
+}
diff --git a/maxkey-connectors/maxkey-connector-base/src/main/java/org/maxkey/connector/GroupConnector.java b/maxkey-connectors/maxkey-connector-base/src/main/java/org/maxkey/connector/GroupConnector.java
new file mode 100644
index 000000000..fa244d324
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-base/src/main/java/org/maxkey/connector/GroupConnector.java
@@ -0,0 +1,33 @@
+package org.maxkey.connector;
+
+import org.maxkey.domain.GroupMember;
+import org.maxkey.domain.Groups;
+
+public abstract class GroupConnector extends AbstractConnector {
+
+ @Override
+ public boolean create(Groups group) throws Exception{
+ return true;
+ }
+
+ @Override
+ public boolean update(Groups group) throws Exception{
+ return true;
+ }
+
+ @Override
+ public boolean delete(Groups group) throws Exception{
+ return true;
+ }
+
+
+ public boolean addMember(GroupMember groupMember) throws Exception{
+ return true;
+ }
+
+
+ public boolean deleteMember(GroupMember groupMember) throws Exception{
+ return true;
+ }
+
+}
diff --git a/maxkey-connectors/maxkey-connector-base/src/main/java/org/maxkey/connector/OrganizationConnector.java b/maxkey-connectors/maxkey-connector-base/src/main/java/org/maxkey/connector/OrganizationConnector.java
new file mode 100644
index 000000000..461628419
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-base/src/main/java/org/maxkey/connector/OrganizationConnector.java
@@ -0,0 +1,22 @@
+package org.maxkey.connector;
+
+import org.maxkey.domain.Organizations;
+
+public abstract class OrganizationConnector extends AbstractConnector {
+
+ @Override
+ public boolean create(Organizations organization) throws Exception{
+ return true;
+ }
+
+ @Override
+ public boolean update(Organizations organization) throws Exception{
+ return true;
+ }
+
+ @Override
+ public boolean delete(Organizations organization) throws Exception{
+ return true;
+ }
+
+}
diff --git a/maxkey-connectors/maxkey-connector-base/src/main/java/org/maxkey/connector/PasswordConnector.java b/maxkey-connectors/maxkey-connector-base/src/main/java/org/maxkey/connector/PasswordConnector.java
new file mode 100644
index 000000000..36a139ce2
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-base/src/main/java/org/maxkey/connector/PasswordConnector.java
@@ -0,0 +1,13 @@
+package org.maxkey.connector;
+
+import org.maxkey.domain.UserInfo;
+
+public abstract class PasswordConnector extends AbstractConnector {
+
+ public boolean sync(UserInfo userInfo) throws Exception{
+ return true;
+ }
+
+
+
+}
diff --git a/maxkey-connectors/maxkey-connector-base/src/main/java/org/maxkey/connector/UserInfoConnector.java b/maxkey-connectors/maxkey-connector-base/src/main/java/org/maxkey/connector/UserInfoConnector.java
new file mode 100644
index 000000000..8d49b038a
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-base/src/main/java/org/maxkey/connector/UserInfoConnector.java
@@ -0,0 +1,23 @@
+package org.maxkey.connector;
+
+import org.maxkey.domain.UserInfo;
+
+public abstract class UserInfoConnector extends AbstractConnector {
+
+ @Override
+ public boolean create(UserInfo userInfo) throws Exception {
+ return true;
+ }
+
+ @Override
+ public boolean update(UserInfo userInfo) throws Exception{
+ return true;
+ }
+
+ @Override
+ public boolean delete(UserInfo userInfo) throws Exception{
+ return true;
+ }
+
+
+}
diff --git a/maxkey-connectors/maxkey-connector-base/src/main/java/org/maxkey/connector/receiver/KafkaGroupsTopicReceiver.java b/maxkey-connectors/maxkey-connector-base/src/main/java/org/maxkey/connector/receiver/KafkaGroupsTopicReceiver.java
new file mode 100644
index 000000000..216d9e596
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-base/src/main/java/org/maxkey/connector/receiver/KafkaGroupsTopicReceiver.java
@@ -0,0 +1,34 @@
+package org.maxkey.connector.receiver;
+
+import java.util.Optional;
+
+import org.apache.kafka.clients.consumer.ConsumerRecord;
+import org.maxkey.connector.GroupConnector;
+import org.maxkey.identity.kafka.KafkaIdentityTopic;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.kafka.annotation.KafkaListener;
+import org.springframework.stereotype.Component;
+@Component
+public class KafkaGroupsTopicReceiver {
+ private static final Logger _logger = LoggerFactory.getLogger(KafkaGroupsTopicReceiver.class);
+
+ @Autowired
+ GroupConnector groupConnector;
+
+ @KafkaListener(topics = {KafkaIdentityTopic.GROUP_TOPIC})
+ public void listen(ConsumerRecord, ?> record) {
+
+ Optional> kafkaMessage = Optional.ofNullable(record.value());
+
+ if (kafkaMessage.isPresent()) {
+
+ Object message = kafkaMessage.get();
+
+ _logger.info("----------------- record =" + record);
+ _logger.info("------------------ message =" + message);
+ }
+
+ }
+}
diff --git a/maxkey-connectors/maxkey-connector-base/src/main/java/org/maxkey/connector/receiver/KafkaOrgsTopicReceiver.java b/maxkey-connectors/maxkey-connector-base/src/main/java/org/maxkey/connector/receiver/KafkaOrgsTopicReceiver.java
new file mode 100644
index 000000000..1c6fadfe1
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-base/src/main/java/org/maxkey/connector/receiver/KafkaOrgsTopicReceiver.java
@@ -0,0 +1,34 @@
+package org.maxkey.connector.receiver;
+
+import java.util.Optional;
+
+import org.apache.kafka.clients.consumer.ConsumerRecord;
+import org.maxkey.connector.OrganizationConnector;
+import org.maxkey.identity.kafka.KafkaIdentityTopic;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.kafka.annotation.KafkaListener;
+import org.springframework.stereotype.Component;
+@Component
+public class KafkaOrgsTopicReceiver {
+ private static final Logger _logger = LoggerFactory.getLogger(KafkaOrgsTopicReceiver.class);
+
+ @Autowired
+ OrganizationConnector organizationConnector;
+
+ @KafkaListener(topics = {KafkaIdentityTopic.ORG_TOPIC})
+ public void listen(ConsumerRecord, ?> record) {
+
+ Optional> kafkaMessage = Optional.ofNullable(record.value());
+
+ if (kafkaMessage.isPresent()) {
+
+ Object message = kafkaMessage.get();
+
+ _logger.info("----------------- record =" + record);
+ _logger.info("------------------ message =" + message);
+ }
+
+ }
+}
diff --git a/maxkey-connectors/maxkey-connector-base/src/main/java/org/maxkey/connector/receiver/KafkaPasswordTopicReceiver.java b/maxkey-connectors/maxkey-connector-base/src/main/java/org/maxkey/connector/receiver/KafkaPasswordTopicReceiver.java
new file mode 100644
index 000000000..afdcbad8a
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-base/src/main/java/org/maxkey/connector/receiver/KafkaPasswordTopicReceiver.java
@@ -0,0 +1,34 @@
+package org.maxkey.connector.receiver;
+
+import java.util.Optional;
+
+import org.apache.kafka.clients.consumer.ConsumerRecord;
+import org.maxkey.connector.PasswordConnector;
+import org.maxkey.identity.kafka.KafkaIdentityTopic;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.kafka.annotation.KafkaListener;
+import org.springframework.stereotype.Component;
+@Component
+public class KafkaPasswordTopicReceiver {
+ private static final Logger _logger = LoggerFactory.getLogger(KafkaPasswordTopicReceiver.class);
+
+ @Autowired
+ PasswordConnector passwordConnector;
+
+ @KafkaListener(topics = {KafkaIdentityTopic.PASSWORD_TOPIC})
+ public void listen(ConsumerRecord, ?> record) {
+
+ Optional> kafkaMessage = Optional.ofNullable(record.value());
+
+ if (kafkaMessage.isPresent()) {
+
+ Object message = kafkaMessage.get();
+
+ _logger.info("----------------- record =" + record);
+ _logger.info("------------------ message =" + message);
+ }
+
+ }
+}
diff --git a/maxkey-connectors/maxkey-connector-base/src/main/java/org/maxkey/connector/receiver/KafkaUserInfoTopicReceiver.java b/maxkey-connectors/maxkey-connector-base/src/main/java/org/maxkey/connector/receiver/KafkaUserInfoTopicReceiver.java
new file mode 100644
index 000000000..b0ff56ff7
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-base/src/main/java/org/maxkey/connector/receiver/KafkaUserInfoTopicReceiver.java
@@ -0,0 +1,34 @@
+package org.maxkey.connector.receiver;
+
+import java.util.Optional;
+
+import org.apache.kafka.clients.consumer.ConsumerRecord;
+import org.maxkey.connector.UserInfoConnector;
+import org.maxkey.identity.kafka.KafkaIdentityTopic;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.kafka.annotation.KafkaListener;
+import org.springframework.stereotype.Component;
+@Component
+public class KafkaUserInfoTopicReceiver {
+ private static final Logger _logger = LoggerFactory.getLogger(KafkaUserInfoTopicReceiver.class);
+
+ @Autowired
+ UserInfoConnector userInfoConnector;
+
+ @KafkaListener(topics = {KafkaIdentityTopic.USERINFO_TOPIC})
+ public void listen(ConsumerRecord, ?> record) {
+
+ Optional> kafkaMessage = Optional.ofNullable(record.value());
+
+ if (kafkaMessage.isPresent()) {
+
+ Object message = kafkaMessage.get();
+
+ _logger.info("----------------- record =" + record);
+ _logger.info("------------------ message =" + message);
+ }
+
+ }
+}
diff --git a/maxkey-connectors/maxkey-connector-ldap/.classpath b/maxkey-connectors/maxkey-connector-ldap/.classpath
new file mode 100644
index 000000000..eca1d9e92
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-ldap/.classpath
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/maxkey-connectors/maxkey-connector-ldap/.project b/maxkey-connectors/maxkey-connector-ldap/.project
new file mode 100644
index 000000000..dadcf381a
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-ldap/.project
@@ -0,0 +1,41 @@
+
+
+ maxkey-connector-ldap
+ Project maxkey-connectors-ldap created by Buildship.
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.wst.common.project.facet.core.builder
+
+
+
+
+ org.eclipse.wst.validation.validationbuilder
+
+
+
+
+ org.eclipse.buildship.core.gradleprojectbuilder
+
+
+
+
+ org.springframework.ide.eclipse.boot.validation.springbootbuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.eclipse.wst.common.project.facet.core.nature
+ org.eclipse.wst.common.modulecore.ModuleCoreNature
+ org.eclipse.jem.workbench.JavaEMFNature
+ org.eclipse.buildship.core.gradleprojectnature
+
+
diff --git a/maxkey-connectors/maxkey-connector-ldap/.settings/org.eclipse.buildship.core.prefs b/maxkey-connectors/maxkey-connector-ldap/.settings/org.eclipse.buildship.core.prefs
new file mode 100644
index 000000000..62e3e7e80
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-ldap/.settings/org.eclipse.buildship.core.prefs
@@ -0,0 +1,2 @@
+connection.project.dir=../..
+eclipse.preferences.version=1
diff --git a/maxkey-connectors/maxkey-connector-ldap/.settings/org.eclipse.core.resources.prefs b/maxkey-connectors/maxkey-connector-ldap/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 000000000..896a9a53a
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-ldap/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/=UTF-8
\ No newline at end of file
diff --git a/maxkey-connectors/maxkey-connector-ldap/.settings/org.eclipse.jdt.core.prefs b/maxkey-connectors/maxkey-connector-ldap/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..8f838df8f
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-ldap/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,14 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.builder.cleanOutputFolder=clean
+org.eclipse.jdt.core.builder.duplicateResourceTask=warning
+org.eclipse.jdt.core.builder.invalidClasspath=abort
+org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore
+org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch
+org.eclipse.jdt.core.circularClasspath=warning
+org.eclipse.jdt.core.classpath.exclusionPatterns=enabled
+org.eclipse.jdt.core.classpath.mainOnlyProjectHasTestOnlyDependency=error
+org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled
+org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource=error
+org.eclipse.jdt.core.compiler.maxProblemPerUnit=100
+org.eclipse.jdt.core.incompatibleJDKLevel=ignore
+org.eclipse.jdt.core.incompleteClasspath=error
diff --git a/maxkey-connectors/maxkey-connector-ldap/.settings/org.eclipse.jdt.launching.prefs b/maxkey-connectors/maxkey-connector-ldap/.settings/org.eclipse.jdt.launching.prefs
new file mode 100644
index 000000000..f8a131b56
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-ldap/.settings/org.eclipse.jdt.launching.prefs
@@ -0,0 +1,3 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.launching.PREF_COMPILER_COMPLIANCE_DOES_NOT_MATCH_JRE=warning
+org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=warning
diff --git a/maxkey-connectors/maxkey-connector-ldap/.settings/org.eclipse.wst.common.component b/maxkey-connectors/maxkey-connector-ldap/.settings/org.eclipse.wst.common.component
new file mode 100644
index 000000000..fdd64accc
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-ldap/.settings/org.eclipse.wst.common.component
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+ uses
+
+
+ uses
+
+
+ uses
+
+
+ uses
+
+
+ uses
+
+
+
diff --git a/maxkey-connectors/maxkey-connector-ldap/.settings/org.eclipse.wst.common.project.facet.core.xml b/maxkey-connectors/maxkey-connector-ldap/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..509bad92c
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-ldap/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/maxkey-connectors/maxkey-connector-ldap/.settings/org.springframework.ide.eclipse.prefs b/maxkey-connectors/maxkey-connector-ldap/.settings/org.springframework.ide.eclipse.prefs
new file mode 100644
index 000000000..a12794d68
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-ldap/.settings/org.springframework.ide.eclipse.prefs
@@ -0,0 +1,2 @@
+boot.validation.initialized=true
+eclipse.preferences.version=1
diff --git a/maxkey-connectors/maxkey-connector-ldap/build.gradle b/maxkey-connectors/maxkey-connector-ldap/build.gradle
new file mode 100644
index 000000000..ce5fa95ee
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-ldap/build.gradle
@@ -0,0 +1,17 @@
+description = "maxkey-connector-ldap"
+
+apply plugin: 'java'
+apply plugin: 'eclipse-wtp'
+
+
+dependencies {
+ //local jars
+ compile fileTree(dir: '../maxkey-lib/*/', include: '*.jar')
+
+ compile project(":maxkey-core")
+ compile project(":maxkey-dao")
+ compile project(":maxkey-client-sdk")
+ compile project(":maxkey-connectors:maxkey-connector-base")
+ compile project(":maxkey-identitys:maxkey-identity-kafka")
+
+}
\ No newline at end of file
diff --git a/maxkey-connectors/maxkey-connector-ldap/src/main/java/org/maxkey/connector/LdapConsumerApplication.java b/maxkey-connectors/maxkey-connector-ldap/src/main/java/org/maxkey/connector/LdapConsumerApplication.java
new file mode 100644
index 000000000..1a5cb7067
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-ldap/src/main/java/org/maxkey/connector/LdapConsumerApplication.java
@@ -0,0 +1,55 @@
+package org.maxkey.connector;
+
+import org.maxkey.constants.ConstantsProperties;
+import org.maxkey.persistence.ldap.LdapUtils;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+
+@Configuration
+@PropertySource(ConstantsProperties.applicationPropertySource)
+@SpringBootApplication
+@ComponentScan(basePackages = {
+ "org.maxkey.connector",
+ "org.maxkey.connector.receiver",
+ "org.maxkey.connector.ldap"
+ })
+public class LdapConsumerApplication {
+
+ public static void main(String[] args) {
+ // TODO Auto-generated method stub
+ ConfigurableApplicationContext context = SpringApplication.run(LdapConsumerApplication.class, args);
+
+ }
+
+ //@Bean(name = "ldapUtils")
+ public LdapUtils getLdapConnection(
+ @Value("${config.connector.ldap.providerUrl}") String providerUrl,
+ @Value("${config.connector.ldap.principal}") String principal,
+ @Value("${config.connector.ldap.credentials}") String credentials,
+ @Value("${config.connector.ldap.baseDN}") String baseDn
+ )throws Exception{
+
+ LdapUtils ldapUtils=new LdapUtils(
+ providerUrl,
+ principal,
+ credentials,
+ baseDn);
+ if(ldapUtils.openConnection()==null){
+ throw new Exception("connection to Ldap Error.");
+ }
+ return ldapUtils;
+ }
+
+
+ protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
+ return application.sources(LdapConsumerApplication.class);
+ }
+
+}
diff --git a/maxkey-connectors/maxkey-connector-ldap/src/main/java/org/maxkey/connector/ldap/Group2Ldap.java b/maxkey-connectors/maxkey-connector-ldap/src/main/java/org/maxkey/connector/ldap/Group2Ldap.java
new file mode 100644
index 000000000..ecac23a00
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-ldap/src/main/java/org/maxkey/connector/ldap/Group2Ldap.java
@@ -0,0 +1,153 @@
+package org.maxkey.connector.ldap;
+
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttribute;
+import javax.naming.directory.BasicAttributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.ModificationItem;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+
+import org.maxkey.connector.GroupConnector;
+import org.maxkey.domain.GroupMember;
+import org.maxkey.domain.Groups;
+import org.maxkey.persistence.ldap.LdapUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+@Component(value = "groupConnector")
+public class Group2Ldap extends GroupConnector {
+ private final static Logger logger = LoggerFactory.getLogger(Group2Ldap.class);
+
+ LdapUtils ldapUtils;
+ public Group2Ldap() {
+
+ }
+
+ @Override
+ public boolean create(Groups group) throws Exception{
+ logger.info("create");
+ try {
+ Attributes attributes = new BasicAttributes();
+ attributes.put(new BasicAttribute("objectClass","groupOfUniqueNames"));
+ attributes.put(new BasicAttribute("cn",group.getName()));
+ attributes.put(new BasicAttribute("uniqueMember","uid=dummy"));
+
+ String dn="cn="+group.getName()+",dc=groups,"+ldapUtils.getBaseDN();
+
+ ldapUtils.getCtx().createSubcontext(dn, attributes);
+ ldapUtils.close();
+ } catch (NamingException e) {
+ e.printStackTrace();
+ }
+ return true;
+ }
+
+ @Override
+ public boolean update(Groups group) throws Exception{
+ logger.info("update");
+ try {
+ SearchControls constraints = new SearchControls();
+ constraints.setSearchScope(ldapUtils.getSearchScope());
+ NamingEnumeration results = ldapUtils.getConnection()
+ .search(ldapUtils.getBaseDN(), "(cn="+group.getName()+")", constraints);
+ String oldDn="";
+ String rdn="";
+ if (results == null || !results.hasMore()) {
+ return create(group);
+ }else{
+ SearchResult sr = (SearchResult) results.next();
+ oldDn =sr.getNameInNamespace();
+ String[] dnSplit=oldDn.split(",");
+ rdn=oldDn.substring(oldDn.indexOf(","), oldDn.length());
+
+ String groupName=dnSplit[0].split("=")[1];
+ if(group.getName()!=groupName){
+ String newDn="cn="+group.getName()+","+rdn;
+ ldapUtils.getCtx().rename(oldDn, newDn);
+ ModificationItem[] modificationItems = new ModificationItem[1];
+ modificationItems[0]=new ModificationItem(DirContext.REMOVE_ATTRIBUTE,new BasicAttribute("cn",groupName));
+ ldapUtils.getCtx().modifyAttributes(newDn, modificationItems);
+ }
+ }
+
+ ldapUtils.close();
+ } catch (NamingException e) {
+ e.printStackTrace();
+ }
+ return true;
+ }
+
+ @Override
+ public boolean delete(Groups group) throws Exception {
+ logger.info("delete");
+ try {
+ String dn="cn="+group.getName()+",dc=groups,"+ldapUtils.getBaseDN();
+ ldapUtils.getCtx().destroySubcontext(dn);
+ ldapUtils.close();
+ } catch (NamingException e) {
+ e.printStackTrace();
+ }
+ return true;
+ }
+
+ @Override
+ public boolean addMember(GroupMember groupMember) throws Exception {
+ try {
+ SearchControls constraints = new SearchControls();
+ constraints.setSearchScope(ldapUtils.getSearchScope());
+ NamingEnumeration results = ldapUtils.getConnection()
+ .search(ldapUtils.getBaseDN(), "(cn="+groupMember.getGroupName()+")", constraints);
+ if (results == null || !results.hasMore()) {
+ Groups group =new Groups();
+ group.setName(groupMember.getGroupName());
+ create(group);
+ }
+
+ String uniqueMember="uid="+groupMember.getMemberName()+",dc=users,"+ldapUtils.getBaseDN();
+ ModificationItem[] modificationItems = new ModificationItem[1];
+ modificationItems[0]=new ModificationItem(DirContext.ADD_ATTRIBUTE,new BasicAttribute("uniqueMember",uniqueMember));
+
+ String dn="cn="+groupMember.getGroupName()+",dc=groups,"+ldapUtils.getBaseDN();
+ logger.debug("dn : "+dn);
+ logger.debug("uniqueMember : "+uniqueMember);
+ ldapUtils.getCtx().modifyAttributes(dn, modificationItems);
+ ldapUtils.close();
+ } catch (NamingException e) {
+ e.printStackTrace();
+ }
+ return true;
+ }
+
+ @Override
+ public boolean deleteMember(GroupMember groupMember) throws Exception{
+ try {
+ SearchControls constraints = new SearchControls();
+ constraints.setSearchScope(ldapUtils.getSearchScope());
+ NamingEnumeration results = ldapUtils.getConnection()
+ .search(ldapUtils.getBaseDN(), "(cn="+groupMember.getGroupName()+")", constraints);
+ if (results == null || !results.hasMore()) {
+ return true;
+ }
+
+ String uniqueMember="uid="+groupMember.getMemberName()+",dc=users,"+ldapUtils.getBaseDN();
+ ModificationItem[] modificationItems = new ModificationItem[1];
+ modificationItems[0]=new ModificationItem(DirContext.REMOVE_ATTRIBUTE,new BasicAttribute("uniqueMember",uniqueMember));
+
+ String dn="cn="+groupMember.getGroupName()+",dc=groups,"+ldapUtils.getBaseDN();
+ logger.debug("dn : "+dn);
+ logger.debug("uniqueMember : "+uniqueMember);
+ ldapUtils.getCtx().modifyAttributes(dn, modificationItems);
+ ldapUtils.close();
+ } catch (NamingException e) {
+ e.printStackTrace();
+ }
+ return true;
+ }
+
+
+
+}
diff --git a/maxkey-connectors/maxkey-connector-ldap/src/main/java/org/maxkey/connector/ldap/Organization2Ldap.java b/maxkey-connectors/maxkey-connector-ldap/src/main/java/org/maxkey/connector/ldap/Organization2Ldap.java
new file mode 100644
index 000000000..bed805421
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-ldap/src/main/java/org/maxkey/connector/ldap/Organization2Ldap.java
@@ -0,0 +1,119 @@
+package org.maxkey.connector.ldap;
+
+import javax.naming.NamingEnumeration;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttribute;
+import javax.naming.directory.BasicAttributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.ModificationItem;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+
+import org.maxkey.connector.OrganizationConnector;
+import org.maxkey.domain.Organizations;
+import org.maxkey.persistence.ldap.LdapUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+@Component(value = "organizationConnector")
+public class Organization2Ldap extends OrganizationConnector{
+ private final static Logger logger = LoggerFactory.getLogger(Organization2Ldap.class);
+
+ LdapUtils ldapUtils;
+ public Organization2Ldap() {
+
+ }
+
+ @Override
+ public boolean create(Organizations organization) throws Exception {
+ logger.info("create");
+ SearchControls constraints = new SearchControls();
+ constraints.setSearchScope(ldapUtils.getSearchScope());
+ NamingEnumeration results = ldapUtils.getConnection()
+ .search(ldapUtils.getBaseDN(), "(&(objectClass=organizationalUnit)(description="+organization.getpId()+"))", constraints);
+ String rdn="";
+ if (results == null || !results.hasMore()) {
+ rdn=ldapUtils.getBaseDN();
+ }else{
+ SearchResult sr = (SearchResult) results.next();
+ rdn =sr.getNameInNamespace();
+ }
+
+ Attributes attributes = new BasicAttributes();
+ attributes.put(new BasicAttribute("objectClass","organizationalUnit"));
+ attributes.put(new BasicAttribute("ou",organization.getName()));
+ //attributes.put(new BasicAttribute("name",organization.getName()));
+ //attributes.put(new BasicAttribute("id",organization.getId()));
+ //attributes.put(new BasicAttribute("porgname",organization.getpName()));
+ //attributes.put(new BasicAttribute("porgid",organization.getpId()));
+ attributes.put(new BasicAttribute("description",organization.getId()));
+
+ String dn="ou="+organization.getName()+","+rdn;
+
+ ldapUtils.getCtx().createSubcontext(dn, attributes);
+ ldapUtils.close();
+
+ return super.create(organization);
+ }
+
+ @Override
+ public boolean update(Organizations organization) throws Exception{
+ logger.info("update");
+ SearchControls constraints = new SearchControls();
+ constraints.setSearchScope(ldapUtils.getSearchScope());
+ NamingEnumeration results = ldapUtils.getConnection()
+ .search(ldapUtils.getBaseDN(), "(&(objectClass=organizationalUnit)(description="+organization.getId()+"))", constraints);
+ String oldDn="";
+ String rdn="";
+ if (results == null || !results.hasMore()) {
+ return create(organization);
+ }else{
+ SearchResult sr = (SearchResult) results.next();
+ oldDn =sr.getNameInNamespace();
+ String[] dnSplit=oldDn.split(",");
+ rdn=oldDn.substring(oldDn.indexOf(",")+1, oldDn.length());
+
+ String ouName=dnSplit[0].split("=")[1];
+ if(organization.getName()!=ouName){
+ String newDn="ou="+organization.getName()+","+rdn;
+ logger.debug("oldDn : "+oldDn);
+ logger.debug("newDn : "+newDn);
+ ldapUtils.getCtx().rename(oldDn, newDn);
+ ModificationItem[] modificationItems = new ModificationItem[1];
+ modificationItems[0]=new ModificationItem(DirContext.REMOVE_ATTRIBUTE,new BasicAttribute("ou",ouName));
+ //modificationItems[1]=new ModificationItem(DirContext.REPLACE_ATTRIBUTE,new BasicAttribute("name",organization.getName()));
+ //modificationItems[2]=new ModificationItem(DirContext.REPLACE_ATTRIBUTE,new BasicAttribute("id",organization.getId()));
+ //modificationItems[3]=new ModificationItem(DirContext.REPLACE_ATTRIBUTE,new BasicAttribute("porgname",organization.getpName()));
+ //modificationItems[4]=new ModificationItem(DirContext.REPLACE_ATTRIBUTE,new BasicAttribute("porgid",organization.getpId()));
+ ldapUtils.getCtx().modifyAttributes(newDn, modificationItems);
+ }
+ }
+
+ ldapUtils.close();
+
+ return super.update(organization);
+ }
+
+ @Override
+ public boolean delete(Organizations organization) throws Exception{
+ logger.info("delete");
+ SearchControls constraints = new SearchControls();
+ constraints.setSearchScope(ldapUtils.getSearchScope());
+ NamingEnumeration results = ldapUtils.getConnection()
+ .search(ldapUtils.getBaseDN(), "(&(objectClass=organizationalUnit)(description="+organization.getId()+"))", constraints);
+ String dn="";
+ if (results == null || !results.hasMore()) {
+
+ }else{
+ SearchResult sr = (SearchResult) results.next();
+ dn =sr.getNameInNamespace();
+ ldapUtils.getCtx().destroySubcontext(dn);
+ }
+
+ ldapUtils.close();
+
+ return super.delete(organization);
+ }
+
+}
diff --git a/maxkey-connectors/maxkey-connector-ldap/src/main/java/org/maxkey/connector/ldap/Password2Ldap.java b/maxkey-connectors/maxkey-connector-ldap/src/main/java/org/maxkey/connector/ldap/Password2Ldap.java
new file mode 100644
index 000000000..e5d70cdce
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-ldap/src/main/java/org/maxkey/connector/ldap/Password2Ldap.java
@@ -0,0 +1,45 @@
+package org.maxkey.connector.ldap;
+
+import javax.naming.NamingException;
+import javax.naming.directory.BasicAttribute;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.ModificationItem;
+
+import org.maxkey.connector.PasswordConnector;
+import org.maxkey.crypto.ReciprocalUtils;
+import org.maxkey.domain.UserInfo;
+import org.maxkey.persistence.ldap.LdapUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+
+@Component(value = "passwordConnector")
+public class Password2Ldap extends PasswordConnector{
+ private final static Logger logger = LoggerFactory.getLogger(Password2Ldap.class);
+
+ LdapUtils ldapUtils;
+
+ public Password2Ldap() {
+
+ }
+
+ @Override
+ public boolean sync(UserInfo userInfo) throws Exception{
+ logger.info("changePassword");
+ try {
+ ModificationItem[] modificationItems = new ModificationItem[1];
+ modificationItems[0]=new ModificationItem(DirContext.REPLACE_ATTRIBUTE,new BasicAttribute("userPassword",ReciprocalUtils.decoder(userInfo.getDecipherable())));
+
+ String dn="uid="+userInfo.getUsername()+",dc=users,"+ldapUtils.getBaseDN();
+
+ ldapUtils.getCtx().modifyAttributes(dn, modificationItems);
+ ldapUtils.close();
+ } catch (NamingException e) {
+ e.printStackTrace();
+ }
+ return true;
+ }
+
+
+}
diff --git a/maxkey-connectors/maxkey-connector-ldap/src/main/java/org/maxkey/connector/ldap/UserInfo2Ldap.java b/maxkey-connectors/maxkey-connector-ldap/src/main/java/org/maxkey/connector/ldap/UserInfo2Ldap.java
new file mode 100644
index 000000000..67030b207
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-ldap/src/main/java/org/maxkey/connector/ldap/UserInfo2Ldap.java
@@ -0,0 +1,140 @@
+package org.maxkey.connector.ldap;
+
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttribute;
+import javax.naming.directory.BasicAttributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.ModificationItem;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+
+import org.maxkey.connector.UserInfoConnector;
+import org.maxkey.crypto.ReciprocalUtils;
+import org.maxkey.domain.UserInfo;
+import org.maxkey.persistence.ldap.LdapUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+@Component(value = "userInfoConnector")
+public class UserInfo2Ldap extends UserInfoConnector{
+ private final static Logger logger = LoggerFactory.getLogger(UserInfo2Ldap.class);
+
+ LdapUtils ldapUtils;
+
+ public UserInfo2Ldap() {
+
+ }
+
+ @Override
+ public boolean create(UserInfo userInfo) throws Exception{
+ logger.info("create");
+ try {
+ Attributes attributes = new BasicAttributes();
+ attributes.put(new BasicAttribute("objectClass","inetOrgPerson"));
+ attributes.put(new BasicAttribute("uid",userInfo.getUsername()));
+ attributes.put(new BasicAttribute("userPassword",ReciprocalUtils.decoder(userInfo.getDecipherable())));
+ attributes.put(new BasicAttribute("displayName",userInfo.getDisplayName()));
+ attributes.put(new BasicAttribute("cn",userInfo.getDisplayName()));
+ attributes.put(new BasicAttribute("givenName",userInfo.getGivenName()));
+ attributes.put(new BasicAttribute("sn",userInfo.getFamilyName()));
+
+ attributes.put(new BasicAttribute("mobile",userInfo.getWorkPhoneNumber()==null?"":userInfo.getWorkPhoneNumber()));
+ attributes.put(new BasicAttribute("mail",userInfo.getWorkEmail()==null?"":userInfo.getWorkEmail()));
+
+ attributes.put(new BasicAttribute("employeeNumber",userInfo.getEmployeeNumber()==null?"":userInfo.getEmployeeNumber()));
+ attributes.put(new BasicAttribute("ou",userInfo.getDepartment()==null?"":userInfo.getDepartment()));
+ String managerDn="uid=dummy";
+ if(userInfo.getManagerId()==null||userInfo.getManagerId().equals("")){
+
+ }else{
+ UserInfo queryManager=new UserInfo();
+ queryManager.setId(userInfo.getManagerId());
+ UserInfo manager=loadUser(queryManager);
+ managerDn="uid="+manager.getUsername()+",dc=users,"+ldapUtils.getBaseDN();
+ }
+ attributes.put(new BasicAttribute("manager",managerDn));
+ attributes.put(new BasicAttribute("departmentNumber",userInfo.getDepartmentId()==null?"":userInfo.getDepartmentId()));
+ attributes.put(new BasicAttribute("title",userInfo.getJobTitle()==null?"":userInfo.getJobTitle()));
+
+
+ String dn="uid="+userInfo.getUsername()+",dc=users,"+ldapUtils.getBaseDN();
+
+ ldapUtils.getCtx().createSubcontext(dn, attributes);
+ ldapUtils.close();
+ super.create(userInfo);
+ } catch (NamingException e) {
+ e.printStackTrace();
+ }
+ return true;
+ }
+
+ @Override
+ public boolean update(UserInfo userInfo) throws Exception{
+ logger.info("update");
+ try {
+ SearchControls constraints = new SearchControls();
+ constraints.setSearchScope(ldapUtils.getSearchScope());
+ NamingEnumeration results = ldapUtils.getConnection()
+ .search(ldapUtils.getBaseDN(), "(&(objectClass=inetOrgPerson)(uid="+userInfo.getUsername()+"))", constraints);
+ if (results == null || !results.hasMore()) {
+ return create(loadUser(userInfo));
+ }
+
+ ModificationItem[] modificationItems = new ModificationItem[10];
+ modificationItems[0]=new ModificationItem(DirContext.REPLACE_ATTRIBUTE,new BasicAttribute("displayName",userInfo.getDisplayName()));
+ modificationItems[1]=new ModificationItem(DirContext.REPLACE_ATTRIBUTE,new BasicAttribute("cn",userInfo.getDisplayName()));
+ modificationItems[2]=new ModificationItem(DirContext.REPLACE_ATTRIBUTE,new BasicAttribute("givenName",userInfo.getGivenName()));
+ modificationItems[3]=new ModificationItem(DirContext.REPLACE_ATTRIBUTE,new BasicAttribute("sn",userInfo.getFamilyName()));
+
+ modificationItems[4]=new ModificationItem(DirContext.REPLACE_ATTRIBUTE,new BasicAttribute("mobile",userInfo.getWorkPhoneNumber()==null?"":userInfo.getWorkPhoneNumber()));
+ modificationItems[5]=new ModificationItem(DirContext.REPLACE_ATTRIBUTE,new BasicAttribute("mail",userInfo.getWorkEmail()==null?"":userInfo.getWorkEmail()));
+
+ modificationItems[6]=new ModificationItem(DirContext.REPLACE_ATTRIBUTE,new BasicAttribute("employeeNumber",userInfo.getEmployeeNumber()==null?"":userInfo.getEmployeeNumber()));
+ modificationItems[7]=new ModificationItem(DirContext.REPLACE_ATTRIBUTE,new BasicAttribute("ou",userInfo.getDepartment()==null?"":userInfo.getDepartment()));
+ modificationItems[8]=new ModificationItem(DirContext.REPLACE_ATTRIBUTE,new BasicAttribute("departmentNumber",userInfo.getDepartmentId()==null?"":userInfo.getDepartmentId()));
+ modificationItems[9]=new ModificationItem(DirContext.REPLACE_ATTRIBUTE,new BasicAttribute("title",userInfo.getJobTitle()==null?"":userInfo.getJobTitle()));
+
+ String managerDn="uid=dummy";
+ if(userInfo.getManagerId()==null||userInfo.getManagerId().equals("")){
+
+ }else{
+ UserInfo queryManager=new UserInfo();
+ queryManager.setId(userInfo.getManagerId());
+ UserInfo manager=loadUser(queryManager);
+ managerDn="uid="+manager.getUsername()+",dc=users,"+ldapUtils.getBaseDN();
+ }
+ modificationItems[9]=new ModificationItem(DirContext.REPLACE_ATTRIBUTE,new BasicAttribute("manager",managerDn));
+
+
+
+ String dn="uid="+userInfo.getUsername()+",dc=users,"+ldapUtils.getBaseDN();
+
+ ldapUtils.getCtx().modifyAttributes(dn, modificationItems);
+ ldapUtils.close();
+ } catch (NamingException e) {
+ e.printStackTrace();
+ }
+ return true;
+
+ }
+
+ @Override
+ public boolean delete(UserInfo userInfo) throws Exception{
+ logger.info("delete");
+ try {
+ String dn="uid="+userInfo.getUsername()+",dc=users,"+ldapUtils.getBaseDN();
+ ldapUtils.getCtx().destroySubcontext(dn);
+ ldapUtils.close();
+ super.delete(userInfo);
+ } catch (NamingException e) {
+ e.printStackTrace();
+ }
+ return true;
+ }
+
+ public UserInfo loadUser(UserInfo UserInfo) {
+ return null;
+ }
+}
diff --git a/maxkey-connectors/maxkey-connector-ldap/src/main/resources/application.properties b/maxkey-connectors/maxkey-connector-ldap/src/main/resources/application.properties
new file mode 100644
index 000000000..4597eff9a
--- /dev/null
+++ b/maxkey-connectors/maxkey-connector-ldap/src/main/resources/application.properties
@@ -0,0 +1,47 @@
+#spring.profiles.active=dev
+#application
+application.title=MaxKey-Connector-LDAP
+application.name=MaxKey-Connector-LDAP
+application.formatted-version=v2.0.0 GA
+
+#server port
+server.port=9601
+
+#datasource
+spring.datasource.username=root
+spring.datasource.password=maxkey
+spring.datasource.url=jdbc:mysql://localhost/maxkey?autoReconnect=true&characterEncoding=UTF-8
+spring.datasource.driver-class-name=com.mysql.jdbc.Driver
+spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
+
+spring.kafka.bootstrap-servers=localhost:9092
+###########【初始化消费者配置】###########
+# 默认的消费组ID
+spring.kafka.consumer.properties.group.id=test-consumer-group
+# 是否自动提交offset
+spring.kafka.consumer.enable-auto-commit=true
+# 提交offset延时(接收到消息后多久提交offset)
+spring.kafka.consumer.auto.commit.interval.ms=1000
+# 当kafka中没有初始offset或offset超出范围时将自动重置offset
+# earliest:重置为分区中最小的offset;
+# latest:重置为分区中最新的offset(消费分区中新产生的数据);
+# none:只要有一个分区不存在已提交的offset,就抛出异常;
+spring.kafka.consumer.auto-offset-reset=latest
+# 消费会话超时时间(超过这个时间consumer没有发送心跳,就会触发rebalance操作)
+spring.kafka.consumer.properties.session.timeout.ms=120000
+# 消费请求超时时间
+spring.kafka.consumer.properties.request.timeout.ms=180000
+# Kafka提供的序列化和反序列化类
+spring.kafka.consumer.key-deserializer=org.apache.kafka.common.serialization.StringDeserializer
+spring.kafka.consumer.value-deserializer=org.apache.kafka.common.serialization.StringDeserializer
+# 消费端监听的topic不存在时,项目启动会报错(关掉)
+spring.kafka.listener.missing-topics-fatal=false
+# 设置批量消费
+# spring.kafka.listener.type=batch
+# 批量消费每次最多消费多少条消息
+# spring.kafka.consumer.max-poll-records=50
+
+config.connector.ldap.providerUrl=ldap://
+config.connector.ldap.principal=maxkey
+config.connector.ldap.credentials=maxkey
+config.connector.ldap.baseDN=dc=maxkey,dc=top
\ No newline at end of file
diff --git a/maxkey-core/src/main/java/org/maxkey/config/ApplicationConfig.java b/maxkey-core/src/main/java/org/maxkey/config/ApplicationConfig.java
index 4f13c3daf..a57793215 100644
--- a/maxkey-core/src/main/java/org/maxkey/config/ApplicationConfig.java
+++ b/maxkey-core/src/main/java/org/maxkey/config/ApplicationConfig.java
@@ -52,6 +52,9 @@ public class ApplicationConfig {
@Value("${server.port:8080}")
private int port;
+ @Value("${config.identity.kafkasupport:false}")
+ private boolean kafkaSupport;
+
public int getPort() {
return port;
}
@@ -198,6 +201,14 @@ public class ApplicationConfig {
this.defaultUri = defaultUri;
}
+ public boolean isKafkaSupport() {
+ return kafkaSupport;
+ }
+
+ public void setKafkaSupport(boolean kafkaSupport) {
+ this.kafkaSupport = kafkaSupport;
+ }
+
/*
* public boolean isWhiteList() { return whiteList; }
*
diff --git a/maxkey-dao/.settings/org.eclipse.jdt.core.prefs b/maxkey-dao/.settings/org.eclipse.jdt.core.prefs
index 35068d95f..8ce52bbdc 100644
--- a/maxkey-dao/.settings/org.eclipse.jdt.core.prefs
+++ b/maxkey-dao/.settings/org.eclipse.jdt.core.prefs
@@ -1,4 +1,17 @@
eclipse.preferences.version=1
+org.eclipse.jdt.core.builder.cleanOutputFolder=clean
+org.eclipse.jdt.core.builder.duplicateResourceTask=warning
+org.eclipse.jdt.core.builder.invalidClasspath=abort
+org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore
+org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch
+org.eclipse.jdt.core.circularClasspath=warning
+org.eclipse.jdt.core.classpath.exclusionPatterns=enabled
+org.eclipse.jdt.core.classpath.mainOnlyProjectHasTestOnlyDependency=error
+org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled
+org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource=error
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.maxProblemPerUnit=100
org.eclipse.jdt.core.compiler.source=1.8
+org.eclipse.jdt.core.incompatibleJDKLevel=ignore
+org.eclipse.jdt.core.incompleteClasspath=error
diff --git a/maxkey-dao/build.gradle b/maxkey-dao/build.gradle
index 50eb89f2f..75cf737dd 100644
--- a/maxkey-dao/build.gradle
+++ b/maxkey-dao/build.gradle
@@ -5,5 +5,5 @@ dependencies {
compile fileTree(dir: '../maxkey-lib/*/', include: '*.jar')
compile project(":maxkey-core")
-
+ compile project(":maxkey-identitys:maxkey-identity-kafka")
}
\ No newline at end of file
diff --git a/maxkey-dao/src/main/java/org/maxkey/dao/service/OrganizationsService.java b/maxkey-dao/src/main/java/org/maxkey/dao/service/OrganizationsService.java
index 4b5af01b7..3d20038b4 100644
--- a/maxkey-dao/src/main/java/org/maxkey/dao/service/OrganizationsService.java
+++ b/maxkey-dao/src/main/java/org/maxkey/dao/service/OrganizationsService.java
@@ -3,11 +3,18 @@ package org.maxkey.dao.service;
import org.apache.mybatis.jpa.persistence.JpaBaseService;
import org.maxkey.dao.persistence.OrganizationsMapper;
import org.maxkey.domain.Organizations;
+import org.maxkey.identity.kafka.KafkaIdentityAction;
+import org.maxkey.identity.kafka.KafkaIdentityTopic;
+import org.maxkey.identity.kafka.KafkaProvisioningService;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class OrganizationsService extends JpaBaseService{
+ @Autowired
+ KafkaProvisioningService kafkaProvisioningService;
+
public OrganizationsService() {
super(OrganizationsMapper.class);
}
@@ -21,4 +28,31 @@ public class OrganizationsService extends JpaBaseService{
return (OrganizationsMapper)super.getMapper();
}
+ public boolean insert(Organizations organization) {
+ if(super.insert(organization)){
+ kafkaProvisioningService.send(
+ KafkaIdentityTopic.ORG_TOPIC, organization, KafkaIdentityAction.CREATE_ACTION);
+ return true;
+ }
+ return false;
+ }
+
+ public boolean update(Organizations organization) {
+ if(super.update(organization)){
+ kafkaProvisioningService.send(
+ KafkaIdentityTopic.ORG_TOPIC, organization, KafkaIdentityAction.UPDATE_ACTION);
+ return true;
+ }
+ return false;
+ }
+
+ public boolean delete(Organizations organization) {
+ if(super.delete(organization)){
+ kafkaProvisioningService.send(
+ KafkaIdentityTopic.ORG_TOPIC, organization, KafkaIdentityAction.DELETE_ACTION);
+ return true;
+ }
+ return false;
+ }
+
}
diff --git a/maxkey-dao/src/main/java/org/maxkey/dao/service/UserInfoService.java b/maxkey-dao/src/main/java/org/maxkey/dao/service/UserInfoService.java
index dfc22a40b..3e1f3d014 100644
--- a/maxkey-dao/src/main/java/org/maxkey/dao/service/UserInfoService.java
+++ b/maxkey-dao/src/main/java/org/maxkey/dao/service/UserInfoService.java
@@ -8,6 +8,9 @@ import org.maxkey.crypto.password.PasswordReciprocal;
import org.maxkey.dao.persistence.UserInfoMapper;
import org.maxkey.domain.ChangePassword;
import org.maxkey.domain.UserInfo;
+import org.maxkey.identity.kafka.KafkaIdentityAction;
+import org.maxkey.identity.kafka.KafkaIdentityTopic;
+import org.maxkey.identity.kafka.KafkaProvisioningService;
import org.maxkey.util.DateUtils;
import org.maxkey.util.StringUtils;
import org.maxkey.web.WebContext;
@@ -29,6 +32,8 @@ public class UserInfoService extends JpaBaseService {
@Autowired
private PasswordEncoder passwordEncoder;
+ @Autowired
+ KafkaProvisioningService kafkaProvisioningService;
public UserInfoService() {
super(UserInfoMapper.class);
@@ -46,22 +51,27 @@ public class UserInfoService extends JpaBaseService {
public boolean insert(UserInfo userInfo) {
userInfo = passwordEncoder(userInfo);
if (super.insert(userInfo)) {
-
+ kafkaProvisioningService.send(
+ KafkaIdentityTopic.USERINFO_TOPIC, userInfo, KafkaIdentityAction.CREATE_ACTION);
return true;
}
return false;
}
- public boolean update(UserInfo userinfo) {
- if(super.update(userinfo)){
+ public boolean update(UserInfo userInfo) {
+ if(super.update(userInfo)){
+ kafkaProvisioningService.send(
+ KafkaIdentityTopic.USERINFO_TOPIC, userInfo, KafkaIdentityAction.UPDATE_ACTION);
return true;
}
return false;
}
- public boolean delete(UserInfo userinfo) {
- if( super.delete(userinfo)){
+ public boolean delete(UserInfo userInfo) {
+ if( super.delete(userInfo)){
+ kafkaProvisioningService.send(
+ KafkaIdentityTopic.USERINFO_TOPIC, userInfo, KafkaIdentityAction.DELETE_ACTION);
return true;
}
return false;
@@ -130,6 +140,8 @@ public class UserInfoService extends JpaBaseService {
changePassword.setUsername(userInfo.getUsername());
changePassword.setDecipherable(userInfo.getDecipherable());
changePassword.setPassword(userInfo.getPassword());
+ kafkaProvisioningService.send(
+ KafkaIdentityTopic.PASSWORD_TOPIC, changePassword, KafkaIdentityAction.PASSWORD_ACTION);
return true;
}
return false;
diff --git a/maxkey-identitys/.project b/maxkey-identitys/.project
index 0132e845e..280b2a642 100644
--- a/maxkey-identitys/.project
+++ b/maxkey-identitys/.project
@@ -15,6 +15,11 @@
+
+ org.springframework.ide.eclipse.boot.validation.springbootbuilder
+
+
+
org.eclipse.jdt.core.javanature
diff --git a/maxkey-identitys/maxkey-identity-kafka/.classpath b/maxkey-identitys/maxkey-identity-kafka/.classpath
new file mode 100644
index 000000000..eca1d9e92
--- /dev/null
+++ b/maxkey-identitys/maxkey-identity-kafka/.classpath
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/maxkey-identitys/maxkey-identity-kafka/.project b/maxkey-identitys/maxkey-identity-kafka/.project
new file mode 100644
index 000000000..740ee0232
--- /dev/null
+++ b/maxkey-identitys/maxkey-identity-kafka/.project
@@ -0,0 +1,41 @@
+
+
+ maxkey-identity-kafka
+ Project maxkey-identity-kafka created by Buildship.
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.wst.common.project.facet.core.builder
+
+
+
+
+ org.eclipse.wst.validation.validationbuilder
+
+
+
+
+ org.eclipse.buildship.core.gradleprojectbuilder
+
+
+
+
+ org.springframework.ide.eclipse.boot.validation.springbootbuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.eclipse.wst.common.project.facet.core.nature
+ org.eclipse.wst.common.modulecore.ModuleCoreNature
+ org.eclipse.jem.workbench.JavaEMFNature
+ org.eclipse.buildship.core.gradleprojectnature
+
+
diff --git a/maxkey-identitys/maxkey-identity-kafka/.settings/org.eclipse.buildship.core.prefs b/maxkey-identitys/maxkey-identity-kafka/.settings/org.eclipse.buildship.core.prefs
new file mode 100644
index 000000000..62e3e7e80
--- /dev/null
+++ b/maxkey-identitys/maxkey-identity-kafka/.settings/org.eclipse.buildship.core.prefs
@@ -0,0 +1,2 @@
+connection.project.dir=../..
+eclipse.preferences.version=1
diff --git a/maxkey-identitys/maxkey-identity-kafka/.settings/org.eclipse.core.resources.prefs b/maxkey-identitys/maxkey-identity-kafka/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 000000000..896a9a53a
--- /dev/null
+++ b/maxkey-identitys/maxkey-identity-kafka/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/=UTF-8
\ No newline at end of file
diff --git a/maxkey-identitys/maxkey-identity-kafka/.settings/org.eclipse.jdt.core.prefs b/maxkey-identitys/maxkey-identity-kafka/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..bc2f94a0b
--- /dev/null
+++ b/maxkey-identitys/maxkey-identity-kafka/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,116 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.builder.cleanOutputFolder=clean
+org.eclipse.jdt.core.builder.duplicateResourceTask=warning
+org.eclipse.jdt.core.builder.invalidClasspath=abort
+org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore
+org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch
+org.eclipse.jdt.core.circularClasspath=warning
+org.eclipse.jdt.core.classpath.exclusionPatterns=enabled
+org.eclipse.jdt.core.classpath.mainOnlyProjectHasTestOnlyDependency=error
+org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled
+org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource=error
+org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled
+org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
+org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
+org.eclipse.jdt.core.compiler.annotation.nonnull.secondary=
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault.secondary=
+org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
+org.eclipse.jdt.core.compiler.annotation.nullable.secondary=
+org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
+org.eclipse.jdt.core.compiler.maxProblemPerUnit=100
+org.eclipse.jdt.core.compiler.problem.APILeak=warning
+org.eclipse.jdt.core.compiler.problem.annotatedTypeArgumentToUnannotated=info
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
+org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
+org.eclipse.jdt.core.compiler.problem.nonnullTypeVariableFromLegacyInvocation=warning
+org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
+org.eclipse.jdt.core.compiler.problem.nullReference=warning
+org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
+org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.pessimisticNullAnalysisForFreeTypeVariables=warning
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.suppressWarningsNotFullyAnalysed=info
+org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.terminalDeprecation=warning
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentType=warning
+org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentTypeStrict=disabled
+org.eclipse.jdt.core.compiler.problem.unlikelyEqualsArgumentType=info
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unstableAutoModuleName=warning
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.incompatibleJDKLevel=ignore
+org.eclipse.jdt.core.incompleteClasspath=error
diff --git a/maxkey-identitys/maxkey-identity-kafka/.settings/org.eclipse.jdt.launching.prefs b/maxkey-identitys/maxkey-identity-kafka/.settings/org.eclipse.jdt.launching.prefs
new file mode 100644
index 000000000..f8a131b56
--- /dev/null
+++ b/maxkey-identitys/maxkey-identity-kafka/.settings/org.eclipse.jdt.launching.prefs
@@ -0,0 +1,3 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.launching.PREF_COMPILER_COMPLIANCE_DOES_NOT_MATCH_JRE=warning
+org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=warning
diff --git a/maxkey-identitys/maxkey-identity-kafka/.settings/org.eclipse.wst.common.component b/maxkey-identitys/maxkey-identity-kafka/.settings/org.eclipse.wst.common.component
new file mode 100644
index 000000000..72b93f2c4
--- /dev/null
+++ b/maxkey-identitys/maxkey-identity-kafka/.settings/org.eclipse.wst.common.component
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+ uses
+
+
+ uses
+
+
+ uses
+
+
+
diff --git a/maxkey-identitys/maxkey-identity-kafka/.settings/org.eclipse.wst.common.project.facet.core.xml b/maxkey-identitys/maxkey-identity-kafka/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..509bad92c
--- /dev/null
+++ b/maxkey-identitys/maxkey-identity-kafka/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/maxkey-identitys/maxkey-identity-kafka/.settings/org.springframework.ide.eclipse.prefs b/maxkey-identitys/maxkey-identity-kafka/.settings/org.springframework.ide.eclipse.prefs
new file mode 100644
index 000000000..a12794d68
--- /dev/null
+++ b/maxkey-identitys/maxkey-identity-kafka/.settings/org.springframework.ide.eclipse.prefs
@@ -0,0 +1,2 @@
+boot.validation.initialized=true
+eclipse.preferences.version=1
diff --git a/maxkey-identitys/maxkey-identity-kafka/build.gradle b/maxkey-identitys/maxkey-identity-kafka/build.gradle
new file mode 100644
index 000000000..375531435
--- /dev/null
+++ b/maxkey-identitys/maxkey-identity-kafka/build.gradle
@@ -0,0 +1,15 @@
+description = "maxkey-identity-kafka"
+
+apply plugin: 'java'
+apply plugin: 'eclipse-wtp'
+
+
+dependencies {
+ //local jars
+ compile fileTree(dir: '../maxkey-lib/*/', include: '*.jar')
+
+ compile project(":maxkey-core")
+ compile project(":maxkey-dao")
+ compile project(":maxkey-client-sdk")
+
+}
\ No newline at end of file
diff --git a/maxkey-identitys/maxkey-identity-kafka/src/main/java/org/maxkey/identity/kafka/KafkaIdentityAction.java b/maxkey-identitys/maxkey-identity-kafka/src/main/java/org/maxkey/identity/kafka/KafkaIdentityAction.java
new file mode 100644
index 000000000..a8356e212
--- /dev/null
+++ b/maxkey-identitys/maxkey-identity-kafka/src/main/java/org/maxkey/identity/kafka/KafkaIdentityAction.java
@@ -0,0 +1,10 @@
+package org.maxkey.identity.kafka;
+
+public class KafkaIdentityAction {
+
+ public static String CREATE_ACTION = "CREATE_ACTION";
+ public static String DELETE_ACTION = "DELETE_ACTION";
+ public static String UPDATE_ACTION = "UPDATE_ACTION";
+ public static String PASSWORD_ACTION = "PASSWORD_ACTION";
+
+}
diff --git a/maxkey-identitys/maxkey-identity-kafka/src/main/java/org/maxkey/identity/kafka/KafkaIdentityTopic.java b/maxkey-identitys/maxkey-identity-kafka/src/main/java/org/maxkey/identity/kafka/KafkaIdentityTopic.java
new file mode 100644
index 000000000..c7b2f887f
--- /dev/null
+++ b/maxkey-identitys/maxkey-identity-kafka/src/main/java/org/maxkey/identity/kafka/KafkaIdentityTopic.java
@@ -0,0 +1,11 @@
+package org.maxkey.identity.kafka;
+
+public class KafkaIdentityTopic {
+
+ public final static String USERINFO_TOPIC = "IDENTITY_USERINFO_TOPIC";
+ public final static String ORG_TOPIC = "IDENTITY_ORG_TOPIC";
+ public final static String GROUP_TOPIC = "IDENTITY_GROUP_TOPIC";
+ public final static String PASSWORD_TOPIC = "IDENTITY_PASSWORD_TOPIC";
+
+
+}
diff --git a/maxkey-identitys/maxkey-identity-kafka/src/main/java/org/maxkey/identity/kafka/KafkaMessage.java b/maxkey-identitys/maxkey-identity-kafka/src/main/java/org/maxkey/identity/kafka/KafkaMessage.java
new file mode 100644
index 000000000..3c170101c
--- /dev/null
+++ b/maxkey-identitys/maxkey-identity-kafka/src/main/java/org/maxkey/identity/kafka/KafkaMessage.java
@@ -0,0 +1,42 @@
+package org.maxkey.identity.kafka;
+
+public class KafkaMessage {
+ String topic;
+ String actionType;
+ String sendTime;
+ String msgId;
+ String content;
+
+ 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 String getSendTime() {
+ return sendTime;
+ }
+ public void setSendTime(String sendTime) {
+ this.sendTime = sendTime;
+ }
+ public String getMsgId() {
+ return msgId;
+ }
+ public void setMsgId(String msgId) {
+ this.msgId = msgId;
+ }
+ public Object getContent() {
+ return content;
+ }
+ public void setContent(String content) {
+ this.content = content;
+ }
+ public KafkaMessage() {
+ }
+}
diff --git a/maxkey-identitys/maxkey-identity-kafka/src/main/java/org/maxkey/identity/kafka/KafkaProvisioningService.java b/maxkey-identitys/maxkey-identity-kafka/src/main/java/org/maxkey/identity/kafka/KafkaProvisioningService.java
new file mode 100644
index 000000000..f6bc66622
--- /dev/null
+++ b/maxkey-identitys/maxkey-identity-kafka/src/main/java/org/maxkey/identity/kafka/KafkaProvisioningService.java
@@ -0,0 +1,48 @@
+package org.maxkey.identity.kafka;
+
+import java.util.UUID;
+
+import org.maxkey.config.ApplicationConfig;
+import org.maxkey.util.DateUtils;
+import org.maxkey.util.JsonUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.kafka.core.KafkaTemplate;
+import org.springframework.stereotype.Component;
+
+@Component
+public class KafkaProvisioningService {
+
+ private static final Logger _logger = LoggerFactory.getLogger(KafkaProvisioningService.class);
+
+ @Autowired
+ protected ApplicationConfig applicationConfig;
+
+ @Autowired
+ protected KafkaTemplate kafkaTemplate;
+
+ public void setApplicationConfig(ApplicationConfig applicationConfig) {
+ this.applicationConfig = applicationConfig;
+ }
+
+ public void setKafkaTemplate(KafkaTemplate kafkaTemplate) {
+ this.kafkaTemplate = kafkaTemplate;
+ }
+
+ public void send(String topic,Object content,String actionType) {
+ if(applicationConfig.isKafkaSupport()) {
+ KafkaMessage message = new KafkaMessage();
+ message.setMsgId(UUID.randomUUID().toString());
+ message.setActionType(actionType);
+ message.setTopic(topic);
+ message.setSendTime(DateUtils.getCurrentDateTimeAsString());
+ message.setContent(JsonUtils.gson2Json(content));
+ String msg = JsonUtils.gson2Json(message);
+ _logger.info("send message = {}", msg);
+
+ kafkaTemplate.send(topic, msg);
+ }
+ }
+
+}
diff --git a/maxkey-identitys/maxkey-identity-scim/.settings/org.eclipse.jdt.core.prefs b/maxkey-identitys/maxkey-identity-scim/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..8f838df8f
--- /dev/null
+++ b/maxkey-identitys/maxkey-identity-scim/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,14 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.builder.cleanOutputFolder=clean
+org.eclipse.jdt.core.builder.duplicateResourceTask=warning
+org.eclipse.jdt.core.builder.invalidClasspath=abort
+org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore
+org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch
+org.eclipse.jdt.core.circularClasspath=warning
+org.eclipse.jdt.core.classpath.exclusionPatterns=enabled
+org.eclipse.jdt.core.classpath.mainOnlyProjectHasTestOnlyDependency=error
+org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled
+org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource=error
+org.eclipse.jdt.core.compiler.maxProblemPerUnit=100
+org.eclipse.jdt.core.incompatibleJDKLevel=ignore
+org.eclipse.jdt.core.incompleteClasspath=error
diff --git a/maxkey-identitys/maxkey-identity-scim/.settings/org.eclipse.jdt.launching.prefs b/maxkey-identitys/maxkey-identity-scim/.settings/org.eclipse.jdt.launching.prefs
new file mode 100644
index 000000000..f8a131b56
--- /dev/null
+++ b/maxkey-identitys/maxkey-identity-scim/.settings/org.eclipse.jdt.launching.prefs
@@ -0,0 +1,3 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.launching.PREF_COMPILER_COMPLIANCE_DOES_NOT_MATCH_JRE=warning
+org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=warning
diff --git a/maxkey-protocols/maxkey-protocol-saml-2.0/.settings/org.eclipse.jdt.core.prefs b/maxkey-protocols/maxkey-protocol-saml-2.0/.settings/org.eclipse.jdt.core.prefs
index 35068d95f..8ce52bbdc 100644
--- a/maxkey-protocols/maxkey-protocol-saml-2.0/.settings/org.eclipse.jdt.core.prefs
+++ b/maxkey-protocols/maxkey-protocol-saml-2.0/.settings/org.eclipse.jdt.core.prefs
@@ -1,4 +1,17 @@
eclipse.preferences.version=1
+org.eclipse.jdt.core.builder.cleanOutputFolder=clean
+org.eclipse.jdt.core.builder.duplicateResourceTask=warning
+org.eclipse.jdt.core.builder.invalidClasspath=abort
+org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore
+org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch
+org.eclipse.jdt.core.circularClasspath=warning
+org.eclipse.jdt.core.classpath.exclusionPatterns=enabled
+org.eclipse.jdt.core.classpath.mainOnlyProjectHasTestOnlyDependency=error
+org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled
+org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource=error
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.maxProblemPerUnit=100
org.eclipse.jdt.core.compiler.source=1.8
+org.eclipse.jdt.core.incompatibleJDKLevel=ignore
+org.eclipse.jdt.core.incompleteClasspath=error
diff --git a/maxkey-protocols/maxkey-protocol-saml-2.0/.settings/org.eclipse.jdt.launching.prefs b/maxkey-protocols/maxkey-protocol-saml-2.0/.settings/org.eclipse.jdt.launching.prefs
new file mode 100644
index 000000000..f8a131b56
--- /dev/null
+++ b/maxkey-protocols/maxkey-protocol-saml-2.0/.settings/org.eclipse.jdt.launching.prefs
@@ -0,0 +1,3 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.launching.PREF_COMPILER_COMPLIANCE_DOES_NOT_MATCH_JRE=warning
+org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=warning
diff --git a/maxkey-web-manage/.project b/maxkey-web-manage/.project
index a4d8d4900..5a4701002 100644
--- a/maxkey-web-manage/.project
+++ b/maxkey-web-manage/.project
@@ -10,6 +10,7 @@
maxkey-client-sdk
maxkey-protocol-oauth-2.0
maxkey-protocol-saml-2.0
+ maxkey-identity-scim
diff --git a/maxkey-web-manage/build.gradle b/maxkey-web-manage/build.gradle
index 1264e7716..f52525c45 100644
--- a/maxkey-web-manage/build.gradle
+++ b/maxkey-web-manage/build.gradle
@@ -22,7 +22,8 @@ dependencies {
compile project(":maxkey-client-sdk")
compile project(":maxkey-protocols:maxkey-protocol-oauth-2.0")
compile project(":maxkey-protocols:maxkey-protocol-saml-2.0")
- compile project(":maxkey-identitys:maxkey-identity-scim")
+ compile project(":maxkey-identitys:maxkey-identity-scim")
+ compile project(":maxkey-identitys:maxkey-identity-kafka")
}
diff --git a/maxkey-web-manage/src/main/java/org/maxkey/MaxKeyMgtApplication.java b/maxkey-web-manage/src/main/java/org/maxkey/MaxKeyMgtApplication.java
index 4cb26eebf..76f074a94 100644
--- a/maxkey-web-manage/src/main/java/org/maxkey/MaxKeyMgtApplication.java
+++ b/maxkey-web-manage/src/main/java/org/maxkey/MaxKeyMgtApplication.java
@@ -34,6 +34,7 @@ import org.springframework.context.annotation.ImportResource;
"org.maxkey.dao",
"org.maxkey.web",
"org.maxkey.web.tag",
+ "org.maxkey.identity.kafka",
"org.maxkey.identity.scim.controller"
})
@MapperScan("org.maxkey.dao.persistence,")
diff --git a/maxkey-web-manage/src/main/resources/application.properties b/maxkey-web-manage/src/main/resources/application.properties
index f808bdc9e..b905749a6 100644
--- a/maxkey-web-manage/src/main/resources/application.properties
+++ b/maxkey-web-manage/src/main/resources/application.properties
@@ -59,4 +59,26 @@ spring.messages.basename=classpath:messages/message
spring.messages.encoding=UTF-8
#main
spring.main.banner-mode=log
-spring.main.allow-bean-definition-overriding=true
\ No newline at end of file
+spring.main.allow-bean-definition-overriding=true
+
+###########【Kafka集群】###########
+spring.kafka.bootstrap-servers=localhost:9092
+###########【初始化生产者配置】###########
+# 重试次数
+spring.kafka.producer.retries=0
+# 应答级别:多少个分区副本备份完成时向生产者发送ack确认(可选0、1、all/-1)
+spring.kafka.producer.acks=1
+# 批量大小
+spring.kafka.producer.batch-size=16384
+# 提交延时
+spring.kafka.producer.properties.linger.ms=0
+# 当生产端积累的消息达到batch-size或接收到消息linger.ms后,生产者就会将消息提交给kafka
+# linger.ms为0表示每接收到一条消息就提交给kafka,这时候batch-size其实就没用了
+
+# 生产端缓冲区大小
+spring.kafka.producer.buffer-memory = 33554432
+# Kafka提供的序列化和反序列化类
+spring.kafka.producer.key-serializer=org.apache.kafka.common.serialization.StringSerializer
+spring.kafka.producer.value-serializer=org.apache.kafka.common.serialization.StringSerializer
+# 自定义分区器
+# spring.kafka.producer.properties.partitioner.class=com.felix.kafka.producer.CustomizePartitioner
\ No newline at end of file
diff --git a/maxkey-web-manage/src/main/resources/maxkey.properties b/maxkey-web-manage/src/main/resources/maxkey.properties
index 3e9c6d44f..88d20d586 100644
--- a/maxkey-web-manage/src/main/resources/maxkey.properties
+++ b/maxkey-web-manage/src/main/resources/maxkey.properties
@@ -11,6 +11,8 @@ config.server.default.uri=${config.server.prefix.uri}/main
config.maxkey.uri=${config.server.name}/maxkey
#InMemory 0 , jdbc 1, Redis 2
config.server.persistence=0
+#identity
+config.identity.kafkasupport=true
############################################################################
# Login configuration
#enable captcha
diff --git a/maxkey-web-maxkey/src/main/resources/application.properties b/maxkey-web-maxkey/src/main/resources/application.properties
index 2b66d507c..a8abd08a7 100644
--- a/maxkey-web-maxkey/src/main/resources/application.properties
+++ b/maxkey-web-maxkey/src/main/resources/application.properties
@@ -68,3 +68,25 @@ spring.messages.encoding=UTF-8
#main
spring.main.banner-mode=log
spring.main.allow-bean-definition-overriding=true
+
+###########【Kafka集群】###########
+spring.kafka.bootstrap-servers=localhost:9092
+###########【初始化生产者配置】###########
+# 重试次数
+spring.kafka.producer.retries=0
+# 应答级别:多少个分区副本备份完成时向生产者发送ack确认(可选0、1、all/-1)
+spring.kafka.producer.acks=1
+# 批量大小
+spring.kafka.producer.batch-size=16384
+# 提交延时
+spring.kafka.producer.properties.linger.ms=0
+# 当生产端积累的消息达到batch-size或接收到消息linger.ms后,生产者就会将消息提交给kafka
+# linger.ms为0表示每接收到一条消息就提交给kafka,这时候batch-size其实就没用了
+
+# 生产端缓冲区大小
+spring.kafka.producer.buffer-memory = 33554432
+# Kafka提供的序列化和反序列化类
+spring.kafka.producer.key-serializer=org.apache.kafka.common.serialization.StringSerializer
+spring.kafka.producer.value-serializer=org.apache.kafka.common.serialization.StringSerializer
+# 自定义分区器
+# spring.kafka.producer.properties.partitioner.class=com.felix.kafka.producer.CustomizePartitioner
diff --git a/maxkey-web-maxkey/src/main/resources/maxkey.properties b/maxkey-web-maxkey/src/main/resources/maxkey.properties
index d6f3ae6cd..f56731a62 100644
--- a/maxkey-web-maxkey/src/main/resources/maxkey.properties
+++ b/maxkey-web-maxkey/src/main/resources/maxkey.properties
@@ -11,6 +11,9 @@ config.server.default.uri=${config.server.prefix.uri}/maxkey/appList
config.server.management.uri=${config.server.name}:9521/maxkey-mgt/login
#InMemory 0 , jdbc 1, Redis 2
config.server.persistence=0
+#identity
+config.identity.kafkasupport=false
+
config.app.issuer=CN=ConSec,CN=COM,CN=SH
############################################################################
# Login configuration
diff --git a/settings.gradle b/settings.gradle
index 1bcc3954c..0eae691ec 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -11,6 +11,13 @@ include 'maxkey-authentications'
//identity
include 'maxkey-identitys:maxkey-identity-scim'
+include 'maxkey-identitys:maxkey-identity-kafka'
+
+
+//connectors
+include 'maxkey-connectors:maxkey-connector-base'
+include 'maxkey-connectors:maxkey-connector-ldap'
+include 'maxkey-connectors:maxkey-connector-activedirectory'
//Protocol
//include 'maxkey-protocols'