module MSS::S3::ACLOptions

Provides a method to {Bucket} and {S3Object} that parses a wide range of ACL options. @api private

Protected Instance Methods

acl_options(acl) click to toggle source

@param [Symbol,String,Hash,AccessControlList] acl Accepts an ACL

description in one of the following formats:

==== Canned ACL

S3 supports a number of canned ACLs for buckets and
objects.  These include:

* `:private`
* `:public_read`
* `:public_read_write`
* `:authenticated_read`
* `:bucket_owner_read` (object-only)
* `:bucket_owner_full_control` (object-only)
* `:log_delivery_write` (bucket-only)

Here is an example of providing a canned ACL to a bucket:

    s3.buckets['bucket-name'].acl = :public_read

==== ACL Grant Hash

You can provide a hash of grants.  The hash is composed of grants (keys)
and grantees (values).  Accepted grant keys are:

* `:grant_read`
* `:grant_write`
* `:grant_read_acp`
* `:grant_write_acp`
* `:grant_full_control`

Grantee strings (values) should be formatted like some of the
following examples:

    id="8a6925ce4adf588a4532142d3f74dd8c71fa124b1ddee97f21c32aa379004fef"
    uri="http://acs.amazonmss.com/groups/global/AllUsers"

You can provide a comma delimited list of multiple grantees in a single
string.  Please note the use of quotes inside the grantee string.
Here is a simple example:

    { :grant_full_control => "emailAddress=\"foo@bar.com\", id=\"abc..mno\"" }

See the S3 API documentation for more information on formatting
grants.

==== AcessControlList Object

You can build an ACL using the {AccessControlList} class and
pass this object.

    acl = MSS::S3::AccessControlList.new
    acl.grant(:full_control).to(:canonical_user_id => "8a6...fef")
    acl #=> this is acceptible

==== ACL XML String

Lastly you can build your own ACL XML document and pass it as a string.

    <<-XML
      <AccessControlPolicy xmlns="http://s3.amazonmss.com/doc/2006-03-01/">
        <Owner>
          <ID>8a6...fef</ID>
          <DisplayName>owner-display-name</DisplayName>
        </Owner>
        <AccessControlList>
          <Grant>
            <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Canonical User">
              <ID>8a6...fef</ID>
              <DisplayName>owner-display-name</DisplayName>
            </Grantee>
            <Permission>FULL_CONTROL</Permission>
          </Grant>
        </AccessControlList>
      </AccessControlPolicy>
    XML

@return [Hash] Returns a hash of options suitable for

passing to {Client#put_bucket_acl} and {Client#put_object_acl}
with a mixture of ACL options.
# File lib/mss/s3/acl_options.rb, line 106
def acl_options acl
  case acl
  when Symbol
    { :acl => acl.to_s.tr('_', '-') }
  when String
    # Strings are either access control policies (xml strings)
    # or they are canned acls
    xml?(acl) ?
      { :access_control_policy => acl } :
      { :acl => acl }
  when AccessControlList
      { :access_control_policy => acl.to_xml }
  when Hash
    # Hashes are either grant hashes or constructor args for an
    # access control list (deprecated)
    grant_hash?(acl) ?
      format_grants(acl) :
      { :access_control_policy => AccessControlList.new(acl).to_xml }
  else
    # failed to parse the acl option
    msg = "expected a canned ACL, AccessControlList object, ACL "
          "XML string or a grants hash"
    raise ArgumentError, msg
  end
end
format_grantee(grantee) click to toggle source
# File lib/mss/s3/acl_options.rb, line 167
def format_grantee grantee
  case grantee
  when String then grantee
  when Hash

    if grantee.keys.count != 1
      msg = "grantee hashes must have exactly 1 key"
      raise ArgumentError, msg
    end

    # A granee hash looks like:
    #
    #     { :id => 'abc...fec' }
    #     { :uri => 'http://abc.com/foo' }
    #
    # It needs to look like
    #
    #     'id="abc...fec"'
    #     'uri="http://abc.com/foo"'
    type, token = grantee.to_a.flatten
    type = type.to_s.split('_').map{|part| ucfirst(part) }.join
    "#{type[0,1].downcase}#{type[1..-1]}=\"#{token}\""
  else
    raise ArgumentError, "grantees must be a string or a hash"
  end
end
format_grants(acl_hash) click to toggle source

@param [Hash] acl_hash @return [Hash] Returns a hash of grant options suitable for

passing to the various S3 client methods that accept ACL grants.
# File lib/mss/s3/acl_options.rb, line 158
def format_grants acl_hash
  grants = {}
  acl_hash.each_pair do |grant,grantees|
    grantees = [grantees] unless grantees.is_a?(Array)
    grants[grant] = grantees.map{|g| format_grantee(g) }.join(', ')
  end
  grants
end
grant_hash?(acl_hash) click to toggle source

@param [Hash] acl_hash @return [Boolean] Retursn `true` if this hash is a hash of grants.

# File lib/mss/s3/acl_options.rb, line 134
def grant_hash? acl_hash
  grant_keys = [
    :grant_read,
    :grant_write,
    :grant_read_acp,
    :grant_write_acp,
    :grant_full_control,
  ]
  acl_hash.keys.all?{|key| grant_keys.include?(key) }
end
ucfirst(str) click to toggle source
# File lib/mss/s3/acl_options.rb, line 194
def ucfirst str
  str[0,1].upcase + str[1..-1]
end
xml?(acl_string) click to toggle source

@param [String] acl_string @return [Boolean] Returns `true` if this string is an xml document.

# File lib/mss/s3/acl_options.rb, line 147
def xml? acl_string
  begin
    REXML::Document.new(acl_string).has_elements?
  rescue
    false
  end
end