Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: Initialize authentication adapters only once at server start #8464

Open
wants to merge 21 commits into
base: alpha
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 47 additions & 25 deletions spec/AuthenticationAdapters.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ describe('AuthenticationProviders', function () {
expect(typeof authAdapter.validateAppId).toBe('function');
}

it('properly loads custom adapter', done => {
it('properly loads custom adapter', async () => {
const validAuthData = {
id: 'hello',
token: 'world',
Expand All @@ -377,6 +377,9 @@ describe('AuthenticationProviders', function () {
const authDataSpy = spyOn(adapter, 'validateAuthData').and.callThrough();
const appIdSpy = spyOn(adapter, 'validateAppId').and.callThrough();

authenticationLoader.initializeAuthAdapter('customAuthentication', {
customAuthentication: adapter,
});
const authenticationHandler = authenticationLoader({
customAuthentication: adapter,
});
Expand All @@ -385,52 +388,38 @@ describe('AuthenticationProviders', function () {
const { validator } = authenticationHandler.getValidatorForProvider('customAuthentication');
validateValidator(validator);

validator(validAuthData, {}, {}).then(
() => {
expect(authDataSpy).toHaveBeenCalled();
// AppIds are not provided in the adapter, should not be called
expect(appIdSpy).not.toHaveBeenCalled();
done();
},
err => {
jfail(err);
done();
}
);
await validator(validAuthData, {}, {});
expect(authDataSpy).toHaveBeenCalled();

expect(appIdSpy).not.toHaveBeenCalled();
});

it('properly loads custom adapter module object', done => {
const authenticationHandler = authenticationLoader({
it('properly loads custom adapter module object', async () => {
authenticationLoader.initializeAuthAdapter('customAuthentication', {
customAuthentication: path.resolve('./spec/support/CustomAuth.js'),
});
const authenticationHandler = authenticationLoader();

validateAuthenticationHandler(authenticationHandler);
const { validator } = authenticationHandler.getValidatorForProvider('customAuthentication');
validateValidator(validator);
validator(
await validator(
{
token: 'my-token',
},
{},
{}
).then(
() => {
done();
},
err => {
jfail(err);
done();
}
);
});

it('properly loads custom adapter module object (again)', done => {
const authenticationHandler = authenticationLoader({
authenticationLoader.initializeAuthAdapter('customAuthentication', {
customAuthentication: {
module: path.resolve('./spec/support/CustomAuthFunction.js'),
options: { token: 'valid-token' },
},
});
const authenticationHandler = authenticationLoader();

validateAuthenticationHandler(authenticationHandler);
const { validator } = authenticationHandler.getValidatorForProvider('customAuthentication');
Expand Down Expand Up @@ -460,6 +449,7 @@ describe('AuthenticationProviders', function () {
appSecret: 'secret',
},
};
authenticationLoader.initializeAuthAdapter('facebook', options);
const { adapter, appIds, providerOptions } = authenticationLoader.loadAuthAdapter(
'facebook',
options
Expand All @@ -483,6 +473,7 @@ describe('AuthenticationProviders', function () {
const authData = {
access_token: 'badtoken',
};
authenticationLoader.initializeAuthAdapter('facebook', options);
const { adapter, appIds, providerOptions } = authenticationLoader.loadAuthAdapter(
'facebook',
options
Expand All @@ -506,6 +497,7 @@ describe('AuthenticationProviders', function () {
const authData = {
access_token: 'badtoken',
};
authenticationLoader.initializeAuthAdapter('facebook', options);
const { adapter, appIds, providerOptions } = authenticationLoader.loadAuthAdapter(
'facebook',
options
Expand All @@ -528,6 +520,7 @@ describe('AuthenticationProviders', function () {
const authData = {
access_token: 'badtoken',
};
authenticationLoader.initializeAuthAdapter('facebook', options);
const { adapter, appIds, providerOptions } = authenticationLoader.loadAuthAdapter(
'facebook',
options
Expand All @@ -552,6 +545,7 @@ describe('AuthenticationProviders', function () {
id: 'test',
access_token: 'test',
};
authenticationLoader.initializeAuthAdapter('facebook', options);
const { adapter, providerOptions } = authenticationLoader.loadAuthAdapter('facebook', options);
await adapter.validateAuthData(authData, providerOptions);
expect(httpsRequest.get.calls.first().args[0].includes('appsecret_proof')).toBe(true);
Expand Down Expand Up @@ -834,6 +828,7 @@ describe('keycloak auth adapter', () => {
id: 'fakeid',
access_token: 'sometoken',
};
authenticationLoader.initializeAuthAdapter('keycloak', options);
const { adapter, providerOptions } = authenticationLoader.loadAuthAdapter('keycloak', options);
try {
await adapter.validateAuthData(authData, providerOptions);
Expand Down Expand Up @@ -861,6 +856,7 @@ describe('keycloak auth adapter', () => {
id: 'fakeid',
access_token: 'sometoken',
};
authenticationLoader.initializeAuthAdapter('keycloak', options);
const { adapter, providerOptions } = authenticationLoader.loadAuthAdapter('keycloak', options);
try {
await adapter.validateAuthData(authData, providerOptions);
Expand Down Expand Up @@ -888,6 +884,7 @@ describe('keycloak auth adapter', () => {
id: 'fakeid',
access_token: 'sometoken',
};
authenticationLoader.initializeAuthAdapter('keycloak', options);
const { adapter, providerOptions } = authenticationLoader.loadAuthAdapter('keycloak', options);
try {
await adapter.validateAuthData(authData, providerOptions);
Expand All @@ -913,6 +910,7 @@ describe('keycloak auth adapter', () => {
id: 'fakeid',
access_token: 'sometoken',
};
authenticationLoader.initializeAuthAdapter('keycloak', options);
const { adapter, providerOptions } = authenticationLoader.loadAuthAdapter('keycloak', options);
try {
await adapter.validateAuthData(authData, providerOptions);
Expand Down Expand Up @@ -946,6 +944,7 @@ describe('keycloak auth adapter', () => {
roles: ['role1'],
groups: ['group1'],
};
authenticationLoader.initializeAuthAdapter('keycloak', options);
const { adapter, providerOptions } = authenticationLoader.loadAuthAdapter('keycloak', options);
try {
await adapter.validateAuthData(authData, providerOptions);
Expand Down Expand Up @@ -979,6 +978,7 @@ describe('keycloak auth adapter', () => {
roles: ['role1'],
groups: ['group1'],
};
authenticationLoader.initializeAuthAdapter('keycloak', options);
const { adapter, providerOptions } = authenticationLoader.loadAuthAdapter('keycloak', options);
try {
await adapter.validateAuthData(authData, providerOptions);
Expand Down Expand Up @@ -1012,6 +1012,7 @@ describe('keycloak auth adapter', () => {
roles: ['role1'],
groups: ['group1'],
};
authenticationLoader.initializeAuthAdapter('keycloak', options);
const { adapter, providerOptions } = authenticationLoader.loadAuthAdapter('keycloak', options);
await adapter.validateAuthData(authData, providerOptions);
expect(httpsRequest.get).toHaveBeenCalledWith({
Expand All @@ -1034,6 +1035,7 @@ describe('oauth2 auth adapter', () => {
oauth2: true,
},
};
authenticationLoader.initializeAuthAdapter('oauth2Authentication', options);
const loadedAuthAdapter = authenticationLoader.loadAuthAdapter('oauth2Authentication', options);
expect(loadedAuthAdapter.adapter).toEqual(oauth2);
});
Expand All @@ -1050,6 +1052,7 @@ describe('oauth2 auth adapter', () => {
debug: true,
},
};
authenticationLoader.initializeAuthAdapter('oauth2Authentication', options);
const loadedAuthAdapter = authenticationLoader.loadAuthAdapter('oauth2Authentication', options);
const appIds = loadedAuthAdapter.appIds;
const providerOptions = loadedAuthAdapter.providerOptions;
Expand All @@ -1073,6 +1076,7 @@ describe('oauth2 auth adapter', () => {
id: 'fakeid',
access_token: 'sometoken',
};
authenticationLoader.initializeAuthAdapter('oauth2Authentication', options);
const { adapter, appIds, providerOptions } = authenticationLoader.loadAuthAdapter(
'oauth2Authentication',
options
Expand All @@ -1097,6 +1101,7 @@ describe('oauth2 auth adapter', () => {
id: 'fakeid',
access_token: 'sometoken',
};
authenticationLoader.initializeAuthAdapter('oauth2Authentication', options);
const { adapter, appIds, providerOptions } = authenticationLoader.loadAuthAdapter(
'oauth2Authentication',
options
Expand All @@ -1121,6 +1126,7 @@ describe('oauth2 auth adapter', () => {
id: 'fakeid',
access_token: 'sometoken',
};
authenticationLoader.initializeAuthAdapter('oauth2Authentication', options);
const { adapter, appIds, providerOptions } = authenticationLoader.loadAuthAdapter(
'oauth2Authentication',
options
Expand All @@ -1147,6 +1153,7 @@ describe('oauth2 auth adapter', () => {
id: 'fakeid',
access_token: 'sometoken',
};
authenticationLoader.initializeAuthAdapter('oauth2Authentication', options);
const { adapter, appIds, providerOptions } = authenticationLoader.loadAuthAdapter(
'oauth2Authentication',
options
Expand All @@ -1173,6 +1180,7 @@ describe('oauth2 auth adapter', () => {
id: 'fakeid',
access_token: 'sometoken',
};
authenticationLoader.initializeAuthAdapter('oauth2Authentication', options);
const { adapter, appIds, providerOptions } = authenticationLoader.loadAuthAdapter(
'oauth2Authentication',
options
Expand Down Expand Up @@ -1200,6 +1208,7 @@ describe('oauth2 auth adapter', () => {
id: 'fakeid',
access_token: 'sometoken',
};
authenticationLoader.initializeAuthAdapter('oauth2Authentication', options);
const { adapter, appIds, providerOptions } = authenticationLoader.loadAuthAdapter(
'oauth2Authentication',
options
Expand Down Expand Up @@ -1229,6 +1238,7 @@ describe('oauth2 auth adapter', () => {
id: 'fakeid',
access_token: 'sometoken',
};
authenticationLoader.initializeAuthAdapter('oauth2Authentication', options);
const { adapter, appIds, providerOptions } = authenticationLoader.loadAuthAdapter(
'oauth2Authentication',
options
Expand Down Expand Up @@ -1260,6 +1270,7 @@ describe('oauth2 auth adapter', () => {
id: 'fakeid',
access_token: 'sometoken',
};
authenticationLoader.initializeAuthAdapter('oauth2Authentication', options);
const { adapter, appIds, providerOptions } = authenticationLoader.loadAuthAdapter(
'oauth2Authentication',
options
Expand Down Expand Up @@ -1291,6 +1302,7 @@ describe('oauth2 auth adapter', () => {
id: 'fakeid',
access_token: 'sometoken',
};
authenticationLoader.initializeAuthAdapter('oauth2Authentication', options);
const { adapter, appIds, providerOptions } = authenticationLoader.loadAuthAdapter(
'oauth2Authentication',
options
Expand Down Expand Up @@ -1320,6 +1332,7 @@ describe('oauth2 auth adapter', () => {
id: 'fakeid',
access_token: 'sometoken',
};
authenticationLoader.initializeAuthAdapter('oauth2Authentication', options);
const { adapter, providerOptions } = authenticationLoader.loadAuthAdapter(
'oauth2Authentication',
options
Expand Down Expand Up @@ -1348,6 +1361,7 @@ describe('oauth2 auth adapter', () => {
id: 'fakeid',
access_token: 'sometoken',
};
authenticationLoader.initializeAuthAdapter('oauth2Authentication', options);
const { adapter, providerOptions } = authenticationLoader.loadAuthAdapter(
'oauth2Authentication',
options
Expand Down Expand Up @@ -1389,6 +1403,7 @@ describe('oauth2 auth adapter', () => {
id: 'fakeid',
access_token: 'sometoken',
};
authenticationLoader.initializeAuthAdapter('oauth2Authentication', options);
const { adapter, providerOptions } = authenticationLoader.loadAuthAdapter(
'oauth2Authentication',
options
Expand Down Expand Up @@ -1432,6 +1447,7 @@ describe('oauth2 auth adapter', () => {
id: 'fakeid',
access_token: 'sometoken',
};
authenticationLoader.initializeAuthAdapter('oauth2Authentication', options);
const { adapter, providerOptions } = authenticationLoader.loadAuthAdapter(
'oauth2Authentication',
options
Expand Down Expand Up @@ -1791,6 +1807,7 @@ describe('Apple Game Center Auth adapter', () => {
'https://cacerts.digicert.com/DigiCertTrustedG4CodeSigningRSA4096SHA3842021CA1.crt.pem',
},
};
authenticationLoader.initializeAuthAdapter('gcenter', options);
const { adapter, appIds, providerOptions } = authenticationLoader.loadAuthAdapter(
'gcenter',
options
Expand All @@ -1809,6 +1826,7 @@ describe('Apple Game Center Auth adapter', () => {
'https://cacerts.digicert.com/DigiCertTrustedG4CodeSigningRSA4096SHA3842021CA1.crt.pem',
},
};
authenticationLoader.initializeAuthAdapter('gcenter', options);
const { adapter, appIds, providerOptions } = authenticationLoader.loadAuthAdapter(
'gcenter',
options
Expand All @@ -1835,6 +1853,7 @@ describe('Apple Game Center Auth adapter', () => {
it('validateAuthData invalid signature id', async () => {
gcenter.cache['https://static.gc.apple.com/public-key/gc-prod-4.cer'] = testCert;
gcenter.cache['https://static.gc.apple.com/public-key/gc-prod-6.cer'] = testCert2;
authenticationLoader.initializeAuthAdapter('gcenter', {});
const { adapter, appIds, providerOptions } = authenticationLoader.loadAuthAdapter(
'gcenter',
{}
Expand Down Expand Up @@ -1929,6 +1948,7 @@ describe('Apple Game Center Auth adapter', () => {
const options = {
gcenter: {},
};
authenticationLoader.initializeAuthAdapter('gcenter', options);
const { adapter, appIds, providerOptions } = authenticationLoader.loadAuthAdapter(
'gcenter',
options
Expand All @@ -1955,6 +1975,7 @@ describe('Apple Game Center Auth adapter', () => {
rootCertificateUrl: 'https://example.com',
},
};
authenticationLoader.initializeAuthAdapter('gcenter', options);
const { adapter, appIds, providerOptions } = authenticationLoader.loadAuthAdapter(
'gcenter',
options
Expand Down Expand Up @@ -1982,6 +2003,7 @@ describe('phant auth adapter', () => {
id: 'fakeid',
access_token: 'sometoken',
};
authenticationLoader.initializeAuthAdapter('phantauth', {});
const { adapter } = authenticationLoader.loadAuthAdapter('phantauth', {});

spyOn(httpsRequest, 'get').and.callFake(() => Promise.resolve({ sub: 'invalidID' }));
Expand Down
8 changes: 7 additions & 1 deletion spec/AuthenticationAdaptersV2.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,8 @@ describe('Auth Adapter features', () => {
const spy = spyOn(modernAdapter3, 'validateOptions').and.callThrough();
const afterSpy = spyOn(modernAdapter3, 'afterFind').and.callThrough();
await reconfigureServer({ auth: { modernAdapter3 }, silent: false });
expect(spy).toHaveBeenCalled();
spy.calls.reset();
const user = new Parse.User();
await user.save({ authData: { modernAdapter3: { id: 'modernAdapter3Data' } } });
await user.fetch({ sessionToken: user.getSessionToken() });
Expand All @@ -366,7 +368,7 @@ describe('Auth Adapter features', () => {
{ id: 'modernAdapter3Data' },
undefined
);
expect(spy).toHaveBeenCalled();
expect(spy).not.toHaveBeenCalled();
});

it('should throw if no triggers found', async () => {
Expand Down Expand Up @@ -1234,6 +1236,10 @@ describe('Auth Adapter features', () => {
await user.save({ authData: { challengeAdapter: { id: 'challengeAdapter' } } });

spyOn(challengeAdapter, 'validateAuthData').and.rejectWith({});
const authenticationLoader = require('../lib/Adapters/Auth');
authenticationLoader.initializeAuthAdapter('challengeAdapter', {
challengeAdapter,
});

await expectAsync(
requestWithExpectedError({
Expand Down
13 changes: 13 additions & 0 deletions spec/ParseUser.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,19 @@ describe('Parse.User testing', () => {
);
});

it('cannot connect to unconfigured adapter', async () => {
await reconfigureServer({
auth: {},
});
const provider = getMockFacebookProvider();
Parse.User._registerAuthenticationProvider(provider);
const user = new Parse.User();
user.set('foo', 'bar');
await expectAsync(user._linkWith('facebook', {})).toBeRejectedWith(
new Parse.Error(Parse.Error.UNSUPPORTED_SERVICE, 'This authentication method is unsupported.')
);
});

it('should not call beforeLogin with become', async done => {
const provider = getMockFacebookProvider();
Parse.User._registerAuthenticationProvider(provider);
Expand Down
Loading