On Fri, May 12, 2017 at 9:56 AM, Carsten Ziegeler <cziege...@apache.org> wrote: > Julian Sedding wrote >> Definitely +1 on doing this right. >> >> Regardless of the above, the goals I read in this thread are the following: >> - only register a service if the required service-user is available >> (ServiceUserMapped) >> - announce service-users lazily >> >> An implementation could consist of a component, let's call it >> ServiceUserRegistry. The ServiceUserRegistry looks for >> ServiceUserProvider services (e.g. a SlingRepository implementation >> could also implement this interface). Furthermore, the >> ServiceUserRegistry implements FindHook (in theory I think a >> ListenerHook would be better, but this does not work with the current >> Felix SCR implementation) looking for requests for ServiceUserMapped >> services and their (optional) sub-service name. If a service is >> requested that is not yet available, the ServiceUserRegistry asks all >> ServiceUserProviders if they can provide a suitable service user. If >> that is the case it registers an appropriately configured service >> (this could be achieved by means of a ComponentFactory). >> >> Unregistering of service users that go away could be handled on two >> levels: 1. if a ServiceUserProvider is unregistered, all service-users >> it provided need to be unregistered as well. 2. A ServiceUserProvider >> needs to be able to signal the ServiceUserRegistry that a user has >> disappeared. >> >> With the introduction of a default service-user mapping, at least the >> name ServiceUserMapped seems no longer appropriate. We could rename it >> to ServiceUser or ServiceUserAvailable. And/or I could imagine going a >> step further and provide a ServiceResourceResolverFactory (an >> interface with a single method "createResourceResolver(Map authInfo)" >> or maybe a second one with no args for convenience). A consumer would >> inject the ServiceResourceResolverFactory instead of a >> ResourceResolverFactory. The @Reference target filter could optionally >> indicate a subservice name. >> >> Please feel free to rip this apart or improve on it! ;) > > :) Thanks, yes we could do something along these lines. But it gets more > complicated with having N resource providers as potentially each > resource provider (which uses authentication) has to have this service > user. Still doable. > > Let's assume for the sake of the discussion that we keep the name > ServiceUserMapped. > > We could register service hooks: if a ServiceUserMapped is requested > which doesn't exist, the hook could: > - get "all" resource providers requiring authentication (let's talk > about "all" below) > - ask each of them through some interface whether they have the > requested service user
Agreed. I called "some interface" ServiceUserProvider. > - if all of them respond with "yes" or if there is no resource provider > requiring authentication, the ServiceUserMapped service is registered > > If a ServiceUserMapped is registered and a resource provider requiring > authentication is added, the above check needs to be done for the new > provider and potentially the ServiceUserMapped gets unregistered. > > I mentioned above that "all" resource providers need to be asked, we > could also argue that only resource providers which require > authentication and are not lazy need to provide the service user. Lazy > resource providers are optional anyway. > Interesting aspect that "all" need to have the service user. I had assumed "at least one" resource provider needs to have the service user. Both "all" and "at least one" are heuristics, because we don't know what the service-user will access. In some cases "all" may be too strict: you need to provide matching users in all RRPs to allow a service user access to one of them. In other cases "at least one" may be to lax: the service user actually needs to access multiple RRPs. Not sure where the sweet spot is... Maybe we should allow indicating the desired RRP(s) in the ServiceUserMapped's target filter (which can be set via configuration, i.e. during deployment). Regards Julian > If we can go with that assumption, the check whether a service user > exists becomes pretty easy: simply try to get a resource resolver with > that service user - if a login exception occurs, it's not available -> > no ServiceUserMapped. Otherwise register the ServiceUserMapped. > > I think with the above simplification it becomes fairly easy to > implement. It neither exposes service users to the world nor does it > require API changes > > > Regards > > Carsten > > -- > Carsten Ziegeler > Adobe Research Switzerland > cziege...@apache.org