parse-stack 1.5.2 → 1.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/Changes.md +5 -0
  3. data/Gemfile.lock +1 -1
  4. data/README.md +40 -80
  5. data/lib/parse/api/all.rb +7 -0
  6. data/lib/parse/api/analytics.rb +8 -3
  7. data/lib/parse/api/apps.rb +29 -1
  8. data/lib/parse/api/batch.rb +14 -129
  9. data/lib/parse/api/cloud_functions.rb +9 -0
  10. data/lib/parse/api/config.rb +10 -1
  11. data/lib/parse/api/files.rb +7 -2
  12. data/lib/parse/api/hooks.rb +45 -2
  13. data/lib/parse/api/objects.rb +43 -6
  14. data/lib/parse/api/push.rb +6 -1
  15. data/lib/parse/api/schemas.rb +15 -1
  16. data/lib/parse/api/sessions.rb +5 -0
  17. data/lib/parse/api/users.rb +64 -5
  18. data/lib/parse/client/authentication.rb +25 -8
  19. data/lib/parse/client/batch.rb +206 -0
  20. data/lib/parse/client/body_builder.rb +12 -6
  21. data/lib/parse/client/caching.rb +42 -10
  22. data/lib/parse/client/protocol.rb +51 -46
  23. data/lib/parse/client/response.rb +1 -47
  24. data/lib/parse/client.rb +171 -42
  25. data/lib/parse/model/acl.rb +184 -39
  26. data/lib/parse/model/associations/belongs_to.rb +1 -0
  27. data/lib/parse/model/classes/role.rb +7 -1
  28. data/lib/parse/model/classes/session.rb +7 -3
  29. data/lib/parse/model/classes/user.rb +107 -0
  30. data/lib/parse/model/core/actions.rb +166 -115
  31. data/lib/parse/model/core/fetching.rb +105 -0
  32. data/lib/parse/model/core/properties.rb +40 -13
  33. data/lib/parse/model/core/querying.rb +123 -39
  34. data/lib/parse/model/core/schema.rb +22 -32
  35. data/lib/parse/model/object.rb +26 -20
  36. data/lib/parse/model/pointer.rb +1 -0
  37. data/lib/parse/query/constraint.rb +65 -27
  38. data/lib/parse/query/constraints.rb +0 -3
  39. data/lib/parse/query/operation.rb +33 -22
  40. data/lib/parse/query/ordering.rb +10 -5
  41. data/lib/parse/stack/generators/rails.rb +5 -1
  42. data/lib/parse/stack/generators/templates/model_installation.rb +1 -1
  43. data/lib/parse/stack/generators/templates/model_role.rb +1 -1
  44. data/lib/parse/stack/generators/templates/model_session.rb +2 -2
  45. data/lib/parse/stack/generators/templates/model_user.rb +1 -1
  46. data/lib/parse/stack/generators/templates/parse.rb +0 -1
  47. data/lib/parse/stack/railtie.rb +1 -0
  48. data/lib/parse/stack/tasks.rb +3 -1
  49. data/lib/parse/stack/version.rb +3 -1
  50. data/lib/parse/webhooks/registration.rb +3 -3
  51. data/lib/parse/webhooks.rb +88 -7
  52. metadata +5 -3
@@ -1,42 +1,113 @@
1
1
  # encoding: UTF-8
2
2
  # frozen_string_literal: true
3
3
 
4
- # An ACL represents the Parse Permissions object used for each record. In Parse,
5
- # it is composed a hash-like object that represent Parse::User objectIds and/or Parse::Role
6
- # names. For each entity (ex. User/Role/Public), you can define read/write priviledges on a particular record.
7
- # The way they are implemented here is through an internal hash, with each value being of type Parse::ACL::Permission object.
8
- # A Permission object contains two accessors - read and write - and knows how to generate its JSON
9
- # structure. In Parse, if you want to give priviledges for an action (ex. read/write), then you set it to true.
10
- # If you want to deny a priviledge, then you set it to false. One important thing is that when
11
- # being converted to the Parse format, removing a priviledge means omiting it from the final
12
- # JSON structure.
13
- # The class below also implements a type of delegate pattern in order to inform the main Parse::Object
14
- # of dirty tracking.
15
4
 
16
5
  module Parse
17
6
 
7
+ # This class allows you to define custom data types for your model fields. You
8
+ # can define a subclass that implements the {DataType.typecast} method to
9
+ # convert to and from a value for serialization. The {Parse::ACL} class is
10
+ # implemented in this fashion.
18
11
  class DataType
