Explorar o código

Fix adding more implied roles in the RoleHierarchy Builder.

Closes gh-15717

Signed-off-by: Niels Basjes <niels@basjes.nl>
Niels Basjes hai 1 ano
pai
achega
2dc787a573

+ 3 - 3
core/src/main/java/org/springframework/security/access/hierarchicalroles/RoleHierarchyImpl.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2023 the original author or authors.
+ * Copyright 2002-2024 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -295,11 +295,11 @@ public class RoleHierarchyImpl implements RoleHierarchy {
 		}
 
 		private Builder addHierarchy(String role, String... impliedRoles) {
-			Set<GrantedAuthority> withPrefix = new HashSet<>();
+			Set<GrantedAuthority> withPrefix = this.hierarchy.computeIfAbsent(this.rolePrefix.concat(role),
+					(r) -> new HashSet<>());
 			for (String impliedRole : impliedRoles) {
 				withPrefix.add(new SimpleGrantedAuthority(this.rolePrefix.concat(impliedRole)));
 			}
-			this.hierarchy.put(this.rolePrefix.concat(role), withPrefix);
 			return this;
 		}
 

+ 19 - 1
core/src/test/java/org/springframework/security/access/hierarchicalroles/RoleHierarchyImplTests.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2016 the original author or authors.
+ * Copyright 2002-2024 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -259,6 +259,24 @@ public class RoleHierarchyImplTests {
 			.containsExactlyInAnyOrderElementsOf(allAuthorities);
 	}
 
+	@Test
+	public void testBuilderWithRepeatedRoleBuilder() {
+		RoleHierarchyImpl roleHierarchyImpl = RoleHierarchyImpl.withDefaultRolePrefix()
+			.role("A")
+			.implies("B")
+			.role("A") // Adding more implied roles to the existing role 'A'
+			.implies("C", "D")
+			.build();
+
+		List<GrantedAuthority> flatAuthorities = AuthorityUtils.createAuthorityList("ROLE_A");
+		List<GrantedAuthority> allAuthorities = AuthorityUtils.createAuthorityList("ROLE_A", "ROLE_B", "ROLE_C",
+				"ROLE_D");
+
+		assertThat(roleHierarchyImpl).isNotNull();
+		assertThat(roleHierarchyImpl.getReachableGrantedAuthorities(flatAuthorities))
+			.containsExactlyInAnyOrderElementsOf(allAuthorities);
+	}
+
 	@Test
 	public void testBuilderWithRolePrefix() {
 		RoleHierarchyImpl roleHierarchyImpl = RoleHierarchyImpl.withRolePrefix("CUSTOM_PREFIX_")