parse-stack 1.6.13 → 1.7.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1be0d0741ab2d2b2c1fb6113f3b4763dfd6d6b1d
4
- data.tar.gz: 83ebaed1bfae4f8a86291bdc23eda363a852f29b
3
+ metadata.gz: 48e731586682a18f7800110c166f20536c46b717
4
+ data.tar.gz: e5cd663b12a7935acb772ff881ca471709de076b
5
5
  SHA512:
6
- metadata.gz: 2a54f519b4aa5561cfa10b6d514024f664652c0614c2291e6e57c9921bb9356e8038618e17fbbe22bc7c5c258d83cad3ff4d3ca5cafe79adb24c804bc7442cb7
7
- data.tar.gz: c398da3567d2b00d506823cb9edc4a2ee064d6f685db654b460655358bf7ade01d4f5b9364ebae4869b0eed9171096832750ef9f70829fe41ae4dec0aa7d2b6f
6
+ metadata.gz: 79a487df290f8e3f7efc843b8f7b079fccd5dee56e52f3821a20f75f3b391675da33ce03e23a01ed9c442305017d2cee5e1d6dcfb52074bca218ee5f8f986044
7
+ data.tar.gz: b54958ad9b82dd8fddc10b6c1701e20eea11701482d27403cc92c41e4db883573feb77a9ab17915738092b940ee319a6b6c394f7afa6d7360790d1b916d524b9
data/Changes.md CHANGED
@@ -1,5 +1,12 @@
1
1
  ## Parse-Stack Changelog
2
2
 
3
+ ### 1.7.0
4
+ - NEW: You can use `set_default_acl` to set default ACLs for your subclasses.
5
+ - NEW: Support for `withinPolygon` query constraint.
6
+ - Refactoring of the default ACL system and deprecation of `Parse::Object.acl`
7
+ - Parse::ACL.everyone returns an ACL instance with public read and writes.
8
+ - Documentation updates.
9
+
3
10
  ### 1.6.12
4
11
  - NEW: Parse.use_shortnames! to utilize shorter class methods. (optional)
5
12
  - NEW: parse-console supports `--url` option to load config from JSON url.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- parse-stack (1.6.13)
4
+ parse-stack (1.7.0)
5
5
  active_model_serializers (>= 0.9, < 1)
6
6
  activemodel (>= 4.2.1, < 6)
7
7
  activesupport (>= 4.2.1, < 6)
data/README.md CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  # Parse Stack - The Parse Server Ruby Client SDK
4
4
 