19
12
  include ::ActiveModel::Model
20
13
  include ::ActiveModel::Serializers::JSON
14
+
15
+ # @return [Hash] the set of attributes for this data type.
21
16
  def attributes
22
17
  {}
23
18
  end
24
19
 
20
+ # Transform an incoming value to another. The default implementation does
21
+ # returns the original value. This method should return an instance of a
22
+ # DataType subclass.
23
+ # @param value [Object] the input value to be typecasted.
24
+ # @param opts [Hash] a set of options to be used when typecasting.
25
+ # @return [Object]
25
26
  def self.typecast(value, **opts)
26
27
  value
27
28
  end
28
29
 
30
+ # Serialize this DataType into an JSON object hash format to be saved to Parse.
31
+ # The default implementation returns an empty hash.
32
+ # @return [Hash]
29
33
  def as_json(*args)
30
34
  {}.as_json
31
35
  end
32
36
 
33
37
  end
34
38
 
39
+ # An ACL represents the dirty-trackable Parse Permissions object used for
40
+ # each record. In Parse, it is composed a hash-like object that represent
41
+ # {Parse::User} objectIds and/or a set of {Parse::Role} names. For each entity
42
+ # (ex. User/Role/Public), you can define read/write priviledges on a particular
43
+ # record through a {Parse::ACL::Permission} instance.
44
+ #
45
+ # If you want to give priviledges for an action (ex. read/write),
46
+ # you set that particular permission it to true. If you want to deny a
47
+ # permission, then you set it to false. Any denied permissions will not be
48
+ # part of the final hash structure that is sent to parse, as omission of a permission
49
+ # means denial.
50
+ #
51
+ # An ACL is represented by a JSON object with the keys being Parse::User object
52
+ # ids or the special key of *, which indicates the public access permissions.
53
+ # The value of each key in the hash is a {Parse::ACL::Permission} object which
54
+ # defines the boolean permission state for read and write.
55
+ # The example below illustrates a Parse ACL JSON object where there is a public
56
+ # read permission, but public write is prevented. In addition, the user with
57
+ # id "3KmCvT7Zsb", is allowed to both read and write this record.
58
+ # {
59
+ # "*": { "read": true },
60
+ # "3KmCvT7Zsb": { "read": true, "write": true }
61
+ # }
62
+ #
63
+ # All Parse::Object subclasses have an acl property by default. With this
64
+ # property, you can apply and delete permissions for this particular Parse
65
+ # object record.
66
+ # user = Parse::User.first
67
+ # artist = Artist.first
68
+ #
69
+ # artist.acl # "*": { "read": true, "write": true }
70
+ #
71
+ # # apply public read, but no public write
72
+ # artist.acl.everyone true, false
73
+ #
74
+ #
75
+ # # allow user to have read and write access
76
+ # artist.acl.apply user.id, true, true
77
+ #
78
+ # # remove all permissions for this user id
79
+ # artist.acl.delete user.id
80
+ #
81
+ # # allow the 'Admins' role read and write
82
+ # artist.acl.apply_role "Admins", true, true
83
+ #
84
+ # artist.save
85
+ # For more information about Parse record ACLs, see the documentation on
86
+ # {https://parseplatform.github.io/docs/rest/guide/#security Security}.
35
87
  class ACL < DataType
36
88
 
89
+ # @!attribute permissions
90
+ # Contains a hash structure of permissions, with keys mapping to either Public '*',
91
+ # a role name or an objectId for a user and values of type {ACL::Permission}.
92
+ # @return [Hash] a hash of permissions.
93
+
94
+ # @!attribute delegate
95
+ # The instance object to be notified of changes. The delegate must support
96
+ # receiving a `acl_will_change!` method.
97
+ # @return [Parse::Object]
37
98
  attr_accessor :permissions, :delegate
99
+
100
+ def permissions
101
+ @permissions ||= {}
102
+ end
103
+
38
104
  PUBLIC = "*"
39
105
 
106
+ # Create a new ACL with default Public read/write permissions and any
107
+ # overrides from the input hash format.
108
+ # @param acls [Hash] a Parse-compatible hash acl format.
109
+ # @param owner [Parse::Object] a delegate to receive notifications of acl changes.
110
+ # This delegate must support receiving `acl_will_change!` method.
40
111
  def initialize(acls = {}, owner: nil)
41
112
  everyone(true, true) # sets Public read/write
42
113
  @delegate = owner
