001/* 002 * Copyright 2018 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.plugins.core.impl.right; 017 018import java.util.Arrays; 019import java.util.HashMap; 020import java.util.HashSet; 021import java.util.List; 022import java.util.Map; 023import java.util.Objects; 024import java.util.Optional; 025import java.util.Set; 026import java.util.stream.Collectors; 027 028import org.apache.avalon.framework.configuration.Configuration; 029import org.apache.avalon.framework.configuration.ConfigurationException; 030import org.apache.commons.lang.StringUtils; 031import org.apache.ibatis.session.SqlSession; 032 033import org.ametys.core.datasource.AbstractMyBatisDAO; 034import org.ametys.core.group.GroupIdentity; 035import org.ametys.core.right.ModifiableProfileAssignmentStorage; 036import org.ametys.core.right.ProfileAssignmentStorage; 037import org.ametys.core.user.UserIdentity; 038 039/** 040 * Jdbc implementation of {@link ProfileAssignmentStorage} which stores profile assignments in database. 041 * This only supports String objects as contexts. 042 */ 043public class JdbcProfileAssignmentStorage extends AbstractMyBatisDAO implements ModifiableProfileAssignmentStorage 044{ 045 /** The jdbc cache */ 046 protected final Map<String, Database> _cache = new HashMap<>(); 047 048 /** The cache for inheritances */ 049 protected final Map<String, Boolean> _inheritances = new HashMap<>(); 050 051 /** If cache of inheritances is up-to-date */ 052 protected boolean _inheritancesUpToDate; 053 054 /** The handled context */ 055 protected String _supportedContext; 056 057 @Override 058 public void configure(Configuration configuration) throws ConfigurationException 059 { 060 super.configure(configuration); 061 _supportedContext = configuration.getChild("context").getValue(); 062 } 063 064 /** 065 * Dump the SQL database in an cached object 066 * @param context The context to seek 067 * @return The database 068 */ 069 protected Database _getFullData(Object context) 070 { 071 String rootContext = "/" + StringUtils.split((String) context, '/')[0]; 072 073 synchronized (_cache) 074 { 075 if (_cache.containsKey(rootContext)) 076 { 077 return _cache.get(rootContext); 078 } 079 080 try (SqlSession session = getSession()) 081 { 082 Map<String, Object> parameters = new HashMap<>(); 083 parameters.put("context", rootContext); 084 085 List<Map<String, String>> profiles = session.selectList("ProfilesAssignment.getAllProfiles", parameters); 086 Database db = new Database(profiles); 087 _cache.put(rootContext, db); 088 089 return db; 090 } 091 } 092 } 093 094 /** 095 * Clear the cache of _getFullData 096 */ 097 protected void _clearCache() 098 { 099 synchronized (_cache) 100 { 101 _cache.clear(); 102 } 103 } 104 105 /** 106 * Clear the cache of _getFullData 107 * @param context The context to seek 108 */ 109 protected void _clearCache(Object context) 110 { 111 String rootContext = "/" + StringUtils.split((String) context, '/')[0]; 112 113 synchronized (_cache) 114 { 115 if (_cache.containsKey(rootContext)) 116 { 117 _cache.remove(rootContext); 118 } 119 } 120 } 121 122 /** 123 * Get the full inheritances from SQL database in an cached object 124 * @return The inheritances 125 */ 126 protected Map<String, Boolean> _getInheritances() 127 { 128 synchronized (_inheritances) 129 { 130 if (!_inheritancesUpToDate) 131 { 132 try (SqlSession session = getSession()) 133 { 134 List<Map<String, Object>> inheritances = session.selectList("ProfilesAssignment.getInheritances", new HashMap<>()); 135 136 inheritances.stream().forEach(result -> 137 { 138 _inheritances.put((String) result.get("context"), (Boolean) result.get("disallow")); 139 }); 140 141 _inheritancesUpToDate = true; 142 } 143 } 144 145 return _inheritances; 146 147 } 148 } 149 150 /** 151 * Clear the cache of _getFullData 152 */ 153 protected void _clearInheritanceCache() 154 { 155 synchronized (_inheritances) 156 { 157 _inheritances.clear(); 158 _inheritancesUpToDate = false; 159 } 160 } 161 162 /* -------------- */ 163 /* HAS PERMISSION */ 164 /* -------------- */ 165 166 /** 167 * Get the object context with prefix if necessary 168 * @param context The context object 169 * @return The prefixed object 170 */ 171 protected Object getObjectWithPrefix (Object context) 172 { 173 return context; 174 } 175 176 /** 177 * Get the prefix for object context 178 * @return The prefix. Can be null if no prefix is necessary 179 */ 180 protected String getPrefix () 181 { 182 return null; 183 } 184 185 public Set<String> hasUserAnyAllowedProfile(Set<? extends Object> rootContexts, UserIdentity user, Set<String> profileIds) 186 { 187 String prefix = getPrefix(); 188 Set<String> stringPrefixContexts = rootContexts.stream().filter(String.class::isInstance).map(context -> (prefix != null ? prefix : "") + (String) context).collect(Collectors.toSet()); 189 190 Set<String> anyAllowedProfiles = new HashSet<>(); 191 for (String stringPrefixContext : stringPrefixContexts) 192 { 193 Set<String> profiles = _getFullData(stringPrefixContext) 194 .getAlloweUserData() 195 .entrySet().stream() 196 .filter(entry -> _equalsOrStartsWith(entry.getKey(), stringPrefixContext)) 197 .map(Map.Entry::getValue) 198 .map(m -> m.get(user)) 199 .filter(Objects::nonNull) 200 .flatMap(Set::stream) 201 .collect(Collectors.toSet()); 202 203 anyAllowedProfiles.addAll(profiles); 204 } 205 206 for (String profileId : profileIds) 207 { 208 if (anyAllowedProfiles.contains(profileId)) 209 { 210 return anyAllowedProfiles; 211 } 212 } 213 return Set.of(); 214 } 215 216 public Set<String> hasGroupAnyAllowedProfile(Set<? extends Object> rootContexts, Set<GroupIdentity> groups, Set<String> profileIds) 217 { 218 String prefix = getPrefix(); 219 Set<String> stringPrefixContexts = rootContexts.stream().filter(String.class::isInstance).map(context -> (prefix != null ? prefix : "") + (String) context).collect(Collectors.toSet()); 220 221 Set<String> anyAllowedProfiles = new HashSet<>(); 222 for (String stringPrefixContext : stringPrefixContexts) 223 { 224 _getFullData(stringPrefixContext) 225 .getAlloweGroupData() 226 .entrySet() 227 .stream() 228 .filter(entry -> _equalsOrStartsWith(entry.getKey(), stringPrefixContext)) 229 .map(Map.Entry::getValue) 230 .forEach(profilesByGroup -> 231 { 232 for (GroupIdentity group : groups) 233 { 234 Set<String> profiles = profilesByGroup.get(group); 235 if (profiles != null) 236 { 237 anyAllowedProfiles.addAll(profiles); 238 } 239 } 240 }); 241 } 242 243 for (String profileId : profileIds) 244 { 245 if (anyAllowedProfiles.contains(profileId)) 246 { 247 return anyAllowedProfiles; 248 } 249 } 250 251 return Set.of(); 252 } 253 254 public Set<String> hasAnyConnectedAnyAllowedProfile(Set<? extends Object> rootContexts, Set<String> profileIds) 255 { 256 String prefix = getPrefix(); 257 Set<String> stringPrefixContexts = rootContexts.stream().filter(String.class::isInstance).map(context -> (prefix != null ? prefix : "") + (String) context).collect(Collectors.toSet()); 258 259 Set<String> anyAllowedProfiles = new HashSet<>(); 260 for (String stringPrefixContext : stringPrefixContexts) 261 { 262 Set<String> profiles = _getFullData(stringPrefixContext) 263 .getAllowedAnyConnected() 264 .entrySet().stream() 265 .filter(entry -> _equalsOrStartsWith(entry.getKey(), stringPrefixContext)) 266 .map(Map.Entry::getValue) 267 .flatMap(Set::stream) 268 .collect(Collectors.toSet()); 269 270 anyAllowedProfiles.addAll(profiles); 271 } 272 273 for (String profileId : profileIds) 274 { 275 if (anyAllowedProfiles.contains(profileId)) 276 { 277 return anyAllowedProfiles; 278 } 279 } 280 return Set.of(); 281 } 282 283 public Set<String> hasAnonymousAnyAllowedProfile(Set<? extends Object> rootContexts, Set<String> profileIds) 284 { 285 String prefix = getPrefix(); 286 Set<String> stringPrefixContexts = rootContexts.stream().filter(String.class::isInstance).map(context -> (prefix != null ? prefix : "") + (String) context).collect(Collectors.toSet()); 287 288 Set<String> anyAllowedProfiles = new HashSet<>(); 289 for (String stringPrefixContext : stringPrefixContexts) 290 { 291 Set<String> profiles = _getFullData(stringPrefixContext) 292 .getAllowedAnonymous() 293 .entrySet().stream() 294 .filter(entry -> _equalsOrStartsWith(entry.getKey(), stringPrefixContext)) 295 .map(Map.Entry::getValue) 296 .flatMap(Set::stream) 297 .collect(Collectors.toSet()); 298 299 anyAllowedProfiles.addAll(profiles); 300 } 301 302 for (String profileId : profileIds) 303 { 304 if (anyAllowedProfiles.contains(profileId)) 305 { 306 return anyAllowedProfiles; 307 } 308 } 309 return Set.of(); 310 } 311 312 private static boolean _equalsOrStartsWith(String value, String prefix) 313 { 314 return value.equals(prefix) || value.startsWith(prefix + "/"); 315 } 316 317 /* --------------------------------------- */ 318 /* ALLOWED PROFILES FOR ANY CONNECTED USER */ 319 /* --------------------------------------- */ 320 321 public Map<UserIdentity, Map<UserOrGroup, Set<String>>> getProfilesForUsers(Object object, UserIdentity user) 322 { 323 Map<UserIdentity, Map<UserOrGroup, Set<String>>> result = new HashMap<>(); 324 325 Map<UserIdentity, Set<String>> allowedProfilesByUser = Optional.ofNullable(_getFullData(object).getAlloweUserData().get(object)).orElse(Map.of()); 326 Map<UserIdentity, Set<String>> deniedProfilesByUser = Optional.ofNullable(_getFullData(object).getDeniedUserData().get(object)).orElse(Map.of()); 327 328 Set<UserIdentity> userKeys; 329 if (user != null) 330 { 331 userKeys = Set.of(user); 332 } 333 else 334 { 335 userKeys = new HashSet<>(); 336 userKeys.addAll(allowedProfilesByUser.keySet()); 337 userKeys.addAll(deniedProfilesByUser.keySet()); 338 } 339 340 for (UserIdentity userKey : userKeys) 341 { 342 result.put(userKey, Map.of(UserOrGroup.ALLOWED, allowedProfilesByUser.containsKey(userKey) ? allowedProfilesByUser.get(userKey) : Set.of(), 343 UserOrGroup.DENIED, deniedProfilesByUser.containsKey(userKey) ? deniedProfilesByUser.get(userKey) : Set.of())); 344 } 345 346 return result; } 347 348 public void addAllowedProfilesForAnyConnectedUser(Object object, Set<String> profileIds) 349 { 350 _clearCache(object); 351 352 try (SqlSession session = getSession()) 353 { 354 Object prefixedObject = getObjectWithPrefix(object); 355 for (String profileId : profileIds) 356 { 357 Map<String, Object> parameters = new HashMap<>(); 358 parameters.put("context", prefixedObject); 359 parameters.put("profileIds", Arrays.asList(profileId)); 360 361 List<Map<String, String>> allowedProfiles = session.selectList("ProfilesAssignment.getAnyConnectedAllowedProfiles", parameters); 362 363 if (allowedProfiles.isEmpty()) 364 { 365 parameters.put("profileId", profileId); 366 session.insert("ProfilesAssignment.addAllowedAnyConnected", parameters); 367 } 368 else 369 { 370 getLogger().debug("Profile {} is already allowed for anyconnected on context {}", profileId, prefixedObject); 371 } 372 373 } 374 375 session.commit(); 376 } 377 } 378 379 public void removeAllowedProfilesForAnyConnectedUser(Object object, Set<String> profileIds) 380 { 381 _clearCache(object); 382 383 try (SqlSession session = getSession(true)) 384 { 385 Map<String, Object> parameters = new HashMap<>(); 386 parameters.put("context", getObjectWithPrefix(object)); 387 parameters.put("profileIds", profileIds); 388 session.delete("ProfilesAssignment.deleteAllowedAnyConnected", parameters); 389 } 390 } 391 392 393 /* -------------------------------------- */ 394 /* DENIED PROFILES FOR ANY CONNECTED USER */ 395 /* -------------------------------------- */ 396 397 public Map<AnonymousOrAnyConnectedKeys, Set<String>> getProfilesForAnonymousAndAnyConnectedUser(Object object) 398 { 399 return Map.of(AnonymousOrAnyConnectedKeys.ANONYMOUS_ALLOWED, Optional.ofNullable(_getFullData(object).getAllowedAnonymous().get(object)).orElse(Set.of()), 400 AnonymousOrAnyConnectedKeys.ANONYMOUS_DENIED, Optional.ofNullable(_getFullData(object).getDeniedAnonymous().get(object)).orElse(Set.of()), 401 AnonymousOrAnyConnectedKeys.ANYCONNECTEDUSER_ALLOWED, Optional.ofNullable(_getFullData(object).getAllowedAnyConnected().get(object)).orElse(Set.of()), 402 AnonymousOrAnyConnectedKeys.ANYCONNECTEDUSER_DENIED, Optional.ofNullable(_getFullData(object).getDeniedAnyConnected().get(object)).orElse(Set.of())); 403 } 404 405 public void addDeniedProfilesForAnyConnectedUser(Object object, Set<String> profileIds) 406 { 407 _clearCache(object); 408 409 try (SqlSession session = getSession()) 410 { 411 Object prefixedObject = getObjectWithPrefix(object); 412 413 for (String profileId : profileIds) 414 { 415 Map<String, Object> parameters = new HashMap<>(); 416 parameters.put("context", prefixedObject); 417 parameters.put("profileIds", Arrays.asList(profileId)); 418 419 List<Map<String, String>> deniedProfiles = session.selectList("ProfilesAssignment.getAnyConnectedDeniedProfiles", parameters); 420 421 if (deniedProfiles.isEmpty()) 422 { 423 parameters.put("profileId", profileId); 424 session.insert("ProfilesAssignment.addDeniedAnyConnected", parameters); 425 } 426 else 427 { 428 getLogger().debug("Profile {} is already denied for anyconnected on context {}", profileId, prefixedObject); 429 } 430 431 } 432 433 session.commit(); 434 } 435 } 436 437 public void removeDeniedProfilesForAnyConnectedUser(Object object, Set<String> profileIds) 438 { 439 _clearCache(object); 440 441 try (SqlSession session = getSession(true)) 442 { 443 Map<String, Object> parameters = new HashMap<>(); 444 parameters.put("context", getObjectWithPrefix(object)); 445 parameters.put("profileIds", profileIds); 446 session.delete("ProfilesAssignment.deleteDeniedAnyConnected", parameters); 447 } 448 } 449 450 451 /* ------------------------------ */ 452 /* ALLOWED PROFILES FOR ANONYMOUS */ 453 /* ------------------------------ */ 454 455 public void addAllowedProfilesForAnonymous(Object object, Set<String> profileIds) 456 { 457 _clearCache(object); 458 459 try (SqlSession session = getSession()) 460 { 461 Object prefixedObject = getObjectWithPrefix(object); 462 463 for (String profileId : profileIds) 464 { 465 Map<String, Object> parameters = new HashMap<>(); 466 parameters.put("context", prefixedObject); 467 parameters.put("profileIds", Arrays.asList(profileId)); 468 469 List<Map<String, String>> allowedProfiles = session.selectList("ProfilesAssignment.getAnonymousAllowedProfiles", parameters); 470 471 if (allowedProfiles.isEmpty()) 472 { 473 parameters.put("profileId", profileId); 474 session.insert("ProfilesAssignment.addAllowedAnonymous", parameters); 475 } 476 else 477 { 478 getLogger().debug("Profile {} is already allowed for anonymous on context {}", profileId, prefixedObject); 479 } 480 } 481 482 session.commit(); 483 } 484 } 485 486 public void removeAllowedProfilesForAnonymous(Object object, Set<String> profileIds) 487 { 488 _clearCache(object); 489 490 try (SqlSession session = getSession(true)) 491 { 492 Map<String, Object> parameters = new HashMap<>(); 493 parameters.put("context", getObjectWithPrefix(object)); 494 parameters.put("profileIds", profileIds); 495 session.delete("ProfilesAssignment.deleteAllowedAnonymous", parameters); 496 } 497 } 498 499 500 /* ----------------------------- */ 501 /* DENIED PROFILES FOR ANONYMOUS */ 502 /* ----------------------------- */ 503 504 public void addDeniedProfilesForAnonymous(Object object, Set<String> profileIds) 505 { 506 _clearCache(object); 507 508 try (SqlSession session = getSession()) 509 { 510 Object prefixedObject = getObjectWithPrefix(object); 511 for (String profileId : profileIds) 512 { 513 Map<String, Object> parameters = new HashMap<>(); 514 parameters.put("context", prefixedObject); 515 parameters.put("profileIds", Arrays.asList(profileId)); 516 517 List<Map<String, String>> deniedProfiles = session.selectList("ProfilesAssignment.getAnonymousDeniedProfiles", parameters); 518 519 if (deniedProfiles.isEmpty()) 520 { 521 parameters.put("profileId", profileId); 522 session.insert("ProfilesAssignment.addDeniedAnonymous", parameters); 523 } 524 else 525 { 526 getLogger().debug("Profile {} is already denied for anonymous on context {}", profileId, prefixedObject); 527 } 528 } 529 530 session.commit(); 531 } 532 } 533 534 public void removeDeniedProfilesForAnonymous(Object object, Set<String> profileIds) 535 { 536 _clearCache(object); 537 538 try (SqlSession session = getSession(true)) 539 { 540 Map<String, Object> parameters = new HashMap<>(); 541 parameters.put("context", getObjectWithPrefix(object)); 542 parameters.put("profileIds", profileIds); 543 session.delete("ProfilesAssignment.deleteDeniedAnonymous", parameters); 544 } 545 } 546 547 548 /* --------------------------- */ 549 /* MANAGEMENT OF ALLOWED USERS */ 550 /* --------------------------- */ 551 552 public void addAllowedUsers(Set<UserIdentity> users, Object object, String profileId) 553 { 554 _clearCache(object); 555 556 try (SqlSession session = getSession()) 557 { 558 Object prefixedObject = getObjectWithPrefix(object); 559 560 for (UserIdentity userIdentity : users) 561 { 562 Map<String, Object> parameters = new HashMap<>(); 563 parameters.put("login", userIdentity.getLogin()); 564 parameters.put("population", userIdentity.getPopulationId()); 565 parameters.put("context", prefixedObject); 566 parameters.put("profileIds", Arrays.asList(profileId)); 567 568 List<Map<String, String>> allowedProfiles = session.selectList("ProfilesAssignment.getUserAllowedProfiles", parameters); 569 570 if (allowedProfiles.isEmpty()) 571 { 572 parameters.put("profileId", profileId); 573 session.insert("ProfilesAssignment.addAllowedUser", parameters); 574 } 575 else 576 { 577 getLogger().debug("Login {} has already profile {} on context {}", userIdentity, profileId, prefixedObject); 578 } 579 580 } 581 582 session.commit(); 583 } 584 } 585 586 public void removeAllowedUsers(Set<UserIdentity> users, Object object, String profileId) 587 { 588 _clearCache(object); 589 590 try (SqlSession session = getSession()) 591 { 592 for (UserIdentity userIdentity : users) 593 { 594 Map<String, Object> parameters = new HashMap<>(); 595 parameters.put("login", userIdentity.getLogin()); 596 parameters.put("population", userIdentity.getPopulationId()); 597 parameters.put("profileIds", Arrays.asList(profileId)); 598 if (object != null) 599 { 600 parameters.put("context", getObjectWithPrefix(object)); 601 } 602 603 session.delete("ProfilesAssignment.deleteAllowedUser", parameters); 604 } 605 session.commit(); 606 } 607 } 608 609 public void removeAllowedUsers(Set<UserIdentity> users, Object object) 610 { 611 _clearCache(object); 612 613 try (SqlSession session = getSession()) 614 { 615 for (UserIdentity userIdentity : users) 616 { 617 Map<String, Object> parameters = new HashMap<>(); 618 parameters.put("login", userIdentity.getLogin()); 619 parameters.put("population", userIdentity.getPopulationId()); 620 if (object != null) 621 { 622 parameters.put("context", getObjectWithPrefix(object)); 623 } 624 625 session.delete("ProfilesAssignment.deleteAllowedUser", parameters); 626 } 627 session.commit(); 628 } 629 } 630 631 632 /* -------------------- */ 633 /* MANAGEMENT OF GROUPS */ 634 /* -------------------- */ 635 636 public Map<GroupIdentity, Map<UserOrGroup, Set<String>>> getProfilesForGroups(Object object, Set<GroupIdentity> groups) 637 { 638 Map<GroupIdentity, Map<UserOrGroup, Set<String>>> result = new HashMap<>(); 639 640 Map<GroupIdentity, Set<String>> allowedProfilesByGroup = Optional.ofNullable(_getFullData(object).getAlloweGroupData().get(object)).orElse(Map.of()); 641 Map<GroupIdentity, Set<String>> deniedProfilesByGroup = Optional.ofNullable(_getFullData(object).getDeniedGroupData().get(object)).orElse(Map.of()); 642 643 Set<GroupIdentity> groupKeys; 644 if (groups != null) 645 { 646 groupKeys = groups; 647 } 648 else 649 { 650 groupKeys = new HashSet<>(); 651 groupKeys.addAll(allowedProfilesByGroup.keySet()); 652 groupKeys.addAll(deniedProfilesByGroup.keySet()); 653 } 654 655 for (GroupIdentity group : groupKeys) 656 { 657 result.put(group, Map.of(UserOrGroup.ALLOWED, allowedProfilesByGroup.containsKey(group) ? allowedProfilesByGroup.get(group) : Set.of(), 658 UserOrGroup.DENIED, deniedProfilesByGroup.containsKey(group) ? deniedProfilesByGroup.get(group) : Set.of())); 659 } 660 661 return result; 662 } 663 664 public void addAllowedGroups(Set<GroupIdentity> groups, Object object, String profileId) 665 { 666 _clearCache(object); 667 668 try (SqlSession session = getSession()) 669 { 670 Object prefixedObject = getObjectWithPrefix(object); 671 for (GroupIdentity group : groups) 672 { 673 Map<String, Object> parameters = new HashMap<>(); 674 parameters.put("groupId", group.getId()); 675 parameters.put("groupDirectory", group.getDirectoryId()); 676 parameters.put("context", prefixedObject); 677 parameters.put("profileIds", Arrays.asList(profileId)); 678 679 List<Map<String, String>> allowedProfiles = session.selectList("ProfilesAssignment.getGroupAllowedProfiles", parameters); 680 681 if (allowedProfiles.isEmpty()) 682 { 683 parameters.put("profileId", profileId); 684 session.insert("ProfilesAssignment.addAllowedGroup", parameters); 685 } 686 else 687 { 688 getLogger().debug("Group {} is already allowed for profile {} on context {}", group, profileId, prefixedObject); 689 } 690 } 691 692 session.commit(); 693 } 694 } 695 696 public void removeAllowedGroups(Set<GroupIdentity> groups, Object object, String profileId) 697 { 698 _clearCache(object); 699 700 try (SqlSession session = getSession()) 701 { 702 for (GroupIdentity group : groups) 703 { 704 Map<String, Object> parameters = new HashMap<>(); 705 parameters.put("groupId", group.getId()); 706 parameters.put("groupDirectory", group.getDirectoryId()); 707 parameters.put("profileIds", Arrays.asList(profileId)); 708 if (object != null) 709 { 710 parameters.put("context", getObjectWithPrefix(object)); 711 } 712 713 session.delete("ProfilesAssignment.deleteAllowedGroup", parameters); 714 } 715 session.commit(); 716 } 717 } 718 719 public void removeAllowedGroups(Set<GroupIdentity> groups, Object object) 720 { 721 _clearCache(object); 722 723 try (SqlSession session = getSession()) 724 { 725 for (GroupIdentity group : groups) 726 { 727 Map<String, Object> parameters = new HashMap<>(); 728 parameters.put("groupId", group.getId()); 729 parameters.put("groupDirectory", group.getDirectoryId()); 730 if (object != null) 731 { 732 parameters.put("context", getObjectWithPrefix(object)); 733 } 734 735 session.delete("ProfilesAssignment.deleteAllowedGroup", parameters); 736 } 737 session.commit(); 738 } 739 } 740 741 public void addDeniedUsers(Set<UserIdentity> users, Object object, String profileId) 742 { 743 _clearCache(object); 744 745 try (SqlSession session = getSession()) 746 { 747 Object prefixedObject = getObjectWithPrefix(object); 748 for (UserIdentity userIdentity : users) 749 { 750 Map<String, Object> parameters = new HashMap<>(); 751 parameters.put("login", userIdentity.getLogin()); 752 parameters.put("population", userIdentity.getPopulationId()); 753 parameters.put("context", prefixedObject); 754 parameters.put("profileIds", Arrays.asList(profileId)); 755 756 List<Map<String, String>> deniedProfiles = session.selectList("ProfilesAssignment.getUserDeniedProfiles", parameters); 757 758 if (deniedProfiles.isEmpty()) 759 { 760 parameters.put("profileId", profileId); 761 session.insert("ProfilesAssignment.addDeniedUser", parameters); 762 } 763 else 764 { 765 getLogger().debug("Login {} is already denied for profile {} on context {}", userIdentity, profileId, prefixedObject); 766 } 767 768 } 769 770 session.commit(); 771 } 772 } 773 774 public void removeDeniedUsers(Set<UserIdentity> users, Object object, String profileId) 775 { 776 _clearCache(object); 777 778 try (SqlSession session = getSession()) 779 { 780 for (UserIdentity userIdentity : users) 781 { 782 Map<String, Object> parameters = new HashMap<>(); 783 parameters.put("login", userIdentity.getLogin()); 784 parameters.put("population", userIdentity.getPopulationId()); 785 parameters.put("profileIds", Arrays.asList(profileId)); 786 if (object != null) 787 { 788 parameters.put("context", getObjectWithPrefix(object)); 789 } 790 791 session.delete("ProfilesAssignment.deleteDeniedUser", parameters); 792 } 793 session.commit(); 794 } 795 } 796 797 public void removeDeniedUsers(Set<UserIdentity> users, Object object) 798 { 799 _clearCache(object); 800 801 try (SqlSession session = getSession()) 802 { 803 for (UserIdentity userIdentity : users) 804 { 805 Map<String, Object> parameters = new HashMap<>(); 806 parameters.put("login", userIdentity.getLogin()); 807 parameters.put("population", userIdentity.getPopulationId()); 808 if (object != null) 809 { 810 parameters.put("context", getObjectWithPrefix(object)); 811 } 812 813 session.delete("ProfilesAssignment.deleteDeniedUser", parameters); 814 } 815 session.commit(); 816 } 817 } 818 819 public void addDeniedGroups(Set<GroupIdentity> groups, Object object, String profileId) 820 { 821 _clearCache(object); 822 823 try (SqlSession session = getSession()) 824 { 825 Object prefixedObject = getObjectWithPrefix(object); 826 for (GroupIdentity group : groups) 827 { 828 Map<String, Object> parameters = new HashMap<>(); 829 parameters.put("groupId", group.getId()); 830 parameters.put("groupDirectory", group.getDirectoryId()); 831 parameters.put("context", prefixedObject); 832 parameters.put("profileIds", Arrays.asList(profileId)); 833 834 List<Map<String, String>> deniedProfiles = session.selectList("ProfilesAssignment.getGroupDeniedProfiles", parameters); 835 836 if (deniedProfiles.isEmpty()) 837 { 838 parameters.put("profileId", profileId); 839 session.insert("ProfilesAssignment.addDeniedGroup", parameters); 840 } 841 else 842 { 843 getLogger().debug("Group {} is already denied for profile {} on context {}", group, profileId, prefixedObject); 844 } 845 } 846 847 session.commit(); 848 } 849 } 850 851 public void removeDeniedGroups(Set<GroupIdentity> groups, Object object, String profileId) 852 { 853 _clearCache(object); 854 855 try (SqlSession session = getSession()) 856 { 857 for (GroupIdentity group : groups) 858 { 859 Map<String, Object> parameters = new HashMap<>(); 860 parameters.put("groupId", group.getId()); 861 parameters.put("groupDirectory", group.getDirectoryId()); 862 parameters.put("profileIds", Arrays.asList(profileId)); 863 if (object != null) 864 { 865 parameters.put("context", getObjectWithPrefix(object)); 866 } 867 868 session.delete("ProfilesAssignment.deleteDeniedGroup", parameters); 869 } 870 session.commit(); 871 } 872 } 873 874 public void removeDeniedGroups(Set<GroupIdentity> groups, Object object) 875 { 876 _clearCache(object); 877 878 try (SqlSession session = getSession()) 879 { 880 for (GroupIdentity group : groups) 881 { 882 Map<String, Object> parameters = new HashMap<>(); 883 parameters.put("groupId", group.getId()); 884 parameters.put("groupDirectory", group.getDirectoryId()); 885 if (object != null) 886 { 887 parameters.put("context", getObjectWithPrefix(object)); 888 } 889 890 session.delete("ProfilesAssignment.deleteDeniedGroup", parameters); 891 } 892 session.commit(); 893 } 894 } 895 896 /* ----------- */ 897 /* INHERITANCE */ 898 /* ----------- */ 899 900 public void disallowInheritance(Object object, boolean disallow) 901 { 902 try (SqlSession session = getSession()) 903 { 904 Object ctxWithPrefix = getObjectWithPrefix(object); 905 906 Map<String, Object> parameters = new HashMap<>(); 907 908 parameters.put("context", ctxWithPrefix); 909 parameters.put("disallow", disallow); 910 911 if (_getInheritances().containsKey(ctxWithPrefix)) 912 { 913 session.insert("ProfilesAssignment.updateInheritance", parameters); 914 } 915 else 916 { 917 session.insert("ProfilesAssignment.insertInheritance", parameters); 918 } 919 session.commit(); 920 921 _clearInheritanceCache(); 922 } 923 } 924 925 public boolean isInheritanceDisallowed(Object object) 926 { 927 Object ctxWithPrefix = getObjectWithPrefix(object); 928 929 Boolean isDisallowed = _getInheritances().get(ctxWithPrefix); 930 return isDisallowed != null && Boolean.TRUE.equals(isDisallowed); 931 } 932 933 934 /* ------ */ 935 /* REMOVE */ 936 /* ------ */ 937 938 public void removeProfile(String profileId) 939 { 940 _clearCache(); 941 942 try (SqlSession session = getSession()) 943 { 944 Map<String, Object> parameters = new HashMap<>(); 945 parameters.put("profileIds", Arrays.asList(profileId)); 946 947 session.delete("ProfilesAssignment.deleteAllowedUser", parameters); 948 session.delete("ProfilesAssignment.deleteDeniedUser", parameters); 949 session.delete("ProfilesAssignment.deleteAllowedGroup", parameters); 950 session.delete("ProfilesAssignment.deleteDeniedGroup", parameters); 951 session.delete("ProfilesAssignment.deleteAllowedAnonymous", parameters); 952 session.delete("ProfilesAssignment.deleteDeniedAnonymous", parameters); 953 session.delete("ProfilesAssignment.deleteAllowedAnyConnected", parameters); 954 session.delete("ProfilesAssignment.deleteDeniedAnyConnected", parameters); 955 956 session.commit(); 957 } 958 } 959 960 public void removeUser(UserIdentity user) 961 { 962 _clearCache(); 963 964 try (SqlSession session = getSession()) 965 { 966 Map<String, String> parameters = new HashMap<>(); 967 parameters.put("login", user.getLogin()); 968 parameters.put("population", user.getPopulationId()); 969 970 session.delete("ProfilesAssignment.deleteAllowedUser", parameters); 971 session.delete("ProfilesAssignment.deleteDeniedUser", parameters); 972 973 session.commit(); 974 } 975 } 976 977 public void removeGroup(GroupIdentity group) 978 { 979 _clearCache(); 980 981 try (SqlSession session = getSession()) 982 { 983 Map<String, String> parameters = new HashMap<>(); 984 parameters.put("groupId", group.getId()); 985 parameters.put("groupDirectory", group.getDirectoryId()); 986 987 session.delete("ProfilesAssignment.deleteAllowedGroup", parameters); 988 session.delete("ProfilesAssignment.deleteDeniedGroup", parameters); 989 990 session.commit(); 991 } 992 } 993 994 /* ------------------------------ */ 995 /* SUPPORT OF OBJECT AND PRIORITY */ 996 /* ------------------------------ */ 997 998 public boolean isSupported(Object object) 999 { 1000 if (object instanceof String) 1001 { 1002 String context = (String) object; 1003 return context.equals(_supportedContext) || context.startsWith(_supportedContext + "/"); 1004 } 1005 return false; 1006 } 1007 1008 public boolean isRootContextSupported(Object rootContext) 1009 { 1010 return isSupported(rootContext); 1011 } 1012 1013 public int getPriority() 1014 { 1015 return ProfileAssignmentStorage.MIN_PRIORITY; 1016 } 1017 1018 private static class Database 1019 { 1020 // Context, ProfileId 1021 private Map<String, Set<String>> _allowedAnonymousData; 1022 // Context, ProfileId 1023 private Map<String, Set<String>> _deniedAnonymousData; 1024 // Context, ProfileId 1025 private Map<String, Set<String>> _allowedAnyConnectedData; 1026 // Context, ProfileId 1027 private Map<String, Set<String>> _deniedAnyConnectedData; 1028 // Context, UserIdentity/GroupIdenty ProfileId 1029 private Map<String, Map<UserIdentity, Set<String>>> _allowedUserData; 1030 // Context, UserIdentity/GroupIdenty ProfileId 1031 private Map<String, Map<UserIdentity, Set<String>>> _deniedUserData; 1032 // Context, UserIdentity/GroupIdenty ProfileId 1033 private Map<String, Map<GroupIdentity, Set<String>>> _allowedGroupData; 1034 // Context, UserIdentity/GroupIdenty ProfileId 1035 private Map<String, Map<GroupIdentity, Set<String>>> _deniedGroupData; 1036 1037 Database(List<Map<String, String>> data) 1038 { 1039 _allowedAnonymousData = new HashMap<>(); 1040 _deniedAnonymousData = new HashMap<>(); 1041 _allowedAnyConnectedData = new HashMap<>(); 1042 _deniedAnyConnectedData = new HashMap<>(); 1043 _allowedUserData = new HashMap<>(); 1044 _deniedUserData = new HashMap<>(); 1045 _allowedGroupData = new HashMap<>(); 1046 _deniedGroupData = new HashMap<>(); 1047 1048 for (Map<String, String> map : data) 1049 { 1050 String type = map.get("type").trim(); 1051 String profileId = map.get("profileId"); 1052 String context = map.get("context"); 1053 1054 if ("ALLOWED_ANONYMOUS".equals(type) || "DENIED_ANONYMOUS".equals(type) || "ALLOWED_ANYCONNECTED".equals(type) || "DENIED_ANYCONNECTED".equals(type)) 1055 { 1056 _buildAnonymousOrAnyConnectedData(type, profileId, context); 1057 } 1058 else if ("ALLOWED_USER".equals(type) || "DENIED_USER".equals(type)) 1059 { 1060 String targetId = map.get("targetId"); 1061 String targetGroup = map.get("targetGroup"); 1062 UserIdentity user = new UserIdentity(targetId, targetGroup); 1063 1064 _buildUserData(type, profileId, context, user); 1065 } 1066 else // if ("ALLOWED_GROUP".equals(type) || "DENIED_GROUP".equals(type)) 1067 { 1068 String targetId = map.get("targetId"); 1069 String targetGroup = map.get("targetGroup"); 1070 GroupIdentity group = new GroupIdentity(targetId, targetGroup); 1071 1072 _buildGroupData(type, profileId, context, group); 1073 } 1074 } 1075 } 1076 1077 private void _buildGroupData(String type, String profileId, String context, GroupIdentity group) 1078 { 1079 Map<String, Map<GroupIdentity, Set<String>>> wData; 1080 if ("ALLOWED_GROUP".equals(type)) 1081 { 1082 wData = _allowedGroupData; 1083 } 1084 else // if ("DENIED_GROUP".equals(type)) 1085 { 1086 wData = _deniedGroupData; 1087 } 1088 1089 if (!wData.containsKey(context)) 1090 { 1091 wData.put(context, new HashMap<>()); 1092 } 1093 Map<GroupIdentity, Set<String>> contextMap = wData.get(context); 1094 1095 if (!contextMap.containsKey(group)) 1096 { 1097 contextMap.put(group, new HashSet<>()); 1098 } 1099 Set<String> profileSet = contextMap.get(group); 1100 1101 profileSet.add(profileId); 1102 } 1103 1104 private void _buildUserData(String type, String profileId, String context, UserIdentity user) 1105 { 1106 Map<String, Map<UserIdentity, Set<String>>> wData; 1107 if ("ALLOWED_USER".equals(type)) 1108 { 1109 wData = _allowedUserData; 1110 } 1111 else // if ("DENIED_USER".equals(type)) 1112 { 1113 wData = _deniedUserData; 1114 } 1115 1116 if (!wData.containsKey(context)) 1117 { 1118 wData.put(context, new HashMap<>()); 1119 } 1120 Map<UserIdentity, Set<String>> contextMap = wData.get(context); 1121 1122 if (!contextMap.containsKey(user)) 1123 { 1124 contextMap.put(user, new HashSet<>()); 1125 } 1126 Set<String> profileSet = contextMap.get(user); 1127 1128 profileSet.add(profileId); 1129 } 1130 1131 private void _buildAnonymousOrAnyConnectedData(String type, String profileId, String context) 1132 { 1133 Map<String, Set<String>> wData; 1134 if ("ALLOWED_ANONYMOUS".equals(type)) 1135 { 1136 wData = _allowedAnonymousData; 1137 } 1138 else if ("DENIED_ANONYMOUS".equals(type)) 1139 { 1140 wData = _deniedAnonymousData; 1141 } 1142 else if ("ALLOWED_ANYCONNECTED".equals(type)) 1143 { 1144 wData = _allowedAnyConnectedData; 1145 } 1146 else // if ("DENIED_ANYCONNECTED".equals(type)) 1147 { 1148 wData = _deniedAnyConnectedData; 1149 } 1150 1151 if (!wData.containsKey(context)) 1152 { 1153 wData.put(context, new HashSet<>()); 1154 } 1155 Set<String> profileSet = wData.get(context); 1156 1157 profileSet.add(profileId); 1158 } 1159 1160 public Map<String, Set<String>> getAllowedAnonymous() 1161 { 1162 return _allowedAnonymousData; 1163 } 1164 public Map<String, Set<String>> getDeniedAnonymous() 1165 { 1166 return _deniedAnonymousData; 1167 } 1168 public Map<String, Set<String>> getAllowedAnyConnected() 1169 { 1170 return _allowedAnyConnectedData; 1171 } 1172 public Map<String, Set<String>> getDeniedAnyConnected() 1173 { 1174 return _deniedAnyConnectedData; 1175 } 1176 public Map<String, Map<UserIdentity, Set<String>>> getAlloweUserData() 1177 { 1178 return _allowedUserData; 1179 } 1180 public Map<String, Map<UserIdentity, Set<String>>> getDeniedUserData() 1181 { 1182 return _deniedUserData; 1183 } 1184 public Map<String, Map<GroupIdentity, Set<String>>> getAlloweGroupData() 1185 { 1186 return _allowedGroupData; 1187 } 1188 public Map<String, Map<GroupIdentity, Set<String>>> getDeniedGroupData() 1189 { 1190 return _deniedGroupData; 1191 } 1192 } 1193}