15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* OAuthSimple
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  * A simpler version of OAuth
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  * author:     jr conlin
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  * mail:       src@anticipatr.com
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  * copyright:  unitedHeroes.net
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  * version:    1.0
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  * url:        http://unitedHeroes.net/OAuthSimple
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  * Copyright (c) 2009, unitedHeroes.net
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  * All rights reserved.
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  * Redistribution and use in source and binary forms, with or without
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  * modification, are permitted provided that the following conditions are met:
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *     * Redistributions of source code must retain the above copyright
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *       notice, this list of conditions and the following disclaimer.
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *     * Redistributions in binary form must reproduce the above copyright
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *       notice, this list of conditions and the following disclaimer in the
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *       documentation and/or other materials provided with the distribution.
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *     * Neither the name of the unitedHeroes.net nor the
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *       names of its contributors may be used to endorse or promote products
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *       derived from this software without specific prior written permission.
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  * THIS SOFTWARE IS PROVIDED BY UNITEDHEROES.NET ''AS IS'' AND ANY
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  * DISCLAIMED. IN NO EVENT SHALL UNITEDHEROES.NET BE LIABLE FOR ANY
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)var OAuthSimple;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if (OAuthSimple === undefined)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Simple OAuth
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * This class only builds the OAuth elements, it does not do the actual
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * transmission or reception of the tokens. It does not validate elements
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * of the token. It is for client use only.
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * api_key is the API key, also known as the OAuth consumer key
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * shared_secret is the shared secret (duh).
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Both the api_key and shared_secret are generally provided by the site
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * offering OAuth services. You need to specify them at object creation
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * because nobody <explative>ing uses OAuth without that minimal set of
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * signatures.
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * If you want to use the higher order security that comes from the
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * OAuth token (sorry, I don't provide the functions to fetch that because
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * sites aren't horribly consistent about how they offer that), you need to
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * pass those in either with .setTokensAndSecrets() or as an argument to the
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * .sign() or .getHeaderString() functions.
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Example:
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       <code>
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        var oauthObject = OAuthSimple().sign({path:'http://example.com/rest/',
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              parameters: 'foo=bar&gorp=banana',
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              signatures:{
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                api_key:'12345abcd',
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                shared_secret:'xyz-5309'
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             }});
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        document.getElementById('someLink').href=oauthObject.signed_url;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       </code>
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * that will sign as a "GET" using "SHA1-MAC" the url. If you need more than
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * that, read on, McDuff.
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /** OAuthSimple creator
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Create an instance of OAuthSimple
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @param api_key {string}       The API Key (sometimes referred to as the consumer key) This value is usually supplied by the site you wish to use.
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @param shared_secret (string) The shared secret. This value is also usually provided by the site you wish to use.
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OAuthSimple = function (consumer_key,shared_secret)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*        if (api_key == undefined)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            throw("Missing argument: api_key (oauth_consumer_key) for OAuthSimple. This is usually provided by the hosting site.");
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (shared_secret == undefined)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            throw("Missing argument: shared_secret (shared secret) for OAuthSimple. This is usually provided by the hosting site.");
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/      this._secrets={};
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this._parameters={};
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // General configuration options.
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (consumer_key !== undefined) {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            this._secrets['consumer_key'] = consumer_key;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (shared_secret !== undefined) {
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            this._secrets['shared_secret'] = shared_secret;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this._default_signature_method= "HMAC-SHA1";
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this._action = "GET";
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this._nonce_chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this.reset = function() {
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            this._parameters={};
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            this._path=undefined;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return this;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        };
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /** set the parameters either from a hash or a string
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         *
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         * @param {string,object} List of parameters for the call, this can either be a URI string (e.g. "foo=bar&gorp=banana" or an object/hash)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         */
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this.setParameters = function (parameters) {
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (parameters === undefined) {
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                parameters = {};
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (typeof(parameters) == 'string') {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                parameters=this._parseParameterString(parameters);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            this._parameters = parameters;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (this._parameters['oauth_nonce'] === undefined) {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                this._getNonce();
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (this._parameters['oauth_timestamp'] === undefined) {
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                this._getTimestamp();
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (this._parameters['oauth_method'] === undefined) {
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                this.setSignatureMethod();
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (this._parameters['oauth_consumer_key'] === undefined) {
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                this._getApiKey();
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if(this._parameters['oauth_token'] === undefined) {
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                this._getAccessToken();
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return this;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        };
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /** convienence method for setParameters
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         *
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         * @param parameters {string,object} See .setParameters
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         */
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this.setQueryString = function (parameters) {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return this.setParameters(parameters);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        };
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /** Set the target URL (does not include the parameters)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         *
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         * @param path {string} the fully qualified URI (excluding query arguments) (e.g "http://example.org/foo")
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         */
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this.setURL = function (path) {
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (path == '') {
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                throw ('No path specified for OAuthSimple.setURL');
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            this._path = path;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return this;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        };
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /** convienence method for setURL
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         *
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         * @param path {string} see .setURL
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         */
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this.setPath = function(path){
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return this.setURL(path);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        };
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /** set the "action" for the url, (e.g. GET,POST, DELETE, etc.)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         *
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         * @param action {string} HTTP Action word.
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         */
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this.setAction = function(action) {
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (action === undefined) {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                action="GET";
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            action = action.toUpperCase();
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (action.match('[^A-Z]')) {
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                throw ('Invalid action specified for OAuthSimple.setAction');
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            this._action = action;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return this;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        };
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /** set the signatures (as well as validate the ones you have)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         *
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         * @param signatures {object} object/hash of the token/signature pairs {api_key:, shared_secret:, oauth_token: oauth_secret:}
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         */
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this.setTokensAndSecrets = function(signatures) {
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (signatures)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                for (var i in signatures) {
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    this._secrets[i] = signatures[i];
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            // Aliases
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (this._secrets['api_key']) {
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                this._secrets.consumer_key = this._secrets.api_key;
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (this._secrets['access_token']) {
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                this._secrets.oauth_token = this._secrets.access_token;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (this._secrets['access_secret']) {
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                this._secrets.oauth_secret = this._secrets.access_secret;
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            // Gauntlet
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (this._secrets.consumer_key === undefined) {
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                throw('Missing required consumer_key in OAuthSimple.setTokensAndSecrets');
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (this._secrets.shared_secret === undefined) {
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                throw('Missing required shared_secret in OAuthSimple.setTokensAndSecrets');
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if ((this._secrets.oauth_token !== undefined) && (this._secrets.oauth_secret === undefined)) {
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                throw('Missing oauth_secret for supplied oauth_token in OAuthSimple.setTokensAndSecrets');
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return this;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        };
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /** set the signature method (currently only Plaintext or SHA-MAC1)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         *
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         * @param method {string} Method of signing the transaction (only PLAINTEXT and SHA-MAC1 allowed for now)
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         */
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this.setSignatureMethod = function(method) {
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (method === undefined) {
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                method = this._default_signature_method;
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            //TODO: accept things other than PlainText or SHA-MAC1
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (method.toUpperCase().match(/(PLAINTEXT|HMAC-SHA1)/) === undefined) {
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                throw ('Unknown signing method specified for OAuthSimple.setSignatureMethod');
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            this._parameters['oauth_signature_method']= method.toUpperCase();
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return this;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        };
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /** sign the request
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         *
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         * note: all arguments are optional, provided you've set them using the
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         * other helper functions.
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         *
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         * @param args {object} hash of arguments for the call
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         *                   {action:, path:, parameters:, method:, signatures:}
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         *                   all arguments are optional.
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         */
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this.sign = function (args) {
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (args === undefined) {
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                args = {};
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            // Set any given parameters
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if(args['action'] !== undefined) {
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                this.setAction(args['action']);
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (args['path'] !== undefined) {
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                this.setPath(args['path']);
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (args['method'] !== undefined) {
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                this.setSignatureMethod(args['method']);
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            this.setTokensAndSecrets(args['signatures']);
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (args['parameters'] !== undefined){
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            this.setParameters(args['parameters']);
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            // check the parameters
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            var normParams = this._normalizedParameters();
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            this._parameters['oauth_signature']=this._generateSignature(normParams);
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return {
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                parameters: this._parameters,
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                signature: this._oauthEscape(this._parameters['oauth_signature']),
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                signed_url: this._path + '?' + this._normalizedParameters(),
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                header: this.getHeaderString()
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            };
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        };
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /** Return a formatted "header" string
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         *
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         * NOTE: This doesn't set the "Authorization: " prefix, which is required.
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         * I don't set it because various set header functions prefer different
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         * ways to do that.
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         *
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         * @param args {object} see .sign
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         */
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this.getHeaderString = function(args) {
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (this._parameters['oauth_signature'] === undefined) {
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                this.sign(args);
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            var result = 'OAuth ';
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            for (var pName in this._parameters)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if (!pName.match(/^oauth/)) {
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    continue;
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if ((this._parameters[pName]) instanceof Array)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                {
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    var pLength = this._parameters[pName].length;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    for (var j=0;j<pLength;j++)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    {
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        result += pName +'="'+this._oauthEscape(this._parameters[pName][j])+'" ';
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                else
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                {
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    result += pName + '="'+this._oauthEscape(this._parameters[pName])+'" ';
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return result;
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        };
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // Start Private Methods.
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /** convert the parameter string into a hash of objects.
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         *
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         */
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this._parseParameterString = function(paramString){
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            var elements = paramString.split('&');
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            var result={};
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            for(var element=elements.shift();element;element=elements.shift())
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                var keyToken=element.split('=');
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                var value='';
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if (keyToken[1]) {
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    value=decodeURIComponent(keyToken[1]);
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if(result[keyToken[0]]){
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    if (!(result[keyToken[0]] instanceof Array))
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    {
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        result[keyToken[0]] = Array(result[keyToken[0]],value);
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    else
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    {
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        result[keyToken[0]].push(value);
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                else
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                {
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    result[keyToken[0]]=value;
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return result;
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        };
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this._oauthEscape = function(string) {
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (string === undefined) {
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                return "";
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (string instanceof Array)
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                throw('Array passed to _oauthEscape');
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return encodeURIComponent(string).replace(/\!/g, "%21").
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            replace(/\*/g, "%2A").
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            replace(/'/g, "%27").
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            replace(/\(/g, "%28").
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            replace(/\)/g, "%29");
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        };
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this._getNonce = function (length) {
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (length === undefined) {
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                length=5;
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            var result = "";
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            var cLength = this._nonce_chars.length;
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            for (var i = 0; i < length;i++) {
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                var rnum = Math.floor(Math.random() *cLength);
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                result += this._nonce_chars.substring(rnum,rnum+1);
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            this._parameters['oauth_nonce']=result;
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return result;
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        };
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this._getApiKey = function() {
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (this._secrets.consumer_key === undefined) {
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                throw('No consumer_key set for OAuthSimple.');
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            this._parameters['oauth_consumer_key']=this._secrets.consumer_key;
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return this._parameters.oauth_consumer_key;
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        };
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this._getAccessToken = function() {
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (this._secrets['oauth_secret'] === undefined) {
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                return '';
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (this._secrets['oauth_token'] === undefined) {
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                throw('No oauth_token (access_token) set for OAuthSimple.');
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            this._parameters['oauth_token'] = this._secrets.oauth_token;
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return this._parameters.oauth_token;
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        };
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this._getTimestamp = function() {
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            var d = new Date();
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            var ts = Math.floor(d.getTime()/1000);
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            this._parameters['oauth_timestamp'] = ts;
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return ts;
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        };
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this.b64_hmac_sha1 = function(k,d,_p,_z){
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // heavily optimized and compressed version of http://pajhome.org.uk/crypt/md5/sha1.js
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // _p = b64pad, _z = character size; not used here but I left them available just in case
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if(!_p){_p='=';}if(!_z){_z=8;}function _f(t,b,c,d){if(t<20){return(b&c)|((~b)&d);}if(t<40){return b^c^d;}if(t<60){return(b&c)|(b&d)|(c&d);}return b^c^d;}function _k(t){return(t<20)?1518500249:(t<40)?1859775393:(t<60)?-1894007588:-899497514;}function _s(x,y){var l=(x&0xFFFF)+(y&0xFFFF),m=(x>>16)+(y>>16)+(l>>16);return(m<<16)|(l&0xFFFF);}function _r(n,c){return(n<<c)|(n>>>(32-c));}function _c(x,l){x[l>>5]|=0x80<<(24-l%32);x[((l+64>>9)<<4)+15]=l;var w=[80],a=1732584193,b=-271733879,c=-1732584194,d=271733878,e=-1009589776;for(var i=0;i<x.length;i+=16){var o=a,p=b,q=c,r=d,s=e;for(var j=0;j<80;j++){if(j<16){w[j]=x[i+j];}else{w[j]=_r(w[j-3]^w[j-8]^w[j-14]^w[j-16],1);}var t=_s(_s(_r(a,5),_f(j,b,c,d)),_s(_s(e,w[j]),_k(j)));e=d;d=c;c=_r(b,30);b=a;a=t;}a=_s(a,o);b=_s(b,p);c=_s(c,q);d=_s(d,r);e=_s(e,s);}return[a,b,c,d,e];}function _b(s){var b=[],m=(1<<_z)-1;for(var i=0;i<s.length*_z;i+=_z){b[i>>5]|=(s.charCodeAt(i/8)&m)<<(32-_z-i%32);}return b;}function _h(k,d){var b=_b(k);if(b.length>16){b=_c(b,k.length*_z);}var p=[16],o=[16];for(var i=0;i<16;i++){p[i]=b[i]^0x36363636;o[i]=b[i]^0x5C5C5C5C;}var h=_c(p.concat(_b(d)),512+d.length*_z);return _c(o.concat(h),512+160);}function _n(b){var t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",s='';for(var i=0;i<b.length*4;i+=3){var r=(((b[i>>2]>>8*(3-i%4))&0xFF)<<16)|(((b[i+1>>2]>>8*(3-(i+1)%4))&0xFF)<<8)|((b[i+2>>2]>>8*(3-(i+2)%4))&0xFF);for(var j=0;j<4;j++){if(i*8+j*6>b.length*32){s+=_p;}else{s+=t.charAt((r>>6*(3-j))&0x3F);}}}return s;}function _x(k,d){return _n(_h(k,d));}return _x(k,d);
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this._normalizedParameters = function() {
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            var elements = new Array();
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            var paramNames = [];
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            var ra =0;
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            for (var paramName in this._parameters)
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if (ra++ > 1000) {
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    throw('runaway 1');
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                paramNames.unshift(paramName);
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            paramNames = paramNames.sort();
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            pLen = paramNames.length;
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            for (var i=0;i<pLen; i++)
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                paramName=paramNames[i];
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                //skip secrets.
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if (paramName.match(/\w+_secret/)) {
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    continue;
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if (this._parameters[paramName] instanceof Array)
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                {
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    var sorted = this._parameters[paramName].sort();
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    var spLen = sorted.length;
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    for (var j = 0;j<spLen;j++){
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        if (ra++ > 1000) {
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            throw('runaway 1');
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            }
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        elements.push(this._oauthEscape(paramName) + '=' +
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  this._oauthEscape(sorted[j]));
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    continue;
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                elements.push(this._oauthEscape(paramName) + '=' +
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              this._oauthEscape(this._parameters[paramName]));
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return elements.join('&');
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        };
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this._generateSignature = function() {
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            var secretKey = this._oauthEscape(this._secrets.shared_secret)+'&'+
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                this._oauthEscape(this._secrets.oauth_secret);
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (this._parameters['oauth_signature_method'] == 'PLAINTEXT')
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                return secretKey;
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (this._parameters['oauth_signature_method'] == 'HMAC-SHA1')
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                var sigString = this._oauthEscape(this._action)+'&'+this._oauthEscape(this._path)+'&'+this._oauthEscape(this._normalizedParameters());
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                return this.b64_hmac_sha1(secretKey,sigString);
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return null;
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        };
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return this;
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
459