Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Modular request decorations (and pluggable authentication) #1

Open
wants to merge 35 commits into
base: master
Choose a base branch
from

Conversation

alekitto
Copy link
Member

@alekitto alekitto commented Feb 4, 2020

Autoconfigured api client was deprecated in favor to a modular http client.
Where possible breaking changes has been avoided.
This is a major change

Motivation:

Custom authenticator was needed in a non-oauth-bundle enabled application.
Basic authentication is required on some urls, OpenID connect on others. This was impossible to handle without rewriting the request method of the Client class.

Proposed solution and examples:

When creating an Http client a set of decorators could be passed to handle transformations and authentication. This allows custom authenticators to be added simpy implementing DecoratorInterface and passing it to the client.

Other transformations could be added based on custom logic. Ex:

  • Different authenticators based on URL
  • Adding header for user switching
  • Adding query parameter for i18n

Changes summary:

  • Internal ContextualClient class has been removed, as the withContext client method.
  • Main http client is now Http.Client class (Api.Client has been deprecated).
  • Requests are enriched (decorated) at client level, not at requestor level.
  • Request decorators:
    • UrlDecorator: resolves path with defined base url
    • VersionSetterDecorator: appends version parameter to accept header
    • BodyConverterDecorator: converts js object when passed as request data (JSON.stringify)
    • OAuthClientTokenAuthenticator: authenticates request with client credentials token
    • OAuthTokenPasswordAuthenticator: authenticates request using access/refresh token pairs where available. Exposes authenticate(user, password) and logout() methods to log users in/out.
  • Accept header has now its own class to handle modifications properly.

@alekitto alekitto changed the title Modular request decorations (and pluggable authentication) [WIP] Modular request decorations (and pluggable authentication) Feb 7, 2020
@alekitto
Copy link
Member Author

alekitto commented Feb 7, 2020

Added WIP tag.

What’s missing, to be added in the next few days:

  • openid connect code flow authenticator
  • openid connect implicit flow authenticator
  • tests (currently broken because of jf autoloader parser bug)

Copy link
Member

@massimilianobraglia massimilianobraglia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey there, @alekitto!

Thanks again for this really useful improvement. This permits every possible user to customize our client request management!!

Just left some really minor comments :)

import NotFoundHttpException from '../Exception/NotFoundHttpException';

/**
* @memberOf Fazland.Atlante.Api

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@memberOf Fazland.Atlante.Http

* Constructor.
*
* @param {RequesterInterface} requester Object which performs http requests.
* @param {DecoratorInterface[]} requestDecorators Decorators to apply to the request.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

* @param {DecoratorInterface[]} [requestDecorators = []] Decorators to apply to the request.

import Headers from '../../Headers';
import NoTokenAvailableException from '../../../Exception/NoTokenAvailableException';

export default class OAuthClientTokenAuthenticator {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generic subnamespace Fazland.Atlante.Decorator.Authentication.OAuth instead having the prefix in the class name

* @param {string} [data_encoding] could be "json" or "form". If "json" encodes token request data with JSON.stringify,
* if "form" data will be encoded as form data.
*/
constructor(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The jsdoc is not aligned to the configuration object specified in the signature

import NoTokenAvailableException from '../../../Exception/NoTokenAvailableException';
import OAuthClientTokenAuthenticator from './OAuthClientTokenAuthenticator';

export default class OAuthTokenPasswordAuthenticator extends OAuthClientTokenAuthenticator {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Subnamespace also for this :)

* @param {null|string} [client_secret]
* @param {string} [client_token_key]
* @param {string} [data_encoding]
* @param {string} [access_token_key]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

* @param {string} [access_token_key = 'access_token']

* @param {string} [client_token_key]
* @param {string} [data_encoding]
* @param {string} [access_token_key]
* @param {string} [refresh_token_key]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

* @param {string} [refresh_token_key = 'refresh_token']


/**
* @param {string} key
* @param {*} default_

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

* @param {*} [default_ = null]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants