keycloak-uncached

[KEYCLOAK-4207] SSSD Provider - NullPointerException when

1/13/2017 5:35:55 PM

Details

diff --git a/federation/sssd/src/main/java/org/keycloak/federation/sssd/api/Sssd.java b/federation/sssd/src/main/java/org/keycloak/federation/sssd/api/Sssd.java
index 308d596..e0a7427 100644
--- a/federation/sssd/src/main/java/org/keycloak/federation/sssd/api/Sssd.java
+++ b/federation/sssd/src/main/java/org/keycloak/federation/sssd/api/Sssd.java
@@ -23,6 +23,7 @@ import org.freedesktop.dbus.Variant;
 import org.freedesktop.dbus.exceptions.DBusException;
 import org.freedesktop.sssd.infopipe.InfoPipe;
 import org.jboss.logging.Logger;
+import org.keycloak.models.UserModel;
 
 import java.util.Arrays;
 import java.util.List;
@@ -68,20 +69,7 @@ public class Sssd {
         return null;
     }
 
-    public Map<String, Variant> getUserAttributes() {
-        String[] attr = {"mail", "givenname", "sn", "telephoneNumber"};
-        Map<String, Variant> attributes = null;
-        try {
-            InfoPipe infoPipe = dBusConnection.getRemoteObject(InfoPipe.BUSNAME, InfoPipe.OBJECTPATH, InfoPipe.class);
-            attributes = infoPipe.getUserAttributes(username, Arrays.asList(attr));
-        } catch (Exception e) {
-            throw new SSSDException("Failed to retrieve user's attributes. Check if SSSD service is active.");
-        }
-
-        return attributes;
-    }
-
-    public List<String> getUserGroups() {
+    public List<String> getGroups() {
         List<String> userGroups;
         try {
             InfoPipe infoPipe = dBusConnection.getRemoteObject(InfoPipe.BUSNAME, InfoPipe.OBJECTPATH, InfoPipe.class);
@@ -113,4 +101,70 @@ public class Sssd {
         return sssdAvailable;
     }
 
+    public User getUser() {
+
+        String[] attr = {"mail", "givenname", "sn", "telephoneNumber"};
+        User user = null;
+        try {
+            InfoPipe infoPipe = dBusConnection.getRemoteObject(InfoPipe.BUSNAME, InfoPipe.OBJECTPATH, InfoPipe.class);
+            user = new User(infoPipe.getUserAttributes(username, Arrays.asList(attr)));
+        } catch (Exception e) {
+            throw new SSSDException("Failed to retrieve user's attributes. Check if SSSD service is active.");
+        }
+        return user;
+    }
+
+    public class User {
+
+        private final String email;
+        private final String firstName;
+        private final String lastName;
+
+        public User(Map<String, Variant> userAttributes) {
+            this.email = getRawAttribute(userAttributes.get("mail"));
+            this.firstName = getRawAttribute(userAttributes.get("givenname"));
+            this.lastName = getRawAttribute(userAttributes.get("sn"));
+
+        }
+
+        public String getEmail() {
+            return email;
+        }
+
+        public String getFirstName() {
+            return firstName;
+        }
+
+        public String getLastName() {
+            return lastName;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o == null) return false;
+
+            UserModel userModel = (UserModel) o;
+            if (firstName != null && !firstName.equals(userModel.getFirstName())) {
+                return false;
+            }
+            if (lastName != null && !lastName.equals(userModel.getLastName())) {
+                return false;
+            }
+            if (email != null) {
+                return email.equals(userModel.getEmail());
+            }
+            if (email != userModel.getEmail()) {
+                return false;
+            }
+            return true;
+        }
+
+        @Override
+        public int hashCode() {
+            int result = email != null ? email.hashCode() : 0;
+            result = 31 * result + (firstName != null ? firstName.hashCode() : 0);
+            result = 31 * result + (lastName != null ? lastName.hashCode() : 0);
+            return result;
+        }
+    }
 }
diff --git a/federation/sssd/src/main/java/org/keycloak/federation/sssd/SSSDFederationProvider.java b/federation/sssd/src/main/java/org/keycloak/federation/sssd/SSSDFederationProvider.java
index 7d43c89..709eac7 100755
--- a/federation/sssd/src/main/java/org/keycloak/federation/sssd/SSSDFederationProvider.java
+++ b/federation/sssd/src/main/java/org/keycloak/federation/sssd/SSSDFederationProvider.java
@@ -17,13 +17,13 @@
 
 package org.keycloak.federation.sssd;
 
-import org.freedesktop.dbus.Variant;
 import org.jboss.logging.Logger;
 import org.keycloak.credential.CredentialInput;
 import org.keycloak.credential.CredentialInputUpdater;
 import org.keycloak.credential.CredentialInputValidator;
 import org.keycloak.credential.CredentialModel;
 import org.keycloak.federation.sssd.api.Sssd;
+import org.keycloak.federation.sssd.api.Sssd.User;
 import org.keycloak.federation.sssd.impl.PAMAuthenticator;
 import org.keycloak.models.*;
 import org.keycloak.models.utils.KeycloakModelUtils;
@@ -34,7 +34,6 @@ import org.keycloak.storage.user.UserLookupProvider;
 
 import java.util.Collections;
 import java.util.HashSet;
-import java.util.Map;
 import java.util.Set;
 
 /**
@@ -112,14 +111,14 @@ public class SSSDFederationProvider implements UserStorageProvider,
 
     protected UserModel importUserToKeycloak(RealmModel realm, String username) {
         Sssd sssd = new Sssd(username);
-        Map<String, Variant> sssdUser = sssd.getUserAttributes();
+        User sssdUser = sssd.getUser();
         logger.debugf("Creating SSSD user: %s to local Keycloak storage", username);
         UserModel user = session.userLocalStorage().addUser(realm, username);
         user.setEnabled(true);
-        user.setEmail(Sssd.getRawAttribute(sssdUser.get("mail")));
-        user.setFirstName(Sssd.getRawAttribute(sssdUser.get("givenname")));
-        user.setLastName(Sssd.getRawAttribute(sssdUser.get("sn")));
-        for (String s : sssd.getUserGroups()) {
+        user.setEmail(sssdUser.getEmail());
+        user.setFirstName(sssdUser.getFirstName());
+        user.setLastName(sssdUser.getLastName());
+        for (String s : sssd.getGroups()) {
             GroupModel group = KeycloakModelUtils.findGroupByPath(realm, "/" + s);
             if (group == null) {
                 group = session.realms().createGroup(realm, s);
@@ -158,8 +157,8 @@ public class SSSDFederationProvider implements UserStorageProvider,
     }
 
     public boolean isValid(RealmModel realm, UserModel local) {
-        Map<String, Variant> attributes = new Sssd(local.getUsername()).getUserAttributes();
-        return Sssd.getRawAttribute(attributes.get("mail")).equalsIgnoreCase(local.getEmail());
+        User user = new Sssd(local.getUsername()).getUser();
+        return user.equals(local);
     }
 
     @Override
diff --git a/testsuite/integration-arquillian/tests/other/sssd/src/test/java/org/keycloak/testsuite/sssd/SSSDTest.java b/testsuite/integration-arquillian/tests/other/sssd/src/test/java/org/keycloak/testsuite/sssd/SSSDTest.java
index 91858c9..aa83e50 100644
--- a/testsuite/integration-arquillian/tests/other/sssd/src/test/java/org/keycloak/testsuite/sssd/SSSDTest.java
+++ b/testsuite/integration-arquillian/tests/other/sssd/src/test/java/org/keycloak/testsuite/sssd/SSSDTest.java
@@ -30,7 +30,9 @@ public class SSSDTest extends AbstractKeycloakTest {
     private static final String USERNAME = "emily";
     private static final String PASSWORD = "emily123";
     private static final String DISABLED_USER = "david";
-    private static final String DISABLED_USER_PASSWORD = "emily123";
+    private static final String DISABLED_USER_PASSWORD = "david123";
+    private static final String NO_EMAIL_USER = "bart";
+    private static final String NO_EMAIL_USER_PASSWORD = "bart123";
 
     private static final String DEFINITELY_NOT_PASSWORD = "not" + PASSWORD;
 
@@ -102,12 +104,12 @@ public class SSSDTest extends AbstractKeycloakTest {
 
     @Test
     public void testAdmin() {
-        log.debug("Testing wrong password for user " + ADMIN_USERNAME);
+        log.debug("Testing password for user " + ADMIN_USERNAME);
 
         driver.navigate().to(getAccountUrl());
         Assert.assertEquals("Browser should be on login page now", "Log in to " + REALM_NAME, driver.getTitle());
         accountLoginPage.login(ADMIN_USERNAME, ADMIN_PASSWORD);
-        Assert.assertEquals("Unexpected error when handling authentication request to identity provider.", accountLoginPage.getInstruction());
+        Assert.assertTrue(profilePage.isCurrent());
     }
 
     @Test
@@ -122,6 +124,16 @@ public class SSSDTest extends AbstractKeycloakTest {
     }
 
     @Test
+    public void testExistingUserWithNoEmailLogIn() {
+        log.debug("Testing correct password, but no e-mail provided");
+
+        driver.navigate().to(getAccountUrl());
+        Assert.assertEquals("Browser should be on login page now", "Log in to " + REALM_NAME, driver.getTitle());
+        accountLoginPage.login(NO_EMAIL_USER, NO_EMAIL_USER_PASSWORD);
+        Assert.assertTrue(profilePage.isCurrent());
+    }
+
+    @Test
     public void testDeleteSSSDFederationProvider() {
         log.debug("Testing correct password");