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