KEYCLOAK-6803 Prevent duplicating required actions in JPA user storage

This commit is contained in:
Hynek Mlnarik 2018-09-03 14:11:32 +02:00 committed by Hynek Mlnařík
parent f0ba8f6591
commit 5fe1905e4b
2 changed files with 65 additions and 8 deletions

View file

@ -47,6 +47,7 @@ import org.keycloak.storage.jpa.entity.FederatedUserCredentialAttributeEntity;
import org.keycloak.storage.jpa.entity.FederatedUserCredentialEntity;
import org.keycloak.storage.jpa.entity.FederatedUserGroupMembershipEntity;
import org.keycloak.storage.jpa.entity.FederatedUserRequiredActionEntity;
import org.keycloak.storage.jpa.entity.FederatedUserRequiredActionEntity.Key;
import org.keycloak.storage.jpa.entity.FederatedUserRoleMappingEntity;
import javax.persistence.EntityManager;
@ -494,14 +495,16 @@ public class JpaUserFederatedStorageProvider implements
@Override
public void addRequiredAction(RealmModel realm, String userId, String action) {
createIndex(realm, userId);
FederatedUserRequiredActionEntity entity = new FederatedUserRequiredActionEntity();
entity.setUserId(userId);
entity.setRealmId(realm.getId());
entity.setStorageProviderId(new StorageId(userId).getProviderId());
entity.setAction(action);
em.persist(entity);
Key key = new FederatedUserRequiredActionEntity.Key(userId, action);
if (em.find(FederatedUserRequiredActionEntity.class, key) == null) {
createIndex(realm, userId);
FederatedUserRequiredActionEntity entity = new FederatedUserRequiredActionEntity();
entity.setUserId(userId);
entity.setRealmId(realm.getId());
entity.setStorageProviderId(new StorageId(userId).getProviderId());
entity.setAction(action);
em.persist(entity);
}
}
@Override

View file

@ -51,7 +51,17 @@ import org.keycloak.testsuite.admin.ApiUtil;
import org.keycloak.testsuite.federation.UserMapStorage;
import org.keycloak.testsuite.federation.UserMapStorageFactory;
import org.keycloak.testsuite.federation.UserPropertyFileStorageFactory;
import org.keycloak.testsuite.pages.LoginPage;
import org.keycloak.testsuite.pages.RegisterPage;
import org.keycloak.testsuite.pages.VerifyEmailPage;
import org.keycloak.testsuite.runonserver.RunOnServerDeployment;
import org.keycloak.testsuite.updaters.RealmAttributeUpdater;
import org.keycloak.testsuite.util.GreenMailRule;
import java.util.Map;
import javax.mail.internet.MimeMessage;
import org.jboss.arquillian.graphene.page.Page;
import org.junit.Rule;
import static org.keycloak.testsuite.actions.RequiredActionEmailVerificationTest.getPasswordResetEmailLink;
import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlDoesntStartWith;
import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWith;
@ -65,6 +75,18 @@ public class UserStorageTest extends AbstractAuthTest {
private String propProviderROId;
private String propProviderRWId;
@Rule
public GreenMailRule greenMail = new GreenMailRule();
@Page
protected LoginPage loginPage;
@Page
protected RegisterPage registerPage;
@Page
protected VerifyEmailPage verifyEmailPage;
private static final File CONFIG_DIR = new File(System.getProperty("auth.server.config.dir", ""));
@Before
@ -267,6 +289,38 @@ public class UserStorageTest extends AbstractAuthTest {
assertFalse(foundRole);
}
@Test
public void testRegisterWithRequiredEmail() throws Exception {
try (AutoCloseable c = new RealmAttributeUpdater(testRealmResource())
.updateWith(r -> {
Map<String, String> config = new HashMap<>();
config.put("from", "auto@keycloak.org");
config.put("host", "localhost");
config.put("port", "3025");
r.setSmtpServer(config);
r.setRegistrationAllowed(true);
r.setVerifyEmail(true);
})
.update()) {
testRealmAccountPage.navigateTo();
loginPage.clickRegister();
registerPage.register("firstName", "lastName", "email@mail.com", "verifyEmail", "password", "password");
verifyEmailPage.assertCurrent();
Assert.assertEquals(1, greenMail.getReceivedMessages().length);
MimeMessage message = greenMail.getReceivedMessages()[0];
String verificationUrl = getPasswordResetEmailLink(message);
driver.navigate().to(verificationUrl.trim());
testRealmAccountPage.assertCurrent();
}
}
public UserResource user(String userId) {
return testRealmResource().users().get(userId);
}