-
Notifications
You must be signed in to change notification settings - Fork 584
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
Align permission API's with Java/Swift #2036
Changes from 10 commits
596a2b9
1bbb6ca
af79225
7746f44
910f304
0ccf723
8f29f3d
0c1f9ce
de146ff
96e20c8
420a97f
2ade730
8c60a7c
c6de784
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -370,14 +370,37 @@ class Class { | |
/** | ||
* The name of the class which these permissions apply to. | ||
* @type {string} | ||
* @deprecated Use name() instead. | ||
*/ | ||
get class_name() {} | ||
|
||
/** | ||
* The name of the class which these permissions apply to. | ||
* @type {string} | ||
* @since 2.17.0 | ||
*/ | ||
get name() {} | ||
|
||
/** | ||
* The permissions for this class. | ||
* @type {Array<Realm.Permissions.Permission>} | ||
*/ | ||
get permissions() {} | ||
|
||
/** | ||
* Finds the Class-level permissions associated with the named Role. If either the role or the permission | ||
* object doesn't exists, it will be created. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "exists" -> "exist" |
||
* | ||
* If the Permission object is created because one didn't exist already, it will be | ||
* created with all privileges disabled. | ||
* | ||
* If the Role object is created because one didn't exists, it will be created | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "exists" -> "exist" |
||
* with no members. | ||
* | ||
* @type {Realm.Permissions.Permission} | ||
* @since 2.17.0 | ||
*/ | ||
findOrCreate(roleName) {} | ||
} | ||
|
||
/** | ||
|
@@ -389,9 +412,25 @@ class Class { | |
* @memberof Realm.Permissions | ||
*/ | ||
class Realm { | ||
|
||
/** | ||
* The permissions for the Realm. | ||
* @type {Array<Realm.Permissions.Permission>} | ||
*/ | ||
get permissions() {} | ||
|
||
/** | ||
* Finds the Realm-level permissions associated with the named Role. If either the role or the permission | ||
* object doesn't exists, it will be created. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "exists" -> "exist" |
||
* | ||
* If the Permission object is created because one didn't exist already, it will be | ||
* created with all privileges disabled. | ||
* | ||
* If the Role object is created because one didn't exists, it will be created | ||
* with no members. | ||
* | ||
* @type {Realm.Permissions.Permission} | ||
* @since 2.17.0 | ||
*/ | ||
findOrCreate(roleName) {} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -174,6 +174,17 @@ class Realm { | |
*/ | ||
privileges(arg) {} | ||
|
||
/** | ||
* Returns the fine-grained permissions object associated with either the Realm itself or a Realm model class. | ||
* | ||
* @param {Realm~ObjectType} [arg] - If no argument is provided, the Realm-level permissions are are returned. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "are are" -> "are" |
||
* Otherwise, the Class-level permissions for the provided type is returned. | ||
* @returns {Object} The permissions object | ||
* @since 2.17.0 | ||
* @see {Realm.Permissions} for details of priviliges and roles. | ||
*/ | ||
permissions(arg) {} | ||
|
||
/** | ||
* Create a new Realm object of the given type and with the specified properties. | ||
* @param {Realm~ObjectType} type - The type of Realm object to create. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -52,6 +52,47 @@ function waitForDownloadConfig(config) { | |
return config; | ||
} | ||
|
||
/** | ||
* Finds the permissions associated with a given Role or create them as needed. | ||
* | ||
* @param {RealmObject} Container RealmObject holding the permission list. | ||
* @param {List<Realm.Permissions.Permission>} list of permissions. | ||
* @param {string} name of the role to find or create permissions for. | ||
*/ | ||
function findOrCreatePermissionForRole(realmObject, permissions, roleName) { | ||
let realm = realmObject._realm; | ||
if (!realm.isInTransaction) { | ||
throw Error("'findOrCreate' can only be called inside a write transaction."); | ||
} | ||
let permissionsObj = permissions.filtered(`role.name = '${roleName}'`)[0]; | ||
if (permissionsObj === undefined) { | ||
let role = realm.objects("__Role").filtered(`name = '${roleName}'`)[0]; | ||
if (role === undefined) { | ||
role = realm.create("__Role", {'name': roleName}); | ||
} | ||
// Create new permissions object with all privileges disabled | ||
permissionsObj = realm.create("__Permission", { 'role': role }); | ||
permissions.push(permissionsObj); | ||
} | ||
return permissionsObj; | ||
} | ||
|
||
/** | ||
* Adds the schema object if one isn't already defined | ||
*/ | ||
function addSchemaIfNeeded(schemaList, schemaObj) { | ||
for (var i = 0; i < schemaList.length; i++) { | ||
const obj = schemaList[i]; | ||
if (obj === undefined) { | ||
continue; | ||
} | ||
if (schemaObj.name === obj.name || (obj.schema !== undefined && (schemaObj.name === obj.schema.name))) { | ||
return; | ||
} | ||
} | ||
schemaList.push(schemaObj); | ||
} | ||
|
||
module.exports = function(realmConstructor) { | ||
// Add the specified Array methods to the Collection prototype. | ||
Object.defineProperties(realmConstructor.Collection.prototype, require('./collection-methods')); | ||
|
@@ -61,8 +102,9 @@ module.exports = function(realmConstructor) { | |
setConstructorOnPrototype(realmConstructor.Results); | ||
setConstructorOnPrototype(realmConstructor.Object); | ||
|
||
//Add async open API | ||
//Add static methods to the Realm object | ||
Object.defineProperties(realmConstructor, getOwnPropertyDescriptors({ | ||
|
||
open(config) { | ||
// If no config is defined, we should just open the default realm | ||
if (config === undefined) { config = {}; } | ||
|
@@ -171,7 +213,6 @@ module.exports = function(realmConstructor) { | |
Object.defineProperty(realmConstructor.Sync.User, '_realmConstructor', { value: realmConstructor }); | ||
realmConstructor.Sync.Credentials = {}; | ||
Object.defineProperties(realmConstructor.Sync.Credentials, getOwnPropertyDescriptors(userMethods.credentials)); | ||
|
||
realmConstructor.Sync.AuthError = require('./errors').AuthError; | ||
|
||
if (realmConstructor.Sync.removeAllListeners) { | ||
|
@@ -221,7 +262,7 @@ module.exports = function(realmConstructor) { | |
} | ||
}; | ||
return config; | ||
} | ||
}; | ||
|
||
if (realmConstructor.Sync._setFeatureToken) { | ||
realmConstructor.Sync.setFeatureToken = function(featureToken) { | ||
|
@@ -242,18 +283,12 @@ module.exports = function(realmConstructor) { | |
Disconnected: "disconnected", | ||
Connecting: "connecting", | ||
Connected: "connected", | ||
} | ||
}; | ||
|
||
// Define the permission schemas as constructors so that they can be | ||
// passed into directly to functions which want object type names | ||
const permissionsSchema = Object.freeze({ | ||
Class: function() {}, | ||
Permission: function() {}, | ||
Realm: function() {}, | ||
Role: function() {}, | ||
User: function() {}, | ||
}); | ||
permissionsSchema.Permission.schema = Object.freeze({ | ||
const Permission = function() {}; | ||
Permission.schema = Object.freeze({ | ||
name: '__Permission', | ||
properties: { | ||
role: '__Role', | ||
|
@@ -267,7 +302,8 @@ module.exports = function(realmConstructor) { | |
} | ||
}); | ||
|
||
permissionsSchema.User.schema = Object.freeze({ | ||
const User = function() {}; | ||
User.schema = Object.freeze({ | ||
name: '__User', | ||
primaryKey: 'id', | ||
properties: { | ||
|
@@ -276,7 +312,8 @@ module.exports = function(realmConstructor) { | |
} | ||
}); | ||
|
||
permissionsSchema.Role.schema = Object.freeze({ | ||
const Role = function() {}; | ||
Role.schema = Object.freeze({ | ||
name: '__Role', | ||
primaryKey: 'name', | ||
properties: { | ||
|
@@ -285,31 +322,99 @@ module.exports = function(realmConstructor) { | |
} | ||
}); | ||
|
||
permissionsSchema.Class.schema = Object.freeze({ | ||
const Class = function() {}; | ||
Class.schema = Object.freeze({ | ||
name: '__Class', | ||
primaryKey: 'name', | ||
properties: { | ||
name: 'string', | ||
permissions: '__Permission[]' | ||
} | ||
}); | ||
Class.prototype.findOrCreate = function(roleName) { | ||
return findOrCreatePermissionForRole(this, this.permissions, roleName); | ||
}; | ||
|
||
permissionsSchema.Realm.schema = Object.freeze({ | ||
const Realm = function() {}; | ||
Realm.schema = Object.freeze({ | ||
name: '__Realm', | ||
primaryKey: 'id', | ||
properties: { | ||
id: 'int', | ||
permissions: '__Permission[]' | ||
} | ||
}); | ||
Realm.prototype.findOrCreate = function(roleName) { | ||
return findOrCreatePermissionForRole(this, this.permissions, roleName); | ||
}; | ||
|
||
const permissionsSchema = { | ||
'Class': Class, | ||
'Permission': Permission, | ||
'Realm': Realm, | ||
'Role': Role, | ||
'User': User, | ||
}; | ||
|
||
if (!realmConstructor.Permissions) { | ||
Object.defineProperty(realmConstructor, 'Permissions', { | ||
value: permissionsSchema, | ||
configurable: false | ||
}); | ||
} | ||
|
||
// Add instance methods to the Realm object that are only applied if Sync is | ||
Object.defineProperties(realmConstructor.prototype, getOwnPropertyDescriptors({ | ||
permissions(arg) { | ||
// If no argument is provided, return the Realm-level permissions | ||
if (arg === undefined) { | ||
return this.objects('__Realm').filtered(`id = 0`)[0]; | ||
} else { | ||
// Else try to find the corresponding Class-level permissions | ||
let schemaName = this._schemaName(arg); | ||
let classPermissions = this.objects('__Class').filtered(`name = '${schemaName}'`); | ||
if (classPermissions.length === 0) { | ||
throw Error(`Could not find Class-level permissions for '${schemaName}'`); | ||
} | ||
return classPermissions[0]; | ||
} | ||
}, | ||
})); | ||
} | ||
|
||
// Realm instance methods that are available always available | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove one "available" |
||
Object.defineProperties(realmConstructor.prototype, getOwnPropertyDescriptors({ | ||
|
||
/** | ||
* Extra internal constructor callback called by the C++ side. | ||
* Used to work around the fact that we cannot override the original constructor, | ||
* but still need to modify any input config. | ||
*/ | ||
_constructor(config) { | ||
// Even though this runs code only available for Sync it requires some serious misconfiguration | ||
// for this to happen | ||
if (config && config.sync) { | ||
if (!Realm.Sync) { | ||
throw new Error("Realm is not compiled with Sync, but the configuration contains sync features."); | ||
} | ||
// Only inject schemas on query-based Realms | ||
if (config.sync.partial === true || config.sync.fullSynchronization === false) { | ||
if (!config.schema) { | ||
config['schema'] = []; | ||
} | ||
|
||
addSchemaIfNeeded(config.schema, realmConstructor.Permissions.Class); | ||
addSchemaIfNeeded(config.schema, realmConstructor.Permissions.Permission); | ||
addSchemaIfNeeded(config.schema, realmConstructor.Permissions.Realm); | ||
addSchemaIfNeeded(config.schema, realmConstructor.Permissions.Role); | ||
addSchemaIfNeeded(config.schema, realmConstructor.Permissions.User); | ||
} | ||
} | ||
return config; | ||
}, | ||
})); | ||
|
||
|
||
// TODO: Remove this now useless object. | ||
var types = Object.freeze({ | ||
'BOOL': 'bool', | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please move
.
to end of sentence: "Added ... usingrealm.getPermissions()
. ([..."