-
Notifications
You must be signed in to change notification settings - Fork 685
Moving OAuth support from Devkit into Mule
- Jira: http://www.mulesoft.org/jira/browse/MULE-6843
- Public discussion: http://forum.mulesoft.org/mulesoft/topics/_3_5_m1_mule_moving_oauth_support_from_devkit_into_mule?utm_content=topic_link&utm_medium=email&utm_source=reply_notification
As for version 3.4.0, a lot of common logic such as OAuth support, connection management, retry interceptors, version checking, etc, is generated and packaged for every single connector. This leads to the following issues:
- Any bugfix, improvement, compatibility change, etc. requires to republish all connectors. Mule and Devkit releases become tightly coupled.
- Backwards compatibility between Mule and Devkit generated extensions becomes hard to impossible in some cases
- There's no way to have centralized control for the resources that Devkit generated extensions use.
To move all OAuth1 and OAuth2 support logic from the connectors into the ESB. This is not about creating a mule OAuth client class nor about reimplementing mule solution for that (unless not right now). This is merely about moving that logic into the ESB so that we have a tighter control over it without depending on connector releases.
Moving the connection management code and actually adding a centralized control for the connectors resources is out of the scope of this story.
Some part of that code will be moved to the mule-commons project. Mainly the classes/interfaces which do not have any dependency to Mule API components. Examples of components moved here are:
- OAuthState
- OAuthParameter
- ConnectionException
- ConnectionExceptionCode
- UnableToAcquireConnectionException
- UnableToReleaseConnectionException
- NotAuthorizedException
- Etc
Most of the code though will be moved to the devkit-support module. This module will contain:
All the static components that are currently shipped with the connectors. By static component I mean all the components which code doesn't vary between connectors other that by the package name. Examples: DefaultHttpCallbackAdapter, FetchAccessTokenMessageProcessor, ProcessTemplate, etc.
- Base classes for all common components. Some components like the OAuth2Manager, the pool ObjectFactory, the Authorize message processor, etc. For these type of component, base abstract classes which contain most of the logic are provided. Devkit will no longer generate classes that carry all of that logic but will simply extends those classes and will implement abstract methods to fill in the blanks (very classic implementation of the Template design pattern)
- Devkit will still be in charge of generating docs and XSD.
Since right now there's no code reuse between connectors but merely code that is generated over and over, the connector's generated code contains specific downcasts and strict type couplings on its code. In order to move that code into the ESB in such a way of making it reusable, it becomes necessary to introduce some interfaces that connectors can use in order to interact with the ESB code. These interfaces are:
- OAuth1Connector
- OAuth2Connector
- OAuth1Adapter
- OAuth2Adapter
Devkit generated classes will implement these accordingly in order to interact with the ESB in a decoupled way.
Nothing. It works perfectly. Your 3.4.0 (or lower) extensions carry all of their code and they have no hook whatsoever to Mule. So they will keep working and they simply don't know about Mule's new capabilities. They won't be able to leverage any enhancements on the Mule either.
It won't work. First of all, all 3.5.0 connectors should specify 3.5 as the minimum compatible version so the connector should fail at start time. Other than that, 3.5.0 extensions will look for ESB classes that will not be found on classpath in prior versions. Forward compatibility will not be supported.
Devkit 3.4.0 and below generates one OAuthState class per connector (so, there is a SalesforceConnectorOAuthState, a BoxConnectorOAuthState and so forth). This class is used to persist a connector's OAuth information into the ObjectStore so that access and refresh tokens can be saved/retrieved. The reason to generate this class on each connector is that some OAuth providers use custom fields that need to be retrieved (salesforce in an example of this).
The problem of this solution is token sharing. For example consider the Google connector suite. It has calendar, contacts, tasks, spreadsheet, drive, gmail and prediction connectors (and counting!). Each one of them are a different connector and thus there are 7 different OAuthState classes. However, the OAuth provider is always the same one: Google. You don't want to authorize against google 7 times, you just want to authorize one with all the necessary scopes and then share the token between connectors.
In order to overcome this problem, mule-commons will now have a unique OAuthState class which will carry all the standard attribute plus a map for the custom stuff. At a first glance, the problem gets solved at this point, however there's a migration issue. Suppose that you have a working iApp which uses any OAuth connector, let's say Box. So, you have an ObjectStore filled with BoxConnectorOAuthState classes. If you then migrate to a newer version of the Box connector compiled with Devkit 3.5.0, the new code won't be able to read that access token anymore since it won't be able to cast an instance of BoxConnectorOAuthState to OAuthState.
To overcome this issue in a transparent way, Devkit will continue to generate instances of BoxConnectorOAuthState only that they will be marked as deprecated. Then, if the new code at the ESB reads an instance of BoxConnectorOAuthState, it will transform it to OAuthState and replace the value at the ObjectStore. In this way, the code will start to automatically migrate the access tokens without requesting the user to re authenticate.
Caveats:
- We need to keep supporting this scenario until 3.4.x reaches end of life. After that we can start to only support OAuthState. Since this logic is in the ESB, we don't have to do anything on the connectors once we decided to drop this behavior.
- Once the user has upgraded to 3.5.0 and the migration starts to take place, there's no easy way for the user to rollback to the 3.4.0 versions of the OAuthState without asking the users to re-authenticate.