Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions src/azure_auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ Currently user.authProvider has `any` type and so we don't have a type for user.
We therefore define its type here
*/
interface Config {
expiry: string;
expiry?: string;
['cmd-args']?: string;
['cmd-path']?: string;
['token-key']: string;
['expiry-key']: string;
['access-token']?: string;
['expires-on']?: string;
}
export class AzureAuth implements Authenticator {
public isAuthProvider(user: User): boolean {
Expand Down Expand Up @@ -47,14 +48,16 @@ export class AzureAuth implements Authenticator {
private isExpired(config: Config): boolean {
const token = config['access-token'];
const expiry = config.expiry;
const expiresOn = config['expires-on'];

if (!token) {
return true;
}
if (!expiry) {
if (!expiry && !expiresOn) {
return false;
}

const expiration = Date.parse(expiry);
const expiration = expiry ? Date.parse(expiry) : new Date(parseInt(expiresOn!, 10));
if (expiration < Date.now()) {
return true;
}
Expand Down
281 changes: 281 additions & 0 deletions src/config_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,287 @@ describe('KubeConfig', () => {
expect(opts.headers.Authorization).to.equal(`Bearer ${token}`);
}
});
it('should populate from auth provider', async () => {
const config = new KubeConfig();
const token = 'token';
config.loadFromClusterAndUser(
{ skipTLSVerify: false } as Cluster,
{
authProvider: {
name: 'azure',
config: {
'access-token': token,
expiry: 'Fri Aug 24 07:32:05 PDT 3018',
},
},
} as User,
);
const opts = {} as requestlib.Options;

await config.applyToRequest(opts);
expect(opts.headers).to.not.be.undefined;
if (opts.headers) {
expect(opts.headers.Authorization).to.equal(`Bearer ${token}`);
}
opts.headers = [];
opts.headers.Host = 'foo.com';
await config.applyToRequest(opts);
expect(opts.headers.Authorization).to.equal(`Bearer ${token}`);
});

it('should populate from auth provider without expirty', async () => {
const config = new KubeConfig();
const token = 'token';
config.loadFromClusterAndUser(
{ skipTLSVerify: false } as Cluster,
{
authProvider: {
name: 'azure',
config: {
'access-token': token,
},
},
} as User,
);
const opts = {} as requestlib.Options;

await config.applyToRequest(opts);
expect(opts.headers).to.not.be.undefined;
if (opts.headers) {
expect(opts.headers.Authorization).to.equal(`Bearer ${token}`);
}
});

it('should populate rejectUnauthorized=false when skipTLSVerify is set', async () => {
const config = new KubeConfig();
const token = 'token';
config.loadFromClusterAndUser(
{ skipTLSVerify: true } as Cluster,
{
authProvider: {
name: 'azure',
config: {
'access-token': token,
},
},
} as User,
);
const opts = {} as requestlib.Options;

await config.applyToRequest(opts);
expect(opts.rejectUnauthorized).to.equal(false);
});

it('should not set rejectUnauthorized if skipTLSVerify is not set', async () => {
// This test is just making 100% sure we validate certs unless we explictly set
// skipTLSVerify = true
const config = new KubeConfig();
const token = 'token';
config.loadFromClusterAndUser(
{} as Cluster,
{
authProvider: {
name: 'azure',
config: {
'access-token': token,
},
},
} as User,
);
const opts = {} as requestlib.Options;

await config.applyToRequest(opts);
expect(opts.rejectUnauthorized).to.equal(undefined);
});

it('should throw with expired token and no cmd', () => {
const config = new KubeConfig();
config.loadFromClusterAndUser(
{ skipTLSVerify: false } as Cluster,
{
authProvider: {
name: 'azure',
config: {
expiry: 'Aug 24 07:32:05 PDT 2017',
},
},
} as User,
);
const opts = {} as requestlib.Options;

return expect(config.applyToRequest(opts)).to.eventually.be.rejectedWith('Token is expired!');
});

it('should throw with bad command', () => {
const config = new KubeConfig();
config.loadFromClusterAndUser(
{ skipTLSVerify: false } as Cluster,
{
authProvider: {
name: 'azure',
config: {
'access-token': 'token',
expiry: 'Aug 24 07:32:05 PDT 2017',
'cmd-path': 'non-existent-command',
},
},
} as User,
);
const opts = {} as requestlib.Options;
return expect(config.applyToRequest(opts)).to.eventually.be.rejectedWith(
/Failed to refresh token/,
);
});

it('should exec with expired token', async () => {
// TODO: fix this test for Windows
if (process.platform === 'win32') {
return;
}
const config = new KubeConfig();
const token = 'token';
const responseStr = `{"token":{"accessToken":"${token}"}}`;
config.loadFromClusterAndUser(
{ skipTLSVerify: false } as Cluster,
{
authProvider: {
name: 'azure',
config: {
expiry: 'Aug 24 07:32:05 PDT 2017',
'cmd-path': 'echo',
'cmd-args': `'${responseStr}'`,
'token-key': '{.token.accessToken}',
'expiry-key': '{.token.token_expiry}',
},
},
} as User,
);
const opts = {} as requestlib.Options;
await config.applyToRequest(opts);
expect(opts.headers).to.not.be.undefined;
if (opts.headers) {
expect(opts.headers.Authorization).to.equal(`Bearer ${token}`);
}
});

it('should exec with expired token', async () => {
// TODO: fix this test for Windows
if (process.platform === 'win32') {
return;
}
const config = new KubeConfig();
const token = 'token';
const responseStr = `{"token":{"accessToken":"${token}"}}`;
config.loadFromClusterAndUser(
{ skipTLSVerify: false } as Cluster,
{
authProvider: {
name: 'azure',
config: {
'expires-on': '1590757517834',
'cmd-path': 'echo',
'cmd-args': `'${responseStr}'`,
'token-key': '{.token.accessToken}',
'expiry-key': '{.token.token_expiry}',
},
},
} as User,
);
const opts = {} as requestlib.Options;
await config.applyToRequest(opts);
expect(opts.headers).to.not.be.undefined;
if (opts.headers) {
expect(opts.headers.Authorization).to.equal(`Bearer ${token}`);
}
});

it('should exec without access-token', async () => {
// TODO: fix this test for Windows
if (process.platform === 'win32') {
return;
}
const config = new KubeConfig();
const token = 'token';
const responseStr = `{"token":{"accessToken":"${token}"}}`;
config.loadFromClusterAndUser(
{ skipTLSVerify: false } as Cluster,
{
authProvider: {
name: 'azure',
config: {
'cmd-path': 'echo',
'cmd-args': `'${responseStr}'`,
'token-key': '{.token.accessToken}',
'expiry-key': '{.token.token_expiry}',
},
},
} as User,
);
const opts = {} as requestlib.Options;
await config.applyToRequest(opts);
expect(opts.headers).to.not.be.undefined;
if (opts.headers) {
expect(opts.headers.Authorization).to.equal(`Bearer ${token}`);
}
});
it('should exec without access-token', async () => {
// TODO: fix this test for Windows
if (process.platform === 'win32') {
return;
}
const config = new KubeConfig();
const token = 'token';
const responseStr = `{"token":{"accessToken":"${token}"}}`;
config.loadFromClusterAndUser(
{ skipTLSVerify: false } as Cluster,
{
authProvider: {
name: 'azure',
config: {
'cmd-path': 'echo',
'cmd-args': `'${responseStr}'`,
'token-key': '{.token.accessToken}',
'expiry-key': '{.token.token_expiry}',
},
},
} as User,
);
const opts = {} as requestlib.Options;
await config.applyToRequest(opts);
expect(opts.headers).to.not.be.undefined;
if (opts.headers) {
expect(opts.headers.Authorization).to.equal(`Bearer ${token}`);
}
});
it('should exec succesfully with spaces in cmd', async () => {
// TODO: fix this test for Windows
if (process.platform === 'win32') {
return;
}
const config = new KubeConfig();
const token = 'token';
const responseStr = `{"token":{"accessToken":"${token}"}}`;
config.loadFromClusterAndUser(
{ skipTLSVerify: false } as Cluster,
{
authProvider: {
name: 'azure', // applies to gcp too as they are both handled by CloudAuth class
config: {
'cmd-path': path.join(__dirname, '..', 'test', 'echo space.js'),
'cmd-args': `'${responseStr}'`,
'token-key': '{.token.accessToken}',
'expiry-key': '{.token.token_expiry}',
},
},
} as User,
);
const opts = {} as requestlib.Options;
await config.applyToRequest(opts);
expect(opts.headers).to.not.be.undefined;
if (opts.headers) {
expect(opts.headers.Authorization).to.equal(`Bearer ${token}`);
}
});
it('should exec with exec auth and env vars', async () => {
// TODO: fix this test for Windows
if (process.platform === 'win32') {
Expand Down