@@ -46,32 +117,43 @@ module Parse
46
117
 
47
118
  end
48
119
 
120
+ # Create a new ACL::Permission instance with the supplied read and write values.
121
+ # @param read [Boolean] the read permission value
122
+ # @param write [Boolean] the write permission value.
123
+ # @return [ACL::Permission]
124
+ # @see ACL::Permission
49
125
  def self.permission(read, write = nil)
50
126
  ACL::Permission.new(read, write)
51
127
  end
52
128
 
53
- def permissions
54
- @permissions ||= {}
55
- end
56
-
129
+ # @return [Boolean] whether two ACLs have the same set of priviledges.
57
130
  def ==(other_acl)
58
131
  return false unless other_acl.is_a?(self.class)
59
132
  return false if permissions.keys != other_acl.permissions.keys
60
133
  permissions.keys.all? { |per| permissions[per] == other_acl.permissions[per] }
61
134
  end
62
135
 
136
+ # Set the public read and write permissions.
137
+ # @param read [Boolean] the read permission state.
138
+ # @param write [Boolean] the write permission state.
139
+ # @return [Hash] the current public permissions.
63
140
  def everyone(read, write)
64
141
  apply(PUBLIC, read, write)
65
142
  permissions[PUBLIC]
66
143
  end
67
144
  alias_method :world, :everyone
68
145
 
69
- # dirty tracking. We will tell the delegate through the acl_will_change! method
146
+ # Calls `acl_will_change!` on the delegate when the permissions have changed.
147
+ # All {Parse::Object} subclasses implement this method.
70
148
  def will_change!
71
149
  @delegate.acl_will_change! if @delegate.respond_to?(:acl_will_change!)
72
150
  end
73
151
 
74
- # removes a permission
152
+ # Removes a permission for an objectId or user.
153
+ # @overload delete(object)
154
+ # @param object [Parse::User] the user to revoke permissions.
155
+ # @overload delete(id)
156
+ # @param id [String] the objectId to revoke permissions.
75
157
  def delete(id)
76
158
  id = id.id if id.is_a?(Parse::Pointer)
77
159
  if id.present? && permissions.has_key?(id)
@@ -80,8 +162,26 @@ module Parse
80
162
  end
81
163
  end
82
164
 
83
- # apply a new permission with a given objectId (or tag)
165
+ # Apply a new permission with a given objectId (or tag)
166
+ # @overload apply(user, read = nil, write = nil)
167
+ # Set the read and write permissions for this user on this ACL.
168
+ # @param user [Parse::User] the user object.
169
+ # @param read [Boolean] the read permission.
170
+ # @param write [Boolean] the write permission.
171
+ # @overload apply(role, read = nil, write = nil)
172
+ # Set the read and write permissions for this role object on this ACL.
173
+ # @param role [Parse::Role] the role object.
174
+ # @param read [Boolean] the read permission.
175
+ # @param write [Boolean] the write permission.
176
+ # @overload apply(id, read = nil, write = nil)
177
+ # Set the read and write permissions for this objectId on this ACL.
178
+ # @param id [String] the objectId for a {Parse::User}.
179
+ # @param read [Boolean] the read permission.
180
+ # @param write [Boolean] the write permission.
181
+ # @return [Hash] the current set of permissions.
182
+ # @see #apply_role
84
183
  def apply(id, read = nil, write = nil)
184
+ return apply_role(id,read,write) if id.is_a?(Parse::Role)
85
185
  id = id.id if id.is_a?(Parse::Pointer)
86
186
  return unless id.present?
87
187
  # create a new Permissions
@@ -99,12 +199,24 @@ module Parse
99
199
  permissions
100
200
  end; alias_method :add, :apply
101
201
 
102
- # You can apply a Role as a permission ex. "Admin". This will add the
103
- # ACL of 'role:Admin' as the key in the permissions hash.
202
+ # Apply a {Parse::Role} to this ACL.
203
+ # @overload apply_role(role, read = nil, write = nil)
204
+ # @param role [Parse::Role] the role object.
205
+ # @param read [Boolean] the read permission.
206
+ # @param write [Boolean] the write permission.
207
+ # @overload apply_role(role_name, read = nil, write = nil)
208
+ # @param role_name [String] the name of the role.
209
+ # @param read [Boolean] the read permission.
210
+ # @param write [Boolean] the write permission.
104
211
  def apply_role(name, read = nil, write = nil)
212
+ name = name.name if name.is_a?(Parse::Role)
105
213
  apply("role:#{name}", read, write)
