diff --git a/federation/sssd/src/main/java/org/freedesktop/sssd/infopipe/User.java b/federation/sssd/src/main/java/org/freedesktop/sssd/infopipe/User.java deleted file mode 100644 index 896b80a0f6..0000000000 --- a/federation/sssd/src/main/java/org/freedesktop/sssd/infopipe/User.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2016 Red Hat, Inc. and/or its affiliates - * and other contributors as indicated by the @author tags. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.freedesktop.sssd.infopipe; - -import org.freedesktop.dbus.DBusInterface; -import org.freedesktop.dbus.DBusInterfaceName; -import org.freedesktop.dbus.DBusMemberName; - -/** - * @author Bruno Oliveira. - */ -@DBusInterfaceName("org.freedesktop.sssd.infopipe.Users") -public interface User extends DBusInterface { - - String OBJECTPATH = "/org/freedesktop/sssd/infopipe/Users"; - - @DBusMemberName("FindByCertificate") - DBusInterface findByCertificate(String pem_cert); - -} 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 7d43c89ce8..709eac7e64 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 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 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/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 308d596122..e0a7427d2b 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 getUserAttributes() { - String[] attr = {"mail", "givenname", "sn", "telephoneNumber"}; - Map 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 getUserGroups() { + public List getGroups() { List 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 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/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 91858c929c..aa83e50d4a 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 @@ -121,6 +123,16 @@ public class SSSDTest extends AbstractKeycloakTest { testUserGroups(); } + @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");