1
2
3
4
5
6
7 package ch.colabproject.colab.api.security.permissions;
8
9 import ch.colabproject.colab.api.controller.RequestManager;
10 import ch.colabproject.colab.api.controller.security.SecurityManager;
11 import ch.colabproject.colab.api.model.card.Card;
12 import ch.colabproject.colab.api.model.card.CardContent;
13 import ch.colabproject.colab.api.model.project.Project;
14 import ch.colabproject.colab.api.model.user.User;
15 import java.util.List;
16 import java.util.Objects;
17 import org.apache.commons.lang3.builder.EqualsBuilder;
18 import org.apache.commons.lang3.builder.HashCodeBuilder;
19 import org.slf4j.Logger;
20 import org.slf4j.LoggerFactory;
21
22
23
24
25
26
27 public final class Conditions {
28
29
30 private static final Logger logger = LoggerFactory.getLogger(Conditions.class);
31
32
33
34
35 public static final Condition alwaysTrue = new AlwaysTrue();
36
37
38
39
40 public static final Condition alwaysFalse = new AlwaysFalse();
41
42
43
44
45 public static final Condition defaultForOrphan = alwaysTrue;
46
47
48
49
50 public static final Condition authenticated = new IsAuthenticated();
51
52
53
54
55 private Conditions() {
56 throw new UnsupportedOperationException("This is a utility class");
57 }
58
59
60
61
62 public static abstract class Condition {
63
64
65
66
67
68
69
70
71
72 public boolean eval(RequestManager requestManager, SecurityManager securityManager) {
73 Boolean cachedResult = requestManager.getConditionResult(this);
74 if (cachedResult != null) {
75 logger.trace("Condition {} is cached and {}", this, cachedResult);
76 return cachedResult;
77 } else {
78 boolean result = this.internalEval(requestManager, securityManager);
79 logger.trace("Condition {} is not cached and {}", this, result);
80 requestManager.registerConditionResult(this, result);
81 return result;
82 }
83 }
84
85
86
87
88
89
90
91
92
93 protected abstract boolean internalEval(RequestManager requestManager,
94 SecurityManager securityManager);
95 }
96
97
98
99
100 private static class AlwaysTrue extends Condition {
101
102 @Override
103 protected boolean internalEval(RequestManager requestManager,
104 SecurityManager securityManager) {
105 return true;
106 }
107
108 @Override
109 public String toString() {
110 return "true";
111 }
112
113 @Override
114 public boolean equals(Object obj) {
115 return obj instanceof AlwaysTrue;
116 }
117
118 @Override
119 public int hashCode() {
120 int hash = 7;
121 hash = 31 * hash + Objects.hashCode(true);
122 return hash;
123 }
124 }
125
126
127
128
129 private static class AlwaysFalse extends Condition {
130
131 @Override
132 protected boolean internalEval(RequestManager requestManager,
133 SecurityManager securityManager) {
134 return false;
135 }
136
137 @Override
138 public String toString() {
139 return "false";
140 }
141
142 @Override
143 public boolean equals(Object obj) {
144 return obj instanceof AlwaysFalse;
145 }
146
147 @Override
148 public int hashCode() {
149 int hash = 7;
150 hash = 31 * hash + Objects.hashCode(true);
151 return hash;
152 }
153
154 }
155
156
157
158
159 public static class And extends Condition {
160
161
162 private Condition[] conditions;
163
164
165
166
167
168
169 public And(Condition... conditions) {
170 this.conditions = conditions;
171 }
172
173 @Override
174 protected boolean internalEval(RequestManager requestManager,
175 SecurityManager securityManager) {
176 for (Condition c : conditions) {
177 if (!c.eval(requestManager, securityManager)) {
178
179 return false;
180 }
181 }
182
183 return true;
184 }
185
186 @Override
187 public String toString() {
188 return "And(" + List.of(conditions) + ')';
189 }
190
191 @Override
192 public int hashCode() {
193 int hash = 3;
194 hash = 31 * hash + new HashCodeBuilder().append(this.conditions).toHashCode();
195 return hash;
196 }
197
198 @Override
199 public boolean equals(Object obj) {
200 if (this == obj) {
201 return true;
202 }
203 if (obj == null) {
204 return false;
205 }
206 if (getClass() != obj.getClass()) {
207 return false;
208 }
209 final And other = (And) obj;
210 if (!Objects.equals(this.conditions, other.conditions)) {
211 return false;
212 }
213 return true;
214 }
215 }
216
217
218
219
220 public static class Or extends Condition {
221
222
223 private Condition[] conditions;
224
225
226
227
228
229
230 public Or(Condition... conditions) {
231 this.conditions = conditions;
232 }
233
234 @Override
235 protected boolean internalEval(RequestManager requestManager,
236 SecurityManager securityManager) {
237 for (Condition c : conditions) {
238 if (c.eval(requestManager, securityManager)) {
239
240 return true;
241 }
242 }
243
244 return false;
245 }
246
247 @Override
248 public String toString() {
249 return "Or(" + List.of(conditions) + ')';
250 }
251
252 @Override
253 public int hashCode() {
254 int hash = 3;
255 hash = 59 * hash + new HashCodeBuilder().append(this.conditions).toHashCode();
256 return hash;
257 }
258
259 @Override
260 public boolean equals(Object obj) {
261 if (this == obj) {
262 return true;
263 }
264 if (obj == null) {
265 return false;
266 }
267 if (getClass() != obj.getClass()) {
268 return false;
269 }
270 final Or other = (Or) obj;
271 if (!new EqualsBuilder().append(this.conditions, other.conditions).isEquals()) {
272 return false;
273 } else {
274 return true;
275 }
276 }
277 }
278
279
280
281
282 public static class Not extends Condition {
283
284
285 private final Condition condition;
286
287
288
289
290
291
292 public Not(Condition condition) {
293 this.condition = condition;
294 }
295
296 @Override
297 protected boolean internalEval(RequestManager requestManager,
298 SecurityManager securityManager) {
299
300 return !condition.eval(requestManager, securityManager);
301 }
302
303 @Override
304 public String toString() {
305 return "Not(" + condition + ')';
306 }
307
308 @Override
309 public int hashCode() {
310 int hash = 5;
311 hash = 37 * hash + Objects.hashCode(this.condition);
312 return hash;
313 }
314
315 @Override
316 public boolean equals(Object obj) {
317 if (this == obj) {
318 return true;
319 }
320 if (obj == null) {
321 return false;
322 }
323 if (getClass() != obj.getClass()) {
324 return false;
325 }
326 final Not other = (Not) obj;
327 if (!Objects.equals(this.condition, other.condition)) {
328 return false;
329 }
330 return true;
331 }
332 }
333
334
335
336
337 public static class IsCurrentUserThisUser extends Condition {
338
339
340 private final User user;
341
342
343
344
345
346
347 public IsCurrentUserThisUser(User user) {
348 this.user = user;
349 }
350
351 @Override
352 protected boolean internalEval(RequestManager requestManager,
353 SecurityManager securityManager) {
354 User currentUser = requestManager.getCurrentUser();
355 return currentUser != null && currentUser.equals(user);
356 }
357
358 @Override
359 public String toString() {
360 return "IsUser(" + user + ")";
361 }
362
363 @Override
364 public int hashCode() {
365 int hash = 5;
366 hash = 73 * hash + Objects.hashCode(this.user);
367 return hash;
368 }
369
370 @Override
371 public boolean equals(Object obj) {
372 if (this == obj) {
373 return true;
374 }
375 if (obj == null) {
376 return false;
377 }
378 if (getClass() != obj.getClass()) {
379 return false;
380 }
381 final IsCurrentUserThisUser other = (IsCurrentUserThisUser) obj;
382 if (!Objects.equals(this.user, other.user)) {
383 return false;
384 }
385 return true;
386 }
387 }
388
389
390
391
392 public static class IsCurrentUserMemberOfProject extends Condition {
393
394
395 private final Project project;
396
397
398
399
400
401
402 public IsCurrentUserMemberOfProject(Project project) {
403 this.project = project;
404 }
405
406 @Override
407 protected boolean internalEval(RequestManager requestManager,
408 SecurityManager securityManager) {
409 return securityManager.isCurrentUserMemberOfTheProjectTeam(project);
410 }
411
412 @Override
413 public String toString() {
414 return "IsMemberOf(" + project + ")";
415 }
416
417 @Override
418 public int hashCode() {
419 int hash = 7;
420 hash = 37 * hash + Objects.hashCode(this.project);
421 return hash;
422 }
423
424 @Override
425 public boolean equals(Object obj) {
426 if (this == obj) {
427 return true;
428 }
429 if (obj == null) {
430 return false;
431 }
432 if (getClass() != obj.getClass()) {
433 return false;
434 }
435 final IsCurrentUserMemberOfProject other = (IsCurrentUserMemberOfProject) obj;
436 if (!Objects.equals(this.project, other.project)) {
437 return false;
438 }
439 return true;
440 }
441 }
442
443
444
445
446 public static class IsCurrentUserInternalToProject extends Condition {
447
448
449 private final Project project;
450
451
452
453
454
455
456 public IsCurrentUserInternalToProject(Project project) {
457 this.project = project;
458 }
459
460 @Override
461 protected boolean internalEval(RequestManager requestManager,
462 SecurityManager securityManager) {
463 return securityManager.isCurrentUserInternalToProject(project);
464 }
465
466 @Override
467 public String toString() {
468 return "IsInternalTo(" + project + ")";
469 }
470
471 @Override
472 public int hashCode() {
473 int hash = 7;
474 hash = 67 * hash + Objects.hashCode(this.project);
475 return hash;
476 }
477
478 @Override
479 public boolean equals(Object obj) {
480 if (this == obj) {
481 return true;
482 }
483 if (obj == null) {
484 return false;
485 }
486 if (getClass() != obj.getClass()) {
487 return false;
488 }
489 final IsCurrentUserInternalToProject other = (IsCurrentUserInternalToProject) obj;
490 if (!Objects.equals(this.project, other.project)) {
491 return false;
492 }
493 return true;
494 }
495 }
496
497
498
499
500 public static class IsCurrentUserTeamMateOfUser extends Condition {
501
502
503 private final User user;
504
505
506
507
508
509
510 public IsCurrentUserTeamMateOfUser(User user) {
511 this.user = user;
512 }
513
514 @Override
515 protected boolean internalEval(RequestManager requestManager,
516 SecurityManager securityManager) {
517 User currentUser = requestManager.getCurrentUser();
518 return currentUser != null && securityManager.areUserTeammate(currentUser, this.user);
519 }
520
521 @Override
522 public String toString() {
523 return "IsTeamMateOf(" + user + ")";
524 }
525
526 @Override
527 public int hashCode() {
528 int hash = 3;
529 hash = 31 * hash + Objects.hashCode(this.user);
530 return hash;
531 }
532
533 @Override
534 public boolean equals(Object obj) {
535 if (this == obj) {
536 return true;
537 }
538 if (obj == null) {
539 return false;
540 }
541 if (getClass() != obj.getClass()) {
542 return false;
543 }
544 final IsCurrentUserTeamMateOfUser other = (IsCurrentUserTeamMateOfUser) obj;
545 if (!Objects.equals(this.user, other.user)) {
546 return false;
547 }
548 return true;
549 }
550 }
551
552
553
554
555 public static class DoCurrentUserWorkOnSameProjectThanUser extends Condition {
556
557
558 private final User user;
559
560
561
562
563
564
565 public DoCurrentUserWorkOnSameProjectThanUser(User user) {
566 this.user = user;
567 }
568
569 @Override
570 protected boolean internalEval(RequestManager requestManager,
571 SecurityManager securityManager) {
572 User currentUser = requestManager.getCurrentUser();
573 return currentUser != null
574 && securityManager.doUsersHaveCommonProject(currentUser, this.user);
575 }
576
577 @Override
578 public String toString() {
579 return "DoCurrentUserWorkOnSameProjectThanUser(" + user + ")";
580 }
581
582 @Override
583 public int hashCode() {
584 int hash = 3;
585 hash = 31 * hash + Objects.hashCode(this.user);
586 return hash;
587 }
588
589 @Override
590 public boolean equals(Object obj) {
591 if (this == obj) {
592 return true;
593 }
594 if (obj == null) {
595 return false;
596 }
597 if (getClass() != obj.getClass()) {
598 return false;
599 }
600 final DoCurrentUserWorkOnSameProjectThanUser other = (DoCurrentUserWorkOnSameProjectThanUser) obj;
601 if (!Objects.equals(this.user, other.user)) {
602 return false;
603 }
604 return true;
605 }
606 }
607
608
609
610
611 private static class IsAuthenticated extends Condition {
612
613 @Override
614 protected boolean internalEval(RequestManager requestManager,
615 SecurityManager securityManager) {
616 return requestManager.isAuthenticated();
617 }
618
619 @Override
620 public String toString() {
621 return "IsAuthenticated";
622 }
623
624 @Override
625 public boolean equals(Object obj) {
626 return obj instanceof IsAuthenticated;
627 }
628
629 @Override
630 public int hashCode() {
631 int hash = 7;
632 hash = 83 * hash;
633 return hash;
634 }
635 }
636
637
638
639
640 public static class HasCardWriteRight extends Condition {
641
642
643 private final Card card;
644
645
646
647
648
649
650 public HasCardWriteRight(Card card) {
651 this.card = card;
652 }
653
654
655
656
657
658
659 public HasCardWriteRight(CardContent cardContent) {
660 this.card = cardContent.getCard();
661 }
662
663 @Override
664 protected boolean internalEval(RequestManager requestManager,
665 SecurityManager securityManager) {
666 return securityManager.hasReadWriteAccess(card);
667 }
668
669 @Override
670 public String toString() {
671 return "HasCardWriteRight(" + card + ")";
672 }
673
674 @Override
675 public int hashCode() {
676 int hash = 7;
677 hash = 47 * hash + Objects.hashCode(this.card);
678 return hash;
679 }
680
681 @Override
682 public boolean equals(Object obj) {
683 if (this == obj) {
684 return true;
685 }
686 if (obj == null) {
687 return false;
688 }
689 if (getClass() != obj.getClass()) {
690 return false;
691 }
692 final HasCardWriteRight other = (HasCardWriteRight) obj;
693 if (!Objects.equals(this.card, other.card)) {
694 return false;
695 }
696 return true;
697 }
698 }
699
700
701
702
703 public static class HasCardReadRight extends Condition {
704
705
706 private final Card card;
707
708
709
710
711
712
713 public HasCardReadRight(Card card) {
714 this.card = card;
715 }
716
717
718
719
720
721
722 public HasCardReadRight(CardContent cardContent) {
723 this.card = cardContent.getCard();
724 }
725
726 @Override
727 protected boolean internalEval(RequestManager requestManager,
728 SecurityManager securityManager) {
729 return securityManager.hasReadAccess(card);
730 }
731
732 @Override
733 public String toString() {
734 return "HasCardReadRight(" + card + ")";
735 }
736
737 @Override
738 public int hashCode() {
739 int hash = 3;
740 hash = 71 * hash + Objects.hashCode(this.card);
741 return hash;
742 }
743
744 @Override
745 public boolean equals(Object obj) {
746 if (this == obj) {
747 return true;
748 }
749 if (obj == null) {
750 return false;
751 }
752 if (getClass() != obj.getClass()) {
753 return false;
754 }
755 final HasCardReadRight other = (HasCardReadRight) obj;
756 if (!Objects.equals(this.card, other.card)) {
757 return false;
758 }
759 return true;
760 }
761 }
762
763 }