Skip to content
This repository was archived by the owner on Jun 11, 2025. It is now read-only.

Commit 5b7877b

Browse files
author
Eric Koleda
authored
Merge pull request #41 from gsuitedevs/rsasha1
Add support for RSA-SHA1 signatures
2 parents 4f213f0 + 27ba853 commit 5b7877b

File tree

4 files changed

+90
-2
lines changed

4 files changed

+90
-2
lines changed

README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,34 @@ differences in how they implement the standard it may be that some APIs
157157
aren't compatible. If you find an API that it does't work with, open an issue or
158158
fix the problem yourself and make a pull request against the source code.
159159

160+
### 3-legged OAuth
161+
162+
This library was primarily designed to support the
163+
[3-legged OAuth flow](http://oauthbible.com/#oauth-10a-three-legged), where
164+
the end-user visits a web page to grant authorization to your application. The
165+
"Usage" section above describes how to configure the library for this flow.
166+
167+
### 2-legged OAuth
168+
169+
This library does not currently support the
170+
[2-legged OAuth flow](http://oauthbible.com/#oauth-10a-two-legged), where
171+
tokens are generated but the user is not prompted to authorize access.
172+
173+
Be aware that many OAuth providers incorrectly use the term "2-legged" when
174+
describing their OAuth flow, when in reality they are using the 1-legged flow,
175+
which this library does support.
176+
177+
### 1-legged OAuth
178+
179+
This library supports the
180+
[1-legged OAuth flow](http://oauthbible.com/#oauth-10a-one-legged), where the
181+
consumer key and secret are simply used to sign requests to the API endpoints,
182+
without the creation or exchanging of tokens. To use this flow, setup the
183+
service with a consumer key and secret (and optionally a token and token secret)
184+
and use it to call the API endpoint. See the
185+
[Semantics3 sample](samples/Semantics3.gs) and [Yelp sample](samples/Yelp.gs)
186+
for some example usage.
187+
160188
## Other features
161189

162190
#### Resetting the access token

samples/XeroPrivate.gs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/**
2+
* This sample that demonstrates how to configured the library for the Xero API,
3+
* when using a private application. Although the Xero documentation calls it a
4+
* "2 legged" flow it is really a 1-legged flow. Public Xero applications use
5+
* a 3-legged flow not shown here.
6+
* @see {@link https://developer.xero.com/documentation/auth-and-limits/private-applications}
7+
*/
8+
9+
var CONSUMER_KEY = '...';
10+
// The private key must be in the PKCS#8 PEM format.
11+
var PRIVATE_KEY = '-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n';
12+
13+
/**
14+
* Authorizes and makes a request to the Xero API.
15+
*/
16+
function run() {
17+
var service = getService();
18+
var url = 'https://api.xero.com/api.xro/2.0/Organisations';
19+
var response = service.fetch(url, {
20+
headers: {
21+
Accept: 'application/json'
22+
}
23+
});
24+
var result = JSON.parse(response.getContentText());
25+
Logger.log(JSON.stringify(result, null, 2));
26+
}
27+
28+
/**
29+
* Reset the authorization state, so that it can be re-tested.
30+
*/
31+
function reset() {
32+
getService().reset();
33+
}
34+
35+
/**
36+
* Configures the service.
37+
*/
38+
function getService() {
39+
return OAuth1.createService('Xero')
40+
// Set the consumer key and secret.
41+
.setConsumerKey(CONSUMER_KEY)
42+
.setConsumerSecret(PRIVATE_KEY)
43+
44+
// Manually set the token to be the consumer key.
45+
.setAccessToken(CONSUMER_KEY)
46+
47+
// Set the OAuth signature method.
48+
.setSignatureMethod('RSA-SHA1');
49+
}

src/Service.gs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ Service_.prototype.setMethod = function(method) {
104104
/**
105105
* Sets the OAuth signature method to use. 'HMAC-SHA1' is the default.
106106
* @param {string} signatureMethod The OAuth signature method. Allowed values
107-
* are 'HMAC-SHA1' and 'PLAINTEXT'.
107+
* are 'HMAC-SHA1', 'RSA-SHA1' and 'PLAINTEXT'.
108108
* @return {Service_} This service, for chaining.
109109
*/
110110
Service_.prototype.setSignatureMethod = function(signatureMethod) {

src/Signer.gs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,11 @@
6969
};
7070
break;
7171
case 'RSA-SHA1':
72-
throw new Error('oauth-1.0a does not support this signature method right now. Coming Soon...');
72+
this.hash = function(base_string, key) {
73+
var sig = Utilities.computeRsaSignature(Utilities.RsaAlgorithm.RSA_SHA_1, base_string, key);
74+
return Utilities.base64Encode(sig);
75+
}
76+
break;
7377
default:
7478
throw new Error('The OAuth 1.0a protocol defines three signature methods: HMAC-SHA1, RSA-SHA1, and PLAINTEXT only');
7579
}
@@ -170,6 +174,13 @@
170174
OAuth.prototype.getSigningKey = function(token_secret) {
171175
token_secret = token_secret || '';
172176

177+
// Don't percent encode the signing key (PKCS#8 PEM private key) when using
178+
// the RSA-SHA1 method. The token secret is never used with the RSA-SHA1
179+
// method.
180+
if (this.signature_method === 'RSA-SHA1') {
181+
return this.consumer.secret;
182+
}
183+
173184
if(!this.last_ampersand && !token_secret) {
174185
return this.percentEncode(this.consumer.secret);
175186
}

0 commit comments

Comments
 (0)