-
Notifications
You must be signed in to change notification settings - Fork 36
/
operations.js
119 lines (103 loc) · 4.15 KB
/
operations.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
var fs = require("fs");
var request = require('request');
var url = require('url');
var crypto = require('crypto');
var exec = require('child_process').exec;
var _ = require("lodash");
var key = require('ursa').coercePrivateKey;
exports.operations = function(config){
return {
sign: function(uri, body, method, fn){
var timestamp = new Date().toISOString().replace(/\....Z/, "Z");
var hashedPath = this.sha(url.parse(uri).path);
var hash = this.sha((body ? JSON.stringify(body) : ""));
var request_headers = {
"Method": method,
"Hashed Path": hashedPath,
"X-Ops-Content-Hash": hash,
"X-Ops-Timestamp": timestamp,
"X-Ops-UserId": config.name
}
var request_headers = _.map(_.pairs(request_headers), function(header){
return header.join(":");
}).join("\n");
var signature = key(config.key_contents).privateEncrypt(request_headers, 'utf8', 'base64');
var auth_headers = {
"Accept": "application/json",
"X-Ops-Timestamp": timestamp,
"X-Ops-UserId": config.name,
"X-Ops-Content-Hash": hash,
"X-Chef-Version": "0.10.4",
"X-Ops-Sign": "version=1.0"
};
var auth_header_count = 0;
_.each(signature.match(/.{1,60}/g), function(signature_section){
var name = ["X-Ops-Authorization", ++auth_header_count].join("-");
auth_headers[name] = signature_section;
});
return fn(auth_headers);
},
sha: function(str){
var sum;
sum = crypto.createHash('sha1');
sum.update(str);
return sum.digest('base64');
},
request: function(url, qs, body, method, fn){
this.sign(url, body, method, function(headers){
var data = {
url: url,
method: method,
headers: headers,
qs: qs || {}
}
if(config.hasOwnProperty('ca')) {
if(config.ca === null) {
data.strictSSL = false;
data.rejectUnauthorized = false;
}
else
data.ca = config.ca;
}
if(config.hasOwnProperty('timeout')) {
data.timeout = config.timeout
}
if(body){
data.body = JSON.stringify(body);
data.headers['Content-type'] = "application/json";
}
request(data, function(err, response){
if (response) {
if(response.statusCode >= 200 && response.statusCode <= 206){
try{
var err = null;
var body = JSON.parse(response.body);
}
catch(e){
var err = new Error("Cannot parse response body");
var body = null;
}
return fn(err, body);
}
else{
var message = ["Received status code:", response.statusCode].join(" ");
try{
var body = JSON.parse(response.body);
if(_.has(body, "error"))
message = [message, body.error].join(" - ");
var err = new Error(message);
}
catch(e){
var err = new Error(message);
}
return fn(err, null)
}
}
else {
return fn(err, null);
}
});
});
}
}
}