-
-
Notifications
You must be signed in to change notification settings - Fork 206
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
ACL broken? #226
Comments
Hello @manhhavu final acl = ParseACL(owner: user);
acl.setPublicReadAccess(allowed: false);
acl.setPublicWriteAccess(allowed: false); The ACL result will contain only the read and write Owner id. "ACL":{"yCTHkRGfmO":{"read":true,"write":true}} |
Hi @RodrigoSMarques , Thanks for your quick reply. Actually, I might not be very clear in my initial question (I've corrected it a little bit). I've rewritten the initial test into two scenarios to be more precise about the issue (at least I hope so).
Please tell me if I missed something. There are the code of two tests, the screenshot of Parse Dashboard and the tests' execution results below: import 'package:parse_server_sdk/parse_server_sdk.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:test_api/test_api.dart';
import 'package:uuid/uuid.dart';
class TestObject extends ParseObject implements ParseCloneable {
static const String _keyTableName = 'TestObject';
static const String _keyName = 'Name';
TestObject() : super(_keyTableName);
TestObject.clone() : this();
String get name => get<String>(_keyName);
set name(String name) => set<String>(_keyName, name);
@override
clone(Map map) => TestObject.clone()..fromJson(map);
}
void main() {
const endpoint = 'https://<parse_endpoint>';
setUp(() async {
// Preferences needed by Parse SDK
SharedPreferences.setMockInitialValues({});
await Parse().initialize(
'<client_name>',
'$endpoint/parse/',
autoSendSessionId: true,
);
});
test('ACL should limit access for objects', () async {
await ParseUser.loginWith('anonymous', {'id': Uuid().v4()});
final user = await ParseUser.currentUser() as ParseUser;
await user.save();
expect(user, isNotNull);
final acl = ParseACL(owner: user);
acl.setPublicReadAccess(allowed: false);
acl.setPublicWriteAccess(allowed: false);
TestObject object1 = TestObject();
object1.name = 'Belong to user';
object1.setACL(acl);
await object1.save();
expect(object1.getACL().getPublicReadAccess(), isFalse);
expect(object1.getACL().getPublicWriteAccess(), isFalse);
// Same object1 retrieved from server
TestObject object1FromServer = (await retrieveAll()).first;
// Check if the same object
expect(object1.objectId, equals(object1FromServer.objectId));
print('ObjectID = ${object1.objectId}');
// Even these assertions pass but in the Parse Dashboard, they are
// 'Public Read + Public Write', screenshot is below
expect(object1FromServer.getACL().getPublicReadAccess(), isFalse);
expect(object1FromServer.getACL().getPublicWriteAccess(), isFalse);
// Suprisingly, these assertions failed.
expect(
object1FromServer.getACL().getReadAccess(userId: user.objectId), isTrue,
reason: "user should be able to read object1");
expect(object1FromServer.getACL().getWriteAccess(userId: user.objectId),
isTrue,
reason: "user should be able to write object1");
}, timeout: new Timeout(new Duration(minutes: 2)));
test(
'Object limited with a not public access ACL should not be seen by other user',
() async {
// User1 #
await ParseUser.loginWith('anonymous', {'id': Uuid().v4()});
final user1 = await ParseUser.currentUser() as ParseUser;
await user1.save();
final acl = ParseACL(owner: user1);
acl.setPublicReadAccess(allowed: false);
acl.setPublicWriteAccess(allowed: false);
TestObject object1 = TestObject();
object1.name = 'Belong to user';
object1.setACL(acl);
await object1.save();
expect(object1.getACL().getPublicReadAccess(), isFalse);
expect(object1.getACL().getPublicWriteAccess(), isFalse);
// User1 sign out
user1.logout(deleteLocalUserData: true);
// User 2 #
await ParseUser.loginWith('anonymous', {'id': Uuid().v4()});
final user2 = await ParseUser.currentUser() as ParseUser;
await user2.save();
expect(user1.objectId != user2.objectId, isTrue);
// Retrieve objects seen by user2
final list = await retrieveAll();
// Make sure user2's objects does not contain object 1
for (var o in list) {
expect(o.objectId != object1.objectId, isTrue,
reason: "User2 should not be able see object1");
}
}, timeout: new Timeout(new Duration(minutes: 2)));
}
Future<List<TestObject>> retrieveAll() async {
final response = await TestObject().getAll();
return response.results.map((el) => el as TestObject).toList();
}
Parse Dashboard screenshot, object1's ACL is Public Read+Public Write First test execution
Second test execution
|
what version of lib are you using? |
I'm using the lib's version 1.0.22 in Flutter v1.7.8+hotfix.3 |
Hi @manhhavu Do the test in version 1.0.21 and report the result. parse_server_sdk: '1.0.21' |
Re @RodrigoSMarques , I've tested the 1.0.21 as you suggested but I always have the same problem. It seems that the ACL is not included in the request being sent to the server. I've activated the debug mode the SDK and here the log:
You can see that the request payload does not include at all ACL section. (Curious enough, the response log includes ACL which does not make sense. I think it just the returns the initial object.) You said that you have no problem with this version 1.0.21. Do you use ACL in your project and do you have any particular configuration? Thanks, |
I think that I might find the bug:
final Map<String, dynamic> target = forApiRQ
? _unsavedChanges
: _getObjectData(); So, when forApiRQ = true, target = _unsavedChanges. void setACL<ParseACL>(ParseACL acl) {
_getObjectData()[keyVarAcl] = acl;
} We can see that only the map in _getObjectData() is changed but the ACL is never added to _unsavedChanges, so it will never get sent to the server, then never be saved. void setACL<ParseACL>(ParseACL acl) {
// The set method updates _getObjectData()
// and the _unsavedChanges at the same time
set(keyVarAcl, acl);
} I've tested this code snippet and it actually passed my unit tests above. Can you confirm my hypothesis above? If it is the case, I'd not mind to create a PR. 😃 |
Hi @manhhavu. ParseACL parseACL = ParseACL(owner: currentUser);
parseACL.setPublicReadAccess(allowed: true);
parseACL.setPublicWriteAccess(allowed: false); I did the test with your change and it is working. You can send the PR to branch 1.0.23 |
Hi @RodrigoSMarques , PR sent 😃 |
Hi,
It seems that ACL for an object is saved incorrectly. Even if I set explicitly an ACL for an object, the object is always considered Public Read + Public Write.
Here is a sample code:
and its execution's result:
you can see the one returned by the query does not contains ACL at all.
It looks like a lot the problem mentioned in issue #129 but I supposed it was fixed. So it must be something else then?
Thanks,
The text was updated successfully, but these errors were encountered: