Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DROOLS-7558 : SSH clone: Fetch roles for the logged in user from the realm itself #1404

Merged
merged 1 commit into from
Dec 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading