-
-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Direct Access to parse-server (#2316)
* Adds ParseServerRESTController experimental support * Adds basic tests * Do not create sessionToken when requests come from cloudCode #1495
- Loading branch information
1 parent
ccf2b14
commit cb7b549
Showing
6 changed files
with
292 additions
and
56 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
const ParseServerRESTController = require('../src/ParseServerRESTController').ParseServerRESTController; | ||
const ParseServer = require('../src/ParseServer').default; | ||
let RESTController; | ||
|
||
describe('ParseServerRESTController', () => { | ||
|
||
beforeEach(() => { | ||
RESTController = ParseServerRESTController(Parse.applicationId, ParseServer.promiseRouter({appId: Parse.applicationId})); | ||
}) | ||
|
||
it('should handle a get request', (done) => { | ||
RESTController.request("GET", "/classes/MyObject").then((res) => { | ||
expect(res.results.length).toBe(0); | ||
done(); | ||
}, (err) => { | ||
console.log(err); | ||
jfail(err); | ||
done(); | ||
}); | ||
}); | ||
|
||
it('should handle a get request with full serverURL mount path', (done) => { | ||
RESTController.request("GET", "/1/classes/MyObject").then((res) => { | ||
expect(res.results.length).toBe(0); | ||
done(); | ||
}, (err) => { | ||
jfail(err); | ||
done(); | ||
}); | ||
}); | ||
|
||
it('should handle a POST batch', (done) => { | ||
RESTController.request("POST", "batch", { | ||
requests: [ | ||
{ | ||
method: 'GET', | ||
path: '/classes/MyObject' | ||
}, | ||
{ | ||
method: 'POST', | ||
path: '/classes/MyObject', | ||
body: {"key": "value"} | ||
}, | ||
{ | ||
method: 'GET', | ||
path: '/classes/MyObject' | ||
} | ||
] | ||
}).then((res) => { | ||
expect(res.length).toBe(3); | ||
done(); | ||
}, (err) => { | ||
jfail(err); | ||
done(); | ||
}); | ||
}); | ||
|
||
it('should handle a POST request', (done) => { | ||
RESTController.request("POST", "/classes/MyObject", {"key": "value"}).then((res) => { | ||
return RESTController.request("GET", "/classes/MyObject"); | ||
}).then((res) => { | ||
expect(res.results.length).toBe(1); | ||
expect(res.results[0].key).toEqual("value"); | ||
done(); | ||
}).fail((err) => { | ||
console.log(err); | ||
jfail(err); | ||
done(); | ||
}); | ||
}); | ||
|
||
it('ensures sessionTokens are properly handled', (done) => { | ||
let userId; | ||
Parse.User.signUp('user', 'pass').then((user) => { | ||
userId = user.id; | ||
let sessionToken = user.getSessionToken(); | ||
return RESTController.request("GET", "/users/me", undefined, {sessionToken}); | ||
}).then((res) => { | ||
// Result is in JSON format | ||
expect(res.objectId).toEqual(userId); | ||
done(); | ||
}).fail((err) => { | ||
console.log(err); | ||
jfail(err); | ||
done(); | ||
}); | ||
}); | ||
|
||
it('ensures masterKey is properly handled', (done) => { | ||
let userId; | ||
Parse.User.signUp('user', 'pass').then((user) => { | ||
userId = user.id; | ||
let sessionToken = user.getSessionToken(); | ||
return Parse.User.logOut().then(() => { | ||
return RESTController.request("GET", "/classes/_User", undefined, {useMasterKey: true}); | ||
}); | ||
}).then((res) => { | ||
expect(res.results.length).toBe(1); | ||
expect(res.results[0].objectId).toEqual(userId); | ||
done(); | ||
}, (err) => { | ||
jfail(err); | ||
done(); | ||
}); | ||
}); | ||
|
||
it('ensures no session token is created on creating users', (done) => { | ||
RESTController.request("POST", "/classes/_User", {username: "hello", password: "world"}).then(() => { | ||
let query = new Parse.Query('_Session'); | ||
return query.find({useMasterKey: true}); | ||
}).then(sessions => { | ||
expect(sessions.length).toBe(0); | ||
done(); | ||
}, (err) => { | ||
jfail(err); | ||
done(); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
const Config = require('./Config'); | ||
const Auth = require('./Auth'); | ||
const RESTController = require('parse/lib/node/RESTController'); | ||
const URL = require('url'); | ||
const Parse = require('parse/node'); | ||
|
||
function getSessionToken(options) { | ||
if (options && typeof options.sessionToken === 'string') { | ||
return Parse.Promise.as(options.sessionToken); | ||
} | ||
return Parse.Promise.as(null); | ||
} | ||
|
||
function getAuth(options, config) { | ||
if (options.useMasterKey) { | ||
return Parse.Promise.as(new Auth.Auth({config, isMaster: true, installationId: 'cloud' })); | ||
} | ||
return getSessionToken(options).then((sessionToken) => { | ||
if (sessionToken) { | ||
options.sessionToken = sessionToken; | ||
return Auth.getAuthForSessionToken({ | ||
config, | ||
sessionToken: sessionToken, | ||
installationId: 'cloud' | ||
}); | ||
} else { | ||
return Parse.Promise.as(new Auth.Auth({ config, installationId: 'cloud' })); | ||
} | ||
}) | ||
} | ||
|
||
function ParseServerRESTController(applicationId, router) { | ||
function handleRequest(method, path, data = {}, options = {}) { | ||
// Store the arguments, for later use if internal fails | ||
let args = arguments; | ||
|
||
let config = new Config(applicationId); | ||
let serverURL = URL.parse(config.serverURL); | ||
if (path.indexOf(serverURL.path) === 0) { | ||
path = path.slice(serverURL.path.length, path.length); | ||
} | ||
|
||
if (path[0] !== "/") { | ||
path = "/" + path; | ||
} | ||
|
||
if (path === '/batch') { | ||
let promises = data.requests.map((request) => { | ||
return handleRequest(request.method, request.path, request.body, options).then((response) => { | ||
return Parse.Promise.as({success: response}); | ||
}, (error) => { | ||
return Parse.Promise.as({error: {code: error.code, error: error.message}}); | ||
}); | ||
}); | ||
return Parse.Promise.all(promises); | ||
} | ||
|
||
let query; | ||
if (method === 'GET') { | ||
query = data; | ||
} | ||
|
||
return new Parse.Promise((resolve, reject) => { | ||
getAuth(options, config).then((auth) => { | ||
let request = { | ||
body: data, | ||
config, | ||
auth, | ||
info: { | ||
applicationId: applicationId, | ||
sessionToken: options.sessionToken | ||
}, | ||
query | ||
}; | ||
return Promise.resolve().then(() => { | ||
return router.tryRouteRequest(method, path, request); | ||
}).then((response) => { | ||
resolve(response.response, response.status, response); | ||
}, (err) => { | ||
if (err instanceof Parse.Error && | ||
err.code == Parse.Error.INVALID_JSON && | ||
err.message == `cannot route ${method} ${path}`) { | ||
RESTController.request.apply(null, args).then(resolve, reject); | ||
} else { | ||
reject(err); | ||
} | ||
}); | ||
}, reject); | ||
}); | ||
}; | ||
|
||
return { | ||
request: handleRequest, | ||
ajax: RESTController.ajax | ||
}; | ||
}; | ||
|
||
export default ParseServerRESTController; | ||
export { ParseServerRESTController }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
cb7b549
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@flovilmart - how do I try this out? Presumably it's not enabled for everyone in 2.2.19?
cb7b549
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@zingano you can enable by setting PARSE_SERVER_ENABLE_EXPERIMENTAL_DIRECT_ACCESS=1 in your environment before starting Parse-server