106
214
  end; alias_method :add_role, :apply_role
107
- # Used for object conversion when formatting the input/output value in Parse::Object properties
215
+
216
+ # Used for object conversion when formatting the input/output value in
217
+ # Parse::Object properties
218
+ # @return [ACL]
219
+ # @see Parse::DataType
108
220
  def self.typecast(value, delegate = nil)
109
221
  ACL.new(value, owner: delegate)
110
222
  end
@@ -113,10 +225,13 @@ module Parse
113
225
  # in the Permissions hash, since omission means denial of priviledge. If the
114
226
  # permission value has neither read or write, then the entire record has been denied
115
227
  # all priviledges
228
+
229
+ # @return [Hash]
116
230
  def attributes
117
231
  permissions.select {|k,v| v.present? }.as_json
118
232
  end
119
233
 
234
+ # @!visibility private
120
235
  def attributes=(h)
121
236
  return unless h.is_a?(Hash)
122
237
  will_change!
@@ -126,48 +241,75 @@ module Parse
126
241
  end
127
242
  end
128
243
 
244
+ # @!visibility private
129
245
  def inspect
130
246
  "ACL(#{as_json.inspect})"
131
247
  end
132
248
 
249
+ # @return [Hash]
133
250
  def as_json(*args)
134
251
  permissions.select {|k,v| v.present? }.as_json
135
252
  end
136
253
 
254
+ # @return [Boolean] true if there are any permissions.
137
255
  def present?
138
256
  permissions.values.any? { |v| v.present? }
139
257
  end
140
258
 
141
- # Permission class
259
+ # The Permission class tracks the read and write permissions for a specific
260
+ # ACL entry. The value of an Parse-ACL hash only contains two keys: "read" and "write".
261
+ #
262
+ # # Example of the ACL format
263
+ # { "*": { "read": true },
264
+ # "3KmCvT7Zsb": { "read": true, "write": true }
265
+ # }
266
+ # This would be managed as:
267
+ # { "*": ACL::Permission.new(true),
268
+ # "3KmCvT7Zsb": ACL::Permission.new(true, true)
269
+ # }
270
+ #
142
271
  class Permission
143
272
  include ::ActiveModel::Model
144
273
  include ::ActiveModel::Serializers::JSON
145
- # we don't support changing priviledges directly since it would become
146
- # crazy to track for dirty tracking
147
- attr_reader :read, :write
148
-
149
- # initialize with read and write priviledge
150
- def initialize(r = nil, w = nil)
151
- if r.is_a?(Hash)
152
- r.symbolize_keys!
153
- # @read = true if r[:read].nil? || r[:read].present?
154
- # @write = true if r[:write].nil? || r[:write].present?
155
- @read = r[:read].present?
156
- @write = r[:write].present?
274
+
275
+ # The *read* permission state.
276
+ # @return [Boolean] whether this permission is allowed.
277
+ attr_reader :read
278
+
279
+ # The *write* permission state.
280
+ # @return [Boolean] whether this permission is allowed.
281
+ attr_reader :write
282
+
283
+ # Create a new permission with the given read and write priviledges.
284
+ # @overload new(read = nil, write = nil)
285
+ # @param read [Boolean] whether reading is allowed.
286
+ # @param write [Boolean] whether writing is allowed.
287
+ # @example
288
+ # ACL::Permission.new(true, false)
289
+ # @overload new(hash)
290
+ # @param hash [Hash] a key value pair for read/write permissions.
291
+ # @example
292
+ # ACL::Permission.new({read: true, write: false})
293
+ #
294
+ def initialize(r_perm = nil, w_perm = nil)
295
+ if r_perm.is_a?(Hash)
296
+ r_perm.symbolize_keys!
297
+ @read = r_perm[:read].present?
298
+ @write = r_perm[:write].present?
157
299
  else
158
- # @read = true if r.nil? || r.present?
159
- # @write = true if w.nil? || w.present?
160
- @read = r.present?
161
- @write = w.present?
300
+ @read = r_perm.present?
301
+ @write = w_perm.present?
162
302
  end
163
303
  end
164
304
 
305
+ # @return [Boolean] whether two permission instances have the same permissions.
165
306
  def ==(per)
166
307
  return false unless per.is_a?(self.class)
167
308
  @read == per.read && @write == per.write
168
309
  end
169
310
 
170
- # omission or false on a priviledge means don't include it
311
+ # @return [Hash] A Parse-compatible ACL-hash. Omission or false on a
312
+ # priviledge means don't include it
171
313
  def as_json(*args)
