18ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen/* OAuthSimple
28ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  * A simpler version of OAuth
38ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  *
48ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  * author:     jr conlin
58ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  * mail:       src@anticipatr.com
68ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  * copyright:  unitedHeroes.net
78ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  * version:    1.0
88ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  * url:        http://unitedHeroes.net/OAuthSimple
98ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  *
108ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  * Copyright (c) 2009, unitedHeroes.net
118ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  * All rights reserved.
128ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  *
138ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  * Redistribution and use in source and binary forms, with or without
148ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  * modification, are permitted provided that the following conditions are met:
158ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  *     * Redistributions of source code must retain the above copyright
168ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  *       notice, this list of conditions and the following disclaimer.
178ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  *     * Redistributions in binary form must reproduce the above copyright
188ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  *       notice, this list of conditions and the following disclaimer in the
198ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  *       documentation and/or other materials provided with the distribution.
208ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  *     * Neither the name of the unitedHeroes.net nor the
218ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  *       names of its contributors may be used to endorse or promote products
228ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  *       derived from this software without specific prior written permission.
238ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  *
248ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  * THIS SOFTWARE IS PROVIDED BY UNITEDHEROES.NET ''AS IS'' AND ANY
258ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
268ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
278ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  * DISCLAIMED. IN NO EVENT SHALL UNITEDHEROES.NET BE LIABLE FOR ANY
288ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
298ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
308ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
318ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
328ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
338ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
348ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen */
358ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenvar OAuthSimple;
368ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
378ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenif (OAuthSimple === undefined)
388ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen{
398ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    /* Simple OAuth
408ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen     *
418ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen     * This class only builds the OAuth elements, it does not do the actual
428ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen     * transmission or reception of the tokens. It does not validate elements
438ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen     * of the token. It is for client use only.
448ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen     *
458ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen     * api_key is the API key, also known as the OAuth consumer key
468ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen     * shared_secret is the shared secret (duh).
478ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen     *
488ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen     * Both the api_key and shared_secret are generally provided by the site
498ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen     * offering OAuth services. You need to specify them at object creation
508ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen     * because nobody <explative>ing uses OAuth without that minimal set of
518ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen     * signatures.
528ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen     *
538ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen     * If you want to use the higher order security that comes from the
548ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen     * OAuth token (sorry, I don't provide the functions to fetch that because
558ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen     * sites aren't horribly consistent about how they offer that), you need to
568ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen     * pass those in either with .setTokensAndSecrets() or as an argument to the
578ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen     * .sign() or .getHeaderString() functions.
588ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen     *
598ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen     * Example:
608ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen       <code>
618ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        var oauthObject = OAuthSimple().sign({path:'http://example.com/rest/',
628ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                                              parameters: 'foo=bar&gorp=banana',
638ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                                              signatures:{
648ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                                                api_key:'12345abcd',
658ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                                                shared_secret:'xyz-5309'
668ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                                             }});
678ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        document.getElementById('someLink').href=oauthObject.signed_url;
688ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen       </code>
698ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen     *
708ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen     * that will sign as a "GET" using "SHA1-MAC" the url. If you need more than
718ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen     * that, read on, McDuff.
728ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen     */
738ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
748ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    /** OAuthSimple creator
758ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen     *
768ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen     * Create an instance of OAuthSimple
778ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen     *
788ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen     * @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.
798ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen     * @param shared_secret (string) The shared secret. This value is also usually provided by the site you wish to use.
808ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen     */
818ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    OAuthSimple = function (consumer_key,shared_secret)
828ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    {
838ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen/*        if (api_key == undefined)
848ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            throw("Missing argument: api_key (oauth_consumer_key) for OAuthSimple. This is usually provided by the hosting site.");
858ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        if (shared_secret == undefined)
868ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            throw("Missing argument: shared_secret (shared secret) for OAuthSimple. This is usually provided by the hosting site.");
878ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen*/      this._secrets={};
888ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        this._parameters={};
898ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
908ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        // General configuration options.
918ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        if (consumer_key !== undefined) {
928ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            this._secrets['consumer_key'] = consumer_key;
938ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            }
948ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        if (shared_secret !== undefined) {
958ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            this._secrets['shared_secret'] = shared_secret;
968ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            }
978ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        this._default_signature_method= "HMAC-SHA1";
988ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        this._action = "GET";
998ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        this._nonce_chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
1008ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
1018ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
1028ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        this.reset = function() {
1038ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            this._parameters={};
1048ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            this._path=undefined;
1058ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            return this;
1068ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        };
1078ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
1088ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        /** set the parameters either from a hash or a string
1098ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen         *
1108ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen         * @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)
1118ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen         */
1128ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        this.setParameters = function (parameters) {
1138ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            if (parameters === undefined) {
1148ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                parameters = {};
1158ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                }
1168ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            if (typeof(parameters) == 'string') {
1178ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                parameters=this._parseParameterString(parameters);
1188ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                }
1198ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            this._parameters = parameters;
1208ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            if (this._parameters['oauth_nonce'] === undefined) {
1218ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                this._getNonce();
1228ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                }
1238ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            if (this._parameters['oauth_timestamp'] === undefined) {
1248ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                this._getTimestamp();
1258ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                }
1268ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            if (this._parameters['oauth_method'] === undefined) {
1278ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                this.setSignatureMethod();
1288ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                }
1298ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            if (this._parameters['oauth_consumer_key'] === undefined) {
1308ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                this._getApiKey();
1318ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                }
1328ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            if(this._parameters['oauth_token'] === undefined) {
1338ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                this._getAccessToken();
1348ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                }
1358ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
1368ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            return this;
1378ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        };
1388ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
1398ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        /** convienence method for setParameters
1408ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen         *
1418ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen         * @param parameters {string,object} See .setParameters
1428ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen         */
1438ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        this.setQueryString = function (parameters) {
1448ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            return this.setParameters(parameters);
1458ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        };
1468ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
1478ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        /** Set the target URL (does not include the parameters)
1488ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen         *
1498ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen         * @param path {string} the fully qualified URI (excluding query arguments) (e.g "http://example.org/foo")
1508ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen         */
1518ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        this.setURL = function (path) {
1528ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            if (path == '') {
1538ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                throw ('No path specified for OAuthSimple.setURL');
1548ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                }
1558ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            this._path = path;
1568ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            return this;
1578ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        };
1588ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
1598ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        /** convienence method for setURL
1608ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen         *
1618ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen         * @param path {string} see .setURL
1628ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen         */
1638ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        this.setPath = function(path){
1648ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            return this.setURL(path);
1658ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        };
1668ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
1678ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        /** set the "action" for the url, (e.g. GET,POST, DELETE, etc.)
1688ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen         *
1698ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen         * @param action {string} HTTP Action word.
1708ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen         */
1718ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        this.setAction = function(action) {
1728ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            if (action === undefined) {
1738ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                action="GET";
1748ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                }
1758ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            action = action.toUpperCase();
1768ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            if (action.match('[^A-Z]')) {
1778ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                throw ('Invalid action specified for OAuthSimple.setAction');
1788ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                }
1798ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            this._action = action;
1808ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            return this;
1818ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        };
1828ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
1838ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        /** set the signatures (as well as validate the ones you have)
1848ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen         *
1858ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen         * @param signatures {object} object/hash of the token/signature pairs {api_key:, shared_secret:, oauth_token: oauth_secret:}
1868ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen         */
1878ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        this.setTokensAndSecrets = function(signatures) {
1888ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            if (signatures)
1898ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            {
1908ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                for (var i in signatures) {
1918ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                    this._secrets[i] = signatures[i];
1928ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                    }
1938ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            }
1948ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            // Aliases
1958ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            if (this._secrets['api_key']) {
1968ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                this._secrets.consumer_key = this._secrets.api_key;
1978ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                }
1988ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            if (this._secrets['access_token']) {
1998ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                this._secrets.oauth_token = this._secrets.access_token;
2008ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                }
2018ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            if (this._secrets['access_secret']) {
2028ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                this._secrets.oauth_secret = this._secrets.access_secret;
2038ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                }
2048ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            // Gauntlet
2058ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            if (this._secrets.consumer_key === undefined) {
2068ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                throw('Missing required consumer_key in OAuthSimple.setTokensAndSecrets');
2078ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                }
2088ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            if (this._secrets.shared_secret === undefined) {
2098ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                throw('Missing required shared_secret in OAuthSimple.setTokensAndSecrets');
2108ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                }
2118ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            if ((this._secrets.oauth_token !== undefined) && (this._secrets.oauth_secret === undefined)) {
2128ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                throw('Missing oauth_secret for supplied oauth_token in OAuthSimple.setTokensAndSecrets');
2138ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                }
2148ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            return this;
2158ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        };
2168ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
2178ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        /** set the signature method (currently only Plaintext or SHA-MAC1)
2188ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen         *
2198ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen         * @param method {string} Method of signing the transaction (only PLAINTEXT and SHA-MAC1 allowed for now)
2208ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen         */
2218ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        this.setSignatureMethod = function(method) {
2228ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            if (method === undefined) {
2238ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                method = this._default_signature_method;
2248ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                }
2258ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            //TODO: accept things other than PlainText or SHA-MAC1
2268ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            if (method.toUpperCase().match(/(PLAINTEXT|HMAC-SHA1)/) === undefined) {
2278ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                throw ('Unknown signing method specified for OAuthSimple.setSignatureMethod');
2288ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                }
2298ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            this._parameters['oauth_signature_method']= method.toUpperCase();
2308ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            return this;
2318ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        };
2328ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
2338ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        /** sign the request
2348ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen         *
2358ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen         * note: all arguments are optional, provided you've set them using the
2368ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen         * other helper functions.
2378ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen         *
2388ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen         * @param args {object} hash of arguments for the call
2398ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen         *                   {action:, path:, parameters:, method:, signatures:}
2408ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen         *                   all arguments are optional.
2418ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen         */
2428ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        this.sign = function (args) {
2438ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            if (args === undefined) {
2448ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                args = {};
2458ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                }
2468ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            // Set any given parameters
2478ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            if(args['action'] !== undefined) {
2488ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                this.setAction(args['action']);
2498ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                }
2508ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            if (args['path'] !== undefined) {
2518ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                this.setPath(args['path']);
2528ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                }
2538ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            if (args['method'] !== undefined) {
2548ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                this.setSignatureMethod(args['method']);
2558ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                }
2568ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            this.setTokensAndSecrets(args['signatures']);
2578ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            if (args['parameters'] !== undefined){
2588ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            this.setParameters(args['parameters']);
2598ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            }
2608ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            // check the parameters
2618ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            var normParams = this._normalizedParameters();
2628ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            this._parameters['oauth_signature']=this._generateSignature(normParams);
2638ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            return {
2648ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                parameters: this._parameters,
2658ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                signature: this._oauthEscape(this._parameters['oauth_signature']),
2668ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                signed_url: this._path + '?' + this._normalizedParameters(),
2678ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                header: this.getHeaderString()
2688ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            };
2698ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        };
2708ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
2718ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        /** Return a formatted "header" string
2728ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen         *
2738ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen         * NOTE: This doesn't set the "Authorization: " prefix, which is required.
2748ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen         * I don't set it because various set header functions prefer different
2758ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen         * ways to do that.
2768ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen         *
2778ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen         * @param args {object} see .sign
2788ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen         */
2798ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        this.getHeaderString = function(args) {
2808ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            if (this._parameters['oauth_signature'] === undefined) {
2818ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                this.sign(args);
2828ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                }
2838ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
2848ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            var result = 'OAuth ';
2858ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            for (var pName in this._parameters)
2868ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            {
2878ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                if (!pName.match(/^oauth/)) {
2888ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                    continue;
2898ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                    }
2908ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                if ((this._parameters[pName]) instanceof Array)
2918ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                {
2928ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                    var pLength = this._parameters[pName].length;
2938ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                    for (var j=0;j<pLength;j++)
2948ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                    {
2958ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                        result += pName +'="'+this._oauthEscape(this._parameters[pName][j])+'" ';
2968ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                    }
2978ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                }
2988ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                else
2998ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                {
3008ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                    result += pName + '="'+this._oauthEscape(this._parameters[pName])+'" ';
3018ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                }
3028ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            }
3038ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            return result;
3048ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        };
3058ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
3068ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        // Start Private Methods.
3078ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
3088ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        /** convert the parameter string into a hash of objects.
3098ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen         *
3108ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen         */
3118ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        this._parseParameterString = function(paramString){
3128ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            var elements = paramString.split('&');
3138ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            var result={};
3148ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            for(var element=elements.shift();element;element=elements.shift())
3158ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            {
3168ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                var keyToken=element.split('=');
3178ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                var value='';
3188ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                if (keyToken[1]) {
3198ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                    value=decodeURIComponent(keyToken[1]);
3208ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                    }
3218ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                if(result[keyToken[0]]){
3228ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                    if (!(result[keyToken[0]] instanceof Array))
3238ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                    {
3248ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                        result[keyToken[0]] = Array(result[keyToken[0]],value);
3258ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                    }
3268ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                    else
3278ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                    {
3288ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                        result[keyToken[0]].push(value);
3298ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                    }
3308ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                }
3318ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                else
3328ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                {
3338ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                    result[keyToken[0]]=value;
3348ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                }
3358ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            }
3368ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            return result;
3378ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        };
3388ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
3398ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        this._oauthEscape = function(string) {
3408ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            if (string === undefined) {
3418ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                return "";
3428ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                }
3438ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            if (string instanceof Array)
3448ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            {
3458ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                throw('Array passed to _oauthEscape');
3468ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            }
3478ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            return encodeURIComponent(string).replace(/\!/g, "%21").
3488ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            replace(/\*/g, "%2A").
3498ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            replace(/'/g, "%27").
3508ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            replace(/\(/g, "%28").
3518ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            replace(/\)/g, "%29");
3528ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        };
3538ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
3548ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        this._getNonce = function (length) {
3558ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            if (length === undefined) {
3568ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                length=5;
3578ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                }
3588ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            var result = "";
3598ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            var cLength = this._nonce_chars.length;
3608ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            for (var i = 0; i < length;i++) {
3618ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                var rnum = Math.floor(Math.random() *cLength);
3628ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                result += this._nonce_chars.substring(rnum,rnum+1);
3638ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            }
3648ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            this._parameters['oauth_nonce']=result;
3658ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            return result;
3668ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        };
3678ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
3688ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        this._getApiKey = function() {
3698ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            if (this._secrets.consumer_key === undefined) {
3708ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                throw('No consumer_key set for OAuthSimple.');
3718ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                }
3728ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            this._parameters['oauth_consumer_key']=this._secrets.consumer_key;
3738ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            return this._parameters.oauth_consumer_key;
3748ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        };
3758ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
3768ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        this._getAccessToken = function() {
3778ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            if (this._secrets['oauth_secret'] === undefined) {
3788ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                return '';
3798ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                }
3808ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            if (this._secrets['oauth_token'] === undefined) {
3818ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                throw('No oauth_token (access_token) set for OAuthSimple.');
3828ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                }
3838ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            this._parameters['oauth_token'] = this._secrets.oauth_token;
3848ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            return this._parameters.oauth_token;
3858ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        };
3868ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
3878ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        this._getTimestamp = function() {
3888ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            var d = new Date();
3898ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            var ts = Math.floor(d.getTime()/1000);
3908ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            this._parameters['oauth_timestamp'] = ts;
3918ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            return ts;
3928ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        };
3938ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
3948ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        this.b64_hmac_sha1 = function(k,d,_p,_z){
3958ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        // heavily optimized and compressed version of http://pajhome.org.uk/crypt/md5/sha1.js
3968ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        // _p = b64pad, _z = character size; not used here but I left them available just in case
3978ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        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);
3988ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        }
3998ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
4008ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
4018ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        this._normalizedParameters = function() {
4028ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            var elements = new Array();
4038ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            var paramNames = [];
4048ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            var ra =0;
4058ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            for (var paramName in this._parameters)
4068ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            {
4078ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                if (ra++ > 1000) {
4088ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                    throw('runaway 1');
4098ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                    }
4108ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                paramNames.unshift(paramName);
4118ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            }
4128ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            paramNames = paramNames.sort();
4138ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            pLen = paramNames.length;
4148ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            for (var i=0;i<pLen; i++)
4158ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            {
4168ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                paramName=paramNames[i];
4178ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                //skip secrets.
4188ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                if (paramName.match(/\w+_secret/)) {
4198ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                    continue;
4208ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                    }
4218ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                if (this._parameters[paramName] instanceof Array)
4228ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                {
4238ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                    var sorted = this._parameters[paramName].sort();
4248ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                    var spLen = sorted.length;
4258ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                    for (var j = 0;j<spLen;j++){
4268ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                        if (ra++ > 1000) {
4278ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                            throw('runaway 1');
4288ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                            }
4298ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                        elements.push(this._oauthEscape(paramName) + '=' +
4308ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                                  this._oauthEscape(sorted[j]));
4318ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                    }
4328ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                    continue;
4338ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                }
4348ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                elements.push(this._oauthEscape(paramName) + '=' +
4358ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                              this._oauthEscape(this._parameters[paramName]));
4368ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            }
4378ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            return elements.join('&');
4388ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        };
4398ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
4408ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        this._generateSignature = function() {
4418ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
4428ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            var secretKey = this._oauthEscape(this._secrets.shared_secret)+'&'+
4438ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                this._oauthEscape(this._secrets.oauth_secret);
4448ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            if (this._parameters['oauth_signature_method'] == 'PLAINTEXT')
4458ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            {
4468ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                return secretKey;
4478ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            }
4488ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            if (this._parameters['oauth_signature_method'] == 'HMAC-SHA1')
4498ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            {
4508ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                var sigString = this._oauthEscape(this._action)+'&'+this._oauthEscape(this._path)+'&'+this._oauthEscape(this._normalizedParameters());
4518ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen                return this.b64_hmac_sha1(secretKey,sigString);
4528ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            }
4538ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen            return null;
4548ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen        };
4558ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen
4568ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    return this;
4578ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen    };
4588ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen}
459