Restricting Controller Service Class Definitions

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Restricting Controller Service Class Definitions

Michael Hogue
All,

   I'm in the process of making some changes to a processor which exposes a
controller service with several implementations. However, I only want to
allow a particular implementation for the processor, but i've not found a
clean way to do this. The rationale behind wanting to do this can be found
in the conversation on PR #1986 [1]. In short, I've written a
RestrictedSSLContextService that allows only a specific set of SSL
algorithms to be chosen. I want to change ListenHTTP to allow only that
implementation and not the StandardSSLContextService.

   PropertyDescriptor builders have a method
identifiesControllerService(clazz) which allows you to dictate which
interface the controller service must implement. This is great because it
should allow me to specify an explicit implementation i'd like to force the
processor to allow. The problem with this is that it necessitates an
additional dependency on a non-API module, which i believe is ill-advised.
It actually results in multiple identical controller service entries when
you go to configure the controller service in the UI due to nar service
loading. This is probably a bad thing.

   I've looked across the code base and don't really see an example of
restricting controller service options to specific implementations if you
only want to allow a subset, for example. Adding a validator wouldn't
really work either since the UI would still allow you to choose a
controller service you don't want to allow. My question to those more
familiar with the codebase is whether there's an obvious way to approach
this or if there needs to be significant changes to allow it.

Thanks,
Mike

[1] https://github.com/apache/nifi/pull/1986
Reply | Threaded
Open this post in threaded view
|

Re: Restricting Controller Service Class Definitions

Bryan Bende
Hi Michael,

Generally processors are supposed to only know about an interface for
the service, and then the framework makes the implementations of that
interface available. So the processors shouldn't really know which
specific implementations are available.

I think there are a couple of things that could be done...

You can make a new interface called RestrictedSSLContextService that
extends SSLContextService, and then have an implementation like
StandardRestrictedSSLContextService... then make your customized
ListenHTTP processor rely only on the new interface
(RestrictedSSLContextService).

Another option might be to do something involving custom validate (as
you mentioned)... If the SSLContextService interface had a method to
return a list/array of the supported protocols, then a processor could
use those values in a custom validate to make sure that a service with
the required protocols was selected. You are right that they would
still see all the services in the drop-down, but the processor would
be invalid and unable to be started until selecting the appropriate
service, and they'd see the validation message about what was wrong.

A final option, although not something that is currently possible,
might be to leverage the security model... If you could restrict who
could create a specific type of component, meaning something like
"admin has create permissions on StandardSSLContext from
nifi-standard-nar", then you could set it up so that regular users can
create your restricted service and only admins (or maybe no one) can
create the other kind.

-Bryan


On Mon, Aug 14, 2017 at 11:35 AM, Michael Hogue
<[hidden email]> wrote:

> All,
>
>    I'm in the process of making some changes to a processor which exposes a
> controller service with several implementations. However, I only want to
> allow a particular implementation for the processor, but i've not found a
> clean way to do this. The rationale behind wanting to do this can be found
> in the conversation on PR #1986 [1]. In short, I've written a
> RestrictedSSLContextService that allows only a specific set of SSL
> algorithms to be chosen. I want to change ListenHTTP to allow only that
> implementation and not the StandardSSLContextService.
>
>    PropertyDescriptor builders have a method
> identifiesControllerService(clazz) which allows you to dictate which
> interface the controller service must implement. This is great because it
> should allow me to specify an explicit implementation i'd like to force the
> processor to allow. The problem with this is that it necessitates an
> additional dependency on a non-API module, which i believe is ill-advised.
> It actually results in multiple identical controller service entries when
> you go to configure the controller service in the UI due to nar service
> loading. This is probably a bad thing.
>
>    I've looked across the code base and don't really see an example of
> restricting controller service options to specific implementations if you
> only want to allow a subset, for example. Adding a validator wouldn't
> really work either since the UI would still allow you to choose a
> controller service you don't want to allow. My question to those more
> familiar with the codebase is whether there's an obvious way to approach
> this or if there needs to be significant changes to allow it.
>
> Thanks,
> Mike
>
> [1] https://github.com/apache/nifi/pull/1986
Reply | Threaded
Open this post in threaded view
|

Re: Restricting Controller Service Class Definitions

Andy LoPresto-2
I don’t think this extends to the general case, but in this instance, I support Bryan’s first suggestion. The RestrictedSSLContextService interface will extend the SSLContextService interface, and the StandardRestrictedSSLContextService class can implement that interface and extend StandardSSLContextService and just override the methods related to getting the supported protocols. I think this is the cleanest solution for the issue. 

Thanks for doing this, Mike. 

Andy LoPresto
PGP Fingerprint: 70EC B3E5 98A6 5A3F D3C4  BACE 3C6E F65B 2F7D EF69

On Aug 14, 2017, at 12:09 PM, Bryan Bende <[hidden email]> wrote:

Hi Michael,

Generally processors are supposed to only know about an interface for
the service, and then the framework makes the implementations of that
interface available. So the processors shouldn't really know which
specific implementations are available.

I think there are a couple of things that could be done...

You can make a new interface called RestrictedSSLContextService that
extends SSLContextService, and then have an implementation like
StandardRestrictedSSLContextService... then make your customized
ListenHTTP processor rely only on the new interface
(RestrictedSSLContextService).

Another option might be to do something involving custom validate (as
you mentioned)... If the SSLContextService interface had a method to
return a list/array of the supported protocols, then a processor could
use those values in a custom validate to make sure that a service with
the required protocols was selected. You are right that they would
still see all the services in the drop-down, but the processor would
be invalid and unable to be started until selecting the appropriate
service, and they'd see the validation message about what was wrong.

