RLMSyncPermission.h 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502
  1. ////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright 2017 Realm Inc.
  4. //
  5. // Licensed under the Apache License, Version 2.0 (the "License");
  6. // you may not use this file except in compliance with the License.
  7. // You may obtain a copy of the License at
  8. //
  9. // http://www.apache.org/licenses/LICENSE-2.0
  10. //
  11. // Unless required by applicable law or agreed to in writing, software
  12. // distributed under the License is distributed on an "AS IS" BASIS,
  13. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. // See the License for the specific language governing permissions and
  15. // limitations under the License.
  16. //
  17. ////////////////////////////////////////////////////////////////////////////
  18. #import <Realm/RLMConstants.h>
  19. #import <Realm/RLMObject.h>
  20. @protocol RLMPermission, RLMPermissionUser;
  21. @class RLMPermission, RLMPermissionUser, RLMPermissionRole,
  22. RLMArray<RLMObjectType>, RLMLinkingObjects<RLMObjectType: RLMObject *>;
  23. NS_ASSUME_NONNULL_BEGIN
  24. /**
  25. A permission which can be applied to a Realm, Class, or specific Object.
  26. Permissions are applied by adding the permission to the RLMRealmPermission singleton
  27. object, the RLMClassPermission object for the desired class, or to a user-defined
  28. RLMArray<RLMPermission> property on a specific Object instance. The meaning of each of
  29. the properties of RLMPermission depend on what the permission is applied to, and so are
  30. left undocumented here. See `RLMRealmPrivileges`, `RLMClassPrivileges`, and
  31. `RLMObjectPrivileges` for details about what each of the properties mean when applied to
  32. that type.
  33. */
  34. @interface RLMPermission : RLMObject
  35. /// The Role which this Permission applies to. All users within the Role are
  36. /// granted the permissions specified by the fields below any
  37. /// objects/classes/realms which use this Permission.
  38. ///
  39. /// This property cannot be modified once set.
  40. @property (nonatomic) RLMPermissionRole *role;
  41. /// Whether the user can read the object to which this Permission is attached.
  42. @property (nonatomic) bool canRead;
  43. /// Whether the user can modify the object to which this Permission is attached.
  44. @property (nonatomic) bool canUpdate;
  45. /// Whether the user can delete the object to which this Permission is attached.
  46. ///
  47. /// This field is only applicable to Permissions attached to Objects, and not
  48. /// to Realms or Classes.
  49. @property (nonatomic) bool canDelete;
  50. /// Whether the user can add or modify Permissions for the object which this
  51. /// Permission is attached to.
  52. @property (nonatomic) bool canSetPermissions;
  53. /// Whether the user can subscribe to queries for this object type.
  54. ///
  55. /// This field is only applicable to Permissions attached to Classes, and not
  56. /// to Realms or Objects.
  57. @property (nonatomic) bool canQuery;
  58. /// Whether the user can create new objects of the type this Permission is attached to.
  59. ///
  60. /// This field is only applicable to Permissions attached to Classes, and not
  61. /// to Realms or Objects.
  62. @property (nonatomic) bool canCreate;
  63. /// Whether the user can modify the schema of the Realm which this
  64. /// Permission is attached to.
  65. ///
  66. /// This field is only applicable to Permissions attached to Realms, and not
  67. /// to Realms or Objects.
  68. @property (nonatomic) bool canModifySchema;
  69. /**
  70. Returns the Permission object for the named Role in the array, creating it if needed.
  71. This function should be used in preference to manually querying the array for
  72. the applicable Permission as it ensures that there is exactly one Permission
  73. for the given Role in the array, merging duplicates or creating and adding new
  74. ones as needed.
  75. */
  76. + (RLMPermission *)permissionForRoleNamed:(NSString *)roleName inArray:(RLMArray<RLMPermission *><RLMPermission> *)array;
  77. /**
  78. Returns the Permission object for the named Role on the Realm, creating it if needed.
  79. This function should be used in preference to manually querying for the
  80. applicable Permission as it ensures that there is exactly one Permission for
  81. the given Role on the Realm, merging duplicates or creating and adding new ones
  82. as needed.
  83. */
  84. + (RLMPermission *)permissionForRoleNamed:(NSString *)roleName onRealm:(RLMRealm *)realm;
  85. /**
  86. Returns the Permission object for the named Role on the Class, creating it if needed.
  87. This function should be used in preference to manually querying for the
  88. applicable Permission as it ensures that there is exactly one Permission for
  89. the given Role on the Class, merging duplicates or creating and adding new ones
  90. as needed.
  91. */
  92. + (RLMPermission *)permissionForRoleNamed:(NSString *)roleName onClass:(Class)cls realm:(RLMRealm *)realm;
  93. /**
  94. Returns the Permission object for the named Role on the named class, creating it if needed.
  95. This function should be used in preference to manually querying for the
  96. applicable Permission as it ensures that there is exactly one Permission for
  97. the given Role on the Class, merging duplicates or creating and adding new ones
  98. as needed.
  99. */
  100. + (RLMPermission *)permissionForRoleNamed:(NSString *)roleName onClassNamed:(NSString *)className realm:(RLMRealm *)realm;
  101. /**
  102. Returns the Permission object for the named Role on the object, creating it if needed.
  103. This function should be used in preference to manually querying for the
  104. applicable Permission as it ensures that there is exactly one Permission for
  105. the given Role on the Realm, merging duplicates or creating and adding new ones
  106. as needed.
  107. The given object must have a RLMArray<RLMPermission> property defined on it. If
  108. more than one such property is present, the first will be used.
  109. */
  110. + (RLMPermission *)permissionForRoleNamed:(NSString *)roleName onObject:(RLMObject *)object;
  111. @end
  112. /**
  113. A Role within the permissions system.
  114. A Role consists of a name for the role and a list of users which are members of the role.
  115. Roles are granted privileges on Realms, Classes and Objects, and in turn grant those
  116. privileges to all users which are members of the role.
  117. A role named "everyone" is automatically created in new Realms, and all new users which
  118. connect to the Realm are automatically added to it. Any other roles you wish to use are
  119. managed as normal Realm objects.
  120. */
  121. @interface RLMPermissionRole : RLMObject
  122. /// The name of the Role
  123. @property (nonatomic) NSString *name;
  124. /// The users which belong to the role
  125. @property (nonatomic) RLMArray<RLMPermissionUser *><RLMPermissionUser> *users;
  126. @end
  127. /**
  128. A representation of a sync user within the permissions system.
  129. RLMPermissionUser objects are created automatically for each sync user which connects to
  130. a Realm, and can also be created manually if you wish to grant permissions to a user
  131. which has not yet connected to this Realm.
  132. */
  133. @interface RLMPermissionUser : RLMObject
  134. /// The unique Realm Object Server user ID string identifying this user. This will have
  135. /// the same value as `-[RLMSyncUser identity]`.
  136. @property (nonatomic) NSString *identity;
  137. /// The user's private role. This will be initialized to a role named for the user's
  138. /// identity that contains this user as its only member.
  139. @property (nonatomic) RLMPermissionRole *role;
  140. /// Roles which this user belongs to.
  141. @property (nonatomic, readonly) RLMLinkingObjects<RLMPermissionRole *> *roles;
  142. /// Get the user object in the given Realm, creating it if needed.
  143. + (RLMPermissionUser *)userInRealm:(RLMRealm *)realm withIdentity:(NSString *)identity;
  144. @end
  145. /**
  146. A singleton object which describes Realm-wide permissions.
  147. An object of this type is automatically created in the Realm for you, and more objects
  148. cannot be created manually. Call `+[RLMRealmPermission objectInRealm:]` to obtain the
  149. instance for a specific Realm.
  150. See `RLMRealmPrivileges` for the meaning of permissions applied to a Realm.
  151. */
  152. @interface RLMRealmPermission : RLMObject
  153. /// The permissions for the Realm.
  154. @property (nonatomic) RLMArray<RLMPermission *><RLMPermission> *permissions;
  155. /// Retrieve the singleton object for the given Realm. This will return `nil`
  156. /// for non-partial-sync Realms.
  157. + (nullable instancetype)objectInRealm:(RLMRealm *)realm;
  158. @end
  159. /**
  160. An object which describes class-wide permissions.
  161. An instance of this object is automatically created in the Realm for class in your schema,
  162. and should not be created manually. Call `+[RLMClassPermission objectInRealm:forClassNamed:]`
  163. or `+[RLMClassPermission objectInRealm:forClass:]` to obtain the existing instance, or
  164. query `RLMClassPermission` as normal.
  165. */
  166. @interface RLMClassPermission : RLMObject
  167. /// The name of the class which these permissions apply to.
  168. @property (nonatomic) NSString *name;
  169. /// The permissions for this class.
  170. @property (nonatomic) RLMArray<RLMPermission *><RLMPermission> *permissions;
  171. /// Retrieve the object for the named RLMObject subclass. This will return `nil`
  172. /// for non-partial-sync Realms.
  173. + (nullable instancetype)objectInRealm:(RLMRealm *)realm forClassNamed:(NSString *)className;
  174. /// Retrieve the object for the given RLMObject subclass. This will return `nil`
  175. /// for non-partial-sync Realms.
  176. + (nullable instancetype)objectInRealm:(RLMRealm *)realm forClass:(Class)cls;
  177. @end
  178. /**
  179. A description of the actual privileges which apply to a Realm.
  180. This is a combination of all of the privileges granted to all of the Roles which the
  181. current User is a member of, obtained by calling `-[RLMRealm privilegesForRealm]` on
  182. the Realm.
  183. By default, all operations are permitted, and each privilege field indicates an operation
  184. which may be forbidden.
  185. */
  186. struct RLMRealmPrivileges {
  187. /// If `false`, the current User is not permitted to see the Realm at all. This can
  188. /// happen only if the Realm was created locally and has not yet been synchronized.
  189. bool read : 1;
  190. /// If `false`, no modifications to the Realm are permitted. Write transactions can
  191. /// be performed locally, but any changes made will be reverted by the server.
  192. /// `setPermissions` and `modifySchema` will always be `false` when this is `false`.
  193. bool update : 1;
  194. /// If `false`, no modifications to the permissions property of the RLMRealmPermissions
  195. /// object for are permitted. Write transactions can be performed locally, but any
  196. /// changes made will be reverted by the server.
  197. ///
  198. /// Note that if invalide privilege changes are made, `-[RLMRealm privilegesFor*:]`
  199. /// will return results reflecting those invalid changes until synchronization occurs.
  200. ///
  201. /// Even if this field is `true`, note that the user will be unable to grant
  202. /// privileges to a Role which they do not themselves have.
  203. ///
  204. /// Adding or removing Users from a Role is controlled by Update privileges on that
  205. /// Role, and not by this value.
  206. bool setPermissions : 1;
  207. /// If `false`, the user is not permitted to add new object types to the Realm or add
  208. /// new properties to existing objec types. Defining new RLMObject subclasses (and not
  209. /// excluding them from the schema with `-[RLMRealmConfiguration setObjectClasses:]`)
  210. /// will result in the application crashing if the object types are not first added on
  211. /// the server by a more privileged user.
  212. bool modifySchema : 1;
  213. };
  214. /**
  215. A description of the actual privileges which apply to a Class within a Realm.
  216. This is a combination of all of the privileges granted to all of the Roles which the
  217. current User is a member of, obtained by calling `-[RLMRealm privilegesForClass:]` or
  218. `-[RLMRealm privilegesForClassNamed:]` on the Realm.
  219. By default, all operations are permitted, and each privilege field indicates an operation
  220. which may be forbidden.
  221. */
  222. struct RLMClassPrivileges {
  223. /// If `false`, the current User is not permitted to see objects of this type, and
  224. /// attempting to query this class will always return empty results.
  225. ///
  226. /// Note that Read permissions are transitive, and so it may be possible to read an
  227. /// object which the user does not directly have Read permissions for by following a
  228. /// link to it from an object they do have Read permissions for. This does not apply
  229. /// to any of the other permission types.
  230. bool read : 1;
  231. /// If `false`, creating new objects of this type is not permitted. Write transactions
  232. /// creating objects can be performed locally, but the objects will be deleted by the
  233. /// server when synchronization occurs.
  234. ///
  235. /// For objects with Primary Keys, it may not be locally determinable if Create or
  236. /// Update privileges are applicable. It may appear that you are creating a new object,
  237. /// but an object with that Primary Key may already exist and simply not be visible to
  238. /// you, in which case it is actually an Update operation.
  239. bool create : 1;
  240. /// If `false`, no modifications to objects of this type are permitted. Write
  241. /// transactions modifying the objects can be performed locally, but any changes made
  242. /// will be reverted by the server.
  243. ///
  244. /// Deleting an object is considered a modification, and is governed by this privilege.
  245. bool update : 1;
  246. /// If `false`, the User is not permitted to create new subscriptions for this class.
  247. /// Local queries against the objects within the Realm will work, but new
  248. /// subscriptions will never add objects to the Realm.
  249. bool subscribe : 1;
  250. /// If `false`, no modifications to the permissions property of the RLMClassPermissions
  251. /// object for this type are permitted. Write transactions can be performed locally,
  252. /// but any changes made will be reverted by the server.
  253. ///
  254. /// Note that if invalid privilege changes are made, `-[RLMRealm privilegesFor*:]`
  255. /// will return results reflecting those invalid changes until synchronization occurs.
  256. ///
  257. /// Even if this field is `true`, note that the user will be unable to grant
  258. /// privileges to a Role which they do not themselves have.
  259. bool setPermissions : 1;
  260. };
  261. /**
  262. A description of the actual privileges which apply to a specific RLMObject.
  263. This is a combination of all of the privileges granted to all of the Roles which the
  264. current User is a member of, obtained by calling `-[RLMRealm privilegesForObject:]` on
  265. the Realm.
  266. By default, all operations are permitted, and each privilege field indicates an operation
  267. which may be forbidden.
  268. */
  269. struct RLMObjectPrivileges {
  270. /// If `false`, the current User is not permitted to read this object directly.
  271. ///
  272. /// Objects which cannot be read by a user will appear in a Realm due to that read
  273. /// permissions are transitive. All objects which a readable object links to are
  274. /// themselves implicitly readable. If the link to an object with `read=false` is
  275. /// removed, the object will be deleted from the local Realm.
  276. bool read : 1;
  277. /// If `false`, modifying the fields of this type is not permitted. Write
  278. /// transactions modifying the objects can be performed locally, but any changes made
  279. /// will be reverted by the server.
  280. ///
  281. /// Note that even if this is `true`, the user may not be able to modify the
  282. /// `RLMArray<RLMPermission> *` property of the object (if it exists), as that is
  283. /// governed by `setPermissions`.
  284. bool update : 1;
  285. /// If `false`, deleting this object is not permitted. Write transactions which delete
  286. /// the object can be performed locally, but the server will restore it.
  287. ///
  288. /// It is possible to have `update` but not `delete` privileges, or vice versa. For
  289. /// objects with primary keys, `delete` but not `update` is ill-advised, as an object
  290. /// can be updated by deleting and recreating it.
  291. bool del : 1;
  292. /// If `false`, modifying the privileges of this specific object is not permitted.
  293. ///
  294. /// Object-specific permissions are set by declaring a `RLMArray<RLMPermission> *`
  295. /// property on the `RLMObject` subclass. Modifications to this property are
  296. /// controlled by `setPermissions` rather than `update`.
  297. ///
  298. /// Even if this field is `true`, note that the user will be unable to grant
  299. /// privileges to a Role which they do not themselves have.
  300. bool setPermissions : 1;
  301. };
  302. /// :nodoc:
  303. FOUNDATION_EXTERN id RLMPermissionForRole(RLMArray *array, id role);
  304. /**
  305. Access levels which can be granted to Realm Mobile Platform users
  306. for specific synchronized Realms, using the permissions APIs.
  307. Note that each access level guarantees all allowed actions provided
  308. by less permissive access levels. Specifically, users with write
  309. access to a Realm can always read from that Realm, and users with
  310. administrative access can always read or write from the Realm.
  311. */
  312. typedef RLM_CLOSED_ENUM(NSUInteger, RLMSyncAccessLevel) {
  313. /// No access whatsoever.
  314. RLMSyncAccessLevelNone = 0,
  315. /**
  316. User can only read the contents of the Realm.
  317. @warning Users who have read-only access to a Realm should open the
  318. Realm using `+[RLMRealm asyncOpenWithConfiguration:callbackQueue:callback:]`.
  319. Attempting to directly open the Realm is an error; in this
  320. case the Realm must be deleted and re-opened.
  321. */
  322. RLMSyncAccessLevelRead = 1,
  323. /// User can read and write the contents of the Realm.
  324. RLMSyncAccessLevelWrite = 2,
  325. /// User can read, write, and administer the Realm, including
  326. /// granting permissions to other users.
  327. RLMSyncAccessLevelAdmin = 3,
  328. };
  329. /**
  330. A property on which a `RLMResults<RLMSyncPermission *>` can be queried or filtered.
  331. @warning If building `NSPredicate`s using format strings including these string
  332. constants, use %K instead of %@ as the substitution parameter.
  333. */
  334. typedef NSString * RLMSyncPermissionSortProperty NS_STRING_ENUM;
  335. /// Sort by the Realm Object Server path to the Realm to which the permission applies.
  336. extern RLMSyncPermissionSortProperty const RLMSyncPermissionSortPropertyPath;
  337. /// Sort by the identity of the user to whom the permission applies.
  338. extern RLMSyncPermissionSortProperty const RLMSyncPermissionSortPropertyUserID;
  339. /// Sort by the date the permissions were last updated.
  340. extern RLMSyncPermissionSortProperty const RLMSyncPermissionSortPropertyUpdated;
  341. /**
  342. A value representing a permission granted to the specified user(s) to access the specified Realm(s).
  343. `RLMSyncPermission` is immutable and can be accessed from any thread.
  344. See https://realm.io/docs/realm-object-server/#permissions for general documentation.
  345. */
  346. @interface RLMSyncPermission : NSObject
  347. /**
  348. The Realm Object Server path to the Realm to which this permission applies (e.g. "/path/to/realm").
  349. Specify "*" if this permission applies to all Realms managed by the server.
  350. */
  351. @property (nonatomic, readonly) NSString *path;
  352. /**
  353. The access level described by this permission.
  354. */
  355. @property (nonatomic, readonly) RLMSyncAccessLevel accessLevel;
  356. /// Whether the access level allows the user to read from the Realm.
  357. @property (nonatomic, readonly) BOOL mayRead;
  358. /// Whether the access level allows the user to write to the Realm.
  359. @property (nonatomic, readonly) BOOL mayWrite;
  360. /// Whether the access level allows the user to administer the Realm.
  361. @property (nonatomic, readonly) BOOL mayManage;
  362. /**
  363. Create a new sync permission value, for use with permission APIs.
  364. @param path The Realm Object Server path to the Realm whose permission should be modified
  365. (e.g. "/path/to/realm"). Pass "*" to apply to all Realms managed by the user.
  366. @param identity The Realm Object Server identity of the user who should be granted access to
  367. the Realm at `path`.
  368. Pass "*" to apply to all users managed by the server.
  369. @param accessLevel The access level to grant.
  370. */
  371. - (instancetype)initWithRealmPath:(NSString *)path
  372. identity:(NSString *)identity
  373. accessLevel:(RLMSyncAccessLevel)accessLevel;
  374. /**
  375. Create a new sync permission value, for use with permission APIs.
  376. @param path The Realm Object Server path to the Realm whose permission should be modified
  377. (e.g. "/path/to/realm"). Pass "*" to apply to all Realms managed by the user.
  378. @param username The username (often an email address) of the user who should be granted access
  379. to the Realm at `path`.
  380. @param accessLevel The access level to grant.
  381. */
  382. - (instancetype)initWithRealmPath:(NSString *)path
  383. username:(NSString *)username
  384. accessLevel:(RLMSyncAccessLevel)accessLevel;
  385. /**
  386. The identity of the user to whom this permission is granted, or "*"
  387. if all users are granted this permission. Nil if the permission is
  388. defined in terms of a key-value pair.
  389. */
  390. @property (nullable, nonatomic, readonly) NSString *identity;
  391. /**
  392. If the permission is defined in terms of a key-value pair, the key
  393. describing the type of criterion used to determine what users the
  394. permission applies to. Otherwise, nil.
  395. */
  396. @property (nullable, nonatomic, readonly) NSString *key;
  397. /**
  398. If the permission is defined in terms of a key-value pair, a string
  399. describing the criterion value used to determine what users the
  400. permission applies to. Otherwise, nil.
  401. */
  402. @property (nullable, nonatomic, readonly) NSString *value;
  403. /**
  404. When this permission was last updated.
  405. */
  406. @property (nonatomic, readonly) NSDate *updatedAt;
  407. /// :nodoc:
  408. - (instancetype)init __attribute__((unavailable("Use the designated initializer")));
  409. /// :nodoc:
  410. + (instancetype)new __attribute__((unavailable("Use the designated initializer")));
  411. // MARK: - Migration assistance
  412. /// :nodoc:
  413. @property (nullable, nonatomic, readonly) NSString *userId __attribute__((unavailable("Renamed to `identity`")));
  414. /// :nodoc:
  415. - (instancetype)initWithRealmPath:(NSString *)path
  416. userID:(NSString *)identity
  417. accessLevel:(RLMSyncAccessLevel)accessLevel
  418. __attribute__((unavailable("Renamed to `-initWithRealmPath:identity:accessLevel:`")));
  419. @end
  420. NS_ASSUME_NONNULL_END