Centralizes AuthData validation

This commit is contained in:
Florent Vilmart
2016-03-10 09:41:56 -05:00
parent 9aaaf78a36
commit 54d154f7aa
6 changed files with 103 additions and 78 deletions

View File

@@ -148,7 +148,8 @@ describe('rest create', () => {
});
it('handles no anonymous users config', (done) => {
var NoAnnonConfig = Object.assign({}, config, {enableAnonymousUsers: false});
var NoAnnonConfig = Object.assign({}, config);
NoAnnonConfig.oauth.setEnableAnonymousUsers(false);
var data1 = {
authData: {
anonymous: {

View File

@@ -7,6 +7,7 @@ var DatabaseAdapter = require('../src/DatabaseAdapter');
var express = require('express');
var facebook = require('../src/oauth/facebook');
var ParseServer = require('../src/index').ParseServer;
var path = require('path');
var databaseURI = process.env.DATABASE_URI;
var cloudMain = process.env.CLOUD_CODE_MAIN || '../spec/cloud/main.js';
@@ -36,7 +37,7 @@ var defaultConfiguration = {
oauth: { // Override the facebook provider
facebook: mockFacebook(),
myoauth: {
module: "../spec/myoauth" // relative path as it's run from src
module: path.resolve(__dirname, "myoauth") // relative path as it's run from src
}
}
};

View File

@@ -20,7 +20,6 @@ export class Config {
this.restAPIKey = cacheInfo.restAPIKey;
this.fileKey = cacheInfo.fileKey;
this.facebookAppIds = cacheInfo.facebookAppIds;
this.enableAnonymousUsers = cacheInfo.enableAnonymousUsers;
this.allowClientClassCreation = cacheInfo.allowClientClassCreation;
this.database = DatabaseAdapter.getDatabaseConnection(applicationId, cacheInfo.collectionPrefix);

View File

@@ -9,7 +9,6 @@ var Auth = require('./Auth');
var Config = require('./Config');
var cryptoUtils = require('./cryptoUtils');
var passwordCrypto = require('./password');
var oauth = require("./oauth");
var Parse = require('parse/node');
var triggers = require('./triggers');
@@ -213,13 +212,7 @@ RestWrite.prototype.validateAuthData = function() {
var authData = this.data.authData;
var providers = Object.keys(authData);
if (providers.length == 1) {
var provider = providers[0];
if (provider == 'anonymous' && !this.config.enableAnonymousUsers) {
throw new Parse.Error(Parse.Error.UNSUPPORTED_SERVICE,
'This authentication method is unsupported.');
}
var providerAuthData = authData[provider];
var hasToken = (providerAuthData && providerAuthData.id);
if (providerAuthData === null || hasToken) {
@@ -238,52 +231,15 @@ RestWrite.prototype.handleOAuthAuthData = function(provider) {
return;
}
var appIds;
var oauthOptions = this.config.oauth[provider];
if (oauthOptions) {
appIds = oauthOptions.appIds;
} else if (provider == "facebook") {
appIds = this.config.facebookAppIds;
}
let validateAuthData = this.config.oauth.getValidatorForProvider(provider);
var validateAuthData;
var validateAppId;
if (oauth[provider]) {
validateAuthData = oauth[provider].validateAuthData;
validateAppId = oauth[provider].validateAppId;
}
// Try the configuration methods
if (oauthOptions) {
if (oauthOptions.module) {
validateAuthData = require(oauthOptions.module).validateAuthData;
validateAppId = require(oauthOptions.module).validateAppId;
if (!validateAuthData) {
throw new Parse.Error(Parse.Error.UNSUPPORTED_SERVICE,
'This authentication method is unsupported.');
};
if (oauthOptions.validateAuthData) {
validateAuthData = oauthOptions.validateAuthData;
}
if (oauthOptions.validateAppId) {
validateAppId = oauthOptions.validateAppId;
}
}
// try the custom provider first, fallback on the oauth implementation
if (!validateAuthData || !validateAppId) {
return false;
};
return validateAuthData(authData, oauthOptions)
return validateAuthData(authData)
.then(() => {
if (appIds && typeof validateAppId === "function") {
return validateAppId(appIds, authData, oauthOptions);
}
// No validation required by the developer
return Promise.resolve();
}).then(() => {
// Check if this user already exists
// TODO: does this handle re-linking correctly?
var query = {};
@@ -314,7 +270,6 @@ RestWrite.prototype.handleOAuthAuthData = function(provider) {
// are different
if (results[0].objectId !== this.query.objectId) {
delete this.data["_auth_data_" + provider ];
console.log("alerady linked!");
throw new Parse.Error(Parse.Error.ACCOUNT_ALREADY_LINKED,
'this auth is already used');
}

View File

@@ -8,7 +8,8 @@ var batch = require('./batch'),
express = require('express'),
middlewares = require('./middlewares'),
multer = require('multer'),
Parse = require('parse/node').Parse;
Parse = require('parse/node').Parse,
oauthManager = require('./oauth');
//import passwordReset from './passwordReset';
import cache from './cache';
@@ -163,9 +164,8 @@ function ParseServer({
hooksController: hooksController,
userController: userController,
verifyUserEmails: verifyUserEmails,
enableAnonymousUsers: enableAnonymousUsers,
allowClientClassCreation: allowClientClassCreation,
oauth: oauth,
oauth: oauthManager(oauth, enableAnonymousUsers),
appName: appName,
publicServerURL: publicServerURL,
customPages: customPages,

View File

@@ -1,25 +1,94 @@
var facebook = require('./facebook');
var instagram = require("./instagram");
var linkedin = require("./linkedin");
var meetup = require("./meetup");
var google = require("./google");
var github = require("./github");
var twitter = require("./twitter");
let facebook = require('./facebook');
let instagram = require("./instagram");
let linkedin = require("./linkedin");
let meetup = require("./meetup");
let google = require("./google");
let github = require("./github");
let twitter = require("./twitter");
module.exports = {
facebook: facebook,
github: github,
google: google,
instagram: instagram,
linkedin: linkedin,
meetup: meetup,
twitter: twitter,
anonymous: {
validateAuthData: function() {
let anonymous = {
validateAuthData: () => {
return Promise.resolve();
},
validateAppId: function() {
validateAppId: () => {
return Promise.resolve();
}
}
let providers = {
facebook,
instagram,
linkedin,
meetup,
google,
github,
twitter,
anonymous
}
module.exports = function(oauthOptions = {}, enableAnonymousUsers = true) {
let _enableAnonymousUsers = enableAnonymousUsers;
let setEnableAnonymousUsers = function(enable) {
_enableAnonymousUsers = enable;
}
// To handle the test cases on configuration
let getValidatorForProvider = function(provider) {
if (provider === 'anonymous' && !_enableAnonymousUsers) {
return;
}
let defaultProvider = providers[provider];
let optionalProvider = oauthOptions[provider];
if (!defaultProvider && !optionalProvider) {
return;
}
let appIds;
if (optionalProvider) {
appIds = optionalProvider.appIds;
}
var validateAuthData;
var validateAppId;
if (defaultProvider) {
validateAuthData = defaultProvider.validateAuthData;
validateAppId = defaultProvider.validateAppId;
}
// Try the configuration methods
if (optionalProvider) {
if (optionalProvider.module) {
validateAuthData = require(optionalProvider.module).validateAuthData;
validateAppId = require(optionalProvider.module).validateAppId;
};
if (optionalProvider.validateAuthData) {
validateAuthData = optionalProvider.validateAuthData;
}
if (optionalProvider.validateAppId) {
validateAppId = optionalProvider.validateAppId;
}
}
if (!validateAuthData || !validateAppId) {
return;
}
return function(authData) {
return validateAuthData(authData, optionalProvider).then(() => {
if (appIds) {
return validateAppId(appIds, authData, optionalProvider);
}
return Promise.resolve();
})
}
}
return Object.freeze({
getValidatorForProvider,
setEnableAnonymousUsers,
})
}