Closed Taco55 closed 5 years ago
I think this is as simple as adding another predicate to the underlying Results
to not show permissions with no rights at all.
Unfortunately not, the corresponding RLMSyncPermissionValue
remains untouched...
This is the output:
Permission before revoke:
RLMSyncPermissionResults <0x174015dd0> (
[0] <RLMSyncPermissionValue> user ID: b581c38ea11000261bbd16bdd526e2b9, path: /3c53068695fc90c10ad2856acb4848d3/data, access level: write
)
Permission after revoke:
RLMSyncPermissionResults <0x170018db0> (
[0] <RLMSyncPermissionValue> user ID: b581c38ea11000261bbd16bdd526e2b9, path: /3c53068695fc90c10ad2856acb4848d3/data, access level: write
)
This permission should have been revoked, but apparently is not...
In the meanwhile, I also observed that sometimes not all permissions are retrieved with retrievePermission
(i.e. they differ from the permission Realm). Unfortunately, I couldn't find out when this is exactly the case, but it is probably related to the issue described above, which always occurs.
This seems like a server-side issue.
Can you provide us a reproduction case showing this issue please? I have not been able to reproduce this.
@austinzheng: I had some difficulty to find time for creating a reproduction case, and it took some time to discover where the issue exactly occurs in order to minimize the case. Hopefully, this case illustrates the problem.
Although it seems that permissions can be changed correctly, the output of retrievePermissions
is not updated accordingly. What does not help to validate this, is that the permission Realms seem not to be accessible with the RealmBrowser anymore? Is that correct?
The reproduction case of the project below can be used as follows:
AppDelegate.swift
AppDelegate.swift
user1
provides permission to user2
. The output will be like:
Permissions of user1
RLMSyncPermissionResults <0x7fb750c09b30> (
[0] <RLMSyncPermissionValue> user ID: 964ba21419474766d1778ae848622405, path: /964ba21419474766d1778ae848622405/permissiondemo, access level: admin,
[1] <RLMSyncPermissionValue> user ID: 14d34e6b3fcd20ff2aaec1cab94a9b94, path: /964ba21419474766d1778ae848622405/permissiondemo, access level: write
)
Permissions of user2
RLMSyncPermissionResults <0x7fb753a0fdf0> (
[0] <RLMSyncPermissionValue> user ID: 14d34e6b3fcd20ff2aaec1cab94a9b94, path: /964ba21419474766d1778ae848622405/permissiondemo, access level: write,
[1] <RLMSyncPermissionValue> user ID: 14d34e6b3fcd20ff2aaec1cab94a9b94, path: /14d34e6b3fcd20ff2aaec1cab94a9b94/permissiondemo, access level: admin
)
user1
provides permission to user2
again, but this permission is not updated correctly (even when the permission is not "reapplied", the permissions are not correctly retrieved):
Permissions of user1
RLMSyncPermissionResults <0x7fe970c08e40> (
[0] <RLMSyncPermissionValue> user ID: 964ba21419474766d1778ae848622405, path: /964ba21419474766d1778ae848622405/permissiondemo, access level: admin
)
Permissions of user2
RLMSyncPermissionResults <0x7fe970e125b0> (
[0] <RLMSyncPermissionValue> user ID: 14d34e6b3fcd20ff2aaec1cab94a9b94, path: /964ba21419474766d1778ae848622405/permissiondemo, access level: write,
[1] <RLMSyncPermissionValue> user ID: 14d34e6b3fcd20ff2aaec1cab94a9b94, path: /14d34e6b3fcd20ff2aaec1cab94a9b94/permissiondemo, access level: admin
)
Copy-paste the following code in AppDelegate.swift
import UIKit
import RealmSwift
struct HostConstants {
static let host = "localhost"
static let appPath = "permissiondemo"
static let syncServerURL = URL(string: "realm://\(host):9080/")!
static let realmURL = syncServerURL.appendingPathComponent("~/\(appPath)")
static let serverURL = URL(string: "http://\(host):9080")!
}
struct Credentials {
var id: String
var username: String
var password: String
init(username: String, password: String, id: String) {
self.username = username
self.password = password
self.id = id
}
}
let user1: Credentials = Credentials(username: "user1@test.com", password: "user1", id: "964ba21419474766d1778ae848622405")
let user2: Credentials = Credentials(username: "user2@test.com", password: "user2", id: "14d34e6b3fcd20ff2aaec1cab94a9b94")
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
SyncManager.shared.logLevel = .warn
let users = SyncUser.all
users.forEach{$0.value.logOut()}
self.initialize()
return true
}
func initialize() {
let credentials = SyncCredentials.usernamePassword(username: user1.username, password: user1.password, register: false)
SyncUser.logIn(with: credentials, server: HostConstants.serverURL) { realmUser, error in
if let error = error { print(error); return }
guard let user = realmUser else { return }
// Set default Realm
let configuration = Realm.Configuration(
inMemoryIdentifier: "inMemoryRealm",
syncConfiguration: SyncConfiguration(user: user, realmURL: HostConstants.realmURL),
schemaVersion: 1,
migrationBlock: { migration, oldSchemaVersion in }
)
Realm.Configuration.defaultConfiguration = configuration
// Open default Realm asynchronously to ensure that the Realm exists before permissions changed
// e.g. when the user is just created
Realm.asyncOpen(configuration: Realm.Configuration.defaultConfiguration) { realm, error in
// Change permission of user2
let components = HostConstants.realmURL.absoluteString.components(separatedBy: "/")
let realmPath = "/" + components[3] + "/" + components[4]
let permission = SyncPermissionValue(realmPath: realmPath, userID: user2.id, accessLevel: .write)
user.applyPermission(permission) { error in
if let error = error { print(error); return }
// Get permissions
SyncUser.current!.retrievePermissions { permissions, error in
if let error = error { print(error); return }
guard let permissions = permissions else { print("No permissions found"); return }
print("Permissions of user1\n", permissions)
self.loginUser2()
}
}
}
}
}
func loginUser2() {
if let user = SyncUser.current { user.logOut() }
let credentials = SyncCredentials.usernamePassword(username: user2.username, password: user2.password, register: false)
SyncUser.logIn(with: credentials, server: HostConstants.serverURL) { realmUser, error in
if let error = error { print(error); return }
guard let user = realmUser else { return }
// Set default Realm
let configuration = Realm.Configuration(
inMemoryIdentifier: "inMemoryRealm",
syncConfiguration: SyncConfiguration(user: user, realmURL: HostConstants.realmURL),
schemaVersion: 1,
migrationBlock: { migration, oldSchemaVersion in }
)
Realm.Configuration.defaultConfiguration = configuration
// Open default Realm asynchronously to ensure that the Realm exists before permissions changed
// e.g. when the user is just created
Realm.asyncOpen(configuration: Realm.Configuration.defaultConfiguration) { realm, error in
// Get permissions
SyncUser.current!.retrievePermissions { permissions, error in
if let error = error { print(error); return }
guard let permissions = permissions else { print("No permissions found"); return }
print("Permissions of user2\n",permissions)
}
}
}
}
}
In addition to my previous comment, I made a more detailed observation. In the following example user1 provides (write) permission to user2 and user3.
When retrievePermission
is used to determine the permissions the output is:
When user1 reapplies permission to user2 and user3, the output is:
This confirms that retrievePermission
does not provide the permission status of a SyncUser
reliable.
Currently, this issue is tagged as "Help", but I am quite confident that this is an ordinary bug.
The exact output of the code below this post is:
First run:
Permissions of user1@test.com (id: 2ab50442b446c9ad74cd9676fb149727:
RLMSyncPermissionResults <0x7fcfa840def0> (
[0] <RLMSyncPermissionValue> user ID: 2ab50442b446c9ad74cd9676fb149727, path: /2ab50442b446c9ad74cd9676fb149727/permissiondemo, access level: admin,
[1] <RLMSyncPermissionValue> user ID: 5183569e0ac9cccd2d1dc6ff3310e7cd, path: /2ab50442b446c9ad74cd9676fb149727/permissiondemo, access level: write
)
Permissions of user2@test.com (id: 5183569e0ac9cccd2d1dc6ff3310e7cd:
RLMSyncPermissionResults <0x7fcfaa80d9c0> (
[0] <RLMSyncPermissionValue> user ID: 5183569e0ac9cccd2d1dc6ff3310e7cd, path: /2ab50442b446c9ad74cd9676fb149727/permissiondemo, access level: write,
[1] <RLMSyncPermissionValue> user ID: 5183569e0ac9cccd2d1dc6ff3310e7cd, path: /5183569e0ac9cccd2d1dc6ff3310e7cd/permissiondemo, access level: admin
)
Permissions of user3@test.com (id: d80eb421a5e4f00aa3606cb6118e6123:
RLMSyncPermissionResults <0x7fcfaa80d780> (
[0] <RLMSyncPermissionValue> user ID: d80eb421a5e4f00aa3606cb6118e6123, path: /2ab50442b446c9ad74cd9676fb149727/permissiondemo, access level: write,
[1] <RLMSyncPermissionValue> user ID: d80eb421a5e4f00aa3606cb6118e6123, path: /d80eb421a5e4f00aa3606cb6118e6123/permissiondemo, access level: admin
)
Second run (after reapplying permissions):
Permissions of user1@test.com (id: 2ab50442b446c9ad74cd9676fb149727:
RLMSyncPermissionResults <0x7faf55907090> (
[0] <RLMSyncPermissionValue> user ID: 2ab50442b446c9ad74cd9676fb149727, path: /2ab50442b446c9ad74cd9676fb149727/permissiondemo, access level: admin,
[1] <RLMSyncPermissionValue> user ID: d80eb421a5e4f00aa3606cb6118e6123, path: /2ab50442b446c9ad74cd9676fb149727/permissiondemo, access level: write
)
Permissions of user2@test.com (id: 5183569e0ac9cccd2d1dc6ff3310e7cd:
RLMSyncPermissionResults <0x7faf55904eb0> (
[0] <RLMSyncPermissionValue> user ID: 5183569e0ac9cccd2d1dc6ff3310e7cd, path: /5183569e0ac9cccd2d1dc6ff3310e7cd/permissiondemo, access level: admin
)
Permissions of user3@test.com (id: d80eb421a5e4f00aa3606cb6118e6123:
RLMSyncPermissionResults <0x7faf5270b470> (
[0] <RLMSyncPermissionValue> user ID: d80eb421a5e4f00aa3606cb6118e6123, path: /2ab50442b446c9ad74cd9676fb149727/permissiondemo, access level: write,
[1] <RLMSyncPermissionValue> user ID: d80eb421a5e4f00aa3606cb6118e6123, path: /d80eb421a5e4f00aa3606cb6118e6123/permissiondemo, access level: admin
)
AppDelegate.swift
import UIKit
import RealmSwift
struct HostConstants {
static let host = "localhost"
static let appPath = "permissiondemo"
static let syncServerURL = URL(string: "realm://\(host):9080/")!
static let realmURL = syncServerURL.appendingPathComponent("~/\(appPath)")
static let serverURL = URL(string: "http://\(host):9080")!
}
struct Credentials {
var id: String
var username: String
var password: String
init(username: String, password: String, id: String) {
self.username = username
self.password = password
self.id = id
}
}
let user1: Credentials = Credentials(username: "user1@test.com", password: "user1", id: "2ab50442b446c9ad74cd9676fb149727")
let user2: Credentials = Credentials(username: "user2@test.com", password: "user2", id: "5183569e0ac9cccd2d1dc6ff3310e7cd")
let user3: Credentials = Credentials(username: "user3@test.com", password: "user3", id: "d80eb421a5e4f00aa3606cb6118e6123")
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
SyncManager.shared.logLevel = .warn
SyncUser.all.forEach{$0.value.logOut()}
// Set permissions and retrieve permissions for all users
self.setPermissionUser1() {
self.retrievePermission(for: user1) {
self.retrievePermission(for: user2) {
self.retrievePermission(for: user3) {
}
}
}
}
return true
}
func setPermissionUser1(completionHandler: (() -> ())? ) {
let credentials = SyncCredentials.usernamePassword(username: user1.username, password: user1.password, register: false)
SyncUser.logIn(with: credentials, server: HostConstants.serverURL) { realmUser, error in
if let error = error { print(error); return }
// Ensure that a Realm exists before permissions are changed
guard let user = realmUser else { return }
let config = self.getRealmConfiguration(for:user)
Realm.asyncOpen(configuration: config) { realm, error in
let components = HostConstants.realmURL.absoluteString.components(separatedBy: "/")
let realmPath = "/" + components[3] + "/" + components[4]
// Change permission of user2
let permission = SyncPermissionValue(realmPath: realmPath, userID: user2.id, accessLevel: .write)
user.applyPermission(permission) { error in
if let error = error { print(error); return }
// Change permission of user3
let permission = SyncPermissionValue(realmPath: realmPath, userID: user3.id, accessLevel: .write)
user.applyPermission(permission) { error in
if let error = error { print(error); return }
completionHandler?()
}
}
}
}
}
func retrievePermission(for customuser: Credentials, completionHandler: (() -> ())?) {
if let user = SyncUser.current { user.logOut() }
let credentials = SyncCredentials.usernamePassword(username: customuser.username, password: customuser.password, register: false)
SyncUser.logIn(with: credentials, server: HostConstants.serverURL) { realmUser, error in
if let error = error { print(error); return }
// Ensure that a Realm exists before permissions are changed
guard let user = realmUser else { return }
let config = self.getRealmConfiguration(for:user)
Realm.asyncOpen(configuration: config) { realm, error in
// Get permissions
SyncUser.current!.retrievePermissions { permissions, error in
if let error = error { print(error); return }
guard let permissions = permissions else { print("No permissions found"); return }
print("Permissions of \(customuser.username) (id: \(customuser.id):\n", permissions)
completionHandler?()
}
}
}
}
func getRealmConfiguration(for user: SyncUser) -> Realm.Configuration {
let configuration = Realm.Configuration(
inMemoryIdentifier: "inMemoryRealm",
syncConfiguration: SyncConfiguration(user: user, realmURL: HostConstants.realmURL),
schemaVersion: 1,
migrationBlock: { migration, oldSchemaVersion in }
)
return configuration
}
}
Thanks for the data. The Realm Object Server team is aware that there is a bug with retrieving permissions and are working on fixing it. If I have any further information to share I'll post in this thread.
If i try to create several synced realms together and then asks for retrievePermissions
only first is returned. I have to dispatch them async one after another to make it work. Seems related.
@austinzheng @APUtils @Taco55 Is this still a problem with ROS 2.0?
To elaborate, ROS 2.0's permissions system was rewritten from ground up, so this problem should be gone now. If it's still around we'd be very interested in any reports, so we can figure out how to fix it.
Sorry for my late reply. Unfortunately, I had to stop using ROS due to this and other issues. With the recent updates I just tried it again and spent several hours on the permission functionality. Although applying permissions work well now, revoking permissions does still not work correctly (or they are not retrieved correctly).
This is quite disappointing and it feels that it has not been tested thoroughly.
I created a new example for ROS 2.6.0 and Swift 3.1. Since this issue is already closed and the permission system is rewritten (and the issue might be different now), I opened a new issue at #334.
Issue moved to realm/docs-platform #249 via ZenHub
I think I mixed things up. Apologize. Re-opening.
Issue moved to realm/docs-platform #250 via ZenHub
The new "Transfer Issue" from github does not work well with zenhub yet. It appears in zenhub as if this issue is still in another repo, but it's not.
Goals
To retrieve the (remaining) permissions of a specific realm after a permission has been revoked using the
retrievePermissions
method in theSyncUser
classExpected Results
Correct update of
RLMSyncPermissionResults
after a permission is revoked withretrievePermissions
Actual Results
Although revoking a permission seems to work correctly (as determined by the Permission Realm using the browser and indicated by the realm-object-server.log below), the 'RLMSyncPermissionResults` is not updated correctly.
Steps to Reproduce
SyncUser
has (read or write) permission to a Realm that he doesn't own. In my case, the permission was provided usingSyncPermissionOffer
.Code Sample
Version of Realm and Tooling
Logs
cat /var/log/realm-object-server.log
1310, scan_server_version=63, scan_client_version=13, latest_server_version=63, latest_server_session_ident=8294238167544798846) 2017-07-31T19:25:57.104Z - info: management: Succeed processing PermissionChange(id='%s...') 2017-07-31T19:25:57.129Z - info: sync-client: Opening Realm file: /var/lib/realm/object-server/internal_data/permission/b581c38ea11000261bbd16bdd526e2b9.realm 2017-07-31T19:25:57.129Z - info: sync-client: Connection[146]: Session[146]: Starting session for '/var/lib/realm/object-server/internal_data/permission/b581c38ea11000261bbd16bdd526e2b9.realm' 2017-07-31T19:25:57.130Z - info: sync-client: Connection[146]: Resolving ':::9080' 2017-07-31T19:25:57.130Z - info: sync-client: Connection[146]: Connecting to endpoint ':::9080' (1/1) 2017-07-31T19:25:57.130Z - info: sync-client: Connection[146]: Connected to endpoint ':::9080' (from '::1:43338') 2017-07-31T19:25:57.130Z - info: sync-client: Opening Realm file: /var/lib/realm/object-server/internal_data/permission/3c53068695fc90c10ad2856acb4848d3.realm 2017-07-31T19:25:57.131Z - info: sync-client: Connection[147]: Session[147]: Starting session for '/var/lib/realm/object-server/internal_data/permission/3c53068695fc90c10ad2856acb4848d3.realm' 2017-07-31T19:25:57.131Z - info: sync-client: Connection[147]: Resolving ':::9080' 2017-07-31T19:25:57.131Z - info: sync-client: Connection[147]: Connecting to endpoint ':::9080' (1/1) 2017-07-31T19:25:57.131Z - info: sync-client: Connection[147]: Connected to endpoint ':::9080' (from '::1:43340') 2017-07-31T19:25:57.140Z - info: sync: HTTP Connection[1163]: Connection from 127.0.0.1:35052 2017-07-31T19:25:57.141Z - info: sync: HTTP Connection[1164]: Connection from 127.0.0.1:35054 2017-07-31T19:25:57.141Z - info: sync: HTTP Connection[1163]: Received: Sync HTTP request(protocol_version=18) 2017-07-31T19:25:57.142Z - info: sync: HTTP Connection[1164]: Received: Sync HTTP request(protocol_version=18) 2017-07-31T19:25:57.143Z - info: sync-client: Connection[146]: Session[146]: Sending: BIND(server_path='/b581c38ea11000261bbd16bdd526e2b9/__permission', signed_user_token_size=469, need_file_ident_pair=0) 2017-07-31T19:25:57.143Z - info: sync-client: Connection[146]: Session[146]: Sending: IDENT(server_file_ident=1, client_file_ident=2, client_file_ident_secret=1981266536871627121, scan_server_version=63, scan_client_version=119, latest_server_version=63, latest_server_session_ident=2709820532315415532) 2017-07-31T19:25:57.144Z - info: sync-client: Connection[147]: Session[147]: Sending: BIND(server_path='/3c53068695fc90c10ad2856acb4848d3/__permission', signed_user_token_size=469, need_file_ident_pair=0) 2017-07-31T19:25:57.144Z - info: sync-client: Connection[147]: Session[147]: Sending: IDENT(server_file_ident=1, client_file_ident=2, client_file_ident_secret=5285274318804938393, scan_server_version=59, scan_client_version=116, latest_server_version=59, latest_server_session_ident=8344419782827238655) 2017-07-31T19:25:57.145Z - info: sync: Sync Connection[1163]: Session[146]: Session initiated (session_ident=146). 2017-07-31T19:25:57.145Z - info: sync: Sync Connection[1163]: Session[146]: Received: BIND(server_path=/b581c38ea11000261bbd16bdd526e2b9/__permission, signed_user_token='...ySl98JOzZEMC49sp8UaJxR5a6pIA==', need_file_ident_pair=0) 2017-07-31T19:25:57.146Z - info: sync: Sync Connection[1164]: Session[147]: Session initiated (session_ident=147). 2017-07-31T19:25:57.146Z - info: sync: Sync Connection[1164]: Session[147]: Received: BIND(server_path=/3c53068695fc90c10ad2856acb4848d3/__permission, signed_user_token='...ySl98JOzZEMC49sp8UaJxR5a6pIA==', need_file_ident_pair=0) 2017-07-31T19:25:57.170Z - info: sync: Sync Connection[1161]: Session[87]: Session terminated (session_ident=87). 2017-07-31T19:25:57.170Z - info: sync: Sync Connection[1161]: Connection closed by client: End of input 2017-07-31T19:25:57.181Z - info: sync: Sync Connection[1164]: Session[147]: Received: IDENT(server_file_ident=1, client_file_ident=2, client_file_ident_secret=5285274318804938393, scan_server_version=59, scan_client_version=116, latest_server_version=59, latest_server_session_ident=8344419782827238655) 2017-07-31T19:25:57.185Z - info: sync: Sync Connection[1163]: Session[146]: Received: IDENT(server_file_ident=1, client_file_ident=2, client_file_ident_secret=1981266536871627121, scan_server_version=63, scan_client_version=119, latest_server_version=63, latest_server_session_ident=2709820532315415532) 2017-07-31T19:25:57.189Z - info: sync: Sync Connection[1162]: Session[89]: Session terminated (session_ident=89). 2017-07-31T19:25:57.189Z - info: sync: Sync Connection[1162]: Connection closed by client: End of input 2017-07-31T19:25:57.221Z - info: sync-client: Closing Realm file: /var/lib/realm/object-server/internal_data/permission/3c53068695fc90c10ad2856acb4848d3.realm 2017-07-31T19:25:57.221Z - info: sync-client: Connection[147]: Session[147]: Sending: UNBIND 2017-07-31T19:25:57.222Z - info: sync: Sync Connection[1164]: Session[147]: Session terminated (session_ident=147). 2017-07-31T19:25:57.222Z - info: sync: Sync Connection[1164]: Connection closed by client: End of input 2017-07-31T19:25:57.225Z - info: sync-client: Closing Realm file: /var/lib/realm/object-server/internal_data/permission/b581c38ea11000261bbd16bdd526e2b9.realm 2017-07-31T19:25:57.225Z - info: sync-client: Connection[146]: Session[146]: Sending: UNBIND 2017-07-31T19:25:57.226Z - info: sync: Sync Connection[1163]: Session[146]: Session terminated (session_ident=146). 2017-07-31T19:25:57.226Z - info: sync: Sync Connection[1163]: Connection closed by client: End of input