Search in sources :

Example 1 with AccountRule

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);
}
Also used : PasswordRule(org.apache.syncope.core.persistence.api.dao.PasswordRule) AccountRule(org.apache.syncope.core.persistence.api.dao.AccountRule) JPAUser(org.apache.syncope.core.persistence.jpa.entity.user.JPAUser) User(org.apache.syncope.core.persistence.api.entity.user.User) AccountPolicyException(org.apache.syncope.core.provisioning.api.utils.policy.AccountPolicyException) Implementation(org.apache.syncope.core.persistence.api.entity.Implementation) NoResultException(javax.persistence.NoResultException) AccountPolicyException(org.apache.syncope.core.provisioning.api.utils.policy.AccountPolicyException) PasswordPolicyException(org.apache.syncope.core.provisioning.api.utils.policy.PasswordPolicyException) DelegatedAdministrationException(org.apache.syncope.core.spring.security.DelegatedAdministrationException) InvalidEntityException(org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException) InvalidEntityException(org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException) AccountPolicy(org.apache.syncope.core.persistence.api.entity.policy.AccountPolicy) PasswordPolicyException(org.apache.syncope.core.provisioning.api.utils.policy.PasswordPolicyException) PasswordPolicy(org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy) Transactional(org.springframework.transaction.annotation.Transactional)

Example 2 with AccountRule

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);
    }
}
Also used : AccountRule(org.apache.syncope.core.persistence.api.dao.AccountRule) AccountRuleConf(org.apache.syncope.common.lib.policy.AccountRuleConf) ImplementationLookup(org.apache.syncope.core.persistence.api.ImplementationLookup)

Example 3 with AccountRule

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);
}
Also used : PasswordRule(org.apache.syncope.core.persistence.api.dao.PasswordRule) PropagationActions(org.apache.syncope.core.provisioning.api.propagation.PropagationActions) PushJobDelegate(org.apache.syncope.core.provisioning.java.pushpull.PushJobDelegate) ItemTransformer(org.apache.syncope.core.provisioning.api.data.ItemTransformer) PullActions(org.apache.syncope.core.provisioning.api.pushpull.PullActions) AccountRuleConfClass(org.apache.syncope.core.persistence.api.dao.AccountRuleConfClass) LogicActions(org.apache.syncope.core.provisioning.api.LogicActions) AuditAppender(org.apache.syncope.core.logic.audit.AuditAppender) PullCorrelationRule(org.apache.syncope.core.persistence.api.dao.PullCorrelationRule) PushActions(org.apache.syncope.core.provisioning.api.pushpull.PushActions) PasswordRuleConfClass(org.apache.syncope.core.persistence.api.dao.PasswordRuleConfClass) SchedTaskJobDelegate(org.apache.syncope.core.provisioning.api.job.SchedTaskJobDelegate) ReportletConfClass(org.apache.syncope.core.persistence.api.dao.ReportletConfClass) AccountRule(org.apache.syncope.core.persistence.api.dao.AccountRule) RecipientsProvider(org.apache.syncope.core.provisioning.api.notification.RecipientsProvider) Reportlet(org.apache.syncope.core.persistence.api.dao.Reportlet) ImplementationType(org.apache.syncope.common.lib.types.ImplementationType) PullCorrelationRuleConfClass(org.apache.syncope.core.persistence.api.dao.PullCorrelationRuleConfClass) ClassPathScanningCandidateComponentProvider(org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider) JWTSSOProvider(org.apache.syncope.core.spring.security.JWTSSOProvider) ReconFilterBuilder(org.apache.syncope.core.provisioning.api.pushpull.ReconFilterBuilder) Validator(org.apache.syncope.core.persistence.api.attrvalue.validation.Validator) AssignableTypeFilter(org.springframework.core.type.filter.AssignableTypeFilter)

Aggregations

AccountRule (org.apache.syncope.core.persistence.api.dao.AccountRule)3 PasswordRule (org.apache.syncope.core.persistence.api.dao.PasswordRule)2 NoResultException (javax.persistence.NoResultException)1 AccountRuleConf (org.apache.syncope.common.lib.policy.AccountRuleConf)1 ImplementationType (org.apache.syncope.common.lib.types.ImplementationType)1 AuditAppender (org.apache.syncope.core.logic.audit.AuditAppender)1 ImplementationLookup (org.apache.syncope.core.persistence.api.ImplementationLookup)1 InvalidEntityException (org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException)1 Validator (org.apache.syncope.core.persistence.api.attrvalue.validation.Validator)1 AccountRuleConfClass (org.apache.syncope.core.persistence.api.dao.AccountRuleConfClass)1 PasswordRuleConfClass (org.apache.syncope.core.persistence.api.dao.PasswordRuleConfClass)1 PullCorrelationRule (org.apache.syncope.core.persistence.api.dao.PullCorrelationRule)1 PullCorrelationRuleConfClass (org.apache.syncope.core.persistence.api.dao.PullCorrelationRuleConfClass)1 Reportlet (org.apache.syncope.core.persistence.api.dao.Reportlet)1 ReportletConfClass (org.apache.syncope.core.persistence.api.dao.ReportletConfClass)1 Implementation (org.apache.syncope.core.persistence.api.entity.Implementation)1 AccountPolicy (org.apache.syncope.core.persistence.api.entity.policy.AccountPolicy)1 PasswordPolicy (org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy)1 User (org.apache.syncope.core.persistence.api.entity.user.User)1 JPAUser (org.apache.syncope.core.persistence.jpa.entity.user.JPAUser)1