1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.syncope.core.spring.policy;
20
21 import java.util.Collection;
22 import java.util.HashSet;
23 import java.util.Objects;
24 import java.util.Set;
25 import java.util.regex.Pattern;
26 import java.util.stream.Collectors;
27 import org.apache.commons.lang3.StringUtils;
28 import org.apache.syncope.common.lib.policy.AccountRuleConf;
29 import org.apache.syncope.common.lib.policy.DefaultAccountRuleConf;
30 import org.apache.syncope.core.persistence.api.entity.Entity;
31 import org.apache.syncope.core.persistence.api.entity.PlainAttr;
32 import org.apache.syncope.core.persistence.api.entity.user.LinkedAccount;
33 import org.apache.syncope.core.persistence.api.entity.user.User;
34 import org.apache.syncope.core.provisioning.api.rules.AccountRule;
35 import org.apache.syncope.core.provisioning.api.rules.AccountRuleConfClass;
36 import org.springframework.transaction.annotation.Transactional;
37 import org.springframework.util.CollectionUtils;
38
39 @AccountRuleConfClass(DefaultAccountRuleConf.class)
40 public class DefaultAccountRule implements AccountRule {
41
42 private DefaultAccountRuleConf conf;
43
44 @Override
45 public void setConf(final AccountRuleConf conf) {
46 if (conf instanceof DefaultAccountRuleConf) {
47 this.conf = DefaultAccountRuleConf.class.cast(conf);
48 } else {
49 throw new IllegalArgumentException(
50 DefaultAccountRuleConf.class.getName() + " expected, got " + conf.getClass().getName());
51 }
52 }
53
54 protected void enforce(final String username, final Set<String> wordsNotPermitted) {
55
56 if (conf.getMinLength() > 0 && conf.getMinLength() > username.length()) {
57 throw new AccountPolicyException("Username too short");
58 }
59
60
61 if (conf.getMaxLength() > 0 && conf.getMaxLength() < username.length()) {
62 throw new AccountPolicyException("Username too long");
63 }
64
65
66 wordsNotPermitted.stream().
67 filter(word -> StringUtils.containsIgnoreCase(username, word)).
68 forEach(item -> {
69 throw new AccountPolicyException("Used word(s) not permitted");
70 });
71
72
73 if (conf.isAllUpperCase() && !username.equals(username.toUpperCase())) {
74 throw new AccountPolicyException("No lowercase characters permitted");
75 }
76 if (conf.isAllLowerCase() && !username.equals(username.toLowerCase())) {
77 throw new AccountPolicyException("No uppercase characters permitted");
78 }
79
80
81 Pattern pattern = conf.getPattern() == null ? Entity.ID_PATTERN : Pattern.compile(conf.getPattern());
82 if (!pattern.matcher(username).matches()) {
83 throw new AccountPolicyException("Username does not match pattern");
84 }
85
86
87 conf.getPrefixesNotPermitted().stream().
88 filter(username::startsWith).findAny().
89 ifPresent(item -> {
90 throw new AccountPolicyException("Prefix not permitted");
91 });
92
93
94 conf.getSuffixesNotPermitted().stream().
95 filter(username::endsWith).findAny().
96 ifPresent(item -> {
97 throw new AccountPolicyException("Suffix not permitted");
98 });
99 }
100
101 @Override
102 public void enforce(final String username) {
103 Set<String> wordsNotPermitted = new HashSet<>(conf.getWordsNotPermitted());
104 enforce(username, wordsNotPermitted);
105 }
106
107 @Transactional(readOnly = true)
108 @Override
109 public void enforce(final User user) {
110 Set<String> wordsNotPermitted = new HashSet<>(conf.getWordsNotPermitted());
111 wordsNotPermitted.addAll(
112 conf.getSchemasNotPermitted().stream().
113 map(schema -> user.getPlainAttr(schema).
114 map(PlainAttr::getValuesAsStrings).orElse(null)).
115 filter(Objects::nonNull).
116 filter(values -> !CollectionUtils.isEmpty(values)).
117 flatMap(Collection::stream).
118 collect(Collectors.toSet()));
119
120 enforce(user.getUsername(), wordsNotPermitted);
121 }
122
123 @Transactional(readOnly = true)
124 @Override
125 public void enforce(final LinkedAccount account) {
126 if (StringUtils.isBlank(account.getUsername())) {
127 return;
128 }
129
130 Set<String> wordsNotPermitted = new HashSet<>(conf.getWordsNotPermitted());
131 wordsNotPermitted.addAll(
132 conf.getSchemasNotPermitted().stream().
133 map(schema -> account.getPlainAttr(schema).
134 map(PlainAttr::getValuesAsStrings).orElse(null)).
135 filter(Objects::nonNull).
136 filter(values -> !CollectionUtils.isEmpty(values)).
137 flatMap(Collection::stream).
138 collect(Collectors.toSet()));
139
140 enforce(account.getUsername(), wordsNotPermitted);
141 }
142 }