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

feat: Pass a valid auth token. #248

Merged
merged 3 commits into from
Jan 13, 2021
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
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,21 @@ const openshiftRestClient = require('openshift-rest-client').OpenshiftClient;
})();
```

It is also possible to send in a valid auth token instead of a username/password. If we use the above example, the settings object might look something like this:

```
const settings = {
};

settings.config = {
url: process.env.CLUSTER_URL,
auth: {
token: process.env.TOKEN
},
insecureSkipTlsVerify: true
};
```

To see more examples of how to customize your config, check out the [kubernetes-client Initializing section](https://www.npmjs.com/package/kubernetes-client#initializing)

#### Load API from a Remote Cluster
Expand Down
28 changes: 27 additions & 1 deletion lib/basic-auth-request.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,31 @@ const buildError = (requestError) => {
return err;
};

// Use this function if a user passes in just an auth token
// This will return a User Openshift Object
async function getUserFromAuthToken (settings) {
return new Promise((resolve, reject) => {
const req = {
method: 'GET',
url: `${settings.url}/apis/user.openshift.io/v1/users/~`,
auth: {
bearer: settings.token
},
strictSSL: 'insecureSkipTlsVerify' in settings ? !settings.insecureSkipTlsVerify : true
};

request(req, (err, resp, body) => {
if (err) return reject(buildError(err));

if (resp.statusCode === 401) {
return reject(new Error(`401 Unable to authenticate with token ${settings.token}`));
}

return resolve(JSON.parse(body));
});
});
}

async function getTokenFromBasicAuth (settings) {
// Get the Auth URL from Openshift endpoint
const authUrl = await getAuthUrlFromOCP(settings.url, 'insecureSkipTlsVerify' in settings ? !settings.insecureSkipTlsVerify : true);
Expand Down Expand Up @@ -46,5 +71,6 @@ async function getTokenFromBasicAuth (settings) {
}

module.exports = {
getTokenFromBasicAuth
getTokenFromBasicAuth,
getUserFromAuthToken
};
17 changes: 13 additions & 4 deletions lib/openshift-rest-client.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const fs = require('fs');
const path = require('path');

const { Client, alias, KubeConfig } = require('kubernetes-client');
const { getTokenFromBasicAuth } = require('./basic-auth-request');
const { getTokenFromBasicAuth, getUserFromAuthToken } = require('./basic-auth-request');
const Request = require('kubernetes-client/backends/request');

const serviceCatalogCRD = require('./specs/service-catalog-crd.json');
Expand Down Expand Up @@ -65,6 +65,7 @@ const spec = JSON.parse(zlib.gunzipSync(fs.readFileSync(path.join(__dirname, 'sp
* @param {object|string} [settings.config] - custom config object(KubeConfig or object). String value will assume a config file location.
* @param {string} [settings.config.url] - Openshift cluster url
* @param {object} [settings.config.auth] -
* @param {string} [settings.config.auth.token] - auth token used to authenticate to the Openshift Cluster
* @param {string} [settings.config.auth.username] - username to authenticate to Openshift
* @param {string} [settings.config.auth.password] - password to authenticate to Openshift
* @param {boolean} [settings.config.insecureSkipTlsVerify] - flag to ignore TLS verification
Expand Down Expand Up @@ -92,15 +93,23 @@ async function openshiftClient (settings = {}) {
clientConfig.backend = new Request({ kubeconfig });
} else if (typeof config === 'object' && config.auth) {
// Check for the auth username password
if ('user' in config.auth || 'username' in config.auth) {
if ('user' in config.auth || 'username' in config.auth || 'token' in config.auth) {
// They are trying the basic auth.
// Get the access token using the username and password
// Check to see if we are passing in a username/password
const { insecureSkipTlsVerify, url, authUrl } = config;
const user = config.auth.username || config.auth.user;
let user = config.auth.username || config.auth.user;
const password = config.auth.password || config.auth.pass;

const accessToken = await getTokenFromBasicAuth({ insecureSkipTlsVerify, url, user, password, authUrl });
let accessToken;

if (config.auth.token) {
const openshiftUser = await getUserFromAuthToken({ insecureSkipTlsVerify, url, token: config.auth.token });
accessToken = config.auth.token;
user = openshiftUser.metadata.name;
} else {
accessToken = await getTokenFromBasicAuth({ insecureSkipTlsVerify, url, user, password, authUrl });
}
const clusterUrl = url;
// Create clusterName from clusterUrl by removing 'https://'
const clusterName = clusterUrl.replace(/(^\w+:|^)\/\//, '');
Expand Down
87 changes: 87 additions & 0 deletions test/basic-auth-request-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,90 @@ test('basic auth request with request error', (t) => {
t.end();
});
});

// Getting the User from a Token Tests

test('get user from token', (t) => {
const basicAuthRequest = proxyquire('../lib/basic-auth-request', {
request: (requestObject, cb) => {
t.equal(requestObject.strictSSL, false, 'should be false');
return cb(null, {
statusCode: 200
},
JSON.stringify({
kind: 'User',
metadata: {
name: 'developer'
}
})
);
}
});

const settings = {
url: 'http://',
token: '12346',
insecureSkipTlsVerify: true
};

const p = basicAuthRequest.getUserFromAuthToken(settings);

t.equal(p instanceof Promise, true, 'is an Promise');

p.then((userObject) => {
t.equal(userObject.metadata.name, 'developer', 'user should be equal');
t.end();
});
});

test('get user from token with 401 status code', (t) => {
const basicAuthRequest = proxyquire('../lib/basic-auth-request', {
request: (requestObject, cb) => {
t.equal(requestObject.strictSSL, false, 'should be false');
return cb(null, {
statusCode: 401,
request: {
uri: {
host: 'https://'
}
}
});
}
});

const settings = {
url: 'http://',
token: '12346',
insecureSkipTlsVerify: true
};

const p = basicAuthRequest.getUserFromAuthToken(settings);

t.equal(p instanceof Promise, true, 'is an Promise');

p.catch((error) => {
t.equal(error.message,
'401 Unable to authenticate with token 12346',
'should be equal');
t.end();
});
});

test('get user from token with request error', (t) => {
const basicAuthRequest = proxyquire('../lib/basic-auth-request', {
request: (requestObject, cb) => {
return cb({ message: 'Error' }, {});
}
});

const settings = {};

const p = basicAuthRequest.getUserFromAuthToken(settings);

t.equal(p instanceof Promise, true, 'is an Promise');

p.catch((error) => {
t.equal(error.message, 'Error', 'should be equal');
t.end();
});
});
66 changes: 66 additions & 0 deletions test/openshift-client-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,72 @@ test('test basic auth - username/password', async (t) => {
t.end();
});

test('test basic auth - token', async (t) => {
const settings = {
config: {
url: 'http://test-url',
auth: {
token: '12345'
}
}
};

const openshiftRestClient = proxyquire('../lib/openshift-rest-client', {
'./basic-auth-request': {
getTokenFromBasicAuth: () => {
t.fail('should not reach this');
},
getUserFromAuthToken: () => {
t.pass('should reach here');
return Promise.resolve({
kind: 'User',
metadata: {
user: 'developer'
}
});
}
}
});

await openshiftRestClient(settings);
t.pass();
t.end();
});

test('test basic auth - token, user and password', async (t) => {
const settings = {
config: {
url: 'http://test-url',
auth: {
username: 'developer',
password: 'developer',
token: '12345'
}
}
};

const openshiftRestClient = proxyquire('../lib/openshift-rest-client', {
'./basic-auth-request': {
getTokenFromBasicAuth: () => {
t.fail('should not reach this');
},
getUserFromAuthToken: () => {
t.pass('should reach here');
return Promise.resolve({
kind: 'User',
metadata: {
user: 'developer'
}
});
}
}
});

await openshiftRestClient(settings);
t.pass();
t.end();
});

test('test basic auth - user/pass', async (t) => {
const settings = {
config: {
Expand Down