comparison src/main/java/de/intevation/lada/util/auth/HeaderAuthorization.java @ 833:fa922101a462

Refactored Authorization. * Introduced "authorizer" * Attribute and datatype depended authorization
author Raimund Renkert <raimund.renkert@intevation.de>
date Fri, 08 Jan 2016 12:05:26 +0100
parents d0510a89e701
children 2fe625c91ab3
comparison
equal deleted inserted replaced
832:59c51da59b30 833:fa922101a462
5 * and comes with ABSOLUTELY NO WARRANTY! Check out 5 * and comes with ABSOLUTELY NO WARRANTY! Check out
6 * the documentation coming with IMIS-Labordaten-Application for details. 6 * the documentation coming with IMIS-Labordaten-Application for details.
7 */ 7 */
8 package de.intevation.lada.util.auth; 8 package de.intevation.lada.util.auth;
9 9
10 import java.lang.reflect.InvocationTargetException;
11 import java.lang.reflect.Method;
12 import java.util.ArrayList; 10 import java.util.ArrayList;
13 import java.util.Arrays; 11 import java.util.Arrays;
12 import java.util.HashMap;
14 import java.util.List; 13 import java.util.List;
15 14 import java.util.Map;
15
16 import javax.annotation.PostConstruct;
16 import javax.inject.Inject; 17 import javax.inject.Inject;
17 import javax.persistence.EntityManager; 18 import javax.persistence.EntityManager;
18 import javax.servlet.http.HttpServletRequest; 19 import javax.servlet.http.HttpServletRequest;
19 20
20 import org.apache.log4j.Logger; 21 import de.intevation.lada.model.land.LKommentarM;
21 22 import de.intevation.lada.model.land.LKommentarP;
22 import de.intevation.lada.model.land.LMessung; 23 import de.intevation.lada.model.land.LMessung;
24 import de.intevation.lada.model.land.LMesswert;
25 import de.intevation.lada.model.land.LOrtszuordnung;
23 import de.intevation.lada.model.land.LProbe; 26 import de.intevation.lada.model.land.LProbe;
24 import de.intevation.lada.model.land.LStatusProtokoll; 27 import de.intevation.lada.model.land.LStatusProtokoll;
28 import de.intevation.lada.model.land.LZusatzWert;
25 import de.intevation.lada.model.stamm.Auth; 29 import de.intevation.lada.model.stamm.Auth;
26 import de.intevation.lada.model.stamm.AuthLstUmw; 30 import de.intevation.lada.model.stamm.DatensatzErzeuger;
31 import de.intevation.lada.model.stamm.MessprogrammKategorie;
32 import de.intevation.lada.model.stamm.Ort;
33 import de.intevation.lada.model.stamm.Probenehmer;
27 import de.intevation.lada.util.annotation.AuthorizationConfig; 34 import de.intevation.lada.util.annotation.AuthorizationConfig;
28 import de.intevation.lada.util.annotation.RepositoryConfig; 35 import de.intevation.lada.util.annotation.RepositoryConfig;
29 import de.intevation.lada.util.data.QueryBuilder; 36 import de.intevation.lada.util.data.QueryBuilder;
30 import de.intevation.lada.util.data.Repository; 37 import de.intevation.lada.util.data.Repository;
31 import de.intevation.lada.util.data.RepositoryType; 38 import de.intevation.lada.util.data.RepositoryType;
39 */ 46 */
40 @AuthorizationConfig(type=AuthorizationType.HEADER) 47 @AuthorizationConfig(type=AuthorizationType.HEADER)
41 public class HeaderAuthorization implements Authorization { 48 public class HeaderAuthorization implements Authorization {
42 49
43 /** 50 /**
44 * The logger used in this class.
45 */
46 @Inject
47 private Logger logger;
48
49 /**
50 * The Repository used to read from Database. 51 * The Repository used to read from Database.
51 */ 52 */
52 @Inject 53 @Inject
53 @RepositoryConfig(type=RepositoryType.RO) 54 @RepositoryConfig(type=RepositoryType.RO)
54 private Repository repository; 55 private Repository repository;
56
57 @SuppressWarnings("rawtypes")
58 private Map<Class, Authorizer> authorizers;
59 @Inject ProbeAuthorizer probeAuthorizer;
60 @Inject MessungAuthorizer messungAuthorizer;
61 @Inject ProbeIdAuthorizer pIdAuthorizer;
62 @Inject MessungIdAuthorizer mIdAuthorizer;
63 @Inject NetzbetreiberAuthorizer netzAuthorizer;
64
65 @SuppressWarnings("rawtypes")
66 @PostConstruct
67 public void init() {
68 authorizers = new HashMap<Class, Authorizer>();
69 authorizers.put(LProbe.class, probeAuthorizer);
70 authorizers.put(LMessung.class, messungAuthorizer);
71 authorizers.put(LOrtszuordnung.class, pIdAuthorizer);
72 authorizers.put(LKommentarP.class, pIdAuthorizer);
73 authorizers.put(LZusatzWert.class, pIdAuthorizer);
74 authorizers.put(LKommentarM.class, mIdAuthorizer);
75 authorizers.put(LMesswert.class, mIdAuthorizer);
76 authorizers.put(LStatusProtokoll.class, mIdAuthorizer);
77 authorizers.put(Probenehmer.class, netzAuthorizer);
78 authorizers.put(DatensatzErzeuger.class, netzAuthorizer);
79 authorizers.put(MessprogrammKategorie.class, netzAuthorizer);
80 authorizers.put(Ort.class, netzAuthorizer);
81 }
55 82
56 /** 83 /**
57 * Request user informations using the HttpServletRequest. 84 * Request user informations using the HttpServletRequest.
58 * 85 *
59 * @param source The HttpServletRequest 86 * @param source The HttpServletRequest
87 public <T> Response filter(Object source, Response data, Class<T> clazz) { 114 public <T> Response filter(Object source, Response data, Class<T> clazz) {
88 UserInfo userInfo = this.getInfo(source); 115 UserInfo userInfo = this.getInfo(source);
89 if (userInfo == null) { 116 if (userInfo == null) {
90 return data; 117 return data;
91 } 118 }
92 if (clazz == LProbe.class) { 119 Authorizer authorizer = authorizers.get(clazz);
93 return this.authorizeProbe(userInfo, data); 120 //This is a hack... Allows wildcard for unknown classes.
94 } 121 if (authorizer == null) {
95 if (clazz == LMessung.class) { 122 return data;
96 return this.authorizeMessung(userInfo, data); 123 }
97 } 124 return authorizer.filter(data, userInfo, clazz);
98 Method[] methods = clazz.getMethods();
99 for (Method method: methods) {
100 if (method.getName().equals("getProbeId")) {
101 return this.authorizeWithProbeId(userInfo, data, clazz);
102 }
103 if (method.getName().equals("getMessungsId")) {
104 return this.authorizeWithMessungsId(userInfo, data, clazz);
105 }
106 }
107 return data;
108 }
109
110 @Override
111 public <T> boolean isAuthorized(int id, Class<T> clazz) {
112 if (clazz == LMessung.class) {
113 LMessung messung = repository.getByIdPlain(
114 LMessung.class,
115 id,
116 "land");
117 if (messung.getStatus() == null) {
118 return false;
119 }
120 LStatusProtokoll status = repository.getByIdPlain(
121 LStatusProtokoll.class,
122 messung.getStatus(),
123 "land");
124 if (status.getStatusWert() == 0) {
125 return false;
126 }
127 return true;
128 }
129 return false;
130 } 125 }
131 126
132 /** 127 /**
133 * Check whether a user is authorized to operate on the given data. 128 * Check whether a user is authorized to operate on the given data.
134 * 129 *
147 ) { 142 ) {
148 UserInfo userInfo = this.getInfo(source); 143 UserInfo userInfo = this.getInfo(source);
149 if (userInfo == null) { 144 if (userInfo == null) {
150 return false; 145 return false;
151 } 146 }
152 if (clazz == LProbe.class) { 147 Authorizer authorizer = authorizers.get(clazz);
153 LProbe probe = (LProbe)data; 148 //This is a hack... Allows wildcard for unknown classes.
154 if (method == RequestMethod.POST) { 149 if (authorizer == null) {
155 return getAuthorization(userInfo, probe);
156 }
157 else if (method == RequestMethod.PUT ||
158 method == RequestMethod.DELETE) {
159 return !isReadOnly(probe.getId());
160 }
161 else {
162 return false;
163 }
164 }
165 else if (clazz == LMessung.class) {
166 LMessung messung = (LMessung)data;
167 Response response =
168 repository.getById(LProbe.class, messung.getProbeId(), "land");
169 LProbe probe = (LProbe)response.getData();
170 if (method == RequestMethod.POST) {
171 return getAuthorization(userInfo, probe);
172 }
173 else if (method == RequestMethod.PUT ||
174 method == RequestMethod.DELETE) {
175 return !this.isMessungReadOnly(messung) &&
176 getAuthorization(userInfo, probe);
177 }
178 }
179 else {
180 Method[] methods = clazz.getMethods();
181 for (Method m: methods) {
182 if (m.getName().equals("getProbeId")) {
183 Integer id;
184 try {
185 id = (Integer) m.invoke(data);
186 } catch (IllegalAccessException | IllegalArgumentException
187 | InvocationTargetException e) {
188 logger.warn(e.getCause() + ": " + e.getMessage());
189 return false;
190 }
191 Response response =
192 repository.getById(LProbe.class, id, "land");
193 LProbe probe = (LProbe)response.getData();
194 return !isReadOnly(id) && getAuthorization(userInfo, probe);
195
196 }
197 if (m.getName().equals("getMessungsId")) {
198 Integer id;
199 try {
200 id = (Integer) m.invoke(data);
201 } catch (IllegalAccessException | IllegalArgumentException
202 | InvocationTargetException e) {
203 logger.warn(e.getCause() + ": " + e.getMessage());
204 return false;
205 }
206 Response mResponse =
207 repository.getById(LMessung.class, id, "land");
208 LMessung messung = (LMessung)mResponse.getData();
209 Response pResponse =
210 repository.getById(
211 LProbe.class,
212 messung.getProbeId(),
213 "land");
214 LProbe probe = (LProbe)pResponse.getData();
215 if (messung.getStatus() == null) {
216 return false;
217 }
218 LStatusProtokoll status = repository.getByIdPlain(
219 LStatusProtokoll.class,
220 messung.getStatus(),
221 "land");
222 return status.getStatusWert() == 0 &&
223 getAuthorization(userInfo, probe);
224 }
225 }
226 }
227 return true;
228 }
229
230 /**
231 * Get the authorization of a single probe.
232 *
233 * @param userInfo The user information.
234 * @param probe The probe to authorize.
235 */
236 private boolean getAuthorization(UserInfo userInfo, LProbe probe) {
237 if (userInfo.getMessstellen().contains(probe.getMstId())) {
238 return true; 150 return true;
239 } 151 }
240 else { 152 return authorizer.isAuthorized(data, method, userInfo, clazz);
241 return false;
242 }
243 } 153 }
244 154
245 /** 155 /**
246 * Request the lada specific groups. 156 * Request the lada specific groups.
247 * 157 *
283 userInfo.setFunktionen(funktionen); 193 userInfo.setFunktionen(funktionen);
284 return userInfo; 194 return userInfo;
285 } 195 }
286 196
287 /** 197 /**
288 * Authorize data that has a messungsId Attribute.
289 *
290 * @param userInfo The user information.
291 * @param data The Response object containing the data.
292 * @param clazz The data object class.
293 * @return A Response object containing the data.
294 */
295 @SuppressWarnings("unchecked")
296 private <T> Response authorizeWithMessungsId(
297 UserInfo userInfo,
298 Response data,
299 Class<T> clazz
300 ) {
301 if (data.getData() instanceof List<?>) {
302 List<Object> objects = new ArrayList<Object>();
303 for (Object object :(List<Object>)data.getData()) {
304 objects.add(authorizeSingleWithMessungsId(userInfo, object, clazz));
305 }
306 data.setData(objects);
307 }
308 else {
309 Object object = data.getData();
310 data.setData(authorizeSingleWithMessungsId(userInfo, object, clazz));
311 }
312 return data;
313 }
314
315 /**
316 * Authorize data that has a probeId Attribute.
317 *
318 * @param userInfo The user information.
319 * @param data The Response object containing the data.
320 * @param clazz The data object class.
321 * @return A Response object containing the data.
322 */
323 @SuppressWarnings("unchecked")
324 private <T> Response authorizeWithProbeId(
325 UserInfo userInfo,
326 Response data,
327 Class<T> clazz
328 ) {
329 if (data.getData() instanceof List<?>) {
330 List<Object> objects = new ArrayList<Object>();
331 for (Object object :(List<Object>)data.getData()) {
332 objects.add(authorizeSingleWithProbeId(
333 userInfo,
334 object,
335 clazz));
336 }
337 data.setData(objects);
338 }
339 else {
340 Object object = data.getData();
341 data.setData(authorizeSingleWithProbeId(userInfo, object, clazz));
342 }
343 return data;
344 }
345
346 /**
347 * Authorize a single data object that has a messungsId Attribute.
348 *
349 * @param userInfo The user information.
350 * @param data The Response object containing the data.
351 * @param clazz The data object class.
352 * @return A Response object containing the data.
353 */
354 private <T> Object authorizeSingleWithMessungsId(
355 UserInfo userInfo,
356 Object data,
357 Class<T> clazz
358 ) {
359 try {
360 Method getMessungsId = clazz.getMethod("getMessungsId");
361 Integer id = (Integer)getMessungsId.invoke(data);
362 LMessung messung =
363 (LMessung)repository.getById(
364 LMessung.class, id, "land").getData();
365 LProbe probe =
366 (LProbe)repository.getById(
367 LProbe.class, messung.getProbeId(), "land").getData();
368
369 boolean readOnly = true;
370 boolean owner = false;
371 if (!userInfo.getNetzbetreiber().contains(
372 probe.getNetzbetreiberId())) {
373 owner = false;
374 readOnly = true;
375 }
376 else {
377 if (userInfo.getMessstellen().contains(probe.getMstId())) {
378 owner = true;
379 }
380 else {
381 owner = false;
382 }
383 readOnly = this.isMessungReadOnly(messung);
384 }
385
386 Method setOwner = clazz.getMethod("setOwner", boolean.class);
387 Method setReadonly = clazz.getMethod("setReadonly", boolean.class);
388 setOwner.invoke(data, owner);
389 setReadonly.invoke(data, readOnly);
390 } catch (NoSuchMethodException | SecurityException
391 | IllegalAccessException | IllegalArgumentException
392 | InvocationTargetException e) {
393 return null;
394 }
395 return data;
396 }
397
398 /**
399 * Authorize a single data object that has a probeId Attribute.
400 *
401 * @param userInfo The user information.
402 * @param data The Response object containing the data.
403 * @param clazz The data object class.
404 * @return A Response object containing the data.
405 */
406 private <T> Object authorizeSingleWithProbeId(
407 UserInfo userInfo,
408 Object data,
409 Class<T> clazz
410 ) {
411 try {
412 Method getProbeId = clazz.getMethod("getProbeId");
413 Integer id = null;
414 if (getProbeId != null) {
415 id = (Integer) getProbeId.invoke(data);
416 }
417 else {
418 return null;
419 }
420 LProbe probe =
421 (LProbe)repository.getById(LProbe.class, id, "land").getData();
422
423 boolean readOnly = true;
424 boolean owner = false;
425 if (!userInfo.getNetzbetreiber().contains(
426 probe.getNetzbetreiberId())) {
427 owner = false;
428 readOnly = true;
429 }
430 else {
431 if (userInfo.getMessstellen().contains(probe.getMstId())) {
432 owner = true;
433 }
434 else {
435 owner = false;
436 }
437 readOnly = this.isReadOnly(id);
438 }
439
440 Method setOwner = clazz.getMethod("setOwner", boolean.class);
441 Method setReadonly = clazz.getMethod("setReadonly", boolean.class);
442 setOwner.invoke(data, owner);
443 setReadonly.invoke(data, readOnly);
444 } catch (NoSuchMethodException | SecurityException
445 | IllegalAccessException | IllegalArgumentException
446 | InvocationTargetException e) {
447 return null;
448 }
449 return data;
450 }
451
452 /**
453 * Authorize probe objects.
454 *
455 * @param userInfo The user information.
456 * @param data The Response object containing the probe objects.
457 * @return A Response object containing the data.
458 */
459 @SuppressWarnings("unchecked")
460 private Response authorizeProbe(UserInfo userInfo, Response data) {
461 if (data.getData() instanceof List<?>) {
462 List<LProbe> proben = new ArrayList<LProbe>();
463 for (LProbe probe :(List<LProbe>)data.getData()) {
464 proben.add(authorizeSingleProbe(userInfo, probe));
465 }
466 data.setData(proben);
467 }
468 else if (data.getData() instanceof LProbe) {
469 LProbe probe = (LProbe)data.getData();
470 data.setData(authorizeSingleProbe(userInfo, probe));
471 }
472 return data;
473 }
474
475 /**
476 * Authorize a sinle probe object.
477 *
478 * @param userInfo The user information.
479 * @param probe The probe object.
480 * @return The probe.
481 */
482 private LProbe authorizeSingleProbe(UserInfo userInfo, LProbe probe) {
483 if (!userInfo.getNetzbetreiber().contains(probe.getNetzbetreiberId())) {
484 probe.setOwner(false);
485 probe.setReadonly(true);
486 return probe;
487 }
488 if (userInfo.getMessstellen().contains(probe.getMstId())) {
489 probe.setOwner(true);
490 }
491 else {
492 probe.setOwner(false);
493 }
494 probe.setReadonly(this.isReadOnly(probe.getId()));
495 return probe;
496 }
497
498 /**
499 * Authorize messung objects.
500 *
501 * @param userInfo The user information.
502 * @param data The Response object containing the messung objects.
503 * @return A Response object containing the data.
504 */
505 @SuppressWarnings("unchecked")
506 private Response authorizeMessung(UserInfo userInfo, Response data) {
507 if (data.getData() instanceof List<?>) {
508 List<LMessung> messungen = new ArrayList<LMessung>();
509 for (LMessung messung :(List<LMessung>)data.getData()) {
510 messungen.add(authorizeSingleMessung(userInfo, messung));
511 }
512 data.setData(messungen);
513 }
514 else if (data.getData() instanceof LMessung) {
515 LMessung messung = (LMessung)data.getData();
516 data.setData(authorizeSingleMessung(userInfo, messung));
517 }
518 return data;
519 }
520
521 /**
522 * Authorize a sinle messung object.
523 *
524 * @param userInfo The user information.
525 * @param messung The messung object.
526 * @return The messung.
527 */
528 private LMessung authorizeSingleMessung(
529 UserInfo userInfo,
530 LMessung messung
531 ) {
532 LProbe probe =
533 (LProbe)repository.getById(
534 LProbe.class, messung.getProbeId(), "land").getData();
535 if (!userInfo.getNetzbetreiber().contains(probe.getNetzbetreiberId())) {
536 messung.setOwner(false);
537 messung.setReadonly(true);
538 return messung;
539 }
540 if (userInfo.getMessstellen().contains(probe.getMstId())) {
541 messung.setOwner(true);
542 }
543 else {
544 messung.setOwner(false);
545 }
546 if (messung.getStatus() == null) {
547 messung.setReadonly(false);
548 }
549 else {
550 LStatusProtokoll status = repository.getByIdPlain(
551 LStatusProtokoll.class,
552 messung.getStatus(),
553 "land");
554 messung.setReadonly(
555 status.getStatusWert() != 0 && status.getStatusWert() != 4);
556 }
557
558 boolean statusEdit = false;
559 if (userInfo.getFunktionen().contains(3)) {
560 QueryBuilder<AuthLstUmw> lstFilter = new QueryBuilder<AuthLstUmw>(
561 repository.entityManager("stamm"),
562 AuthLstUmw.class);
563 lstFilter.or("lstId", userInfo.getMessstellen());
564 List<AuthLstUmw> lsts =
565 repository.filterPlain(lstFilter.getQuery(), "stamm");
566 for (int i = 0; i < lsts.size(); i++) {
567 if (lsts.get(i).getUmwId().equals(probe.getUmwId())) {
568 statusEdit = true;
569 }
570 }
571 }
572 else if (userInfo.getFunktionen().contains(2) &&
573 userInfo.getNetzbetreiber().contains(probe.getNetzbetreiberId())) {
574 statusEdit = true;
575 }
576 else if (userInfo.getFunktionen().contains(1) &&
577 userInfo.getMessstellen().contains(probe.getMstId())) {
578 statusEdit = true;
579 }
580 messung.setStatusEdit(statusEdit);
581
582 return messung;
583 }
584
585 /**
586 * Test whether a probe is readonly. 198 * Test whether a probe is readonly.
587 * 199 *
588 * @param probeId The probe Id. 200 * @param probeId The probe Id.
589 * @return True if the probe is readonly. 201 * @return True if the probe is readonly.
590 */ 202 */
618 * @param userInfo The user information. 230 * @param userInfo The user information.
619 * @param data The probe data to test. 231 * @param data The probe data to test.
620 * @return True if the user is authorized else returns false. 232 * @return True if the user is authorized else returns false.
621 */ 233 */
622 @Override 234 @Override
623 public boolean isAuthorized(UserInfo userInfo, Object data) { 235 public <T> boolean isAuthorized(
624 if (data instanceof LProbe) { 236 UserInfo userInfo,
625 return getAuthorization(userInfo, (LProbe)data); 237 Object data,
626 } 238 Class<T> clazz
627 else if (data instanceof LMessung) { 239 ) {
628 LProbe probe = repository.getByIdPlain(LProbe.class, ((LMessung)data).getProbeId(), "land"); 240 Authorizer authorizer = authorizers.get(clazz);
629 return getAuthorization(userInfo, probe); 241 //This is a hack... Allows wildcard for unknown classes.
630 } 242 if (authorizer == null) {
631 return false; 243 return true;
632 } 244 }
633 245 return authorizer.isAuthorized(data, RequestMethod.GET, userInfo, clazz);
634 private boolean isMessungReadOnly(LMessung messung) {
635 if (messung.getStatus() == null) {
636 return false;
637 }
638 LStatusProtokoll status = repository.getByIdPlain(
639 LStatusProtokoll.class,
640 messung.getStatus(),
641 "land");
642 return (status.getStatusWert() != 0 && status.getStatusWert() != 4);
643 } 246 }
644 } 247 }
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)