[KEYCLOAK-4207] SSSD Provider - NullPointerException when mail attribute is not filled
This commit is contained in:
parent
c4cce147e2
commit
9fb46a7b1c
4 changed files with 91 additions and 61 deletions
|
@ -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 <a href="mailto:bruno@abstractj.org">Bruno Oliveira</a>.
|
||||
*/
|
||||
@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);
|
||||
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
Loading…
Reference in a new issue