Repository: gravitee-io/graviteeio-access-management
Pull request #612 (2019-07-01 19:05:35)

fix(authenticate): Allow groups without members during authentication
fix gravitee-io/issues#2073


Patch:
diff --git a/gravitee-am-service/src/main/java/io/gravitee/am/service/impl/UserServiceImpl.java b/gravitee-am-service/src/main/java/io/gravitee/am/service/impl/UserServiceImpl.java
index 30904172be..0d2fd36330 100644
--- a/gravitee-am-service/src/main/java/io/gravitee/am/service/impl/UserServiceImpl.java
+++ b/gravitee-am-service/src/main/java/io/gravitee/am/service/impl/UserServiceImpl.java
@@ -293,7 +293,7 @@ public class UserServiceImpl implements UserService {
                     .flatMapSingle(entry -> groupRepository.findByIdIn(entry.getValue())
                             .map(groups -> groups
                                     .stream()
-                                    .filter(group -> group.getMembers().contains(user.getId()))
+                                    .filter(group -> group.getMembers() != null && group.getMembers().contains(user.getId()))
                                     .findFirst())
                             .map(optionalGroup -> optionalGroup.isPresent() ? Optional.of(entry.getKey()) : Optional.<String>empty()))
                     .toList()
diff --git a/gravitee-am-ui/build.json b/gravitee-am-ui/build.json
index 3f1ed722a5..b9d979295e 100644
--- a/gravitee-am-ui/build.json
+++ b/gravitee-am-ui/build.json
@@ -1,3 +1,3 @@
 {
-    "version": "2.7.1"
+    "version": "2.8.0-SNAPSHOT"
 }
diff --git a/gravitee-am-ui/package.json b/gravitee-am-ui/package.json
index 7a350cd401..0550282adb 100644
--- a/gravitee-am-ui/package.json
+++ b/gravitee-am-ui/package.json
@@ -1,6 +1,6 @@
 {
   "name": "gravitee-am-webui",
-  "version": "2.7.1",
+  "version": "2.8.0-SNAPSHOT",
   "license": "Apache-2.0",
   "scripts": {
     "ng": "ng",


Test patch:
diff --git a/gravitee-am-service/src/test/java/io/gravitee/am/service/UserServiceTest.java b/gravitee-am-service/src/test/java/io/gravitee/am/service/UserServiceTest.java
index d83c2bba3f..58612c32cd 100644
--- a/gravitee-am-service/src/test/java/io/gravitee/am/service/UserServiceTest.java
+++ b/gravitee-am-service/src/test/java/io/gravitee/am/service/UserServiceTest.java
@@ -15,9 +15,11 @@
  */
 package io.gravitee.am.service;
 
+import io.gravitee.am.model.Group;
 import io.gravitee.am.model.User;
 import io.gravitee.am.model.common.Page;
 import io.gravitee.am.repository.exceptions.TechnicalException;
+import io.gravitee.am.repository.management.api.GroupRepository;
 import io.gravitee.am.repository.management.api.UserRepository;
 import io.gravitee.am.service.exception.TechnicalManagementException;
 import io.gravitee.am.service.exception.UserAlreadyExistsException;
@@ -36,8 +38,7 @@ import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.runners.MockitoJUnitRunner;
 
-import java.util.Collections;
-import java.util.Set;
+import java.util.*;
 
 import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.*;
@@ -55,6 +56,9 @@ public class UserServiceTest {
     @Mock
     private UserRepository userRepository;
 
+    @Mock
+    private GroupRepository groupRepository;
+
     private final static String DOMAIN = "domain1";
 
     @Test
@@ -288,4 +292,77 @@ public class UserServiceTest {
 
         verify(userRepository, never()).delete("my-user");
     }
+
+    @Test
+    public void shouldFindOrCreate_CreateEmptyUser() {
+        String domain = "Domain";
+        String username = "foo";
+        String source = "SRC";
+        io.gravitee.am.identityprovider.api.User user = mock(io.gravitee.am.identityprovider.api.User.class);
+        when(user.getUsername()).thenReturn(username);
+        HashMap<String, Object> additionalInformation = new HashMap<>();
+        additionalInformation.put("source", source);
+        when(user.getAdditionalInformation()).thenReturn(additionalInformation);
+        when(userRepository.findByDomainAndUsernameAndSource(domain, username, source)).thenReturn(Maybe.empty());
+        when(userRepository.create(any())).thenReturn(Single.just(mock(User.class)));
+
+        TestObserver testObserver = userService.findOrCreate(domain, user).test();
+        testObserver.awaitTerminalEvent();
+
+        testObserver.assertComplete();
+        testObserver.assertNoErrors();
+        verify(userRepository, times(1)).create(any());
+        verify(userRepository, never()).update(any());
+    }
+
+    @Test
+    public void shouldFindOrCreate_UpdateKnownUser() {
+        String domain = "Domain";
+        String username = "foo";
+        String source = "SRC";
+        io.gravitee.am.identityprovider.api.User user = mock(io.gravitee.am.identityprovider.api.User.class);
+        when(user.getUsername()).thenReturn(username);
+        HashMap<String, Object> additionalInformation = new HashMap<>();
+        additionalInformation.put("source", source);
+        when(user.getAdditionalInformation()).thenReturn(additionalInformation);
+        when(userRepository.findByDomainAndUsernameAndSource(domain, username, source)).thenReturn(Maybe.just(mock(User.class)));
+        when(userRepository.update(any())).thenReturn(Single.just(mock(User.class)));
+
+        TestObserver testObserver = userService.findOrCreate(domain, user).test();
+        testObserver.awaitTerminalEvent();
+
+        testObserver.assertComplete();
+        testObserver.assertNoErrors();
+        verify(userRepository, never()).create(any());
+        verify(userRepository, times(1)).update(any());
+    }
+
+    @Test
+    public void shouldFindOrCreate_UpdateKnownUserWithEmptyGroup() {
+        String domain = "Domain";
+        String username = "foo";
+        String source = "SRC";
+        io.gravitee.am.identityprovider.api.User user = mock(io.gravitee.am.identityprovider.api.User.class);
+        when(user.getUsername()).thenReturn(username);
+        HashMap<String, Object> additionalInformation = new HashMap<>();
+        additionalInformation.put("source", source);
+        Map<String, List<String>> groupMapping = new HashMap<>();
+        groupMapping.put("foo", Collections.singletonList("bar"));
+        additionalInformation.put("_RESERVED_AM_GROUP_MAPPING_", groupMapping);
+        when(user.getAdditionalInformation()).thenReturn(additionalInformation);
+        User existingUser = mock(User.class);
+        when(userRepository.findByDomainAndUsernameAndSource(domain, username, source)).thenReturn(Maybe.just(existingUser));
+        when(userRepository.update(any())).thenReturn(Single.just(mock(User.class)));
+        Group group = mock(Group.class);
+        when(group.getMembers()).thenReturn(null);
+        when(groupRepository.findByIdIn(any())).thenReturn(Single.just(Collections.singletonList(group)));
+
+        TestObserver testObserver = userService.findOrCreate(domain, user).test();
+        testObserver.awaitTerminalEvent();
+
+        testObserver.assertComplete();
+        testObserver.assertNoErrors();
+        verify(userRepository, never()).create(any());
+        verify(userRepository, times(1)).update(any());
+    }
 }