Class: Parse::ACL

Inherits:
DataType show all
Defined in:
lib/parse/model/acl.rb

Overview

An ACL represents the dirty-trackable Parse Permissions object used for each record. In Parse, it is composed a hash-like object that represent User objectIds and/or a set of Role names. For each entity (ex. User/Role/Public), you can define read/write privileges on a particular record through a Permission instance.

If you want to give privileges for an action (ex. read/write), you set that particular permission it to true. If you want to deny a permission, then you set it to false. Any denied permissions will not be part of the final hash structure that is sent to parse, as omission of a permission means denial.

An ACL is represented by a JSON object with the keys being Parse::User object ids or the special key of “*”, which indicates the public access permissions. The value of each key in the hash is a Permission object which defines the boolean permission state for read and write. The example below illustrates a Parse ACL JSON object where there is a public read permission, but public write is prevented. In addition, the user with id “3KmCvT7Zsb” is allowed to both read and write this record, and the “Admins” role is also allowed write access.

{ "*": { "read": true }, "3KmCvT7Zsb": { "read": true, "write": true }, "role:Admins": { "write": true } } 

All Parse::Object subclasses have an acl property by default. With this property, you can apply and delete permissions for this particular Parse object record.

user = Parse::User.first artist = Artist.first artist.acl # "*": { "read": true, "write": true }  # apply public read, but no public write artist.acl.everyone true, false # allow user to have read and write access artist.acl.apply user.id, true, true # remove all permissions for this user id artist.acl.delete user.id # allow the 'Admins' role read and write artist.acl.apply_role "Admins", true, true # remove write from all attached privileges artist.acl.no_write! # remove all attached privileges artist.acl.master_key_only! artist.save 

You may also set default ACLs for your subclasses by using Object.set_default_acl. These will be get applied for newly created instances. All subclasses have public read and write enabled by default.

class AdminData < Parse::Object # Disable public read and write  set_default_acl :public, read: true, write: false # Allow Admin roles to read/write  set_default_acl 'Admin', role: true, read: true, write: true end data = AdminData.new data.acl # => ACL({"role:Admin"=>{"read"=>true, "write"=>true}}) 

For more information about Parse record ACLs, see the documentation on Security.

Defined Under Namespace

Classes: Permission

Constant Summary collapse

PUBLIC =

The key field value for public permissions.

"*".freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(acls = nil, owner: nil) ⇒ ACL

Create a new ACL with default Public read/write permissions and any overrides from the input hash format.

Parameters:

  • acls (Hash) (defaults to: nil)

    a Parse-compatible hash acl format.

  • owner (Parse::Object) (defaults to: nil)

    a delegate to receive notifications of acl changes. This delegate must support receiving `acl_will_change!` method.

 141 142 143 144 145
# File 'lib/parse/model/acl.rb', line 141 def initialize(acls = nil, owner: nil) acls = acls.as_json if acls.is_a?(ACL) self.attributes = acls if acls.is_a?(Hash) @delegate = owner end

Instance Attribute Details

#delegateObject

The instance object to be notified of changes. The delegate must support receiving a Object#acl_will_change! method.

 118
# File 'lib/parse/model/acl.rb', line 118 attr_accessor :permissions, :delegate

#permissionsHash

Contains a hash structure of permissions, with keys mapping to either Public '*', a role name or an objectId for a user and values of type Permission. If you modify this attribute directly, you should call Object#acl_will_change! on the target object in order for dirty tracking to register changes.

Examples:

object.acl.permissions # => { "*": { "read": true }, "3KmCvT7Zsb": { "read": true, "write": true } }

Returns:

  • (Hash)

    a hash of permissions.

 118 119 120
# File 'lib/parse/model/acl.rb', line 118 def permissions @permissions end

Class Method Details

.everyone(read = true, write = true) ⇒ Object

Create a new ACL with default Public read/write permissions and any overrides from the input hash format.

Parameters:

  • read (Boolean) (defaults to: true)

    the read permissions for PUBLIC (default: true)

  • write (Boolean) (defaults to: true)

    the write permissions for PUBLIC (default: true)

Version:

  • 1.7.0

 152 153 154 155 156
# File 'lib/parse/model/acl.rb', line 152 def self.everyone(read = true, write = true) acl = Parse::ACL.new acl.everyone(read, write) acl end

.permission(read, write = nil) ⇒ ACL::Permission

Create a new ACL::Permission instance with the supplied read and write values.

Parameters:

  • read (Boolean)

    the read permission value

  • write (Boolean) (defaults to: nil)

    the write permission value.

Returns:

See Also:

 163 164 165
# File 'lib/parse/model/acl.rb', line 163 def self.permission(read, write = nil) ACL::Permission.new(read, write) end

.typecast(value, delegate = nil) ⇒ ACL

Used for object conversion when formatting the input/output value in Parse::Object properties

