Skip to content

Commit f876b6d

Browse files
committed
feat: implement new authenticators to handle sdk authentication (#37)
* feat: implement new authenticators to handle sdk authentication * refactor: remove support for user-managed access tokens in the token managers * refactor(iam-token-manager): do not use a default auth header if client id/secret are not set * docs: update the migration document to reflect these changes * refactor: rename token managers * refactor(iam-token-manager): rename method `setAuthorizationInfo` to `setClientIdAndSecret` BREAKING CHANGE: The old style of passing credentials to the base service will no longer work. An Authenticator instance MUST be passed in to the base service constructor. BREAKING CHANGE: token managers no longer support user access tokens. use BearerTokenAuthenticator instead BREAKING CHANGE: The class names of the token managers have changed. * `Icp4dTokenManagerV1` renamed to `Cp4dTokenManager` * `IamTokenManagerV1` renamed to `IamTokenManager` * `JwtTokenManagerV1` renamed to `JwtTokenManager` BREAKING CHANGE: The public method `setAuthorizationInfo` is renamed to `setClientIdAndSecret`
1 parent dc24154 commit f876b6d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+2128
-1374
lines changed

.eslintignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ node_modules/
88
**/*v*.js
99
!test/**/*.js
1010
lib/*.js
11-
auth/*.js
11+
auth/**/*.js
1212
index.js
1313
scripts/typedoc/

.gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ doc/
99
.env
1010
.eslintcache
1111
lib/*.js
12-
auth/*.js
12+
auth/**/*.js
1313
iam-token-manager/*.js
1414
index.js
1515
.nyc_output
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* Copyright 2019 IBM Corp. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { OutgoingHttpHeaders } from 'http';
18+
19+
// This could just be the type for the `baseOptions` field of the Base Service
20+
// but to avoid a circular dependency or a refactor, this will do for now
21+
export interface AuthenticateOptions {
22+
headers?: OutgoingHttpHeaders;
23+
[propName: string]: any;
24+
}
25+
26+
// callback can send one arg, error or null
27+
export type AuthenticateCallback = (result: null | Error) => void;
28+
29+
export interface AuthenticatorInterface {
30+
authenticate(options: AuthenticateOptions, callback: AuthenticateCallback): void
31+
}

auth/authenticators/authenticator.ts

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/**
2+
* Copyright 2019 IBM Corp. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { OutgoingHttpHeaders } from 'http';
18+
import { getMissingParams } from '../../lib/helper';
19+
import { checkCredentials } from '../utils/helpers'; // just using '../utils' here leads to a test failure. need to open an issue against typescript
20+
import { AuthenticateCallback, AuthenticateOptions, AuthenticatorInterface } from './authenticator-interface';
21+
22+
export class Authenticator implements AuthenticatorInterface {
23+
/**
24+
* Base Authenticator Class
25+
*
26+
* Provides the Base Authenticator class for others to extend.
27+
*/
28+
constructor() {
29+
if (!(this instanceof Authenticator)) {
30+
throw new Error(
31+
'the "new" keyword is required to create authenticator instances'
32+
);
33+
}
34+
}
35+
36+
public authenticate(options: AuthenticateOptions, callback: AuthenticateCallback): void {
37+
throw new Error('Should be implemented by subclass!');
38+
}
39+
40+
protected validate(options: any, requiredOptions: string[]): void {
41+
// check for required params
42+
const missingParamsError = getMissingParams(options, requiredOptions);
43+
if (missingParamsError) {
44+
throw missingParamsError;
45+
}
46+
47+
// check certain credentials for common user errors: username, password, and apikey
48+
// note: will only apply to certain authenticators
49+
const credsToCheck = ['username', 'password', 'apikey']
50+
const credentialProblems = checkCredentials(options, credsToCheck);
51+
if (credentialProblems) {
52+
throw new Error(credentialProblems);
53+
}
54+
}
55+
}
+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/**
2+
* Copyright 2019 IBM Corp. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import extend = require('extend');
18+
import { computeBasicAuthHeader } from '../utils';
19+
import { Authenticator } from './authenticator';
20+
import { AuthenticateCallback, AuthenticateOptions, AuthenticatorInterface } from './authenticator-interface';
21+
22+
export type Options = {
23+
username?: string;
24+
password?: string;
25+
}
26+
27+
export class BasicAuthenticator extends Authenticator implements AuthenticatorInterface {
28+
protected requiredOptions = ['username', 'password'];
29+
private username: string;
30+
private password: string;
31+
32+
/**
33+
* Basic Authenticator Class
34+
*
35+
* Handles the Basic Authentication pattern.
36+
*
37+
* @param {Object} options
38+
* @param {String} options.username
39+
* @param {String} options.password
40+
* @constructor
41+
*/
42+
constructor(options: Options) {
43+
super();
44+
45+
this.validate(options, this.requiredOptions);
46+
47+
this.username = options.username;
48+
this.password = options.password;
49+
}
50+
51+
public authenticate(options: AuthenticateOptions, callback: AuthenticateCallback): void {
52+
const authHeaderString = computeBasicAuthHeader(this.username, this.password);
53+
const authHeader = { Authorization: authHeaderString }
54+
55+
options.headers = extend(true, {}, options.headers, authHeader);
56+
callback(null);
57+
}
58+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/**
2+
* Copyright 2019 IBM Corp. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import extend = require('extend');
18+
import { Authenticator } from './authenticator';
19+
import { AuthenticateCallback, AuthenticateOptions, AuthenticatorInterface } from './authenticator-interface';
20+
21+
export type Options = {
22+
bearerToken: string;
23+
}
24+
25+
export class BearerTokenAuthenticator extends Authenticator implements AuthenticatorInterface {
26+
protected requiredOptions = ['bearerToken'];
27+
private bearerToken: string;
28+
29+
/**
30+
* Bearer Token Authenticator Class
31+
*
32+
* Handles the Bearer Token pattern.
33+
*
34+
* @param {Object} options
35+
* @param {String} options.bearerToken - bearer token to pass in header
36+
* @constructor
37+
*/
38+
constructor(options: Options) {
39+
super();
40+
41+
this.validate(options, this.requiredOptions);
42+
43+
this.bearerToken = options.bearerToken;
44+
}
45+
46+
public setBearerToken(bearerToken: string): void {
47+
this.bearerToken = bearerToken;
48+
}
49+
50+
public authenticate(options: AuthenticateOptions, callback: AuthenticateCallback): void {
51+
const authHeader = { Authorization: `Bearer ${this.bearerToken}` };
52+
options.headers = extend(true, {}, options.headers, authHeader);
53+
callback(null);
54+
}
55+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/**
2+
* Copyright 2019 IBM Corp. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { OutgoingHttpHeaders } from 'http';
18+
import { Cp4dTokenManager } from '../token-managers';
19+
import { BaseOptions, TokenRequestBasedAuthenticator } from './token-request-based-authenticator';
20+
21+
export interface Options extends BaseOptions {
22+
username: string;
23+
password: string;
24+
url: string;
25+
}
26+
27+
export class CloudPakForDataAuthenticator extends TokenRequestBasedAuthenticator {
28+
protected requiredOptions = ['username', 'password', 'url'];
29+
private username: string;
30+
private password: string;
31+
32+
/**
33+
* Cloud Pak for Data Authenticator Class
34+
*
35+
* Handles the CP4D authentication pattern:
36+
* A username and password are provided and used to retrieve a bearer token.
37+
*
38+
* @param {Object} options
39+
* @constructor
40+
*/
41+
constructor(options: Options) {
42+
super(options);
43+
44+
this.validate(options, this.requiredOptions);
45+
46+
this.username = options.username;
47+
this.password = options.password;
48+
49+
// the param names are shared between the authenticator and the token manager
50+
// so we can just pass along the options object
51+
this.tokenManager = new Cp4dTokenManager(options);
52+
}
53+
}
+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/**
2+
* Copyright 2019 IBM Corp. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { OutgoingHttpHeaders } from 'http';
18+
import { IamTokenManager } from '../token-managers';
19+
import { BaseOptions, TokenRequestBasedAuthenticator } from './token-request-based-authenticator';
20+
21+
export interface Options extends BaseOptions {
22+
apikey: string;
23+
clientId?: string;
24+
clientSecret?: string;
25+
}
26+
27+
export class IamAuthenticator extends TokenRequestBasedAuthenticator {
28+
protected requiredOptions = ['apikey'];
29+
private apikey: string;
30+
private clientId: string;
31+
private clientSecret: string;
32+
33+
/**
34+
* IAM Authenticator Class
35+
*
36+
* Handles the IAM authentication pattern.
37+
*
38+
* @param {Object} options
39+
* @constructor
40+
*/
41+
constructor(options: Options) {
42+
super(options);
43+
44+
this.validate(options, this.requiredOptions);
45+
46+
this.apikey = options.apikey;
47+
this.clientId = options.clientId;
48+
this.clientSecret = options.clientSecret;
49+
50+
// the param names are shared between the authenticator and the token manager
51+
// so we can just pass along the options object
52+
this.tokenManager = new IamTokenManager(options);
53+
}
54+
55+
/**
56+
* Setter for the Client ID and the Client Secret. Both should be provided.
57+
*
58+
* @param {string} clientId
59+
* @param {string} clientSecret
60+
* @returns {void}
61+
*/
62+
public setClientIdAndSecret(clientId: string, clientSecret: string): void {
63+
this.clientId = clientId;
64+
this.clientSecret = clientSecret;
65+
66+
// update properties in token manager
67+
this.tokenManager.setClientIdAndSecret(clientId, clientSecret);
68+
}
69+
}

auth/authenticators/index.ts

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* Copyright 2019 IBM Corp. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
export { AuthenticatorInterface } from './authenticator-interface';
18+
export { Authenticator } from './authenticator';
19+
export { BasicAuthenticator } from './basic-authenticator';
20+
export { BearerTokenAuthenticator } from './bearer-token-authenticator';
21+
export { CloudPakForDataAuthenticator } from './cloud-pak-for-data-authenticator';
22+
export { IamAuthenticator } from './iam-authenticator';
23+
export { NoauthAuthenticator } from './no-auth-authenticator';
24+
export { TokenRequestBasedAuthenticator } from './token-request-based-authenticator';

0 commit comments

Comments
 (0)