Merge pull request #791 from ParsePlatform/nlutsenko.triggers.installationId
Propagate installationId to all Cloud Code triggers.
This commit is contained in:
@@ -749,6 +749,80 @@ describe('miscellaneous', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('test beforeSave/afterSave get installationId', function(done) {
|
||||||
|
let triggerTime = 0;
|
||||||
|
Parse.Cloud.beforeSave('GameScore', function(req, res) {
|
||||||
|
triggerTime++;
|
||||||
|
expect(triggerTime).toEqual(1);
|
||||||
|
expect(req.installationId).toEqual('yolo');
|
||||||
|
res.success();
|
||||||
|
});
|
||||||
|
Parse.Cloud.afterSave('GameScore', function(req) {
|
||||||
|
triggerTime++;
|
||||||
|
expect(triggerTime).toEqual(2);
|
||||||
|
expect(req.installationId).toEqual('yolo');
|
||||||
|
});
|
||||||
|
|
||||||
|
var headers = {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'X-Parse-Application-Id': 'test',
|
||||||
|
'X-Parse-REST-API-Key': 'rest',
|
||||||
|
'X-Parse-Installation-Id': 'yolo'
|
||||||
|
};
|
||||||
|
request.post({
|
||||||
|
headers: headers,
|
||||||
|
url: 'http://localhost:8378/1/classes/GameScore',
|
||||||
|
body: JSON.stringify({ a: 'b' })
|
||||||
|
}, (error, response, body) => {
|
||||||
|
expect(error).toBe(null);
|
||||||
|
expect(triggerTime).toEqual(2);
|
||||||
|
|
||||||
|
Parse.Cloud._removeHook("Triggers", "beforeSave", "GameScore");
|
||||||
|
Parse.Cloud._removeHook("Triggers", "afterSave", "GameScore");
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('test beforeDelete/afterDelete get installationId', function(done) {
|
||||||
|
let triggerTime = 0;
|
||||||
|
Parse.Cloud.beforeDelete('GameScore', function(req, res) {
|
||||||
|
triggerTime++;
|
||||||
|
expect(triggerTime).toEqual(1);
|
||||||
|
expect(req.installationId).toEqual('yolo');
|
||||||
|
res.success();
|
||||||
|
});
|
||||||
|
Parse.Cloud.afterDelete('GameScore', function(req) {
|
||||||
|
triggerTime++;
|
||||||
|
expect(triggerTime).toEqual(2);
|
||||||
|
expect(req.installationId).toEqual('yolo');
|
||||||
|
});
|
||||||
|
|
||||||
|
var headers = {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'X-Parse-Application-Id': 'test',
|
||||||
|
'X-Parse-REST-API-Key': 'rest',
|
||||||
|
'X-Parse-Installation-Id': 'yolo'
|
||||||
|
};
|
||||||
|
request.post({
|
||||||
|
headers: headers,
|
||||||
|
url: 'http://localhost:8378/1/classes/GameScore',
|
||||||
|
body: JSON.stringify({ a: 'b' })
|
||||||
|
}, (error, response, body) => {
|
||||||
|
expect(error).toBe(null);
|
||||||
|
request.del({
|
||||||
|
headers: headers,
|
||||||
|
url: 'http://localhost:8378/1/classes/GameScore/' + JSON.parse(body).objectId
|
||||||
|
}, (error, response, body) => {
|
||||||
|
expect(error).toBe(null);
|
||||||
|
expect(triggerTime).toEqual(2);
|
||||||
|
|
||||||
|
Parse.Cloud._removeHook("Triggers", "beforeDelete", "GameScore");
|
||||||
|
Parse.Cloud._removeHook("Triggers", "afterDelete", "GameScore");
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('test cloud function query parameters', (done) => {
|
it('test cloud function query parameters', (done) => {
|
||||||
Parse.Cloud.define('echoParams', (req, res) => {
|
Parse.Cloud.define('echoParams', (req, res) => {
|
||||||
res.success(req.params);
|
res.success(req.params);
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ describe('Parse Role testing', () => {
|
|||||||
return createRole(rolesNames[2], anotherRole, user);
|
return createRole(rolesNames[2], anotherRole, user);
|
||||||
}).then( (lastRole) => {
|
}).then( (lastRole) => {
|
||||||
roleIds[lastRole.get("name")] = lastRole.id;
|
roleIds[lastRole.get("name")] = lastRole.id;
|
||||||
var auth = new Auth(new Config("test") , true, user);
|
var auth = new Auth({ config: new Config("test"), isMaster: true, user: user });
|
||||||
return auth._loadRoles();
|
return auth._loadRoles();
|
||||||
})
|
})
|
||||||
}).then( (roles) => {
|
}).then( (roles) => {
|
||||||
|
|||||||
15
src/Auth.js
15
src/Auth.js
@@ -7,10 +7,11 @@ import cache from './cache';
|
|||||||
// An Auth object tells you who is requesting something and whether
|
// An Auth object tells you who is requesting something and whether
|
||||||
// the master key was used.
|
// the master key was used.
|
||||||
// userObject is a Parse.User and can be null if there's no user.
|
// userObject is a Parse.User and can be null if there's no user.
|
||||||
function Auth(config, isMaster, userObject) {
|
function Auth({ config, isMaster = false, user, installationId } = {}) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
|
this.installationId = installationId;
|
||||||
this.isMaster = isMaster;
|
this.isMaster = isMaster;
|
||||||
this.user = userObject;
|
this.user = user;
|
||||||
|
|
||||||
// Assuming a users roles won't change during a single request, we'll
|
// Assuming a users roles won't change during a single request, we'll
|
||||||
// only load them once.
|
// only load them once.
|
||||||
@@ -33,19 +34,19 @@ Auth.prototype.couldUpdateUserId = function(userId) {
|
|||||||
|
|
||||||
// A helper to get a master-level Auth object
|
// A helper to get a master-level Auth object
|
||||||
function master(config) {
|
function master(config) {
|
||||||
return new Auth(config, true, null);
|
return new Auth({ config, isMaster: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
// A helper to get a nobody-level Auth object
|
// A helper to get a nobody-level Auth object
|
||||||
function nobody(config) {
|
function nobody(config) {
|
||||||
return new Auth(config, false, null);
|
return new Auth({ config, isMaster: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a promise that resolves to an Auth object
|
// Returns a promise that resolves to an Auth object
|
||||||
var getAuthForSessionToken = function(config, sessionToken) {
|
var getAuthForSessionToken = function({ config, sessionToken, installationId } = {}) {
|
||||||
var cachedUser = cache.users.get(sessionToken);
|
var cachedUser = cache.users.get(sessionToken);
|
||||||
if (cachedUser) {
|
if (cachedUser) {
|
||||||
return Promise.resolve(new Auth(config, false, cachedUser));
|
return Promise.resolve(new Auth({ config, isMaster: false, installationId, user: cachedUser }));
|
||||||
}
|
}
|
||||||
var restOptions = {
|
var restOptions = {
|
||||||
limit: 1,
|
limit: 1,
|
||||||
@@ -67,7 +68,7 @@ var getAuthForSessionToken = function(config, sessionToken) {
|
|||||||
obj['sessionToken'] = sessionToken;
|
obj['sessionToken'] = sessionToken;
|
||||||
let userObject = Parse.Object.fromJSON(obj);
|
let userObject = Parse.Object.fromJSON(obj);
|
||||||
cache.users.set(sessionToken, userObject);
|
cache.users.set(sessionToken, userObject);
|
||||||
return new Auth(config, false, userObject);
|
return new Auth({ config, isMaster: false, installationId, user: userObject });
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ export class UserController extends AdaptableController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
verifyEmail(username, token) {
|
verifyEmail(username, token) {
|
||||||
if (!this.shouldVerifyEmails) {
|
if (!this.shouldVerifyEmails) {
|
||||||
// Trying to verify email when not enabled
|
// Trying to verify email when not enabled
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ function handleParseHeaders(req, res, next) {
|
|||||||
var isMaster = (info.masterKey === req.config.masterKey);
|
var isMaster = (info.masterKey === req.config.masterKey);
|
||||||
|
|
||||||
if (isMaster) {
|
if (isMaster) {
|
||||||
req.auth = new auth.Auth(req.config, true);
|
req.auth = new auth.Auth({ config: req.config, installationId: info.installationId, isMaster: true });
|
||||||
next();
|
next();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -114,23 +114,23 @@ function handleParseHeaders(req, res, next) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!info.sessionToken) {
|
if (!info.sessionToken) {
|
||||||
req.auth = new auth.Auth(req.config, false);
|
req.auth = new auth.Auth({ config: req.config, installationId: info.installationId, isMaster: false });
|
||||||
next();
|
next();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return auth.getAuthForSessionToken(
|
return auth.getAuthForSessionToken({ config: req.config, installationId: info.installationId, sessionToken: info.sessionToken })
|
||||||
req.config, info.sessionToken).then((auth) => {
|
.then((auth) => {
|
||||||
if (auth) {
|
if (auth) {
|
||||||
req.auth = auth;
|
req.auth = auth;
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
}).catch((error) => {
|
})
|
||||||
|
.catch((error) => {
|
||||||
// TODO: Determine the correct error scenario.
|
// TODO: Determine the correct error scenario.
|
||||||
console.log(error);
|
console.log(error);
|
||||||
throw new Parse.Error(Parse.Error.UNKNOWN_ERROR, error);
|
throw new Parse.Error(Parse.Error.UNKNOWN_ERROR, error);
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var allowCrossDomain = function(req, res, next) {
|
var allowCrossDomain = function(req, res, next) {
|
||||||
|
|||||||
@@ -110,12 +110,11 @@ export function getRequestObject(triggerType, auth, parseObject, originalParseOb
|
|||||||
if (auth.user) {
|
if (auth.user) {
|
||||||
request['user'] = auth.user;
|
request['user'] = auth.user;
|
||||||
}
|
}
|
||||||
// TODO: Add installation to Auth?
|
|
||||||
if (auth.installationId) {
|
if (auth.installationId) {
|
||||||
request['installationId'] = auth.installationId;
|
request['installationId'] = auth.installationId;
|
||||||
}
|
}
|
||||||
return request;
|
return request;
|
||||||
};
|
}
|
||||||
|
|
||||||
// Creates the response object, and uses the request object to pass data
|
// Creates the response object, and uses the request object to pass data
|
||||||
// The API will call this with REST API formatted objects, this will
|
// The API will call this with REST API formatted objects, this will
|
||||||
|
|||||||
Reference in New Issue
Block a user