Parameters:

  • value (Hash)

    a Parse ACL hash to construct a Parse::ACL instance.

  • delegate (Object) (defaults to: nil)

    any object that would need to be notified of changes.

Returns:

See Also:

 281 282 283
# File 'lib/parse/model/acl.rb', line 281 def self.typecast(value, delegate = nil) ACL.new(value, owner: delegate) end

Instance Method Details

#==(other_acl) ⇒ Boolean

Determines whether two ACLs or a Parse-ACL hash is equivalent to this object.

Examples:

acl = Parse::ACL.new # create a public read-only ACL acl.apply :public, true, false acl.as_json # => {'*' => { "read" => true }}  create a second instance with similar privileges acl2 = Parse::ACL.everyone(true, false) acl2.as_json # => {'*' => { "read" => true }}  acl == acl2 # => true acl == {'*' => { "read" => true }} # hash ok too  acl2.apply_role 'Admin', true, true # rw for Admins acl == acl2 # => false

Returns:

  • (Boolean)

    whether two ACLs have the same set of privileges.

 184 185 186 187
# File 'lib/parse/model/acl.rb', line 184 def ==(other_acl) return false unless other_acl.is_a?(self.class) || other_acl.is_a?(Hash) as_json == other_acl.as_json end

#all_read!Array

Grants read permission on all existing users and roles attached to this object.

Examples:

object.acl # { "*": { "read" : true }, # "3KmCvT7Zsb": { "read" : true, "write": true }, # "role:Admins": { "write": true } # } object.acl.all_read! # Outcome: # { "*": { "read" : true }, # "3KmCvT7Zsb": { "read" : true, "write": true }, # "role:Admins": { "read" : true, "write": true} # }

Returns:

  • (Array)

    list of ACL keys

Version:

  • 1.7.2

 353 354 355 356 357 358
# File 'lib/parse/model/acl.rb', line 353 def all_read! will_change! permissions.keys.each do |perm| permissions[perm].read! true end end

#all_write!Array

Grants write permission on all existing users and roles attached to this object.

Examples:

object.acl # { "*": { "read" : true }, # "3KmCvT7Zsb": { "read" : true, "write": true }, # "role:Admins": { "write": true } # } object.acl.all_write! # Outcome: # { "*": { "read" : true, "write": true }, # "3KmCvT7Zsb": { "read" : true, "write": true }, # "role:Admins": { "write": true } # }

Returns:

  • (Array)

    list of ACL keys

Version:

  • 1.7.2

 375 376 377 378 379 380
# File 'lib/parse/model/acl.rb', line 375 def all_write! will_change! permissions.keys.each do |perm| permissions[perm].write! true end end

#apply(user, read = nil, write = nil) ⇒ Hash #apply(role, read = nil, write = nil) ⇒ Hash #apply(id, read = nil, write = nil) ⇒ Hash Also known as: add

Apply a new permission with a given objectId, tag or :public.

Overloads:

  • #apply(user, read = nil, write = nil) ⇒ Hash

    Set the read and write permissions for this user on this ACL.

    Parameters:

    • user (Parse::User)

      the user object.

    • read (Boolean) (defaults to: nil)

      the read permission.

    • write (Boolean) (defaults to: nil)

      the write permission.

  • #apply(role, read = nil, write = nil) ⇒ Hash

    Set the read and write permissions for this role object on this ACL.

    Parameters:

    • role (Parse::Role)

      the role object.

    • read (Boolean) (defaults to: nil)

      the read permission.

    • write (Boolean) (defaults to: nil)

      the write permission.

  • #apply(id, read = nil, write = nil) ⇒ Hash

    Set the read and write permissions for this objectId on this ACL.

    Parameters:

    • id (String|:public)

      the objectId for a User. If :public is passed, then the PUBLIC read and write permissions will be modified.

    • read (Boolean) (defaults to: nil)

      the read permission.

    • write (Boolean) (defaults to: nil)

      the write permission.

Returns:

  • (Hash)

    the current set of permissions.

See Also:

 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257
# File 'lib/parse/model/acl.rb', line 238 def apply(id, read = nil, write = nil) return apply_role(id, read, write) if id.is_a?(Parse::Role) id = id.id if id.is_a?(Parse::Pointer) unless id.present? raise ArgumentError, "Invalid argument applying ACLs: must be either objectId, role or :public" end id = PUBLIC if id.to_sym == :public # create a new Permissions  permission = ACL.permission(read, write) # if the input is already an Permission object, then set it directly  permission = read if read.is_a?(Parse::ACL::Permission) if permission.is_a?(ACL::Permission) if permissions[id.to_s] != permission will_change! # dirty track  permissions[id.to_s] = permission end end permissions end

#apply_role(role, read = nil, write = nil) ⇒ Object #apply_role(role_name, read = nil, write = nil) ⇒ Object Also known as: add_role

Apply a Role to this ACL.

Overloads:

  • #apply_role(role, read = nil, write = nil) ⇒ Object

    Parameters:

    • role (Parse::Role)

      the role object.

    • read (Boolean) (defaults to: nil)

      the read permission.

    • write (Boolean) (defaults to: nil)

      the write permission.

  • #apply_role(role_name, read = nil, write = nil) ⇒ Object

    Parameters:

    • role_name (String)

      the name of the role.

    • read (Boolean) (defaults to: nil)

      the read permission.

    • write (Boolean) (defaults to: nil)

      the write permission.

 269 270 271 272
# File 'lib/parse/model/acl.rb', line 269 def apply_role(name, read = nil, write = nil) name = name.name if name.is_a?(Parse::Role) apply("role:#{name}", read, write) end

#as_json(*args) ⇒ Hash

Returns:

 310 311 312
# File 'lib/parse/model/acl.rb', line 310 def as_json(*args) permissions.select { |k, v| v.present? }.as_json end

#attributesHash

Used for JSON serialization. Only if an attribute is non-nil, do we allow it in the Permissions hash, since omission means denial of priviledge. If the permission value has neither read or write, then the entire record has been denied all privileges

Returns:

 290 291 292
# File 'lib/parse/model/acl.rb', line 290 def attributes permissions.select { |k, v| v.present? }.as_json end

#delete(object) ⇒ Object #delete(id) ⇒ Object

Removes a permission for an objectId or user.

Overloads:

  • #delete(object) ⇒ Object

    Parameters:

    • object (Parse::User)

      the user to revoke permissions.

  • #delete(id) ⇒ Object

    Parameters:

    • id (String)

      the objectId to revoke permissions.

 211 212 213 214 215 216 217
# File 'lib/parse/model/acl.rb', line 211 def delete(id) id = id.id if id.is_a?(Parse::Pointer) if id.present? && permissions.has_key?(id) will_change! permissions.delete(id) end end

#everyone(read, write) ⇒ Hash Also known as: world

Set the public read and write permissions.

Parameters:

  • read (Boolean)

    the read permission state.

  • write (Boolean)

    the write permission state.

Returns:

  • (Hash)

    the current public permissions.

 193 194 195 196
# File 'lib/parse/model/acl.rb', line 193 def everyone(read, write) apply(PUBLIC, read, write) permissions[PUBLIC] end

#master_key_only!Hash Also known as: clear!

Removes all ACLs, which only allows requests using the Parse Server master key to query and modify the object.

Examples:

object.acl # { "*": { "read" : true }, # "3KmCvT7Zsb": { "read" : true, "write": true }, # "role:Admins": { "write": true } # } object.acl.master_key_only! # Outcome: # { }

Returns:

  • (Hash)

    The cleared permissions hash

Version:

  • 1.7.2

 332 333 334 335
# File 'lib/parse/model/acl.rb', line 332 def master_key_only! will_change! @permissions = {} end

#no_read!Array

Denies read permission on all existing users and roles attached to this object.

Examples:

object.acl # { "*": { "read" : true }, # "3KmCvT7Zsb": { "read" : true, "write": true }, # "role:Admins": { "write": true } # } object.acl.no_read! # Outcome: # { "*": nil, # "3KmCvT7Zsb": { "write": true }, # "role:Admins": { "write": true } # }

Returns:

  • (Array)

    list of ACL keys

Version:

  • 1.7.2

 397 398 399 400 401 402
# File 'lib/parse/model/acl.rb', line 397 def no_read! will_change! permissions.keys.each do |perm| permissions[perm].read! false end end

#no_write!Array

Denies write permission on all existing users and roles attached to this object.

Examples:

object.acl # { "*": { "read" : true }, # "3KmCvT7Zsb": { "read" : true, "write": true }, # "role:Admins": { "write": true } # } object.acl.no_write! # Outcome: # { "*": { "read" : true }, # "3KmCvT7Zsb": { "read" : true }, # "role:Admins": nil # }

Returns:

  • (Array)

    list of ACL keys

Version:

  • 1.7.2

 419 420 421 422 423 424
# File 'lib/parse/model/acl.rb', line 419 def no_write! will_change! permissions.keys.each do |perm| permissions[perm].write! false end end

#present?Boolean

Returns true if there are any permissions.

Returns:

  • (Boolean)

    true if there are any permissions.

 315 316 317
# File 'lib/parse/model/acl.rb', line 315 def present? permissions.values.any? { |v| v.present? } end

#will_change!Object

Calls `acl_will_change!` on the delegate when the permissions have changed. All Object subclasses implement this method.

 202 203 204
# File 'lib/parse/model/acl.rb', line 202 def will_change! @delegate.acl_will_change! if @delegate.respond_to?(:acl_will_change!) end