Skip to content

Commit 1e2af2c

Browse files
committed
Adds class level permission requiring authenticated user
1 parent 676d2e2 commit 1e2af2c

File tree

2 files changed

+232
-0
lines changed

2 files changed

+232
-0
lines changed

spec/Schema.spec.js

Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -799,3 +799,216 @@ describe('SchemaController', () => {
799799
done();
800800
});
801801
});
802+
803+
describe('Class Level Permissions for requiredAuth', () => {
804+
805+
function createUser() {
806+
let user = new Parse.User();
807+
user.set("username", "hello");
808+
user.set("password", "world");
809+
return user.signUp(null);
810+
}
811+
it('required auth test find', (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+
'find': {
818+
'requiresAuthentication': true
819+
}
820+
});
821+
}).then((schema) => {
822+
var query = new Parse.Query('Stuff');
823+
return query.find();
824+
}).then((results) => {
825+
fail('Class permissions should have rejected this query.');
826+
done();
827+
}, (e) => {
828+
expect(e.message).toEqual('Permission denied, user needs to be authenticated.');
829+
done();
830+
});
831+
});
832+
833+
it('required auth test find authenticated', (done) => {
834+
config.database.loadSchema().then((schema) => {
835+
// Just to create a valid class
836+
return schema.validateObject('Stuff', {foo: 'bar'});
837+
}).then((schema) => {
838+
return schema.setPermissions('Stuff', {
839+
'find': {
840+
'requiresAuthentication': true
841+
}
842+
});
843+
}).then((schema) => {
844+
return createUser();
845+
}).then((user) => {
846+
var query = new Parse.Query('Stuff');
847+
return query.find();
848+
}).then((results) => {
849+
expect(results.length).toEqual(0);
850+
done();
851+
}, (e) => {
852+
console.error(e);
853+
fail("Should not have failed");
854+
done();
855+
});
856+
});
857+
858+
it('required auth test create authenticated', (done) => {
859+
config.database.loadSchema().then((schema) => {
860+
// Just to create a valid class
861+
return schema.validateObject('Stuff', {foo: 'bar'});
862+
}).then((schema) => {
863+
return schema.setPermissions('Stuff', {
864+
'create': {
865+
'requiresAuthentication': true
866+
}
867+
});
868+
}).then((schema) => {
869+
return createUser();
870+
}).then((user) => {
871+
let stuff = new Parse.Object('Stuff');
872+
stuff.set('foo', 'bar');
873+
return stuff.save();
874+
}).then((savedObject) => {
875+
done();
876+
}, (e) => {
877+
console.error(e);
878+
fail("Should not have failed");
879+
done();
880+
});
881+
});
882+
883+
it('required auth test create authenticated', (done) => {
884+
config.database.loadSchema().then((schema) => {
885+
// Just to create a valid class
886+
return schema.validateObject('Stuff', {foo: 'bar'});
887+
}).then((schema) => {
888+
return schema.setPermissions('Stuff', {
889+
'create': {
890+
'requiresAuthentication': true
891+
}
892+
});
893+
}).then((user) => {
894+
let stuff = new Parse.Object('Stuff');
895+
stuff.set('foo', 'bar');
896+
return stuff.save();
897+
}).then((results) => {
898+
fail('Class permissions should have rejected this query.');
899+
done();
900+
}, (e) => {
901+
expect(e.message).toEqual('Permission denied, user needs to be authenticated.');
902+
done();
903+
});
904+
});
905+
906+
it('required auth test create/get/update/delete authenticated', (done) => {
907+
config.database.loadSchema().then((schema) => {
908+
// Just to create a valid class
909+
return schema.validateObject('Stuff', {foo: 'bar'});
910+
}).then((schema) => {
911+
return schema.setPermissions('Stuff', {
912+
'create': {
913+
'requiresAuthentication': true
914+
},
915+
'get': {
916+
'requiresAuthentication': true
917+
},
918+
'delete': {
919+
'requiresAuthentication': true
920+
},
921+
'update': {
922+
'requiresAuthentication': true
923+
}
924+
});
925+
}).then((schema) => {
926+
return createUser();
927+
}).then((user) => {
928+
let stuff = new Parse.Object('Stuff');
929+
stuff.set('foo', 'bar');
930+
return stuff.save().then(() => {
931+
let query = new Parse.Query('Stuff');
932+
return query.get(stuff.id);
933+
});
934+
}).then((gotStuff) => {
935+
gotStuff.save({'foo': 'baz'}).then(() => {
936+
return gotStuff.destroy();
937+
})
938+
}).then(() => {
939+
done();
940+
}, (e) => {
941+
console.error(e);
942+
fail("Should not have failed");
943+
done();
944+
});
945+
});
946+
947+
it('required auth test create/get/update/delete not authenitcated', (done) => {
948+
config.database.loadSchema().then((schema) => {
949+
// Just to create a valid class
950+
return schema.validateObject('Stuff', {foo: 'bar'});
951+
}).then((schema) => {
952+
return schema.setPermissions('Stuff', {
953+
'get': {
954+
'requiresAuthentication': true
955+
},
956+
'delete': {
957+
'requiresAuthentication': true
958+
},
959+
'update': {
960+
'requiresAuthentication': true
961+
}
962+
});
963+
}).then((user) => {
964+
let stuff = new Parse.Object('Stuff');
965+
stuff.set('foo', 'bar');
966+
return stuff.save().then(() => {
967+
let query = new Parse.Query('Stuff');
968+
return query.get(stuff.id);
969+
});
970+
}).then((res) => {
971+
fail("Should not succeed!");
972+
done();
973+
}, (e) => {
974+
expect(e.message).toEqual('Permission denied, user needs to be authenticated.');
975+
done();
976+
});
977+
});
978+
979+
it('required auth test create/get/update/delete not authenitcated', (done) => {
980+
config.database.loadSchema().then((schema) => {
981+
// Just to create a valid class
982+
return schema.validateObject('Stuff', {foo: 'bar'});
983+
}).then((schema) => {
984+
return schema.setPermissions('Stuff', {
985+
'find': {
986+
'requiresAuthentication': true
987+
},
988+
'delete': {
989+
'requiresAuthentication': true
990+
},
991+
'update': {
992+
'requiresAuthentication': true
993+
}
994+
});
995+
}).then((user) => {
996+
let stuff = new Parse.Object('Stuff');
997+
stuff.set('foo', 'bar');
998+
return stuff.save().then(() => {
999+
let query = new Parse.Query('Stuff');
1000+
return query.get(stuff.id);
1001+
})
1002+
}).then((result) => {
1003+
expect(result.get('foo')).toEqual('bar');
1004+
let query = new Parse.Query('Stuff');
1005+
return query.find();
1006+
}).then((res) => {
1007+
fail("Should not succeed!");
1008+
done();
1009+
}, (e) => {
1010+
expect(e.message).toEqual('Permission denied, user needs to be authenticated.');
1011+
done();
1012+
});
1013+
});
1014+
})

src/Controllers/SchemaController.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,25 @@ class SchemaController {
676676
}
677677
let classPerms = this.perms[className];
678678
let perms = classPerms[operation];
679+
680+
// If only for authenticated users
681+
// make sure we have an aclGroup
682+
if (perms['requiresAuthentication']) {
683+
// If aclGroup has * (public)
684+
if (!aclGroup || aclGroup.length == 0) {
685+
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND,
686+
'Permission denied, user needs to be authenticated.');
687+
} else if (aclGroup.indexOf('*') > -1 && aclGroup.length == 1) {
688+
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND,
689+
'Permission denied, user needs to be authenticated.');
690+
}
691+
// no other CLP than requiresAuthentication
692+
// let's resolve that!
693+
if (Object.keys(perms).length == 1) {
694+
return Promise.resolve();
695+
}
696+
}
697+
679698
// No matching CLP, let's check the Pointer permissions
680699
// And handle those later
681700
let permissionField = ['get', 'find'].indexOf(operation) > -1 ? 'readUserFields' : 'writeUserFields';

0 commit comments

Comments
 (0)