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.beans.config.ContentRepository;
37 import info.magnolia.cms.core.Content;
38 import info.magnolia.cms.security.auth.callback.CredentialsCallbackHandler;
39 import info.magnolia.cms.security.auth.callback.PlainTextCallbackHandler;
40 import info.magnolia.cms.util.ObservationUtil;
41
42 import javax.jcr.RepositoryException;
43 import javax.jcr.observation.EventIterator;
44 import javax.jcr.observation.EventListener;
45 import javax.security.auth.Subject;
46 import javax.security.auth.login.LoginContext;
47 import javax.security.auth.login.LoginException;
48
49 import org.apache.commons.lang.StringUtils;
50 import org.slf4j.Logger;
51 import org.slf4j.LoggerFactory;
52
53
54
55
56
57
58
59 public class SystemUserManager extends MgnlUserManager {
60
61
62
63
64 private static Logger log = LoggerFactory.getLogger(SystemUserManager.class);
65
66
67
68
69
70 private User anonymousUser;
71
72 public SystemUserManager() {
73
74 EventListener anonymousListener = new EventListener() {
75
76 public void onEvent(EventIterator events) {
77 anonymousUser = null;
78 log.debug("Anonymous user reloaded");
79 }
80
81 };
82
83 final String anonymousUserPath = "/" + Realm.REALM_SYSTEM + "/" + UserManager.ANONYMOUS_USER;
84 ObservationUtil.registerChangeListener(
85 ContentRepository.USERS,
86 anonymousUserPath,
87 true,
88 "mgnl:user",
89 anonymousListener);
90
91 ObservationUtil.registerChangeListener(
92 ContentRepository.USER_GROUPS,
93 "/",
94 true,
95 "mgnl:group",
96 anonymousListener);
97
98 ObservationUtil.registerDeferredChangeListener(
99 ContentRepository.USER_ROLES,
100 "/",
101 true,
102 "mgnl:role",
103 anonymousListener,
104 1000,
105 5000);
106 }
107
108 @Override
109 public String getRealmName() {
110 String name = super.getRealmName();
111
112 if (StringUtils.isEmpty(name)) {
113 log.error("realm of system user manager is not set!");
114 return Realm.REALM_SYSTEM;
115 }
116 return name;
117 }
118
119 @Override
120 public User getSystemUser() {
121 return getOrCreateUser(UserManager.SYSTEM_USER, UserManager.SYSTEM_PSWD);
122 }
123
124 @Override
125 public User getAnonymousUser() {
126 if (anonymousUser == null) {
127
128 anonymousUser = getRequiredSystemUser(UserManager.ANONYMOUS_USER, UserManager.ANONYMOUS_USER);
129 }
130 return anonymousUser;
131 }
132
133
134
135
136 private User getRequiredSystemUser(String username, String password) {
137 MgnlUser user = null;
138 Content node;
139 try {
140 node = getHierarchyManager().getContent("/" + Realm.REALM_SYSTEM + "/" + username);
141 }
142 catch (RepositoryException e) {
143 log.error("Error caught while loading the system user "
144 + username
145 + ": "
146 + e.getClass().getName()
147 + ": "
148 + e.getMessage(), e);
149 return null;
150 }
151 if (node == null) {
152 log.error("User not found: {}.", username);
153 return null;
154 }
155
156 user = userInstance(node);
157 Subject subject = getSubject(username, password);
158 user.setSubject(subject);
159 return user;
160 }
161
162 protected User getOrCreateUser(String userName, String password) {
163 User user = getUser(userName);
164 if (user == null) {
165 log.error(
166 "Failed to get system user [{}], will try to create new system user with default password",
167 userName);
168 user = this.createUser(userName, password);
169 }
170 return user;
171 }
172
173 private Subject getSubject(String userName, String password) {
174 CredentialsCallbackHandler callbackHandler = new PlainTextCallbackHandler(
175 userName,
176 password.toCharArray(),
177 getRealmName());
178 try {
179 LoginContext loginContext = new LoginContext("magnolia", callbackHandler);
180 loginContext.login();
181 return loginContext.getSubject();
182 }
183 catch (LoginException le) {
184 log.error("Failed to login as " + userName + " user", le);
185 }
186 return null;
187 }
188 }