Skip to content

Commit 2fbcc5a

Browse files
ziv-codefreshitai-codefresh
authored andcommitted
Support new API key authentication context (#57)
1 parent ba4990c commit 2fbcc5a

File tree

9 files changed

+119
-42
lines changed

9 files changed

+119
-42
lines changed

examples/cfconfig

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,7 @@
11
contexts:
2-
testcontext1:
3-
type: JWT
4-
name: testcontext1
2+
default:
3+
type: APIKey
4+
name: blabla
55
url: 'https://g.codefresh.io'
6-
token: >-
7-
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJfaWQiOiI1NTJlOTQyMjM4MjQ4MzFkMDBiMWNhM2UiLCJhY2NvdW50SWQiOiI1NjgwZjEzMDM0Y2RiMzE3N2M4MmFjYjIiLCJpYXQiOjE1MTIyMzA5MDcsImV4cCI6MTUxNDgyMjkwN30.-OUq7kVLVghCjV4tp7swSzCyzPn-GR3ZF0A-aZo1ic0
8-
acl-type: account
9-
user-id: 552e94223824831d00b1ca3e
10-
account-id: 5680f13034cdb3177c82acb2
11-
expires: 1514822907
12-
user-name: verchol
13-
account-name: verchol_github
14-
current-context: testcontext1
6+
token: 5a4e0b118f2eba0100b538c8.d732aaae8b55fc99a359735644399cdc
7+
current-context: default

lib/interface/cli/codefresh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ recursive(path.resolve(__dirname, 'commands'), (err, files) => {
3939
})
4040
.config('cfconfig', 'Custom path for authentication contexts config file', (configFilePath) => {
4141
try {
42-
authManager.loadContexts(configFilePath, process.env.CF_TOKEN, process.env.CF_URL || DEFAULTS.URL);
42+
authManager.loadContexts(configFilePath, process.env.CF_API_KEY, process.env.CF_URL || DEFAULTS.URL);
4343
} catch (err) {
4444
printError(err);
4545
process.exit(1);

lib/interface/cli/commands/auth/create-context.cmd.js

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,49 +4,52 @@ const _ = require('lodash');
44
const CFError = require('cf-errors');
55
const DEFAULTS = require('../../defaults');
66
const { auth } = require('../../../../logic');
7-
const { JWTContext } = auth.contexts;
7+
const { JWTContext, APIKeyContext } = auth.contexts;
88
const authManager = auth.manager;
99
const authRoot = require('../root/auth.cmd');
1010

1111
const _loginWithToken = async (url, token) => {
12+
let authContext;
1213
try {
13-
const authContext = JWTContext.createFromToken(token, url);
14+
authContext = JWTContext.createFromToken(token, url);
1415
return authContext;
1516

1617
} catch (err) {
17-
const error = new CFError({
18-
cause: err,
19-
message: 'Failed to login with token',
20-
});
21-
throw error;
18+
try {
19+
authContext = APIKeyContext.createFromToken(token, url);
20+
return authContext;
21+
22+
} catch (err) {
23+
const error = new CFError({
24+
cause: err,
25+
message: 'Failed to login with api key',
26+
});
27+
throw error;
28+
}
2229
}
2330
};
2431

2532
const command = new Command({
26-
command: 'create-context <name>',
33+
command: 'create-context [name]',
2734
description: 'create-context',
2835
builder: (yargs) => {
2936
return yargs
30-
.usage('Create a new context from a given token')
37+
.usage('Create a new authentication context using an API key')
3138
.option('url', {
3239
describe: 'Codefresh system custom url',
3340
default: DEFAULTS.URL,
3441
})
3542
.positional('name', {
3643
describe: 'Context name',
44+
default: 'default',
3745
})
38-
.option('token', {
39-
describe: 'Access token',
46+
.option('api-key', {
47+
describe: 'API key',
4048
required: true,
41-
})
42-
.option('type', {
43-
describe: 'Token type',
44-
choices: [JWTContext.TYPE],
45-
default: JWTContext.TYPE,
4649
});
4750
},
4851
handler: async (argv) => {
49-
const authContext = await _loginWithToken(argv.url, argv.token);
52+
const authContext = await _loginWithToken(argv.url, argv['api-key']);
5053

5154
await authContext.validate();
5255

lib/interface/cli/commands/root/auth.cmd.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ const auth = new Command({
1414
'place.\n' +
1515
' 2. If $CFCONFIG environment variable is set, then it is used as the cfconfig file path.\n' +
1616
' 3. Otherwise, ${HOME}/.cfconfig is used.\n' +
17-
' 4. If $CF_TOKEN environment variable is set, then it will be used as the current-context ($CF_URL can be used for custom Codefresh systems).')
17+
' 4. If $CF_API_KEY environment variable is set, then it will be used as the current-context ($CF_URL can be used for custom Codefresh systems).')
1818
.example('$0 auth login username password', '# Login using USER and PASSWORD')
1919
.example('$0 auth login username password --url http://custom-domain.com',
2020
'# Login using USER and PASSWORD to a CUSTOM on-premise codefresh instance')
21-
.example('$0 auth create-context name --token token', '# Create authentication context NAME using TOKEN')
21+
.example('$0 auth create-context name --api-key key', '# Create authentication context NAME using KEY')
2222
.example('$0 auth get-contexts', '# List all existing authentication contexts')
2323
.example('$0 auth use-context name', '# Set active authentication context using NAME context')
2424
.example('$0 auth current-context', '# Show active authentication context')

lib/logic/api/helper.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ const sendHttpRequest = async (httpOptions, authContext) => {
1919
response = await rp(finalOptions);
2020
} catch (err) {
2121
if (_.isEqual(err.statusCode, 401)) {
22-
printError('Unauthorized error: Please update your authentication context');
22+
printError('Unauthorized error: Please create or update your authentication context');
2323
process.exit(1);
2424
}
2525
if (_.isEqual(err.statusCode, 403)) {
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
const _ = require('lodash');
2+
const CFError = require('cf-errors');
3+
const Context = require('./Context');
4+
const api = require('../../api');
5+
6+
const TYPE = 'APIKey';
7+
8+
class APIKeyContext extends Context {
9+
constructor(options) {
10+
super(options);
11+
this.type = TYPE;
12+
this.token = options.token;
13+
this.name = options.name || this.name;
14+
this.defaultColumns = ['current', 'name', 'url'];
15+
}
16+
17+
prepareHttpOptions() {
18+
return {
19+
baseUrl: this.url,
20+
headers: {
21+
Authorization: this.token,
22+
},
23+
};
24+
}
25+
26+
async validate() {
27+
try {
28+
await api.user.getByAuthContext(this);
29+
} catch (err) {
30+
// TODO catch 401 errors, etc...
31+
throw new CFError({
32+
cause: err,
33+
message: 'API Key is not valid',
34+
});
35+
}
36+
}
37+
38+
toString() {
39+
return `name: ${this.name}, url: ${this.url}`;
40+
}
41+
42+
serialize() {
43+
const data = {
44+
token: this.token,
45+
};
46+
47+
return _.assignIn(super.serialize(), data);
48+
}
49+
50+
static createFromSerialized(rawContext) {
51+
return new APIKeyContext({
52+
name: rawContext.name,
53+
url: rawContext.url,
54+
token: rawContext.token,
55+
});
56+
}
57+
58+
static createFromToken(token, url) {
59+
return new APIKeyContext({
60+
token,
61+
url,
62+
});
63+
}
64+
}
65+
66+
APIKeyContext.TYPE = TYPE;
67+
68+
module.exports = APIKeyContext;

lib/logic/auth/contexts/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
const JWTContext = require('./JWTContext');
2+
const APIKeyContext = require('./APIKeyContext');
23

34
module.exports = {
45
JWTContext,
6+
APIKeyContext,
57
};

lib/logic/auth/manager.js

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const CFError = require('cf-errors');
44
const yaml = require('js-yaml');
55

66
// context classes
7-
const { JWTContext } = require('./contexts');
7+
const { JWTContext, APIKeyContext } = require('./contexts');
88

99
/**
1010
* A singelton that is in charge of providing an easy interface to the authentication configuration file on the file system
@@ -84,6 +84,11 @@ class Manager {
8484
this.addContext(context);
8585
break;
8686
}
87+
case APIKeyContext.TYPE: {
88+
const context = APIKeyContext.createFromSerialized(rawContext);
89+
this.addContext(context);
90+
break;
91+
}
8792
default: {
8893
throw new CFError(`Failed to parse context of type: ${rawContext.type}`);
8994
}
@@ -111,17 +116,23 @@ class Manager {
111116

112117
// Supports the ability to use the cli with a JWT token
113118
// TODO in the future when we support more than 1 type of token (Currently only JWT) we need to refactor this
114-
try {
115-
if (cfToken && cfUrl) {
119+
if (cfToken && cfUrl) {
120+
try {
116121
const context = JWTContext.createFromToken(cfToken, cfUrl);
117122
this.addContext(context);
118123
this.setCurrentContext(context);
124+
} catch (err) {
125+
try {
126+
const context = APIKeyContext.createFromToken(cfToken, cfUrl);
127+
this.addContext(context);
128+
this.setCurrentContext(context);
129+
} catch (error) {
130+
throw new CFError({
131+
cause: error,
132+
message: 'Failed to parse CF_API_KEY environment variable',
133+
});
134+
}
119135
}
120-
} catch (err) {
121-
throw new CFError({
122-
cause: err,
123-
message: 'Failed to handle CF_TOKEN',
124-
});
125136
}
126137
}
127138

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "codefresh",
3-
"version": "0.4.9",
3+
"version": "0.5.0",
44
"description": "Codefresh command line utility",
55
"main": "index.js",
66
"preferGlobal": true,

0 commit comments

Comments
 (0)