3030import org .elasticsearch .common .util .concurrent .ThreadContext ;
3131import org .elasticsearch .common .util .set .Sets ;
3232import org .elasticsearch .license .XPackLicenseState ;
33- import org .elasticsearch .license .XPackLicenseState .Feature ;
3433import org .elasticsearch .xpack .core .common .IteratingActionListener ;
3534import org .elasticsearch .xpack .core .security .authc .Authentication ;
3635import org .elasticsearch .xpack .core .security .authz .RoleDescriptor ;
8483import static org .elasticsearch .xpack .security .support .SecurityIndexManager .isMoveFromRedToNonRed ;
8584
8685/**
87- * A composite roles store that combines built in roles, file-based roles, and index-based roles. Checks the built in roles first, then the
88- * file roles, and finally the index roles.
86+ * A composite roles store that can retrieve roles from multiple sources.
87+ * @see RoleProviders
8988 */
9089public class CompositeRolesStore {
9190
@@ -98,8 +97,7 @@ public class CompositeRolesStore {
9897
9998 private final DeprecationLogger deprecationLogger = DeprecationLogger .getLogger (CompositeRolesStore .class );
10099
101- private final FileRolesStore fileRolesStore ;
102- private final NativeRolesStore nativeRolesStore ;
100+ private final RoleProviders roleProviders ;
103101 private final NativePrivilegeStore privilegeStore ;
104102 private final XPackLicenseState licenseState ;
105103 private final Consumer <Collection <RoleDescriptor >> effectiveRoleDescriptorsConsumer ;
@@ -114,25 +112,31 @@ public class CompositeRolesStore {
114112 private final ApiKeyService apiKeyService ;
115113 private final ServiceAccountService serviceAccountService ;
116114 private final boolean isAnonymousEnabled ;
117- private final List <BiConsumer <Set <String >, ActionListener <RoleRetrievalResult >>> builtInRoleProviders ;
118- private final List <BiConsumer <Set <String >, ActionListener <RoleRetrievalResult >>> allRoleProviders ;
119115 private final Role superuserRole ;
120116 private final Role xpackUserRole ;
121117 private final Role asyncSearchUserRole ;
122118 private final Automaton restrictedIndicesAutomaton ;
123119
124- public CompositeRolesStore (Settings settings , FileRolesStore fileRolesStore , NativeRolesStore nativeRolesStore ,
125- ReservedRolesStore reservedRolesStore , NativePrivilegeStore privilegeStore ,
126- List <BiConsumer <Set <String >, ActionListener <RoleRetrievalResult >>> rolesProviders ,
120+ public CompositeRolesStore (Settings settings , RoleProviders roleProviders , NativePrivilegeStore privilegeStore ,
127121 ThreadContext threadContext , XPackLicenseState licenseState , FieldPermissionsCache fieldPermissionsCache ,
128122 ApiKeyService apiKeyService , ServiceAccountService serviceAccountService ,
129123 DocumentSubsetBitsetCache dlsBitsetCache , IndexNameExpressionResolver resolver ,
130124 Consumer <Collection <RoleDescriptor >> effectiveRoleDescriptorsConsumer ) {
131- this .fileRolesStore = Objects .requireNonNull (fileRolesStore );
132- this .dlsBitsetCache = Objects .requireNonNull (dlsBitsetCache );
133- fileRolesStore .addListener (this ::invalidate );
134- this .nativeRolesStore = Objects .requireNonNull (nativeRolesStore );
125+ this .roleProviders = roleProviders ;
126+ roleProviders .addChangeListener (new RoleProviders .ChangeListener () {
127+ @ Override
128+ public void rolesChanged (Set <String > roles ) {
129+ CompositeRolesStore .this .invalidate (roles );
130+ }
131+
132+ @ Override
133+ public void providersChanged () {
134+ CompositeRolesStore .this .invalidateAll ();
135+ }
136+ });
137+
135138 this .privilegeStore = Objects .requireNonNull (privilegeStore );
139+ this .dlsBitsetCache = Objects .requireNonNull (dlsBitsetCache );
136140 this .licenseState = Objects .requireNonNull (licenseState );
137141 this .fieldPermissionsCache = Objects .requireNonNull (fieldPermissionsCache );
138142 this .apiKeyService = Objects .requireNonNull (apiKeyService );
@@ -152,16 +156,6 @@ public CompositeRolesStore(Settings settings, FileRolesStore fileRolesStore, Nat
152156 nlcBuilder .setMaximumWeight (nlcCacheSize );
153157 }
154158 this .negativeLookupCache = nlcBuilder .build ();
155- this .builtInRoleProviders = List .of (reservedRolesStore , fileRolesStore , nativeRolesStore );
156- if (rolesProviders .isEmpty ()) {
157- this .allRoleProviders = this .builtInRoleProviders ;
158- } else {
159- List <BiConsumer <Set <String >, ActionListener <RoleRetrievalResult >>> allList =
160- new ArrayList <>(builtInRoleProviders .size () + rolesProviders .size ());
161- allList .addAll (builtInRoleProviders );
162- allList .addAll (rolesProviders );
163- this .allRoleProviders = Collections .unmodifiableList (allList );
164- }
165159 this .anonymousUser = new AnonymousUser (settings );
166160 this .isAnonymousEnabled = AnonymousUser .isAnonymousEnabled (settings );
167161 this .restrictedIndicesAutomaton = resolver .getSystemNameAutomaton ();
@@ -411,9 +405,7 @@ private void roleDescriptors(Set<String> roleNames, ActionListener<RolesRetrieva
411405
412406 private void loadRoleDescriptorsAsync (Set <String > roleNames , ActionListener <RolesRetrievalResult > listener ) {
413407 final RolesRetrievalResult rolesResult = new RolesRetrievalResult ();
414- final List <BiConsumer <Set <String >, ActionListener <RoleRetrievalResult >>> asyncRoleProviders =
415- licenseState .checkFeature (Feature .SECURITY_CUSTOM_ROLE_PROVIDERS ) ? allRoleProviders : builtInRoleProviders ;
416-
408+ final List <BiConsumer <Set <String >, ActionListener <RoleRetrievalResult >>> asyncRoleProviders = roleProviders .getProviders ();
417409 final ActionListener <RoleRetrievalResult > descriptorsListener =
418410 ContextPreservingActionListener .wrapPreservingContext (ActionListener .wrap (ignore -> {
419411 rolesResult .setMissingRoles (roleNames );
@@ -553,13 +545,12 @@ public void invalidate(Set<String> roles) {
553545 }
554546
555547 public void usageStats (ActionListener <Map <String , Object >> listener ) {
556- final Map <String , Object > usage = new HashMap <>(2 );
557- usage .put ("file" , fileRolesStore .usageStats ());
548+ final Map <String , Object > usage = new HashMap <>();
558549 usage .put ("dls" , Map .of ("bit_set_cache" , dlsBitsetCache .usageStats ()));
559- nativeRolesStore .usageStats (ActionListener . wrap ( map -> {
560- usage .put ( "native" , map );
561- listener . onResponse ( usage ) ;
562- }, listener :: onFailure ));
550+ roleProviders .usageStats (listener . map ( roleUsage -> {
551+ usage .putAll ( roleUsage );
552+ return usage ;
553+ }));
563554 }
564555
565556 public void onSecurityIndexStateChange (SecurityIndexManager .State previousState , SecurityIndexManager .State currentState ) {
0 commit comments