Skip to content

Commit 879fff3

Browse files
ad-mfredericosilva
authored andcommitted
Add idempotency in requests (#482)
* Add idempotency in requests * Drop getToken in lib/api.js
1 parent 24ba0f2 commit 879fff3

5 files changed

Lines changed: 28 additions & 25 deletions

File tree

bin/generic/credential/password/add/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
const Cli = require('lib/cli');
44
const credentials = require('lib/credentials');
5+
const crypto = require('lib/crypto');
56

67
const options = {
78
name: {
@@ -40,7 +41,7 @@ module.exports = (resource) => Cli.createCommand('add', {
4041
let password = args.password;
4142

4243
if (!password) {
43-
password = await credentials.randomPassword();
44+
password = await crypto.randomPassword();
4445
console.error(`The generated password is: ${password}`);
4546
}
4647

lib/api.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
'use strict';
2-
2+
const crypto = require('./crypto');
33
const superagent = require('superagent');
44
const Cookie = require('cookie');
55
const WebSocket = require('ws');
@@ -17,6 +17,7 @@ const API_SSH_PORT = process.env.API_SSH_PORT || 22;
1717

1818
const API_URL = API_SECURE ? `https://${API_HOSTNAME}/v1` : `http://${API_HOSTNAME}/v1`;
1919
const WS_URL = API_SECURE ? `wss://${API_HOSTNAME}/ws` : `ws://${API_HOSTNAME}/ws`;
20+
const RETRY_IDEMPOTENT_COUNT = 3;
2021

2122
const SSH_SERVER_HOST_KEY = '3e2aa423d42d7e8b14d50625512c8ac19db767ed';
2223

@@ -246,14 +247,14 @@ const update = async (method, uri, body) => {
246247
if (verbose && !!body) {
247248
logger('verbose', 'body', JSON.stringify(body, null, 2));
248249
}
249-
250250
const prefer_async = 'no-wait' in args && args['no-wait'];
251251
const prefer_value = prefer_async ? 'respond-async,wait=0' : `respond-async,wait=${60 * 60 * 24}`;
252252

253253
const res = await api(method, uri)
254254
.send(body)
255-
.set({ Prefer: prefer_value });
256-
255+
.set({ Prefer: prefer_value })
256+
.set({ 'x-idempotency-key': await crypto.randomPassword()})
257+
.retry(RETRY_IDEMPOTENT_COUNT);
257258
saveCookie(res);
258259
if (verbose) {
259260
logger('verbose', 'status', res.status);

lib/credentials.js

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -81,19 +81,11 @@ const getCredentialCreate = async (args, credential_types) => {
8181
return credential;
8282
};
8383

84-
const randomPassword = (size = 15) => new Promise((resolve, reject) =>
85-
crypto.randomBytes(size, function (err, buffer) {
86-
if (err) {
87-
reject(err);
88-
}
89-
resolve(buffer.toString('hex'));
90-
})
91-
);
84+
9285

9386
module.exports = {
9487
getCredentialCreate,
9588
hashPassword,
96-
randomPassword,
9789
password_types,
9890
types,
9991
};

lib/crypto.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
'use strict';
2+
3+
const crypto = require('crypto');
4+
5+
const randomPassword = (size = 15) => new Promise((resolve, reject) =>
6+
crypto.randomBytes(size, function (err, buffer) {
7+
if (err) {
8+
return reject(err);
9+
}
10+
return resolve(buffer.toString('hex'));
11+
})
12+
);
13+
14+
module.exports = {
15+
randomPassword,
16+
};

lib/tests.js

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
'use strict';
2-
const crypto = require('crypto');
2+
const crypto = require('./crypto');
33
const { spawn } = require('child_process');
44
const shell_quote = require('shell-quote');
55
const os = require('os');
@@ -322,13 +322,6 @@ const resourceAccessCycle = (type, project, options = {}) => wrap(type, options,
322322
}
323323
});
324324

325-
const getToken = () => new Promise((resolve, reject) => crypto.randomBytes(48, function (err, buffer) {
326-
if (err) {
327-
reject(err);
328-
}
329-
resolve(buffer.toString('hex'));
330-
}));
331-
332325
const randomFileName = () => path.join(os.tmpdir(), `test-h1-cli-${now}-${Math.random()}`);
333326

334327
const getRandomFile = (content = 'some-content') => {
@@ -379,7 +372,7 @@ const passwordLifeCycle = async (t, type, resource) => {
379372
const new_name = `renamed-${name}`;
380373

381374
await run(`${type} credential list --${type} ${resource.name}`);
382-
const secret = await getToken();
375+
const secret = await crypto.getPassword();
383376
await run(`${type} credential password add --name ${name} --password ${secret} --${type} ${resource.name}`);
384377
const list = await run(`${type} credential password list --${getOption(type)} ${resource.name}`);
385378
t.true(list.some(p => p.name === name));
@@ -478,7 +471,7 @@ const logStreamProcess = async (t, type, resource, trigger) => {
478471
await delay(2000); // allows wss connection to start
479472
const ids = [];
480473
for (let i = 0; i <= 10; i++) {
481-
const id_request = await getToken();
474+
const id_request = await crypto.getPassword();
482475
await trigger(id_request);
483476
ids.push(id_request);
484477
}
@@ -546,7 +539,7 @@ module.exports = {
546539
// tests for environment
547540
requireSlaveProject,
548541
// requirements
549-
getToken,
542+
getToken: crypto.randomPassword, // back-ward compatibility
550543
getRandomFile,
551544
runProcess,
552545
randomFileName,

0 commit comments

Comments
 (0)