Skip to content

Commit

Permalink
Improve RBAC data generator
Browse files Browse the repository at this point in the history
1. Add forget noise option: Added the capability to forget
roles based on a given percentage. This allows for
simulating scenarios where roles might be overlooked or
removed from the system.
2. Add addition noise option: Ability
 to add noise roles with a specified chance, enhancing
 the variability of generated data by introducing
 additional roles randomly.
  • Loading branch information
tchrapovic committed Apr 10, 2024
1 parent 5c04221 commit 765e6e9
Show file tree
Hide file tree
Showing 5 changed files with 153 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,17 @@ public class BaseGeneratorOptions {
public static final String P_INCLUDE_AUX = "-ia";
public static final String P_INCLUDE_AUX_LONG = "--include-aux";

public static final String P_FORGET_NOISE = "-fn";
public static final String P_FORGET_NOISE_LONG = "--forget-noise";

public static final String P_ADDITION_NOISE = "-an";
public static final String P_ADDITION_NOISE_LONG = "--addition-noise";

@Parameter(names = { P_ADDITION_NOISE, P_ADDITION_NOISE_LONG }, descriptionKey = "baseGeneratorOptions.forget.noise")
private int forgetNoise = 0;
@Parameter(names = { P_FORGET_NOISE, P_FORGET_NOISE_LONG }, descriptionKey = "baseGeneratorOptions.addition.noise")
private int additionNoise = 0;

@Parameter(names = { P_INCLUDE_AUX, P_INCLUDE_AUX_LONG }, descriptionKey = "baseGeneratorOptions.includeAux")
private boolean isAuxInclude = false;

Expand Down Expand Up @@ -104,4 +115,13 @@ public String getDivision() {
public boolean isAuxInclude() {
return isAuxInclude;
}

public int getForgetNoise() {
return forgetNoise;
}

public int getAdditionNoise() {
return additionNoise;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public void executeImport() {

if (generatorOptions.isTransform()) {
log.info("Make sure that RoleType objects is recomputed");
remakeUsersBusinessRoles(context, result, null, null);
remakeUsersBusinessRoles(context, result, generatorOptions, null, null);
}
}

Expand All @@ -85,6 +85,7 @@ private void initialObjectsImport(@NotNull RepositoryService repositoryService)
importPlanktonRoles(initialObjectsDefinition, repositoryService, result, log);
importMultipliedBasicRoles(initialObjectsDefinition, repositoryService, result, log);
importBusinessRoles(initialObjectsDefinition, repositoryService, result, log);
importNoiseRoles(initialObjectsDefinition, repositoryService, result, log);
log.info("Initial role objects imported");
}

Expand Down Expand Up @@ -149,6 +150,27 @@ private void importPlanktonRoles(
}
}

private void importNoiseRoles(
@NotNull InitialObjectsDefinition initialObjectsDefinition,
@NotNull RepositoryService repositoryService,
@NotNull OperationResult result,
@NotNull Log log) {
List<RoleType> rolesObjects = initialObjectsDefinition.getNoiseRolesObjects();
log.info("Importing noise roles: 0/{}", rolesObjects.size());
for (int i = 0; i < rolesObjects.size(); i++) {
log.info("Importing noise roles: {}/{}", i + 1, rolesObjects.size());
RoleType role = rolesObjects.get(i);
try {
repositoryService.addObject(role.asPrismObject(), null, result);
} catch (ObjectAlreadyExistsException e) {
log.warn("Role {} already exists", role.getName());
} catch (SchemaException e) {
log.error("Error adding role {}", role.getName(), e);
throw new RuntimeException(e);
}
}
}

private void importRole(
@NotNull RoleType role,
@NotNull RepositoryService repositoryService,
Expand Down Expand Up @@ -565,12 +587,14 @@ private void resolveContractors(int contractorsCount, RepositoryService reposito
*
* @param context The Ninja context.
* @param result The operation result used for tracking the operation.
* @param noise
* @param query The query for searching users.
* @param options The options for retrieving users.
* @throws RuntimeException If an error occurs during the process.
*/
public static void remakeUsersBusinessRoles(@NotNull NinjaContext context,
@NotNull OperationResult result,
GeneratorOptions generatorOptions,
@Nullable ObjectQuery query,
@Nullable Collection<SelectorOptions<GetOperationOptions>> options) {

Expand All @@ -579,7 +603,7 @@ public static void remakeUsersBusinessRoles(@NotNull NinjaContext context,
log.info("Replace business role for their inducements on users started");

ResultHandler<UserType> handler = (object, parentResult) -> {
executeChangesOnUser(result, object, repository, log);
executeChangesOnUser(result, object, generatorOptions, repository, log);
return true;
};

Expand All @@ -603,7 +627,12 @@ public static void remakeUsersBusinessRoles(@NotNull NinjaContext context,
* @param log The log used for logging the operation.
* @throws RuntimeException If an error occurs during the process.
*/
private static void executeChangesOnUser(@NotNull OperationResult result, @NotNull PrismObject<UserType> object, RepositoryService repository, Log log) {
private static void executeChangesOnUser(
@NotNull OperationResult result,
@NotNull PrismObject<UserType> object,
GeneratorOptions generatorOptions,
RepositoryService repository,
Log log) {
String userOid = object.getOid();
PolyString name = object.getName();
if (name == null) {
Expand Down Expand Up @@ -633,7 +662,19 @@ private static void executeChangesOnUser(@NotNull OperationResult result, @NotNu
List<ItemDelta<?, ?>> modifications = new ArrayList<>();
try {

RoleType noiseRole = getNoiseRole(generatorOptions.getAdditionNoise());
if (noiseRole != null) {
modifications.add(PrismContext.get().deltaFor(UserType.class)
.item(UserType.F_ASSIGNMENT).add(createRoleAssignment(noiseRole.getOid()))
.asItemDelta());
}

for (AssignmentType assignmentType : inducement) {
boolean allowed = isExcluded(generatorOptions.getForgetNoise());
if (allowed) {
continue;
}

modifications.add(PrismContext.get().deltaFor(UserType.class)
.item(UserType.F_ASSIGNMENT).add(createRoleAssignment(assignmentType.getTargetRef().getOid()))
.asItemDelta());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/
package com.evolveum.midpoint.ninja.action.mining.generator.context;

import static com.evolveum.midpoint.ninja.action.mining.generator.object.InitialObjectsDefinition.getNoiseRolesObjects;
import static com.evolveum.midpoint.schema.util.FocusTypeUtil.createArchetypeAssignment;
import static com.evolveum.midpoint.schema.util.FocusTypeUtil.createTargetAssignment;

Expand Down Expand Up @@ -41,7 +42,8 @@ public class RbacGeneratorUtils {
* @return The randomly selected location business role.
*/
protected static @NotNull InitialObjectsDefinition.LocationInitialBusinessRole getRandomLocationBusinessRole() {
InitialObjectsDefinition.LocationInitialBusinessRole[] roles = InitialObjectsDefinition.LocationInitialBusinessRole.values();
InitialObjectsDefinition.LocationInitialBusinessRole[] roles = InitialObjectsDefinition
.LocationInitialBusinessRole.values();
Random random = new Random();
return roles[random.nextInt(roles.length)];
}
Expand All @@ -63,7 +65,8 @@ public class RbacGeneratorUtils {
* @return The randomly selected plankton abstract role.
*/
protected static @NotNull InitialObjectsDefinition.PlanktonApplicationBusinessAbstractRole getRandomPlanktonRole() {
InitialObjectsDefinition.PlanktonApplicationBusinessAbstractRole[] roles = InitialObjectsDefinition.PlanktonApplicationBusinessAbstractRole.values();
InitialObjectsDefinition.PlanktonApplicationBusinessAbstractRole[] roles = InitialObjectsDefinition
.PlanktonApplicationBusinessAbstractRole.values();
Random random = new Random();
return roles[random.nextInt(roles.length)];
}
Expand Down Expand Up @@ -259,4 +262,27 @@ static void resolveAuxRoles(@NotNull UserType user) {
}
}

/**
* Resolve chance.
*
* @param chance The chance to resolve.
* @return True if the chance is resolved, false otherwise.
*/
public static boolean isExcluded(int chance) {
Random random = new Random();
return random.nextInt(100) < chance;
}

public static @Nullable RoleType getNoiseRole(int chance) {
Random random = new Random();
boolean b = random.nextInt(100) < chance;
List<RoleType> noiseRolesObjects = getNoiseRolesObjects();

if (b && !noiseRolesObjects.isEmpty()) {
int randomIndex = random.nextInt(noiseRolesObjects.size());
return noiseRolesObjects.get(randomIndex);
} else {
return null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ public List<RoleType> getPlanktonRolesObjects() {
return roleObjects;
}

public static List<RoleType> getNoiseRolesObjects() {
List<RoleType> roleObjects = new ArrayList<>();
addRoleObjects(NoiseApplicationBusinessAbstractRole.values(), roleObjects);
return roleObjects;
}

public List<OrgType> getOrgObjects() {
List<OrgType> orgObjects = new ArrayList<>();
addOrgObjects(Organization.values(), orgObjects);
Expand Down Expand Up @@ -383,6 +389,56 @@ public boolean isArchetypeRoleEnable() {
}
}


public enum NoiseApplicationBusinessAbstractRole implements InitialAbstractRole {

SOCIAL_MEDIA_MANAGER("c368b9a1-3c58-4d6f-9f86-a23ccf8a4f06", "Social Media Manager"),
SOCIAL_MEDIA_ANALYST("6e42c7ab-4c75-4c17-bf69-63049315680c", "Social Media Analyst"),
SOCIAL_MEDIA_WRITER("f659fe15-9e98-4468-9e7d-80eabe6253c9", "Social Media Writer"),
SOCIAL_MEDIA_READER("f3e4d45c-d311-4f8b-99da-a96313ec7eb0", "Social Media Reader"),
SOCIAL_MEDIA_AUDITOR("dd36aaa5-d671-4a5d-b2c0-3af937f5db0c", "Social Media Auditor"),
SOCIAL_MEDIA_ADMIN("62231b07-af48-4dfb-8250-a40f13994d0c", "Social Media Admin");

private final String oid;
private final String name;

NoiseApplicationBusinessAbstractRole(String oid, String name) {
this.oid = oid;
this.name = name;
}

@Override
public String getOidValue() {
return oid;
}

@Override
public String getName() {
return name;
}

@Override
public @Nullable List<String> getAssociations() {
return null;
}

@Override
public String getArchetypeOid() {
return Archetypes.NOISE_ROLE.getOidValue();
}

@Override
public int getAssociationsMultiplier() {
return 0;
}

@Override
public boolean isArchetypeRoleEnable() {
return true;
}
}


public enum BasicAbstractRole implements InitialAbstractRole {

AD_GROUP_EMPLOYEES("c112783f-5e01-4b1b-bd5b-f5fe1a091413", "AD Group Employees",
Expand Down Expand Up @@ -562,7 +618,8 @@ public enum Archetypes implements InitialArchetype {
"purple", "fe fe-role"),
BIRTHRIGHT_ROLE("d212dcd9-b062-49fd-adbd-7815868f132c", "Birthright Role Archetype",
"orange", "fe fe-role"),

NOISE_ROLE("5b8a247c-443f-4a9a-a125-963b36383061", "Noise Role Archetype",
"blue", "fe fe-role"),
REGULAR_USER("86638d1c-66b6-40a9-817e-cf88ca7aaced", "Regular User Archetype",
"blue", "fa fa-user"),
SEMI_REGULAR_USER("e3b84663-1f37-46fa-ab06-70cbac038885", "Semi-regular User Archetype",
Expand Down
3 changes: 3 additions & 0 deletions tools/ninja/src/main/resources/messages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -178,3 +178,6 @@ baseGeneratorOptions.archetypeRole=Specify is archetype role should be used
baseGeneratorOptions.archetypeUser=Specify is archetype user should be used
baseGeneratorOptions.userDivision=User division regular:semi-regular:irregular:managers:sales:security-officers:contractors. Default: "30:20:20:10:10:5:5"
baseGeneratorOptions.includeAux=Include aux roles
baseGeneratorOptions.forget.noise=Forget noise in percent (int). Chance that we will forget about some roles.
baseGeneratorOptions.addition.noise=Addition noise in percent (int). Chance that we will add some noise roles.

0 comments on commit 765e6e9

Please sign in to comment.