module S33r module S3Logging # For manipulating logging directives on resources # (see http://docs.amazonwebservices.com/AmazonS3/2006-03-01/LoggingHowTo.html). # # Creating a LoggingResource instance using new and no arguments will generate a "blank" instance; # this can be put to the ?logging URL for a resource to remove logging from it. # # To set a Bucket up for logging, create a LoggingResource with the correct log_target and # log_prefix settings and put that to the ?logging URL for a bucket. class LoggingResource attr_accessor :log_target, :log_prefix # +log_target+ is the bucket to put logs into. # +log_prefix+ is the prefix for log files put into the +log_target+ bucket. def initialize(log_target=nil, log_prefix=nil) @log_target = log_target @log_prefix = log_prefix end # Generate a BucketLoggingStatus XML document for putting to the ?logging # URL for a resource. def to_xml xml_str = "" xml = Builder::XmlMarkup.new(:target => xml_str, :indent => 0) xml.instruct! # BucketLoggingStatus XML. xml.BucketLoggingStatus({"xmlns" => RESPONSE_NAMESPACE_URI}) { unless @log_target.nil? and @log_prefix.nil? xml.LoggingEnabled { xml.TargetBucket @log_target xml.TargetPrefix @log_prefix } end } xml_str end # Convert XML from S3 response into a LoggingResource # #-- TODO: tests def self.from_xml(logging_xml) return nil if logging_xml.nil? logging_xml = S33r.remove_namespace(logging_xml) doc = XML.get_xml_doc(logging_xml) log_target = doc.xget('//TargetBucket') log_prefix = doc.xget('//TargetPrefix') self.new(log_target, log_prefix) end end end # Extensions to the S3ACL module to cover logging. module S3ACL class Policy # Does the ACL make the associated resource available as a log target? def log_targetable? log_target_grants = Grant.log_target_grants log_target_grants.each { |g| return false if !grants.include?(g) } return true end # Add permissions to an instances which give READ_ACL # and WRITE permissions to the LogDelivery group. Used # to enable a bucket as a logging destination. # # Returns true if grants added, false otherwise # (if already a log target). def add_log_target_grants if log_targetable? return false else Grant.log_target_grants.each { |g| add_grant(g) } return true end end # Remove log target ACLs from the document. # # Returns true if all log target grants were removed; # false otherwise. # # NB even if this method returns false, that doesn't mean # the bucket is still a log target. Use log_targetable? to check # whether a bucket can be used as a log target. def remove_log_target_grants ok = true Grant.log_target_grants.each { |g| ok = ok and remove_grant(g) } ok end end class Grant # Generator for a grant which gives the LogDelivery group # write and read_acl permissions on a bucket. # # Returns an array with the two required Grant instances. def Grant.log_target_grants log_delivery_group = Group.new(:log_delivery) [Grant.new(log_delivery_group, :read_acl), Grant.new(log_delivery_group, :write)] end end end end