RLMSyncPermission.h 21 KB

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