Skip to content

Commit cf86774

Browse files
committed
Adds class level permission requiring authenticated user
1 parent 75ae958 commit cf86774

File tree

2 files changed

+232
-0
lines changed

2 files changed

+232
-0
lines changed

spec/Schema.spec.js

+213
Original file line numberDiff line numberDiff line change
@@ -704,3 +704,216 @@ describe('Schema', () => {
704704
done();
705705
});
706706
});
707+
708+
describe('Class Level Permissions for requiredAuth', () => {
709+
710+
function createUser(username = 'hello', password = 'world') {
711+
let user = new Parse.User();
712+
user.set("username", "hello");
713+
user.set("password", "world");
714+
return user.signUp(null);
715+
}
716+
it('required auth test find', (done) => {
717+
config.database.loadSchema().then((schema) => {
718+
// Just to create a valid class
719+
return schema.validateObject('Stuff', {foo: 'bar'});
720+
}).then((schema) => {
721+
return schema.setPermissions('Stuff', {
722+
'find': {
723+
'requiresAuthentication': true
724+
}
725+
});
726+
}).then((schema) => {
727+
var query = new Parse.Query('Stuff');
728+
return query.find();
729+
}).then((results) => {
730+
fail('Class permissions should have rejected this query.');
731+
done();
732+
}, (e) => {
733+
expect(e.message).toEqual('Permission denied, user needs to be authenticated.');
734+
done();
735+
});
736+
});
737+
738+
it('required auth test find authenticated', (done) => {
739+
config.database.loadSchema().then((schema) => {
740+
// Just to create a valid class
741+
return schema.validateObject('Stuff', {foo: 'bar'});
742+
}).then((schema) => {
743+
return schema.setPermissions('Stuff', {
744+
'find': {
745+
'requiresAuthentication': true
746+
}
747+
});
748+
}).then((schema) => {
749+
return createUser();
750+
}).then((user) => {
751+
var query = new Parse.Query('Stuff');
752+
return query.find();
753+
}).then((results) => {
754+
expect(results.length).toEqual(0);
755+
done();
756+
}, (e) => {
757+
console.error(e);
758+
fail("Should not have failed");
759+
done();
760+
});
761+
});
762+
763+
it('required auth test create authenticated', (done) => {
764+
config.database.loadSchema().then((schema) => {
765+
// Just to create a valid class
766+
return schema.validateObject('Stuff', {foo: 'bar'});
767+
}).then((schema) => {
768+
return schema.setPermissions('Stuff', {
769+
'create': {
770+
'requiresAuthentication': true
771+
}
772+
});
773+
}).then((schema) => {
774+
return createUser();
775+
}).then((user) => {
776+
let stuff = new Parse.Object('Stuff');
777+
stuff.set('foo', 'bar');
778+
return stuff.save();
779+
}).then((savedObject) => {
780+
done();
781+
}, (e) => {
782+
console.error(e);
783+
fail("Should not have failed");
784+
done();
785+
});
786+
});
787+
788+
it('required auth test create authenticated', (done) => {
789+
config.database.loadSchema().then((schema) => {
790+
// Just to create a valid class
791+
return schema.validateObject('Stuff', {foo: 'bar'});
792+
}).then((schema) => {
793+
return schema.setPermissions('Stuff', {
794+
'create': {
795+
'requiresAuthentication': true
796+
}
797+
});
798+
}).then((user) => {
799+
let stuff = new Parse.Object('Stuff');
800+
stuff.set('foo', 'bar');
801+
return stuff.save();
802+
}).then((results) => {
803+
fail('Class permissions should have rejected this query.');
804+
done();
805+
}, (e) => {
806+
expect(e.message).toEqual('Permission denied, user needs to be authenticated.');
807+
done();
808+
});
809+
});
810+
811+
it('required auth test create/get/update/delete authenticated', (done) => {
812+
config.database.loadSchema().then((schema) => {
813+
// Just to create a valid class
814+
return schema.validateObject('Stuff', {foo: 'bar'});
815+
}).then((schema) => {
816+
return schema.setPermissions('Stuff', {
817+
'create': {
818+
'requiresAuthentication': true
819+
},
820+
'get': {
821+
'requiresAuthentication': true
822+
},
823+
'delete': {
824+
'requiresAuthentication': true
825+
},
826+
'update': {
827+
'requiresAuthentication': true
828+
}
829+
});
830+
}).then((schema) => {
831+
return createUser();
832+
}).then((user) => {
833+
let stuff = new Parse.Object('Stuff');
834+
stuff.set('foo', 'bar');
835+
return stuff.save().then(() => {
836+
let query = new Parse.Query('Stuff');
837+
return query.get(stuff.id);
838+
});
839+
}).then((gotStuff) => {
840+
gotStuff.save({'foo': 'baz'}).then(() => {
841+
return gotStuff.destroy();
842+
})
843+
}).then(() => {
844+
done();
845+
}, (e) => {
846+
console.error(e);
847+
fail("Should not have failed");
848+
done();
849+
});
850+
});
851+
852+
it('required auth test create/get/update/delete not authenitcated', (done) => {
853+
config.database.loadSchema().then((schema) => {
854+
// Just to create a valid class
855+
return schema.validateObject('Stuff', {foo: 'bar'});
856+
}).then((schema) => {
857+
return schema.setPermissions('Stuff', {
858+
'get': {
859+
'requiresAuthentication': true
860+
},
861+
'delete': {
862+
'requiresAuthentication': true
863+
},
864+
'update': {
865+
'requiresAuthentication': true
866+
}
867+
});
868+
}).then((user) => {
869+
let stuff = new Parse.Object('Stuff');
870+
stuff.set('foo', 'bar');
871+
return stuff.save().then(() => {
872+
let query = new Parse.Query('Stuff');
873+
return query.get(stuff.id);
874+
});
875+
}).then((res) => {
876+
fail("Should not succeed!");
877+
done();
878+
}, (e) => {
879+
expect(e.message).toEqual('Permission denied, user needs to be authenticated.');
880+
done();
881+
});
882+
});
883+
884+
it('required auth test create/get/update/delete not authenitcated', (done) => {
885+
config.database.loadSchema().then((schema) => {
886+
// Just to create a valid class
887+
return schema.validateObject('Stuff', {foo: 'bar'});
888+
}).then((schema) => {
889+
return schema.setPermissions('Stuff', {
890+
'find': {
891+
'requiresAuthentication': true
892+
},
893+
'delete': {
894+
'requiresAuthentication': true
895+
},
896+
'update': {
897+
'requiresAuthentication': true
898+
}
899+
});
900+
}).then((user) => {
901+
let stuff = new Parse.Object('Stuff');
902+
stuff.set('foo', 'bar');
903+
return stuff.save().then(() => {
904+
let query = new Parse.Query('Stuff');
905+
return query.get(stuff.id);
906+
})
907+
}).then((result) => {
908+
expect(result.get('foo')).toEqual('bar');
909+
let query = new Parse.Query('Stuff');
910+
return query.find();
911+
}).then((res) => {
912+
fail("Should not succeed!");
913+
done();
914+
}, (e) => {
915+
expect(e.message).toEqual('Permission denied, user needs to be authenticated.');
916+
done();
917+
});
918+
});
919+
})

src/Schema.js

+19
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,25 @@ class Schema {
495495
return Promise.resolve();
496496
}
497497
var perms = this.perms[className][operation];
498+
499+
// If only for authenticated users
500+
// make sure we have an aclGroup
501+
if (perms['requiresAuthentication']) {
502+
// If aclGroup has * (public)
503+
if (!aclGroup || aclGroup.length == 0) {
504+
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND,
505+
'Permission denied, user needs to be authenticated.');
506+
} else if (aclGroup.indexOf('*') > -1 && aclGroup.length == 1) {
507+
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND,
508+
'Permission denied, user needs to be authenticated.');
509+
}
510+
// no other CLP than requiresAuthentication
511+
// let's resolve that!
512+
if (Object.keys(perms).length == 1) {
513+
return Promise.resolve();
514+
}
515+
}
516+
498517
// Handle the public scenario quickly
499518
if (perms['*']) {
500519
return Promise.resolve();

0 commit comments

Comments
 (0)