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

Allow protectedFields for Authenticated users and Public. Fix userField with keys/excludedKeys #6415

Merged
Show file tree
Hide file tree
Changes from 4 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
80 changes: 80 additions & 0 deletions spec/ParseGraphQLServer.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ const fetch = require('node-fetch');
const FormData = require('form-data');
const ws = require('ws');
require('./helper');
const { updateCLP } = require('./dev');

const pluralize = require('pluralize');
const { getMainDefinition } = require('apollo-utilities');
const { ApolloLink, split } = require('apollo-link');
Expand Down Expand Up @@ -4632,6 +4634,84 @@ describe('ParseGraphQLServer', () => {
).toBeDefined();
});

it('should respect protectedFields', async done => {
await prepareData();
await parseGraphQLServer.parseGraphQLSchema.databaseController.schemaCache.clear();

const className = 'GraphQLClass';

await updateCLP(
{
get: { '*': true },
find: { '*': true },

protectedFields: {
'*': ['someField', 'someOtherField'],
authenticated: ['someField'],
'userField:pointerToUser': [],
[user2.id]: [],
},
},
className
);

const getObject = async (className, id, user) => {
const headers = user
? { ['X-Parse-Session-Token']: user.getSessionToken() }
: undefined;

const specificQueryResult = await apolloClient.query({
query: gql`
query GetSomeObject($id: ID!) {
get: graphQLClass(id: $id) {
pointerToUser {
username
id
}
someField
someOtherField
}
}
`,
variables: {
id: id,
},
context: {
headers: headers,
},
});

return specificQueryResult.data.get;
};

const id = object3.id;

/* not authenticated */
const objectPublic = await getObject(className, id, undefined);

expect(objectPublic.someField).toBeNull();
expect(objectPublic.someOtherField).toBeNull();

/* authenticated */
const objectAuth = await getObject(className, id, user1);

expect(objectAuth.someField).toBeNull();
expect(objectAuth.someOtherField).toBe('B');

/* pointer field */
const objectPointed = await getObject(className, id, user5);

expect(objectPointed.someField).toBe('someValue3');
expect(objectPointed.someOtherField).toBe('B');

/* for user id */
const objectForUser = await getObject(className, id, user2);

expect(objectForUser.someField).toBe('someValue3');
expect(objectForUser.someOtherField).toBe('B');

done();
});
describe_only_db('mongo')('read preferences', () => {
it('should read from primary by default', async () => {
try {
Expand Down
32 changes: 32 additions & 0 deletions spec/ParseQuery.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -4868,4 +4868,36 @@ describe('Parse.Query testing', () => {
const results = await query.find();
equal(results[0].get('array').length, 105);
});

it('exclude keys (sdk query)', async done => {
const obj = new TestObject({ foo: 'baz', hello: 'world' });
await obj.save();

const query = new Parse.Query('TestObject');
query.exclude('foo');

const object = await query.get(obj.id);
expect(object.get('foo')).toBeUndefined();
expect(object.get('hello')).toBe('world');
done();
});

xit('todo: exclude keys with select key (sdk query get)', async done => {
// there is some problem with js sdk caching

const obj = new TestObject({ foo: 'baz', hello: 'world' });
await obj.save();

const query = new Parse.Query('TestObject');

query.withJSON({
keys: 'hello',
excludeKeys: 'hello',
});

const object = await query.get(obj.id);
expect(object.get('foo')).toBeUndefined();
expect(object.get('hello')).toBeUndefined();
done();
});
});
52 changes: 51 additions & 1 deletion spec/PointerPermissions.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2047,7 +2047,7 @@ describe('Pointer Permissions', () => {
}

async function logIn(userObject) {
await Parse.User.logIn(userObject.getUsername(), 'password');
return await Parse.User.logIn(userObject.getUsername(), 'password');
}

async function updateCLP(clp) {
Expand Down Expand Up @@ -3098,5 +3098,55 @@ describe('Pointer Permissions', () => {
done();
});
});

describe('using pointer-fields and queries with keys projection', () => {
let user1;
/**
* owner: user1
*
* testers: [user1]
*/
let obj;

/**
* Clear cache, create user and object, login user
*/
async function initialize() {
await Config.get(Parse.applicationId).database.schemaCache.clear();

user1 = await createUser('user1');
user1 = await logIn(user1);

obj = new Parse.Object(className);

obj.set('owner', user1);
obj.set('field', 'field');
obj.set('test', 'test');

await Parse.Object.saveAll([obj], { useMasterKey: true });

await obj.fetch();
}

beforeEach(async () => {
await initialize();
});

it('should be enforced regardless of pointer-field being included in keys (select)', async done => {
await updateCLP({
get: { '*': true },
find: { pointerFields: ['owner'] },
update: { pointerFields: ['owner'] },
});

const query = new Parse.Query('AnObject');
query.select('field', 'test');

const [object] = await query.find({ objectId: obj.id });
expect(object.get('field')).toBe('field');
expect(object.get('test')).toBe('test');
done();
});
});
});
});
Loading