You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dlab.apache.org by bh...@apache.org on 2019/03/19 15:20:13 UTC
[incubator-dlab] 01/01: EPMCDLAB-000 refactored ldap authentication
This is an automated email from the ASF dual-hosted git repository.
bhliva pushed a commit to branch ldab_refactored
in repository https://gitbox.apache.org/repos/asf/incubator-dlab.git
commit 9260408088fd9a46f0377055c21a329ccc78b6e7
Author: bhliva <bo...@epam.com>
AuthorDate: Tue Jan 29 17:16:13 2019 +0200
EPMCDLAB-000 refactored ldap authentication
---
.../main/java/com/epam/dlab/auth/UserInfoDAO.java | 11 +-
.../epam/dlab/auth/UserVerificationService.java | 2 +-
.../aws/service/AwsUserVerificationService.java | 16 +-
.../auth/azure/AzureAuthenticationResource.java | 10 +-
services/security-service/pom.xml | 6 +
services/security-service/security.yml | 112 +++--------
.../dlab/auth/SecurityServiceConfiguration.java | 37 +++-
.../epam/dlab/auth/core/CacheableReference.java | 53 -----
.../epam/dlab/auth/core/DlabLdapConnection.java | 2 +-
.../dlab/auth/core/DlabLdapConnectionFactory.java | 48 +++++
.../com/epam/dlab/auth/core/LdapFilterCache.java | 78 -------
.../java/com/epam/dlab/auth/core/LoginCache.java | 82 --------
.../com/epam/dlab/auth/core/LoginConveyor.java | 66 ------
.../java/com/epam/dlab/auth/core/LoginStep.java | 46 -----
.../com/epam/dlab/auth/core/UserInfoBuilder.java | 196 ------------------
.../java/com/epam/dlab/auth/dao/LdapUserDAO.java | 223 ++-------------------
.../com/epam/dlab/auth/dao/LdapUserDAOImpl.java | 164 +++++++++++++++
.../main/java/com/epam/dlab/auth/dao/Request.java | 115 ++---------
.../epam/dlab/auth/dao/SearchRequestBuilder.java | 25 ---
.../epam/dlab/auth/dao/UserInfoDAODumbImpl.java | 6 +-
.../epam/dlab/auth/dao/UserInfoDAOMongoImpl.java | 82 ++++----
.../dlab/auth/dao/filter/SearchResultMapper.java | 30 ---
.../auth/dao/filter/SearchResultProcessor.java | 67 -------
.../com/epam/dlab/auth/dao/script/DeepMap.java | 56 ------
.../epam/dlab/auth/dao/script/ScriptHolder.java | 58 ------
.../dao/script/SearchResultToDictionaryMapper.java | 97 ---------
.../auth/modules/AwsSecurityServiceModule.java | 4 +-
.../auth/modules/AzureSecurityServiceModule.java | 4 +-
.../auth/modules/GcpSecurityServiceModule.java | 4 +-
.../dlab/auth/modules/SecurityServiceModule.java | 13 +-
.../SynchronousLdapAuthenticationResource.java | 77 +++++++
.../SynchronousLdapAuthenticationService.java | 183 -----------------
.../dlab/auth/service/AuthenticationService.java | 33 +++
.../service/impl/LdapAuthenticationService.java | 82 ++++++++
.../test/java/com/epam/dlab/auth/aws/AwsTest.java | 77 -------
.../com/epam/dlab/auth/core/LoginConveyorTest.java | 130 ------------
.../dlab/auth/dao/script/ScriptHolderTest.java | 64 ------
.../java/com/epam/dlab/auth/ldap/AuthTest.java | 28 ---
.../java/com/epam/dlab/auth/ldap/BasicTest.java | 115 -----------
.../java/com/epam/dlab/auth/ldap/JsonTest.java | 83 --------
.../java/com/epam/dlab/auth/ldap/ScriptList.java | 75 -------
.../impl/LdapAuthenticationServiceTest.java | 138 +++++++++++++
42 files changed, 717 insertions(+), 2081 deletions(-)
diff --git a/services/dlab-auth-common/src/main/java/com/epam/dlab/auth/UserInfoDAO.java b/services/dlab-auth-common/src/main/java/com/epam/dlab/auth/UserInfoDAO.java
index d7c0bbb..931a050 100644
--- a/services/dlab-auth-common/src/main/java/com/epam/dlab/auth/UserInfoDAO.java
+++ b/services/dlab-auth-common/src/main/java/com/epam/dlab/auth/UserInfoDAO.java
@@ -13,17 +13,18 @@
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 com.epam.dlab.auth;
+import java.util.Optional;
+
public interface UserInfoDAO {
- UserInfo getUserInfoByAccessToken(String accessToken);
+ Optional<UserInfo> getUserInfoByAccessToken(String accessToken);
- void updateUserInfoTTL(String accessToken, UserInfo ui);
+ void updateUserInfoTTL(String accessToken, UserInfo ui);
- void deleteUserInfo(String accessToken);
+ void deleteUserInfo(String accessToken);
- void saveUserInfo(UserInfo ui);
+ void saveUserInfo(UserInfo ui);
}
diff --git a/services/dlab-auth-common/src/main/java/com/epam/dlab/auth/UserVerificationService.java b/services/dlab-auth-common/src/main/java/com/epam/dlab/auth/UserVerificationService.java
index 0c9daac..7ceccae 100644
--- a/services/dlab-auth-common/src/main/java/com/epam/dlab/auth/UserVerificationService.java
+++ b/services/dlab-auth-common/src/main/java/com/epam/dlab/auth/UserVerificationService.java
@@ -23,5 +23,5 @@ package com.epam.dlab.auth;
@FunctionalInterface
public interface UserVerificationService {
- void verify(String username, UserInfo userInfo);
+ void verify(UserInfo userInfo);
}
diff --git a/services/security-aws/src/main/java/com/epam/dlab/auth/aws/service/AwsUserVerificationService.java b/services/security-aws/src/main/java/com/epam/dlab/auth/aws/service/AwsUserVerificationService.java
index 9224755..c66f1f8 100644
--- a/services/security-aws/src/main/java/com/epam/dlab/auth/aws/service/AwsUserVerificationService.java
+++ b/services/security-aws/src/main/java/com/epam/dlab/auth/aws/service/AwsUserVerificationService.java
@@ -38,15 +38,15 @@ public class AwsUserVerificationService implements UserVerificationService {
}
@Override
- public void verify(String username, UserInfo userInfo) {
- verifyAwsUser(username, userInfo);
- verifyAwsKeys(username, userInfo);
+ public void verify(UserInfo userInfo) {
+ verifyAwsUser(userInfo);
+ verifyAwsKeys(userInfo);
}
- private User verifyAwsUser(String username, UserInfo userInfo) {
+ private User verifyAwsUser(UserInfo userInfo) {
try {
- User awsUser = awsUserDAO.getAwsUser(username);
+ User awsUser = awsUserDAO.getAwsUser(userInfo.getName());
if (awsUser != null) {
userInfo.setAwsUser(true);
return awsUser;
@@ -58,16 +58,16 @@ public class AwsUserVerificationService implements UserVerificationService {
}
}
- private List<AccessKeyMetadata> verifyAwsKeys(String username, UserInfo userInfo) {
+ private List<AccessKeyMetadata> verifyAwsKeys(UserInfo userInfo) {
userInfo.getKeys().clear();
try {
- List<AccessKeyMetadata> keys = awsUserDAO.getAwsAccessKeys(username);
+ List<AccessKeyMetadata> keys = awsUserDAO.getAwsAccessKeys(userInfo.getName());
if (keys == null || keys.isEmpty()
|| keys.stream().noneMatch(k -> "Active".equalsIgnoreCase(k.getStatus()))) {
- throw new DlabException("Cannot get aws access key for user " + username);
+ throw new DlabException("Cannot get aws access key for user " + userInfo.getName());
}
keys.forEach(e -> userInfo.addKey(e.getAccessKeyId(), e.getStatus()));
diff --git a/services/security-azure/src/main/java/com/epam/dlab/auth/azure/AzureAuthenticationResource.java b/services/security-azure/src/main/java/com/epam/dlab/auth/azure/AzureAuthenticationResource.java
index db58e07..622d432 100644
--- a/services/security-azure/src/main/java/com/epam/dlab/auth/azure/AzureAuthenticationResource.java
+++ b/services/security-azure/src/main/java/com/epam/dlab/auth/azure/AzureAuthenticationResource.java
@@ -44,6 +44,7 @@ import java.io.IOException;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
+import java.util.Optional;
/**
* Used to authenticate users against Azure Active Directory
@@ -105,16 +106,15 @@ public class AzureAuthenticationResource<C extends Configuration> extends Abstra
public UserInfo getUserInfo(String accessToken, @Context HttpServletRequest request) {
String remoteIp = request.getRemoteAddr();
- UserInfo ui = userInfoDao.getUserInfoByAccessToken(accessToken);
+ final Optional<UserInfo> ui = userInfoDao.getUserInfoByAccessToken(accessToken);
- if (ui != null) {
- ui = ui.withToken(accessToken);
- userInfoDao.updateUserInfoTTL(accessToken, ui);
+ if (ui.isPresent()) {
+ userInfoDao.updateUserInfoTTL(accessToken, ui.get().withToken(accessToken));
log.debug("restored UserInfo from DB {}", ui);
}
log.debug("Authorized {} {} {}", accessToken, ui, remoteIp);
- return ui;
+ return ui.get().withToken(accessToken);
}
/**
diff --git a/services/security-service/pom.xml b/services/security-service/pom.xml
index 468c324..e68370b 100644
--- a/services/security-service/pom.xml
+++ b/services/security-service/pom.xml
@@ -123,6 +123,12 @@ limitations under the License.
<artifactId>dlab-utils</artifactId>
<version>${project.parent.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <version>${org.mockito.version}</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
diff --git a/services/security-service/security.yml b/services/security-service/security.yml
index aa294e3..c83ca77 100644
--- a/services/security-service/security.yml
+++ b/services/security-service/security.yml
@@ -30,95 +30,29 @@ useLdapBindTemplate: true
ldapBindTemplate: uid=%s,LDAP_OU,LDAP_DN
ldapBindAttribute: uid
ldapSearchAttribute: uid
-ldapSearch:
- - name: userLookUp
- cache: true
- expirationTimeMsec: 600000
- scope: SUBTREE
- attributes:
- - cn
- - mail
- - uid
- - gidNumber
- timeLimit: 0
- base: LDAP_DN
- filter: "(&(objectClass=inetOrgPerson)(uid=%uid%))"
- - name: userInfo
- cache: true
- expirationTimeMsec: 600000
- scope: SUBTREE
- attributes:
- - cn
- - gidNumber
- timeLimit: 0
- base: LDAP_DN
- filter: "(&(objectClass=inetOrgPerson)(uid=%uid%))"
- searchResultProcessor:
- language: python
-# path: c:\tmp\enrich.py
- code: |
- def enrichUserInfo(ui,context):
- name = ui.getName()
- key = context['key'].lower()
- userInfo=context['userInfo']
- if not key in userInfo:
- raise Exception('Python LDAP UserInfo not found for '+key)
- uid= userInfo[key]
- cn = context['userInfo'][key]['cn'].split(' ')
- ui.setFirstName(cn[0])
- ui.setLastName(cn[1])
- return ui
- - name: groupInfo
- cache: true
- expirationTimeMsec: 600000
- scope: SUBTREE
- attributes:
- - cn
- - mail
- - gidNumber
- - memberUid
- timeLimit: 0
- base: LDAP_DN
- filter: "(&(objectClass=posixGroup))"
- searchResultProcessor:
- language: javascript
-# path: c:\tmp\enrich.js
- code: |
- var enrichUserInfo = function(ui,context) {
- name = ui.getName();
- key = context['key'].toLowerCase();
- userInfo=context['userInfo'];
- if( userInfo[key] == undefined ) {
- throw 'JavaScript LDAP UserInfo not found for '+key;
- }
- uid= userInfo[key];
- userGid = uid['gidnumber'];
- groupInfo=context['groupInfo'];
- for( dn in groupInfo ) {
- group = groupInfo[dn];
- if( userGid == group['gidnumber']) {
- ui.addRole(group['cn']);
- } else {
- grMembers = group['memberuid'];
- if (grMembers != undefined) {
- index = grMembers.split(",");
- members = new Array();
- for(i in index) {
- members[i] = grMembers.split(",")[i];
- }
- for (member in members) {
- if (members[member] != undefined) {
- if (members[member].toLowerCase() == name.toLowerCase()) {
- ui.addRole(group['cn']);
- }
- }
- }
- }
- }
- }
- return ui;
- }
-
+ldapGroupAttribute: memberUid
+ldapGroupNameAttribute: cn
+ldapGroupUserAttribute: uid
+ldapSearchRequest:
+ expirationTimeMsec: 600000
+ scope: SUBTREE
+ attributes:
+ - cn
+ - mail
+ - uid
+ - gidNumber
+ timeLimit: 0
+ base: LDAP_DN
+ filter: "(&(objectClass=inetOrgPerson)(uid=$LDAP_SEARCH_ATTRIBUTE))"
+ldapGroupSearchRequest:
+ expirationTimeMsec: 600000
+ scope: SUBTREE
+ attributes:
+ - cn
+ - memberUid
+ timeLimit: 0
+ base: LDAP_DN
+ filter: "(&(objectClass=posixGroup))"
server:
requestLog:
appenders:
diff --git a/services/security-service/src/main/java/com/epam/dlab/auth/SecurityServiceConfiguration.java b/services/security-service/src/main/java/com/epam/dlab/auth/SecurityServiceConfiguration.java
index 5593978..3ec3f69 100644
--- a/services/security-service/src/main/java/com/epam/dlab/auth/SecurityServiceConfiguration.java
+++ b/services/security-service/src/main/java/com/epam/dlab/auth/SecurityServiceConfiguration.java
@@ -26,7 +26,6 @@ import org.apache.directory.ldap.client.api.LdapConnectionConfig;
import javax.validation.constraints.Min;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
public class SecurityServiceConfiguration extends ServiceConfiguration {
@@ -40,8 +39,6 @@ public class SecurityServiceConfiguration extends ServiceConfiguration {
@Min(5)
private int loginAuthenticationTimeout = 10;
@JsonProperty
- private List<Request> ldapSearch;
- @JsonProperty
private String ldapBindTemplate;
@JsonProperty
private String ldapBindAttribute;
@@ -58,16 +55,38 @@ public class SecurityServiceConfiguration extends ServiceConfiguration {
private LdapConnectionConfig ldapConfiguration;
+ private String ldapGroupAttribute;
+ private String ldapGroupNameAttribute;
+ private String ldapGroupUserAttribute;
+
+ @JsonProperty
+ private Request ldapSearchRequest;
+
+ @JsonProperty
+ private Request ldapGroupSearchRequest;
+
public SecurityServiceConfiguration() {
super();
}
- public boolean isUserInfoPersistenceEnabled() {
- return userInfoPersistenceEnabled;
+ public String getLdapGroupUserAttribute() {
+ return ldapGroupUserAttribute;
+ }
+
+ public String getLdapGroupAttribute() {
+ return ldapGroupAttribute;
+ }
+
+ public String getLdapGroupNameAttribute() {
+ return ldapGroupNameAttribute;
}
- public List<Request> getLdapSearch() {
- return ldapSearch;
+ public Request getLdapGroupSearchRequest() {
+ return ldapGroupSearchRequest;
+ }
+
+ public boolean isUserInfoPersistenceEnabled() {
+ return userInfoPersistenceEnabled;
}
public LdapConnectionConfig getLdapConnectionConfig() {
@@ -117,4 +136,8 @@ public class SecurityServiceConfiguration extends ServiceConfiguration {
public GcpLoginConfiguration getGcpLoginConfiguration() {
return gcpLoginConfiguration;
}
+
+ public Request getLdapSearchRequest() {
+ return ldapSearchRequest;
+ }
}
diff --git a/services/security-service/src/main/java/com/epam/dlab/auth/core/CacheableReference.java b/services/security-service/src/main/java/com/epam/dlab/auth/core/CacheableReference.java
deleted file mode 100644
index 60ff0d3..0000000
--- a/services/security-service/src/main/java/com/epam/dlab/auth/core/CacheableReference.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2016, EPAM SYSTEMS INC
- *
- * 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 com.epam.dlab.auth.core;
-
-import com.aegisql.conveyor.BuilderSupplier;
-
-import java.util.function.Supplier;
-
-public class CacheableReference<T> implements Supplier<T> {
-
- /** The reference. */
- private final T reference;
-
- /**
- * Instantiates a new immutable reference.
- *
- * @param ref the ref
- */
- private CacheableReference(T ref) {
- this.reference = ref;
- }
-
- /* (non-Javadoc)
- * @see java.util.function.Supplier#get()
- */
- @Override
- public T get() {
- return reference;
- }
-
- public static <T> BuilderSupplier<T> newInstance(T ref) {
- return () -> new CacheableReference<>(ref);
- }
-
- @Override
- public String toString() {
- return ""+reference;
- }
-}
diff --git a/services/security-service/src/main/java/com/epam/dlab/auth/core/DlabLdapConnection.java b/services/security-service/src/main/java/com/epam/dlab/auth/core/DlabLdapConnection.java
index 51ee800..0ca2f97 100644
--- a/services/security-service/src/main/java/com/epam/dlab/auth/core/DlabLdapConnection.java
+++ b/services/security-service/src/main/java/com/epam/dlab/auth/core/DlabLdapConnection.java
@@ -27,7 +27,7 @@ public abstract class DlabLdapConnection implements Closeable {
abstract LdapConnection getConnection() throws Exception;
- public LdapConnection connect() throws Exception {
+ public LdapConnection getBoundConnection() throws Exception {
final LdapConnection connection = getConnection();
if (!connection.connect()) {
log.error("Cannot establish a connection to LDAP server");
diff --git a/services/security-service/src/main/java/com/epam/dlab/auth/core/DlabLdapConnectionFactory.java b/services/security-service/src/main/java/com/epam/dlab/auth/core/DlabLdapConnectionFactory.java
new file mode 100644
index 0000000..0a76b53
--- /dev/null
+++ b/services/security-service/src/main/java/com/epam/dlab/auth/core/DlabLdapConnectionFactory.java
@@ -0,0 +1,48 @@
+/*
+ *
+ * * Copyright (c) 2018, EPAM SYSTEMS INC
+ * *
+ * * 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 com.epam.dlab.auth.core;
+
+import com.epam.dlab.auth.SecurityServiceConfiguration;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import org.apache.directory.ldap.client.api.LdapConnectionConfig;
+import org.apache.directory.ldap.client.api.LdapConnectionPool;
+import org.apache.directory.ldap.client.api.LdapNetworkConnection;
+import org.apache.directory.ldap.client.api.ValidatingPoolableLdapConnectionFactory;
+
+@Singleton
+public class DlabLdapConnectionFactory {
+
+
+ private final LdapConnectionConfig connConfig;
+ private final LdapConnectionPool connectionPool;
+ private final boolean usePool;
+
+ @Inject
+ public DlabLdapConnectionFactory(SecurityServiceConfiguration configuration) {
+ this.connConfig = configuration.getLdapConnectionConfig();
+ this.connectionPool = new LdapConnectionPool(new ValidatingPoolableLdapConnectionFactory(connConfig));
+ this.usePool = configuration.isLdapUseConnectionPool();
+ }
+
+ public DlabLdapConnection newConnection() {
+ return usePool ? new ReturnableConnection(connectionPool) :
+ new SimpleConnection(new LdapNetworkConnection(connConfig));
+ }
+}
diff --git a/services/security-service/src/main/java/com/epam/dlab/auth/core/LdapFilterCache.java b/services/security-service/src/main/java/com/epam/dlab/auth/core/LdapFilterCache.java
deleted file mode 100644
index 7a37dcc..0000000
--- a/services/security-service/src/main/java/com/epam/dlab/auth/core/LdapFilterCache.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/***************************************************************************
-
- Copyright (c) 2016, EPAM SYSTEMS INC
-
- 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 com.epam.dlab.auth.core;
-
-import com.aegisql.conveyor.cart.command.CancelCommand;
-import com.aegisql.conveyor.utils.caching.CachingConveyor;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.Map;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Supplier;
-
-public class LdapFilterCache extends CachingConveyor<String,String,Map<String,Object>> {
-
- private final static Logger LOG = LoggerFactory.getLogger(LdapFilterCache.class);
-
- private final static LdapFilterCache INSTANCE = new LdapFilterCache();
-
- public static LdapFilterCache getInstance() {
- return INSTANCE;
- }
-
- private LdapFilterCache() {
- super();
- this.setName("LdapFilterCache");
- this.setIdleHeartBeat(1, TimeUnit.SECONDS);
- this.setDefaultCartConsumer((b,l,s)-> LOG.debug("LdapFilterCache consume {} {}",l,s.get()));
- this.setOnTimeoutAction((s)->{
- LOG.trace("LdapFilterCache Timeout {}",s.get());
- });
- this.setScrapConsumer(bin->{
- LOG.debug("LdapFilterCache {}: {}", bin.failureType, bin.scrap);
- });
- }
-
- public void removeLdapFilterInfo(String token) {
- this.addCommand(new CancelCommand<>(token));
- }
-
- public Map<String,Object> getLdapFilterInfo(String token) {
- Supplier<? extends Map<String,Object>> s = this.getProductSupplier(token);
- if( s == null ) {
- return null;
- } else {
- return s.get();
- }
- }
-
- public void save(String token, Map<String,Object> ldapInfo,long expTimeMsec) {
- CompletableFuture<Boolean> cacheFuture = LdapFilterCache.getInstance().createBuild(token, CacheableReference.newInstance(ldapInfo),expTimeMsec,TimeUnit.MILLISECONDS);
- try {
- if(! cacheFuture.get() ) {
- throw new Exception("Cache offer future returned 'false' for "+ldapInfo);
- }
- } catch (Exception e) {
- throw new RuntimeException("Cache offer failed for "+ldapInfo,e);
- }
- }
-
-}
diff --git a/services/security-service/src/main/java/com/epam/dlab/auth/core/LoginCache.java b/services/security-service/src/main/java/com/epam/dlab/auth/core/LoginCache.java
deleted file mode 100644
index 4c48172..0000000
--- a/services/security-service/src/main/java/com/epam/dlab/auth/core/LoginCache.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/***************************************************************************
-
- Copyright (c) 2016, EPAM SYSTEMS INC
-
- 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 com.epam.dlab.auth.core;
-
-import com.aegisql.conveyor.cart.command.CancelCommand;
-import com.aegisql.conveyor.utils.caching.CachingConveyor;
-import com.epam.dlab.auth.UserInfo;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Supplier;
-
-public class LoginCache extends CachingConveyor<String,String,UserInfo> {
-
- private final static Logger LOG = LoggerFactory.getLogger(LoginCache.class);
-
- private final static LoginCache INSTANCE = new LoginCache();
-
- public static LoginCache getInstance() {
- return INSTANCE;
- }
-
- private LoginCache() {
- super();
- this.setName("UserInfoCache");
- this.setIdleHeartBeat(1, TimeUnit.SECONDS);
- this.setDefaultBuilderTimeout(60, TimeUnit.MINUTES);
- this.enablePostponeExpirationOnTimeout(false);
- this.enablePostponeExpiration(true);
- this.setExpirationPostponeTime(60,TimeUnit.MINUTES);
- this.setDefaultCartConsumer((b,l,s)-> LOG.debug("UserInfoCache consume {} {}",l,s.get()));
- this.setOnTimeoutAction((s)->{
- LOG.trace("UserInfoCache Timeout {}",s.get());
- });
- this.setScrapConsumer(bin->{
- LOG.debug("UserInfoCache {}: {}", bin.failureType, bin.scrap);
- });
- }
-
- public void removeUserInfo(String token) {
- this.addCommand(new CancelCommand<>(token));
- }
-
- public UserInfo getUserInfo(String token) {
- Supplier<? extends UserInfo> s = this.getProductSupplier(token);
- if( s == null ) {
- return null;
- } else {
- return s.get();
- }
- }
-
- public void save(UserInfo userInfo) {
- CompletableFuture<Boolean> cacheFuture = LoginCache.getInstance().createBuild(userInfo.getAccessToken(), CacheableReference.newInstance(userInfo));
- try {
- if(! cacheFuture.get() ) {
- throw new Exception("Offer future returned 'false' for "+userInfo);
- }
- } catch (Exception e) {
- throw new RuntimeException("User Info cache offer failure for "+userInfo,e);
- }
- }
-
-}
diff --git a/services/security-service/src/main/java/com/epam/dlab/auth/core/LoginConveyor.java b/services/security-service/src/main/java/com/epam/dlab/auth/core/LoginConveyor.java
deleted file mode 100644
index 9c903ff..0000000
--- a/services/security-service/src/main/java/com/epam/dlab/auth/core/LoginConveyor.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/***************************************************************************
-
- Copyright (c) 2016, EPAM SYSTEMS INC
-
- 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 com.epam.dlab.auth.core;
-
-import com.aegisql.conveyor.utils.parallel.KBalancedParallelConveyor;
-import com.epam.dlab.auth.UserInfo;
-import com.epam.dlab.auth.UserInfoDAO;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.TimeUnit;
-
-public class LoginConveyor extends KBalancedParallelConveyor<String,LoginStep,UserInfo>{
-
- private final static Logger LOG = LoggerFactory.getLogger(LoginConveyor.class);
-
- private UserInfoDAO userInfoDao;
-
- public LoginConveyor(long builderTimeout) {
- super(4);
- this.setName("LoginConveyor");
- this.setIdleHeartBeat(1, TimeUnit.SECONDS);
- this.setDefaultBuilderTimeout(builderTimeout, TimeUnit.SECONDS);
- this.setResultConsumer(res->{
- LOG.debug("UserInfo Build Success: {}",res);
- LoginCache.getInstance().save(res.product);
- if(userInfoDao != null) {
- userInfoDao.saveUserInfo(res.product);
- } else {
- LOG.warn("UserInfo Build not saved: {}",res);
- }
- });
- this.setScrapConsumer(bin-> LOG.error("UserInfo Build Failed: {}",bin));
- }
-
- public void setUserInfoDao(UserInfoDAO userInfoDao) {
- this.userInfoDao = userInfoDao;
- }
-
- public CompletableFuture<UserInfo> startUserInfoBuild(String token, String username) {
- LOG.debug("startUserInfoBuild {} {} {}",token,username);
- return this.createBuildFuture(token,UserInfoBuilder.supplier(token,username));
- }
-
- public void cancel(String token, LoginStep step, String errorMessage) {
- LOG.debug("Canceling {}: {}",token,errorMessage);
- this.add(token,new RuntimeException(errorMessage),step);
- }
-}
diff --git a/services/security-service/src/main/java/com/epam/dlab/auth/core/LoginStep.java b/services/security-service/src/main/java/com/epam/dlab/auth/core/LoginStep.java
deleted file mode 100644
index 2f6e4fe..0000000
--- a/services/security-service/src/main/java/com/epam/dlab/auth/core/LoginStep.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/***************************************************************************
-
- Copyright (c) 2016, EPAM SYSTEMS INC
-
- 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 com.epam.dlab.auth.core;
-
-import com.aegisql.conveyor.SmartLabel;
-
-import java.util.function.BiConsumer;
-
-public enum LoginStep implements SmartLabel<UserInfoBuilder> {
- LDAP_LOGIN(UserInfoBuilder::ldapLoginPassed),
- LDAP_USER_INFO(UserInfoBuilder::ldapUserInfo),
- AWS_USER(UserInfoBuilder::awsUser),
- AWS_KEYS(UserInfoBuilder::awsKeys),
- AWS_KEYS_EMPTY(UserInfoBuilder::awsKeysEmpty),
- REMOTE_IP(UserInfoBuilder::remoteIp),
- LDAP_USER_INFO_ERROR(UserInfoBuilder::ldapUserInfoError),
- LDAP_GROUP_INFO_ERROR(UserInfoBuilder::ldapGroupInfoError),
- AWS_USER_ERROR(UserInfoBuilder::awsUserError),
- AWS_KEYS_ERROR(UserInfoBuilder::awsKeysError),
- ;
- BiConsumer<UserInfoBuilder, Object> setter;
- @SuppressWarnings("unchecked")
- <T extends Object> LoginStep (BiConsumer<UserInfoBuilder,T> setter) {
- this.setter = (BiConsumer<UserInfoBuilder, Object>) setter;
- }
- @Override
- public BiConsumer<UserInfoBuilder, Object> get() {
- return setter;
- }
-}
diff --git a/services/security-service/src/main/java/com/epam/dlab/auth/core/UserInfoBuilder.java b/services/security-service/src/main/java/com/epam/dlab/auth/core/UserInfoBuilder.java
deleted file mode 100644
index 8e7b75e..0000000
--- a/services/security-service/src/main/java/com/epam/dlab/auth/core/UserInfoBuilder.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/***************************************************************************
-
- Copyright (c) 2016, EPAM SYSTEMS INC
-
- 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 com.epam.dlab.auth.core;
-
-import com.aegisql.conveyor.BuilderSupplier;
-import com.aegisql.conveyor.Testing;
-import com.amazonaws.services.identitymanagement.model.AccessKeyMetadata;
-import com.epam.dlab.auth.UserInfo;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.concurrent.atomic.LongAdder;
-import java.util.function.Supplier;
-
-public class UserInfoBuilder implements Supplier<UserInfo>, Testing {
-
- private final static Logger LOG = LoggerFactory.getLogger(UserInfoBuilder.class);
-
- private UserInfo userInfo;
-
- private RuntimeException ldapError = null;
- private RuntimeException ldapGroupError = null;
- private RuntimeException awsUserError = null;
- private RuntimeException awsKeyError = null;
-
-
- private int readinessStatus = 0b00000000;
-
- public final static int FIRST_NAME = 0b0000001;
- public final static int LAST_NAME = 0b0000010;
- public final static int AWS_USER_SET = 0b0000100;
- public final static int ROLE_SET = 0b0001000;
- public final static int REMOTE_IP = 0b0010000;
- public final static int AWS_KEYS = 0b0100000;
- public final static int LOGIN = 0b1000000;
-
- public final static int READYNESS_MASK = 0b1111111;
-
- public static boolean testMask(Supplier<? extends UserInfo> supplier, int mask) {
- UserInfoBuilder builder = (UserInfoBuilder) supplier;
- LOG.debug("testing {} vs {} = {}",builder.readinessStatus,mask,(builder.readinessStatus & mask) == mask);
- return (builder.readinessStatus & mask) == mask;
- }
-
- public void setMask(int mask) {
- this.readinessStatus |= mask;
- }
-
- public static BuilderSupplier<UserInfo> supplier(final String token, final String username ) {
- LOG.debug("supplier requested {} {}",token, username);
- return () -> new UserInfoBuilder(token,username);
- }
-
- public static void ldapLoginPassed(UserInfoBuilder b, Object t) {
- b.setMask( LOGIN );
- }
-
- public static void firstName(UserInfoBuilder b, String firstName) {
- LOG.debug("firstName {}",firstName);
-
- b.userInfo.setFirstName(firstName);
- b.setMask( FIRST_NAME );
- }
-
- public static void lastName(UserInfoBuilder b, String lastName) {
- LOG.debug("lastName {}",lastName);
-
- b.userInfo.setLastName(lastName);
- b.setMask( LAST_NAME );
- }
-
- public static void remoteIp(UserInfoBuilder b, String remoteIp) {
- LOG.debug("remoteIp {}",remoteIp);
-
- b.userInfo.setRemoteIp(remoteIp);
- b.setMask( REMOTE_IP );
- }
-
- public static void awsUser(UserInfoBuilder b, Boolean awsUser) {
- LOG.debug("awsUser {}",awsUser);
-
- b.userInfo.setAwsUser(awsUser);
- b.setMask( AWS_USER_SET );
- }
-
- public static void roles(UserInfoBuilder b, Collection<String> roles) {
- LOG.debug("roles {}",roles);
- roles.forEach( role -> b.userInfo.addRole(role) );
- b.setMask( ROLE_SET );
- }
-
- public static void ldapUserInfo(UserInfoBuilder b, UserInfo ui) {
- LOG.debug("merge user info{}",ui);
- UserInfoBuilder.firstName(b,ui.getFirstName());
- UserInfoBuilder.lastName(b,ui.getLastName());
- UserInfoBuilder.roles(b,ui.getRoles());
- }
-
- public UserInfoBuilder(String token, String username) {
- this.userInfo = new UserInfo(username, token);
- }
-
- public UserInfoBuilder() {
-
- }
-
- @Override
- public UserInfo get() {
- if( ldapError != null ) throw ldapError;
- if( ldapGroupError != null ) throw ldapGroupError;
- if( awsUserError != null ) throw awsUserError;
- if( awsKeyError != null ) throw awsKeyError;
- return userInfo;
- }
-
- @Override
- public String toString() {
- return "UserInfoBuilder{" +
- "userInfo=" + userInfo +
- ", readinessStatus=" + readinessStatus +
- '}';
- }
-
- @Override
- public boolean test() {
- return UserInfoBuilder.testMask(this,UserInfoBuilder.READYNESS_MASK);
- }
-
- public static void awsKeys(UserInfoBuilder b, List<AccessKeyMetadata> keyMetadata) {
- LOG.debug("AWS Keys {}",keyMetadata);
- LongAdder counter = new LongAdder();
- if(keyMetadata != null) {
- keyMetadata.forEach(k -> {
- String key = k.getAccessKeyId();
- String status = k.getStatus();
- if ("Active".equalsIgnoreCase(status)) {
- counter.increment();
- }
- b.userInfo.addKey(key, status);
- });
- }
-
- if( counter.intValue() == 0 ) {
- b.awsKeyError = new RuntimeException("Please contact AWS administrator to activate your Access Key");
- }
- b.setMask( AWS_KEYS );
- }
-
- public static void awsKeysEmpty(UserInfoBuilder b, List<AccessKeyMetadata> keyMetadata) {
- LOG.debug("AWS Keys {}",keyMetadata);
- b.setMask( AWS_KEYS );
- }
-
- public static void ldapUserInfoError(UserInfoBuilder b, RuntimeException t) {
- LOG.error("ldapUserInfoError {}", t.getMessage());
- b.ldapError = t;
- b.setMask( LOGIN );
- }
-
- public static void ldapGroupInfoError(UserInfoBuilder b, RuntimeException t) {
- LOG.error("ldapGroupInfoError {}", t.getMessage());
- b.ldapGroupError = t;
- b.setMask( FIRST_NAME | LAST_NAME | ROLE_SET );
- }
-
- public static void awsUserError(UserInfoBuilder b, RuntimeException t) {
- LOG.error("awsUserError {}", t.getMessage());
- b.awsUserError = t;
- b.setMask( AWS_USER_SET );
- }
-
- public static void awsKeysError(UserInfoBuilder b, RuntimeException t) {
- LOG.error("awsKeysError {}", t.getMessage());
- b.awsKeyError = t;
- b.setMask( AWS_KEYS );
- }
-
-}
diff --git a/services/security-service/src/main/java/com/epam/dlab/auth/dao/LdapUserDAO.java b/services/security-service/src/main/java/com/epam/dlab/auth/dao/LdapUserDAO.java
index 0b9fa65..9bf1cdd 100644
--- a/services/security-service/src/main/java/com/epam/dlab/auth/dao/LdapUserDAO.java
+++ b/services/security-service/src/main/java/com/epam/dlab/auth/dao/LdapUserDAO.java
@@ -1,210 +1,29 @@
-/***************************************************************************
-
- Copyright (c) 2016, EPAM SYSTEMS INC
-
- 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.
-
- ****************************************************************************/
+/*
+ *
+ * * Copyright (c) 2018, EPAM SYSTEMS INC
+ * *
+ * * 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 com.epam.dlab.auth.dao;
-import com.epam.dlab.auth.SecurityServiceConfiguration;
import com.epam.dlab.auth.UserInfo;
-import com.epam.dlab.auth.core.DlabLdapConnection;
-import com.epam.dlab.auth.core.LdapFilterCache;
-import com.epam.dlab.auth.core.ReturnableConnection;
-import com.epam.dlab.auth.core.SimpleConnection;
-import com.epam.dlab.auth.dao.filter.SearchResultProcessor;
-import com.epam.dlab.auth.dao.script.ScriptHolder;
-import com.epam.dlab.auth.dao.script.SearchResultToDictionaryMapper;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.pool.PoolableObjectFactory;
-import org.apache.directory.api.ldap.model.cursor.SearchCursor;
-import org.apache.directory.api.ldap.model.exception.LdapException;
-import org.apache.directory.api.ldap.model.message.SearchRequest;
-import org.apache.directory.ldap.client.api.*;
-
-import java.io.IOException;
-import java.util.*;
-import java.util.regex.Pattern;
-
-@Slf4j
-public class LdapUserDAO {
-
- // the request from security.yml for user look up by one of the parameters (mail or phone).
- // configured in the same request configuration under "filter" key: "(&(objectClass=inetOrgPerson)(mail=%mail%))"
- private static final String USER_LOOK_UP = "userLookUp";
- private static final String DISTINGUISH_NAME = "dn";
- private final LdapConnectionConfig connConfig;
- private final List<Request> requests;
- private final String bindTemplate;
- private final String ldapBindAttribute;
- private final String ldapSearchAttribute;
- private final LdapConnectionPool usersPool;
- private final LdapConnectionPool searchPool;
- private final ScriptHolder script = new ScriptHolder();
- private final boolean useBindTemplate;
- private boolean useCache;
- private boolean ldapUseConnectionPool;
-
- public LdapUserDAO(SecurityServiceConfiguration config, boolean useCache) {
- this.connConfig = config.getLdapConnectionConfig();
- this.requests = config.getLdapSearch();
- this.useBindTemplate = config.isUseLdapBindTemplate();
- this.bindTemplate = config.getLdapBindTemplate();
- this.ldapBindAttribute = config.getLdapBindAttribute();
- this.ldapSearchAttribute = "%" + config.getLdapSearchAttribute() + "%";
- PoolableObjectFactory<LdapConnection> userPoolFactory = new ValidatingPoolableLdapConnectionFactory
- (connConfig);
- this.usersPool = new LdapConnectionPool(userPoolFactory);
- PoolableObjectFactory<LdapConnection> searchPoolFactory = new ValidatingPoolableLdapConnectionFactory
- (connConfig);
- this.searchPool = new LdapConnectionPool(searchPoolFactory);
- this.useCache = useCache;
- this.ldapUseConnectionPool = config.isLdapUseConnectionPool();
- }
-
- private DlabLdapConnection getConnection(LdapConnectionPool connectionPool) {
- return ldapUseConnectionPool ? new ReturnableConnection(connectionPool) :
- new SimpleConnection(new LdapNetworkConnection(connConfig));
- }
-
- public UserInfo getUserInfo(String username, String password) throws Exception {
- Map<String, Object> userAttributes;
-
- try (DlabLdapConnection connection = getConnection(usersPool)) {
- final LdapConnection ldapConnection = connection.connect();
- userAttributes = searchUsersAttributes(username, ldapConnection);
- String bindAttribute = userAttributes.get(ldapBindAttribute).toString();
- bindUser(username, password, bindAttribute, ldapConnection, (String) userAttributes.get(DISTINGUISH_NAME));
-
- UserInfo userInfo = new UserInfo(username, "******");
- userAttributes.entrySet().forEach(entry -> addAttribute(userInfo, entry));
-
- return userInfo;
- } catch (Exception e) {
- log.error("LDAP getUserInfo authentication error for username '{}': {}", username, e.getMessage(), e);
- throw e;
- }
- }
-
- private void bindUser(String username, String password, String cn, LdapConnection userCon, String dn) throws
- LdapException {
- userCon.bind(getBind(cn, dn), password);
- userCon.unBind();
- log.debug("User '{}' identified.", username);
- }
-
- private String getBind(String cn, String dn) {
- String bind;
- if (useBindTemplate) {
- log.info("Biding with template : {} and username/cn: {}", bindTemplate, cn);
- bind = String.format(bindTemplate, cn);
- } else {
- log.info("Biding using dn : {}", dn);
- bind = dn;
- }
- return bind;
- }
-
- private Map<String, Object> searchUsersAttributes(final String username, LdapConnection userCon) throws
- IOException, LdapException {
- Map<String, Object> contextMap;
- Map<String, Object> userAttributes = new HashMap<>();
- for (Request request : requests) {
- if (request.getName().equalsIgnoreCase(USER_LOOK_UP)) {
- log.info("Request: {}", request.getName());
- log.info("Putting user param {} : {}", ldapSearchAttribute, username);
- SearchRequest sr = request.buildSearchRequest(Collections.
- singletonMap(Pattern.quote(ldapSearchAttribute), username));
- String filter = sr.getFilter().toString();
- contextMap = (useCache) ? LdapFilterCache.getInstance().getLdapFilterInfo(filter) : null;
- SearchResultToDictionaryMapper mapper = new SearchResultToDictionaryMapper(request.getName(),
- new HashMap<>());
- log.debug("Retrieving new branch {} for {}", request.getName(), filter);
- try (SearchCursor cursor = userCon.search(sr)) {
- contextMap = mapper.transformSearchResult(cursor);
- Iterator<Object> iterator = contextMap.values().iterator();
- if (iterator.hasNext()) {
- @SuppressWarnings("unchecked")
- Map<String, Object> ua = (Map<String, Object>) iterator.next();
- log.info("User atttr {} ", ua);
- userAttributes = ua;
- }
- }
- }
- }
- log.info("User context is: {}", userAttributes);
- return userAttributes;
- }
-
- public UserInfo enrichUserInfo(final UserInfo userInfo) throws Exception {
- log.debug("Enriching user info for user: {}", userInfo);
- String username = userInfo.getName();
- UserInfo ui = userInfo.withToken("******");
- try (DlabLdapConnection connection = getConnection(searchPool)) {
- final LdapConnection ldapConnection = connection.connect();
- Map<String, Object> conextTree = new HashMap<>();
- for (Request req : requests) {
- if (req.getName().equalsIgnoreCase(USER_LOOK_UP)) {
- addUserAttributes(username, ui, ldapConnection);
- }
- log.info("Request: {}", req.getName());
- SearchResultProcessor proc = req.getSearchResultProcessor();
- log.info("Putting user param {} : {} for user enriching", ldapSearchAttribute, username);
- SearchRequest sr = req.buildSearchRequest(Collections
- .singletonMap(Pattern.quote(ldapSearchAttribute), username));
- String filter = sr.getFilter().toString();
- Map<String, Object> contextMap = (useCache) ? LdapFilterCache.getInstance().getLdapFilterInfo(filter)
- : null;
- SearchResultToDictionaryMapper mapper = new SearchResultToDictionaryMapper(req.getName(),
- conextTree);
- if (contextMap == null) {
- log.debug("Retrieving new branch {} for {}", req.getName(), filter);
- try (SearchCursor cursor = ldapConnection.search(sr)) {
- contextMap = mapper.transformSearchResult(cursor);
- }
- if (req.isCache() && useCache) {
- LdapFilterCache.getInstance().save(filter, contextMap, req.getExpirationTimeMsec());
- }
- } else {
- log.debug("Restoring old branch {} for {}: {}", req.getName(), filter, contextMap);
- mapper.getBranch().putAll(contextMap);
- }
- if (proc != null) {
- log.debug("Executing: {}", proc.getLanguage());
- conextTree.put("key", ui.getKeys().get("dn"));
- ui = script.evalOnce(req.getName(), proc.getLanguage(), proc.getCode()).apply(ui, conextTree);
- }
- }
- } catch (Exception e) {
- log.error("LDAP enrichUserInfo authentication error for username '{}': {}", username, e.getMessage(), e);
- throw e;
- }
- return ui;
- }
+import java.util.Set;
- private void addUserAttributes(String username, UserInfo ui, LdapConnection ldapConnection) throws IOException,
- LdapException {
- Map<String, Object> usersAttributes = searchUsersAttributes(username, ldapConnection);
- usersAttributes.entrySet().stream().filter(e -> Objects.nonNull(e.getValue()))
- .forEach(attribute -> addAttribute(ui, attribute));
- }
+public interface LdapUserDAO {
+ UserInfo getUserInfo(String username, String password);
- private void addAttribute(UserInfo ui, Map.Entry<String, Object> attribute) {
- ui.addKey(attribute.getKey().toLowerCase(), attribute.getValue().toString());
- log.debug("Adding attribute {} : {}", attribute.getKey().toLowerCase(), attribute.getValue
- ().toString());
- }
+ Set<String> getUserGroups(UserInfo userInfo);
}
diff --git a/services/security-service/src/main/java/com/epam/dlab/auth/dao/LdapUserDAOImpl.java b/services/security-service/src/main/java/com/epam/dlab/auth/dao/LdapUserDAOImpl.java
new file mode 100644
index 0000000..7c62e64
--- /dev/null
+++ b/services/security-service/src/main/java/com/epam/dlab/auth/dao/LdapUserDAOImpl.java
@@ -0,0 +1,164 @@
+/*
+ *
+ * * Copyright (c) 2018, EPAM SYSTEMS INC
+ * *
+ * * 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 com.epam.dlab.auth.dao;
+
+import com.epam.dlab.auth.SecurityServiceConfiguration;
+import com.epam.dlab.auth.UserInfo;
+import com.epam.dlab.auth.core.DlabLdapConnection;
+import com.epam.dlab.auth.core.DlabLdapConnectionFactory;
+import com.epam.dlab.exceptions.DlabException;
+import com.google.inject.Inject;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.directory.api.ldap.model.cursor.SearchCursor;
+import org.apache.directory.api.ldap.model.entry.Attribute;
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.api.ldap.model.message.SearchRequestImpl;
+import org.apache.directory.api.ldap.model.message.SearchResultEntry;
+import org.apache.directory.api.ldap.model.message.SearchScope;
+import org.apache.directory.api.ldap.model.name.Dn;
+import org.apache.directory.ldap.client.api.LdapConnection;
+
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
+@Slf4j
+public class LdapUserDAOImpl implements LdapUserDAO {
+ private static final String LDAP_SEARCH_ATTRIBUTE = "$LDAP_SEARCH_ATTRIBUTE";
+ private static final String COMMON_NAME_ATTRIBUTE = "cn";
+ private final DlabLdapConnectionFactory connectionFactory;
+ private final SecurityServiceConfiguration configuration;
+
+ @Inject
+ public LdapUserDAOImpl(DlabLdapConnectionFactory connectionFactory, SecurityServiceConfiguration configuration) {
+ this.connectionFactory = connectionFactory;
+ this.configuration = configuration;
+ }
+
+ @Override
+ public UserInfo getUserInfo(String username, String password) {
+
+ try (DlabLdapConnection connection = connectionFactory.newConnection()) {
+ return getUserInfo(username, password, connection.getBoundConnection());
+ } catch (Exception e) {
+ log.error("Can not get user info for user {} due to: {}", username, e.getMessage());
+ throw new DlabException("Can not get user info due to: " + e.getMessage(), e);
+ }
+ }
+
+ @Override
+ public Set<String> getUserGroups(UserInfo userInfo) {
+ final String groupUserAttribute = userInfo.getKeys().get(configuration.getLdapGroupUserAttribute());
+ try (DlabLdapConnection connection = connectionFactory.newConnection()) {
+ final LdapConnection ldapConnection = connection.getBoundConnection();
+ try (SearchCursor result = ldapConnection.search(getGroupSearchRequest())) {
+ return StreamSupport.stream(result.spliterator(), false)
+ .filter(r -> r instanceof SearchResultEntry)
+ .map(r -> ((SearchResultEntry) r).getEntry())
+ .flatMap(e -> groupStream(groupUserAttribute, e)).collect(Collectors.toSet());
+ }
+ } catch (Exception e) {
+ log.error("Can not get user groups for user {} due to: {}", userInfo.getName(), e.getMessage());
+ throw new DlabException("Can not get user groups due to: " + e.getMessage());
+ }
+ }
+
+ private Stream<? extends String> groupStream(String groupUserAttribute, Entry e) {
+ final Attribute groupAttribute = e.get(configuration.getLdapGroupAttribute());
+ return StreamSupport.stream(groupAttribute.spliterator(), false)
+ .anyMatch(v -> v.toString().equals(groupUserAttribute)) ?
+ Stream.of(e.get(configuration.getLdapGroupNameAttribute()).get().toString()) :
+ Stream.empty();
+ }
+
+ private UserInfo getUserInfo(String username, String password, LdapConnection ldapConnection) throws Exception {
+ try (SearchCursor result = ldapConnection.search(getUserSearchRequest(username))) {
+ return StreamSupport.stream(result.spliterator(), false)
+ .filter(r -> r instanceof SearchResultEntry)
+ .map(r -> ((SearchResultEntry) r).getEntry())
+ .map(e -> toUserInfo(e, username))
+ .peek(u -> bind(ldapConnection, u, password))
+ .findAny()
+ .orElseThrow(() -> new DlabException("User " + username + " not found"));
+ }
+ }
+
+ private void bind(LdapConnection ldapConnection, UserInfo u, String password) {
+ if (configuration.isUseLdapBindTemplate()) {
+ final String bindTemplate = configuration.getLdapBindTemplate();
+ final String ldapBindAttrName = configuration.getLdapBindAttribute();
+ final String bindAttrValue = Optional.ofNullable(u.getKeys().get(ldapBindAttrName))
+ .orElseThrow(() -> new DlabException("Bind attribute " + ldapBindAttrName + " is not found"));
+ log.info("Biding with template: {} and attribute {} with value: {}", bindTemplate, ldapBindAttrName,
+ bindAttrValue);
+ try {
+ ldapConnection.bind(String.format(bindTemplate, bindAttrValue), password);
+ ldapConnection.unBind();
+ } catch (LdapException e) {
+ log.error("Can not bind user due to: {}", e.getMessage());
+ throw new DlabException("Can not bind user due to: " + e.getMessage(), e);
+ }
+ }
+ }
+
+ private UserInfo toUserInfo(Entry e, String username) {
+ final Dn dn = e.getDn();
+ log.debug("Entry dn: {}", dn);
+ final UserInfo userInfo = new UserInfo(username, null);
+ e.getAttributes()
+ .forEach(a -> userInfo.addKey(a.getId(), a.get().toString()));
+ final String cn = userInfo.getKeys().get(COMMON_NAME_ATTRIBUTE);
+ final String[] splittedCommonName = cn.split(" ");
+ if (splittedCommonName.length == 2) {
+ userInfo.setFirstName(splittedCommonName[0]);
+ userInfo.setLastName(splittedCommonName[1]);
+ }
+
+ return userInfo;
+ }
+
+ private SearchRequestImpl getUserSearchRequest(String username) throws LdapException {
+ final SearchRequestImpl searchRequest = new SearchRequestImpl();
+ final Request searchRequestParams = configuration.getLdapSearchRequest();
+ searchRequest.setBase(new Dn(searchRequestParams.getBase()));
+ searchRequest.setFilter(searchRequestParams.getFilter().replace(LDAP_SEARCH_ATTRIBUTE, username));
+ searchRequest.setScope(SearchScope.valueOf(searchRequestParams.getScope()));
+ searchRequest.setTimeLimit(searchRequestParams.getTimeLimit());
+ final List<String> attributes = searchRequestParams.getAttributes();
+ searchRequest.addAttributes(attributes.toArray(new String[BigDecimal.ZERO.intValue()]));
+ return searchRequest;
+ }
+
+ private SearchRequestImpl getGroupSearchRequest() throws LdapException {
+ final SearchRequestImpl searchRequest = new SearchRequestImpl();
+ final Request searchRequestParams = configuration.getLdapGroupSearchRequest();
+ searchRequest.setBase(new Dn(searchRequestParams.getBase()));
+ searchRequest.setFilter(searchRequestParams.getFilter());
+ searchRequest.setScope(SearchScope.valueOf(searchRequestParams.getScope()));
+ searchRequest.setTimeLimit(searchRequestParams.getTimeLimit());
+ final List<String> attributes = searchRequestParams.getAttributes();
+ searchRequest.addAttributes(attributes.toArray(new String[BigDecimal.ZERO.intValue()]));
+ return searchRequest;
+ }
+}
diff --git a/services/security-service/src/main/java/com/epam/dlab/auth/dao/Request.java b/services/security-service/src/main/java/com/epam/dlab/auth/dao/Request.java
index 64f0f39..e58a7a6 100644
--- a/services/security-service/src/main/java/com/epam/dlab/auth/dao/Request.java
+++ b/services/security-service/src/main/java/com/epam/dlab/auth/dao/Request.java
@@ -1,118 +1,33 @@
/***************************************************************************
-Copyright (c) 2016, EPAM SYSTEMS INC
+ Copyright (c) 2016, EPAM SYSTEMS INC
-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
+ 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
+ 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.
-
-****************************************************************************/
+ 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 com.epam.dlab.auth.dao;
-import com.epam.dlab.auth.dao.filter.SearchResultProcessor;
-import org.apache.directory.api.ldap.model.message.SearchRequest;
-import org.apache.directory.api.ldap.model.message.SearchRequestImpl;
-import org.apache.directory.api.ldap.model.message.SearchScope;
-import org.apache.directory.api.ldap.model.name.Dn;
+import lombok.Data;
import java.util.List;
-import java.util.Map;
+@Data
public class Request {
-/*
-- request:
- scope: SUBTREE
- attributes:
- - "*"
- timeLimit: 0
- base: dc=example,dc=com
- filter:
- * */
-
private String name;
private String scope;
private List<String> attributes;
- private int timeLimit = 0;
+ private int timeLimit;
private String base;
private String filter = "";
- private SearchResultProcessor searchResultProcessor;
- private boolean cache = false;
- private long expirationTimeMsec = 600000; //10 minutes
- public String getScope() {
- return scope;
- }
- public String[] getAttributes() {
- return attributes.toArray(new String[]{});
- }
- public int getTimeLimit() {
- return timeLimit;
- }
- public String getBase() {
- return base;
- }
- public String getFilter() {
- return filter;
- }
-
- public SearchResultProcessor getSearchResultProcessor() {
- return searchResultProcessor;
- }
- public void setSearchResultProcessor(SearchResultProcessor searchResultProcessor) {
- this.searchResultProcessor = searchResultProcessor;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public boolean isCache() {
- return cache;
- }
- public void setCache(boolean cache) {
- this.cache = cache;
- }
- public long getExpirationTimeMsec() {
- return expirationTimeMsec;
- }
- public void setExpirationTimeMsec(long expirationTimeMsec) {
- this.expirationTimeMsec = expirationTimeMsec;
- }
- public SearchRequest buildSearchRequest(Map<String,Object> replace) {
- SearchRequest sr = new SearchRequestImpl();
- try {
- sr.setBase(new Dn(this.base));
- sr.addAttributes(this.getAttributes());
- if(this.filter != null && ! "".equals(this.filter ) ){
- String f = filter;
- for(String key:replace.keySet()) {
- f = f.replaceAll(key, replace.get(key).toString());
- }
- sr.setFilter(f);
- }
- sr.setScope(SearchScope.valueOf(this.scope));
- sr.setTimeLimit(this.timeLimit);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- return sr;
- }
-
- @Override
- public String toString() {
- return "RequestConfig [scope=" + scope + ", attributes=" + attributes + ", timeLimit=" + timeLimit + ", base=" + base
- + ", filter=" + filter + "]";
- }
-
-
-
+ private long expirationTimeMsec = 600000;
}
diff --git a/services/security-service/src/main/java/com/epam/dlab/auth/dao/SearchRequestBuilder.java b/services/security-service/src/main/java/com/epam/dlab/auth/dao/SearchRequestBuilder.java
deleted file mode 100644
index 3d608ac..0000000
--- a/services/security-service/src/main/java/com/epam/dlab/auth/dao/SearchRequestBuilder.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/***************************************************************************
-
-Copyright (c) 2016, EPAM SYSTEMS INC
-
-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 com.epam.dlab.auth.dao;
-
-public class SearchRequestBuilder {
- public SearchRequestBuilder() {
-
- }
-}
diff --git a/services/security-service/src/main/java/com/epam/dlab/auth/dao/UserInfoDAODumbImpl.java b/services/security-service/src/main/java/com/epam/dlab/auth/dao/UserInfoDAODumbImpl.java
index 1ecf642..690d93c 100644
--- a/services/security-service/src/main/java/com/epam/dlab/auth/dao/UserInfoDAODumbImpl.java
+++ b/services/security-service/src/main/java/com/epam/dlab/auth/dao/UserInfoDAODumbImpl.java
@@ -23,14 +23,16 @@ import com.epam.dlab.auth.UserInfoDAO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.Optional;
+
public class UserInfoDAODumbImpl implements UserInfoDAO {
private static final Logger LOG = LoggerFactory.getLogger(UserInfoDAODumbImpl.class);
@Override
- public UserInfo getUserInfoByAccessToken(String accessToken) {
+ public Optional<UserInfo> getUserInfoByAccessToken(String accessToken) {
LOG.debug("UserInfo persistence find unavailable: {}",accessToken);
- return null;
+ return Optional.empty();
}
@Override
diff --git a/services/security-service/src/main/java/com/epam/dlab/auth/dao/UserInfoDAOMongoImpl.java b/services/security-service/src/main/java/com/epam/dlab/auth/dao/UserInfoDAOMongoImpl.java
index 67b28ea..b5c91be 100644
--- a/services/security-service/src/main/java/com/epam/dlab/auth/dao/UserInfoDAOMongoImpl.java
+++ b/services/security-service/src/main/java/com/epam/dlab/auth/dao/UserInfoDAOMongoImpl.java
@@ -13,7 +13,6 @@
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 com.epam.dlab.auth.dao;
@@ -31,10 +30,13 @@ import com.mongodb.client.MongoCollection;
import lombok.extern.slf4j.Slf4j;
import java.util.Date;
+import java.util.Optional;
@Singleton
@Slf4j
public class UserInfoDAOMongoImpl implements UserInfoDAO {
+ private static final String EXPIRE_AT_COLUMN = "expireAt";
+ private static final String SECURITY_COLLECTION = "security";
private final MongoService ms;
private final long inactiveUserTimeoutMsec;
@@ -45,52 +47,24 @@ public class UserInfoDAOMongoImpl implements UserInfoDAO {
}
@Override
- public UserInfo getUserInfoByAccessToken(String accessToken) {
+ public Optional<UserInfo> getUserInfoByAccessToken(String accessToken) {
BasicDBObject uiSearchDoc = new BasicDBObject();
uiSearchDoc.put("_id", accessToken);
- MongoCollection<BasicDBObject> mc = ms.getCollection("security", BasicDBObject.class);
+ MongoCollection<BasicDBObject> mc = ms.getCollection(SECURITY_COLLECTION, BasicDBObject.class);
FindIterable<BasicDBObject> res = mc.find(uiSearchDoc);
BasicDBObject uiDoc = res.first();
- if (uiDoc == null) {
- log.warn("UI not found {}", accessToken);
- return null;
- }
- Date lastAccess = uiDoc.getDate("expireAt");
- if (inactiveUserTimeoutMsec < Math.abs(new Date().getTime() - lastAccess.getTime())) {
- log.warn("UI for {} expired but were not evicted from DB. Contact MongoDB admin to create expireable " +
- "index" +
- " on 'expireAt' key.", accessToken);
- this.deleteUserInfo(accessToken);
- return null;
- }
- String name = uiDoc.get("name").toString();
- String firstName = uiDoc.getString("firstName", "");
- String lastName = uiDoc.getString("lastName", "");
- String remoteIp = uiDoc.getString("remoteIp", "");
- BasicDBList roles = (BasicDBList) uiDoc.get("roles");
- Boolean awsUser = uiDoc.getBoolean("awsUser", false);
- UserInfo ui = new UserInfo(name, accessToken);
- ui.setFirstName(firstName);
- ui.setLastName(lastName);
- ui.setRemoteIp(remoteIp);
- ui.setAwsUser(awsUser);
- Object awsKeys = uiDoc.get("awsKeys");
- if (awsKeys != null) {
- ((BasicDBObject) awsKeys).forEach((key, val) -> ui.addKey(key, val.toString()));
- }
- roles.forEach(o -> ui.addRole("" + o));
- log.debug("Found persistent {}", ui);
- return ui;
+ return Optional.ofNullable(uiDoc)
+ .filter(doc -> !isExpired(accessToken, doc.getDate(EXPIRE_AT_COLUMN)))
+ .map(doc -> toUserInfo(accessToken, doc));
}
@Override
public void updateUserInfoTTL(String accessToken, UserInfo ui) {
- //Update is caleed often, but does not need to be synchronized with the main thread
BasicDBObject uiDoc = new BasicDBObject();
uiDoc.put("_id", accessToken);
- uiDoc.put("expireAt", new Date(System.currentTimeMillis()));
- MongoCollection<BasicDBObject> security = ms.getCollection("security", BasicDBObject.class);
+ uiDoc.put(EXPIRE_AT_COLUMN, new Date(System.currentTimeMillis()));
+ MongoCollection<BasicDBObject> security = ms.getCollection(SECURITY_COLLECTION, BasicDBObject.class);
security.updateOne(new BasicDBObject("_id", accessToken), new BasicDBObject("$set", uiDoc));
log.debug("Updated persistent {}", accessToken);
@@ -101,7 +75,7 @@ public class UserInfoDAOMongoImpl implements UserInfoDAO {
//delete used in logout and has to be synchronized
BasicDBObject uiDoc = new BasicDBObject();
uiDoc.put("_id", accessToken);
- MongoCollection<BasicDBObject> security = ms.getCollection("security", BasicDBObject.class);
+ MongoCollection<BasicDBObject> security = ms.getCollection(SECURITY_COLLECTION, BasicDBObject.class);
security.deleteOne(uiDoc);
log.debug("Deleted persistent {}", accessToken);
}
@@ -119,12 +93,42 @@ public class UserInfoDAOMongoImpl implements UserInfoDAO {
uiDoc.put("roles", ui.getRoles());
uiDoc.put("remoteIp", ui.getRemoteIp());
uiDoc.put("awsUser", ui.isAwsUser());
- uiDoc.put("expireAt", new Date(System.currentTimeMillis()));
+ uiDoc.put(EXPIRE_AT_COLUMN, new Date(System.currentTimeMillis()));
uiDoc.put("awsKeys", ui.getKeys());
- MongoCollection<BasicDBObject> security = ms.getCollection("security", BasicDBObject.class);
+ MongoCollection<BasicDBObject> security = ms.getCollection(SECURITY_COLLECTION, BasicDBObject.class);
security.insertOne(uiDoc);
log.debug("Saved persistent {}", ui);
}
+ private UserInfo toUserInfo(String accessToken, BasicDBObject uiDoc) {
+ String name = uiDoc.get("name").toString();
+ String firstName = uiDoc.getString("firstName", "");
+ String lastName = uiDoc.getString("lastName", "");
+ String remoteIp = uiDoc.getString("remoteIp", "");
+ BasicDBList roles = (BasicDBList) uiDoc.get("roles");
+ boolean awsUser = uiDoc.getBoolean("awsUser", false);
+ UserInfo ui = new UserInfo(name, accessToken);
+ ui.setFirstName(firstName);
+ ui.setLastName(lastName);
+ ui.setRemoteIp(remoteIp);
+ ui.setAwsUser(awsUser);
+ Object awsKeys = uiDoc.get("awsKeys");
+ if (awsKeys != null) {
+ ((BasicDBObject) awsKeys).forEach((key, val) -> ui.addKey(key, val.toString()));
+ }
+ roles.forEach(o -> ui.addRole("" + o));
+ return ui;
+ }
+
+ private boolean isExpired(String accessToken, Date lastAccess) {
+ if (inactiveUserTimeoutMsec < Math.abs(new Date().getTime() - lastAccess.getTime())) {
+ log.warn("UI for {} expired but were not evicted from DB. Contact MongoDB admin to create expireable " +
+ "index on 'expireAt' key.", accessToken);
+ this.deleteUserInfo(accessToken);
+ return true;
+ }
+ return false;
+ }
+
}
diff --git a/services/security-service/src/main/java/com/epam/dlab/auth/dao/filter/SearchResultMapper.java b/services/security-service/src/main/java/com/epam/dlab/auth/dao/filter/SearchResultMapper.java
deleted file mode 100644
index 7b51a98..0000000
--- a/services/security-service/src/main/java/com/epam/dlab/auth/dao/filter/SearchResultMapper.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/***************************************************************************
-
- Copyright (c) 2016, EPAM SYSTEMS INC
-
- 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 com.epam.dlab.auth.dao.filter;
-
-import org.apache.directory.api.ldap.model.cursor.SearchCursor;
-
-import java.io.IOException;
-import java.util.Map;
-
-public interface SearchResultMapper<M extends Map<String, Object>> {
- M transformSearchResult(SearchCursor cursor) throws IOException;
-
- M getBranch();
-}
diff --git a/services/security-service/src/main/java/com/epam/dlab/auth/dao/filter/SearchResultProcessor.java b/services/security-service/src/main/java/com/epam/dlab/auth/dao/filter/SearchResultProcessor.java
deleted file mode 100644
index 936ac05..0000000
--- a/services/security-service/src/main/java/com/epam/dlab/auth/dao/filter/SearchResultProcessor.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/***************************************************************************
-
- Copyright (c) 2016, EPAM SYSTEMS INC
-
- 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 com.epam.dlab.auth.dao.filter;
-
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-
-public class SearchResultProcessor {
- private String language;
- private String code;
- private String path;
-
- public String getLanguage() {
- return language;
- }
-
- public void setLanguage(String language) {
- this.language = language;
- }
-
- public String getCode() {
- if (code == null || "".equals(code)) {
- try {
- code = new String(Files.readAllBytes(Paths.get(path)));
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
- return code;
- }
-
- public void setCode(String code) {
- this.code = code;
- }
-
- public String getPath() {
- return path;
- }
-
- public void setPath(String path) {
- this.path = path;
- }
-
- @Override
- public String toString() {
- return "SearchResultProcessor [language=" + language + ", path=" + path + ", code=" + code + "]";
- }
-
-
-}
diff --git a/services/security-service/src/main/java/com/epam/dlab/auth/dao/script/DeepMap.java b/services/security-service/src/main/java/com/epam/dlab/auth/dao/script/DeepMap.java
deleted file mode 100644
index 9d54a8b..0000000
--- a/services/security-service/src/main/java/com/epam/dlab/auth/dao/script/DeepMap.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/***************************************************************************
-
-Copyright (c) 2016, EPAM SYSTEMS INC
-
-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 com.epam.dlab.auth.dao.script;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public class DeepMap {
-
- private final Map<String, Object> root;
-
- public DeepMap(Map<String, Object> parent) {
- super();
- this.root = parent;
- }
-
- public DeepMap() {
- super();
- this.root = new HashMap<>();
- }
-
- public Map<String, Object> getRoot() {
- return root;
- }
-
- public DeepMap getBranch(String branchName) {
- @SuppressWarnings("unchecked")
- Map<String, Object> branch = (Map<String, Object>) root.get(branchName);
- if( branch == null ) {
- branch = new HashMap<>();
- root.put(branchName, branch);
- }
- return new DeepMap(branch);
- }
-
- public void put(String key,Object val) {
- root.put(key, val);
- }
-
-}
diff --git a/services/security-service/src/main/java/com/epam/dlab/auth/dao/script/ScriptHolder.java b/services/security-service/src/main/java/com/epam/dlab/auth/dao/script/ScriptHolder.java
deleted file mode 100644
index 83cd4b5..0000000
--- a/services/security-service/src/main/java/com/epam/dlab/auth/dao/script/ScriptHolder.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/***************************************************************************
-
-Copyright (c) 2016, EPAM SYSTEMS INC
-
-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 com.epam.dlab.auth.dao.script;
-
-import com.epam.dlab.auth.UserInfo;
-
-import javax.script.Invocable;
-import javax.script.ScriptEngine;
-import javax.script.ScriptEngineManager;
-import javax.script.ScriptException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.function.BiFunction;
-
-public class ScriptHolder {
-
- private final static String FUNCTION = "enrichUserInfo";
-
- private final ScriptEngineManager mgr = new ScriptEngineManager();
- private final Map<String,Invocable> map = new HashMap<>();
-
- public ScriptHolder() {
-
- }
-
- public BiFunction<UserInfo,Map<String,?>,UserInfo> evalOnce(String name, String language, String code) throws ScriptException {
- if( ! map.containsKey(name)) {
- ScriptEngine engine = mgr.getEngineByName( language );
- engine.eval(code);
- map.put(name, (Invocable) engine);
- }
- return (ui,context)->{
- try {
- return (UserInfo) map.get(name).invokeFunction(FUNCTION, ui,context);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- };
- }
-
-
-}
diff --git a/services/security-service/src/main/java/com/epam/dlab/auth/dao/script/SearchResultToDictionaryMapper.java b/services/security-service/src/main/java/com/epam/dlab/auth/dao/script/SearchResultToDictionaryMapper.java
deleted file mode 100644
index f9c7a47..0000000
--- a/services/security-service/src/main/java/com/epam/dlab/auth/dao/script/SearchResultToDictionaryMapper.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/***************************************************************************
-
- Copyright (c) 2016, EPAM SYSTEMS INC
-
- 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 com.epam.dlab.auth.dao.script;
-
-import com.epam.dlab.auth.dao.filter.SearchResultMapper;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.directory.api.ldap.model.cursor.SearchCursor;
-import org.apache.directory.api.ldap.model.entry.Entry;
-import org.apache.directory.api.ldap.model.message.SearchResultEntry;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-public class SearchResultToDictionaryMapper implements SearchResultMapper<Map<String, Object>> {
-
- private static final Logger LOG = LoggerFactory.getLogger(SearchResultToDictionaryMapper.class);
- private static final String DISTINGUISH_NAME = "dn";
-
- private final DeepMap root;
- private final DeepMap reqBranch;
- private final String name;
-
- public SearchResultToDictionaryMapper(String name) {
- this.name = name;
- this.root = new DeepMap();
- reqBranch = root.getBranch(name);
- }
-
- public SearchResultToDictionaryMapper(String name, Map<String, Object> context) {
- this.name = name;
- this.root = new DeepMap(context);
- reqBranch = root.getBranch(name);
- }
-
- @Override
- public Map<String, Object> transformSearchResult(SearchCursor cursor) throws IOException {
- LOG.debug(name);
- cursor.forEach(response -> {
- if (response instanceof SearchResultEntry) {
- Entry resultEntry = ((SearchResultEntry) response).getEntry();
- String dn = resultEntry.getDn().toString();
- LOG.debug("\tEntryDN {}", dn);
- DeepMap dnBranch = reqBranch.getBranch(dn.toLowerCase());
- dnBranch.put(DISTINGUISH_NAME, dn);
- resultEntry.forEach(attr -> {
-
- // Since there might be multiple attributes with the same name, it is required to collect all their values (i.e. memberUid in group)
- if (attr.size() > 1) {
-
- List<Object> list = new ArrayList<>();
- attr.iterator().forEachRemaining(list::add);
-
- String join = StringUtils.join(list, ",");
- dnBranch.put(attr.getId() + "", join);
- LOG.debug("\t\tAttr {} : {} ", attr.getId(), join);
- } else {
- dnBranch.put(attr.getId() + "", attr.get() + "");
- LOG.debug("\t\tAttr {}", attr);
- }
- });
- }
- });
- return reqBranch.getRoot();
- }
-
- @Override
- public Map<String, Object> getBranch() {
- return reqBranch.getRoot();
- }
-
- @Override
- public String toString() {
- return "SearchResultToDictionaryMapper [name=" + name + ", parent=" + root + ", branch=" + reqBranch + "]";
- }
-
-
-}
diff --git a/services/security-service/src/main/java/com/epam/dlab/auth/modules/AwsSecurityServiceModule.java b/services/security-service/src/main/java/com/epam/dlab/auth/modules/AwsSecurityServiceModule.java
index d07bb7a..43683fe 100644
--- a/services/security-service/src/main/java/com/epam/dlab/auth/modules/AwsSecurityServiceModule.java
+++ b/services/security-service/src/main/java/com/epam/dlab/auth/modules/AwsSecurityServiceModule.java
@@ -25,7 +25,7 @@ import com.epam.dlab.auth.aws.dao.AwsUserDAO;
import com.epam.dlab.auth.aws.dao.AwsUserDAOImpl;
import com.epam.dlab.auth.aws.service.AwsCredentialRefreshService;
import com.epam.dlab.auth.aws.service.AwsUserVerificationService;
-import com.epam.dlab.auth.resources.SynchronousLdapAuthenticationService;
+import com.epam.dlab.auth.resources.SynchronousLdapAuthenticationResource;
import com.epam.dlab.cloud.CloudModule;
import com.google.inject.Injector;
import com.google.inject.Provides;
@@ -51,7 +51,7 @@ public class AwsSecurityServiceModule extends CloudModule {
@Override
public void init(Environment environment, Injector injector) {
- environment.jersey().register(injector.getInstance(SynchronousLdapAuthenticationService.class));
+ environment.jersey().register(injector.getInstance(SynchronousLdapAuthenticationResource.class));
if (conf.isAwsUserIdentificationEnabled()) {
environment.lifecycle().manage(injector.getInstance(AwsCredentialRefreshService.class));
}
diff --git a/services/security-service/src/main/java/com/epam/dlab/auth/modules/AzureSecurityServiceModule.java b/services/security-service/src/main/java/com/epam/dlab/auth/modules/AzureSecurityServiceModule.java
index e517093..9b02044 100644
--- a/services/security-service/src/main/java/com/epam/dlab/auth/modules/AzureSecurityServiceModule.java
+++ b/services/security-service/src/main/java/com/epam/dlab/auth/modules/AzureSecurityServiceModule.java
@@ -25,7 +25,7 @@ import com.epam.dlab.auth.azure.AzureSecurityResource;
import com.epam.dlab.auth.azure.service.AzureAuthorizationCodeService;
import com.epam.dlab.auth.azure.service.AzureAuthorizationCodeServiceImpl;
import com.epam.dlab.auth.conf.AzureLoginConfiguration;
-import com.epam.dlab.auth.resources.SynchronousLdapAuthenticationService;
+import com.epam.dlab.auth.resources.SynchronousLdapAuthenticationResource;
import com.epam.dlab.cloud.CloudModule;
import com.google.inject.Injector;
import io.dropwizard.setup.Environment;
@@ -63,7 +63,7 @@ public class AzureSecurityServiceModule extends CloudModule {
public void init(Environment environment, Injector injector) {
if (conf.getAzureLoginConfiguration().isUseLdap()) {
- environment.jersey().register(injector.getInstance(SynchronousLdapAuthenticationService.class));
+ environment.jersey().register(injector.getInstance(SynchronousLdapAuthenticationResource.class));
} else {
final AzureAuthenticationResource azureAuthenticationResource = new AzureAuthenticationResource(conf,
injector.getInstance(UserInfoDAO.class), conf.getAzureLoginConfiguration(),
diff --git a/services/security-service/src/main/java/com/epam/dlab/auth/modules/GcpSecurityServiceModule.java b/services/security-service/src/main/java/com/epam/dlab/auth/modules/GcpSecurityServiceModule.java
index ff59a84..c8de7dd 100644
--- a/services/security-service/src/main/java/com/epam/dlab/auth/modules/GcpSecurityServiceModule.java
+++ b/services/security-service/src/main/java/com/epam/dlab/auth/modules/GcpSecurityServiceModule.java
@@ -21,7 +21,7 @@ import com.epam.dlab.auth.UserVerificationService;
import com.epam.dlab.auth.gcp.resources.GcpOauth2SecurityResource;
import com.epam.dlab.auth.gcp.service.GcpAuthenticationService;
import com.epam.dlab.auth.oauth2.Oauth2AuthenticationService;
-import com.epam.dlab.auth.resources.SynchronousLdapAuthenticationService;
+import com.epam.dlab.auth.resources.SynchronousLdapAuthenticationResource;
import com.epam.dlab.cloud.CloudModule;
import com.google.api.client.auth.oauth2.AuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
@@ -60,7 +60,7 @@ public class GcpSecurityServiceModule extends CloudModule {
@Override
public void init(Environment environment, Injector injector) {
- environment.jersey().register(injector.getInstance(SynchronousLdapAuthenticationService.class));
+ environment.jersey().register(injector.getInstance(SynchronousLdapAuthenticationResource.class));
if (conf.isOauth2authenticationEnabled()) {
environment.jersey().register(injector.getInstance(GcpOauth2SecurityResource.class));
}
diff --git a/services/security-service/src/main/java/com/epam/dlab/auth/modules/SecurityServiceModule.java b/services/security-service/src/main/java/com/epam/dlab/auth/modules/SecurityServiceModule.java
index b2ba95d..7672faa 100644
--- a/services/security-service/src/main/java/com/epam/dlab/auth/modules/SecurityServiceModule.java
+++ b/services/security-service/src/main/java/com/epam/dlab/auth/modules/SecurityServiceModule.java
@@ -21,8 +21,11 @@ import com.epam.dlab.auth.SecurityServiceConfiguration;
import com.epam.dlab.auth.UserInfoDAO;
import com.epam.dlab.auth.UserVerificationService;
import com.epam.dlab.auth.dao.LdapUserDAO;
+import com.epam.dlab.auth.dao.LdapUserDAOImpl;
import com.epam.dlab.auth.dao.UserInfoDAODumbImpl;
import com.epam.dlab.auth.dao.UserInfoDAOMongoImpl;
+import com.epam.dlab.auth.service.AuthenticationService;
+import com.epam.dlab.auth.service.impl.LdapAuthenticationService;
import com.epam.dlab.mongo.MongoService;
import com.google.inject.Provides;
import com.google.inject.Singleton;
@@ -39,6 +42,8 @@ public class SecurityServiceModule extends ModuleBase<SecurityServiceConfigurati
@Override
protected void configure() {
bind(SecurityServiceConfiguration.class).toInstance(configuration);
+ bind(LdapUserDAO.class).to(LdapUserDAOImpl.class);
+ bind(AuthenticationService.class).to(LdapAuthenticationService.class);
if (configuration.isUserInfoPersistenceEnabled()) {
bind(UserInfoDAO.class).to(UserInfoDAOMongoImpl.class);
} else {
@@ -52,13 +57,7 @@ public class SecurityServiceModule extends ModuleBase<SecurityServiceConfigurati
return configuration.getMongoFactory().build(environment);
}
- @Provides
- @Singleton
- private LdapUserDAO ldapUserDAOWithoutCache() {
- return new LdapUserDAO(configuration, false);
- }
-
public static UserVerificationService defaultUserVerificationService() {
- return (username, userInfo) -> log.debug("No additional user verification configured");
+ return userInfo -> log.debug("No additional user verification configured");
}
}
diff --git a/services/security-service/src/main/java/com/epam/dlab/auth/resources/SynchronousLdapAuthenticationResource.java b/services/security-service/src/main/java/com/epam/dlab/auth/resources/SynchronousLdapAuthenticationResource.java
new file mode 100644
index 0000000..113208d
--- /dev/null
+++ b/services/security-service/src/main/java/com/epam/dlab/auth/resources/SynchronousLdapAuthenticationResource.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2017, EPAM SYSTEMS INC
+ *
+ * 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 com.epam.dlab.auth.resources;
+
+import com.epam.dlab.auth.UserInfo;
+import com.epam.dlab.auth.dto.UserCredentialDTO;
+import com.epam.dlab.auth.service.AuthenticationService;
+import com.epam.dlab.rest.dto.ErrorDTO;
+import com.google.inject.Inject;
+import lombok.extern.slf4j.Slf4j;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+/**
+ * Used for authentication against LDAP server
+ */
+@Path("/")
+@Consumes(MediaType.APPLICATION_JSON)
+@Produces(MediaType.APPLICATION_JSON)
+@Slf4j
+public class SynchronousLdapAuthenticationResource {
+ private static final String INVALID_CREDENTIALS = "Username or password is invalid";
+ private final AuthenticationService authenticationService;
+
+ @Inject
+ public SynchronousLdapAuthenticationResource(AuthenticationService authenticationService) {
+ this.authenticationService = authenticationService;
+ }
+
+ @POST
+ @Path("/login")
+ public Response login(UserCredentialDTO cred) {
+ log.debug("validating username:{} password:****** token:{}", cred.getUsername(), cred.getAccessToken());
+ return authenticationService.login(cred)
+ .map(userInfo -> Response.ok(userInfo.getAccessToken()).build())
+ .orElse(unauthorizedResponse());
+ }
+
+ @POST
+ @Path("/getuserinfo")
+ public UserInfo getUserInfo(String accessToken) {
+ return authenticationService.getUserInfo(accessToken).orElse(null);
+ }
+
+ @POST
+ @Path("/logout")
+ public Response logout(String accessToken) {
+ authenticationService.logout(accessToken);
+ return Response.ok().build();
+ }
+
+ private Response unauthorizedResponse() {
+ return Response.status(Response.Status.UNAUTHORIZED)
+ .entity(new ErrorDTO(Response.Status.UNAUTHORIZED.getStatusCode(), INVALID_CREDENTIALS))
+ .type(MediaType.APPLICATION_JSON)
+ .build();
+ }
+}
diff --git a/services/security-service/src/main/java/com/epam/dlab/auth/resources/SynchronousLdapAuthenticationService.java b/services/security-service/src/main/java/com/epam/dlab/auth/resources/SynchronousLdapAuthenticationService.java
deleted file mode 100644
index 2194215..0000000
--- a/services/security-service/src/main/java/com/epam/dlab/auth/resources/SynchronousLdapAuthenticationService.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright (c) 2017, EPAM SYSTEMS INC
- *
- * 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 com.epam.dlab.auth.resources;
-
-import com.epam.dlab.auth.SecurityServiceConfiguration;
-import com.epam.dlab.auth.UserInfo;
-import com.epam.dlab.auth.UserInfoDAO;
-import com.epam.dlab.auth.UserVerificationService;
-import com.epam.dlab.auth.dao.LdapUserDAO;
-import com.epam.dlab.auth.dto.UserCredentialDTO;
-import com.epam.dlab.auth.rest.AbstractAuthenticationService;
-import com.epam.dlab.constants.ServiceConsts;
-import com.epam.dlab.exceptions.DlabException;
-import com.epam.dlab.rest.dto.ErrorDTO;
-import com.google.inject.Inject;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
-/**
- * Used for authentication against LDAP server
- */
-@Path("/")
-@Consumes(MediaType.APPLICATION_JSON)
-@Produces(MediaType.APPLICATION_JSON)
-public class SynchronousLdapAuthenticationService extends AbstractAuthenticationService<SecurityServiceConfiguration> {
- private final LdapUserDAO ldapUserDAO;
- private final UserInfoDAO userInfoDao;
- private final UserVerificationService userVerificationService;
-
- @Inject
- public SynchronousLdapAuthenticationService(SecurityServiceConfiguration config, UserInfoDAO userInfoDao,
- LdapUserDAO ldapUserDAO,
- UserVerificationService userVerificationService) {
- super(config);
- this.ldapUserDAO = ldapUserDAO;
- this.userInfoDao = userInfoDao;
- this.userVerificationService = userVerificationService;
- }
-
- @Override
- @POST
- @Path("/login")
- public Response login(UserCredentialDTO credential, @Context HttpServletRequest request) {
-
- String username = credential.getUsername();
- String password = credential.getPassword();
- String accessToken = credential.getAccessToken();
- String remoteIp = request.getRemoteAddr();
- String userAgent = request.getHeader(HttpHeaders.USER_AGENT);
-
- log.debug("validating username:{} password:****** token:{} ip:{}", username, accessToken, remoteIp);
-
- final Response.Status unauthorized = Response.Status.UNAUTHORIZED;
- if (accessToken != null && !accessToken.isEmpty()) {
- UserInfo ui = getUserInfo(accessToken, userAgent, remoteIp);
- if (ui != null) {
- return Response.ok(accessToken).build();
- } else {
- log.debug("User info not found on login by access_token for user {}", username);
- return Response.status(unauthorized).build();
- }
- }
-
- try {
-
- login(username, password);
- UserInfo enriched = enrichUser(username);
- userVerificationService.verify(username, enriched);
-
- enriched.setRemoteIp(remoteIp);
- log.info("User authenticated is {}", enriched);
- String token = getRandomToken();
-
- userInfoDao.saveUserInfo(enriched.withToken(token));
- return Response.ok(token).build();
-
- } catch (Exception e) {
- log.error("User {} is not authenticated", username, e);
- return Response.status(unauthorized)
- .entity(new ErrorDTO(unauthorized.getStatusCode(), e.getMessage()))
- .type(MediaType.APPLICATION_JSON).build();
- }
- }
-
- @Override
- @POST
- @Path("/getuserinfo")
- public UserInfo getUserInfo(String accessToken, @Context HttpServletRequest request) {
- String userAgent = request.getHeader(HttpHeaders.USER_AGENT);
- String remoteIp = request.getRemoteAddr();
-
- UserInfo ui = getUserInfo(accessToken, userAgent, remoteIp);
-
- if (ui != null) {
- return ui;
- }
-
- log.debug("Session {} is expired", accessToken);
-
- return null;
- }
-
- private UserInfo getUserInfo(String accessToken, String userAgent, String remoteIp) {
-
- UserInfo ui = userInfoDao.getUserInfoByAccessToken(accessToken);
-
- if (ui != null) {
- ui = ui.withToken(accessToken);
- updateTTL(accessToken, ui, userAgent);
- log.debug("restored UserInfo from DB {}", ui);
-
- log.debug("Authorized {} {} {}", accessToken, ui, remoteIp);
- return ui;
- }
-
- return null;
-
- }
-
- @Override
- @POST
- @Path("/logout")
- public Response logout(String accessToken) {
- userInfoDao.deleteUserInfo(accessToken);
- log.info("Logged out user {}", accessToken);
- return Response.ok().build();
- }
-
- private UserInfo login(String username, String password) {
- try {
- UserInfo userInfo = ldapUserDAO.getUserInfo(username, password);
- log.debug("User Authenticated: {}", username);
- return userInfo;
- } catch (Exception e) {
- log.error("Authentication error", e);
- throw new DlabException("Username or password are not valid", e);
- }
- }
-
- private UserInfo enrichUser(String username) {
-
- try {
- UserInfo userInfo = ldapUserDAO.enrichUserInfo(new UserInfo(username, null));
- log.debug("User Enriched: {}", username);
- return userInfo;
- } catch (Exception e) {
- log.error("Authentication error", e);
- throw new DlabException("User not authorized. Please contact DLAB administrator.");
- }
- }
-
-
- private void updateTTL(String accessToken, UserInfo ui, String userAgent) {
- log.debug("updating TTL agent {} {}", userAgent, ui);
- if (ServiceConsts.PROVISIONING_USER_AGENT.equals(userAgent)) {
- return;
- }
-
- userInfoDao.updateUserInfoTTL(accessToken, ui);
- }
-}
diff --git a/services/security-service/src/main/java/com/epam/dlab/auth/service/AuthenticationService.java b/services/security-service/src/main/java/com/epam/dlab/auth/service/AuthenticationService.java
new file mode 100644
index 0000000..fde6a82
--- /dev/null
+++ b/services/security-service/src/main/java/com/epam/dlab/auth/service/AuthenticationService.java
@@ -0,0 +1,33 @@
+/*
+ *
+ * * Copyright (c) 2018, EPAM SYSTEMS INC
+ * *
+ * * 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 com.epam.dlab.auth.service;
+
+import com.epam.dlab.auth.UserInfo;
+import com.epam.dlab.auth.dto.UserCredentialDTO;
+
+import java.util.Optional;
+
+public interface AuthenticationService {
+
+ Optional<UserInfo> getUserInfo(String token);
+
+ Optional<UserInfo> login(UserCredentialDTO credentialDTO);
+
+ void logout(String token);
+}
diff --git a/services/security-service/src/main/java/com/epam/dlab/auth/service/impl/LdapAuthenticationService.java b/services/security-service/src/main/java/com/epam/dlab/auth/service/impl/LdapAuthenticationService.java
new file mode 100644
index 0000000..d17cd85
--- /dev/null
+++ b/services/security-service/src/main/java/com/epam/dlab/auth/service/impl/LdapAuthenticationService.java
@@ -0,0 +1,82 @@
+/*
+ *
+ * * Copyright (c) 2018, EPAM SYSTEMS INC
+ * *
+ * * 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 com.epam.dlab.auth.service.impl;
+
+import com.epam.dlab.auth.UserInfo;
+import com.epam.dlab.auth.UserInfoDAO;
+import com.epam.dlab.auth.UserVerificationService;
+import com.epam.dlab.auth.dao.LdapUserDAO;
+import com.epam.dlab.auth.dto.UserCredentialDTO;
+import com.epam.dlab.auth.service.AuthenticationService;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Optional;
+
+import static com.epam.dlab.auth.rest.AbstractAuthenticationService.getRandomToken;
+
+@Singleton
+@Slf4j
+public class LdapAuthenticationService implements AuthenticationService {
+ private final UserInfoDAO userInfoDAO;
+ private final LdapUserDAO ldapUserDAO;
+ private final UserVerificationService verificationService;
+
+ @Inject
+ public LdapAuthenticationService(UserInfoDAO userInfoDAO, LdapUserDAO ldapUserDAO,
+ UserVerificationService verificationService) {
+ this.userInfoDAO = userInfoDAO;
+ this.ldapUserDAO = ldapUserDAO;
+ this.verificationService = verificationService;
+ }
+
+ @Override
+ public Optional<UserInfo> getUserInfo(String token) {
+ return userInfoDAO.getUserInfoByAccessToken(token)
+ .map(userInfo -> touchedUser(token, userInfo));
+ }
+
+ @Override
+ public Optional<UserInfo> login(UserCredentialDTO credentialDTO) {
+ final String token = credentialDTO.getAccessToken();
+ return StringUtils.isNoneBlank(token) ? getUserInfo(token) : getLdapUserInfo(credentialDTO);
+ }
+
+ @Override
+ public void logout(String token) {
+ userInfoDAO.deleteUserInfo(token);
+ }
+
+ private Optional<UserInfo> getLdapUserInfo(UserCredentialDTO credentialDTO) {
+ final UserInfo user = ldapUserDAO.getUserInfo(credentialDTO.getUsername(), credentialDTO.getPassword());
+ user.addRoles(ldapUserDAO.getUserGroups(user));
+ verificationService.verify(user);
+ final String token = getRandomToken();
+ final UserInfo userWithToken = user.withToken(token);
+ userInfoDAO.saveUserInfo(userWithToken);
+ return Optional.of(userWithToken);
+ }
+
+ private UserInfo touchedUser(String token, UserInfo userInfo) {
+ userInfoDAO.updateUserInfoTTL(token, userInfo);
+ return userInfo.withToken(token);
+ }
+}
diff --git a/services/security-service/src/test/java/com/epam/dlab/auth/aws/AwsTest.java b/services/security-service/src/test/java/com/epam/dlab/auth/aws/AwsTest.java
deleted file mode 100644
index 15c5b9d..0000000
--- a/services/security-service/src/test/java/com/epam/dlab/auth/aws/AwsTest.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/***************************************************************************
-
-Copyright (c) 2016, EPAM SYSTEMS INC
-
-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 com.epam.dlab.auth.aws;
-
-import com.epam.dlab.auth.UserInfo;
-import com.epam.dlab.auth.core.LdapFilterCache;
-import com.epam.dlab.auth.core.LoginCache;
-import org.junit.*;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-public class AwsTest {
- @BeforeClass
- public static void setUpBeforeClass() throws Exception {
- }
-
- @AfterClass
- public static void tearDownAfterClass() throws Exception {
- }
-
- @Before
- public void setUp() throws Exception {
- }
-
- @After
- public void tearDown() throws Exception {
- }
-
- @Test
- public void testLoginCache() throws InterruptedException {
- LoginCache c = LoginCache.getInstance();
- c.setDefaultBuilderTimeout(1, TimeUnit.SECONDS);
- c.setIdleHeartBeat(100,TimeUnit.MILLISECONDS);
- c.save(new UserInfo("test","a"));
- UserInfo u = c.getUserInfo("a");
- assertNotNull(u);
- System.out.println(u);
- }
-
- @Test
- public void testLdapCache() throws InterruptedException {
- LdapFilterCache c = LdapFilterCache.getInstance();
- c.setIdleHeartBeat(100,TimeUnit.MILLISECONDS);
- Map<String,Object> m = new HashMap<>();
- m.put("name","a");
- c.save("a",m,100);
- Map<String,Object> m2 = c.getLdapFilterInfo("a");
- assertNotNull(m2);
- assertTrue(m==m2);
- m2.put("test","me");
- System.out.println(m);
- Thread.sleep(1000);
- }
-
-
-}
diff --git a/services/security-service/src/test/java/com/epam/dlab/auth/core/LoginConveyorTest.java b/services/security-service/src/test/java/com/epam/dlab/auth/core/LoginConveyorTest.java
deleted file mode 100644
index 4e7406b..0000000
--- a/services/security-service/src/test/java/com/epam/dlab/auth/core/LoginConveyorTest.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/***************************************************************************
-
- Copyright (c) 2016, EPAM SYSTEMS INC
-
- 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 com.epam.dlab.auth.core;
-
-import com.amazonaws.services.identitymanagement.model.AccessKeyMetadata;
-import com.epam.dlab.auth.UserInfo;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.ArrayList;
-import java.util.concurrent.*;
-
-public class LoginConveyorTest {
-
- LoginConveyor lc = new LoginConveyor(10);
-
- @Before
- public void createCOnveyor(){
- }
-
- @After
- public void stopConveyor() {
- }
-
- @Test
- public void setUserInfoDao() throws Exception {
-
- }
-
- @SuppressWarnings("serial")
- @Test
- public void startUserInfoBuild() throws Exception {
- CompletableFuture<UserInfo> uf = lc.startUserInfoBuild("1","test");
- UserInfo uiSource = new UserInfo("a","b");
- uiSource.setFirstName("test");
- uiSource.setLastName("user");
- uiSource.addRole("admin");
-
- lc.add("1","127.0.0.1",LoginStep.REMOTE_IP);
- lc.add("1","OK",LoginStep.LDAP_LOGIN);
- lc.add("1",uiSource, LoginStep.LDAP_USER_INFO);
- lc.add("1",true, LoginStep.AWS_USER);
- lc.add("1",new ArrayList<AccessKeyMetadata>() {
- { add(new AccessKeyMetadata()
- .withAccessKeyId("a")
- .withStatus("Active"));
- }} ,LoginStep.AWS_KEYS);
-
-
-
- UserInfo ui = uf.get(15, TimeUnit.SECONDS);
- System.out.println("Future now: "+ui);
- }
-
- @Test
- public void startUserInfoBuildWithoutAws() throws Exception {
- CompletableFuture<UserInfo> uf = lc.startUserInfoBuild("1","test");
- UserInfo uiSource = new UserInfo("a","b");
- uiSource.setFirstName("test");
- uiSource.setLastName("user");
- uiSource.addRole("admin");
-
- lc.add("1","127.0.0.1",LoginStep.REMOTE_IP);
- lc.add("1","OK",LoginStep.LDAP_LOGIN);
- lc.add("1",uiSource, LoginStep.LDAP_USER_INFO);
- lc.add("1",true, LoginStep.AWS_USER);
- lc.add("1",new ArrayList<AccessKeyMetadata>() ,LoginStep.AWS_KEYS_EMPTY);
-
-
-
- UserInfo ui = uf.get(15, TimeUnit.SECONDS);
- System.out.println("Future now: "+ui);
- }
-
- @Test(expected = CancellationException.class)
- public void cacheTest() throws ExecutionException, InterruptedException, TimeoutException {
- LoginCache cache = LoginCache.getInstance();
- System.out.println("---cacheTest");
- //Just for this test
- cache.setDefaultBuilderTimeout(1,TimeUnit.SECONDS);
- cache.setExpirationPostponeTime(1,TimeUnit.SECONDS);
-
- UserInfo userInfo = new UserInfo("test","user");
- userInfo.setFirstName("Mike");
- userInfo.setLastName("T");
- userInfo.addRole("tr");
- userInfo.setAwsUser(true);
- userInfo.addKey("a","Active");
-
- CompletableFuture<Boolean> f = cache.createBuild("2", CacheableReference.newInstance(userInfo));
- CompletableFuture<UserInfo> uif = cache.getFuture("2");
- f.get();
- //this will take at least 2 seconds
- for(int i = 0; i < 10; i++) {
- UserInfo ui = cache.getUserInfo("2");
- System.out.println(i+": "+ui);
- Thread.sleep(200);
- }
- //and finally will exit with timeout
- uif.get(5,TimeUnit.SECONDS);
- }
-
- @Test
- public void add() throws Exception {
-
- }
-
- @Test
- public void cancel() throws Exception {
-
- }
-
-}
\ No newline at end of file
diff --git a/services/security-service/src/test/java/com/epam/dlab/auth/dao/script/ScriptHolderTest.java b/services/security-service/src/test/java/com/epam/dlab/auth/dao/script/ScriptHolderTest.java
deleted file mode 100644
index b449ae2..0000000
--- a/services/security-service/src/test/java/com/epam/dlab/auth/dao/script/ScriptHolderTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/***************************************************************************
-
-Copyright (c) 2016, EPAM SYSTEMS INC
-
-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 com.epam.dlab.auth.dao.script;
-
-import com.epam.dlab.auth.UserInfo;
-import org.junit.*;
-
-import javax.script.ScriptException;
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.junit.Assert.assertNotNull;
-
-public class ScriptHolderTest {
-
- @BeforeClass
- public static void setUpBeforeClass() throws Exception {
- }
-
- @AfterClass
- public static void tearDownAfterClass() throws Exception {
- }
-
- @Before
- public void setUp() throws Exception {
- }
-
- @After
- public void tearDown() throws Exception {
- }
-
- @Test
- public void test() throws ScriptException {
- ScriptHolder sh = new ScriptHolder();
- Map<String,Object> map = new HashMap<>();
- map.put("key1", "val1");
- map.put("key2", "val2");
- UserInfo ui1 = sh.evalOnce("first", "javascript", "var enrichUserInfo=function(ui,context){ui.addRole(context['key1']);ui.setFirstName(\"Mike\");return ui;}").apply(new UserInfo("",""), map);
- System.out.println(ui1);
- assertNotNull(ui1);
-
- UserInfo ui2 = sh.evalOnce("second", "python", "def enrichUserInfo(ui,context):\n ui.addRole(context['key2'])\n ui.setLastName(\"Teplitskiy\")\n return ui\n").apply(ui1, map);
- System.out.println(ui2);
- assertNotNull(ui2);
-
- }
-
-}
diff --git a/services/security-service/src/test/java/com/epam/dlab/auth/ldap/AuthTest.java b/services/security-service/src/test/java/com/epam/dlab/auth/ldap/AuthTest.java
deleted file mode 100644
index c0a1110..0000000
--- a/services/security-service/src/test/java/com/epam/dlab/auth/ldap/AuthTest.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/***************************************************************************
-
-Copyright (c) 2016, EPAM SYSTEMS INC
-
-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 com.epam.dlab.auth.ldap;
-
-public class AuthTest {
-
- public static void main(String[] args) {
- System.out.println("auth test");
-
- }
-
-}
diff --git a/services/security-service/src/test/java/com/epam/dlab/auth/ldap/BasicTest.java b/services/security-service/src/test/java/com/epam/dlab/auth/ldap/BasicTest.java
deleted file mode 100644
index c976925..0000000
--- a/services/security-service/src/test/java/com/epam/dlab/auth/ldap/BasicTest.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/***************************************************************************
-
-Copyright (c) 2016, EPAM SYSTEMS INC
-
-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 com.epam.dlab.auth.ldap;
-
-import org.apache.commons.pool.PoolableObjectFactory;
-import org.apache.directory.api.ldap.model.cursor.SearchCursor;
-import org.apache.directory.api.ldap.model.entry.Entry;
-import org.apache.directory.api.ldap.model.message.SearchRequest;
-import org.apache.directory.api.ldap.model.message.SearchRequestImpl;
-import org.apache.directory.api.ldap.model.message.SearchResultEntry;
-import org.apache.directory.api.ldap.model.message.SearchScope;
-import org.apache.directory.api.ldap.model.name.Dn;
-import org.apache.directory.ldap.client.api.LdapConnection;
-import org.apache.directory.ldap.client.api.LdapConnectionConfig;
-import org.apache.directory.ldap.client.api.LdapConnectionPool;
-import org.apache.directory.ldap.client.api.ValidatingPoolableLdapConnectionFactory;
-//import org.apache.directory.ldap.client.api.PoolableLdapConnectionFactory;
-
-public class BasicTest {
-
- public static void main(String[] args) throws Exception {
- System.out.println("Basic test");
- LdapConnectionConfig config = new LdapConnectionConfig();
- config.setLdapHost( "localhost" );
- config.setLdapPort( 3890 );
- config.setName( "cn=admin,dc=example,dc=com" );
- config.setCredentials( "ldap" );
- PoolableObjectFactory<LdapConnection> poolFactory = new ValidatingPoolableLdapConnectionFactory( config );
- LdapConnectionPool pool = new LdapConnectionPool( poolFactory );
- pool.setTestOnBorrow( true );
- LdapConnection con = pool.borrowObject();
-
- SearchRequest sr = new SearchRequestImpl();
- sr.setScope(SearchScope.SUBTREE);
- sr.addAttributes("*");
- sr.setTimeLimit(0);
- sr.setBase(new Dn("dc=example,dc=com"));
- sr.setFilter("(cn=Mike Teplitskiy)");
- sr.setMessageId(1);
-
-// EntryCursor cursor = con.search( "dc=example,dc=com", "(objectclass=*)", SearchScope.SUBTREE );
- SearchCursor cursor = con.search( sr );
-//
-// cursor.forEach(entry->{
-// System.out.println( "---- DN "+entry.getDn() );
-// entry.forEach(attr->{
-// System.out.println( "---- ATTR "+attr );
-// });
-//
-// });
-
- cursor.forEach(response->{
- if ( response instanceof SearchResultEntry )
- {
- Entry resultEntry = ( ( SearchResultEntry ) response ).getEntry();
- System.out.println( "---- DN "+resultEntry.getDn() );
- resultEntry.forEach(attr-> System.out.println( "---- ATTR "+attr ));
- }
- });
- cursor.close();
-
- sr.setFilter("(cn=John Doe)");
- sr.setMessageId(1);
- cursor = con.search( sr );
- cursor.forEach(response->{
- if ( response instanceof SearchResultEntry )
- {
- Entry resultEntry = ( ( SearchResultEntry ) response ).getEntry();
- System.out.println( "---- DN "+resultEntry.getDn() );
- resultEntry.forEach(attr-> System.out.println( "---- ATTR "+attr ));
- }
- });
- cursor.close();
-
-
-
- con.unBind();
-
- con.bind("uid=mike,ou=People,dc=example,dc=com","test");
- sr.setFilter("(uid=mike)");
- sr.setMessageId(2);
- cursor = con.search( sr );
- cursor.forEach(response->{
- if ( response instanceof SearchResultEntry )
- {
- Entry resultEntry = ( ( SearchResultEntry ) response ).getEntry();
- System.out.println( "---- DN "+resultEntry.getDn() );
- resultEntry.forEach(attr-> System.out.println( "---- ATTR "+attr ));
- }
- });
- cursor.close();
-
- System.out.println("Press ENTER");
- pool.releaseConnection(con);
- pool.close();
-
- }
-
-}
diff --git a/services/security-service/src/test/java/com/epam/dlab/auth/ldap/JsonTest.java b/services/security-service/src/test/java/com/epam/dlab/auth/ldap/JsonTest.java
deleted file mode 100644
index 932f60e..0000000
--- a/services/security-service/src/test/java/com/epam/dlab/auth/ldap/JsonTest.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/***************************************************************************
-
-Copyright (c) 2016, EPAM SYSTEMS INC
-
-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 com.epam.dlab.auth.ldap;
-
-import com.epam.dlab.auth.UserInfo;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import org.junit.*;
-
-import java.io.IOException;
-
-import static org.junit.Assert.assertNotNull;
-
-public class JsonTest {
-
- @BeforeClass
- public static void setUpBeforeClass() throws Exception {
- }
-
- @AfterClass
- public static void tearDownAfterClass() throws Exception {
- }
-
- @Before
- public void setUp() throws Exception {
- }
-
- @After
- public void tearDown() throws Exception {
- }
-
- @Test
- public void test1() throws IOException {
- ObjectMapper om = new ObjectMapper();
- String jv = om.writeValueAsString(new UserInfo("user","info"));
- assertNotNull(jv);
- System.out.println(jv);
- UserInfo ui = om.readerFor(UserInfo.class).readValue(jv);
- assertNotNull(ui);
- System.out.println(ui);
- //String js = "{\\\"username\\\":\"user\",\\\"access_token\\\":\"info\",\\\"firstName\\\":null,\\\"lastName\\\":null,\\\"roles\\\":[]}";
- //System.out.println(js);
- //UserInfo ui2 = om.readerFor(UserInfo.class).readValue(js);
-
-
- }
- @Test
- public void test2() throws IOException {
- ObjectMapper om = new ObjectMapper();
- UserInfo ui = new UserInfo("user","info");
- ui.setFirstName("first");
- ui.setLastName("last");
- ui.addRole("r1");
- ui.addRole("r2");
- String jv = om.writeValueAsString(ui);
- assertNotNull(jv);
- System.out.println(jv);
- UserInfo ui2 = om.readerFor(UserInfo.class).readValue(jv);
- assertNotNull(ui2);
- System.out.println(ui2);
- //String js = "{\\\"username\\\":\"user\",\\\"access_token\\\":\"info\",\\\"firstName\\\":null,\\\"lastName\\\":null,\\\"roles\\\":[]}";
- //System.out.println(js);
- //UserInfo ui2 = om.readerFor(UserInfo.class).readValue(js);
-
-
- }
-
-}
diff --git a/services/security-service/src/test/java/com/epam/dlab/auth/ldap/ScriptList.java b/services/security-service/src/test/java/com/epam/dlab/auth/ldap/ScriptList.java
deleted file mode 100644
index 75763a1..0000000
--- a/services/security-service/src/test/java/com/epam/dlab/auth/ldap/ScriptList.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/***************************************************************************
-
-Copyright (c) 2016, EPAM SYSTEMS INC
-
-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 com.epam.dlab.auth.ldap;
-
-import com.epam.dlab.auth.UserInfo;
-
-import javax.script.*;
-import java.util.List;
-
-public class ScriptList {
-
- public static void main( String[] args ) throws ScriptException, NoSuchMethodException {
-
- ScriptEngineManager mgr = new ScriptEngineManager();
- List<ScriptEngineFactory> factories = mgr.getEngineFactories();
-
- for (ScriptEngineFactory factory : factories) {
-
- System.out.println("ScriptEngineFactory Info");
-
- String engName = factory.getEngineName();
- String engVersion = factory.getEngineVersion();
- String langName = factory.getLanguageName();
- String langVersion = factory.getLanguageVersion();
-
- System.out.printf("\tScript Engine: %s (%s)%n", engName, engVersion);
-
- List<String> engNames = factory.getNames();
- for(String name : engNames) {
- System.out.printf("\tEngine Alias: %s%n", name);
- }
-
- System.out.printf("\tLanguage: %s (%s)%n", langName, langVersion);
-
- }
-
- ScriptEngine python = mgr.getEngineByName("python");
- ScriptEngine js = mgr.getEngineByName("javascript");
- python.eval("print \"Hello Python!\"");
-
- js.eval("print('Hello JavaScript!');");
-
- Invocable ijs = (Invocable) js;
- Invocable ipy = (Invocable) python;
-
- js.eval("var f=function(ui){print(ui);ui.setFirstName(\"Mike\");return ui;};");
-
- Object res = ijs.invokeFunction("f", new UserInfo("test", "pass"));
- System.out.println(res);
-
- python.eval("def f(ui):\n print ui\n ui.setLastName(\"Teplitskiy\")\n return ui\n");
- Object res2 = ipy.invokeFunction("f", new UserInfo("test", "pass"));
- System.out.println(res2);
-
-
-
- }
-
-}
\ No newline at end of file
diff --git a/services/security-service/src/test/java/com/epam/dlab/auth/service/impl/LdapAuthenticationServiceTest.java b/services/security-service/src/test/java/com/epam/dlab/auth/service/impl/LdapAuthenticationServiceTest.java
new file mode 100644
index 0000000..ac4a258
--- /dev/null
+++ b/services/security-service/src/test/java/com/epam/dlab/auth/service/impl/LdapAuthenticationServiceTest.java
@@ -0,0 +1,138 @@
+/*
+ *
+ * * Copyright (c) 2018, EPAM SYSTEMS INC
+ * *
+ * * 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 com.epam.dlab.auth.service.impl;
+
+import com.epam.dlab.auth.UserInfo;
+import com.epam.dlab.auth.UserInfoDAO;
+import com.epam.dlab.auth.UserVerificationService;
+import com.epam.dlab.auth.dao.LdapUserDAO;
+import com.epam.dlab.auth.dto.UserCredentialDTO;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import java.util.Optional;
+
+import static org.junit.Assert.*;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.refEq;
+import static org.mockito.Mockito.*;
+
+@RunWith(MockitoJUnitRunner.class)
+public class LdapAuthenticationServiceTest {
+
+ private static final String TOKEN = "token123";
+ private static final String USER = "user";
+ private static final String PASSWORD = "password";
+ @Mock
+ private LdapUserDAO ldapUserDAO;
+ @Mock
+ private UserInfoDAO userInfoDAO;
+ @Mock
+ private UserVerificationService verificationService;
+ @InjectMocks
+ private LdapAuthenticationService ldapAuthenticationService;
+
+ @Test
+ public void getUserInfo() {
+
+ when(userInfoDAO.getUserInfoByAccessToken(anyString())).thenReturn(Optional.of(userInfo()));
+ final Optional<UserInfo> userInfo = ldapAuthenticationService.getUserInfo(TOKEN);
+
+ assertTrue(userInfo.isPresent());
+ assertEquals(USER.toLowerCase(), userInfo.get().getName());
+ assertEquals(TOKEN, userInfo.get().getAccessToken());
+
+ verify(userInfoDAO).getUserInfoByAccessToken(TOKEN);
+ verify(userInfoDAO).updateUserInfoTTL(eq(TOKEN), refEq(userInfo()));
+ verifyNoMoreInteractions(userInfoDAO);
+ }
+
+ @Test
+ public void getUserInfoWhenUserNotFound() {
+
+ when(userInfoDAO.getUserInfoByAccessToken(anyString())).thenReturn(Optional.empty());
+ final Optional<UserInfo> userInfo = ldapAuthenticationService.getUserInfo(TOKEN);
+
+ assertFalse(userInfo.isPresent());
+
+ verify(userInfoDAO).getUserInfoByAccessToken(TOKEN);
+ verifyNoMoreInteractions(userInfoDAO);
+ }
+
+ @Test
+ public void loginWithoutAccessToken() {
+
+ when(ldapUserDAO.getUserInfo(anyString(), anyString())).thenReturn(userInfo());
+ final Optional<UserInfo> userInfo = ldapAuthenticationService.login(getCredentialDTO());
+
+ assertTrue(userInfo.isPresent());
+ assertEquals(USER, userInfo.get().getName());
+ assertNotNull(userInfo.get().getAccessToken());
+
+ verify(verificationService).verify(refEq(userInfo()));
+ verify(ldapUserDAO).getUserInfo(USER, PASSWORD);
+ verify(ldapUserDAO).getUserGroups(refEq(userInfo()));
+ verify(userInfoDAO).saveUserInfo(refEq(userInfo().withToken(TOKEN), "accessToken"));
+ verifyNoMoreInteractions(ldapUserDAO, userInfoDAO);
+ }
+
+ @Test
+ public void loginWithAccessToken() {
+
+ when(userInfoDAO.getUserInfoByAccessToken(anyString())).thenReturn(Optional.of(userInfo()));
+ final UserCredentialDTO credentialDTO = getCredentialDTO();
+ credentialDTO.setAccessToken(TOKEN);
+ final Optional<UserInfo> userInfo = ldapAuthenticationService.login(credentialDTO);
+
+ assertTrue(userInfo.isPresent());
+ assertEquals(USER, userInfo.get().getName());
+ assertNotNull(userInfo.get().getAccessToken());
+
+ verify(userInfoDAO).getUserInfoByAccessToken(TOKEN);
+ verify(userInfoDAO).updateUserInfoTTL(eq(TOKEN), refEq(userInfo()));
+ verifyNoMoreInteractions(userInfoDAO);
+ verifyZeroInteractions(ldapUserDAO, verificationService);
+ }
+
+ @Test
+ public void logout() {
+
+ ldapAuthenticationService.logout(TOKEN);
+
+ verify(userInfoDAO).deleteUserInfo(TOKEN);
+ verifyNoMoreInteractions(userInfoDAO);
+ verifyZeroInteractions(ldapUserDAO);
+ }
+
+ private UserInfo userInfo() {
+ return new UserInfo(USER, null);
+ }
+
+ private UserCredentialDTO getCredentialDTO() {
+ final UserCredentialDTO dto = new UserCredentialDTO();
+ dto.setUsername(USER);
+ dto.setPassword(PASSWORD);
+ return dto;
+ }
+
+}
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@dlab.apache.org
For additional commands, e-mail: commits-help@dlab.apache.org