172
314
  h = {}
173
315
  h[:read] = true if @read
@@ -175,6 +317,7 @@ module Parse
175
317
  h.empty? ? nil : h.as_json
176
318
  end
177
319
 
320
+ # @return [Hash]
178
321
  def attributes
179
322
  h = {}
180
323
  h.merge!(read: :boolean) if @read
@@ -182,10 +325,12 @@ module Parse
182
325
  h
183
326
  end
184
327
 
328
+ # @!visibility private
185
329
  def inspect
186
330
  as_json.inspect
187
331
  end
188
332
 
333
+ # @return [Boolean] whether there is at least one permission set to true.
189
334
  def present?
190
335
  @read.present? || @write.present?
191
336
  end
@@ -8,6 +8,7 @@ require_relative 'relation_collection_proxy'
8
8
 
9
9
 
10
10
  module Parse
11
+ # Defines all the types of Parse object associations.
11
12
  module Associations
12
13
  # This association creates a one-to-one association with another Parse model.
13
14
  # BelongsTo relation is the simplies association in which the local
@@ -4,15 +4,21 @@ require_relative '../object'
4
4
  require_relative 'user'
5
5
  module Parse
6
6
  # This class represents the data and columns contained in the standard Parse `_Role` collection.
7
+ # Roles allow the an application to group a set of {Parse::User} records with the same set of
8
+ # permissions, so that specific records in the database can have {Parse::ACL}s related to a role
9
+ # than trying to add all the users in a group.
7
10
  class Role < Parse::Object
8
-
11
+
9
12
  parse_class Parse::Model::CLASS_ROLE
10
13
  # @return [String] the name of this role.
11
14
  property :name
15
+ # This attribute is mapped as a `has_many` Parse relation association with the {Parse::Role} class,
16
+ # as roles can be associated with multiple child roles to support role inheritance.
12
17
  # The roles Parse relation provides a mechanism to create a hierarchical inheritable types of permissions
13
18
  # by assigning child roles.
14
19
  # @return [RelationCollectionProxy<Role>] a collection of Roles.
15
20
  has_many :roles, through: :relation
21
+ # This attribute is mapped as a `has_many` Parse relation association with the {Parse::User} class.
16
22
  # @return [RelationCollectionProxy<User>] a Parse relation of users belonging to this role.
17
23
  has_many :users, through: :relation
18
24
 
@@ -21,10 +21,14 @@ module Parse
21
21
  property :installation_id
22
22
  # @return [Boolean] whether this session token is restricted.
23
23
  property :restricted, :boolean
24
- # @return [String] the session token for this installation and user pair.
24
+ # @!attribute [r] session_token
25
+ # @return [String] the session token for this installation and user pair.
25
26
  property :session_token
26
- # @return [User] the user corresponding to this session.
27
- # @see User
27
+ # @!attribute [r] user
28
+ # This property is mapped as a `belongs_to` association with the {Parse::User}
29
+ # class. Every session instance is tied to a specific logged in user.
30
+ # @return [User] the user corresponding to this session.
31
+ # @see User
28
32
  belongs_to :user
29
33
 
30
34
  # Return the Session record for this session token.
@@ -21,6 +21,105 @@ module Parse
21
21
  # The main class representing the _User table in Parse. A user can either be signed up or anonymous.
22
22
  # All users need to have a username and a password, with email being optional but globally unique if set.
23
23
  # You may add additional properties by redeclaring the class to match your specific schema.
