RLMSyncUser.h 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536
  1. ////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright 2016 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 <Foundation/Foundation.h>
  19. #import "RLMRealmConfiguration.h"
  20. #import "RLMSyncCredentials.h"
  21. #import "RLMSyncPermission.h"
  22. @class RLMSyncUser, RLMSyncUserInfo, RLMSyncCredentials, RLMSyncPermission, RLMSyncSession, RLMRealm, RLMSyncPermissionOffer;
  23. /**
  24. The state of the user object.
  25. */
  26. typedef NS_ENUM(NSUInteger, RLMSyncUserState) {
  27. /// The user is logged out. Call `logInWithCredentials:...` with valid credentials to log the user back in.
  28. RLMSyncUserStateLoggedOut,
  29. /// The user is logged in, and any Realms associated with it are syncing with the Realm Object Server.
  30. RLMSyncUserStateActive,
  31. /// The user has encountered a fatal error state, and cannot be used.
  32. RLMSyncUserStateError,
  33. };
  34. /// A block type used for APIs which asynchronously vend an `RLMSyncUser`.
  35. typedef void(^RLMUserCompletionBlock)(RLMSyncUser * _Nullable, NSError * _Nullable);
  36. /// A block type used to report the status of a password change operation.
  37. /// If the `NSError` argument is nil, the operation succeeded.
  38. typedef void(^RLMPasswordChangeStatusBlock)(NSError * _Nullable);
  39. /// A block type used to report the status of a permission apply or revoke operation.
  40. /// If the `NSError` argument is nil, the operation succeeded.
  41. typedef void(^RLMPermissionStatusBlock)(NSError * _Nullable);
  42. /// A block type used to report the status of a permission offer operation.
  43. typedef void(^RLMPermissionOfferStatusBlock)(NSString * _Nullable, NSError * _Nullable);
  44. /// A block type used to report the status of a permission offer response operation.
  45. typedef void(^RLMPermissionOfferResponseStatusBlock)(NSURL * _Nullable, NSError * _Nullable);
  46. /// A block type used to asynchronously report results of a permissions get operation.
  47. /// Exactly one of the two arguments will be populated.
  48. typedef void(^RLMPermissionResultsBlock)(NSArray<RLMSyncPermission *> * _Nullable, NSError * _Nullable);
  49. /// A block type used to asynchronously report results of a permission offerss get operation.
  50. /// Exactly one of the two arguments will be populated.
  51. typedef void(^RLMPermissionOfferResultsBlock)(NSArray<RLMSyncPermissionOffer *> * _Nullable, NSError * _Nullable);
  52. /// A block type used to asynchronously report results of a user info retrieval.
  53. /// Exactly one of the two arguments will be populated.
  54. typedef void(^RLMRetrieveUserBlock)(RLMSyncUserInfo * _Nullable, NSError * _Nullable);
  55. /// A block type used to report an error related to a specific user.
  56. typedef void(^RLMUserErrorReportingBlock)(RLMSyncUser * _Nonnull, NSError * _Nonnull);
  57. NS_ASSUME_NONNULL_BEGIN
  58. /**
  59. A `RLMSyncUser` instance represents a single Realm Object Server user account.
  60. A user may have one or more credentials associated with it. These credentials
  61. uniquely identify the user to the authentication provider, and are used to sign
  62. into a Realm Object Server user account.
  63. Note that user objects are only vended out via SDK APIs, and cannot be directly
  64. initialized. User objects can be accessed from any thread.
  65. */
  66. @interface RLMSyncUser : NSObject
  67. /**
  68. A dictionary of all valid, logged-in user identities corresponding to their user objects.
  69. */
  70. + (NSDictionary<NSString *, RLMSyncUser *> *)allUsers NS_REFINED_FOR_SWIFT;
  71. /**
  72. The logged-in user. `nil` if none exists.
  73. @warning Throws an exception if more than one logged-in user exists.
  74. */
  75. + (nullable RLMSyncUser *)currentUser NS_REFINED_FOR_SWIFT;
  76. /**
  77. The unique Realm Object Server user ID string identifying this user.
  78. */
  79. @property (nullable, nonatomic, readonly) NSString *identity;
  80. /**
  81. The user's refresh token used to access the Realm Object Server.
  82. This is required to make HTTP requests to Realm Object Server's REST API
  83. for functionality not exposed natively. It should be treated as sensitive data.
  84. */
  85. @property (nullable, nonatomic, readonly) NSString *refreshToken;
  86. /**
  87. The URL of the authentication server this user will communicate with.
  88. */
  89. @property (nullable, nonatomic, readonly) NSURL *authenticationServer;
  90. /**
  91. Whether the user is a Realm Object Server administrator. Value reflects the
  92. state at the time of the last successful login of this user.
  93. */
  94. @property (nonatomic, readonly) BOOL isAdmin;
  95. /**
  96. The current state of the user.
  97. */
  98. @property (nonatomic, readonly) RLMSyncUserState state;
  99. #pragma mark - Lifecycle
  100. /**
  101. Create, log in, and asynchronously return a new user object, specifying a custom
  102. timeout for the network request and a custom queue to run the callback upon.
  103. Credentials identifying the user must be passed in. The user becomes available in
  104. the completion block, at which point it is ready for use.
  105. */
  106. + (void)logInWithCredentials:(RLMSyncCredentials *)credentials
  107. authServerURL:(NSURL *)authServerURL
  108. timeout:(NSTimeInterval)timeout
  109. callbackQueue:(dispatch_queue_t)callbackQueue
  110. onCompletion:(RLMUserCompletionBlock)completion NS_REFINED_FOR_SWIFT;
  111. /**
  112. Create, log in, and asynchronously return a new user object.
  113. If the login completes successfully, the completion block will invoked with
  114. a `RLMSyncUser` object representing the logged-in user. This object can be
  115. used to open synchronized Realms. If the login fails, the completion block
  116. will be invoked with an error.
  117. The completion block always runs on the main queue.
  118. @param credentials A credentials value identifying the user to be logged in.
  119. @param authServerURL The URL of the authentication server (e.g. "http://realm.example.org:9080").
  120. @param completion A callback block that returns a user object or an error,
  121. indicating the completion of the login operation.
  122. */
  123. + (void)logInWithCredentials:(RLMSyncCredentials *)credentials
  124. authServerURL:(NSURL *)authServerURL
  125. onCompletion:(RLMUserCompletionBlock)completion
  126. NS_SWIFT_UNAVAILABLE("Use the full version of this API.");
  127. /**
  128. Returns the default configuration for the user. The default configuration
  129. points to the default query-based Realm on the server the user authenticated against.
  130. */
  131. - (RLMRealmConfiguration *)configuration NS_REFINED_FOR_SWIFT;
  132. /**
  133. Create a query-based configuration instance for the given url.
  134. @param url The unresolved absolute URL to the Realm on the Realm Object Server,
  135. e.g. "realm://example.org/~/path/to/realm". "Unresolved" means the
  136. path should contain the wildcard marker `~`, which will automatically
  137. be filled in with the user identity by the Realm Object Server.
  138. @return A default configuration object with the sync configuration set to use the given URL.
  139. */
  140. - (RLMRealmConfiguration *)configurationWithURL:(nullable NSURL *)url NS_REFINED_FOR_SWIFT;
  141. /**
  142. Create a configuration instance for the given url.
  143. @param url The unresolved absolute URL to the Realm on the Realm Object Server,
  144. e.g. "realm://example.org/~/path/to/realm". "Unresolved" means the
  145. path should contain the wildcard marker `~`, which will automatically
  146. be filled in with the user identity by the Realm Object Server.
  147. @param fullSynchronization If YES, all objects in the server Realm are
  148. automatically synchronized, and the query subscription
  149. methods cannot be used.
  150. @return A default configuration object with the sync configuration set to use
  151. the given URL and options.
  152. */
  153. - (RLMRealmConfiguration *)configurationWithURL:(nullable NSURL *)url
  154. fullSynchronization:(bool)fullSynchronization NS_REFINED_FOR_SWIFT;
  155. /**
  156. Create a configuration instance for the given url.
  157. @param url The unresolved absolute URL to the Realm on the Realm Object Server,
  158. e.g. "realm://example.org/~/path/to/realm". "Unresolved" means the
  159. path should contain the wildcard marker `~`, which will automatically
  160. be filled in with the user identity by the Realm Object Server.
  161. @param fullSynchronization If YES, all objects in the server Realm are
  162. automatically synchronized, and the query subscription
  163. methods cannot be used.
  164. @param enableSSLValidation If NO, invalid SSL certificates for the server will
  165. not be rejected. THIS SHOULD NEVER BE USED IN
  166. PRODUCTION AND EXISTS ONLY FOR TESTING PURPOSES.
  167. @param urlPrefix A prefix which is prepending to URLs constructed for
  168. the server. This should normally be `nil`, and customized only
  169. to match corresponding settings on the server.
  170. @return A default configuration object with the sync configuration set to use
  171. the given URL and options.
  172. */
  173. - (RLMRealmConfiguration *)configurationWithURL:(nullable NSURL *)url
  174. fullSynchronization:(bool)fullSynchronization
  175. enableSSLValidation:(bool)enableSSLValidation
  176. urlPrefix:(nullable NSString *)urlPrefix NS_REFINED_FOR_SWIFT;
  177. /**
  178. Log a user out, destroying their server state, unregistering them from the SDK,
  179. and removing any synced Realms associated with them from on-disk storage on
  180. next app launch. If the user is already logged out or in an error state, this
  181. method does nothing.
  182. This method should be called whenever the application is committed to not using
  183. a user again unless they are recreated.
  184. Failing to call this method may result in unused files and metadata needlessly
  185. taking up space.
  186. */
  187. - (void)logOut;
  188. /**
  189. An optional error handler which can be set to notify the host application when
  190. the user encounters an error. Errors reported by this error handler are always
  191. `RLMSyncAuthError`s.
  192. @note Check for `RLMSyncAuthErrorInvalidAccessToken` to see if the user has
  193. been remotely logged out because its refresh token expired, or because the
  194. third party authentication service providing the user's identity has
  195. logged the user out.
  196. @warning Regardless of whether an error handler is installed, certain user errors
  197. will automatically cause the user to enter the logged out state.
  198. */
  199. @property (nullable, nonatomic) RLMUserErrorReportingBlock errorHandler NS_REFINED_FOR_SWIFT;
  200. #pragma mark - Sessions
  201. /**
  202. Retrieve a valid session object belonging to this user for a given URL, or `nil`
  203. if no such object exists.
  204. */
  205. - (nullable RLMSyncSession *)sessionForURL:(NSURL *)url;
  206. /**
  207. Retrieve all the valid sessions belonging to this user.
  208. */
  209. - (NSArray<RLMSyncSession *> *)allSessions;
  210. #pragma mark - Passwords
  211. /**
  212. Change this user's password asynchronously.
  213. @warning Changing a user's password using an authentication server that doesn't
  214. use HTTPS is a major security flaw, and should only be done while
  215. testing.
  216. @param newPassword The user's new password.
  217. @param completion Completion block invoked when login has completed or failed.
  218. The callback will be invoked on a background queue provided
  219. by `NSURLSession`.
  220. */
  221. - (void)changePassword:(NSString *)newPassword completion:(RLMPasswordChangeStatusBlock)completion;
  222. /**
  223. Change an arbitrary user's password asynchronously.
  224. @note The current user must be an admin user for this operation to succeed.
  225. @warning Changing a user's password using an authentication server that doesn't
  226. use HTTPS is a major security flaw, and should only be done while
  227. testing.
  228. @param newPassword The user's new password.
  229. @param userID The identity of the user whose password should be changed.
  230. @param completion Completion block invoked when login has completed or failed.
  231. The callback will be invoked on a background queue provided
  232. by `NSURLSession`.
  233. */
  234. - (void)changePassword:(NSString *)newPassword forUserID:(NSString *)userID completion:(RLMPasswordChangeStatusBlock)completion;
  235. /**
  236. Ask the server to send a password reset email to the given email address.
  237. If `email` is an email address which is associated with a user account that was
  238. registered using the "password" authentication service, the server will send an
  239. email to that address with a password reset token. No error is reported if the
  240. email address is invalid or not associated with an account.
  241. @param serverURL The authentication server URL for the user.
  242. @param email The email address to send the email to.
  243. @param completion A block which will be called when the request completes or
  244. fails. The callback will be invoked on a background queue
  245. provided by `NSURLSession`, and not on the calling queue.
  246. */
  247. + (void)requestPasswordResetForAuthServer:(NSURL *)serverURL
  248. userEmail:(NSString *)email
  249. completion:(RLMPasswordChangeStatusBlock)completion;
  250. /**
  251. Change a user's password using a one-time password reset token.
  252. By default, the password reset email sent by ROS will link to a web site where
  253. the user can select a new password, and the app will not need to call this
  254. method. If you wish to instead handle this within your native app, you must
  255. change the `baseURL` in the server configuration for `PasswordAuthProvider` to
  256. a scheme registered for your app, extract the token from the URL, and call this
  257. method after prompting the user for a new password.
  258. @warning Changing a user's password using an authentication server that doesn't
  259. use HTTPS is a major security flaw, and should only be done while
  260. testing.
  261. @param serverURL The authentication server URL for the user.
  262. @param token The one-time use token from the URL.
  263. @param newPassword The user's new password.
  264. @param completion A block which will be called when the request completes or
  265. fails. The callback will be invoked on a background queue
  266. provided by `NSURLSession`, and not on the calling queue.
  267. */
  268. + (void)completePasswordResetForAuthServer:(NSURL *)serverURL
  269. token:(NSString *)token
  270. password:(NSString *)newPassword
  271. completion:(RLMPasswordChangeStatusBlock)completion;
  272. /**
  273. Ask the server to send a confirmation email to the given email address.
  274. If `email` is an email address which is associated with a user account that was
  275. registered using the "password" authentication service, the server will send an
  276. email to that address with a confirmation token. No error is reported if the
  277. email address is invalid or not associated with an account.
  278. @param serverURL The authentication server URL for the user.
  279. @param email The email address to send the email to.
  280. @param completion A block which will be called when the request completes or
  281. fails. The callback will be invoked on a background queue
  282. provided by `NSURLSession`, and not on the calling queue.
  283. */
  284. + (void)requestEmailConfirmationForAuthServer:(NSURL *)serverURL
  285. userEmail:(NSString *)email
  286. completion:(RLMPasswordChangeStatusBlock)completion;
  287. /**
  288. Confirm a user's email using a one-time confirmation token.
  289. By default, the confirmation email sent by ROS will link to a web site with
  290. a generic "thank you for confirming your email" message, and the app will not
  291. need to call this method. If you wish to instead handle this within your native
  292. app, you must change the `baseURL` in the server configuration for
  293. `PasswordAuthProvider` to a scheme registered for your app, extract the token
  294. from the URL, and call this method.
  295. @param serverURL The authentication server URL for the user.
  296. @param token The one-time use token from the URL.
  297. @param completion A block which will be called when the request completes or
  298. fails. The callback will be invoked on a background queue
  299. provided by `NSURLSession`, and not on the calling queue.
  300. */
  301. + (void)confirmEmailForAuthServer:(NSURL *)serverURL
  302. token:(NSString *)token
  303. completion:(RLMPasswordChangeStatusBlock)completion;
  304. #pragma mark - Administrator
  305. /**
  306. Given a Realm Object Server authentication provider and a provider identifier for a user
  307. (for example, a username), look up and return user information for that user.
  308. @param providerUserIdentity The username or identity of the user as issued by the authentication provider.
  309. In most cases this is different from the Realm Object Server-issued identity.
  310. @param provider The authentication provider that manages the user whose information is desired.
  311. @param completion Completion block invoked when request has completed or failed.
  312. The callback will be invoked on a background queue provided
  313. by `NSURLSession`.
  314. */
  315. - (void)retrieveInfoForUser:(NSString *)providerUserIdentity
  316. identityProvider:(RLMIdentityProvider)provider
  317. completion:(RLMRetrieveUserBlock)completion;
  318. #pragma mark - Permissions
  319. /**
  320. Asynchronously retrieve all permissions associated with the user calling this method.
  321. The results will be returned through the callback block, or an error if the operation failed.
  322. The callback block will be run on a background thread and not the calling thread.
  323. */
  324. - (void)retrievePermissionsWithCallback:(RLMPermissionResultsBlock)callback;
  325. /**
  326. Apply a given permission.
  327. The operation will take place asynchronously, and the callback will be used to report whether
  328. the permission change succeeded or failed. The user calling this method must have the right
  329. to grant the given permission, or else the operation will fail.
  330. @see `RLMSyncPermission`
  331. */
  332. - (void)applyPermission:(RLMSyncPermission *)permission callback:(RLMPermissionStatusBlock)callback;
  333. /**
  334. Create a permission offer for a Realm.
  335. A permission offer is used to grant access to a Realm this user manages to another
  336. user. Creating a permission offer produces a string token which can be passed to the
  337. recepient in any suitable way (for example, via e-mail).
  338. The operation will take place asynchronously. The token can be accepted by the recepient
  339. using the `-[RLMSyncUser acceptOfferForToken:callback:]` method.
  340. @param url The URL of the Realm for which the permission offer should pertain. This
  341. may be the URL of any Realm which this user is allowed to manage. If the URL
  342. has a `~` wildcard it will be replaced with this user's user identity.
  343. @param accessLevel What access level to grant to whoever accepts the token.
  344. @param expirationDate Optionally, a date which indicates when the offer expires. If the
  345. recepient attempts to accept the offer after the date it will be rejected.
  346. @param callback A callback indicating whether the operation succeeded or failed. If it
  347. succeeded the token will be passed in as a string.
  348. @see `acceptOfferForToken:callback:`
  349. */
  350. - (void)createOfferForRealmAtURL:(NSURL *)url
  351. accessLevel:(RLMSyncAccessLevel)accessLevel
  352. expiration:(nullable NSDate *)expirationDate
  353. callback:(RLMPermissionOfferStatusBlock)callback NS_REFINED_FOR_SWIFT;
  354. /**
  355. Accept a permission offer.
  356. Pass in a token representing a permission offer. The operation will take place asynchronously.
  357. If the operation succeeds, the callback will be passed the URL of the Realm for which the
  358. offer applied, so the Realm can be opened.
  359. The token this method accepts can be created by the offering user through the
  360. `-[RLMSyncUser createOfferForRealmAtURL:accessLevel:expiration:callback:]` method.
  361. @see `createOfferForRealmAtURL:accessLevel:expiration:callback:`
  362. */
  363. - (void)acceptOfferForToken:(NSString *)token
  364. callback:(RLMPermissionOfferResponseStatusBlock)callback;
  365. /**
  366. Revoke a permission offer.
  367. Pass in a token representing a permission offer which was created by this
  368. user. The operation will take place asynchronously. If the operation succeeds,
  369. the callback will be passed the URL of the Realm for which the offer was
  370. revoked. After this operation completes, the token can no longer be accepted
  371. by the recipient.
  372. @see `createOfferForRealmAtURL:accessLevel:expiration:callback:`
  373. */
  374. - (void)invalidateOfferForToken:(NSString *)token
  375. callback:(RLMPermissionStatusBlock)callback;
  376. /**
  377. Asynchronously retrieve all pending permission offers created by the calling user.
  378. The results will be returned through the callback block, or an error if the operation failed.
  379. The callback block will be run on a background thread and not the calling thread.
  380. */
  381. - (void)retrievePermissionOffersWithCallback:(RLMPermissionOfferResultsBlock)callback;
  382. /// :nodoc:
  383. - (instancetype)init __attribute__((unavailable("RLMSyncUser cannot be created directly")));
  384. /// :nodoc:
  385. + (instancetype)new __attribute__((unavailable("RLMSyncUser cannot be created directly")));
  386. @end
  387. #pragma mark - User info classes
  388. /**
  389. A data object representing a user account associated with a user.
  390. @see `RLMSyncUserInfo`
  391. */
  392. @interface RLMSyncUserAccountInfo : NSObject
  393. /// The authentication provider which manages this user account.
  394. @property (nonatomic, readonly) RLMIdentityProvider provider;
  395. /// The username or identity of this user account.
  396. @property (nonatomic, readonly) NSString *providerUserIdentity;
  397. /// :nodoc:
  398. - (instancetype)init __attribute__((unavailable("RLMSyncUserAccountInfo cannot be created directly")));
  399. /// :nodoc:
  400. + (instancetype)new __attribute__((unavailable("RLMSyncUserAccountInfo cannot be created directly")));
  401. @end
  402. /**
  403. A data object representing information about a user that was retrieved from a user lookup call.
  404. */
  405. @interface RLMSyncUserInfo : NSObject
  406. /**
  407. An array of all the user accounts associated with this user.
  408. */
  409. @property (nonatomic, readonly) NSArray<RLMSyncUserAccountInfo *> *accounts;
  410. /**
  411. The identity issued to this user by the Realm Object Server.
  412. */
  413. @property (nonatomic, readonly) NSString *identity;
  414. /**
  415. Metadata about this user stored on the Realm Object Server.
  416. */
  417. @property (nonatomic, readonly) NSDictionary<NSString *, NSString *> *metadata;
  418. /**
  419. Whether the user is flagged on the Realm Object Server as an administrator.
  420. */
  421. @property (nonatomic, readonly) BOOL isAdmin;
  422. /// :nodoc:
  423. - (instancetype)init __attribute__((unavailable("RLMSyncUserInfo cannot be created directly")));
  424. /// :nodoc:
  425. + (instancetype)new __attribute__((unavailable("RLMSyncUserInfo cannot be created directly")));
  426. @end
  427. NS_ASSUME_NONNULL_END