Skip to content

Commit c1dcaf1

Browse files
flovilmartArthur Cinader
authored andcommitted
Auth Adapters refactoring (#3177)
* Moves all authentication providers to Adapter/Auth * refactors specs * Deprecates oauth option in favor of auth option - Deprecates facebookAppIds option (in favor of auth.facebook.appIds) - Adds warnings about the deprecated options * nits
1 parent a906726 commit c1dcaf1

28 files changed

+407
-267
lines changed

spec/OAuth.spec.js renamed to spec/AuthenticationAdapters.spec.js

Lines changed: 90 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -1,145 +1,13 @@
1-
var OAuth = require("../src/authDataManager/OAuth1Client");
21
var request = require('request');
32
var Config = require("../src/Config");
43
var defaultColumns = require('../src/Controllers/SchemaController').defaultColumns;
4+
var authenticationLoader = require('../src/Adapters/Auth');
5+
var path = require('path');
56

6-
describe('OAuth', function() {
7-
it("Nonce should have right length", (done) => {
8-
jequal(OAuth.nonce().length, 30);
9-
done();
10-
});
11-
12-
it("Should properly build parameter string", (done) => {
13-
var string = OAuth.buildParameterString({c:1, a:2, b:3})
14-
jequal(string, "a=2&b=3&c=1");
15-
done();
16-
});
17-
18-
it("Should properly build empty parameter string", (done) => {
19-
var string = OAuth.buildParameterString()
20-
jequal(string, "");
21-
done();
22-
});
23-
24-
it("Should properly build signature string", (done) => {
25-
var string = OAuth.buildSignatureString("get", "http://dummy.com", "");
26-
jequal(string, "GET&http%3A%2F%2Fdummy.com&");
27-
done();
28-
});
29-
30-
it("Should properly generate request signature", (done) => {
31-
var request = {
32-
host: "dummy.com",
33-
path: "path"
34-
};
35-
36-
var oauth_params = {
37-
oauth_timestamp: 123450000,
38-
oauth_nonce: "AAAAAAAAAAAAAAAAA",
39-
oauth_consumer_key: "hello",
40-
oauth_token: "token"
41-
};
42-
43-
var consumer_secret = "world";
44-
var auth_token_secret = "secret";
45-
request = OAuth.signRequest(request, oauth_params, consumer_secret, auth_token_secret);
46-
jequal(request.headers['Authorization'], 'OAuth oauth_consumer_key="hello", oauth_nonce="AAAAAAAAAAAAAAAAA", oauth_signature="8K95bpQcDi9Nd2GkhumTVcw4%2BXw%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="123450000", oauth_token="token", oauth_version="1.0"');
47-
done();
48-
});
49-
50-
it("Should properly build request", (done) => {
51-
var options = {
52-
host: "dummy.com",
53-
consumer_key: "hello",
54-
consumer_secret: "world",
55-
auth_token: "token",
56-
auth_token_secret: "secret",
57-
// Custom oauth params for tests
58-
oauth_params: {
59-
oauth_timestamp: 123450000,
60-
oauth_nonce: "AAAAAAAAAAAAAAAAA"
61-
}
62-
};
63-
var path = "path";
64-
var method = "get";
65-
66-
var oauthClient = new OAuth(options);
67-
var req = oauthClient.buildRequest(method, path, {"query": "param"});
68-
69-
jequal(req.host, options.host);
70-
jequal(req.path, "/"+path+"?query=param");
71-
jequal(req.method, "GET");
72-
jequal(req.headers['Content-Type'], 'application/x-www-form-urlencoded');
73-
jequal(req.headers['Authorization'], 'OAuth oauth_consumer_key="hello", oauth_nonce="AAAAAAAAAAAAAAAAA", oauth_signature="wNkyEkDE%2F0JZ2idmqyrgHdvC0rs%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="123450000", oauth_token="token", oauth_version="1.0"')
74-
done();
75-
});
76-
77-
78-
function validateCannotAuthenticateError(data, done) {
79-
jequal(typeof data, "object");
80-
jequal(typeof data.errors, "object");
81-
var errors = data.errors;
82-
jequal(typeof errors[0], "object");
83-
// Cannot authenticate error
84-
jequal(errors[0].code, 32);
85-
done();
86-
}
87-
88-
it("Should fail a GET request", (done) => {
89-
var options = {
90-
host: "api.twitter.com",
91-
consumer_key: "XXXXXXXXXXXXXXXXXXXXXXXXX",
92-
consumer_secret: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
93-
};
94-
var path = "/1.1/help/configuration.json";
95-
var params = {"lang": "en"};
96-
var oauthClient = new OAuth(options);
97-
oauthClient.get(path, params).then(function(data){
98-
validateCannotAuthenticateError(data, done);
99-
})
100-
});
101-
102-
it("Should fail a POST request", (done) => {
103-
var options = {
104-
host: "api.twitter.com",
105-
consumer_key: "XXXXXXXXXXXXXXXXXXXXXXXXX",
106-
consumer_secret: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
107-
};
108-
var body = {
109-
lang: "en"
110-
};
111-
var path = "/1.1/account/settings.json";
112-
113-
var oauthClient = new OAuth(options);
114-
oauthClient.post(path, null, body).then(function(data){
115-
validateCannotAuthenticateError(data, done);
116-
})
117-
});
118-
119-
it("Should fail a request", (done) => {
120-
var options = {
121-
host: "localhost",
122-
consumer_key: "XXXXXXXXXXXXXXXXXXXXXXXXX",
123-
consumer_secret: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
124-
};
125-
var body = {
126-
lang: "en"
127-
};
128-
var path = "/";
129-
130-
var oauthClient = new OAuth(options);
131-
oauthClient.post(path, null, body).then(function(){
132-
jequal(false, true);
133-
done();
134-
}).catch(function(){
135-
jequal(true, true);
136-
done();
137-
})
138-
});
139-
7+
describe('AuthenticationProviers', function() {
1408
["facebook", "github", "instagram", "google", "linkedin", "meetup", "twitter", "janrainengage", "janraincapture", "vkontakte"].map(function(providerName){
1419
it("Should validate structure of "+providerName, (done) => {
142-
var provider = require("../src/authDataManager/"+providerName);
10+
var provider = require("../src/Adapters/Auth/"+providerName);
14311
jequal(typeof provider.validateAuthData, "function");
14412
jequal(typeof provider.validateAppId, "function");
14513
jequal(provider.validateAuthData({}, {}).constructor, Promise.prototype.constructor);
@@ -325,5 +193,90 @@ describe('OAuth', function() {
325193
});
326194
});
327195

196+
function validateValidator(validator) {
197+
expect(typeof validator).toBe('function');
198+
}
199+
200+
function validateAuthenticationHandler(authenticatonHandler) {
201+
expect(authenticatonHandler).not.toBeUndefined();
202+
expect(typeof authenticatonHandler.getValidatorForProvider).toBe('function');
203+
expect(typeof authenticatonHandler.getValidatorForProvider).toBe('function');
204+
}
205+
206+
it('properly loads custom adapter', (done) => {
207+
var validAuthData = {
208+
id: 'hello',
209+
token: 'world'
210+
}
211+
let adapter = {
212+
validateAppId: function() {
213+
return Promise.resolve();
214+
},
215+
validateAuthData: function(authData) {
216+
if (authData.id == validAuthData.id && authData.token == validAuthData.token) {
217+
return Promise.resolve();
218+
}
219+
return Promise.reject();
220+
}
221+
};
328222

329-
})
223+
let authDataSpy = spyOn(adapter, 'validateAuthData').and.callThrough();
224+
let appIdSpy = spyOn(adapter, 'validateAppId').and.callThrough();
225+
226+
let authenticationHandler = authenticationLoader({
227+
customAuthentication: adapter
228+
});
229+
230+
validateAuthenticationHandler(authenticationHandler);
231+
let validator = authenticationHandler.getValidatorForProvider('customAuthentication');
232+
validateValidator(validator);
233+
234+
validator(validAuthData).then(() => {
235+
expect(authDataSpy).toHaveBeenCalled();
236+
// AppIds are not provided in the adapter, should not be called
237+
expect(appIdSpy).not.toHaveBeenCalled();
238+
done();
239+
}, (err) => {
240+
jfail(err);
241+
done();
242+
})
243+
});
244+
245+
it('properly loads custom adapter module object', (done) => {
246+
let authenticationHandler = authenticationLoader({
247+
customAuthentication: path.resolve('./spec/support/CustomAuth.js')
248+
});
249+
250+
validateAuthenticationHandler(authenticationHandler);
251+
let validator = authenticationHandler.getValidatorForProvider('customAuthentication');
252+
validateValidator(validator);
253+
254+
validator({
255+
token: 'my-token'
256+
}).then(() => {
257+
done();
258+
}, (err) => {
259+
jfail(err);
260+
done();
261+
})
262+
});
263+
264+
it('properly loads custom adapter module object', (done) => {
265+
let authenticationHandler = authenticationLoader({
266+
customAuthentication: { module: path.resolve('./spec/support/CustomAuthFunction.js'), options: { token: 'valid-token' }}
267+
});
268+
269+
validateAuthenticationHandler(authenticationHandler);
270+
let validator = authenticationHandler.getValidatorForProvider('customAuthentication');
271+
validateValidator(validator);
272+
273+
validator({
274+
token: 'valid-token'
275+
}).then(() => {
276+
done();
277+
}, (err) => {
278+
jfail(err);
279+
done();
280+
})
281+
});
282+
});

spec/OAuth1.spec.js

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
var OAuth = require("../src/Adapters/Auth/OAuth1Client");
2+
3+
describe('OAuth', function() {
4+
it("Nonce should have right length", (done) => {
5+
jequal(OAuth.nonce().length, 30);
6+
done();
7+
});
8+
9+
it("Should properly build parameter string", (done) => {
10+
var string = OAuth.buildParameterString({c:1, a:2, b:3})
11+
jequal(string, "a=2&b=3&c=1");
12+
done();
13+
});
14+
15+
it("Should properly build empty parameter string", (done) => {
16+
var string = OAuth.buildParameterString()
17+
jequal(string, "");
18+
done();
19+
});
20+
21+
it("Should properly build signature string", (done) => {
22+
var string = OAuth.buildSignatureString("get", "http://dummy.com", "");
23+
jequal(string, "GET&http%3A%2F%2Fdummy.com&");
24+
done();
25+
});
26+
27+
it("Should properly generate request signature", (done) => {
28+
var request = {
29+
host: "dummy.com",
30+
path: "path"
31+
};
32+
33+
var oauth_params = {
34+
oauth_timestamp: 123450000,
35+
oauth_nonce: "AAAAAAAAAAAAAAAAA",
36+
oauth_consumer_key: "hello",
37+
oauth_token: "token"
38+
};
39+
40+
var consumer_secret = "world";
41+
var auth_token_secret = "secret";
42+
request = OAuth.signRequest(request, oauth_params, consumer_secret, auth_token_secret);
43+
jequal(request.headers['Authorization'], 'OAuth oauth_consumer_key="hello", oauth_nonce="AAAAAAAAAAAAAAAAA", oauth_signature="8K95bpQcDi9Nd2GkhumTVcw4%2BXw%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="123450000", oauth_token="token", oauth_version="1.0"');
44+
done();
45+
});
46+
47+
it("Should properly build request", (done) => {
48+
var options = {
49+
host: "dummy.com",
50+
consumer_key: "hello",
51+
consumer_secret: "world",
52+
auth_token: "token",
53+
auth_token_secret: "secret",
54+
// Custom oauth params for tests
55+
oauth_params: {
56+
oauth_timestamp: 123450000,
57+
oauth_nonce: "AAAAAAAAAAAAAAAAA"
58+
}
59+
};
60+
var path = "path";
61+
var method = "get";
62+
63+
var oauthClient = new OAuth(options);
64+
var req = oauthClient.buildRequest(method, path, {"query": "param"});
65+
66+
jequal(req.host, options.host);
67+
jequal(req.path, "/"+path+"?query=param");
68+
jequal(req.method, "GET");
69+
jequal(req.headers['Content-Type'], 'application/x-www-form-urlencoded');
70+
jequal(req.headers['Authorization'], 'OAuth oauth_consumer_key="hello", oauth_nonce="AAAAAAAAAAAAAAAAA", oauth_signature="wNkyEkDE%2F0JZ2idmqyrgHdvC0rs%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="123450000", oauth_token="token", oauth_version="1.0"')
71+
done();
72+
});
73+
74+
75+
function validateCannotAuthenticateError(data, done) {
76+
jequal(typeof data, "object");
77+
jequal(typeof data.errors, "object");
78+
var errors = data.errors;
79+
jequal(typeof errors[0], "object");
80+
// Cannot authenticate error
81+
jequal(errors[0].code, 32);
82+
done();
83+
}
84+
85+
it("Should fail a GET request", (done) => {
86+
var options = {
87+
host: "api.twitter.com",
88+
consumer_key: "XXXXXXXXXXXXXXXXXXXXXXXXX",
89+
consumer_secret: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
90+
};
91+
var path = "/1.1/help/configuration.json";
92+
var params = {"lang": "en"};
93+
var oauthClient = new OAuth(options);
94+
oauthClient.get(path, params).then(function(data){
95+
validateCannotAuthenticateError(data, done);
96+
})
97+
});
98+
99+
it("Should fail a POST request", (done) => {
100+
var options = {
101+
host: "api.twitter.com",
102+
consumer_key: "XXXXXXXXXXXXXXXXXXXXXXXXX",
103+
consumer_secret: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
104+
};
105+
var body = {
106+
lang: "en"
107+
};
108+
var path = "/1.1/account/settings.json";
109+
110+
var oauthClient = new OAuth(options);
111+
oauthClient.post(path, null, body).then(function(data){
112+
validateCannotAuthenticateError(data, done);
113+
})
114+
});
115+
116+
it("Should fail a request", (done) => {
117+
var options = {
118+
host: "localhost",
119+
consumer_key: "XXXXXXXXXXXXXXXXXXXXXXXXX",
120+
consumer_secret: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
121+
};
122+
var body = {
123+
lang: "en"
124+
};
125+
var path = "/";
126+
127+
var oauthClient = new OAuth(options);
128+
oauthClient.post(path, null, body).then(function(){
129+
jequal(false, true);
130+
done();
131+
}).catch(function(){
132+
jequal(true, true);
133+
done();
134+
})
135+
});
136+
});

spec/TwitterAuth.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
let twitter = require('../src/authDataManager/twitter');
1+
let twitter = require('../src/Adapters/Auth/twitter');
22

33
describe('Twitter Auth', () => {
44
it('should use the proper configuration', () => {

spec/helper.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ var defaultConfiguration = {
102102
bundleId: 'bundleId',
103103
}
104104
},
105-
oauth: { // Override the facebook provider
105+
auth: { // Override the facebook provider
106106
facebook: mockFacebook(),
107107
myoauth: {
108108
module: path.resolve(__dirname, "myoauth") // relative path as it's run from src

0 commit comments

Comments
 (0)