use of org.apache.syncope.core.persistence.api.dao.AccountRule in project syncope by apache.
the class JPAUserDAO method enforcePolicies.
@Transactional(readOnly = true)
@Override
public Pair<Boolean, Boolean> enforcePolicies(final User user) {
// ------------------------------
// Verify password policies
// ------------------------------
LOG.debug("Password Policy enforcement");
try {
int maxPPSpecHistory = 0;
for (PasswordPolicy policy : getPasswordPolicies(user)) {
if (user.getPassword() == null && !policy.isAllowNullPassword()) {
throw new PasswordPolicyException("Password mandatory");
}
for (Implementation impl : policy.getRules()) {
Optional<PasswordRule> rule = ImplementationManager.buildPasswordRule(impl);
if (rule.isPresent()) {
rule.get().enforce(user);
}
}
if (user.verifyPasswordHistory(user.getClearPassword(), policy.getHistoryLength())) {
throw new PasswordPolicyException("Password value was used in the past: not allowed");
}
if (policy.getHistoryLength() > maxPPSpecHistory) {
maxPPSpecHistory = policy.getHistoryLength();
}
}
// update user's password history with encrypted password
if (maxPPSpecHistory > 0 && user.getPassword() != null && !user.getPasswordHistory().contains(user.getPassword())) {
user.getPasswordHistory().add(user.getPassword());
}
// keep only the last maxPPSpecHistory items in user's password history
if (maxPPSpecHistory < user.getPasswordHistory().size()) {
for (int i = 0; i < user.getPasswordHistory().size() - maxPPSpecHistory; i++) {
user.getPasswordHistory().remove(i);
}
}
} catch (Exception e) {
LOG.error("Invalid password for {}", user, e);
throw new InvalidEntityException(User.class, EntityViolationType.InvalidPassword, e.getMessage());
} finally {
// password has been validated, let's remove its clear version
user.removeClearPassword();
}
// ------------------------------
// Verify account policies
// ------------------------------
LOG.debug("Account Policy enforcement");
boolean suspend = false;
boolean propagateSuspension = false;
try {
if (user.getUsername() == null) {
throw new AccountPolicyException("Null username");
}
if (adminUser.equals(user.getUsername()) || anonymousUser.equals(user.getUsername())) {
throw new AccountPolicyException("Not allowed: " + user.getUsername());
}
if (!USERNAME_PATTERN.matcher(user.getUsername()).matches()) {
throw new AccountPolicyException("Character(s) not allowed");
}
for (AccountPolicy policy : getAccountPolicies(user)) {
for (Implementation impl : policy.getRules()) {
Optional<AccountRule> rule = ImplementationManager.buildAccountRule(impl);
if (rule.isPresent()) {
rule.get().enforce(user);
}
}
suspend |= user.getFailedLogins() != null && policy.getMaxAuthenticationAttempts() > 0 && user.getFailedLogins() > policy.getMaxAuthenticationAttempts() && !user.isSuspended();
propagateSuspension |= policy.isPropagateSuspension();
}
} catch (Exception e) {
LOG.error("Invalid username for {}", user, e);
throw new InvalidEntityException(User.class, EntityViolationType.InvalidUsername, e.getMessage());
}
return ImmutablePair.of(suspend, propagateSuspension);
}
use of org.apache.syncope.core.persistence.api.dao.AccountRule in project syncope by apache.
the class ImplementationManager method buildAccountRule.
public static Optional<AccountRule> buildAccountRule(final Implementation impl) throws InstantiationException, IllegalAccessException {
switch(impl.getEngine()) {
case GROOVY:
return Optional.of(ImplementationManager.<AccountRule>buildGroovy(impl));
case JAVA:
default:
AccountRule rule = null;
AccountRuleConf ruleConf = POJOHelper.deserialize(impl.getBody(), AccountRuleConf.class);
Class<? extends AccountRule> ruleClass = ApplicationContextProvider.getApplicationContext().getBean(ImplementationLookup.class).getAccountRuleClass(ruleConf.getClass());
if (ruleClass == null) {
LOG.warn("Could not find matching account rule for {}", impl.getClass());
} else {
// fetch (or create) rule
if (ApplicationContextProvider.getBeanFactory().containsSingleton(ruleClass.getName())) {
rule = (AccountRule) ApplicationContextProvider.getBeanFactory().getSingleton(ruleClass.getName());
} else {
rule = (AccountRule) ApplicationContextProvider.getBeanFactory().createBean(ruleClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, false);
ApplicationContextProvider.getBeanFactory().registerSingleton(ruleClass.getName(), rule);
}
rule.setConf(ruleConf);
}
return Optional.ofNullable(rule);
}
}
use of org.apache.syncope.core.persistence.api.dao.AccountRule in project syncope by apache.
the class ClassPathScanImplementationLookup method load.
@Override
@SuppressWarnings("unchecked")
public void load() {
classNames = new EnumMap<>(ImplementationType.class);
for (ImplementationType type : ImplementationType.values()) {
classNames.put(type, new HashSet<>());
}
jwtSSOProviderClasses = new HashSet<>();
reportletClasses = new HashMap<>();
accountRuleClasses = new HashMap<>();
passwordRuleClasses = new HashMap<>();
correlationRuleClasses = new HashMap<>();
auditAppenderClasses = new HashSet<>();
ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
scanner.addIncludeFilter(new AssignableTypeFilter(JWTSSOProvider.class));
scanner.addIncludeFilter(new AssignableTypeFilter(Reportlet.class));
scanner.addIncludeFilter(new AssignableTypeFilter(AccountRule.class));
scanner.addIncludeFilter(new AssignableTypeFilter(PasswordRule.class));
scanner.addIncludeFilter(new AssignableTypeFilter(PullCorrelationRule.class));
scanner.addIncludeFilter(new AssignableTypeFilter(ItemTransformer.class));
scanner.addIncludeFilter(new AssignableTypeFilter(SchedTaskJobDelegate.class));
scanner.addIncludeFilter(new AssignableTypeFilter(ReconFilterBuilder.class));
scanner.addIncludeFilter(new AssignableTypeFilter(LogicActions.class));
scanner.addIncludeFilter(new AssignableTypeFilter(PropagationActions.class));
scanner.addIncludeFilter(new AssignableTypeFilter(PullActions.class));
scanner.addIncludeFilter(new AssignableTypeFilter(PushActions.class));
scanner.addIncludeFilter(new AssignableTypeFilter(Validator.class));
scanner.addIncludeFilter(new AssignableTypeFilter(RecipientsProvider.class));
scanner.addIncludeFilter(new AssignableTypeFilter(AuditAppender.class));
scanner.findCandidateComponents(getBasePackage()).forEach(bd -> {
try {
Class<?> clazz = ClassUtils.resolveClassName(bd.getBeanClassName(), ClassUtils.getDefaultClassLoader());
boolean isAbstractClazz = Modifier.isAbstract(clazz.getModifiers());
if (JWTSSOProvider.class.isAssignableFrom(clazz) && !isAbstractClazz) {
classNames.get(ImplementationType.JWT_SSO_PROVIDER).add(clazz.getName());
jwtSSOProviderClasses.add(clazz);
}
if (Reportlet.class.isAssignableFrom(clazz) && !isAbstractClazz) {
ReportletConfClass annotation = clazz.getAnnotation(ReportletConfClass.class);
if (annotation == null) {
LOG.warn("Found Reportlet {} without declared configuration", clazz.getName());
} else {
classNames.get(ImplementationType.REPORTLET).add(clazz.getName());
reportletClasses.put(annotation.value(), (Class<? extends Reportlet>) clazz);
}
}
if (AccountRule.class.isAssignableFrom(clazz) && !isAbstractClazz) {
AccountRuleConfClass annotation = clazz.getAnnotation(AccountRuleConfClass.class);
if (annotation == null) {
LOG.warn("Found account policy rule {} without declared configuration", clazz.getName());
} else {
classNames.get(ImplementationType.ACCOUNT_RULE).add(clazz.getName());
accountRuleClasses.put(annotation.value(), (Class<? extends AccountRule>) clazz);
}
}
if (PasswordRule.class.isAssignableFrom(clazz) && !isAbstractClazz) {
PasswordRuleConfClass annotation = clazz.getAnnotation(PasswordRuleConfClass.class);
if (annotation == null) {
LOG.warn("Found password policy rule {} without declared configuration", clazz.getName());
} else {
classNames.get(ImplementationType.PASSWORD_RULE).add(clazz.getName());
passwordRuleClasses.put(annotation.value(), (Class<? extends PasswordRule>) clazz);
}
}
if (PullCorrelationRule.class.isAssignableFrom(clazz) && !isAbstractClazz) {
PullCorrelationRuleConfClass annotation = clazz.getAnnotation(PullCorrelationRuleConfClass.class);
if (annotation == null) {
LOG.warn("Found pull correlation rule {} without declared configuration", clazz.getName());
} else {
classNames.get(ImplementationType.ACCOUNT_RULE).add(clazz.getName());
correlationRuleClasses.put(annotation.value(), (Class<? extends PullCorrelationRule>) clazz);
}
}
if (ItemTransformer.class.isAssignableFrom(clazz) && !isAbstractClazz && !clazz.equals(JEXLItemTransformerImpl.class)) {
classNames.get(ImplementationType.ITEM_TRANSFORMER).add(clazz.getName());
}
if (SchedTaskJobDelegate.class.isAssignableFrom(clazz) && !isAbstractClazz && !PullJobDelegate.class.isAssignableFrom(clazz) && !PushJobDelegate.class.isAssignableFrom(clazz) && !GroupMemberProvisionTaskJobDelegate.class.isAssignableFrom(clazz)) {
classNames.get(ImplementationType.TASKJOB_DELEGATE).add(bd.getBeanClassName());
}
if (ReconFilterBuilder.class.isAssignableFrom(clazz) && !isAbstractClazz) {
classNames.get(ImplementationType.RECON_FILTER_BUILDER).add(bd.getBeanClassName());
}
if (LogicActions.class.isAssignableFrom(clazz) && !isAbstractClazz) {
classNames.get(ImplementationType.LOGIC_ACTIONS).add(bd.getBeanClassName());
}
if (PropagationActions.class.isAssignableFrom(clazz) && !isAbstractClazz) {
classNames.get(ImplementationType.PROPAGATION_ACTIONS).add(bd.getBeanClassName());
}
if (PullActions.class.isAssignableFrom(clazz) && !isAbstractClazz) {
classNames.get(ImplementationType.PULL_ACTIONS).add(bd.getBeanClassName());
}
if (PushActions.class.isAssignableFrom(clazz) && !isAbstractClazz) {
classNames.get(ImplementationType.PUSH_ACTIONS).add(bd.getBeanClassName());
}
if (Validator.class.isAssignableFrom(clazz) && !isAbstractClazz) {
classNames.get(ImplementationType.VALIDATOR).add(bd.getBeanClassName());
}
if (RecipientsProvider.class.isAssignableFrom(clazz) && !isAbstractClazz) {
classNames.get(ImplementationType.RECIPIENTS_PROVIDER).add(bd.getBeanClassName());
}
if (AuditAppender.class.isAssignableFrom(clazz) && !isAbstractClazz) {
classNames.get(ImplementationType.AUDIT_APPENDER).add(clazz.getName());
auditAppenderClasses.add(clazz);
}
} catch (Throwable t) {
LOG.warn("Could not inspect class {}", bd.getBeanClassName(), t);
}
});
classNames = Collections.unmodifiableMap(classNames);
LOG.debug("Implementation classes found: {}", classNames);
jwtSSOProviderClasses = Collections.unmodifiableSet(jwtSSOProviderClasses);
reportletClasses = Collections.unmodifiableMap(reportletClasses);
accountRuleClasses = Collections.unmodifiableMap(accountRuleClasses);
passwordRuleClasses = Collections.unmodifiableMap(passwordRuleClasses);
correlationRuleClasses = Collections.unmodifiableMap(correlationRuleClasses);
auditAppenderClasses = Collections.unmodifiableSet(auditAppenderClasses);
}
Aggregations