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

Introduce a token-manager class for token handling #89

Merged
merged 5 commits into from
May 5, 2020

Conversation

vmatyus
Copy link
Contributor

@vmatyus vmatyus commented Apr 28, 2020

The new TokenManager class will be responsible only for the token handling specifically.
Changed some private fields to protected: tokenInfo, expireTime, refreshTime.
Placed getCurrentTime into the utils module to be globally usable.

Checklist
  • npm test passes (tip: npm run lint-fix can correct most style issues)
  • tests are included
  • documentation is changed or added

token-manager class will be responsible only for the token handling specifically and change some private fields to protected: tokenInfo, expireTime, refreshTime.
@CLAassistant
Copy link

CLAassistant commented Apr 28, 2020

CLA assistant check
All committers have signed the CLA.

@mkistler mkistler requested review from mkistler and dpopp07 April 28, 2020 22:37
Copy link
Contributor

@mkistler mkistler left a comment

Choose a reason for hiding this comment

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

This looks good but there a few small fixups and minor improvements I'd like you to make.

* A class for shared functionality for parsing, storing, and requesting
* JWT tokens. Intended to be used as a parent to be extended for token
* request management. Child classes should implement `requestToken()`
* to retrieve the bearer token from intended sources.
Copy link
Contributor

Choose a reason for hiding this comment

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

This comment needs work. First, it should not refer to "JWT tokens" since this class is about generic "tokens". Also, I think child classes also need to implement saveTokenInfo.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in e92c3de

import { RequestWrapper } from '../../lib/request-wrapper';
import {getCurrentTime} from "../utils";

/** Configuration options for JWT token retrieval. */
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/** Configuration options for JWT token retrieval. */
/** Configuration options for token retrieval. */

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in e92c3de

* @returns {Promise}
*/
protected requestToken(): Promise<any> {
const errMsg = '`requestToken` MUST be overridden by a subclass of JwtTokenManagerV1.';
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
const errMsg = '`requestToken` MUST be overridden by a subclass of JwtTokenManagerV1.';
const errMsg = '`requestToken` MUST be overridden by a subclass of TokenManagerV1.';

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in e92c3de

protected disableSslVerification: boolean;
protected headers: OutgoingHttpHeaders;
protected requestWrapperInstance: RequestWrapper;
protected tokenInfo: any;
Copy link
Contributor

Choose a reason for hiding this comment

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

While we're abstracting, I think we should delegate tokenInfo and tokenName to subclasses of TokenManager, with only accessToken visible at this level.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry, but I am not catching your point. TokenInfo currently in use to check that a token already is stored in the object. Here is a reference to a line where there properties are used:
https://github.com/vmatyusGitHub/node-sdk-core/blob/2269660441b93d426932ec9b0dfb51ac1dc0159a/auth/token-managers/token-manager.ts#L98
In the constructor TokenInfo is initialised to an empty object and tokenName shall be initialised in a subclass.
Are you suggesting to have only accesToken property with type string, this way I shall remove tokenInfo and tokenName from the object's property list?

Copy link
Member

Choose a reason for hiding this comment

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

Since tokenInfo is used in the logic contained in this file, I'm fine with it existing here.

Copy link
Contributor

Choose a reason for hiding this comment

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

Here was my thinking: This class requires its subclasses to implement saveTokenInfo, which is passed the response of the token request. saveTokenInfo has to set some member variables ... specifically expireTime, refreshTime, and tokenInfo.

But what is tokenInfo? It is just an object that must contain a field named tokenName that contains the access token. From the point of view of a generic TokenManager, these are extraneous details. All it needs is the accessToken. So why not simplify the TokenManager class (i.e. make it more general), and simply use accessToken set by saveTokenInfo, and push the complexity of varying token property names into the subclass, JWTTokenManager.

I can live with the code the way it is, but I think it would be better if tokenInfo and tokenName was pushed down into JWTTokenManager and TokenManager only dealt with accessToken.

Copy link
Contributor Author

@vmatyus vmatyus May 4, 2020

Choose a reason for hiding this comment

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

Now, I understand your request. Thank you for the more detailed description. I created a modification that would use accessToken. In this commit the change can be reviewed: 064b92f

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was just wondering why it is important to use TokenInfo inside JwtTokenManager? Will there be a feature in the future that will be built upon the content of this object?

Copy link
Member

Choose a reason for hiding this comment

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

Are you referring to the type TokenInfo? I don't know that we have a specific feature in mind for the future so it is not truly important. However, I think it is worth leaving in as at the very least it provides a developer with knowledge of what they can expect the response to look like.

}

/**
* Save the token from the response and the calculated expiration time to the object's state.
Copy link
Contributor

Choose a reason for hiding this comment

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

We should be explicit. This method must set accessToken (see earlier comment), expireTime, and refreshTime based on the tokenResponse.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Half fixed in e92c3de

Remove all jwt reference from the class and function descriptions.
Extend child classes implementation description with `saveTokenInfo` implementation requirement.
Add more explicit description to `saveTokenInfo`
Copy link
Member

@dpopp07 dpopp07 left a comment

Choose a reason for hiding this comment

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

I think the change looks good. I did leave a couple stylistic comments to address before merging. I will also wait to merge until Mike approves as well

function getCurrentTime(): number {
return Math.floor(Date.now() / 1000);
}
import {TokenManager, TokenManagerOptions} from "./token-manager";
Copy link
Member

Choose a reason for hiding this comment

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

Style suggestion:

Suggested change
import {TokenManager, TokenManagerOptions} from "./token-manager";
import { TokenManager, TokenManagerOptions } from "./token-manager";

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in fc4e9b6

import { OutgoingHttpHeaders } from 'http';
import logger from '../../lib/logger';
import { RequestWrapper } from '../../lib/request-wrapper';
import {getCurrentTime} from "../utils";
Copy link
Member

Choose a reason for hiding this comment

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

Style suggestion:

Suggested change
import {getCurrentTime} from "../utils";
import { getCurrentTime } from "../utils";

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in fc4e9b6

protected disableSslVerification: boolean;
protected headers: OutgoingHttpHeaders;
protected requestWrapperInstance: RequestWrapper;
protected tokenInfo: any;
Copy link
Member

Choose a reason for hiding this comment

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

Since tokenInfo is used in the logic contained in this file, I'm fine with it existing here.

@vmatyus vmatyus requested a review from mkistler April 30, 2020 12:11
Copy link
Contributor

@mkistler mkistler left a comment

Choose a reason for hiding this comment

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

The code as-is is fine but I think it could be marginally better with a slightly different design. I'll leave it to you to decide whether to include that in this PR or leave it for future work.

protected disableSslVerification: boolean;
protected headers: OutgoingHttpHeaders;
protected requestWrapperInstance: RequestWrapper;
protected tokenInfo: any;
Copy link
Contributor

Choose a reason for hiding this comment

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

Here was my thinking: This class requires its subclasses to implement saveTokenInfo, which is passed the response of the token request. saveTokenInfo has to set some member variables ... specifically expireTime, refreshTime, and tokenInfo.

But what is tokenInfo? It is just an object that must contain a field named tokenName that contains the access token. From the point of view of a generic TokenManager, these are extraneous details. All it needs is the accessToken. So why not simplify the TokenManager class (i.e. make it more general), and simply use accessToken set by saveTokenInfo, and push the complexity of varying token property names into the subclass, JWTTokenManager.

I can live with the code the way it is, but I think it would be better if tokenInfo and tokenName was pushed down into JWTTokenManager and TokenManager only dealt with accessToken.

@dpopp07
Copy link
Member

dpopp07 commented May 1, 2020

I second @mkistler - I think the suggestion is good but I can live with the current code. @vmatyusGitHub what do you think?

@vmatyus
Copy link
Contributor Author

vmatyus commented May 4, 2020

In my custom authentication case also only 1 access token is in use, so I also think it is a valid request. I am open to implement it.

Store token in accessToken and move varying token property names into subclass JWT.
Update tests to use accessToken field.
Copy link
Contributor

@mkistler mkistler left a comment

Choose a reason for hiding this comment

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

Looks Great! 👍

Thanks for making the accessToken change!

@vmatyus
Copy link
Contributor Author

vmatyus commented May 5, 2020

@mkistler and @dpopp07 Thanks for answering my concerns and reviewing my changes.

@vmatyus
Copy link
Contributor Author

vmatyus commented May 5, 2020

Can I ask to merge this PR?

@dpopp07 dpopp07 merged commit 23c5f3f into IBM:master May 5, 2020
ibm-devx-automation pushed a commit that referenced this pull request May 5, 2020
# [2.4.0](v2.3.2...v2.4.0) (2020-05-05)

### Features

* **token-manager:** Introduce a token-manager class for token handling ([#89](#89)) ([23c5f3f](23c5f3f))
@ibm-devx-automation
Copy link

🎉 This PR is included in version 2.4.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

JurajNyiri pushed a commit to JurajNyiri/node-sdk-core that referenced this pull request Aug 22, 2024
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.14.16 to 14.14.19.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants