blob: 1184ac8dfee7435bcc8fc17d7dcfa818619ad754 [file] [log] [blame]
Michael Hanl87106d12015-09-14 18:13:51 +02001package de.ids_mannheim.korap.security.auth;
2
3import de.ids_mannheim.korap.auditing.AuditRecord;
Michael Hanl00b64e02016-05-24 20:24:27 +02004import de.ids_mannheim.korap.config.Attributes;
Michael Hanldaf86602016-05-12 14:31:52 +02005import de.ids_mannheim.korap.config.BeansFactory;
Michael Hanl87106d12015-09-14 18:13:51 +02006import de.ids_mannheim.korap.config.KustvaktConfiguration;
7import de.ids_mannheim.korap.config.URIParam;
8import de.ids_mannheim.korap.exceptions.*;
Michael Hanl19390652016-01-16 11:01:24 +01009import de.ids_mannheim.korap.interfaces.AuthenticationIface;
10import de.ids_mannheim.korap.interfaces.AuthenticationManagerIface;
11import de.ids_mannheim.korap.interfaces.EncryptionIface;
Michael Hanlc0ed00f2016-06-23 14:33:10 +020012import de.ids_mannheim.korap.interfaces.ValidatorIface;
Michael Hanlf21773f2015-10-16 23:02:31 +020013import de.ids_mannheim.korap.interfaces.db.AuditingIface;
14import de.ids_mannheim.korap.interfaces.db.EntityHandlerIface;
Michael Hanl415276b2016-01-29 16:39:37 +010015import de.ids_mannheim.korap.interfaces.db.UserDataDbIface;
Michael Hanlc0ed00f2016-06-23 14:33:10 +020016import de.ids_mannheim.korap.interfaces.defaults.ApacheValidator;
Michael Hanl87106d12015-09-14 18:13:51 +020017import de.ids_mannheim.korap.user.*;
Michael Hanlcb2d3f92016-06-02 17:34:06 +020018import de.ids_mannheim.korap.utils.StringUtils;
Michael Hanl87106d12015-09-14 18:13:51 +020019import de.ids_mannheim.korap.utils.TimeUtils;
Michael Hanl87106d12015-09-14 18:13:51 +020020import org.slf4j.Logger;
Michael Hanlac113e52016-01-19 15:49:20 +010021import org.slf4j.LoggerFactory;
Michael Hanl87106d12015-09-14 18:13:51 +020022
Michael Hanlc0ed00f2016-06-23 14:33:10 +020023import java.io.IOException;
Michael Hanl87106d12015-09-14 18:13:51 +020024import java.io.UnsupportedEncodingException;
25import java.security.NoSuchAlgorithmException;
Michael Hanldaf86602016-05-12 14:31:52 +020026import java.util.Collection;
Michael Hanl87106d12015-09-14 18:13:51 +020027import java.util.Map;
28
29/**
Michael Hanl8abaf9e2016-05-23 16:46:35 +020030 * contains the logic to authentication and registration processes.
31 * Uses
32 * interface implementations (AuthenticationIface) for different
33 * databases and handlers
34 *
Michael Hanl87106d12015-09-14 18:13:51 +020035 * @author hanl
36 */
37public class KustvaktAuthenticationManager extends AuthenticationManagerIface {
38
Michael Hanlac113e52016-01-19 15:49:20 +010039 private static Logger jlog = LoggerFactory
Michael Hanlfdd9a012015-11-13 15:56:38 +010040 .getLogger(KustvaktAuthenticationManager.class);
Michael Hanl87106d12015-09-14 18:13:51 +020041 private EncryptionIface crypto;
42 private EntityHandlerIface entHandler;
43 private AuditingIface auditing;
Michael Hanle17eaa52016-01-22 20:55:05 +010044 private KustvaktConfiguration config;
Michael Hanldaf86602016-05-12 14:31:52 +020045 private Collection userdatadaos;
46 private LoginCounter counter;
Michael Hanlc0ed00f2016-06-23 14:33:10 +020047 private ValidatorIface validator;
Michael Hanl8abaf9e2016-05-23 16:46:35 +020048
49 public KustvaktAuthenticationManager (EntityHandlerIface userdb,
50 EncryptionIface crypto,
51 KustvaktConfiguration config,
52 AuditingIface auditer,
53 Collection<UserDataDbIface> userdatadaos) {
Michael Hanl87106d12015-09-14 18:13:51 +020054 this.entHandler = userdb;
Michael Hanle17eaa52016-01-22 20:55:05 +010055 this.config = config;
Michael Hanl87106d12015-09-14 18:13:51 +020056 this.crypto = crypto;
57 this.auditing = auditer;
58 this.counter = new LoginCounter(config);
Michael Hanldaf86602016-05-12 14:31:52 +020059 this.userdatadaos = userdatadaos;
Michael Hanlc0ed00f2016-06-23 14:33:10 +020060 // todo: load via beancontext
61 try {
62 this.validator = new ApacheValidator();
63 } catch (IOException e) {
64 e.printStackTrace();
65 }
Michael Hanl87106d12015-09-14 18:13:51 +020066 }
67
Michael Hanl8abaf9e2016-05-23 16:46:35 +020068
Michael Hanl87106d12015-09-14 18:13:51 +020069 /**
70 * get session object if token was a session token
Michael Hanl8abaf9e2016-05-23 16:46:35 +020071 *
Michael Hanl87106d12015-09-14 18:13:51 +020072 * @param token
73 * @param host
74 * @param useragent
75 * @return
76 * @throws KustvaktException
77 */
Michael Hanlc0ed00f2016-06-23 14:33:10 +020078 @Override
Michael Hanl8abaf9e2016-05-23 16:46:35 +020079 public TokenContext getTokenStatus (String token, String host,
Michael Hanl87106d12015-09-14 18:13:51 +020080 String useragent) throws KustvaktException {
Michael Hanl3520dcd2016-02-08 19:11:37 +010081 jlog.info("getting session status of token type '{}'",
82 token.split(" ")[0]);
Michael Hanl87106d12015-09-14 18:13:51 +020083 AuthenticationIface provider = getProvider(
Michael Hanlcb2d3f92016-06-02 17:34:06 +020084 StringUtils.getTokenType(token), null);
Michael Hanl19390652016-01-16 11:01:24 +010085
86 if (provider == null)
Michael Hanlc0ed00f2016-06-23 14:33:10 +020087 // throw exception for missing type parameter
Michael Hanl19390652016-01-16 11:01:24 +010088 throw new KustvaktException(StatusCodes.ILLEGAL_ARGUMENT,
89 "token type not defined or found", "token_type");
90
Michael Hanlc0ed00f2016-06-23 14:33:10 +020091 TokenContext context = provider.getTokenContext(token);
92 System.out.println("CONTEXT "+ context.toResponse());
93 if (context != null && TimeUtils.isExpired(context.getExpirationTime()))
94 throw new KustvaktException(StatusCodes.EXPIRED);
95
Michael Hanlf1e85e72016-01-21 16:55:45 +010096 // if (!matchStatus(host, useragent, context))
97 // provider.removeUserSession(token);
Michael Hanl87106d12015-09-14 18:13:51 +020098 return context;
99 }
100
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200101
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200102 @Override
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200103 public User getUser (String username) throws KustvaktException {
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200104 //User user;
105 //Object value = this.getCacheValue(username);
Michael Hanl87106d12015-09-14 18:13:51 +0200106
Michael Hanlc4446022016-02-12 18:03:17 +0100107 if (User.UserFactory.isDemo(username))
108 return User.UserFactory.getDemoUser();
109
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200110 //if (value != null) {
111 // Map map = (Map) value;
112 // user = User.UserFactory.toUser(map);
113 //}
114 // else {
115 // user = entHandler.getAccount(username);
116 // this.storeInCache(username, user.toCache());
Michael Hanl7368aa42016-02-05 18:15:47 +0100117 // todo: not valid. for the duration of the session, the host should not change!
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200118 //}
Michael Hanl87106d12015-09-14 18:13:51 +0200119 //todo:
120 // user.addField(Attributes.HOST, context.getHostAddress());
121 // user.addField(Attributes.USER_AGENT, context.getUserAgent());
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200122 return entHandler.getAccount(username);
Michael Hanl87106d12015-09-14 18:13:51 +0200123 }
124
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200125
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200126
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200127 public TokenContext refresh (TokenContext context) throws KustvaktException {
128 AuthenticationIface provider = getProvider(context.getTokenType(), null);
Michael Hanl19390652016-01-16 11:01:24 +0100129 if (provider == null) {
Michael Hanl5fac8ab2016-01-29 16:33:04 +0100130 //todo:
Michael Hanl19390652016-01-16 11:01:24 +0100131 }
132
Michael Hanl87106d12015-09-14 18:13:51 +0200133 try {
134 provider.removeUserSession(context.getToken());
135 User user = getUser(context.getUsername());
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200136 return provider.createTokenContext(user, context.params());
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200137 }
138 catch (KustvaktException e) {
Michael Hanl87106d12015-09-14 18:13:51 +0200139 throw new WrappedException(e, StatusCodes.LOGIN_FAILED);
140 }
141 }
142
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200143
Michael Hanl87106d12015-09-14 18:13:51 +0200144 /**
145 * @param type
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200146 * @param attributes
147 * contains username and password to authenticate the
148 * user.
149 * Depending of the authentication schema, may contain
150 * other values as well
Michael Hanl87106d12015-09-14 18:13:51 +0200151 * @return User
152 * @throws KustvaktException
153 */
Michael Hanl5fac8ab2016-01-29 16:33:04 +0100154 @Override
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200155 public User authenticate (int type, String username, String password,
Michael Hanl5fac8ab2016-01-29 16:33:04 +0100156 Map<String, Object> attributes) throws KustvaktException {
Michael Hanl87106d12015-09-14 18:13:51 +0200157 User user;
158 switch (type) {
159 case 1:
160 // todo:
161 user = authenticateShib(attributes);
162 break;
163 default:
164 user = authenticate(username, password, attributes);
165 break;
166 }
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200167 auditing.audit(AuditRecord.serviceRecord(user.getId(),
168 StatusCodes.LOGIN_SUCCESSFUL, user.toString()));
Michael Hanl87106d12015-09-14 18:13:51 +0200169 return user;
170 }
171
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200172
Michael Hanl5fac8ab2016-01-29 16:33:04 +0100173 @Override
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200174 public TokenContext createTokenContext (User user,
175 Map<String, Object> attr, String provider_key)
176 throws KustvaktException {
Michael Hanl19390652016-01-16 11:01:24 +0100177 AuthenticationIface provider = getProvider(provider_key,
178 Attributes.API_AUTHENTICATION);
Michael Hanl87106d12015-09-14 18:13:51 +0200179
180 if (attr.get(Attributes.SCOPES) != null)
Michael Hanl5dd931a2016-01-29 16:40:38 +0100181 this.getUserData(user, UserDetails.class);
Michael Hanl87106d12015-09-14 18:13:51 +0200182
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200183 TokenContext context = provider.createTokenContext(user, attr);
Michael Hanl87106d12015-09-14 18:13:51 +0200184 if (context == null)
185 throw new KustvaktException(StatusCodes.NOT_SUPPORTED);
Michael Hanl5fac8ab2016-01-29 16:33:04 +0100186 context.setUserAgent((String) attr.get(Attributes.USER_AGENT));
Michael Hanl87106d12015-09-14 18:13:51 +0200187 context.setHostAddress(Attributes.HOST);
188 return context;
189 }
190
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200191
Michael Hanl87106d12015-09-14 18:13:51 +0200192 //todo: test
Michael Hanlf1e85e72016-01-21 16:55:45 +0100193 @Deprecated
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200194 private boolean matchStatus (String host, String useragent,
Michael Hanl87106d12015-09-14 18:13:51 +0200195 TokenContext context) {
196 if (host.equals(context.getHostAddress())) {
197 if (useragent.equals(context.getUserAgent()))
198 return true;
199 }
200 return false;
201 }
202
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200203
204 private User authenticateShib (Map<String, Object> attributes)
Michael Hanl87106d12015-09-14 18:13:51 +0200205 throws KustvaktException {
206 // todo use persistent id, since eppn is not unique
207 String eppn = (String) attributes.get(Attributes.EPPN);
208
209 if (eppn == null || eppn.isEmpty())
210 throw new KustvaktException(StatusCodes.REQUEST_INVALID);
211
212 if (!attributes.containsKey(Attributes.EMAIL)
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200213 && validator.isValid(eppn, Attributes.EMAIL))
Michael Hanl87106d12015-09-14 18:13:51 +0200214 attributes.put(Attributes.EMAIL, eppn);
215
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200216 User user = null;
217 if (isRegistered(eppn))
Michael Hanl87106d12015-09-14 18:13:51 +0200218 user = createShibbUserAccount(attributes);
219 return user;
220 }
221
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200222
Michael Hanl87106d12015-09-14 18:13:51 +0200223 //todo: what if attributes null?
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200224 private User authenticate (String username, String password,
Michael Hanl5fac8ab2016-01-29 16:33:04 +0100225 Map<String, Object> attr) throws KustvaktException {
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200226 Map<String, Object> attributes = validator.validateMap(attr);
Michael Hanl87106d12015-09-14 18:13:51 +0200227 User unknown;
228 // just to make sure that the plain password does not appear anywhere in the logs!
229
230 try {
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200231 validator.validateEntry(username, Attributes.USERNAME);
232 } catch (KustvaktException e) {
Michael Hanl87106d12015-09-14 18:13:51 +0200233 throw new WrappedException(e, StatusCodes.LOGIN_FAILED, username);
234 }
235
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200236 if (username == null || username.isEmpty())
Michael Hanl87106d12015-09-14 18:13:51 +0200237 throw new WrappedException(new KustvaktException(username,
238 StatusCodes.BAD_CREDENTIALS), StatusCodes.LOGIN_FAILED);
239 else {
240 try {
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200241 unknown = entHandler.getAccount(username);
242 } catch (EmptyResultException e) {
Michael Hanl87106d12015-09-14 18:13:51 +0200243 // mask exception to disable user guessing in possible attacks
244 throw new WrappedException(new KustvaktException(username,
245 StatusCodes.BAD_CREDENTIALS), StatusCodes.LOGIN_FAILED,
246 username);
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200247 }
248 catch (KustvaktException e) {
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200249 jlog.error("Error: {}", e);
Michael Hanl87106d12015-09-14 18:13:51 +0200250 throw new WrappedException(e, StatusCodes.LOGIN_FAILED,
251 attributes.toString());
252 }
253 }
Michael Hanle17eaa52016-01-22 20:55:05 +0100254 jlog.trace("Authentication: found username " + unknown.getUsername());
Michael Hanl87106d12015-09-14 18:13:51 +0200255 if (unknown instanceof KorAPUser) {
256 if (password == null || password.isEmpty())
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200257 throw new WrappedException(new KustvaktException(
258 unknown.getId(), StatusCodes.BAD_CREDENTIALS),
Michael Hanl87106d12015-09-14 18:13:51 +0200259 StatusCodes.LOGIN_FAILED, username);
260
261 KorAPUser user = (KorAPUser) unknown;
262 boolean check = crypto.checkHash(password, user.getPassword());
263
264 if (!check) {
265 // the fail counter only applies for wrong password
266 jlog.warn("Wrong Password!");
267 processLoginFail(unknown);
268 throw new WrappedException(new KustvaktException(user.getId(),
269 StatusCodes.BAD_CREDENTIALS), StatusCodes.LOGIN_FAILED,
270 username);
271 }
272
273 // bad credentials error has presedence over account locked or unconfirmed codes
274 // since latter can lead to account guessing of third parties
275 if (user.isAccountLocked()) {
276 URIParam param = (URIParam) user.getField(URIParam.class);
277
278 if (param.hasValues()) {
279 jlog.debug("Account is not yet activated for user '{}'",
280 user.getUsername());
281 if (TimeUtils.getNow().isAfter(param.getUriExpiration())) {
Michael Hanlac113e52016-01-19 15:49:20 +0100282 jlog.error(
283 "URI token is expired. Deleting account for user {}",
284 user.getUsername());
Michael Hanl87106d12015-09-14 18:13:51 +0200285 deleteAccount(user);
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200286 throw new WrappedException(new KustvaktException(
287 unknown.getId(), StatusCodes.EXPIRED,
288 "account confirmation uri has expired",
289 param.getUriFragment()),
Michael Hanl87106d12015-09-14 18:13:51 +0200290 StatusCodes.LOGIN_FAILED, username);
291 }
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200292 throw new WrappedException(new KustvaktException(
293 unknown.getId(), StatusCodes.UNCONFIRMED_ACCOUNT),
Michael Hanl87106d12015-09-14 18:13:51 +0200294 StatusCodes.LOGIN_FAILED, username);
295 }
Michael Hanlac113e52016-01-19 15:49:20 +0100296 jlog.error("ACCESS DENIED: account not active for '{}'",
297 unknown.getUsername());
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200298 throw new WrappedException(new KustvaktException(
299 unknown.getId(), StatusCodes.ACCOUNT_DEACTIVATED),
Michael Hanl87106d12015-09-14 18:13:51 +0200300 StatusCodes.LOGIN_FAILED, username);
301 }
302
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200303 }
304 else if (unknown instanceof ShibUser) {
Michael Hanl87106d12015-09-14 18:13:51 +0200305 //todo
306 }
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200307 jlog.debug("Authentication done: " + username);
Michael Hanl87106d12015-09-14 18:13:51 +0200308 return unknown;
309 }
310
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200311
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200312 public boolean isRegistered (String username) {
Michael Hanl87106d12015-09-14 18:13:51 +0200313 User user;
314 if (username == null || username.isEmpty())
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200315 return false;
316 // throw new KustvaktException(username, StatusCodes.ILLEGAL_ARGUMENT,
317 // "username must be set", username);
Michael Hanl87106d12015-09-14 18:13:51 +0200318
319 try {
320 user = entHandler.getAccount(username);
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200321 }
322 catch (EmptyResultException e) {
Michael Hanl87106d12015-09-14 18:13:51 +0200323 jlog.debug("user does not exist ({})", username);
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200324 return false;
Michael Hanl87106d12015-09-14 18:13:51 +0200325
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200326 }
327 catch (KustvaktException e) {
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200328 jlog.error("KorAPException", e.string());
329 return false;
330 //throw new KustvaktException(username, StatusCodes.ILLEGAL_ARGUMENT,
331 // "username invalid", username);
Michael Hanl87106d12015-09-14 18:13:51 +0200332 }
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200333 return user != null;
Michael Hanl87106d12015-09-14 18:13:51 +0200334 }
335
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200336
337 public void logout (TokenContext context) throws KustvaktException {
Michael Hanl87106d12015-09-14 18:13:51 +0200338 try {
Michael Hanl19390652016-01-16 11:01:24 +0100339 AuthenticationIface provider = getProvider(context.getTokenType(),
340 null);
341
342 if (provider == null) {
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200343 throw new KustvaktException(StatusCodes.ILLEGAL_ARGUMENT,
344 "provider not supported!", context.getTokenType());
Michael Hanl19390652016-01-16 11:01:24 +0100345 }
Michael Hanl87106d12015-09-14 18:13:51 +0200346 provider.removeUserSession(context.getToken());
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200347 }
348 catch (KustvaktException e) {
Michael Hanl87106d12015-09-14 18:13:51 +0200349 throw new WrappedException(e, StatusCodes.LOGOUT_FAILED,
350 context.toString());
351 }
352 auditing.audit(AuditRecord.serviceRecord(context.getUsername(),
353 StatusCodes.LOGOUT_SUCCESSFUL, context.toString()));
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200354 this.removeCacheEntry(context.getToken());
Michael Hanl87106d12015-09-14 18:13:51 +0200355 }
356
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200357
358 private void processLoginFail (User user) throws KustvaktException {
Michael Hanl87106d12015-09-14 18:13:51 +0200359 counter.registerFail(user.getUsername());
360 if (!counter.validate(user.getUsername())) {
361 try {
362 this.lockAccount(user);
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200363 }
364 catch (KustvaktException e) {
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200365 jlog.error("user account could not be locked", e);
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200366 throw new WrappedException(e, StatusCodes.UPDATE_ACCOUNT_FAILED);
Michael Hanl87106d12015-09-14 18:13:51 +0200367 }
368 throw new WrappedException(new KustvaktException(user.getId(),
369 StatusCodes.ACCOUNT_DEACTIVATED), StatusCodes.LOGIN_FAILED);
370 }
371 }
372
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200373
374 public void lockAccount (User user) throws KustvaktException {
Michael Hanl87106d12015-09-14 18:13:51 +0200375 if (!(user instanceof KorAPUser))
376 throw new KustvaktException(StatusCodes.REQUEST_INVALID);
377
378 KorAPUser u = (KorAPUser) user;
379 u.setAccountLocked(true);
380 jlog.info("locking account for user: {}", user.getUsername());
381 entHandler.updateAccount(u);
382 }
383
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200384
385 public KorAPUser checkPasswordAllowance (KorAPUser user,
386 String oldPassword, String newPassword) throws KustvaktException {
Michael Hanl87106d12015-09-14 18:13:51 +0200387 String dbPassword = user.getPassword();
388
389 if (oldPassword.trim().equals(newPassword.trim())) {
390 // TODO: special error StatusCodes for this?
391 throw new WrappedException(new KustvaktException(user.getId(),
392 StatusCodes.ILLEGAL_ARGUMENT),
393 StatusCodes.PASSWORD_RESET_FAILED, newPassword);
394 }
395
396 boolean check = crypto.checkHash(oldPassword, dbPassword);
397
398 if (!check)
399 throw new WrappedException(new KustvaktException(user.getId(),
400 StatusCodes.BAD_CREDENTIALS),
401 StatusCodes.PASSWORD_RESET_FAILED);
402
403 try {
Michael Hanlcb2d3f92016-06-02 17:34:06 +0200404 user.setPassword(crypto.secureHash(newPassword));
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200405 }
406 catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
Michael Hanl87106d12015-09-14 18:13:51 +0200407 throw new WrappedException(new KustvaktException(user.getId(),
408 StatusCodes.ILLEGAL_ARGUMENT, "password invalid",
409 newPassword), StatusCodes.PASSWORD_RESET_FAILED,
410 user.toString(), newPassword);
411 }
412 return user;
413 }
414
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200415
Michael Hanl87106d12015-09-14 18:13:51 +0200416 //fixme: use clientinfo for logging/auditing?! = from where did he access the reset function?
417 @Override
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200418 public void resetPassword (String uriFragment, String username,
Michael Hanl87106d12015-09-14 18:13:51 +0200419 String newPassphrase) throws KustvaktException {
Michael Hanl87106d12015-09-14 18:13:51 +0200420 try {
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200421 validator.validateEntry(username, Attributes.USERNAME);
422 validator.validateEntry(newPassphrase, Attributes.PASSWORD);
423 } catch (KustvaktException e) {
424 jlog.error("Error: {}", e.string());
Michael Hanl87106d12015-09-14 18:13:51 +0200425 throw new WrappedException(new KustvaktException(username,
426 StatusCodes.ILLEGAL_ARGUMENT, "password invalid",
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200427 newPassphrase), StatusCodes.PASSWORD_RESET_FAILED,
428 username, newPassphrase);
Michael Hanl87106d12015-09-14 18:13:51 +0200429 }
430
431 try {
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200432 newPassphrase= crypto.secureHash(newPassphrase);
433 } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
Michael Hanlac113e52016-01-19 15:49:20 +0100434 jlog.error("Encoding/Algorithm Error", e);
Michael Hanl87106d12015-09-14 18:13:51 +0200435 throw new WrappedException(new KustvaktException(username,
436 StatusCodes.ILLEGAL_ARGUMENT, "password invalid",
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200437 newPassphrase), StatusCodes.PASSWORD_RESET_FAILED,
438 username, uriFragment, newPassphrase);
Michael Hanl87106d12015-09-14 18:13:51 +0200439 }
440 int result = entHandler
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200441 .resetPassphrase(username, uriFragment, newPassphrase);
Michael Hanl87106d12015-09-14 18:13:51 +0200442
443 if (result == 0)
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200444 throw new WrappedException(new KustvaktException(username,
445 StatusCodes.EXPIRED, "URI fragment expired", uriFragment),
Michael Hanl87106d12015-09-14 18:13:51 +0200446 StatusCodes.PASSWORD_RESET_FAILED, username, uriFragment);
447 else if (result == 1)
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200448 jlog.info("successfully reset password for user {}", username);
Michael Hanl87106d12015-09-14 18:13:51 +0200449 }
450
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200451
452 public void confirmRegistration (String uriFragment, String username)
Michael Hanl87106d12015-09-14 18:13:51 +0200453 throws KustvaktException {
Michael Hanl87106d12015-09-14 18:13:51 +0200454 try {
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200455 validator.validateEntry(username, Attributes.USERNAME);
456 } catch (KustvaktException e) {
457 jlog.error("Error: {}", e.string());
Michael Hanl87106d12015-09-14 18:13:51 +0200458 throw new WrappedException(e,
459 StatusCodes.ACCOUNT_CONFIRMATION_FAILED, username,
460 uriFragment);
461 }
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200462 int r = entHandler.activateAccount(username, uriFragment);
Michael Hanl87106d12015-09-14 18:13:51 +0200463 if (r == 0) {
464 User user;
465 try {
466 user = entHandler.getAccount(username);
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200467 }
468 catch (EmptyResultException e) {
Michael Hanl87106d12015-09-14 18:13:51 +0200469 throw new WrappedException(new KustvaktException(username,
470 StatusCodes.BAD_CREDENTIALS),
471 StatusCodes.ACCOUNT_CONFIRMATION_FAILED, username,
472 uriFragment);
473 }
474 entHandler.deleteAccount(user.getId());
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200475 throw new WrappedException(new KustvaktException(user.getId(),
476 StatusCodes.EXPIRED),
Michael Hanl87106d12015-09-14 18:13:51 +0200477 StatusCodes.ACCOUNT_CONFIRMATION_FAILED, username,
478 uriFragment);
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200479 }
480 else if (r == 1)
Michael Hanl87106d12015-09-14 18:13:51 +0200481 jlog.info("successfully confirmed user registration for user {}",
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200482 username);
Michael Hanl87106d12015-09-14 18:13:51 +0200483 // register successful audit!
484 }
485
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200486
Michael Hanl87106d12015-09-14 18:13:51 +0200487 /**
488 * @param attributes
489 * @return
490 * @throws KustvaktException
491 */
492 //fixme: remove clientinfo object (not needed), use json representation to get stuff
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200493 public User createUserAccount (Map<String, Object> attributes,
Michael Hanl5fac8ab2016-01-29 16:33:04 +0100494 boolean confirmation_required) throws KustvaktException {
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200495 Map<String, Object> safeMap = validator.validateMap(attributes);
496
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200497 if (safeMap.get(Attributes.USERNAME) == null
498 || ((String) safeMap.get(Attributes.USERNAME)).isEmpty())
Michael Hanl87106d12015-09-14 18:13:51 +0200499 throw new KustvaktException(StatusCodes.ILLEGAL_ARGUMENT,
500 "username must be set", "username");
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200501 if (safeMap.get(Attributes.PASSWORD) == null
502 || ((String) safeMap.get(Attributes.PASSWORD)).isEmpty())
Michael Hanl87106d12015-09-14 18:13:51 +0200503 throw new KustvaktException(safeMap.get(Attributes.USERNAME),
504 StatusCodes.ILLEGAL_ARGUMENT, "password must be set",
505 "password");
506
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200507 String username = validator.validateEntry(
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200508 (String) safeMap.get(Attributes.USERNAME), Attributes.USERNAME);
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200509 String password = validator.validateEntry(
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200510 (String) safeMap.get(Attributes.PASSWORD), Attributes.PASSWORD);
Michael Hanl87106d12015-09-14 18:13:51 +0200511 String hash;
512 try {
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200513 hash = crypto.secureHash(password);
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200514 }
515 catch (UnsupportedEncodingException | NoSuchAlgorithmException e) {
Michael Hanlac113e52016-01-19 15:49:20 +0100516 jlog.error("Encryption error", e);
Michael Hanl87106d12015-09-14 18:13:51 +0200517 throw new KustvaktException(StatusCodes.ILLEGAL_ARGUMENT);
518 }
519
Michael Hanle17eaa52016-01-22 20:55:05 +0100520 KorAPUser user = User.UserFactory.getUser(username);
Michael Hanldaf86602016-05-12 14:31:52 +0200521 Object id = attributes.get(Attributes.ID);
522 if (id != null && id instanceof Integer)
523 user.setId((Integer) id);
Michael Hanl7368aa42016-02-05 18:15:47 +0100524
Michael Hanldaf86602016-05-12 14:31:52 +0200525 user.setAccountLocked(confirmation_required);
Michael Hanle17eaa52016-01-22 20:55:05 +0100526 if (confirmation_required) {
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200527 URIParam param = new URIParam(crypto.createToken(), TimeUtils
528 .plusSeconds(config.getExpiration()).getMillis());
Michael Hanl19390652016-01-16 11:01:24 +0100529 user.addField(param);
530 }
Michael Hanl87106d12015-09-14 18:13:51 +0200531 user.setPassword(hash);
532 try {
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200533 UserDetails details = new UserDetails();
534 details.read(safeMap, true);
535
536 UserSettings settings = new UserSettings();
537 settings.read(safeMap, true);
538
Michael Hanlc4446022016-02-12 18:03:17 +0100539 jlog.info("Creating new user account for user {}",
540 user.getUsername());
Michael Hanl87106d12015-09-14 18:13:51 +0200541 entHandler.createAccount(user);
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200542 details.setUserId(user.getId());
543 settings.setUserId(user.getId());
Michael Hanl5fac8ab2016-01-29 16:33:04 +0100544
Michael Hanlf8fcc7a2016-06-03 17:41:07 +0200545 UserDataDbIface dao = BeansFactory.getTypeFactory()
546 .getTypeInterfaceBean(userdatadaos, UserDetails.class);
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200547 //todo: remove this
Michael Hanldaf86602016-05-12 14:31:52 +0200548 assert dao != null;
549 dao.store(details);
Michael Hanlf8fcc7a2016-06-03 17:41:07 +0200550 dao = BeansFactory.getTypeFactory().getTypeInterfaceBean(
551 userdatadaos, UserSettings.class);
Michael Hanldaf86602016-05-12 14:31:52 +0200552 assert dao != null;
553 dao.store(settings);
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200554 }
555 catch (KustvaktException e) {
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200556 jlog.error("Error: {}", e.string());
Michael Hanl87106d12015-09-14 18:13:51 +0200557 throw new WrappedException(e, StatusCodes.CREATE_ACCOUNT_FAILED,
558 user.toString());
559 }
560
561 auditing.audit(AuditRecord.serviceRecord(user.getUsername(),
562 StatusCodes.CREATE_ACCOUNT_SUCCESSFUL));
563 return user;
564 }
565
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200566
Michael Hanl87106d12015-09-14 18:13:51 +0200567 //todo:
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200568 private ShibUser createShibbUserAccount (Map<String, Object> attributes)
Michael Hanl87106d12015-09-14 18:13:51 +0200569 throws KustvaktException {
570 jlog.debug("creating shibboleth user account for user attr: {}",
571 attributes);
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200572 Map<String, Object> safeMap = validator.validateMap(attributes);
Michael Hanl87106d12015-09-14 18:13:51 +0200573
574 //todo eppn non-unique.join with idp or use persistent_id as username identifier
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200575 ShibUser user = User.UserFactory.getShibInstance(
576 (String) safeMap.get(Attributes.EPPN),
577 (String) safeMap.get(Attributes.MAIL),
578 (String) safeMap.get(Attributes.CN));
Michael Hanl87106d12015-09-14 18:13:51 +0200579 user.setAffiliation((String) safeMap.get(Attributes.EDU_AFFIL));
Michael Hanl87106d12015-09-14 18:13:51 +0200580 user.setAccountCreation(TimeUtils.getNow().getMillis());
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200581
582
583 UserDetails d = new UserDetails();
584 d.read(attributes, true);
585
586 UserSettings s = new UserSettings();
587 s.read(attributes, true);
588
Michael Hanl87106d12015-09-14 18:13:51 +0200589 entHandler.createAccount(user);
Michael Hanl25aac542016-02-01 18:16:44 +0100590
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200591 s.setUserId(user.getId());
592 d.setUserId(user.getId());
Michael Hanl25aac542016-02-01 18:16:44 +0100593
Michael Hanlf8fcc7a2016-06-03 17:41:07 +0200594 UserDataDbIface dao = BeansFactory.getTypeFactory()
595 .getTypeInterfaceBean(userdatadaos, UserDetails.class);
Michael Hanldaf86602016-05-12 14:31:52 +0200596 assert dao != null;
597 dao.store(d);
Michael Hanl25aac542016-02-01 18:16:44 +0100598
Michael Hanlf8fcc7a2016-06-03 17:41:07 +0200599 dao = BeansFactory.getTypeFactory().getTypeInterfaceBean(userdatadaos,
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200600 UserSettings.class);
Michael Hanldaf86602016-05-12 14:31:52 +0200601 assert dao != null;
602 dao.store(d);
Michael Hanl25aac542016-02-01 18:16:44 +0100603
Michael Hanl87106d12015-09-14 18:13:51 +0200604 return user;
605 }
606
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200607
Michael Hanl87106d12015-09-14 18:13:51 +0200608 /**
609 * link shibboleth and korap user account to one another.
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200610 *
611 * @param current
612 * currently logged in user
613 * @param for_name
614 * foreign user name the current account should be
615 * linked to
616 * @param transstrat
617 * transfer status of user data (details, settings,
618 * user queries)
619 * 0 = the currently logged in data should be kept
620 * 1 = the foreign account data should be kept
Michael Hanl87106d12015-09-14 18:13:51 +0200621 * @throws NotAuthorizedException
622 * @throws KustvaktException
623 */
624 // todo:
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200625 public void accountLink (User current, String for_name, int transstrat)
Michael Hanl87106d12015-09-14 18:13:51 +0200626 throws KustvaktException {
627 // User foreign = entHandler.getAccount(for_name);
628
629 // if (current.getAccountLink() == null && current.getAccountLink()
630 // .isEmpty()) {
631 // if (current instanceof KorAPUser && foreign instanceof ShibUser) {
632 // if (transstrat == 1)
633 // current.transfer(foreign);
634 //// foreign.setAccountLink(current.getUsername());
635 //// current.setAccountLink(foreign.getUsername());
636 // // entHandler.purgeDetails(foreign);
637 // // entHandler.purgeSettings(foreign);
638 // }else if (foreign instanceof KorAPUser
639 // && current instanceof ShibUser) {
640 // if (transstrat == 0)
641 // foreign.transfer(current);
642 //// current.setAccountLink(foreign.getUsername());
643 // // entHandler.purgeDetails(current);
644 // // entHandler.purgeSettings(current);
645 // // entHandler.purgeSettings(current);
646 // }
647 // entHandler.updateAccount(current);
648 // entHandler.updateAccount(foreign);
649 // }
650 }
651
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200652
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200653 // todo: test and rest usage?!
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200654 public boolean updateAccount (User user) throws KustvaktException {
Michael Hanl87106d12015-09-14 18:13:51 +0200655 boolean result;
Michael Hanl87106d12015-09-14 18:13:51 +0200656 if (user instanceof DemoUser)
657 throw new KustvaktException(user.getId(),
658 StatusCodes.REQUEST_INVALID,
659 "account not updateable for demo user", user.getUsername());
660 else {
Michael Hanle17eaa52016-01-22 20:55:05 +0100661 // crypto.validate(user);
Michael Hanl87106d12015-09-14 18:13:51 +0200662 try {
663 result = entHandler.updateAccount(user) > 0;
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200664 }
665 catch (KustvaktException e) {
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200666 jlog.error("Error: {}", e.string());
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200667 throw new WrappedException(e, StatusCodes.UPDATE_ACCOUNT_FAILED);
Michael Hanl87106d12015-09-14 18:13:51 +0200668 }
669 }
670 if (result) {
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200671 // this.removeCacheEntry(user.getUsername());
Michael Hanl87106d12015-09-14 18:13:51 +0200672 auditing.audit(AuditRecord.serviceRecord(user.getId(),
673 StatusCodes.UPDATE_ACCOUNT_SUCCESSFUL, user.toString()));
674 }
675 return result;
676 }
677
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200678
679 public boolean deleteAccount (User user) throws KustvaktException {
Michael Hanl87106d12015-09-14 18:13:51 +0200680 boolean result;
Michael Hanl87106d12015-09-14 18:13:51 +0200681 if (user instanceof DemoUser)
682 return true;
683 else {
684 try {
685 result = entHandler.deleteAccount(user.getId()) > 0;
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200686 }
687 catch (KustvaktException e) {
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200688 jlog.error("Error: {}", e.string());
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200689 throw new WrappedException(e, StatusCodes.DELETE_ACCOUNT_FAILED);
Michael Hanl87106d12015-09-14 18:13:51 +0200690 }
691 }
692 if (result) {
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200693 // this.removeCacheEntry(user.getUsername());
Michael Hanl87106d12015-09-14 18:13:51 +0200694 auditing.audit(AuditRecord.serviceRecord(user.getUsername(),
695 StatusCodes.DELETE_ACCOUNT_SUCCESSFUL, user.toString()));
696 }
697 return result;
698 }
699
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200700
701 public Object[] validateResetPasswordRequest (String username, String email)
Michael Hanl87106d12015-09-14 18:13:51 +0200702 throws KustvaktException {
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200703 String uritoken;
704 validator.validateEntry(email, Attributes.EMAIL);
Michael Hanl87106d12015-09-14 18:13:51 +0200705 User ident;
706 try {
707 ident = entHandler.getAccount(username);
708 if (ident instanceof DemoUser)
709 // throw new NotAuthorizedException(StatusCodes.PERMISSION_DENIED,
710 // "password reset now allowed for DemoUser", "");
711 throw new WrappedException(username,
712 StatusCodes.PASSWORD_RESET_FAILED, username);
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200713 }
714 catch (EmptyResultException e) {
Michael Hanl87106d12015-09-14 18:13:51 +0200715 throw new WrappedException(new KustvaktException(username,
716 StatusCodes.ILLEGAL_ARGUMENT, "username not found",
717 username), StatusCodes.PASSWORD_RESET_FAILED, username);
718 }
719
Michael Hanl5dd931a2016-01-29 16:40:38 +0100720 Userdata data = this.getUserData(ident, UserDetails.class);
Michael Hanl87106d12015-09-14 18:13:51 +0200721 KorAPUser user = (KorAPUser) ident;
Michael Hanl5fac8ab2016-01-29 16:33:04 +0100722
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200723 if (!email.equals(data.get(Attributes.EMAIL)))
Michael Hanl87106d12015-09-14 18:13:51 +0200724 // throw new NotAuthorizedException(StatusCodes.ILLEGAL_ARGUMENT,
725 // "invalid parameter: email", "email");
726 throw new WrappedException(new KustvaktException(user.getId(),
727 StatusCodes.ILLEGAL_ARGUMENT, "email invalid", email),
728 StatusCodes.PASSWORD_RESET_FAILED, email);
729 uritoken = crypto.encodeBase();
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200730 URIParam param = new URIParam(uritoken, TimeUtils.plusHours(24)
731 .getMillis());
Michael Hanl87106d12015-09-14 18:13:51 +0200732 user.addField(param);
733
734 try {
735 entHandler.updateAccount(user);
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200736 }
737 catch (KustvaktException e) {
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200738 jlog.error("Error ", e.string());
Michael Hanl87106d12015-09-14 18:13:51 +0200739 throw new WrappedException(e, StatusCodes.PASSWORD_RESET_FAILED);
740 }
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200741 return new Object[] { uritoken, TimeUtils.format(param.getUriExpiration()) };
Michael Hanl87106d12015-09-14 18:13:51 +0200742 }
743
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200744
Michael Hanlc2a9f622016-01-28 16:40:06 +0100745 @Override
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200746 public <T extends Userdata> T getUserData (User user, Class<T> clazz)
Michael Hanl5fac8ab2016-01-29 16:33:04 +0100747 throws WrappedException {
748
749 try {
Michael Hanlf8fcc7a2016-06-03 17:41:07 +0200750 UserDataDbIface<T> dao = BeansFactory.getTypeFactory()
751 .getTypeInterfaceBean(
752 BeansFactory.getKustvaktContext()
753 .getUserDataProviders(), clazz);
Michael Hanldaf86602016-05-12 14:31:52 +0200754 T data = null;
755 if (dao != null)
756 data = dao.get(user);
757
Michael Hanl7368aa42016-02-05 18:15:47 +0100758 if (data == null)
Michael Hanle56bb892016-05-25 17:34:41 +0200759 throw new KustvaktException(user.getId(),
Michael Hanl33829ec2016-05-28 17:03:38 +0200760 StatusCodes.EMPTY_RESULTS, "No data found!",
761 clazz.getSimpleName());
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200762 return data;
763 }
764 catch (KustvaktException e) {
Michael Hanl00ef5462016-06-06 17:39:59 +0200765 jlog.error("Error during user data retrieval: {}", e.getEntity());
Michael Hanl5fac8ab2016-01-29 16:33:04 +0100766 throw new WrappedException(e, StatusCodes.GET_ACCOUNT_FAILED);
767 }
Michael Hanl4f9002d2016-01-27 23:21:45 +0100768 }
769
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200770
Michael Hanl4f9002d2016-01-27 23:21:45 +0100771 //todo: cache userdata outside of the user object!
Michael Hanlc2a9f622016-01-28 16:40:06 +0100772 @Override
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200773 public void updateUserData (Userdata data) throws WrappedException {
Michael Hanl87106d12015-09-14 18:13:51 +0200774 try {
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200775 data.validate(this.validator);
Michael Hanlf8fcc7a2016-06-03 17:41:07 +0200776 UserDataDbIface dao = BeansFactory.getTypeFactory()
777 .getTypeInterfaceBean(
778 BeansFactory.getKustvaktContext()
779 .getUserDataProviders(), data.getClass());
Michael Hanldaf86602016-05-12 14:31:52 +0200780 if (dao != null)
781 dao.update(data);
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200782 }
783 catch (KustvaktException e) {
Michael Hanle56bb892016-05-25 17:34:41 +0200784 jlog.error("Error during update of user data!", e.getEntity());
Michael Hanl5fac8ab2016-01-29 16:33:04 +0100785 throw new WrappedException(e, StatusCodes.UPDATE_ACCOUNT_FAILED);
Michael Hanl87106d12015-09-14 18:13:51 +0200786 }
Michael Hanl87106d12015-09-14 18:13:51 +0200787 }
Michael Hanl87106d12015-09-14 18:13:51 +0200788}