Files
kami-parse-server/spec/OAuth.spec.js
Drew ab06055369 Postgres exclude failing tests (#2081)
* reload the right data

More passing postgres tests

Handle schema updates, and $in for non array columns

remove authdata from user and implement ensureUniqueness

Make some tests work, detect existing classes

Throw proper error for unique index violation

fix findOneAndUpdate

Support more types

support more type

Support boolean, fix _rperm/_wperm, add TODO

Support string types and also simplify tests

Move operator flattening into Parse Server and out of mongo adapters

Move authdata transform for create into Parse Server

Move authdata transforms completely in to Parse Server

Fix test setup

inline addSchema

Inject default schema to response from DB adapter

* Mark tests that don't work in Postgres

* Exclude one more test

* Exclude some more failing tests

* Exclude more tests
2016-06-17 12:59:16 -04:00

325 lines
11 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
var OAuth = require("../src/authDataManager/OAuth1Client");
var request = require('request');
var Config = require("../src/Config");
var defaultColumns = require('../src/Controllers/SchemaController').defaultColumns;
describe('OAuth', function() {
it("Nonce should have right length", (done) => {
jequal(OAuth.nonce().length, 30);
done();
});
it("Should properly build parameter string", (done) => {
var string = OAuth.buildParameterString({c:1, a:2, b:3})
jequal(string, "a=2&b=3&c=1");
done();
});
it("Should properly build empty parameter string", (done) => {
var string = OAuth.buildParameterString()
jequal(string, "");
done();
});
it("Should properly build signature string", (done) => {
var string = OAuth.buildSignatureString("get", "http://dummy.com", "");
jequal(string, "GET&http%3A%2F%2Fdummy.com&");
done();
});
it("Should properly generate request signature", (done) => {
var request = {
host: "dummy.com",
path: "path"
};
var oauth_params = {
oauth_timestamp: 123450000,
oauth_nonce: "AAAAAAAAAAAAAAAAA",
oauth_consumer_key: "hello",
oauth_token: "token"
};
var consumer_secret = "world";
var auth_token_secret = "secret";
request = OAuth.signRequest(request, oauth_params, consumer_secret, auth_token_secret);
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"');
done();
});
it("Should properly build request", (done) => {
var options = {
host: "dummy.com",
consumer_key: "hello",
consumer_secret: "world",
auth_token: "token",
auth_token_secret: "secret",
// Custom oauth params for tests
oauth_params: {
oauth_timestamp: 123450000,
oauth_nonce: "AAAAAAAAAAAAAAAAA"
}
};
var path = "path";
var method = "get";
var oauthClient = new OAuth(options);
var req = oauthClient.buildRequest(method, path, {"query": "param"});
jequal(req.host, options.host);
jequal(req.path, "/"+path+"?query=param");
jequal(req.method, "GET");
jequal(req.headers['Content-Type'], 'application/x-www-form-urlencoded');
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"')
done();
});
function validateCannotAuthenticateError(data, done) {
jequal(typeof data, "object");
jequal(typeof data.errors, "object");
var errors = data.errors;
jequal(typeof errors[0], "object");
// Cannot authenticate error
jequal(errors[0].code, 32);
done();
}
it("Should fail a GET request", (done) => {
var options = {
host: "api.twitter.com",
consumer_key: "XXXXXXXXXXXXXXXXXXXXXXXXX",
consumer_secret: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
};
var path = "/1.1/help/configuration.json";
var params = {"lang": "en"};
var oauthClient = new OAuth(options);
oauthClient.get(path, params).then(function(data){
validateCannotAuthenticateError(data, done);
})
});
it("Should fail a POST request", (done) => {
var options = {
host: "api.twitter.com",
consumer_key: "XXXXXXXXXXXXXXXXXXXXXXXXX",
consumer_secret: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
};
var body = {
lang: "en"
};
var path = "/1.1/account/settings.json";
var oauthClient = new OAuth(options);
oauthClient.post(path, null, body).then(function(data){
validateCannotAuthenticateError(data, done);
})
});
it("Should fail a request", (done) => {
var options = {
host: "localhost",
consumer_key: "XXXXXXXXXXXXXXXXXXXXXXXXX",
consumer_secret: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
};
var body = {
lang: "en"
};
var path = "/";
var oauthClient = new OAuth(options);
oauthClient.post(path, null, body).then(function(data){
jequal(false, true);
done();
}).catch(function(){
jequal(true, true);
done();
})
});
["facebook", "github", "instagram", "google", "linkedin", "meetup", "twitter"].map(function(providerName){
it("Should validate structure of "+providerName, (done) => {
var provider = require("../src/authDataManager/"+providerName);
jequal(typeof provider.validateAuthData, "function");
jequal(typeof provider.validateAppId, "function");
jequal(provider.validateAuthData({}, {}).constructor, Promise.prototype.constructor);
jequal(provider.validateAppId("app", "key", {}).constructor, Promise.prototype.constructor);
done();
});
});
var getMockMyOauthProvider = function() {
return {
authData: {
id: "12345",
access_token: "12345",
expiration_date: new Date().toJSON(),
},
shouldError: false,
loggedOut: false,
synchronizedUserId: null,
synchronizedAuthToken: null,
synchronizedExpiration: null,
authenticate: function(options) {
if (this.shouldError) {
options.error(this, "An error occurred");
} else if (this.shouldCancel) {
options.error(this, null);
} else {
options.success(this, this.authData);
}
},
restoreAuthentication: function(authData) {
if (!authData) {
this.synchronizedUserId = null;
this.synchronizedAuthToken = null;
this.synchronizedExpiration = null;
return true;
}
this.synchronizedUserId = authData.id;
this.synchronizedAuthToken = authData.access_token;
this.synchronizedExpiration = authData.expiration_date;
return true;
},
getAuthType: function() {
return "myoauth";
},
deauthenticate: function() {
this.loggedOut = true;
this.restoreAuthentication(null);
}
};
};
var ExtendedUser = Parse.User.extend({
extended: function() {
return true;
}
});
var createOAuthUser = function(callback) {
var jsonBody = {
authData: {
myoauth: getMockMyOauthProvider().authData
}
};
var options = {
headers: {'X-Parse-Application-Id': 'test',
'X-Parse-REST-API-Key': 'rest',
'X-Parse-Installation-Id': 'yolo',
'Content-Type': 'application/json' },
url: 'http://localhost:8378/1/users',
body: JSON.stringify(jsonBody)
};
return request.post(options, callback);
}
it_exclude_dbs(['postgres'])("should create user with REST API", done => {
createOAuthUser((error, response, body) => {
expect(error).toBe(null);
var b = JSON.parse(body);
ok(b.sessionToken);
expect(b.objectId).not.toBeNull();
expect(b.objectId).not.toBeUndefined();
var sessionToken = b.sessionToken;
var q = new Parse.Query("_Session");
q.equalTo('sessionToken', sessionToken);
q.first({useMasterKey: true}).then((res) => {
expect(res.get("installationId")).toEqual('yolo');
done();
}).fail((err) => {
fail('should not fail fetching the session');
done();
})
});
});
it_exclude_dbs(['postgres'])("should only create a single user with REST API", (done) => {
var objectId;
createOAuthUser((error, response, body) => {
expect(error).toBe(null);
var b = JSON.parse(body);
expect(b.objectId).not.toBeNull();
expect(b.objectId).not.toBeUndefined();
objectId = b.objectId;
createOAuthUser((error, response, body) => {
expect(error).toBe(null);
var b = JSON.parse(body);
expect(b.objectId).not.toBeNull();
expect(b.objectId).not.toBeUndefined();
expect(b.objectId).toBe(objectId);
done();
});
});
});
it_exclude_dbs(['postgres'])("unlink and link with custom provider", (done) => {
var provider = getMockMyOauthProvider();
Parse.User._registerAuthenticationProvider(provider);
Parse.User._logInWith("myoauth", {
success: function(model) {
ok(model instanceof Parse.User, "Model should be a Parse.User");
strictEqual(Parse.User.current(), model);
ok(model.extended(), "Should have used the subclass.");
strictEqual(provider.authData.id, provider.synchronizedUserId);
strictEqual(provider.authData.access_token, provider.synchronizedAuthToken);
strictEqual(provider.authData.expiration_date, provider.synchronizedExpiration);
ok(model._isLinked("myoauth"), "User should be linked to myoauth");
model._unlinkFrom("myoauth", {
success: function(model) {
ok(!model._isLinked("myoauth"),
"User should not be linked to myoauth");
ok(!provider.synchronizedUserId, "User id should be cleared");
ok(!provider.synchronizedAuthToken, "Auth token should be cleared");
ok(!provider.synchronizedExpiration,
"Expiration should be cleared");
// make sure the auth data is properly deleted
var config = new Config(Parse.applicationId);
config.database.adapter.find('_User', {
fields: Object.assign({}, defaultColumns._Default, defaultColumns._Installation),
}, { objectId: model.id }, {})
.then(res => {
expect(res.length).toBe(1);
expect(res[0]._auth_data_myoauth).toBeUndefined();
expect(res[0]._auth_data_myoauth).not.toBeNull();
model._linkWith("myoauth", {
success: function(model) {
ok(provider.synchronizedUserId, "User id should have a value");
ok(provider.synchronizedAuthToken,
"Auth token should have a value");
ok(provider.synchronizedExpiration,
"Expiration should have a value");
ok(model._isLinked("myoauth"),
"User should be linked to myoauth");
done();
},
error: function(model, error) {
ok(false, "linking again should succeed");
done();
}
});
});
},
error: function(model, error) {
ok(false, "unlinking should succeed");
done();
}
});
},
error: function(model, error) {
ok(false, "linking should have worked");
done();
}
});
});
})