mirror of
https://github.com/fog/fog.git
synced 2022-11-09 13:51:43 -05:00
Add grant, revoke and list methods for cross tenant object acls implementation.
This commit is contained in:
parent
0ce276f4f7
commit
13509fced4
3 changed files with 144 additions and 39 deletions
|
@ -58,7 +58,10 @@ module Fog
|
|||
end
|
||||
# set the acl on the directory based on the headers
|
||||
if !(read_header.nil? && write_header.nil?)
|
||||
directory.acl = connection.header_to_acl(read_header, write_header)
|
||||
read_acl, write_acl = connection.header_to_perm_acl(read_header, write_header)
|
||||
# do not want to expose the read_acl and write_acl as writable attributes
|
||||
directory.instance_variable_set(:@read_acl, read_acl)
|
||||
directory.instance_variable_set(:@write_acl, write_acl)
|
||||
end
|
||||
directory.files.merge_attributes(options)
|
||||
directory.files.instance_variable_set(:@loaded, true)
|
||||
|
|
|
@ -12,15 +12,70 @@ module Fog
|
|||
attribute :bytes, :aliases => 'X-Container-Bytes-Used'
|
||||
attribute :count, :aliases => 'X-Container-Object-Count'
|
||||
|
||||
def acl=(new_acl)
|
||||
if new_acl.nil?
|
||||
new_acl = "private"
|
||||
def initialize(attributes = {})
|
||||
@read_acl = []
|
||||
@write_acl = []
|
||||
super
|
||||
end
|
||||
|
||||
def read_acl
|
||||
@read_acl
|
||||
end
|
||||
|
||||
def write_acl
|
||||
@write_acl
|
||||
end
|
||||
|
||||
def can_read?(user)
|
||||
return false if @read_acl.nil?
|
||||
list_users_with_read.include?(user)
|
||||
end
|
||||
|
||||
def can_write?(user)
|
||||
return false if @write_acl.nil?
|
||||
list_users_with_write.include?(user)
|
||||
end
|
||||
|
||||
def can_read_write?(user)
|
||||
can_read?(user) && can_write?(user)
|
||||
end
|
||||
|
||||
def list_users_with_read
|
||||
users = []
|
||||
users = @read_acl.map {|acl| acl.split(':')[1]} unless @read_acl.nil?
|
||||
return users
|
||||
end
|
||||
|
||||
def list_users_with_write
|
||||
users = []
|
||||
users = @write_acl.map {|acl| acl.split(':')[1]} unless @write_acl.nil?
|
||||
return users
|
||||
end
|
||||
|
||||
def grant(perm, users=[])
|
||||
r_acl, w_acl = connection.perm_to_acl(perm, users)
|
||||
unless r_acl.nil?
|
||||
@read_acl = @read_acl + r_acl
|
||||
@read_acl.uniq!
|
||||
end
|
||||
valid_acls = ['private', 'public-read', 'public-write', 'public-read-write']
|
||||
unless valid_acls.include?(new_acl)
|
||||
raise ArgumentError.new("acl must be one of [#{valid_acls.join(', ')}]")
|
||||
unless w_acl.nil?
|
||||
@write_acl = @write_acl + w_acl
|
||||
@write_acl.uniq!
|
||||
end
|
||||
@acl = new_acl
|
||||
true
|
||||
end
|
||||
|
||||
def revoke(perm, users=[])
|
||||
r_acl, w_acl = connection.perm_to_acl(perm, users)
|
||||
unless r_acl.nil?
|
||||
@read_acl = @read_acl - r_acl
|
||||
@read_acl.uniq!
|
||||
end
|
||||
unless w_acl.nil?
|
||||
@write_acl = @write_acl - w_acl
|
||||
@write_acl.uniq!
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
def destroy
|
||||
|
@ -50,18 +105,20 @@ module Fog
|
|||
|
||||
def public=(new_public)
|
||||
if new_public
|
||||
@acl = 'public-read'
|
||||
self.grant("pr")
|
||||
else
|
||||
@acl = 'private'
|
||||
self.revoke("pr")
|
||||
end
|
||||
@public = new_public
|
||||
end
|
||||
|
||||
def public?
|
||||
if @acl.nil?
|
||||
if @read_acl.empty?
|
||||
false
|
||||
elsif @read_acl.include?(".r:*")
|
||||
true
|
||||
else
|
||||
@acl == 'public-read'
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -70,7 +127,7 @@ module Fog
|
|||
@public_url ||= begin
|
||||
begin response = connection.head_container(key)
|
||||
# escape the key to cover for special char. in container names
|
||||
url = "#{connection.url}/#{Fog::HP.escape(key)}"
|
||||
url = connection.public_url(key)
|
||||
rescue Fog::Storage::HP::NotFound => err
|
||||
nil
|
||||
end
|
||||
|
@ -135,9 +192,8 @@ module Fog
|
|||
def save
|
||||
requires :key
|
||||
options = {}
|
||||
if @acl
|
||||
options.merge!(connection.acl_to_header(@acl))
|
||||
end
|
||||
# write out the acls into the headers before save
|
||||
options.merge!(connection.perm_acl_to_header(@read_acl, @write_acl))
|
||||
connection.put_container(key, options)
|
||||
# Added an extra check to see if CDN is enabled for the container
|
||||
if (!connection.cdn.nil? && connection.cdn.enabled?)
|
||||
|
|
|
@ -53,34 +53,80 @@ module Fog
|
|||
"#{@scheme}://#{@host}:#{@port}#{@path}"
|
||||
end
|
||||
|
||||
def acl_to_header(acl)
|
||||
def public_url(container=nil, object=nil)
|
||||
public_url = nil
|
||||
unless container.nil?
|
||||
if object.nil?
|
||||
# return container public url
|
||||
public_url = "#{url}/#{Fog::HP.escape(container)}"
|
||||
else
|
||||
# return object public url
|
||||
public_url = "#{url}/#{Fog::HP.escape(container)}/#{Fog::HP.escape(object)}"
|
||||
end
|
||||
end
|
||||
public_url
|
||||
end
|
||||
|
||||
def perm_to_acl(perm, users=[])
|
||||
read_perm_acl = []
|
||||
write_perm_acl = []
|
||||
valid_public_perms = ['pr', 'pw', 'prw']
|
||||
valid_account_perms = ['r', 'w', 'rw']
|
||||
valid_perms = valid_public_perms + valid_account_perms
|
||||
unless valid_perms.include?(perm)
|
||||
raise ArgumentError.new("permission must be one of [#{valid_perms.join(', ')}]")
|
||||
end
|
||||
# tackle the public access differently
|
||||
if valid_public_perms.include?(perm)
|
||||
case perm
|
||||
when "pr"
|
||||
read_perm_acl = [".r:*",".rlistings"]
|
||||
when "pw"
|
||||
write_perm_acl = ["*"]
|
||||
when "prw"
|
||||
read_perm_acl = [".r:*",".rlistings"]
|
||||
write_perm_acl = ["*"]
|
||||
end
|
||||
elsif valid_account_perms.include?(perm)
|
||||
# tackle the user access differently
|
||||
unless (users.nil? || users.empty?)
|
||||
# return the correct acls
|
||||
tenant_id = "*" # this might change later
|
||||
acl_array = users.map { |u| "#{tenant_id}:#{u}" }
|
||||
#acl_string = acl_array.join(',')
|
||||
case perm
|
||||
when "r"
|
||||
read_perm_acl = acl_array
|
||||
when "w"
|
||||
write_perm_acl = acl_array
|
||||
when "rw"
|
||||
read_perm_acl = acl_array
|
||||
write_perm_acl = acl_array
|
||||
end
|
||||
end
|
||||
end
|
||||
return read_perm_acl, write_perm_acl
|
||||
end
|
||||
|
||||
def perm_acl_to_header(read_perm_acl, write_perm_acl)
|
||||
header = {}
|
||||
case acl
|
||||
when "private"
|
||||
header['X-Container-Read'] = ""
|
||||
header['X-Container-Write'] = ""
|
||||
when "public-read"
|
||||
header['X-Container-Read'] = ".r:*,.rlistings"
|
||||
when "public-write"
|
||||
header['X-Container-Write'] = "*"
|
||||
when "public-read-write"
|
||||
header['X-Container-Read'] = ".r:*,.rlistings"
|
||||
header['X-Container-Write'] = "*"
|
||||
if read_perm_acl.nil? && write_perm_acl.nil?
|
||||
header = {'X-Container-Read' => "", 'X-Container-Write' => ""}
|
||||
elsif !read_perm_acl.nil? && write_perm_acl.nil?
|
||||
header = {'X-Container-Read' => "#{read_perm_acl.join(',')}", 'X-Container-Write' => ""}
|
||||
elsif read_perm_acl.nil? && !write_perm_acl.nil?
|
||||
header = {'X-Container-Read' => "", 'X-Container-Write' => "#{write_perm_acl.join(',')}"}
|
||||
elsif !read_perm_acl.nil? && !write_perm_acl.nil?
|
||||
header = {'X-Container-Read' => "#{read_perm_acl.join(',')}", 'X-Container-Write' => "#{write_perm_acl.join(',')}"}
|
||||
end
|
||||
header
|
||||
end
|
||||
|
||||
def header_to_acl(read_header=nil, write_header=nil)
|
||||
acl = nil
|
||||
if read_header.nil? && write_header.nil?
|
||||
acl = nil
|
||||
elsif !read_header.nil? && read_header.include?(".r:*") && write_header.nil?
|
||||
acl = "public-read"
|
||||
elsif !write_header.nil? && write_header.include?("*") && read_header.nil?
|
||||
acl = "public-write"
|
||||
elsif !read_header.nil? && read_header.include?(".r:*") && !write_header.nil? && write_header.include?("*")
|
||||
acl = "public-read-write"
|
||||
end
|
||||
def header_to_perm_acl(read_header=nil, write_header=nil)
|
||||
read_h, write_h = nil
|
||||
read_h = read_header.split(',') unless read_header.nil?
|
||||
write_h = write_header.split(',') unless write_header.nil?
|
||||
return read_h, write_h
|
||||
end
|
||||
|
||||
def generate_object_temp_url(container, object, expires_secs, method)
|
||||
|
|
Loading…
Add table
Reference in a new issue