diff options
author | Seth Chisamore <schisamo@opscode.com> | 2012-10-30 10:39:35 -0400 |
---|---|---|
committer | Seth Chisamore <schisamo@opscode.com> | 2012-10-30 10:39:35 -0400 |
commit | 24dc69a9a97e82a6e4207de68d6dcc664178249b (patch) | |
tree | 19bb289c9f88b4bbab066bc56b95d6d222fd5c35 /lib/chef/mixin/securable.rb | |
parent | 9348c1c9c80ee757354d624b7dc1b78ebc7605c4 (diff) | |
download | chef-24dc69a9a97e82a6e4207de68d6dcc664178249b.tar.gz |
[OC-3564] move core Chef to the repo root \o/ \m/
The opscode/chef repository now only contains the core Chef library code
used by chef-client, knife and chef-solo!
Diffstat (limited to 'lib/chef/mixin/securable.rb')
-rw-r--r-- | lib/chef/mixin/securable.rb | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/lib/chef/mixin/securable.rb b/lib/chef/mixin/securable.rb new file mode 100644 index 0000000000..47c388b239 --- /dev/null +++ b/lib/chef/mixin/securable.rb @@ -0,0 +1,180 @@ +# +# Author:: Seth Chisamore (<schisamo@opscode.com>) +# Copyright:: Copyright (c) 2011 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +class Chef + module Mixin + module Securable + + def owner(arg=nil) + set_or_return( + :owner, + arg, + :regex => Chef::Config[:user_valid_regex] + ) + end + + alias :user :owner + + def group(arg=nil) + set_or_return( + :group, + arg, + :regex => Chef::Config[:group_valid_regex] + ) + end + + def mode(arg=nil) + set_or_return( + :mode, + arg, + :callbacks => { + "not in valid numeric range" => lambda { |m| + if m.kind_of?(String) + m =~ /^0/ || m="0#{m}" + end + + # Windows does not support the sticky or setuid bits + if Chef::Platform.windows? + Integer(m)<=0777 && Integer(m)>=0 + else + Integer(m)<=07777 && Integer(m)>=0 + end + }, + } + ) + end + + # TODO should this be separated into different files? + if RUBY_PLATFORM =~ /mswin|mingw|windows/ + + # === rights_attribute + # "meta-method" for dynamically creating rights attributes on resources. + # + # Multiple rights attributes can be declared. This enables resources to + # have multiple rights attributes with separate runtime states. + # + # For example, +Chef::Resource::RemoteDirectory+ supports different + # rights on the directories and files by declaring separate rights + # attributes for each (rights and files_rights). + # + # ==== User Level API + # Given a resource that calls + # + # rights_attribute(:rights) + # + # Then the resource DSL could be used like this: + # + # rights :read, ["Administrators","Everyone"] + # rights :deny, "Pinky" + # rights :full_control, "Users", :applies_to_children => true + # rights :write, "John Keiser", :applies_to_children => :containers_only, :applies_to_self => false, :one_level_deep => true + # + # ==== Internal Data Structure + # rights attributes support multiple right declarations + # in a single resource block--the data will be merged + # into a single internal hash. + # + # The internal representation is a hash with the following keys: + # + # * `:permissions`: Integer of Windows permissions flags, 1..2^32 + # or one of `[:full_control, :modify, :read_execute, :read, :write]` + # * `:principals`: String or Array of Strings represnting usernames on + # the system. + # * `:applies_to_children` (optional): Boolean + # * `:applies_to_self` (optional): Boolean + # * `:one_level_deep` (optional): Boolean + # + def self.rights_attribute(name) + + # equivalent to something like: + # def rights(permissions=nil, principals=nil, args_hash=nil) + define_method(name) do |*args| + # Ruby 1.8 compat: default the arguments + permissions = args.length >= 1 ? args[0] : nil + principals = args.length >= 2 ? args[1] : nil + args_hash = args.length >= 3 ? args[2] : nil + raise ArgumentError.new("wrong number of arguments (#{args.length} for 3)") if args.length >= 4 + + rights = self.instance_variable_get("@#{name.to_s}".to_sym) + unless permissions.nil? + input = { + :permissions => permissions, + :principals => principals + } + input.merge!(args_hash) unless args_hash.nil? + + validations = {:permissions => { :required => true }, + :principals => { :required => true, :kind_of => [String, Array] }, + :applies_to_children => { :equal_to => [ true, false, :containers_only, :objects_only ]}, + :applies_to_self => { :kind_of => [ TrueClass, FalseClass ] }, + :one_level_deep => { :kind_of => [ TrueClass, FalseClass ] } + } + validate(input, validations) + + [ permissions ].flatten.each do |permission| + if permission.is_a?(Integer) + if permission < 0 || permission > 1<<32 + raise ArgumentError, "permissions flags must be positive and <= 32 bits (#{permission})" + end + elsif !([:full_control, :modify, :read_execute, :read, :write].include?(permission.to_sym)) + raise ArgumentError, "permissions parameter must be :full_control, :modify, :read_execute, :read, :write or an integer representing Windows permission flags" + end + end + + [ principals ].flatten.each do |principal| + if !principal.is_a?(String) + raise ArgumentError, "principals parameter must be a string or array of strings representing usernames" + end + end + + if input[:applies_to_children] == false + if input[:applies_to_self] == false + raise ArgumentError, "'rights' attribute must specify either :applies_to_children or :applies_to_self." + end + if input[:one_level_deep] == true + raise ArgumentError, "'rights' attribute specified :one_level_deep without specifying :applies_to_children." + end + end + rights ||= [] + rights << input + end + set_or_return( + name, + rights, + {} + ) + end + end + + # create a default 'rights' attribute + rights_attribute(:rights) + rights_attribute(:deny_rights) + + def inherits(arg=nil) + set_or_return( + :inherits, + arg, + :kind_of => [ TrueClass, FalseClass ] + ) + end + + end # Windows-specific + + end + end +end |