1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.cms.security;
35
36 import static info.magnolia.cms.security.SecurityConstants.*;
37
38 import info.magnolia.cms.core.Content;
39
40 import java.io.Serializable;
41 import java.util.Calendar;
42 import java.util.Collection;
43 import java.util.Collections;
44 import java.util.Map;
45 import java.util.Set;
46 import java.util.TreeSet;
47
48 import org.apache.jackrabbit.util.ISO8601;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
51
52
53
54
55
56
57
58 public class MgnlUser extends AbstractUser implements User, Serializable {
59
60 private static final Logger log = LoggerFactory.getLogger(MgnlUser.class);
61
62 private final Map<String, String> properties;
63 private final Collection<String> groups;
64 private final Collection<String> roles;
65
66 private final String name;
67 private final String language;
68 private final String encodedPassword;
69 private boolean enabled = true;
70 private String path;
71 private String uuid;
72
73 private final String realm;
74
75
76 public MgnlUser(String name, String realm, Collection<String> groups, Collection<String> roles, Map<String, String> properties) {
77 this.name = name;
78 this.roles = Collections.unmodifiableCollection(roles);
79 this.groups = Collections.unmodifiableCollection(groups);
80 this.properties = Collections.unmodifiableMap(properties);
81 this.realm = realm;
82
83
84 language = properties.get(MgnlUserManager.PROPERTY_LANGUAGE);
85 String enbld = properties.get(MgnlUserManager.PROPERTY_ENABLED);
86
87 enabled = enbld == null ? true : Boolean.parseBoolean(properties.get(MgnlUserManager.PROPERTY_ENABLED));
88 encodedPassword = properties.get(MgnlUserManager.PROPERTY_PASSWORD);
89 }
90
91 public MgnlUser(String name, String realm, Collection<String> groups, Collection<String> roles, Map<String, String> properties, String path, String uuid) {
92 this(name, realm, groups, roles, properties);
93 this.path = path;
94 this.uuid = uuid;
95 }
96
97
98
99
100
101
102
103 @Override
104 public boolean inGroup(String groupName) {
105 log.debug("inGroup({})", groupName);
106 return SecuritySupport.Factory.getInstance().getUserManager(getRealm()).hasAny(getName(), groupName, NODE_GROUPS);
107 }
108
109
110
111
112 @Override
113 public void removeGroup(String groupName) throws UnsupportedOperationException {
114 log.debug("removeGroup({})", groupName);
115 throw new UnsupportedOperationException("use manager to remove groups!");
116 }
117
118
119
120
121
122
123 @Override
124 public void addGroup(String groupName) throws UnsupportedOperationException {
125 log.debug("addGroup({})", groupName);
126 throw new UnsupportedOperationException("use manager to add groups!");
127 }
128
129 @Override
130 public boolean isEnabled() {
131 log.debug("isEnabled()");
132 return enabled;
133 }
134
135
136
137
138
139
140 @Override
141 @Deprecated
142 public void setEnabled(boolean enabled) {
143 log.debug("setEnabled({})", enabled);
144 throw new UnsupportedOperationException("use manager to enable user!");
145 }
146
147
148
149
150
151
152
153 @Override
154 public boolean hasRole(String roleName) {
155 return SecuritySupport.Factory.getInstance().getUserManager(getRealm()).hasAny(getName(), roleName, NODE_ROLES);
156 }
157
158 @Override
159 public void removeRole(String roleName) throws UnsupportedOperationException {
160 log.debug("removeRole({})", roleName);
161 throw new UnsupportedOperationException("use manager to remove roles!");
162 }
163
164 @Override
165 public void addRole(String roleName) throws UnsupportedOperationException {
166 log.debug("addRole({})", roleName);
167 throw new UnsupportedOperationException("use manager to add roles!");
168 }
169
170 public int getFailedLoginAttempts() {
171 try {
172 return Integer.valueOf(this.properties.get("failedLoginAttempts"));
173 } catch (Exception e) {
174 return 0;
175 }
176 }
177
178 public Calendar getReleaseTime() {
179 try {
180 return ISO8601.parse(this.properties.get("releaseTime"));
181 } catch (Exception e) {
182 return null;
183 }
184 }
185
186 @Override
187 public String getName() {
188 log.debug("getName()=>{}", name);
189 return name;
190 }
191
192 @Override
193 public String getPassword() {
194 return encodedPassword;
195 }
196
197 @Deprecated
198
199
200
201 protected String decodePassword(String encodedPassword) {
202 throw new UnsupportedOperationException();
203 }
204
205 @Override
206 public String getLanguage() {
207 log.debug("getLang()=>{}", language);
208 return this.language;
209 }
210
211 @Override
212 public String getProperty(String propertyName) {
213 log.debug("getProperty({})", propertyName);
214 return properties.get(propertyName);
215 }
216
217 @Override
218 public Collection<String> getGroups() {
219 log.debug("getGroups()");
220 return groups;
221 }
222
223 @Override
224 public Collection<String> getAllGroups() {
225
226
227 log.debug("get groups for {}", getName());
228
229 final Set<String> allGroups = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
230 final Collection<String> groups = getGroups();
231
232
233 GroupManager man = SecuritySupport.Factory.getInstance().getGroupManager();
234
235
236 addSubgroups(allGroups, man, groups);
237
238 return allGroups;
239 }
240
241 @Override
242 public Collection<String> getRoles() {
243 log.debug("getRoles()");
244 return roles;
245 }
246
247 @Override
248 public Collection<String> getAllRoles() {
249
250 log.debug("get roles for {}", getName());
251
252 final Set<String> allRoles = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
253 final Collection<String> roles = getRoles();
254
255
256 allRoles.addAll(roles);
257
258 Collection<String> allGroups = getAllGroups();
259
260
261 GroupManager man = SecuritySupport.Factory.getInstance().getGroupManager();
262
263
264 for (String group : allGroups) {
265 try {
266 allRoles.addAll(man.getGroup(group).getRoles());
267 } catch (AccessDeniedException e) {
268 log.debug("Skipping denied group {} for user {}", group, getName(), e);
269 } catch (UnsupportedOperationException e) {
270 log.debug("Skipping unsupported getGroup() for group {} and user {}", group, getName(), e);
271 }
272 }
273 return allRoles;
274 }
275
276 public String getPath() {
277 return this.path;
278 }
279
280 @Deprecated
281 public void setPath(String path) {
282 this.path = path;
283 }
284
285
286
287
288 private void addSubgroups(final Set<String> allGroups, GroupManager man, Collection<String> groups) {
289 for (String groupName : groups) {
290
291 if (!allGroups.contains(groupName)) {
292 allGroups.add(groupName);
293 try {
294 Group group = man.getGroup(groupName);
295 if (group == null) {
296 log.error("Failed to resolve group {} for user {}.", groupName, name);
297 continue;
298 }
299 Collection<String> subgroups = group.getGroups();
300
301 addSubgroups(allGroups, man, subgroups);
302 } catch (AccessDeniedException e) {
303 log.debug("Skipping denied group {} for user {}", groupName, getName(), e);
304 } catch (UnsupportedOperationException e) {
305 log.debug("Skipping unsupported getGroup() for group {} and user {}", groupName, getName(), e);
306 }
307
308 }
309 }
310 }
311
312 public String getRealm() {
313 return realm;
314 }
315
316
317
318
319
320
321 @Deprecated
322 public void setLastAccess() {
323 throw new UnsupportedOperationException("Use manager to update user details.");
324 }
325
326
327
328
329
330
331 @Deprecated
332 public Content getUserNode() {
333 throw new UnsupportedOperationException("Underlying storage node is no longer exposed nor required for custom user stores.");
334 }
335
336
337
338
339 @Override
340 @Deprecated
341 public void setProperty(String propertyName, String value) {
342 throw new UnsupportedOperationException("Use manager to modify properties of the user.");
343 }
344
345 @Override
346 public String getIdentifier() {
347 return uuid;
348 }
349
350
351
352
353 @Deprecated
354 public String getUuid() {
355 return uuid;
356 }
357
358 @Override
359 public String toString() {
360 return "MgnlUser - " + name + " [" + uuid + "]";
361 }
362 }