5
- [Parse Stack](https://github.com/modernistik/parse-stack) is the [Parse Server](https://github.com/ParsePlatform/parse-server) SDK, REST Client and ORM framework for [Ruby](https://www.ruby-lang.org/en/). It provides a client adapter, a query engine, an object relational mapper (ORM) and a Cloud Code Webhooks rack application.
5
+ [Parse Stack](https://github.com/modernistik/parse-stack) is the [Parse Server](http://parseplatform.org/) SDK, REST Client and ORM framework for [Ruby](https://www.ruby-lang.org/en/). It provides a client adapter, a query engine, an object relational mapper (ORM) and a Cloud Code Webhooks rack application.
6
6
 
7
- Below is a [quick start guide](https://github.com/modernistik/parse-stack#overview), but you can also check out the full *[API Reference](https://www.modernistik.com/gems/parse-stack/)* for more detailed information about our Parse Server SDK.
7
+ Below is a [quick start guide](https://github.com/modernistik/parse-stack#overview), but you can also check out the full *[API Reference](https://www.modernistik.com/gems/parse-stack/index.html)* for more detailed information about our Parse Server SDK.
8
8
 
9
9
  #### Tutorial Videos
10
10
  1. Getting Started: https://youtu.be/zoYSGmciDlQ
@@ -15,7 +15,7 @@ Below is a [quick start guide](https://github.com/modernistik/parse-stack#overvi
15
15
  [![Gem Version](https://img.shields.io/gem/v/parse-stack.svg)](https://github.com/modernistik/parse-stack)
16
16
  [![Downloads](https://img.shields.io/gem/dt/parse-stack.svg)](https://rubygems.org/gems/parse-stack)
17
17
  [![Build Status](https://travis-ci.org/modernistik/parse-stack.svg?branch=master)](https://travis-ci.org/modernistik/parse-stack)
18
- [![API Reference](http://img.shields.io/badge/api-docs-blue.svg)](https://www.modernistik.com/gems/parse-stack/)
18
+ [![API Reference](http://img.shields.io/badge/api-docs-blue.svg)](https://www.modernistik.com/gems/parse-stack/index.html)
19
19
 
20
20
  ### Questions?
21
21
  [![Gitter](https://badges.gitter.im/modernistik/parse-stack.svg)](https://gitter.im/modernistik/parse-stack?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
@@ -57,12 +57,12 @@ Master : true
57
57
  ```
58
58
 
59
59
  ## Overview
60
- Parse-Stack is a full stack framework that utilizes several ideas behind [DataMapper](http://datamapper.org/docs/find.html) and [ActiveModel](https://github.com/rails/rails/tree/master/activemodel) to manage and maintain larger scale ruby applications and tools that utilize the [Parse Server Platform](https://github.com/ParsePlatform/parse-server). If you are familiar with these technologies, the framework should feel familiar to you.
60
+ Parse-Stack is a full stack framework that utilizes several ideas behind [DataMapper](http://datamapper.org/docs/find.html) and [ActiveModel](https://github.com/rails/rails/tree/master/activemodel) to manage and maintain larger scale ruby applications and tools that utilize the [Parse Server Platform](http://parseplatform.org/). If you are familiar with these technologies, the framework should feel familiar to you.
61
61
 
62
62
  ```ruby
63
63
  require 'parse/stack'
64
64
 
65
- Parse.setup server_url: 'https://localhost:1337/parse',
65
+ Parse.setup server_url: 'http://localhost:1337/parse',
66
66
  app_id: APP_ID,
67
67
  api_key: REST_API_KEY,
68
68
  master_key: YOUR_MASTER_KEY # optional
@@ -80,6 +80,9 @@ class Song < Parse::Object
80
80
  belongs_to :artist
81
81
  # `like` is a Parse Relation to User class
82
82
  has_many :likes, as: :user, through: :relation
83
+
84
+ # deny public write to Song records by default
85
+ set_default_acl :public, read: true, write: false
83
86
  end
84
87
 
85
88
  class Artist < Parse::Object
@@ -153,6 +156,7 @@ result = Parse.call_function :myFunctionName, {param: value}
153
156
  - [Parse::ACL](#parseacl)
154
157
  - [Parse::Session](#parsesession)
155
158
  - [Parse::Installation](#parseinstallation)
159
+ - [Parse::Product](#parseproduct)
156
160
  - [Parse::Role](#parserole)
157
161
  - [Parse::User](#parseuser)
158
162
  - [Signup](#signup)
@@ -188,6 +192,7 @@ result = Parse.call_function :myFunctionName, {param: value}
188
192
  - [Creating, Saving and Deleting Records](#creating-saving-and-deleting-records)
189
193
  - [Create](#create)
190
194
  - [Saving](#saving)
195
+ - [Saving applying User ACLs](#saving-applying-user-acls)
191
196
  - [Raising an exception when save fails](#raising-an-exception-when-save-fails)
192
197
  - [Modifying Associations](#modifying-associations)
193
198
  - [Batch Requests](#batch-requests)
@@ -229,6 +234,7 @@ result = Parse.call_function :myFunctionName, {param: value}
229
234
  - [Geo Queries](#geo-queries)
230
235
  - [Max Distance Constraint](#max-distance-constraint)
231
236
  - [Bounding Box Constraint](#bounding-box-constraint)
237
+ - [Polygon Area Constraint](#polygon-area-constraint)
232
238
  - [Relational Queries](#relational-queries)
233
239
  - [Compound Queries](#compound-queries)
234
240
  - [Query Scopes](#query-scopes)
@@ -244,7 +250,8 @@ result = Parse.call_function :myFunctionName, {param: value}
244
250
  - [Register Webhooks](#register-webhooks)
245
251
  - [Parse REST API Client](#parse-rest-api-client)
246
252
  - [Request Caching](#request-caching)
247
- - [Development](#development)
253
+ - [Contributing](#contributing)
254
+ - [License](#license)
248
255
 
249
256
  <!-- END doctoc generated TOC please keep comment here to allow auto update -->
250
257
 
@@ -590,11 +597,27 @@ All `Parse::Object` subclasses have an `acl` property by default. With this prop
590
597
 
591
598
  artist.save
592
599
  ```
600
+ You may also set default ACLs for newly created insatnces of your subclasses using `set_default_acl`:
601
+
602
+ ```ruby
603
+ class AdminData < Parse::Object
604
+
605
+ # Disable public read and write
606
+ set_default_acl :public, read: false, write: false
607
+
608
+ # but allow members of the Admin role to read and write
609
+ set_default_acl 'Admin', role: true, read: true, write: true
610
+
611
+ end
612
+
613
+ data = AdminData.new
614
+ data.acl # => ACL({"role:Admin"=>{"read"=>true, "write"=>true}})
615
+ ```
593
616
 
594
617
  For more information about Parse record ACLs, see the documentation at [Security](http://docs.parseplatform.org/rest/guide/#security)
595
618
 
596
619
  ### [Parse::Session](https://www.modernistik.com/gems/parse-stack/Parse/Session.html)
597
- This class represents the data and columns contained in the standard Parse `_Session` collection. You may add additional properties and methods to this class. See [Session API Reference](https://www.modernistik.com/gems/parse-stack/Parse/Session). You may call `Parse.use_shortnames!` to use `Session` in addition to `Parse::Session`.
620
+ This class represents the data and columns contained in the standard Parse `_Session` collection. You may add additional properties and methods to this class. See [Session API Reference](https://www.modernistik.com/gems/parse-stack/Parse/Session.html). You may call `Parse.use_shortnames!` to use `Session` in addition to `Parse::Session`.
598
621
 
599
622
  You can get a specific `Parse::Session` given a session_token by using the `session` method. You can also find the user tied to a specific Parse session or session token with `Parse::User.session`.
600
623
 
@@ -606,25 +629,25 @@ session.user # the Parse user for this session
606
629
  # or fetch user with a session token
607
630
  user = Parse::User.session(token)
608
631
 
609
- # save an object with the priviledges (ACLs) of this user
632
+ # save an object with the privileges (ACLs) of this user
610
633
  some_object.save( session: user.session_token )
611
634
 
612
- # delete an object with the priviledges of this user
635
+ # delete an object with the privileges of this user
613
636
  some_object.destroy( session: user.session_token )
614
637
 
615
638
  ```
616
639
 
617
- ### [Parse::Installation](https://www.modernistik.com/gems/parse-stack/Parse/Installation)
618
- This class represents the data and columns contained in the standard Parse `_Installation` collection. You may add additional properties and methods to this class. See [Installation API Reference](https://www.modernistik.com/gems/parse-stack/Parse/Installation). You may call `Parse.use_shortnames!` to use `Installation` in addition to `Parse::Installation`.
640
+ ### [Parse::Installation](https://www.modernistik.com/gems/parse-stack/Parse/Installation.html)
641
+ This class represents the data and columns contained in the standard Parse `_Installation` collection. You may add additional properties and methods to this class. See [Installation API Reference](https://www.modernistik.com/gems/parse-stack/Parse/Installation.html). You may call `Parse.use_shortnames!` to use `Installation` in addition to `Parse::Installation`.
619
642
 
620
- ### [Parse::Product](https://www.modernistik.com/gems/parse-stack/Parse/Product)
621
- This class represents the data and columns contained in the standard Parse `_Product` collection. You may add additional properties and methods to this class. See [Product API Reference](https://www.modernistik.com/gems/parse-stack/Parse/Product). You may call `Parse.use_shortnames!` to use `Product` in addition to `Parse::Product`.
643
+ ### [Parse::Product](https://www.modernistik.com/gems/parse-stack/Parse/Product.html)
644
+ This class represents the data and columns contained in the standard Parse `_Product` collection. You may add additional properties and methods to this class. See [Product API Reference](https://www.modernistik.com/gems/parse-stack/Parse/Product.html). You may call `Parse.use_shortnames!` to use `Product` in addition to `Parse::Product`.
622
645
 
623
- ### [Parse::Role](https://www.modernistik.com/gems/parse-stack/Parse/Role)
624
- This class represents the data and columns contained in the standard Parse `_Role` collection. You may add additional properties and methods to this class. See [Roles API Reference](https://www.modernistik.com/gems/parse-stack/Parse/Role). You may call `Parse.use_shortnames!` to use `Role` in addition to `Parse::Role`.
646
+ ### [Parse::Role](https://www.modernistik.com/gems/parse-stack/Parse/Role.html)
647
+ This class represents the data and columns contained in the standard Parse `_Role` collection. You may add additional properties and methods to this class. See [Roles API Reference](https://www.modernistik.com/gems/parse-stack/Parse/Role.html). You may call `Parse.use_shortnames!` to use `Role` in addition to `Parse::Role`.
625
648
 
626
- ### [Parse::User](https://www.modernistik.com/gems/parse-stack/Parse/User)
627
- This class represents the data and columns contained in the standard Parse `_User` collection. You may add additional properties and methods to this class. See [User API Reference](https://www.modernistik.com/gems/parse-stack/Parse/User). You may call `Parse.use_shortnames!` to use `User` in addition to `Parse::User`.
649
+ ### [Parse::User](https://www.modernistik.com/gems/parse-stack/Parse/User.html)
650
+ This class represents the data and columns contained in the standard Parse `_User` collection. You may add additional properties and methods to this class. See [User API Reference](https://www.modernistik.com/gems/parse-stack/Parse/User.html). You may call `Parse.use_shortnames!` to use `User` in addition to `Parse::User`.
628
651
 
629
652
  #### Signup
630
653
  You can signup new users in two ways. You can either use a class method `Parse::User.signup` to create a new user with the minimum fields of username, password and email, or create a `Parse::User` object can call the `signup!` method. If signup fails, it will raise the corresponding exception.
@@ -638,7 +661,7 @@ user.signup!
638
661
  ```
639
662
 
640
663
  ##### Third-Party Services
641
- You can signup users using third-party services like Facebook and Twitter as described in: [Signing Up and Logging In](http://docs.parseplatform.org/rest/guide/#signing-up). To do this with Parse-Stack, you can call the `Parse::User.autologin_service` method by passing the service name and the corresponding authentication hash data. For a listing of supported third-party authentication services, see [OAuth](https://github.com/ParsePlatform/parse-server/wiki/OAuth).
664
+ You can signup users using third-party services like Facebook and Twitter as described in: [Signing Up and Logging In](http://docs.parseplatform.org/rest/guide/#signing-up). To do this with Parse-Stack, you can call the `Parse::User.autologin_service` method by passing the service name and the corresponding authentication hash data. For a listing of supported third-party authentication services, see [OAuth](http://docs.parseplatform.org/parse-server/guide/#oauth-and-3rd-party-authentication).
642
665
 
643
666
  ```ruby
644
667
  fb_auth = {}
@@ -1374,7 +1397,7 @@ To commit a new record or changes to an existing record to Parse, use the `#save
1374
1397
  The save operation can handle both creating and updating existing objects. If you do not want to update the association data of a changed object, you may use the `#update` method to only save the changed property values. In the case where you want to force update an object even though it has not changed, to possibly trigger your `before_save` hooks, you can use the `#update!` method. In addition, just like with other ActiveModel objects, you may call `reload!` to fetch the current record again from the data store.
1375
1398
 
1376
1399
  ### Saving applying User ACLs
1377
- You may save and delete objects from Parse on behalf of a logged in user by passing the session token to the call to `save` or `destroy`. Doing so will allow Parse to apply the ACLs of this user against the record to see if the user is authorized to read or write the record. See [Parse::Actions](https://www.modernistik.com/gems/parse-stack/Parse/Actions).
1400
+ You may save and delete objects from Parse on behalf of a logged in user by passing the session token to the call to `save` or `destroy`. Doing so will allow Parse to apply the ACLs of this user against the record to see if the user is authorized to read or write the record. See [Parse::Actions](https://www.modernistik.com/gems/parse-stack/Parse/Core/Actions.html).
1378
1401
 
1379
1402
  ```ruby
1380
1403
  user = Parse::User.login('myuser','pass')
@@ -1745,7 +1768,7 @@ The `where` clause is based on utilizing a set of constraints on the defined col
1745
1768
  { :column.constraint => value }
1746
1769
  ```
1747
1770
 
1748
- ## Query Constraints
1771
+ ## [Query Constraints](https://www.modernistik.com/gems/parse-stack/Parse/Constraint.html)
1749
1772
  Most of the constraints supported by Parse are available to `Parse::Query`. Assuming you have a column named `field`, here are some examples. For an explanation of the constraints, please see [Parse Query Constraints documentation](http://docs.parseplatform.org/rest/guide/#queries). You can build your own custom query constraints by creating a `Parse::Constraint` subclass. For all these `where` clauses assume `q` is a `Parse::Query` object.
1750
1773
 
1751
1774
  #### Equals
@@ -1958,7 +1981,7 @@ Song.all :artist => Artist.pointer(artist_id)
1958
1981
  Song.all :artist => Parse::Pointer.new("Artist", artist_id)
1959
1982
  ```
1960
1983
 
1961
- ### Geo Queries
1984
+ ### [Geo Queries](https://www.modernistik.com/gems/parse-stack/Parse/Constraint/NearSphereQueryConstraint.html)
1962
1985
  Equivalent to the `$nearSphere` Parse query operation. This is only applicable if the field is of type `GeoPoint`. This will query Parse and return a list of results ordered by distance with the nearest object being first.
1963
1986
 
1964
1987
  ```ruby
@@ -1984,7 +2007,7 @@ PlaceObject.all :location.near => geopoint.max_miles(10)
1984
2007
 
1985
2008
  We will support `$maxDistanceInKilometers` (for kms) and `$maxDistanceInRadians` (for radian angle) in the future.
1986
2009
 
1987
- #### Bounding Box Constraint
2010
+ #### [Bounding Box Constraint](https://www.modernistik.com/gems/parse-stack/Parse/Constraint/WithinGeoBoxQueryConstraint.html)
1988
2011
  Equivalent to the `$within` Parse query operation and `$box` geopoint constraint. The rectangular bounding box is defined by a southwest point as the first parameter, followed by the a northeast point. Please note that Geo box queries that cross the international date lines are not currently supported by Parse.
1989
2012
 
1990
2013
  ```ruby
@@ -1999,6 +2022,22 @@ ne = Parse::GeoPoint.new 36.12, -115.31 # Las Vegas
1999
2022
  PlaceObject.all :location.within_box => [sw,ne]
2000
2023
  ```
2001
2024
 
2025
+ #### [Polygon Area Constraint](https://www.modernistik.com/gems/parse-stack/Parse/Constraint/WithinPolygonQueryConstraint.html)
2026
+ Equivalent to the `$geoWithin` Parse query operation and `$polygon` geopoint constraint. The polygon area is described by a list of `Parse::GeoPoint` objects and should contain 3 or more points. This feature is only available in Parse-Server version 2.4.2 and later.
2027
+
2028
+ ```ruby
2029
+ # As many points as you want, minimum 3
2030
+ q.where :field.within_polygon => [geopoint1, geopoint2, geopoint3]
2031
+
2032
+ # Polygon for the Bermuda Triangle
2033
+ bermuda = Parse::GeoPoint.new 32.3078000,-64.7504999 # Bermuda
2034
+ miami = Parse::GeoPoint.new 25.7823198,-80.2660226 # Miami, FL
2035
+ san_juan = Parse::GeoPoint.new 18.3848232,-66.0933608 # San Juan, PR
2036
+
2037
+ # get all sunken ships inside the Bermuda Triangle
2038
+ SunkenShip.all :location.within_polygon => [bermuda, san_juan, miami]
2039
+ ```
2040
+
2002
2041
  ### Relational Queries
2003
2042
  Equivalent to the `$relatedTo` Parse query operation. If you want to retrieve objects that are members of a `Relation` field in your Parse class.
2004
2043
 
data/Rakefile CHANGED
@@ -29,6 +29,6 @@ end
29
29
 
30
30
  YARD::Rake::YardocTask.new do |t|
31
31
  t.files = ['lib/**/*.rb'] # optional
32
- # t.options = ['--any', '--extra', '--opts'] # optional
32
+ t.options = ['-o', 'doc/parse-stack' ] # optional
33
33
  t.stats_options = ['--list-undoc'] # optional
34
34
  end
data/bin/console CHANGED
@@ -6,16 +6,24 @@ require 'dotenv'
6
6
  require 'byebug'
7
7
  Dotenv.load
8
8
 
9
- Parse.setup # cache: 'redis://localhost:6379'
9
+ def setup
10
+ Parse.setup # cache: 'redis://localhost:6379'
10
11
 
11
- puts "[ParseServerURL] #{Parse.client.server_url}"
12
- puts "[ParseAppID] #{Parse.client.app_id}"
12
+ puts "[ParseServerURL] #{Parse.client.server_url}"
13
+ puts "[ParseAppID] #{Parse.client.app_id}"
13
14
 
14
- if Parse.client.master_key.present?
15
- Parse.auto_generate_models!.each do |model|
16
- puts "Generated #{model}"
15
+ if Parse.client.master_key.present?
16
+ Parse.auto_generate_models!.each do |model|
17
+ puts "Generated #{model}"
18
+ end
17
19
  end
20
+
18
21
  end
22
+ puts "Type 'setup' to connect to Parse-Server"
23
+
24
+ # Create shortnames
25
+ Parse.use_shortnames!
26
+
19
27
  # You can add fixtures and/or initialization code here to make experimenting
20
28
  # with your gem easier. You can also use a different console, if you like.
21
29
 
data/bin/parse-console CHANGED
@@ -3,7 +3,8 @@
3
3
  require 'optparse'
4
4
  require 'json'
5
5
  require 'open-uri'
6
- require 'active_support/all'
6
+ require 'active_support'
7
+ require 'active_support/core_ext'
7
8
 
8
9
  DEFAULT_CONFIG_FILE = 'config.json'
9
10
  DEFAULT_CONFIG_CONTENTS = {
@@ -10,7 +10,7 @@ module Parse
10
10
  # Send analytics data.
11
11
  # @param event_name [String] the name of the event.
12
12
  # @param metrics [Hash] the metrics to attach to event.
13
- # @see https://parseplatform.github.io/docs/rest/guide/#analytics-app-open-analytics Parse Analytics
13
+ # @see http://docs.parseplatform.org/rest/guide/#analytics Parse Analytics
14
14
  def send_analytics(event_name, metrics = {})
15
15
  request :post, "events/#{event_name}", body: metrics
16
16
  end
@@ -12,7 +12,7 @@ module Parse
12
12
  # Update the schema for a collection.
13
13
  # @param payload [Hash] the paylod for the Push notification.
14
14
  # @return [Parse::Response]
15
- # @see https://parseplatform.github.io/docs/rest/guide/#sending-pushes Sending Pushes
15
+ # @see http://docs.parseplatform.org/rest/guide/#sending-pushes Sending Pushes
16
16
  def push(payload = {})
17
17
  request :post, PUSH_PATH, body: payload.as_json
18
18
  end
@@ -39,10 +39,10 @@ module Parse
39
39
  # An ACL represents the dirty-trackable Parse Permissions object used for
40
40
  # each record. In Parse, it is composed a hash-like object that represent
41
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
42
+ # (ex. User/Role/Public), you can define read/write privileges on a particular
43
43
  # record through a {Parse::ACL::Permission} instance.
44
44
  #
45
- # If you want to give priviledges for an action (ex. read/write),
45
+ # If you want to give privileges for an action (ex. read/write),
46
46
  # you set that particular permission it to true. If you want to deny a
47
47
  # permission, then you set it to false. Any denied permissions will not be
48
48
  # part of the final hash structure that is sent to parse, as omission of a permission
@@ -82,8 +82,26 @@ module Parse
82
82
  # artist.acl.apply_role "Admins", true, true
83
83
  #
84
84
  # artist.save
85
+ #
86
+ # You may also set default ACLs for your subclasses by using {Parse::Object.set_default_acl}.
87
+ # These will be get applied for newly created instances. All subclasses have
88
+ # public read and write enabled by default.
89
+ #
90
+ # class AdminData < Parse::Object
91
+ #
92
+ # # Disable public read and write
93
+ # set_default_acl :public, read: true, write: false
94
+ #
95
+ # # Allow Admin roles to read/write
96
+ # set_default_acl 'Admin', role: true, read: true, write: true
97
+ #
98
+ # end
99
+ #
100
+ # data = AdminData.new
101
+ # data.acl # => ACL({"role:Admin"=>{"read"=>true, "write"=>true}})
102
+ #
85
103
  # For more information about Parse record ACLs, see the documentation on
86
- # {https://parseplatform.github.io/docs/rest/guide/#security Security}.
104
+ # {http://docs.parseplatform.org/rest/guide/#security Security}.
87
105
  class ACL < DataType
88
106
 
89
107
  # @!attribute permissions
@@ -101,20 +119,28 @@ module Parse
101
119
  @permissions ||= {}
102
120
  end
103
121
  # The key field value for public permissions.
104
- PUBLIC = "*"
122
+ PUBLIC = "*".freeze
105
123
 
106
124
  # Create a new ACL with default Public read/write permissions and any
107
125
  # overrides from the input hash format.
108
126
  # @param acls [Hash] a Parse-compatible hash acl format.
109
127
  # @param owner [Parse::Object] a delegate to receive notifications of acl changes.
110
128
  # This delegate must support receiving `acl_will_change!` method.
111
- def initialize(acls = {}, owner: nil)
112
- everyone(true, true) # sets Public read/write
129
+ def initialize(acls = nil, owner: nil)
130
+ acls = acls.as_json if acls.is_a?(ACL)
131
+ self.attributes = acls if acls.is_a?(Hash)
113
132
  @delegate = owner
114
- if acls.is_a?(Hash)
115
- self.attributes = acls
116
- end
133
+ end
117
134
 
135
+ # Create a new ACL with default Public read/write permissions and any
136
+ # overrides from the input hash format.
137
+ # @param read [Boolean] the read permissions for PUBLIC (default: true)
138
+ # @param write [Boolean] the write permissions for PUBLIC (default: true)
139
+ # @version 1.7.0
140
+ def self.everyone(read = true, write = true)
141
+ acl = Parse::ACL.new
142
+ acl.everyone(read, write)
143
+ acl
118
144
  end
119
145
 
120
146
  # Create a new ACL::Permission instance with the supplied read and write values.
@@ -125,12 +151,27 @@ module Parse
125
151
  def self.permission(read, write = nil)
126
152
  ACL::Permission.new(read, write)
127
153
  end
128
-
129
- # @return [Boolean] whether two ACLs have the same set of priviledges.
154
+ # Determines whether two ACLs or a Parse-ACL hash is equivalent to this object.
155
+ # @example
156
+ # acl = Parse::ACL.new
157
+ # # create a public read-only ACL
158
+ # acl.apply :public, true, false
159
+ # acl.as_json # => {'*' => { "read" => true }}
160
+ #
161
+ # create a second instance with similar privileges
162
+ # acl2 = Parse::ACL.everyone(true, false)
163
+ # acl2.as_json # => {'*' => { "read" => true }}
164
+ #
165
+ # acl == acl2 # => true
166
+ # acl == {'*' => { "read" => true }} # hash ok too
167
+ #
168
+ # acl2.apply_role 'Admin', true, true # rw for Admins
169
+ # acl == acl2 # => false
170
+ #
171
+ # @return [Boolean] whether two ACLs have the same set of privileges.
130
172
  def ==(other_acl)
131
- return false unless other_acl.is_a?(self.class)
132
- return false if permissions.keys != other_acl.permissions.keys
133
- permissions.keys.all? { |per| permissions[per] == other_acl.permissions[per] }
173
+ return false unless other_acl.is_a?(self.class) || other_acl.is_a?(Hash)
174
+ as_json == other_acl.as_json
134
175
  end
135
176
 
136
177
  # Set the public read and write permissions.
@@ -162,7 +203,7 @@ module Parse
162
203
  end
163
204
  end
164
205
 
165
- # Apply a new permission with a given objectId (or tag)
206
+ # Apply a new permission with a given objectId, tag or :public.
166
207
  # @overload apply(user, read = nil, write = nil)
167
208
  # Set the read and write permissions for this user on this ACL.
168
209
  # @param user [Parse::User] the user object.
@@ -175,7 +216,8 @@ module Parse
175
216
  # @param write [Boolean] the write permission.
176
217
  # @overload apply(id, read = nil, write = nil)
177
218
  # Set the read and write permissions for this objectId on this ACL.
178
- # @param id [String] the objectId for a {Parse::User}.
219
+ # @param id [String|:public] the objectId for a {Parse::User}. If :public is passed,
220
+ # then the {Parse::ACL::PUBLIC} read and write permissions will be modified.
179
221
  # @param read [Boolean] the read permission.
180
222
  # @param write [Boolean] the write permission.
181
223
  # @return [Hash] the current set of permissions.
@@ -183,12 +225,14 @@ module Parse
183
225
  def apply(id, read = nil, write = nil)
184
226
  return apply_role(id,read,write) if id.is_a?(Parse::Role)
185
227
  id = id.id if id.is_a?(Parse::Pointer)
186
- return unless id.present?
228
+ unless id.present?
229
+ raise ArgumentError, "Invalid argument applying ACLs: must be either objectId, role or :public"
230
+ end
231
+ id = PUBLIC if id.to_sym == :public
187
232
  # create a new Permissions
188
233
  permission = ACL.permission(read, write)
189
234
  # if the input is already an Permission object, then set it directly
190
235
  permission = read if read.is_a?(Parse::ACL::Permission)
191
-
192
236
  if permission.is_a?(ACL::Permission)
193
237
  if permissions[id.to_s] != permission
194
238
  will_change! # dirty track
@@ -215,6 +259,8 @@ module Parse
215
259
 
216
260
  # Used for object conversion when formatting the input/output value in
217
261
  # Parse::Object properties
262
+ # @param value [Hash] a Parse ACL hash to construct a Parse::ACL instance.
263
+ # @param delegate [Object] any object that would need to be notified of changes.
218
264
  # @return [ACL]
219
265
  # @see Parse::DataType
220
266
  def self.typecast(value, delegate = nil)
@@ -224,8 +270,7 @@ module Parse
224
270
  # Used for JSON serialization. Only if an attribute is non-nil, do we allow it
225
271
  # in the Permissions hash, since omission means denial of priviledge. If the
226
272
  # permission value has neither read or write, then the entire record has been denied
227
- # all priviledges
228
-
273
+ # all privileges
229
274
  # @return [Hash]
230
275
  def attributes
231
276
  permissions.select {|k,v| v.present? }.as_json
@@ -280,7 +325,7 @@ module Parse
280
325
  # @return [Boolean] whether this permission is allowed.
281
326
  attr_reader :write
282
327
 
283
- # Create a new permission with the given read and write priviledges.
328
+ # Create a new permission with the given read and write privileges.
284
329
  # @overload new(read = nil, write = nil)
285
330
  # @param read [Boolean] whether reading is allowed.
286
331
  # @param write [Boolean] whether writing is allowed.
@@ -293,7 +338,7 @@ module Parse
293
338
  #
294
339
  def initialize(r_perm = nil, w_perm = nil)
295
340
  if r_perm.is_a?(Hash)
296
- r_perm.symbolize_keys!
341
+ r_perm = r_perm.symbolize_keys
297
342
  @read = r_perm[:read].present?
298
343
  @write = r_perm[:write].present?
299
344
  else
@@ -15,7 +15,7 @@ module Parse
15
15
  # to implement your associations, will affect how `has_many` works in
16
16
  # Parse-Stack. Parse natively supports one-to-many and many-to-many
17
17
  # relationships using `Array` and `Relations`, as described in
18
- # {https://parseplatform.github.io/docs/js/guide/#relational-data Parse Relational Data}.
18
+ # {http://docs.parseplatform.org/js/guide/#relations Parse Relational Data}.
19
19
  # Both of these methods require you define a specific column type in your
20
20
  # Parse table that will be used to store information about the association.
21
21
  #
@@ -169,7 +169,7 @@ module Parse
169
169
  # *ParseRelation-Approach*
170
170
  #
171
171
  # Other than the use of arrays, Parse supports native one-to-many and many-to-many
172
- # associations through what is referred to as a {https://parseplatform.github.io/docs/js/guide/#many-to-many-relationships Parse Relation}.
172
+ # associations through what is referred to as a {http://docs.parseplatform.org/js/guide/#many-to-many Parse Relation}.
173
173
  # This is implemented by defining a column to be of type `Relation` which
174
174
  # refers to a foreign class. Parse-Stack supports this by passing the
175
175
  # `through: :relation` option to the `has_many` method. Designating a column
@@ -183,7 +183,7 @@ module Parse
183
183
  #
184
184
  # *3*. Applying query constraints for a set of records within a relation is performed against the foreign table class, not the class having the relational column.
185
185
  #
186
- # The Parse documentation provides more details on associations, see {http://parseplatform.github.io/docs/ios/guide/#relations Parse Relations Guide}.
186
+ # The Parse documentation provides more details on associations, see {http://docs.parseplatform.org/ios/guide/#relations Parse Relations Guide}.
187
187
  # Parse-Stack will handle the work for (2) and (3) automatically.
188
188
  #
189
189
  # In the example below, a `Band` can have thousands of `Fans`. We setup a
@@ -74,11 +74,11 @@ module Parse
74
74
  # *OAuth-Login*
75
75
  #
76
76
  # You can signup users using third-party services like Facebook and Twitter as
77
- # described in {https://parseplatform.github.io/docs/rest/guide/#signing-up-and-logging-in
77
+ # described in {http://docs.parseplatform.org/rest/guide/#signing-up
78
78
  # Signing Up and Logging In}. To do this with Parse-Stack, you can call the
79
79
  # {Parse::User.autologin_service} method by passing the service name and the
80
80
  # corresponding authentication hash data. For a listing of supported third-party
81
- # authentication services, see {https://github.com/ParsePlatform/parse-server/wiki/OAuth OAuth}.
81
+ # authentication services, see {http://docs.parseplatform.org/parse-server/guide/#oauth-and-3rd-party-authentication OAuth}.
82
82
  #
83
83
  # fb_auth = {}
84
84
  # fb_auth[:id] = "123456789"
@@ -105,12 +105,12 @@ module Parse
105
105
  #
106
106
  # You can link or unlink user accounts with third-party services like
107
107
  # Facebook and Twitter as described in:
108
- # {https://parseplatform.github.io/docs/rest/guide/#linking Linking and Unlinking Users}.
108
+ # {http://docs.parseplatform.org/rest/guide/#linking-users Linking and Unlinking Users}.
109
109
  # To do this, you must first get the corresponding authentication data for the
110
110
  # specific service, and then apply it to the user using the linking and
111
111
  # unlinking methods. Each method returns true or false if the action was
112
112
  # successful. For a listing of supported third-party authentication services,
113
- # see {https://github.com/ParsePlatform/parse-server/wiki/OAuth OAuth}.
113
+ # see {http://docs.parseplatform.org/parse-server/guide/#oauth-and-3rd-party-authentication OAuth}.
114
114
  #
115
115
  # user = Parse::User.first
116
116
  #
@@ -157,8 +157,8 @@ module Parse
157
157
  # @see Parse::Model.autosave_on_create
158
158
  def first_or_create(query_attrs = {}, resource_attrs = {})
159
159
 
160
- query_attrs.symbolize_keys!
161
- resource_attrs.symbolize_keys!
160
+ query_attrs = query_attrs.symbolize_keys
161
+ resource_attrs = resource_attrs.symbolize_keys
162
162
  obj = query(query_attrs).first
163
163
 
164
164
  if obj.blank?
@@ -511,7 +511,7 @@ module Parse
511
511
  # we will create the object. If the object has an id, we will update the record.
512
512
  #
513
513
  # You may pass a session token to the `session` argument to perform this actions
514
- # with the priviledges of a certain user.
514
+ # with the privileges of a certain user.
515
515
  #
516
516
  # You can define before and after :save callbacks
517
517
  # autoraise: set to true will automatically raise an exception if the save fails
@@ -116,7 +116,7 @@ module Parse
116
116
  # or with an array of two items where the first is the lat and the second is the lng (ex. [32.22,-118.81])
117
117
  def attributes=(h)
118
118
  if h.is_a?(Hash)
119
- h.symbolize_keys!
119
+ h = h.symbolize_keys
120
120
  @latitude = h[:latitude].to_f || h[:lat].to_f || @latitude
121
121
  @longitude = h[:longitude].to_f || h[:lng].to_f || @longitude
122
122
  elsif h.is_a?(Array) && h.count == 2
@@ -165,12 +165,12 @@ module Parse
165
165
  # to set it to something different.
166
166
  class << self
167
167
 
168
- attr_accessor :disable_serialized_string_date, :parse_class, :acl
169
-
168
+ attr_accessor :disable_serialized_string_date, :parse_class
169
+ attr_reader :default_acls
170
170
  # @!attribute disable_serialized_string_date
171
171
  # Disables returning a serialized string date properties when encoding to JSON.
172
172
  # This affects created_at and updated_at fields in order to be backwards compatible with old SDKs.
173
- # @return [Boolean]
173
+ # @return [Boolean] the disabled status of whether string dates should be serialized.
174
174
 
175
175
  # The class method to override the implicitly assumed Parse collection name
176
176
  # in your Parse database. The default Parse collection name is the singular form
@@ -195,16 +195,51 @@ module Parse
195
195
  @parse_class
196
196
  end
197
197
 
198
- # A method to override the default ACLs for new objects for this particular
199
- # subclass.
200
- # @param acls [Hash] a hash with key value pairs of ACLs permissions.
201
- # @return [ACL] the default ACLs for this class.
202
- def acl(acls = {}, owner: nil)
203
- acls = {"*" => {read: true, write: false} }.merge( acls ).symbolize_keys
204
- @acl ||= Parse::ACL.new(acls, owner: owner)
198
+ # The set of default ACLs to be applied on newly created instances of this class.
199
+ # By default, public read and write are enabled.
200
+ # @see Parse::ACL.everyone
201
+ # @return [Parse::ACL] the current default ACLs for this class.
202
+ def default_acls
203
+ @default_acls ||= Parse::ACL.everyone # default public read/write
205
204
  end
206
205
 
207
- end
206
+ # A method to set default ACLs to be applied for newly created
207
+ # instances of this class. All subclasses have public read and write enabled
208
+ # by default.
209
+ # @example
210
+ # class AdminData < Parse::Object
211
+ #
212
+ # # Disable public read and write
213
+ # set_default_acl :public, read: false, write: false
214
+ #
215
+ # # but allow members of the Admin role to read and write
216
+ # set_default_acl 'Admin', role: true, read: true, write: true
217
+ #
218
+ # end
219
+ #
220
+ # data = AdminData.new
221
+ # data.acl # => ACL({"role:Admin"=>{"read"=>true, "write"=>true}})
222
+ #
223
+ # @param id [String|:public] The name for ACL entry. This can be an objectId, a role name or :public.
224
+ # @param read [Boolean] Whether to allow read permissions (default: false).
225
+ # @param write [Boolean] Whether to allow write permissions (default: false).
226
+ # @param role [Boolean] Whether the `id` argument should be applied as a role name.
227
+ # @see Parse::ACL#apply_role
228
+ # @see Parse::ACL#apply
229
+ # @version 1.7.0
230
+ def set_default_acl(id, read: false, write: false, role: false)
231
+ unless id.present?
232
+ raise ArgumentError, "Invalid argument applying #{self}.default_acls : must be either objectId, role or :public"
233
+ end
234
+ role ? default_acls.apply_role(id, read, write) : default_acls.apply(id, read, write)
235
+ end
236
+
237
+ # @!visibility private
238
+ def acl(acls, owner: nil)
239
+ raise "[#{self}.acl DEPRECATED] - Use `#{self}.default_acl` instead."
240
+ end
241
+
242
+ end # << self
208
243
 
209
244
  # @return [String] the Parse class for this object.
210
245
  # @see Parse::Object.parse_class
@@ -255,9 +290,10 @@ module Parse
255
290
  apply_attributes!(opts, dirty_track: !dirty_track)
256
291
  end
257
292
 
258
- if self.acl.blank?
259
- self.acl = self.class.acl({}, owner: self) || Parse::ACL.new(owner: self)
260
- end
293
+ # if no ACLs, then apply the class default acls
294
+ # ACL.typecast will auto convert of Parse::ACL
295
+ self.acl = self.class.default_acls.as_json if self.acl.nil?
296
+
261
297
  clear_changes! if @id.present? #then it was an import
262
298
 
263
299
  # do not apply defaults on a pointer because it will stop it from being
data/lib/parse/query.rb CHANGED
@@ -13,7 +13,7 @@ require 'active_support/core_ext'
13
13
 
14
14
  module Parse
15
15
  # The {Parse::Query} class provides the lower-level querying interface for
16
- # your Parse collections by utilizing the {http://parseplatform.github.io/docs/rest/guide/#queries
16
+ # your Parse collections by utilizing the {http://docs.parseplatform.org/rest/guide/#queries
17
17
  # REST Querying interface}. This is the main engine behind making Parse queries
18
18
  # on remote collections. It takes a set of constraints and generates the
19
19
  # proper hash parameters that are passed to an API request in order to retrive
@@ -58,7 +58,7 @@ module Parse
58
58
  # Most of the constraints supported by Parse are available to `Parse::Query`.
59
59
  # Assuming you have a column named `field`, here are some examples. For an
60
60
  # explanation of the constraints, please see
61
- # {http://parseplatform.github.io/docs/rest/guide/#queries Parse Query Constraints documentation}.
61
+ # {http://docs.parseplatform.org/rest/guide/#queries Parse Query Constraints documentation}.
62
62
  # You can build your own custom query constraints by creating a `Parse::Constraint`
63
63
  # subclass. For all these `where` clauses assume `q` is a `Parse::Query` object.
64
64
  class Query
@@ -131,7 +131,7 @@ module Parse
131
131
  # @!attribute [rw] session_token
132
132
  # Set the session token to send with this API request. A session token is tied to
133
133
  # a logged in {Parse::User}. When sending a session_token in the request,
134
- # this performs the query on behalf of the user (with their allowed priviledges).
134
+ # this performs the query on behalf of the user (with their allowed privileges).
135
135
  # Using the short hand (inline) form, you can also pass an authenticated {Parse::User} instance
136
136
  # or a {Parse::Session} instance.
137
137
  # @example
@@ -107,7 +107,7 @@ module Parse
107
107
  d = { __type: Parse::Model::TYPE_DATE, iso: d.iso8601(3) } if d.respond_to?(:iso8601)
108
108
  d = d.pointer if d.respond_to?(:pointer) #simplified query object
109
109
  d = d.to_s if d.is_a?(Regexp)
110
- #d = d.pointer if d.is_a?(Parse::Object) #simplified query object
110
+ # d = d.pointer if d.is_a?(Parse::Object) #simplified query object
111
111
  # d = d.compile
112
112
  if d.is_a?(Parse::Query)
113
113
  compiled = d.compile(encode: false, includeClassName: true)
@@ -663,6 +663,50 @@ module Parse
663
663
  end
664
664
  end
665
665
 
666
+ # Equivalent to the `$geoWithin` Parse query operation and `$polygon` geopoints
667
+ # constraint. The polygon area is defined by a list of {Parse::GeoPoint}
668
+ # objects that make up the enclosed area. A polygon query should have 3 or more geopoints.
669
+ # Please note that some Geo queries that cross the international date lines are not currently
670
+ # supported by Parse.
671
+ #
672
+ # # As many points as you want, minimum 3
673
+ # q.where :field.within_polygon => [geopoint1, geopoint2, geopoint3]
674
+ #
675
+ # # Polygon for the Bermuda Triangle
676
+ # bermuda = Parse::GeoPoint.new 32.3078000,-64.7504999 # Bermuda
677
+ # miami = Parse::GeoPoint.new 25.7823198,-80.2660226 # Miami, FL
678
+ # san_juan = Parse::GeoPoint.new 18.3848232,-66.0933608 # San Juan, PR
679
+ #
680
+ # # get all sunken ships inside the Bermuda Triangle
681
+ # SunkenShip.all :location.within_polygon => [bermuda, san_juan, miami]
682
+ #
683
+ class WithinPolygonQueryConstraint < Constraint
684
+ # @!method within_polygon
685
+ # A registered method on a symbol to create the constraint. Maps to Parse
686
+ # operator "$geoWithin" with "$polygon" subconstraint. Takes an array of {Parse::GeoPoint} objects.
687
+ # @example
688
+ # # As many points as you want
689
+ # q.where :field.within_polygon => [geopoint1, geopoint2, geopoint3]
690
+ # @return [WithinPolygonQueryConstraint]
691
+ # @version 1.7.0 (requires Server v2.4.2 or later)
692
+ contraint_keyword :$geoWithin
693
+ register :within_polygon
694
+
695
+ # @return [Hash] the compiled constraint.
696
+ def build
697
+ geopoint_values = formatted_value
698
+ unless geopoint_values.is_a?(Array) &&
699
+ geopoint_values.all? {|point| point.is_a?(Parse::GeoPoint) } &&
700
+ geopoint_values.count > 2
701
+ raise ArgumentError, '[Parse::Query] Invalid query value parameter passed to'\
702
+ ' `within_polygon` constraint: Value must be an array with 3'\
703
+ ' or more `Parse::GeoPoint` objects'
704
+ end
705
+
706
+ { @operation.operand => { :$geoWithin => { :$polygon => geopoint_values } } }
707
+ end
708
+ end
709
+
666
710
  end
667
711
 
668
712
  end
@@ -6,6 +6,6 @@ module Parse
6
6
  # The Parse Server SDK for Ruby
7
7
  module Stack
8
8
  # The current version.
9
- VERSION = "1.6.13"
9
+ VERSION = "1.7.0"
10
10
  end
11
11
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: parse-stack
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.13
4
+ version: 1.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anthony Persaud
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-06-09 00:00:00.000000000 Z
11
+ date: 2017-06-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel