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 info.magnolia.cms.core.MgnlNodeType;
37 import info.magnolia.cms.security.auth.ACL;
38 import info.magnolia.cms.security.auth.PrincipalCollection;
39 import info.magnolia.cms.security.auth.PrincipalCollectionImpl;
40 import info.magnolia.cms.util.ObservationUtil;
41 import info.magnolia.context.MgnlContext;
42 import info.magnolia.repository.RepositoryConstants;
43
44 import java.security.Principal;
45 import java.util.ArrayList;
46 import java.util.Collection;
47 import java.util.Collections;
48
49 import javax.jcr.Node;
50 import javax.jcr.RepositoryException;
51 import javax.jcr.Session;
52 import javax.jcr.observation.EventIterator;
53 import javax.jcr.observation.EventListener;
54 import javax.security.auth.Subject;
55
56 import org.apache.commons.lang.StringUtils;
57 import org.slf4j.Logger;
58 import org.slf4j.LoggerFactory;
59
60
61
62
63
64
65
66 public class SystemUserManager extends MgnlUserManager {
67
68
69
70
71 private static Logger log = LoggerFactory.getLogger(SystemUserManager.class);
72
73
74
75
76
77 private User anonymousUser;
78
79
80
81
82
83 private PrincipalCollection anonymousPermissions;
84
85 public SystemUserManager() {
86
87 EventListener anonymousListener = new EventListener() {
88
89 @Override
90 public void onEvent(EventIterator events) {
91 anonymousUser = null;
92 anonymousPermissions = null;
93 log.debug("Anonymous user reloaded");
94 }
95
96 };
97
98 final String anonymousUserPath = "/" + Realm.REALM_SYSTEM.getName() + "/" + UserManager.ANONYMOUS_USER;
99 ObservationUtil.registerChangeListener(
100 RepositoryConstants.USERS,
101 anonymousUserPath,
102 true,
103 MgnlNodeType.USER,
104 anonymousListener);
105
106 ObservationUtil.registerChangeListener(
107 RepositoryConstants.USER_GROUPS,
108 "/",
109 true,
110 MgnlNodeType.GROUP,
111 anonymousListener);
112
113 ObservationUtil.registerDeferredChangeListener(
114 RepositoryConstants.USER_ROLES,
115 "/",
116 true,
117 new String[]{MgnlNodeType.ROLE,MgnlNodeType.NT_CONTENTNODE},
118 anonymousListener,
119 1000,
120 5000);
121 }
122
123 @Override
124 public String getRealmName() {
125 String name = super.getRealmName();
126
127 if (StringUtils.isEmpty(name)) {
128 log.error("realm of system user manager is not set!");
129 return Realm.REALM_SYSTEM.getName();
130 }
131 return name;
132 }
133
134 @Override
135 public User getSystemUser() {
136 return getOrCreateUser(UserManager.SYSTEM_USER, UserManager.SYSTEM_PSWD);
137 }
138
139 @Override
140 public User getAnonymousUser() {
141 if (anonymousUser == null) {
142
143 anonymousUser = getRequiredSystemUser(UserManager.ANONYMOUS_USER, UserManager.ANONYMOUS_USER);
144 }
145 return anonymousUser;
146 }
147
148 public Subject getAnonymousSubject() {
149 if (anonymousPermissions == null) {
150 Subject subject = SecurityUtil.createSubjectAndPopulate(getAnonymousUser());
151 anonymousPermissions = PrincipalUtil.findPrincipal(subject, PrincipalCollection.class);
152 return subject;
153 }
154 Subject subject = new Subject();
155 subject.getPrincipals().add(getAnonymousUser());
156
157
158 Collection<Principal> permissions = new ArrayList<Principal>();
159 for (Principal principal : anonymousPermissions.getCollection()) {
160 ACL acl = (ACL) principal;
161
162 permissions.add(new ACLImpl(acl.getName(), new ArrayList<Permission>(acl.getList())));
163 }
164 subject.getPrincipals().add(new PrincipalCollectionImpl(Collections.unmodifiableCollection(permissions)));
165 return subject;
166 }
167
168
169
170
171 private User getRequiredSystemUser(final String username, String password) {
172 return MgnlContext.doInSystemContext(new SilentSessionOp<User>(getRepositoryName()) {
173
174 @Override
175 public User doExec(Session session) throws RepositoryException {
176 User user = null;
177 Node node;
178 try {
179 node = session.getNode("/" + Realm.REALM_SYSTEM.getName() + "/" + username);
180 }
181 catch (RepositoryException e) {
182 log.error("Error caught while loading the system user "
183 + username
184 + ": "
185 + e.getClass().getName()
186 + ": "
187 + e.getMessage(), e);
188 return null;
189 }
190 if (node == null) {
191 log.error("User not found: {}.", username);
192 return null;
193 }
194
195 user = newUserInstance(node);
196 return user;
197 }});
198 }
199
200 protected User getOrCreateUser(String userName, String password) {
201 User user = getUser(userName);
202 if (user == null) {
203 log.error(
204 "Failed to get system user [{}], will try to create new system user with default password",
205 userName);
206 user = this.createUser(userName, password);
207 }
208 return user;
209 }
210 }