Core部分だけできた。そのうちbitbucketに上げます。
function IAMClient(accessKeyId, secretAccessKey) { this.accessKeyId = accessKeyId; this.secretAccessKey = secretAccessKey; } IAMClient.prototype = { USER_AGENT: 'Watashi_ha_Kitsune_desu/0.1.0', API_VERSION: '2010-05-08', HOST: 'iam.amazonaws.com', TIMEOUT: 30000, query: function (action, params, callback, async) { if (!params) { params = []; } var queryString = this.makeQuery(action, params); var xhr = new XMLHttpRequest(); xhr.open('POST', 'https://' + this.HOST + '/', async); xhr.setRequestHeader('User-Agent', this.USER_AGENT); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhr.setRequestHeader('Content-Length', queryString.length); xhr.setRequestHeader('Connection', 'close'); function extxhr() { xhr.success = function() { return (xhr.status >= 200 && xhr.status < 300); } xhr.callback = function(xhr) { callback && callback(xhr); } xhr.xml = function() { var xml = new XML(xhr.responseText.replace(/xmlns="[^"]*"/, "")); return xml; } return xhr; } if (async) { xhr.onreadystatechange = function() { if (xhr.readyState != 4) { return; } try { extxhr().callback(); } catch (e) { alert(e); } }; } else { xhr.onreadystatechange = function() {}; } var timer = setTimeout(xhr.abort, this.TIMEOUT); try { xhr.send(queryString); clearTimeout(timer); } catch(e) { if (!async) { clearTimeout(timer); } throw e; } return extxhr(); }, // query makeQuery: function(action, params) { var kvs = []; kvs.push(['Action', action]); kvs.push(['Version', this.API_VERSION]); kvs.push(['SignatureVersion', '2']); kvs.push(['SignatureMethod', 'HmacSHA1']); kvs.push(['Timestamp', this.timestamp()]); kvs.push(['AWSAccessKeyId', this.accessKeyId]); for (var i = 0; i < params.length; i++) { kvs.push(params[i]); } kvs.sort(function(a, b) { a = a[0]; b = b[0]; return (a < b) ? -1 : (a > b) ? 1 : 0; }); var queryParams = []; for (var i = 0; i < kvs.length; i++) { var key = kvs[i][0]; var val = encodeURIComponent(kvs[i][1]); queryParams.push(key + '=' + val); } var queryString = queryParams.join('&'); var stringToSign = 'POST\n' + this.HOST + '\n/\n' + queryString; var signature = b64_hmac_sha1(this.secretAccessKey, stringToSign); queryString += '&Signature=' + encodeURIComponent(signature); return queryString; }, // makeQuery timestamp: function(date) { if (!date) { date = new Date(); } function pad(num) { return (num < 10 ? '0' : '') + num; } var year = pad(date.getUTCFullYear()); var mon = pad(date.getUTCMonth() + 1); var day = pad(date.getUTCDate()); var hour = pad(date.getUTCHours()); var min = pad(date.getUTCMinutes()); var sec = pad(date.getUTCSeconds()); return [year, mon, day].join('-') + 'T' + [hour, min, sec].join(':') + 'Z'; } // timestamp } // IAMClient
使い方はこんな感じ。
var iamcli = new IAMClient('<YourAWSAccessKeyId>', '<YourAWSSecretAccessKey>'); var xhr = iamcli.query('ListUsers'); alert(xhr.xml()..Users.member);
E4Xは便利ですね。