A final option, although not something that is currently possible,
might be to leverage the security model... If you could restrict who
could create a specific type of component, meaning something like
"admin has create permissions on StandardSSLContext from
nifi-standard-nar", then you could set it up so that regular users can
create your restricted service and only admins (or maybe no one) can
create the other kind.

-Bryan


On Mon, Aug 14, 2017 at 11:35 AM, Michael Hogue
<[hidden email]> wrote:
All,

  I'm in the process of making some changes to a processor which exposes a
controller service with several implementations. However, I only want to
allow a particular implementation for the processor, but i've not found a
clean way to do this. The rationale behind wanting to do this can be found
in the conversation on PR #1986 [1]. In short, I've written a
RestrictedSSLContextService that allows only a specific set of SSL
algorithms to be chosen. I want to change ListenHTTP to allow only that
implementation and not the StandardSSLContextService.

  PropertyDescriptor builders have a method
identifiesControllerService(clazz) which allows you to dictate which
interface the controller service must implement. This is great because it
should allow me to specify an explicit implementation i'd like to force the
processor to allow. The problem with this is that it necessitates an
additional dependency on a non-API module, which i believe is ill-advised.
It actually results in multiple identical controller service entries when
you go to configure the controller service in the UI due to nar service
loading. This is probably a bad thing.

  I've looked across the code base and don't really see an example of
restricting controller service options to specific implementations if you
only want to allow a subset, for example. Adding a validator wouldn't
really work either since the UI would still allow you to choose a
controller service you don't want to allow. My question to those more
familiar with the codebase is whether there's an obvious way to approach
this or if there needs to be significant changes to allow it.

Thanks,
Mike

[1] https://github.com/apache/nifi/pull/1986


signature.asc (859 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Restricting Controller Service Class Definitions

Michael Hogue
I had thought about the interface extension, but thought i should probably
field the question first. Thanks much for the prompt feedback. I'll go
forward with the recommended solution.

Thanks!

On Mon, Aug 14, 2017 at 12:12 PM Andy LoPresto <[hidden email]> wrote:

> I don’t think this extends to the general case, but in this instance, I
> support Bryan’s first suggestion. The RestrictedSSLContextService interface
> will extend the SSLContextService interface, and the
> StandardRestrictedSSLContextService class can implement that interface and
> extend StandardSSLContextService and just override the methods related to
> getting the supported protocols. I think this is the cleanest solution for
> the issue.
>
> Thanks for doing this, Mike.
>
> Andy LoPresto
> [hidden email]
> *[hidden email] <[hidden email]>*
> PGP Fingerprint: 70EC B3E5 98A6 5A3F D3C4  BACE 3C6E F65B 2F7D EF69
>
> On Aug 14, 2017, at 12:09 PM, Bryan Bende <[hidden email]> wrote:
>
> Hi Michael,
>
> Generally processors are supposed to only know about an interface for
> the service, and then the framework makes the implementations of that
> interface available. So the processors shouldn't really know which
> specific implementations are available.
>
> I think there are a couple of things that could be done...
>
> You can make a new interface called RestrictedSSLContextService that
> extends SSLContextService, and then have an implementation like
> StandardRestrictedSSLContextService... then make your customized
> ListenHTTP processor rely only on the new interface
> (RestrictedSSLContextService).
>
> Another option might be to do something involving custom validate (as
> you mentioned)... If the SSLContextService interface had a method to
> return a list/array of the supported protocols, then a processor could
> use those values in a custom validate to make sure that a service with
> the required protocols was selected. You are right that they would
> still see all the services in the drop-down, but the processor would
> be invalid and unable to be started until selecting the appropriate
> service, and they'd see the validation message about what was wrong.
>
> A final option, although not something that is currently possible,
> might be to leverage the security model... If you could restrict who
> could create a specific type of component, meaning something like
> "admin has create permissions on StandardSSLContext from
> nifi-standard-nar", then you could set it up so that regular users can
> create your restricted service and only admins (or maybe no one) can
> create the other kind.
>
> -Bryan
>
>
> On Mon, Aug 14, 2017 at 11:35 AM, Michael Hogue
> <[hidden email]> wrote:
>
> All,
>
>   I'm in the process of making some changes to a processor which exposes a
> controller service with several implementations. However, I only want to
> allow a particular implementation for the processor, but i've not found a
> clean way to do this. The rationale behind wanting to do this can be found
> in the conversation on PR #1986 [1]. In short, I've written a
> RestrictedSSLContextService that allows only a specific set of SSL
> algorithms to be chosen. I want to change ListenHTTP to allow only that
> implementation and not the StandardSSLContextService.
>
>   PropertyDescriptor builders have a method
> identifiesControllerService(clazz) which allows you to dictate which
> interface the controller service must implement. This is great because it
> should allow me to specify an explicit implementation i'd like to force the
> processor to allow. The problem with this is that it necessitates an
> additional dependency on a non-API module, which i believe is ill-advised.
> It actually results in multiple identical controller service entries when
> you go to configure the controller service in the UI due to nar service
> loading. This is probably a bad thing.
>
>   I've looked across the code base and don't really see an example of
> restricting controller service options to specific implementations if you
> only want to allow a subset, for example. Adding a validator wouldn't
> really work either since the UI would still allow you to choose a
> controller service you don't want to allow. My question to those more
> familiar with the codebase is whether there's an obvious way to approach
> this or if there needs to be significant changes to allow it.
>
> Thanks,
> Mike
>
> [1] https://github.com/apache/nifi/pull/1986
>
>
>