Centralizes AuthData validation
This commit is contained in:
@@ -148,7 +148,8 @@ describe('rest create', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('handles no anonymous users config', (done) => {
|
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 = {
|
var data1 = {
|
||||||
authData: {
|
authData: {
|
||||||
anonymous: {
|
anonymous: {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ var DatabaseAdapter = require('../src/DatabaseAdapter');
|
|||||||
var express = require('express');
|
var express = require('express');
|
||||||
var facebook = require('../src/oauth/facebook');
|
var facebook = require('../src/oauth/facebook');
|
||||||
var ParseServer = require('../src/index').ParseServer;
|
var ParseServer = require('../src/index').ParseServer;
|
||||||
|
var path = require('path');
|
||||||
|
|
||||||
var databaseURI = process.env.DATABASE_URI;
|
var databaseURI = process.env.DATABASE_URI;
|
||||||
var cloudMain = process.env.CLOUD_CODE_MAIN || '../spec/cloud/main.js';
|
var cloudMain = process.env.CLOUD_CODE_MAIN || '../spec/cloud/main.js';
|
||||||
@@ -36,7 +37,7 @@ var defaultConfiguration = {
|
|||||||
oauth: { // Override the facebook provider
|
oauth: { // Override the facebook provider
|
||||||
facebook: mockFacebook(),
|
facebook: mockFacebook(),
|
||||||
myoauth: {
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ export class Config {
|
|||||||
this.restAPIKey = cacheInfo.restAPIKey;
|
this.restAPIKey = cacheInfo.restAPIKey;
|
||||||
this.fileKey = cacheInfo.fileKey;
|
this.fileKey = cacheInfo.fileKey;
|
||||||
this.facebookAppIds = cacheInfo.facebookAppIds;
|
this.facebookAppIds = cacheInfo.facebookAppIds;
|
||||||
this.enableAnonymousUsers = cacheInfo.enableAnonymousUsers;
|
|
||||||
this.allowClientClassCreation = cacheInfo.allowClientClassCreation;
|
this.allowClientClassCreation = cacheInfo.allowClientClassCreation;
|
||||||
this.database = DatabaseAdapter.getDatabaseConnection(applicationId, cacheInfo.collectionPrefix);
|
this.database = DatabaseAdapter.getDatabaseConnection(applicationId, cacheInfo.collectionPrefix);
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ var Auth = require('./Auth');
|
|||||||
var Config = require('./Config');
|
var Config = require('./Config');
|
||||||
var cryptoUtils = require('./cryptoUtils');
|
var cryptoUtils = require('./cryptoUtils');
|
||||||
var passwordCrypto = require('./password');
|
var passwordCrypto = require('./password');
|
||||||
var oauth = require("./oauth");
|
|
||||||
var Parse = require('parse/node');
|
var Parse = require('parse/node');
|
||||||
var triggers = require('./triggers');
|
var triggers = require('./triggers');
|
||||||
|
|
||||||
@@ -213,13 +212,7 @@ RestWrite.prototype.validateAuthData = function() {
|
|||||||
var authData = this.data.authData;
|
var authData = this.data.authData;
|
||||||
var providers = Object.keys(authData);
|
var providers = Object.keys(authData);
|
||||||
if (providers.length == 1) {
|
if (providers.length == 1) {
|
||||||
|
var provider = providers[0];
|
||||||
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 providerAuthData = authData[provider];
|
||||||
var hasToken = (providerAuthData && providerAuthData.id);
|
var hasToken = (providerAuthData && providerAuthData.id);
|
||||||
if (providerAuthData === null || hasToken) {
|
if (providerAuthData === null || hasToken) {
|
||||||
@@ -238,52 +231,15 @@ RestWrite.prototype.handleOAuthAuthData = function(provider) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var appIds;
|
let validateAuthData = this.config.oauth.getValidatorForProvider(provider);
|
||||||
var oauthOptions = this.config.oauth[provider];
|
|
||||||
if (oauthOptions) {
|
|
||||||
appIds = oauthOptions.appIds;
|
|
||||||
} else if (provider == "facebook") {
|
|
||||||
appIds = this.config.facebookAppIds;
|
|
||||||
}
|
|
||||||
|
|
||||||
var validateAuthData;
|
if (!validateAuthData) {
|
||||||
var validateAppId;
|
throw new Parse.Error(Parse.Error.UNSUPPORTED_SERVICE,
|
||||||
|
'This authentication method is unsupported.');
|
||||||
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 (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(() => {
|
.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
|
// Check if this user already exists
|
||||||
// TODO: does this handle re-linking correctly?
|
// TODO: does this handle re-linking correctly?
|
||||||
var query = {};
|
var query = {};
|
||||||
@@ -314,7 +270,6 @@ RestWrite.prototype.handleOAuthAuthData = function(provider) {
|
|||||||
// are different
|
// are different
|
||||||
if (results[0].objectId !== this.query.objectId) {
|
if (results[0].objectId !== this.query.objectId) {
|
||||||
delete this.data["_auth_data_" + provider ];
|
delete this.data["_auth_data_" + provider ];
|
||||||
console.log("alerady linked!");
|
|
||||||
throw new Parse.Error(Parse.Error.ACCOUNT_ALREADY_LINKED,
|
throw new Parse.Error(Parse.Error.ACCOUNT_ALREADY_LINKED,
|
||||||
'this auth is already used');
|
'this auth is already used');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ var batch = require('./batch'),
|
|||||||
express = require('express'),
|
express = require('express'),
|
||||||
middlewares = require('./middlewares'),
|
middlewares = require('./middlewares'),
|
||||||
multer = require('multer'),
|
multer = require('multer'),
|
||||||
Parse = require('parse/node').Parse;
|
Parse = require('parse/node').Parse,
|
||||||
|
oauthManager = require('./oauth');
|
||||||
|
|
||||||
//import passwordReset from './passwordReset';
|
//import passwordReset from './passwordReset';
|
||||||
import cache from './cache';
|
import cache from './cache';
|
||||||
@@ -163,9 +164,8 @@ function ParseServer({
|
|||||||
hooksController: hooksController,
|
hooksController: hooksController,
|
||||||
userController: userController,
|
userController: userController,
|
||||||
verifyUserEmails: verifyUserEmails,
|
verifyUserEmails: verifyUserEmails,
|
||||||
enableAnonymousUsers: enableAnonymousUsers,
|
|
||||||
allowClientClassCreation: allowClientClassCreation,
|
allowClientClassCreation: allowClientClassCreation,
|
||||||
oauth: oauth,
|
oauth: oauthManager(oauth, enableAnonymousUsers),
|
||||||
appName: appName,
|
appName: appName,
|
||||||
publicServerURL: publicServerURL,
|
publicServerURL: publicServerURL,
|
||||||
customPages: customPages,
|
customPages: customPages,
|
||||||
|
|||||||
@@ -1,25 +1,94 @@
|
|||||||
var facebook = require('./facebook');
|
let facebook = require('./facebook');
|
||||||
var instagram = require("./instagram");
|
let instagram = require("./instagram");
|
||||||
var linkedin = require("./linkedin");
|
let linkedin = require("./linkedin");
|
||||||
var meetup = require("./meetup");
|
let meetup = require("./meetup");
|
||||||
var google = require("./google");
|
let google = require("./google");
|
||||||
var github = require("./github");
|
let github = require("./github");
|
||||||
var twitter = require("./twitter");
|
let twitter = require("./twitter");
|
||||||
|
|
||||||
module.exports = {
|
let anonymous = {
|
||||||
facebook: facebook,
|
validateAuthData: () => {
|
||||||
github: github,
|
return Promise.resolve();
|
||||||
google: google,
|
},
|
||||||
instagram: instagram,
|
validateAppId: () => {
|
||||||
linkedin: linkedin,
|
return Promise.resolve();
|
||||||
meetup: meetup,
|
}
|
||||||
twitter: twitter,
|
}
|
||||||
anonymous: {
|
|
||||||
validateAuthData: function() {
|
let providers = {
|
||||||
return Promise.resolve();
|
facebook,
|
||||||
},
|
instagram,
|
||||||
validateAppId: function() {
|
linkedin,
|
||||||
return Promise.resolve();
|
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,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user