24
+ #
25
+ # *Signup*
26
+ #
27
+ # You can signup new users in two ways. You can either use a class method
28
+ # {Parse::User.signup} to create a new user with the minimum fields of username,
29
+ # password and email, or create a {Parse::User} object can call the {#signup!}
30
+ # method. If signup fails, it will raise the corresponding exception.
31
+ #
32
+ # user = Parse::User.signup(username, password, email)
33
+ #
34
+ # #or
35
+ # user = Parse::User.new username: "user", password: "s3cret"
36
+ # user.signup!
37
+ #
38
+ # *Login/Logout*
39
+ #
40
+ # With the {Parse::User} class, you can also perform login and logout
41
+ # functionality. The class special accessors for {#session_token} and {#session}
42
+ # to manage its authentication state. This will allow you to authenticate
43
+ # users as well as perform Parse queries as a specific user using their session
44
+ # token. To login a user, use the {Parse::User.login} method by supplying the
45
+ # corresponding username and password, or if you already have a user record,
46
+ # use {#login!} with the proper password.
47
+ #
48
+ # user = Parse::User.login(username,password)
49
+ # user.session_token # session token from a Parse::Session
50
+ # user.session # Parse::Session tied to the token
51
+ #
52
+ # # You can login user records
53
+ # user = Parse::User.first
54
+ # user.session_token # nil
55
+ #
56
+ # passwd = 'p_n7!-e8' # corresponding password
57
+ # user.login!(passwd) # true
58
+ #
59
+ # user.session_token # 'r:pnktnjyb996sj4p156gjtp4im'
60
+ #
61
+ # # logout to delete the session
62
+ # user.logout
63
+ #
64
+ # If you happen to already have a valid session token, you can use it to
65
+ # retrieve the corresponding Parse::User.
66
+ #
67
+ # # finds user with session token
68
+ # user = Parse::User.session(session_token)
69
+ #
70
+ # user.logout # deletes the corresponding session
71
+ #
72
+ # *OAuth-Login*
73
+ #
74
+ # You can signup users using third-party services like Facebook and Twitter as
75
+ # described in {https://parseplatform.github.io/docs/rest/guide/#signing-up-and-logging-in
76
+ # Signing Up and Logging In}. To do this with Parse-Stack, you can call the
77
+ # {Parse::User.autologin_service} method by passing the service name and the
78
+ # corresponding authentication hash data. For a listing of supported third-party
79
+ # authentication services, see {https://github.com/ParsePlatform/parse-server/wiki/OAuth OAuth}.
80
+ #
81
+ # fb_auth = {}
82
+ # fb_auth[:id] = "123456789"
83
+ # fb_auth[:access_token] = "SaMpLeAAiZBLR995wxBvSGNoTrEaL"
84
+ # fb_auth[:expiration_date] = "2025-02-21T23:49:36.353Z"
85
+ #
86
+ # # signup or login a user with this auth data.
87
+ # user = Parse::User.autologin_service(:facebook, fb_auth)
88
+ #
89
+ # You may also combine both approaches of signing up a new user with a
90
+ # third-party service and set additional custom fields. For this, use the
91
+ # method {Parse::User.create}.
92
+ #
93
+ # # or to signup a user with additional data, but linked to Facebook
94
+ # data = {
95
+ # username: "johnsmith",
96
+ # name: "John",
97
+ # email: "user@example.com",
98
+ # authData: { facebook: fb_auth }
99
+ # }
100
+ # user = Parse::User.create data
101
+ #
102
+ # *Linking/Unlinking*
103
+ #
104
+ # You can link or unlink user accounts with third-party services like
105
+ # Facebook and Twitter as described in:
106
+ # {https://parseplatform.github.io/docs/rest/guide/#linking Linking and Unlinking Users}.
107
+ # To do this, you must first get the corresponding authentication data for the
108
+ # specific service, and then apply it to the user using the linking and
109
+ # unlinking methods. Each method returns true or false if the action was
110
+ # successful. For a listing of supported third-party authentication services,
111
+ # see {https://github.com/ParsePlatform/parse-server/wiki/OAuth OAuth}.
112
+ #
113
+ # user = Parse::User.first
114
+ #
115
+ # fb_auth = { ... } # Facebook auth data
116
+ #
117
+ # # Link this user's Facebook account with Parse
118
+ # user.link_auth_data! :facebook, fb_auth
119
+ #
120
+ # # Unlinks this user's Facebook account from Parse
121
+ # user.unlink_auth_data! :facebook
122
+ #
24
123
  class User < Parse::Object
25
124
 
26
125
  parse_class Parse::Model::CLASS_USER
@@ -101,6 +200,7 @@ module Parse
101
200
 
102
201
  # Request a password reset for this user
103
202
  # @return [Boolean] true if it was successful requested. false otherwise.
203
+ # @see Parse::User.request_password_reset
104
204
  def request_password_reset
105
205
  return false if email.nil?
106
206
  Parse::User.request_password_reset(email)
@@ -251,6 +351,13 @@ module Parse
251
351
  end
252
352
 
253
353
  # Request a password reset for a registered email.
354
+ # @example
355
+ # user = Parse::User.first
356
+ #
357
+ # # pass a user object
358
+ # Parse::User.request_password_reset user
359
+ # # or email
360
+ # Parse::User.request_password_reset("user@example.com")
254
361
  # @param email [String] The user's email address.
255
362
  # @return [Boolean] True/false if successful.
256
363
  def self.request_password_reset(email)