mirror of
https://gitee.com/dromara/MaxKey.git
synced 2025-12-06 17:08:29 +08:00
connectors
This commit is contained in:
parent
a952c5addb
commit
7f17ce92ef
@ -292,6 +292,7 @@ subprojects {
|
||||
compile group: 'org.apache.santuario', name: 'xmlsec', version: '1.5.8'
|
||||
compile group: 'org.ogce', name: 'xpp3', version: '1.1.6'
|
||||
compile group: 'com.thoughtworks.xstream', name: 'xstream', version: '1.4.10'
|
||||
|
||||
//local jars
|
||||
compile fileTree(dir: "${rootDir}/maxkey-lib/", include: '*.jar')
|
||||
//阿里云
|
||||
|
||||
@ -13,6 +13,12 @@
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="bin/main" path="src/main/resources">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="main"/>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/>
|
||||
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
|
||||
<classpathentry kind="output" path="bin/default"/>
|
||||
|
||||
@ -2,5 +2,6 @@
|
||||
<wb-module deploy-name="maxkey-client-sdk">
|
||||
<wb-resource deploy-path="/" source-path="/src/main/java"/>
|
||||
<wb-resource deploy-path="/" source-path="/src/test/java"/>
|
||||
<wb-resource deploy-path="/" source-path="/src/main/resources"/>
|
||||
</wb-module>
|
||||
</project-modules>
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
description = "maxkey-client-sdk"
|
||||
|
||||
dependencies {
|
||||
compile fileTree(dir: '../maxkey-lib/log/', include: '*slf4j*.jar')
|
||||
compile fileTree(dir: '../maxkey-lib/log/', include: 'log4j*.jar')
|
||||
compile fileTree(dir: '../maxkey-lib/apache/', include: 'commons-logging*.jar')
|
||||
compile fileTree(dir: '../maxkey-lib/apache/', include: 'commons-codec*.jar')
|
||||
compile fileTree(dir: '../maxkey-lib/json/', include: 'gson*.jar')
|
||||
compile fileTree(dir: '../maxkey-lib/java/', include: '*.jar')
|
||||
dependencies {
|
||||
/*compile group: 'commons-io', name: 'commons-io', version: '2.6'
|
||||
compile group: 'commons-logging', name: 'commons-logging', version: '1.2'
|
||||
compile group: 'log4j', name: 'log4j', version: '1.2.17'
|
||||
compile group: 'org.slf4j', name: 'slf4j-api', version: '1.5.11'
|
||||
compile group: 'commons-codec', name: 'commons-codec', version: '1.14'
|
||||
compile group: 'com.nimbusds', name: 'nimbus-jose-jwt', version: '8.10'
|
||||
compile group: 'com.google.code.gson', name: 'gson', version: '2.8.6'
|
||||
*/
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,106 @@
|
||||
package org.maxkey.client.http;
|
||||
|
||||
/*
|
||||
public class ApacheHttpClient{
|
||||
|
||||
private final CloseableHttpAsyncClient client;
|
||||
|
||||
public ApacheHttpClient() {
|
||||
this(ApacheHttpClientConfig.defaultConfig());
|
||||
}
|
||||
|
||||
public ApacheHttpClient(ApacheHttpClientConfig config) {
|
||||
this(config.getHttpAsyncClientBuilder());
|
||||
}
|
||||
|
||||
public ApacheHttpClient(HttpAsyncClientBuilder builder) {
|
||||
this(builder.build());
|
||||
}
|
||||
|
||||
public ApacheHttpClient(CloseableHttpAsyncClient client) {
|
||||
this.client = client;
|
||||
this.client.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
client.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Future<T> executeAsync(String userAgent, Map<String, String> headers, Verb httpVerb, String completeUrl,
|
||||
byte[] bodyContents, OAuthAsyncRequestCallback<T> callback, OAuthRequest.ResponseConverter<T> converter) {
|
||||
final HttpEntity entity = bodyContents == null ? null : new ByteArrayEntity(bodyContents);
|
||||
return doExecuteAsync(userAgent, headers, httpVerb, completeUrl, entity, callback, converter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Future<T> executeAsync(String userAgent, Map<String, String> headers, Verb httpVerb, String completeUrl,
|
||||
MultipartPayload bodyContents, OAuthAsyncRequestCallback<T> callback,
|
||||
OAuthRequest.ResponseConverter<T> converter) {
|
||||
|
||||
throw new UnsupportedOperationException("ApacheHttpClient does not support MultipartPayload yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Future<T> executeAsync(String userAgent, Map<String, String> headers, Verb httpVerb, String completeUrl,
|
||||
String bodyContents, OAuthAsyncRequestCallback<T> callback, OAuthRequest.ResponseConverter<T> converter) {
|
||||
final HttpEntity entity = bodyContents == null ? null : new StringEntity(bodyContents, StandardCharsets.UTF_8);
|
||||
return doExecuteAsync(userAgent, headers, httpVerb, completeUrl, entity, callback, converter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Future<T> executeAsync(String userAgent, Map<String, String> headers, Verb httpVerb, String completeUrl,
|
||||
File bodyContents, OAuthAsyncRequestCallback<T> callback, OAuthRequest.ResponseConverter<T> converter) {
|
||||
final HttpEntity entity = bodyContents == null ? null : new FileEntity(bodyContents);
|
||||
return doExecuteAsync(userAgent, headers, httpVerb, completeUrl, entity, callback, converter);
|
||||
}
|
||||
|
||||
private <T> Future<T> doExecuteAsync(String userAgent, Map<String, String> headers, Verb httpVerb,
|
||||
String completeUrl, HttpEntity entity, OAuthAsyncRequestCallback<T> callback,
|
||||
OAuthRequest.ResponseConverter<T> converter) {
|
||||
final RequestBuilder builder = getRequestBuilder(httpVerb);
|
||||
builder.setUri(completeUrl);
|
||||
|
||||
if (httpVerb.isPermitBody()) {
|
||||
if (!headers.containsKey(CONTENT_TYPE)) {
|
||||
builder.addHeader(CONTENT_TYPE, DEFAULT_CONTENT_TYPE);
|
||||
}
|
||||
builder.setEntity(entity);
|
||||
}
|
||||
|
||||
for (Map.Entry<String, String> header : headers.entrySet()) {
|
||||
builder.addHeader(header.getKey(), header.getValue());
|
||||
}
|
||||
|
||||
if (userAgent != null) {
|
||||
builder.setHeader(OAuthConstants.USER_AGENT_HEADER_NAME, userAgent);
|
||||
}
|
||||
final OAuthAsyncCompletionHandler<T> handler = new OAuthAsyncCompletionHandler<>(callback, converter);
|
||||
final Future<HttpResponse> future = client.execute(builder.build(), handler);
|
||||
return new ApacheHttpFuture<>(future, handler);
|
||||
}
|
||||
|
||||
private static RequestBuilder getRequestBuilder(Verb httpVerb) {
|
||||
switch (httpVerb) {
|
||||
case GET:
|
||||
return RequestBuilder.get();
|
||||
case PUT:
|
||||
return RequestBuilder.put();
|
||||
case DELETE:
|
||||
return RequestBuilder.delete();
|
||||
case HEAD:
|
||||
return RequestBuilder.head();
|
||||
case POST:
|
||||
return RequestBuilder.post();
|
||||
case PATCH:
|
||||
return RequestBuilder.patch();
|
||||
case TRACE:
|
||||
return RequestBuilder.trace();
|
||||
case OPTIONS:
|
||||
return RequestBuilder.options();
|
||||
default:
|
||||
throw new IllegalArgumentException("message build error: unknown verb type");
|
||||
}
|
||||
}
|
||||
}*/
|
||||
@ -1,160 +0,0 @@
|
||||
/*
|
||||
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.client.oauth.builder.api;
|
||||
|
||||
|
||||
import org.maxkey.client.http.HttpVerb;
|
||||
import org.maxkey.client.oauth.extractors.*;
|
||||
import org.maxkey.client.oauth.model.*;
|
||||
import org.maxkey.client.oauth.oauth.*;
|
||||
import org.maxkey.client.oauth.services.*;
|
||||
|
||||
/**
|
||||
* Default implementation of the OAuth protocol, version 1.0a
|
||||
*
|
||||
* This class is meant to be extended by concrete implementations of the API,
|
||||
* providing the endpoints and endpoint-http-verbs.
|
||||
*
|
||||
* If your Api adheres to the 1.0a protocol correctly, you just need to extend
|
||||
* this class and define the getters for your endpoints.
|
||||
*
|
||||
* If your Api does something a bit different, you can override the different
|
||||
* extractors or services, in order to fine-tune the process. Please read the
|
||||
* javadocs of the interfaces to get an idea of what to do.
|
||||
*
|
||||
* @author Pablo Fernandez
|
||||
*
|
||||
*/
|
||||
public abstract class DefaultApi10a implements Api
|
||||
{
|
||||
/**
|
||||
* Returns the access token extractor.
|
||||
*
|
||||
* @return access token extractor
|
||||
*/
|
||||
public AccessTokenExtractor getAccessTokenExtractor()
|
||||
{
|
||||
return new TokenExtractorImpl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the base string extractor.
|
||||
*
|
||||
* @return base string extractor
|
||||
*/
|
||||
public BaseStringExtractor getBaseStringExtractor()
|
||||
{
|
||||
return new BaseStringExtractorImpl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the header extractor.
|
||||
*
|
||||
* @return header extractor
|
||||
*/
|
||||
public HeaderExtractor getHeaderExtractor()
|
||||
{
|
||||
return new HeaderExtractorImpl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the request token extractor.
|
||||
*
|
||||
* @return request token extractor
|
||||
*/
|
||||
public RequestTokenExtractor getRequestTokenExtractor()
|
||||
{
|
||||
return new TokenExtractorImpl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the signature service.
|
||||
*
|
||||
* @return signature service
|
||||
*/
|
||||
public SignatureService getSignatureService()
|
||||
{
|
||||
return new HMACSha1SignatureService();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the timestamp service.
|
||||
*
|
||||
* @return timestamp service
|
||||
*/
|
||||
public TimestampService getTimestampService()
|
||||
{
|
||||
return new TimestampServiceImpl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the verb for the access token endpoint (defaults to POST)
|
||||
*
|
||||
* @return access token endpoint verb
|
||||
*/
|
||||
public HttpVerb getAccessTokenVerb()
|
||||
{
|
||||
return HttpVerb.POST;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the verb for the request token endpoint (defaults to POST)
|
||||
*
|
||||
* @return request token endpoint verb
|
||||
*/
|
||||
public HttpVerb getRequestTokenVerb()
|
||||
{
|
||||
return HttpVerb.POST;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL that receives the request token requests.
|
||||
*
|
||||
* @return request token URL
|
||||
*/
|
||||
public abstract String getRequestTokenEndpoint();
|
||||
|
||||
/**
|
||||
* Returns the URL that receives the access token requests.
|
||||
*
|
||||
* @return access token URL
|
||||
*/
|
||||
public abstract String getAccessTokenEndpoint();
|
||||
|
||||
/**
|
||||
* Returns the URL where you should redirect your users to authenticate
|
||||
* your application.
|
||||
*
|
||||
* @param requestToken the request token you need to authorize
|
||||
* @return the URL where you should redirect your users
|
||||
*/
|
||||
public abstract String getAuthorizationUrl(Token requestToken);
|
||||
|
||||
/**
|
||||
* Returns the {@link OAuthService} for this Api
|
||||
*
|
||||
* @param apiKey Key
|
||||
* @param apiSecret Api Secret
|
||||
* @param callback OAuth callback (either URL or 'oob')
|
||||
* @param scope OAuth scope (optional)
|
||||
*/
|
||||
public OAuthService createService(OAuthConfig config)
|
||||
{
|
||||
return new OAuth10aServiceImpl(this, config);
|
||||
}
|
||||
}
|
||||
@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.client.oauth.builder.api;
|
||||
|
||||
import org.maxkey.client.oauth.model.Token;
|
||||
|
||||
public class MaxkeyApi10a extends DefaultApi10a
|
||||
{
|
||||
private static final String DEFAULT_WEB_URL = "https://sso.maxkey.top/maxkey";
|
||||
private static final String AUTHORIZATION_URL = DEFAULT_WEB_URL+"/oauth/v10a/authz?oauth_token=%s";
|
||||
|
||||
public MaxkeyApi10a() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAccessTokenEndpoint()
|
||||
{
|
||||
return DEFAULT_WEB_URL+"/oauth/v10a/access_token";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRequestTokenEndpoint()
|
||||
{
|
||||
return DEFAULT_WEB_URL+"/oauth/v10a/request_token";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthorizationUrl(Token requestToken)
|
||||
{
|
||||
return String.format(AUTHORIZATION_URL, requestToken.getToken());
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,86 +0,0 @@
|
||||
/*
|
||||
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.client.oauth.builder.api;
|
||||
|
||||
import org.maxkey.client.oauth.model.*;
|
||||
|
||||
public class OAuthApi10a extends DefaultApi10a
|
||||
{
|
||||
//private static final String REQUEST_TOKEN_URL = "http://api.t.sina.com.cn/oauth/request_token";
|
||||
//private static final String ACCESS_TOKEN_URL = "http://api.t.sina.com.cn/oauth/access_token";
|
||||
//private static final String AUTHORIZE_URL = "http://api.t.sina.com.cn/oauth/authorize?oauth_token=%s";
|
||||
private String requestTokenUrl;
|
||||
private String accessTokenUrl;
|
||||
private String authorizeUrl;
|
||||
|
||||
public OAuthApi10a(String requestTokenUrl,String authorizeUrl, String accessTokenUrl) {
|
||||
super();
|
||||
this.requestTokenUrl = requestTokenUrl;
|
||||
this.authorizeUrl = authorizeUrl;
|
||||
this.accessTokenUrl = accessTokenUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRequestTokenEndpoint()
|
||||
{
|
||||
return requestTokenUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAccessTokenEndpoint()
|
||||
{
|
||||
return accessTokenUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthorizationUrl(Token requestToken)
|
||||
{
|
||||
return String.format(authorizeUrl, requestToken.getToken());
|
||||
}
|
||||
|
||||
public String getRequestTokenUrl() {
|
||||
return requestTokenUrl;
|
||||
}
|
||||
|
||||
public void setRequestTokenUrl(String requestTokenUrl) {
|
||||
this.requestTokenUrl = requestTokenUrl;
|
||||
}
|
||||
|
||||
public String getAccessTokenUrl() {
|
||||
return accessTokenUrl;
|
||||
}
|
||||
|
||||
public void setAccessTokenUrl(String accessTokenUrl) {
|
||||
this.accessTokenUrl = accessTokenUrl;
|
||||
}
|
||||
|
||||
public String getAuthorizeUrl() {
|
||||
return authorizeUrl;
|
||||
}
|
||||
|
||||
public void setAuthorizeUrl(String authorizeUrl) {
|
||||
this.authorizeUrl = authorizeUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "OAuthApi10a [requestTokenUrl=" + requestTokenUrl
|
||||
+ ", accessTokenUrl=" + accessTokenUrl + ", authorizeUrl="
|
||||
+ authorizeUrl + "]";
|
||||
}
|
||||
}
|
||||
@ -1,240 +0,0 @@
|
||||
/*
|
||||
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.client.oauth.oauth;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.maxkey.client.http.Request;
|
||||
import org.maxkey.client.http.RequestTuner;
|
||||
import org.maxkey.client.http.Response;
|
||||
import org.maxkey.client.oauth.builder.api.*;
|
||||
import org.maxkey.client.oauth.model.*;
|
||||
import org.maxkey.client.oauth.services.*;
|
||||
import org.maxkey.client.utils.MapUtils;
|
||||
|
||||
/**
|
||||
* OAuth 1.0a implementation of {@link OAuthService}
|
||||
*
|
||||
* @author Pablo Fernandez
|
||||
*/
|
||||
public class OAuth10aServiceImpl implements OAuthService
|
||||
{
|
||||
private static final String VERSION = "1.0";
|
||||
|
||||
private OAuthConfig config;
|
||||
private DefaultApi10a api;
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*
|
||||
* @param api OAuth1.0a api information
|
||||
* @param config OAuth 1.0a configuration param object
|
||||
*/
|
||||
public OAuth10aServiceImpl(DefaultApi10a api, OAuthConfig config)
|
||||
{
|
||||
this.api = api;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*
|
||||
* @param clientId
|
||||
* @param clientSecret
|
||||
* @param redirectUri
|
||||
*/
|
||||
public OAuth10aServiceImpl(String clientId, String clientSecret,String redirectUri)
|
||||
{
|
||||
this.api = new MaxkeyApi10a();
|
||||
this.config =new OAuthConfig(clientId,clientSecret,redirectUri);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public Token getRequestToken(int timeout, TimeUnit unit)
|
||||
{
|
||||
return getRequestToken(new TimeoutTuner(timeout, unit));
|
||||
}
|
||||
|
||||
public Token getRequestToken()
|
||||
{
|
||||
return getRequestToken(2, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
public Token getRequestToken(RequestTuner tuner)
|
||||
{
|
||||
config.log("obtaining request token from " + api.getRequestTokenEndpoint());
|
||||
OAuthRequest request = new OAuthRequest(api.getRequestTokenVerb(), api.getRequestTokenEndpoint());
|
||||
|
||||
config.log("setting oauth_callback to " + config.getCallback());
|
||||
request.addOAuthParameter(OAuthConstants.CALLBACK, config.getCallback());
|
||||
addOAuthParams(request, OAuthConstants.EMPTY_TOKEN);
|
||||
appendSignature(request);
|
||||
|
||||
config.log("sending request...");
|
||||
Response response = request.send(tuner);
|
||||
String body = response.getBody();
|
||||
|
||||
config.log("response status code: " + response.getCode());
|
||||
config.log("response body: " + body);
|
||||
return api.getRequestTokenExtractor().extract(body);
|
||||
}
|
||||
|
||||
private void addOAuthParams(OAuthRequest request, Token token)
|
||||
{
|
||||
request.addOAuthParameter(OAuthConstants.TIMESTAMP, api.getTimestampService().getTimestampInSeconds());
|
||||
request.addOAuthParameter(OAuthConstants.NONCE, api.getTimestampService().getNonce());
|
||||
request.addOAuthParameter(OAuthConstants.CONSUMER_KEY, config.getApiKey());
|
||||
request.addOAuthParameter(OAuthConstants.SIGN_METHOD, api.getSignatureService().getSignatureMethod());
|
||||
request.addOAuthParameter(OAuthConstants.VERSION, getVersion());
|
||||
if(config.hasScope()) request.addOAuthParameter(OAuthConstants.SCOPE, config.getScope());
|
||||
request.addOAuthParameter(OAuthConstants.SIGNATURE, getSignature(request, token));
|
||||
|
||||
config.log("appended additional OAuth parameters: " + MapUtils.toString(request.getOauthParameters()));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public Token getAccessToken(Token requestToken, Verifier verifier, int timeout, TimeUnit unit)
|
||||
{
|
||||
return getAccessToken(requestToken, verifier, new TimeoutTuner(timeout, unit));
|
||||
}
|
||||
|
||||
public Token getAccessToken(Token requestToken, Verifier verifier)
|
||||
{
|
||||
return getAccessToken(requestToken, verifier, 2, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
public Token getAccessToken(Token requestToken, Verifier verifier, RequestTuner tuner)
|
||||
{
|
||||
config.log("obtaining access token from " + api.getAccessTokenEndpoint());
|
||||
OAuthRequest request = new OAuthRequest(api.getAccessTokenVerb(), api.getAccessTokenEndpoint());
|
||||
request.addOAuthParameter(OAuthConstants.TOKEN, requestToken.getToken());
|
||||
request.addOAuthParameter(OAuthConstants.VERIFIER, verifier.getValue());
|
||||
|
||||
config.log("setting token to: " + requestToken + " and verifier to: " + verifier);
|
||||
addOAuthParams(request, requestToken);
|
||||
appendSignature(request);
|
||||
Response response = request.send(tuner);
|
||||
return api.getAccessTokenExtractor().extract(response.getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void signRequest(Token token, OAuthRequest request)
|
||||
{
|
||||
config.log("signing request: " + request.getCompleteUrl());
|
||||
|
||||
// Do not append the token if empty. This is for two legged OAuth calls.
|
||||
if (!token.isEmpty())
|
||||
{
|
||||
request.addOAuthParameter(OAuthConstants.TOKEN, token.getToken());
|
||||
}
|
||||
config.log("setting token to: " + token);
|
||||
addOAuthParams(request, token);
|
||||
appendSignature(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public String getVersion()
|
||||
{
|
||||
return VERSION;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public String getAuthorizationUrl(Token requestToken)
|
||||
{
|
||||
return api.getAuthorizationUrl(requestToken);
|
||||
}
|
||||
|
||||
private String getSignature(OAuthRequest request, Token token)
|
||||
{
|
||||
config.log("generating signature...");
|
||||
config.log("using base64 encoder: " + Base64Encoder.type());
|
||||
String baseString = api.getBaseStringExtractor().extract(request);
|
||||
String signature = api.getSignatureService().getSignature(baseString, config.getApiSecret(), token.getSecret());
|
||||
|
||||
config.log("base string is: " + baseString);
|
||||
config.log("signature is: " + signature);
|
||||
return signature;
|
||||
}
|
||||
|
||||
private void appendSignature(OAuthRequest request)
|
||||
{
|
||||
switch (config.getSignatureType())
|
||||
{
|
||||
case Header:
|
||||
config.log("using Http Header signature");
|
||||
|
||||
String oauthHeader = api.getHeaderExtractor().extract(request);
|
||||
request.addHeader(OAuthConstants.HEADER, oauthHeader);
|
||||
break;
|
||||
case QueryString:
|
||||
config.log("using Querystring signature");
|
||||
|
||||
for (Map.Entry<String, String> entry : request.getOauthParameters().entrySet())
|
||||
{
|
||||
request.addQuerystringParameter(entry.getKey(), entry.getValue());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static class TimeoutTuner extends RequestTuner
|
||||
{
|
||||
private final int duration;
|
||||
private final TimeUnit unit;
|
||||
|
||||
public TimeoutTuner(int duration, TimeUnit unit)
|
||||
{
|
||||
this.duration = duration;
|
||||
this.unit = unit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tune(Request request)
|
||||
{
|
||||
request.setReadTimeout(duration, unit);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void signAccessTokenRequest(Token accessToken, OAuthRequest request) {
|
||||
// TODO Auto-generated method stub
|
||||
config.log("signing request: " + request.getCompleteUrl());
|
||||
|
||||
// Do not append the token if empty. This is for two legged OAuth calls.
|
||||
if (!accessToken.isEmpty())
|
||||
{
|
||||
request.addQuerystringParameter(OAuthConstants.ACCESS_TOKEN, accessToken.getToken());
|
||||
}else{
|
||||
throw new IllegalArgumentException("accessToken can not be null .");
|
||||
}
|
||||
config.log("setting token to: " + accessToken);
|
||||
|
||||
}
|
||||
}
|
||||
@ -50,7 +50,7 @@ public class AuthenticationFilter implements Filter {
|
||||
|
||||
private static final String UUID_REGEX = "^[0-9a-z]{8}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{12}$";
|
||||
|
||||
public static final String CONST_CONNSEC_USERINFO="CONST_CONNSEC_USERINFO";
|
||||
public static final String CONST_MAXKEY_USERINFO="CONST_MAXKEY_USERINFO";
|
||||
|
||||
private String clientId;
|
||||
private String clientSecret;
|
||||
@ -77,9 +77,9 @@ public class AuthenticationFilter implements Filter {
|
||||
|
||||
UserInfo userInfo=restClient.getUserInfo(accessToken.getToken());
|
||||
|
||||
session.setAttribute(CONST_CONNSEC_USERINFO, userInfo);
|
||||
session.setAttribute(CONST_MAXKEY_USERINFO, userInfo);
|
||||
|
||||
}else if(session.getAttribute(CONST_CONNSEC_USERINFO)==null){
|
||||
}else if(session.getAttribute(CONST_MAXKEY_USERINFO)==null){
|
||||
String authorizationUrl = service.getAuthorizationUrl(EMPTY_TOKEN);
|
||||
log.debug("Redirect to authorization Url : "+authorizationUrl);
|
||||
httpServletResponse.sendRedirect(authorizationUrl);
|
||||
|
||||
@ -46,7 +46,7 @@ public class SingleSignOutFilter implements Filter {
|
||||
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
|
||||
|
||||
HttpSession session = httpServletRequest.getSession();
|
||||
session.removeAttribute(AuthenticationFilter.CONST_CONNSEC_USERINFO);
|
||||
session.removeAttribute(AuthenticationFilter.CONST_MAXKEY_USERINFO);
|
||||
session.invalidate();
|
||||
|
||||
httpServletResponse.sendRedirect(singleSignOutEndpoint);
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
|
||||
package com.connsec.client.oauth.test;
|
||||
package org.maxkey.client.oauth.test;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
|
||||
package com.connsec.client.oauth.test;
|
||||
package org.maxkey.client.oauth.test;
|
||||
|
||||
import org.maxkey.client.http.Response;
|
||||
import org.maxkey.client.oauth.builder.api.MaxkeyPasswordApi20;
|
||||
@ -22,4 +22,4 @@
|
||||
* @author Administrator
|
||||
*
|
||||
*/
|
||||
package com.connsec.client.oauth.test;
|
||||
package org.maxkey.client.oauth.test;
|
||||
@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
|
||||
package com.connsec.client.utils;
|
||||
package org.maxkey.client.utils;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
@ -22,4 +22,4 @@
|
||||
* @author Administrator
|
||||
*
|
||||
*/
|
||||
package com.connsec.client.utils;
|
||||
package org.maxkey.client.utils;
|
||||
@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
|
||||
package com.connsec.rest;
|
||||
package org.maxkey.rest;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
@ -21,12 +21,17 @@ import java.util.Optional;
|
||||
|
||||
import org.apache.kafka.clients.consumer.ConsumerRecord;
|
||||
import org.maxkey.connector.GroupConnector;
|
||||
import org.maxkey.domain.Groups;
|
||||
import org.maxkey.identity.kafka.KafkaIdentityAction;
|
||||
import org.maxkey.identity.kafka.KafkaIdentityTopic;
|
||||
import org.maxkey.identity.kafka.KafkaMessage;
|
||||
import org.maxkey.util.JsonUtils;
|
||||
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);
|
||||
@ -36,15 +41,31 @@ public class KafkaGroupsTopicReceiver {
|
||||
|
||||
@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);
|
||||
try {
|
||||
Optional<?> kafkaMessage = Optional.ofNullable(record.value());
|
||||
|
||||
if (kafkaMessage.isPresent()) {
|
||||
|
||||
Object message = kafkaMessage.get();
|
||||
|
||||
_logger.debug("----------------- record =" + record);
|
||||
_logger.debug("------------------ message =" + message);
|
||||
|
||||
KafkaMessage receiverMessage = JsonUtils.gson2Object(message.toString(), KafkaMessage.class);
|
||||
Groups group = JsonUtils.gson2Object(receiverMessage.getContent().toString(),Groups.class);
|
||||
|
||||
if(receiverMessage.getActionType().equalsIgnoreCase(KafkaIdentityAction.CREATE_ACTION)) {
|
||||
groupConnector.create(group);
|
||||
}else if(receiverMessage.getActionType().equalsIgnoreCase(KafkaIdentityAction.UPDATE_ACTION)) {
|
||||
groupConnector.update(group);
|
||||
}else if(receiverMessage.getActionType().equalsIgnoreCase(KafkaIdentityAction.DELETE_ACTION)) {
|
||||
groupConnector.delete(group);
|
||||
}else{
|
||||
_logger.info("Other Action ");
|
||||
}
|
||||
}
|
||||
}catch(Exception e) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -21,12 +21,17 @@ import java.util.Optional;
|
||||
|
||||
import org.apache.kafka.clients.consumer.ConsumerRecord;
|
||||
import org.maxkey.connector.OrganizationConnector;
|
||||
import org.maxkey.domain.Organizations;
|
||||
import org.maxkey.identity.kafka.KafkaIdentityAction;
|
||||
import org.maxkey.identity.kafka.KafkaIdentityTopic;
|
||||
import org.maxkey.identity.kafka.KafkaMessage;
|
||||
import org.maxkey.util.JsonUtils;
|
||||
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);
|
||||
@ -36,15 +41,31 @@ public class KafkaOrgsTopicReceiver {
|
||||
|
||||
@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);
|
||||
try {
|
||||
Optional<?> kafkaMessage = Optional.ofNullable(record.value());
|
||||
|
||||
if (kafkaMessage.isPresent()) {
|
||||
|
||||
Object message = kafkaMessage.get();
|
||||
|
||||
_logger.debug("----------------- record =" + record);
|
||||
_logger.debug("------------------ message =" + message);
|
||||
|
||||
KafkaMessage receiverMessage = JsonUtils.gson2Object(message.toString(), KafkaMessage.class);
|
||||
Organizations org = JsonUtils.gson2Object(receiverMessage.getContent().toString(),Organizations.class);
|
||||
|
||||
if(receiverMessage.getActionType().equalsIgnoreCase(KafkaIdentityAction.CREATE_ACTION)) {
|
||||
organizationConnector.create(org);
|
||||
}else if(receiverMessage.getActionType().equalsIgnoreCase(KafkaIdentityAction.UPDATE_ACTION)) {
|
||||
organizationConnector.update(org);
|
||||
}else if(receiverMessage.getActionType().equalsIgnoreCase(KafkaIdentityAction.DELETE_ACTION)) {
|
||||
organizationConnector.delete(org);
|
||||
}else{
|
||||
_logger.info("Other Action ");
|
||||
}
|
||||
}
|
||||
}catch(Exception e) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -21,12 +21,17 @@ import java.util.Optional;
|
||||
|
||||
import org.apache.kafka.clients.consumer.ConsumerRecord;
|
||||
import org.maxkey.connector.PasswordConnector;
|
||||
import org.maxkey.domain.UserInfo;
|
||||
import org.maxkey.identity.kafka.KafkaIdentityAction;
|
||||
import org.maxkey.identity.kafka.KafkaIdentityTopic;
|
||||
import org.maxkey.identity.kafka.KafkaMessage;
|
||||
import org.maxkey.util.JsonUtils;
|
||||
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);
|
||||
@ -36,16 +41,27 @@ public class KafkaPasswordTopicReceiver {
|
||||
|
||||
@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);
|
||||
try {
|
||||
Optional<?> kafkaMessage = Optional.ofNullable(record.value());
|
||||
|
||||
if (kafkaMessage.isPresent()) {
|
||||
|
||||
Object message = kafkaMessage.get();
|
||||
|
||||
_logger.debug("----------------- record =" + record);
|
||||
_logger.debug("------------------ message =" + message);
|
||||
|
||||
KafkaMessage receiverMessage = JsonUtils.gson2Object(message.toString(), KafkaMessage.class);
|
||||
UserInfo userInfo = JsonUtils.gson2Object(receiverMessage.getContent().toString(),UserInfo.class);
|
||||
|
||||
if(receiverMessage.getActionType().equalsIgnoreCase(KafkaIdentityAction.PASSWORD_ACTION)) {
|
||||
passwordConnector.update(userInfo);
|
||||
}else{
|
||||
_logger.info("Other Action ");
|
||||
}
|
||||
}
|
||||
}catch(Exception e) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,12 +21,17 @@ import java.util.Optional;
|
||||
|
||||
import org.apache.kafka.clients.consumer.ConsumerRecord;
|
||||
import org.maxkey.connector.UserInfoConnector;
|
||||
import org.maxkey.domain.UserInfo;
|
||||
import org.maxkey.identity.kafka.KafkaIdentityAction;
|
||||
import org.maxkey.identity.kafka.KafkaIdentityTopic;
|
||||
import org.maxkey.identity.kafka.KafkaMessage;
|
||||
import org.maxkey.util.JsonUtils;
|
||||
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);
|
||||
@ -36,15 +41,31 @@ public class KafkaUserInfoTopicReceiver {
|
||||
|
||||
@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);
|
||||
try {
|
||||
Optional<?> kafkaMessage = Optional.ofNullable(record.value());
|
||||
|
||||
if (kafkaMessage.isPresent()) {
|
||||
|
||||
Object message = kafkaMessage.get();
|
||||
|
||||
_logger.debug("----------------- record =" + record);
|
||||
_logger.debug("------------------ message =" + message);
|
||||
|
||||
KafkaMessage receiverMessage = JsonUtils.gson2Object(message.toString(), KafkaMessage.class);
|
||||
UserInfo userInfo = JsonUtils.gson2Object(receiverMessage.getContent().toString(),UserInfo.class);
|
||||
|
||||
if(receiverMessage.getActionType().equalsIgnoreCase(KafkaIdentityAction.CREATE_ACTION)) {
|
||||
userInfoConnector.create(userInfo);
|
||||
}else if(receiverMessage.getActionType().equalsIgnoreCase(KafkaIdentityAction.UPDATE_ACTION)) {
|
||||
userInfoConnector.update(userInfo);
|
||||
}else if(receiverMessage.getActionType().equalsIgnoreCase(KafkaIdentityAction.DELETE_ACTION)) {
|
||||
userInfoConnector.delete(userInfo);
|
||||
}else{
|
||||
_logger.info("Other Action ");
|
||||
}
|
||||
}
|
||||
}catch(Exception e) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
36
maxkey-connectors/maxkey-connector-dingding/.classpath
Normal file
36
maxkey-connectors/maxkey-connector-dingding/.classpath
Normal file
@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="bin/main" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="main"/>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="bin/main" path="src/main/resources">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="main"/>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="bin/test" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="test"/>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="bin/test" path="src/test/resources">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="test"/>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/>
|
||||
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer">
|
||||
<attributes>
|
||||
<attribute name="org.eclipse.jst.component.nondependency" value=""/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="bin/default"/>
|
||||
</classpath>
|
||||
41
maxkey-connectors/maxkey-connector-dingding/.project
Normal file
41
maxkey-connectors/maxkey-connector-dingding/.project
Normal file
@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>maxkey-connector-dingding</name>
|
||||
<comment>Project maxkey-connector-dingding created by Buildship.</comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.common.project.facet.core.builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.validation.validationbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.springframework.ide.eclipse.boot.validation.springbootbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
|
||||
<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
|
||||
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
|
||||
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@ -0,0 +1,2 @@
|
||||
connection.project.dir=../..
|
||||
eclipse.preferences.version=1
|
||||
@ -0,0 +1,2 @@
|
||||
eclipse.preferences.version=1
|
||||
encoding/<project>=UTF-8
|
||||
@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project-modules id="moduleCoreId" project-version="1.5.0">
|
||||
<wb-module deploy-name="maxkey-connector-dingding">
|
||||
<wb-resource deploy-path="/" source-path="src/main/resources"/>
|
||||
<wb-resource deploy-path="/" source-path="src/main/java"/>
|
||||
<dependent-module deploy-path="../" handle="module:/resource/maxkey-core/maxkey-core">
|
||||
<dependency-type>uses</dependency-type>
|
||||
</dependent-module>
|
||||
<dependent-module deploy-path="../" handle="module:/resource/maxkey-persistence/maxkey-persistence">
|
||||
<dependency-type>uses</dependency-type>
|
||||
</dependent-module>
|
||||
<dependent-module deploy-path="../" handle="module:/resource/maxkey-client-sdk/maxkey-client-sdk">
|
||||
<dependency-type>uses</dependency-type>
|
||||
</dependent-module>
|
||||
<dependent-module deploy-path="../" handle="module:/resource/maxkey-connector-base/maxkey-connector-base">
|
||||
<dependency-type>uses</dependency-type>
|
||||
</dependent-module>
|
||||
<dependent-module deploy-path="../" handle="module:/resource/maxkey-identity-kafka/maxkey-identity-kafka">
|
||||
<dependency-type>uses</dependency-type>
|
||||
</dependent-module>
|
||||
</wb-module>
|
||||
</project-modules>
|
||||
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<faceted-project>
|
||||
<fixed facet="jst.java"/>
|
||||
<installed facet="jst.utility" version="1.0"/>
|
||||
<installed facet="jst.java" version="1.8"/>
|
||||
</faceted-project>
|
||||
@ -0,0 +1,2 @@
|
||||
boot.validation.initialized=true
|
||||
eclipse.preferences.version=1
|
||||
17
maxkey-connectors/maxkey-connector-dingding/build.gradle
Normal file
17
maxkey-connectors/maxkey-connector-dingding/build.gradle
Normal file
@ -0,0 +1,17 @@
|
||||
description = "maxkey-connector-dingding"
|
||||
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'eclipse-wtp'
|
||||
|
||||
|
||||
dependencies {
|
||||
//local jars
|
||||
compile fileTree(dir: '../maxkey-lib/*/', include: '*.jar')
|
||||
|
||||
compile project(":maxkey-core")
|
||||
compile project(":maxkey-persistence")
|
||||
compile project(":maxkey-client-sdk")
|
||||
compile project(":maxkey-connectors:maxkey-connector-base")
|
||||
compile project(":maxkey-identitys:maxkey-identity-kafka")
|
||||
|
||||
}
|
||||
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.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.dingding"
|
||||
})
|
||||
public class DingdingConsumerApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
// TODO Auto-generated method stub
|
||||
ConfigurableApplicationContext context = SpringApplication.run(DingdingConsumerApplication.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(DingdingConsumerApplication.class);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.connector.dingding;
|
||||
|
||||
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 Group2Dingding extends GroupConnector {
|
||||
private final static Logger logger = LoggerFactory.getLogger(Group2Dingding.class);
|
||||
|
||||
LdapUtils ldapUtils;
|
||||
public Group2Dingding() {
|
||||
|
||||
}
|
||||
|
||||
@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<SearchResult> 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<SearchResult> 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<SearchResult> 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.connector.dingding;
|
||||
|
||||
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 Organization2Dingding extends OrganizationConnector{
|
||||
private final static Logger logger = LoggerFactory.getLogger(Organization2Dingding.class);
|
||||
|
||||
LdapUtils ldapUtils;
|
||||
public Organization2Dingding() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean create(Organizations organization) throws Exception {
|
||||
logger.info("create");
|
||||
SearchControls constraints = new SearchControls();
|
||||
constraints.setSearchScope(ldapUtils.getSearchScope());
|
||||
NamingEnumeration<SearchResult> results = ldapUtils.getConnection()
|
||||
.search(ldapUtils.getBaseDN(), "(&(objectClass=organizationalUnit)(description="+organization.getParentId()+"))", 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<SearchResult> 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<SearchResult> 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);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.connector.dingding;
|
||||
|
||||
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 Password2Dingding extends PasswordConnector{
|
||||
private final static Logger logger = LoggerFactory.getLogger(Password2Dingding.class);
|
||||
|
||||
LdapUtils ldapUtils;
|
||||
|
||||
public Password2Dingding() {
|
||||
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.connector.dingding;
|
||||
|
||||
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 UserInfo2Dingding extends UserInfoConnector{
|
||||
private final static Logger logger = LoggerFactory.getLogger(UserInfo2Dingding.class);
|
||||
|
||||
LdapUtils ldapUtils;
|
||||
|
||||
public UserInfo2Dingding() {
|
||||
|
||||
}
|
||||
|
||||
@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<SearchResult> 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;
|
||||
}
|
||||
}
|
||||
@ -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=LdapConsumerGroup
|
||||
# 是否自动提交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
|
||||
36
maxkey-connectors/maxkey-connector-feishu/.classpath
Normal file
36
maxkey-connectors/maxkey-connector-feishu/.classpath
Normal file
@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="bin/main" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="main"/>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="bin/main" path="src/main/resources">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="main"/>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="bin/test" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="test"/>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="bin/test" path="src/test/resources">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="test"/>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/>
|
||||
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer">
|
||||
<attributes>
|
||||
<attribute name="org.eclipse.jst.component.nondependency" value=""/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="bin/default"/>
|
||||
</classpath>
|
||||
41
maxkey-connectors/maxkey-connector-feishu/.project
Normal file
41
maxkey-connectors/maxkey-connector-feishu/.project
Normal file
@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>maxkey-connector-feishu</name>
|
||||
<comment>Project maxkey-connector-feishu created by Buildship.</comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.common.project.facet.core.builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.validation.validationbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.springframework.ide.eclipse.boot.validation.springbootbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
|
||||
<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
|
||||
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
|
||||
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@ -0,0 +1,2 @@
|
||||
connection.project.dir=../..
|
||||
eclipse.preferences.version=1
|
||||
@ -0,0 +1,2 @@
|
||||
eclipse.preferences.version=1
|
||||
encoding/<project>=UTF-8
|
||||
@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project-modules id="moduleCoreId" project-version="1.5.0">
|
||||
<wb-module deploy-name="maxkey-connector-feishu">
|
||||
<wb-resource deploy-path="/" source-path="src/main/resources"/>
|
||||
<wb-resource deploy-path="/" source-path="src/main/java"/>
|
||||
<dependent-module deploy-path="../" handle="module:/resource/maxkey-core/maxkey-core">
|
||||
<dependency-type>uses</dependency-type>
|
||||
</dependent-module>
|
||||
<dependent-module deploy-path="../" handle="module:/resource/maxkey-persistence/maxkey-persistence">
|
||||
<dependency-type>uses</dependency-type>
|
||||
</dependent-module>
|
||||
<dependent-module deploy-path="../" handle="module:/resource/maxkey-client-sdk/maxkey-client-sdk">
|
||||
<dependency-type>uses</dependency-type>
|
||||
</dependent-module>
|
||||
<dependent-module deploy-path="../" handle="module:/resource/maxkey-connector-base/maxkey-connector-base">
|
||||
<dependency-type>uses</dependency-type>
|
||||
</dependent-module>
|
||||
<dependent-module deploy-path="../" handle="module:/resource/maxkey-identity-kafka/maxkey-identity-kafka">
|
||||
<dependency-type>uses</dependency-type>
|
||||
</dependent-module>
|
||||
</wb-module>
|
||||
</project-modules>
|
||||
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<faceted-project>
|
||||
<fixed facet="jst.java"/>
|
||||
<installed facet="jst.utility" version="1.0"/>
|
||||
<installed facet="jst.java" version="1.8"/>
|
||||
</faceted-project>
|
||||
@ -0,0 +1,2 @@
|
||||
boot.validation.initialized=true
|
||||
eclipse.preferences.version=1
|
||||
17
maxkey-connectors/maxkey-connector-feishu/build.gradle
Normal file
17
maxkey-connectors/maxkey-connector-feishu/build.gradle
Normal file
@ -0,0 +1,17 @@
|
||||
description = "maxkey-connector-feishu"
|
||||
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'eclipse-wtp'
|
||||
|
||||
|
||||
dependencies {
|
||||
//local jars
|
||||
compile fileTree(dir: '../maxkey-lib/*/', include: '*.jar')
|
||||
|
||||
compile project(":maxkey-core")
|
||||
compile project(":maxkey-persistence")
|
||||
compile project(":maxkey-client-sdk")
|
||||
compile project(":maxkey-connectors:maxkey-connector-base")
|
||||
compile project(":maxkey-identitys:maxkey-identity-kafka")
|
||||
|
||||
}
|
||||
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.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 FeishuConsumerApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
// TODO Auto-generated method stub
|
||||
ConfigurableApplicationContext context = SpringApplication.run(FeishuConsumerApplication.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(FeishuConsumerApplication.class);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.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 Group2Feishu extends GroupConnector {
|
||||
private final static Logger logger = LoggerFactory.getLogger(Group2Feishu.class);
|
||||
|
||||
LdapUtils ldapUtils;
|
||||
public Group2Feishu() {
|
||||
|
||||
}
|
||||
|
||||
@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<SearchResult> 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<SearchResult> 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<SearchResult> 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.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 Organization2Feishu extends OrganizationConnector{
|
||||
private final static Logger logger = LoggerFactory.getLogger(Organization2Feishu.class);
|
||||
|
||||
LdapUtils ldapUtils;
|
||||
public Organization2Feishu() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean create(Organizations organization) throws Exception {
|
||||
logger.info("create");
|
||||
SearchControls constraints = new SearchControls();
|
||||
constraints.setSearchScope(ldapUtils.getSearchScope());
|
||||
NamingEnumeration<SearchResult> results = ldapUtils.getConnection()
|
||||
.search(ldapUtils.getBaseDN(), "(&(objectClass=organizationalUnit)(description="+organization.getParentId()+"))", 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<SearchResult> 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<SearchResult> 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);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.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 Password2Feishu extends PasswordConnector{
|
||||
private final static Logger logger = LoggerFactory.getLogger(Password2Feishu.class);
|
||||
|
||||
LdapUtils ldapUtils;
|
||||
|
||||
public Password2Feishu() {
|
||||
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.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 UserInfo2Feishu extends UserInfoConnector{
|
||||
private final static Logger logger = LoggerFactory.getLogger(UserInfo2Feishu.class);
|
||||
|
||||
LdapUtils ldapUtils;
|
||||
|
||||
public UserInfo2Feishu() {
|
||||
|
||||
}
|
||||
|
||||
@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<SearchResult> 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;
|
||||
}
|
||||
}
|
||||
@ -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=LdapConsumerGroup
|
||||
# 是否自动提交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
|
||||
36
maxkey-connectors/maxkey-connector-welink/.classpath
Normal file
36
maxkey-connectors/maxkey-connector-welink/.classpath
Normal file
@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="bin/main" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="main"/>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="bin/main" path="src/main/resources">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="main"/>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="bin/test" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="test"/>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="bin/test" path="src/test/resources">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="test"/>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/>
|
||||
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer">
|
||||
<attributes>
|
||||
<attribute name="org.eclipse.jst.component.nondependency" value=""/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="bin/default"/>
|
||||
</classpath>
|
||||
41
maxkey-connectors/maxkey-connector-welink/.project
Normal file
41
maxkey-connectors/maxkey-connector-welink/.project
Normal file
@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>maxkey-connector-welink</name>
|
||||
<comment>Project maxkey-connector-welink created by Buildship.</comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.common.project.facet.core.builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.validation.validationbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.springframework.ide.eclipse.boot.validation.springbootbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
|
||||
<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
|
||||
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
|
||||
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@ -0,0 +1,2 @@
|
||||
connection.project.dir=../..
|
||||
eclipse.preferences.version=1
|
||||
@ -0,0 +1,2 @@
|
||||
eclipse.preferences.version=1
|
||||
encoding/<project>=UTF-8
|
||||
@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project-modules id="moduleCoreId" project-version="1.5.0">
|
||||
<wb-module deploy-name="maxkey-connector-welink">
|
||||
<wb-resource deploy-path="/" source-path="src/main/resources"/>
|
||||
<wb-resource deploy-path="/" source-path="src/main/java"/>
|
||||
<dependent-module deploy-path="../" handle="module:/resource/maxkey-core/maxkey-core">
|
||||
<dependency-type>uses</dependency-type>
|
||||
</dependent-module>
|
||||
<dependent-module deploy-path="../" handle="module:/resource/maxkey-persistence/maxkey-persistence">
|
||||
<dependency-type>uses</dependency-type>
|
||||
</dependent-module>
|
||||
<dependent-module deploy-path="../" handle="module:/resource/maxkey-client-sdk/maxkey-client-sdk">
|
||||
<dependency-type>uses</dependency-type>
|
||||
</dependent-module>
|
||||
<dependent-module deploy-path="../" handle="module:/resource/maxkey-connector-base/maxkey-connector-base">
|
||||
<dependency-type>uses</dependency-type>
|
||||
</dependent-module>
|
||||
<dependent-module deploy-path="../" handle="module:/resource/maxkey-identity-kafka/maxkey-identity-kafka">
|
||||
<dependency-type>uses</dependency-type>
|
||||
</dependent-module>
|
||||
</wb-module>
|
||||
</project-modules>
|
||||
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<faceted-project>
|
||||
<fixed facet="jst.java"/>
|
||||
<installed facet="jst.utility" version="1.0"/>
|
||||
<installed facet="jst.java" version="1.8"/>
|
||||
</faceted-project>
|
||||
@ -0,0 +1,2 @@
|
||||
boot.validation.initialized=true
|
||||
eclipse.preferences.version=1
|
||||
17
maxkey-connectors/maxkey-connector-welink/build.gradle
Normal file
17
maxkey-connectors/maxkey-connector-welink/build.gradle
Normal file
@ -0,0 +1,17 @@
|
||||
description = "maxkey-connector-welink"
|
||||
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'eclipse-wtp'
|
||||
|
||||
|
||||
dependencies {
|
||||
//local jars
|
||||
compile fileTree(dir: '../maxkey-lib/*/', include: '*.jar')
|
||||
|
||||
compile project(":maxkey-core")
|
||||
compile project(":maxkey-persistence")
|
||||
compile project(":maxkey-client-sdk")
|
||||
compile project(":maxkey-connectors:maxkey-connector-base")
|
||||
compile project(":maxkey-identitys:maxkey-identity-kafka")
|
||||
|
||||
}
|
||||
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.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 WelinkConsumerApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
// TODO Auto-generated method stub
|
||||
ConfigurableApplicationContext context = SpringApplication.run(WelinkConsumerApplication.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(WelinkConsumerApplication.class);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.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 Group2Welink extends GroupConnector {
|
||||
private final static Logger logger = LoggerFactory.getLogger(Group2Welink.class);
|
||||
|
||||
LdapUtils ldapUtils;
|
||||
public Group2Welink() {
|
||||
|
||||
}
|
||||
|
||||
@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<SearchResult> 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<SearchResult> 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<SearchResult> 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.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 Organization2Welink extends OrganizationConnector{
|
||||
private final static Logger logger = LoggerFactory.getLogger(Organization2Welink.class);
|
||||
|
||||
LdapUtils ldapUtils;
|
||||
public Organization2Welink() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean create(Organizations organization) throws Exception {
|
||||
logger.info("create");
|
||||
SearchControls constraints = new SearchControls();
|
||||
constraints.setSearchScope(ldapUtils.getSearchScope());
|
||||
NamingEnumeration<SearchResult> results = ldapUtils.getConnection()
|
||||
.search(ldapUtils.getBaseDN(), "(&(objectClass=organizationalUnit)(description="+organization.getParentId()+"))", 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<SearchResult> 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<SearchResult> 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);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.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 Password2Welink extends PasswordConnector{
|
||||
private final static Logger logger = LoggerFactory.getLogger(Password2Welink.class);
|
||||
|
||||
LdapUtils ldapUtils;
|
||||
|
||||
public Password2Welink() {
|
||||
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.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 UserInfo2Welink extends UserInfoConnector{
|
||||
private final static Logger logger = LoggerFactory.getLogger(UserInfo2Welink.class);
|
||||
|
||||
LdapUtils ldapUtils;
|
||||
|
||||
public UserInfo2Welink() {
|
||||
|
||||
}
|
||||
|
||||
@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<SearchResult> 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;
|
||||
}
|
||||
}
|
||||
@ -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=LdapConsumerGroup
|
||||
# 是否自动提交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
|
||||
36
maxkey-connectors/maxkey-connector-workweixin/.classpath
Normal file
36
maxkey-connectors/maxkey-connector-workweixin/.classpath
Normal file
@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="bin/main" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="main"/>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="bin/main" path="src/main/resources">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="main"/>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="bin/test" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="test"/>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="bin/test" path="src/test/resources">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="test"/>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/>
|
||||
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer">
|
||||
<attributes>
|
||||
<attribute name="org.eclipse.jst.component.nondependency" value=""/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="bin/default"/>
|
||||
</classpath>
|
||||
41
maxkey-connectors/maxkey-connector-workweixin/.project
Normal file
41
maxkey-connectors/maxkey-connector-workweixin/.project
Normal file
@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>maxkey-connector-workweixin</name>
|
||||
<comment>Project maxkey-connector-workweixin created by Buildship.</comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.common.project.facet.core.builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.validation.validationbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.springframework.ide.eclipse.boot.validation.springbootbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
|
||||
<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
|
||||
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
|
||||
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@ -0,0 +1,2 @@
|
||||
connection.project.dir=../..
|
||||
eclipse.preferences.version=1
|
||||
@ -0,0 +1,2 @@
|
||||
eclipse.preferences.version=1
|
||||
encoding/<project>=UTF-8
|
||||
@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project-modules id="moduleCoreId" project-version="1.5.0">
|
||||
<wb-module deploy-name="maxkey-connector-workweixin">
|
||||
<wb-resource deploy-path="/" source-path="src/main/resources"/>
|
||||
<wb-resource deploy-path="/" source-path="src/main/java"/>
|
||||
<dependent-module deploy-path="../" handle="module:/resource/maxkey-core/maxkey-core">
|
||||
<dependency-type>uses</dependency-type>
|
||||
</dependent-module>
|
||||
<dependent-module deploy-path="../" handle="module:/resource/maxkey-persistence/maxkey-persistence">
|
||||
<dependency-type>uses</dependency-type>
|
||||
</dependent-module>
|
||||
<dependent-module deploy-path="../" handle="module:/resource/maxkey-client-sdk/maxkey-client-sdk">
|
||||
<dependency-type>uses</dependency-type>
|
||||
</dependent-module>
|
||||
<dependent-module deploy-path="../" handle="module:/resource/maxkey-connector-base/maxkey-connector-base">
|
||||
<dependency-type>uses</dependency-type>
|
||||
</dependent-module>
|
||||
<dependent-module deploy-path="../" handle="module:/resource/maxkey-identity-kafka/maxkey-identity-kafka">
|
||||
<dependency-type>uses</dependency-type>
|
||||
</dependent-module>
|
||||
</wb-module>
|
||||
</project-modules>
|
||||
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<faceted-project>
|
||||
<fixed facet="jst.java"/>
|
||||
<installed facet="jst.utility" version="1.0"/>
|
||||
<installed facet="jst.java" version="1.8"/>
|
||||
</faceted-project>
|
||||
@ -0,0 +1,2 @@
|
||||
boot.validation.initialized=true
|
||||
eclipse.preferences.version=1
|
||||
17
maxkey-connectors/maxkey-connector-workweixin/build.gradle
Normal file
17
maxkey-connectors/maxkey-connector-workweixin/build.gradle
Normal file
@ -0,0 +1,17 @@
|
||||
description = "maxkey-connector-workweixin"
|
||||
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'eclipse-wtp'
|
||||
|
||||
|
||||
dependencies {
|
||||
//local jars
|
||||
compile fileTree(dir: '../maxkey-lib/*/', include: '*.jar')
|
||||
|
||||
compile project(":maxkey-core")
|
||||
compile project(":maxkey-persistence")
|
||||
compile project(":maxkey-client-sdk")
|
||||
compile project(":maxkey-connectors:maxkey-connector-base")
|
||||
compile project(":maxkey-identitys:maxkey-identity-kafka")
|
||||
|
||||
}
|
||||
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.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 WeixinConsumerApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
// TODO Auto-generated method stub
|
||||
ConfigurableApplicationContext context = SpringApplication.run(WeixinConsumerApplication.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(WeixinConsumerApplication.class);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.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 Group2Weixin extends GroupConnector {
|
||||
private final static Logger logger = LoggerFactory.getLogger(Group2Weixin.class);
|
||||
|
||||
LdapUtils ldapUtils;
|
||||
public Group2Weixin() {
|
||||
|
||||
}
|
||||
|
||||
@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<SearchResult> 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<SearchResult> 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<SearchResult> 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.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 Organization2Weixin extends OrganizationConnector{
|
||||
private final static Logger logger = LoggerFactory.getLogger(Organization2Weixin.class);
|
||||
|
||||
LdapUtils ldapUtils;
|
||||
public Organization2Weixin() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean create(Organizations organization) throws Exception {
|
||||
logger.info("create");
|
||||
SearchControls constraints = new SearchControls();
|
||||
constraints.setSearchScope(ldapUtils.getSearchScope());
|
||||
NamingEnumeration<SearchResult> results = ldapUtils.getConnection()
|
||||
.search(ldapUtils.getBaseDN(), "(&(objectClass=organizationalUnit)(description="+organization.getParentId()+"))", 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<SearchResult> 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<SearchResult> 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);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.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 Password2Weixin extends PasswordConnector{
|
||||
private final static Logger logger = LoggerFactory.getLogger(Password2Weixin.class);
|
||||
|
||||
LdapUtils ldapUtils;
|
||||
|
||||
public Password2Weixin() {
|
||||
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.maxkey.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 UserInfo2Weixin extends UserInfoConnector{
|
||||
private final static Logger logger = LoggerFactory.getLogger(UserInfo2Weixin.class);
|
||||
|
||||
LdapUtils ldapUtils;
|
||||
|
||||
public UserInfo2Weixin() {
|
||||
|
||||
}
|
||||
|
||||
@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<SearchResult> 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;
|
||||
}
|
||||
}
|
||||
@ -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=LdapConsumerGroup
|
||||
# 是否自动提交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
|
||||
@ -13,11 +13,6 @@
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.web.container"/>
|
||||
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer">
|
||||
<attributes>
|
||||
<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
|
||||
<classpathentry kind="output" path="bin/default"/>
|
||||
</classpath>
|
||||
|
||||
@ -17,6 +17,11 @@
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.common.project.facet.core.builder</name>
|
||||
<arguments>
|
||||
@ -27,11 +32,6 @@
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
|
||||
@ -3,16 +3,16 @@ description = "maxkey-web-manage"
|
||||
// Apply the java plugin to add support for Java
|
||||
apply plugin: 'java'
|
||||
//apply plugin: 'war'
|
||||
apply plugin: 'eclipse-wtp'
|
||||
apply plugin: 'com.bmuschko.tomcat-base'
|
||||
apply plugin: 'com.bmuschko.tomcat'
|
||||
//apply plugin: 'eclipse-wtp'
|
||||
//apply plugin: 'com.bmuschko.tomcat-base'
|
||||
//apply plugin: 'com.bmuschko.tomcat'
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath "com.bmuschko:gradle-tomcat-plugin:2.2.3"
|
||||
//classpath "com.bmuschko:gradle-tomcat-plugin:2.2.3"
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,6 +28,7 @@ dependencies {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
eclipse {
|
||||
|
||||
wtp {
|
||||
@ -39,4 +40,4 @@ eclipse {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}*/
|
||||
@ -20,11 +20,6 @@
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.web.container"/>
|
||||
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer">
|
||||
<attributes>
|
||||
<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
|
||||
<classpathentry kind="output" path="bin/default"/>
|
||||
</classpath>
|
||||
|
||||
@ -23,6 +23,11 @@
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.common.project.facet.core.builder</name>
|
||||
<arguments>
|
||||
@ -33,11 +38,6 @@
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
|
||||
@ -3,16 +3,16 @@ description = "maxkey-web-maxkey"
|
||||
// Apply the java plugin to add support for Java
|
||||
apply plugin: 'java'
|
||||
//apply plugin: 'war'
|
||||
apply plugin: 'eclipse-wtp'
|
||||
apply plugin: 'com.bmuschko.tomcat-base'
|
||||
apply plugin: 'com.bmuschko.tomcat'
|
||||
//apply plugin: 'eclipse-wtp'
|
||||
//apply plugin: 'com.bmuschko.tomcat-base'
|
||||
//apply plugin: 'com.bmuschko.tomcat'
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath "com.bmuschko:gradle-tomcat-plugin:2.2.3"
|
||||
//classpath "com.bmuschko:gradle-tomcat-plugin:2.2.3"
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
@ -34,7 +34,7 @@ dependencies {
|
||||
compile project(":maxkey-identitys:maxkey-identity-kafka")
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
//For Eclipse IDE only
|
||||
eclipse {
|
||||
|
||||
@ -53,4 +53,4 @@ tomcat {
|
||||
httpPort = 80
|
||||
contextPath = '/maxkey'
|
||||
|
||||
}
|
||||
}*/
|
||||
@ -17,8 +17,18 @@ include 'maxkey-identitys:maxkey-identity-rest'
|
||||
|
||||
//connectors
|
||||
include 'maxkey-connectors:maxkey-connector-base'
|
||||
include 'maxkey-connectors:maxkey-connector-ldap'
|
||||
//MS Active Directory
|
||||
include 'maxkey-connectors:maxkey-connector-activedirectory'
|
||||
//OpenLDAP
|
||||
include 'maxkey-connectors:maxkey-connector-ldap'
|
||||
//企业微信
|
||||
include 'maxkey-connectors:maxkey-connector-workweixin'
|
||||
//阿里钉钉
|
||||
include 'maxkey-connectors:maxkey-connector-dingding'
|
||||
//字节跳动飞书
|
||||
include 'maxkey-connectors:maxkey-connector-feishu'
|
||||
//华为WeLink
|
||||
include 'maxkey-connectors:maxkey-connector-welink'
|
||||
|
||||
//Protocol
|
||||
//include 'maxkey-protocols'
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user