Merge pull request #9313 from tdjac0bs/validate_auth_token_refactor

Refactor connection definition of userId to wait for validateAuthToken
This commit is contained in:
Fred Dixon 2020-04-28 23:37:28 -04:00 committed by GitHub
commit f1c41d5d43
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 97 additions and 18 deletions

View File

@ -2,6 +2,9 @@ import { check } from 'meteor/check';
import Logger from '/imports/startup/server/logger';
import Users from '/imports/api/users';
import userJoin from './userJoin';
import pendingAuthenticationsStore from '../store/pendingAuthentications';
import createDummyUser from '../modifiers/createDummyUser';
import setConnectionIdAndAuthToken from '../modifiers/setConnectionIdAndAuthToken';
const clearOtherSessions = (sessionUserId, current = false) => {
const serverSessions = Meteor.server.sessions;
@ -12,12 +15,58 @@ const clearOtherSessions = (sessionUserId, current = false) => {
};
export default function handleValidateAuthToken({ body }, meetingId) {
const { userId, valid, waitForApproval } = body;
const { userId, valid, authToken, waitForApproval } = body;
check(userId, String);
check(authToken, String);
check(valid, Boolean);
check(waitForApproval, Boolean);
const pendingAuths = pendingAuthenticationsStore.take(meetingId, userId, authToken);
if(!valid) {
pendingAuths.forEach (
pendingAuth => {
try {
const {methodInvocationObject} = pendingAuth;
const connectionId = methodInvocationObject.connection.id;
methodInvocationObject.connection.close();
Logger.info(`Closed connection ${connectionId} due to invalid auth token.`);
} catch (e) {
Logger.error(`Error closing socket for meetingId '${meetingId}', userId '${userId}', authToken ${authToken}`);
}
}
);
return;
}
if(valid) {
// Define user ID on connections
pendingAuths.forEach (
pendingAuth => {
const {methodInvocationObject} = pendingAuth;
/* Logic migrated from validateAuthToken method ( postponed to only run in case of success response ) - Begin */
const sessionId = `${meetingId}--${userId}`;
methodInvocationObject.setUserId(sessionId);
const User = Users.findOne({
meetingId,
userId: userId,
});
if (!User) {
createDummyUser(meetingId, userId, authToken);
}
setConnectionIdAndAuthToken(meetingId, userId, methodInvocationObject.connection.id, authToken);
/* End of logic migrated from validateAuthToken */
}
);
}
const selector = {
meetingId,
userId,

View File

@ -1,35 +1,22 @@
import { Meteor } from 'meteor/meteor';
import RedisPubSub from '/imports/startup/server/redis';
import Logger from '/imports/startup/server/logger';
import Users from '/imports/api/users';
import createDummyUser from '../modifiers/createDummyUser';
import setConnectionIdAndAuthToken from '../modifiers/setConnectionIdAndAuthToken';
import pendingAuthenticationsStore from '../store/pendingAuthentications';
export default function validateAuthToken(meetingId, requesterUserId, requesterToken) {
const REDIS_CONFIG = Meteor.settings.private.redis;
const CHANNEL = REDIS_CONFIG.channels.toAkkaApps;
const EVENT_NAME = 'ValidateAuthTokenReqMsg';
const sessionId = `${meetingId}--${requesterUserId}`;
this.setUserId(sessionId);
const User = Users.findOne({
meetingId,
userId: requesterUserId,
});
if (!User) {
createDummyUser(meetingId, requesterUserId, requesterToken);
}
setConnectionIdAndAuthToken(meetingId, requesterUserId, this.connection.id, requesterToken);
// Store reference of methodInvocationObject ( to postpone the connection userId definition )
pendingAuthenticationsStore.add(meetingId, requesterUserId, requesterToken, this);
const payload = {
userId: requesterUserId,
authToken: requesterToken,
};
Logger.info(`User '${requesterUserId}' is trying to validate auth token for meeting '${meetingId}'`);
Logger.info(`User '${requesterUserId}' is trying to validate auth token for meeting '${meetingId}' from connection '${this.connection.id}'`);
return RedisPubSub.publishUserMessage(CHANNEL, EVENT_NAME, meetingId, requesterUserId, payload);
}

View File

@ -0,0 +1,43 @@
import Logger from '/imports/startup/server/logger';
class PendingAuthentitcations {
constructor () {
Logger.debug("PendingAuthentitcations :: constructor");
this.store = [];
}
generateKey (meetingId, userId, authToken) {
// Protect against separator injection
meetingId = meetingId.replace(/ /g, '');
userId = userId.replace(/ /g, '');
authToken = authToken.replace(/ /g, '');
// Space separated key
return '${meetingId} ${userId} ${authToken}';
}
add (meetingId, userId, authToken, methodInvocationObject) {
Logger.debug("PendingAuthentitcations :: add", {meetingId, userId, authToken});
this.store.push({
key: this.generateKey(meetingId, userId, authToken),
meetingId, userId, authToken, methodInvocationObject
});
}
take (meetingId, userId, authToken) {
Logger.debug("PendingAuthentitcations :: take", {meetingId, userId, authToken});
const key = this.generateKey(meetingId, userId, authToken);
// find matches
const matches = this.store.filter( e => e.key === key );
// remove matches (if any)
if(matches.length) {
this.store = this.store.filter( e => e.key !== key ) ;
}
// return matches
return matches;
}
}
export default new PendingAuthentitcations();