Skip to content

Commit

Permalink
DROOLS-7558 : SSH clone: Fetch roles for the logged in user from the …
Browse files Browse the repository at this point in the history
…realm itself (#1404)
  • Loading branch information
Rikkola authored Dec 8, 2023
1 parent a3396ef commit c463ad5
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,52 +19,52 @@
import javax.enterprise.inject.Alternative;
import javax.inject.Inject;

import org.jboss.errai.security.shared.api.Role;
import org.jboss.errai.security.shared.api.RoleImpl;
import org.jboss.errai.security.shared.api.identity.User;
import org.jboss.errai.security.shared.api.identity.UserImpl;
import org.jboss.errai.security.shared.exception.FailedAuthenticationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.uberfire.security.WorkbenchUserManager;
import org.wildfly.security.auth.server.RealmUnavailableException;
import org.wildfly.security.auth.server.SecurityDomain;
import org.wildfly.security.evidence.Evidence;
import org.wildfly.security.evidence.PasswordGuessEvidence;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/**
* Default implementation of {@link ElytronIdentityHelper}, it relies in the platform {@link SecurityDomain} to obtain
* the user credentials
* Default implementation of {@link ElytronIdentityHelper}, it relies in the platform {@link SecurityDomain} to obtain the user credentials
*/
@Alternative
public class DefaultElytronIdentityHelper implements ElytronIdentityHelper {

private static final Logger logger = LoggerFactory.getLogger(DefaultElytronIdentityHelper.class);

private final WorkbenchUserManager workbenchUserManager;

@Inject
public DefaultElytronIdentityHelper(final WorkbenchUserManager workbenchUserManager) {
this.workbenchUserManager = workbenchUserManager;
public DefaultElytronIdentityHelper() {
}

@Override
public User getIdentity(String userName, String password) {
public User getIdentity(final String userName, final String password) {

try {
if (login(userName, password)) {
return workbenchUserManager.getUser(userName);
}
final Evidence evidence = new PasswordGuessEvidence(password.toCharArray());
final Iterator<String> userRoles = login(userName, evidence);
final Collection<Role> roles = new ArrayList<>();
userRoles.forEachRemaining(role -> roles.add(new RoleImpl(role)));

return new UserImpl(userName, roles);
} catch (Exception ex) {
logger.debug("Identity provided for '{}' not valid", userName);
}

throw new FailedAuthenticationException();
}

protected boolean login(String userName, String password) {
final Evidence evidence = new PasswordGuessEvidence(password.toCharArray());
try {
SecurityDomain.getCurrent().authenticate(userName, evidence);
return true;
} catch (Exception e) {
throw new FailedAuthenticationException(e.getMessage());
}
protected Iterator<String> login(final String userName, final Evidence evidence) throws RealmUnavailableException {
return SecurityDomain.getCurrent().authenticate(userName, evidence).getRoles().iterator();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,18 @@
import javax.enterprise.inject.Produces;
import javax.inject.Inject;

import org.uberfire.security.WorkbenchUserManager;

/**
* Default producer for {@link ElytronIdentityHelper}
*/
@ApplicationScoped
public class ElytronIdentityHelperProducer {

private final WorkbenchUserManager workbenchUserManager;

@Inject
public ElytronIdentityHelperProducer(WorkbenchUserManager workbenchUserManager) {
this.workbenchUserManager = workbenchUserManager;
public ElytronIdentityHelperProducer() {
}

@Produces
public ElytronIdentityHelper getDefaultElytronIdentityHelper() {
return new DefaultElytronIdentityHelper(workbenchUserManager);
return new DefaultElytronIdentityHelper();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,27 @@

package org.uberfire.backend.server.security.elytron;

import org.jboss.errai.security.shared.api.RoleImpl;
import org.jboss.errai.security.shared.api.identity.User;
import org.jboss.errai.security.shared.exception.FailedAuthenticationException;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.uberfire.security.WorkbenchUserManager;
import org.wildfly.security.auth.server.RealmUnavailableException;
import org.wildfly.security.auth.server.SecurityIdentity;
import org.wildfly.security.authz.Roles;
import org.wildfly.security.evidence.Evidence;

import java.util.ArrayList;
import java.util.Iterator;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.*;

@RunWith(MockitoJUnitRunner.class)
public class DefaultElytronIdentityHelperTest {
Expand All @@ -38,37 +45,49 @@ public class DefaultElytronIdentityHelperTest {
private static final String PASSWORD = "password";

private DefaultElytronIdentityHelper helper;

@Mock
private WorkbenchUserManager workbenchUserManager;
private ArrayList<String> roles = new ArrayList<>();

@Before
public void init() {
helper = spy(new DefaultElytronIdentityHelper(workbenchUserManager) {
helper = spy(new DefaultElytronIdentityHelper() {
@Override
protected boolean login(String userName, String password) {
return true;
protected Iterator<String> login(String userName, Evidence evidence) {
return roles.iterator();
}
});
}

@After
public void after() {
roles.clear();
}

@Test
public void testSuccessfulLogin() {
public void testSuccessfulLogin() throws RealmUnavailableException {
roles.add("admin");
roles.add("rest-all");

when(helper.login(eq(USERNAME), eq(PASSWORD))).thenReturn(true);
final User identity = helper.getIdentity(USERNAME, PASSWORD);

helper.getIdentity(USERNAME, PASSWORD);
assertEquals(USERNAME, identity.getIdentifier());
assertTrue(identity.getRoles().contains(new RoleImpl("admin")));
assertTrue(identity.getRoles().contains(new RoleImpl("rest-all")));
assertEquals(2, identity.getRoles().size());
}

@Test
public void testSuccessfulLoginNoRoles() throws RealmUnavailableException {

verify(workbenchUserManager).getUser(USERNAME);
final User identity = helper.getIdentity(USERNAME, PASSWORD);

assertTrue(identity.getRoles().isEmpty());
}

@Test(expected = FailedAuthenticationException.class)
public void testUnSuccessfulLogin() {
public void testUnSuccessfulLogin() throws RealmUnavailableException {

doThrow(new RuntimeException("whatever error")).when(helper).login(eq(USERNAME), eq(PASSWORD));
doThrow(new RuntimeException("whatever error")).when(helper).login(any(), any());

helper.getIdentity(USERNAME, PASSWORD);

verify(workbenchUserManager, never()).getUser(USERNAME);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,9 @@ public class ElytronIdentityHelperProducerTest {

private ElytronIdentityHelperProducer producer;

@Mock
private WorkbenchUserManager workbenchUserManager;

@Before
public void init() {
producer = new ElytronIdentityHelperProducer(workbenchUserManager);
producer = new ElytronIdentityHelperProducer();
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
import org.uberfire.backend.server.security.elytron.ElytronIdentityHelperProducer;
import org.uberfire.ext.security.management.keycloak.KCAdapterUserManagementService;
import org.uberfire.ext.security.management.keycloak.KCCredentialsUserManagementService;
import org.uberfire.security.WorkbenchUserManager;

/**
* Produces {@link ElytronIdentityHelper} based on the user management service configured on the
Expand All @@ -45,8 +44,7 @@ public class KeyCloakElytronIdentityHelperProducer extends ElytronIdentityHelper
private boolean isKeyCloak;

@Inject
public KeyCloakElytronIdentityHelperProducer(WorkbenchUserManager workbenchUserManager) {
super(workbenchUserManager);
public KeyCloakElytronIdentityHelperProducer() {
}

@PostConstruct
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,11 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.uberfire.backend.server.security.elytron.DefaultElytronIdentityHelper;
import org.uberfire.backend.server.security.elytron.ElytronIdentityHelper;
import org.uberfire.ext.security.management.keycloak.KCAdapterUserManagementService;
import org.uberfire.ext.security.management.keycloak.KCCredentialsUserManagementService;
import org.uberfire.security.WorkbenchUserManager;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
Expand All @@ -35,14 +33,11 @@
@RunWith(MockitoJUnitRunner.class)
public class KeyCloakElytronIdentityHelperProducerTest {

@Mock
private WorkbenchUserManager workbenchUserManager;

private KeyCloakElytronIdentityHelperProducer producer;

@Before
public void init() {
producer = new KeyCloakElytronIdentityHelperProducer(workbenchUserManager);
producer = new KeyCloakElytronIdentityHelperProducer();
}

@Test
Expand Down

0 comments on commit c463ad5

Please sign in to comment.