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