Skip to content

Commit af93f47

Browse files
committed
Allow the dataset to generate users with a limited number of unique passwords
Closes #1237 Signed-off-by: Ryan Emerson <[email protected]>
1 parent 217d700 commit af93f47

File tree

2 files changed

+31
-4
lines changed

2 files changed

+31
-4
lines changed

dataset/src/main/java/org/keycloak/benchmark/dataset/DatasetResourceProvider.java

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.keycloak.benchmark.dataset.config.DatasetException;
3434
import org.keycloak.benchmark.dataset.organization.OrganizationProvisioner;
3535
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
36+
import org.keycloak.credential.hash.PasswordHashProvider;
3637
import org.keycloak.events.Event;
3738
import org.keycloak.events.EventStoreProvider;
3839
import org.keycloak.events.EventType;
@@ -52,6 +53,7 @@
5253
import org.keycloak.models.UserModel;
5354
import org.keycloak.models.UserSessionModel;
5455
import org.keycloak.models.cache.CacheRealmProvider;
56+
import org.keycloak.models.credential.PasswordCredentialModel;
5557
import org.keycloak.models.utils.KeycloakModelUtils;
5658
import org.keycloak.protocol.oidc.OIDCAdvancedConfigWrapper;
5759
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
@@ -435,6 +437,8 @@ private void createUsersImpl(Task task, DatasetConfig config, RealmModel realm)
435437
}
436438

437439
private void addUserCreationTasks(RealmContext context, Task task, DatasetConfig config, ExecutorHelper executor, int startIndex, int usersCount) {
440+
// Initialize password credentials if unique-credentials-count is configured
441+
List<PasswordCredentialModel> credentials = initializeCredentials(config, context);
438442

439443
for (int i = startIndex; i < (startIndex + usersCount); i += config.getUsersPerTransaction()) {
440444
final int usersStartIndex = i;
@@ -446,7 +450,7 @@ private void addUserCreationTasks(RealmContext context, Task task, DatasetConfig
446450
executor.addTaskRunningInTransaction(session -> {
447451
KeycloakModelUtils.cloneContextRealmClientToSession(baseSession.getContext(), session);
448452

449-
createUsers(context, session, usersStartIndex, endIndex);
453+
createUsers(context, session, usersStartIndex, endIndex, credentials);
450454

451455
task.debug(logger, "Created users in realm %s from %d to %d", context.getRealm().getName(), usersStartIndex, endIndex);
452456

@@ -457,6 +461,17 @@ private void addUserCreationTasks(RealmContext context, Task task, DatasetConfig
457461
}
458462
}
459463

464+
private List<PasswordCredentialModel> initializeCredentials(DatasetConfig config, RealmContext context) {
465+
PasswordPolicy policy = context.getRealm().getPasswordPolicy();
466+
PasswordHashProvider hash = policy.getHashAlgorithm() != null ?
467+
baseSession.getProvider(PasswordHashProvider.class, policy.getHashAlgorithm()) :
468+
baseSession.getProvider(PasswordHashProvider.class);
469+
470+
return IntStream.range(0, config.getUniqueCredentialCount())
471+
.boxed()
472+
.map(i -> hash.encodedCredential("password-" + i, policy.getHashIterations()))
473+
.toList();
474+
}
460475

461476
@GET
462477
@Path("/create-events")
@@ -1130,7 +1145,7 @@ private void createClients(RealmContext context, Task task, KeycloakSession sess
11301145
}
11311146

11321147
// Worker task to be triggered by single executor thread
1133-
private void createUsers(RealmContext context, KeycloakSession session, int startIndex, int endIndex) {
1148+
private void createUsers(RealmContext context, KeycloakSession session, int startIndex, int endIndex, List<PasswordCredentialModel> credentials) {
11341149
// Refresh the realm
11351150
RealmModel realm = session.realms().getRealm(context.getRealm().getId());
11361151
DatasetConfig config = context.getConfig();
@@ -1147,8 +1162,13 @@ private void createUsers(RealmContext context, KeycloakSession session, int star
11471162
user.setLastName(username + "-last");
11481163
user.setEmail(username + String.format("@%s.com", realm.getName()));
11491164

1150-
String password = String.format("%s-password", username);
1151-
user.credentialManager().updateCredential(UserCredentialModel.password(password, false));
1165+
if (credentials.isEmpty()) {
1166+
String password = String.format("%s-password", username);
1167+
user.credentialManager().updateCredential(UserCredentialModel.password(password, false));
1168+
} else {
1169+
PasswordCredentialModel password = credentials.get(i % config.getUniqueCredentialCount());
1170+
user.credentialManager().createStoredCredential(password);
1171+
}
11521172

11531173
// Assign a role to a user if any exist in the realm
11541174
if (!context.getRealmRoles().isEmpty()) {

dataset/src/main/java/org/keycloak/benchmark/dataset/config/DatasetConfig.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,9 @@ public class DatasetConfig {
226226
@QueryParamIntFill(paramName = "identity-provider-mappers-count", operations = CREATE_ORGS)
227227
private int identityProviderMappersCount;
228228

229+
@QueryParamIntFill(paramName = "unique-credential-count", defaultValue = 0, operations = CREATE_USERS)
230+
private int uniqueCredentialCount;
231+
229232
// String representation of this configuration (cached here to not be computed in runtime)
230233
private String toString = "DatasetConfig []";
231234

@@ -432,4 +435,8 @@ public int getIdentityProvidersCount() {
432435
public int getIdentityProviderMappersCount() {
433436
return identityProviderMappersCount;
434437
}
438+
439+
public int getUniqueCredentialCount() {
440+
return uniqueCredentialCount;
441+
}
435442
}

0 commit comments

Comments
 (0)