Search and cleanup security question answers runnable import com.evolveum.midpoint.model.api.ModelExecuteOptions import com.evolveum.midpoint.prism.path.ItemPath import com.evolveum.midpoint.xml.ns._public.common.common_3.SecurityPolicyType import com.evolveum.midpoint.xml.ns._public.common.common_3.SecurityQuestionsCredentialsType import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType Boolean autoCleanUp = false String logPrefix = "SecQTask: " log.info(logPrefix + "Starting the task : {}", taskName) log.info(logPrefix + "Searching for 'active' security Questions @ Security policies") def identifiers = [] def idCount = [] Integer localCount for (secPol in midpoint.searchObjects(midpoint.queryFor(SecurityPolicyType.class, ". type SecurityPolicyType"))) { log.info(logPrefix + "Processing : {}", secPol.name?.toString()) localCount = 0 for (secQuestion in secPol.getCredentials()?.getSecurityQuestions()?.getQuestion()) { localCount += 1 if (identifiers.indexOf(secQuestion.getIdentifier()) >= 0) { log.info(logPrefix + "FOUND DUPLICITY - already used identifier : {}", secQuestion.getIdentifier()) } else { identifiers.add(secQuestion.getIdentifier()) idCount.add(0) } } log.info(logPrefix + "There has been found {} security question(s).", localCount.toString()) } if (identifiers.size() > 0) { log.info(logPrefix + "Current unique identifiers ({} in total) :\n{}", identifiers.size().toString() ,identifiers.join("\n")) } log.info(logPrefix + "Searching for answers on User objects...") def deltas SecurityQuestionsCredentialsType secQ for (user in midpoint.searchObjects(midpoint.queryFor(UserType.class, ". type UserType"))) { deltas = null secQ = user.getCredentials()?.getSecurityQuestions() if (!secQ) continue for (secAnswer in secQ.getQuestionAnswer()) { int answerIndex = identifiers.indexOf(secAnswer.getQuestionIdentifier()) if (answerIndex >= 0) { idCount[answerIndex] += 1 } else { log.info(logPrefix + "Found invalid answer : {} @ {} ( {} )", secAnswer.getQuestionIdentifier(), user.oid, user.name.toString()) if (autoCleanUp) { if (deltas == null) { deltas = midpoint.deltaFor(UserType.class) } deltas = deltas.item(ItemPath.fromString('credentials/securityQuestions/questionAnswer')) .delete(secAnswer.clone()) } } } if (autoCleanUp) { if (deltas) { deltas = deltas.asObjectDeltas(user.getOid()) log.info(logPrefix + "Processing changes for : {} ( {} )", user.name?.toString(), user.oid) midpoint.executeChanges(deltas, ModelExecuteOptions.getRaw()) } } } log.info(logPrefix + "User objects have been checked ...") if (identifiers.size() == 0) { log.info(logPrefix + "No security question has been found...") } else { String listOut = "" Integer step = 0 Integer listSize = identifiers.size() while ((listSize - step) > 0) { listOut += "\n" + identifiers[step] + ":" + idCount[step] step += 1 } log.info(logPrefix + "Security question identifiers and answer counts:{}", listOut) } log.info(logPrefix + "End of the task : {}", taskName) One time processing taskName $task/name