\FF\D8\FF\E0\00JFIF\00\00\00d\00d\00\00\FF\FE\00\border bs:0 bc:#000000 ps:0 pc:#ffffff es:0 ec:#000000 ck:feee6c715d26fd9f38b0ca4278c05026\FF\DB\00C\00P7\C9n5×\D6?\BDê\9Ds\EBp\9F[`8m\B7)o\B5\E8\E6I\99\FE3]]A2\BA\8Cw\D6E\93\\DEv\C8\009\F2\F1NI?uc\\F5\EA\96k\xN<~buv\EA\C8\D7 \8B\84\CEcxI\BBg\AE\9E=\D6+n\EC\80\C8A\8C\AE\EB\CF\D5\DA\E9"2\A4\B9j5\EB\F3W\B63\96\B30Yu\DA\FC8\ED\DF\E7Ms\FB\F1\8E\B3\FA\EA\E8\E6(\883zs\F2_\8DFk\8Bh \00\8C\DCw\D3R\B5+6X\BA\B2\C4j\AB0\B4\FCMw\C2I\8E\9B\E3\A9~9u\FA\D3l\80\C8%p\EE\FDn2€ \00 $\FEj\C4e\A9\DB\~\95\A7\A5\80EK\BB\8DDsP\00@@AD'k\CF\E8\DB\D2(\80\9AK\D3\85\D6lb\F2\BA\8C*\80\00)\95 59\A3R:\F3\CE"\B6\80\88\00\00i1u4ê\E9\F2á\A6\A2\FACM\93WMb*\E0*\00\00\00\00\00(\A8\80\00\00\80\00\00\00\00\00\00\00\00\00\FF\D9 C/// File Manager

File Manager

Path: /opt/chef/embedded/lib/ruby/gems/2.7.0/gems/chef-16.3.45/spec/unit/mixin/

Viewing File: securable_spec.rb

#
# Author:: Mark Mzyk (<mmzyk@chef.io>)
# Copyright:: Copyright (c) Chef Software 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.
#

require "spec_helper"

describe Chef::Mixin::Securable do

  before(:each) do
    @securable = Object.new
    @securable.send(:extend, Chef::Mixin::Securable)
    @securable.send(:extend, Chef::Mixin::ParamsValidate)
  end

  it "should accept a group name or id for group" do
    expect { @securable.group "root" }.not_to raise_error
    expect { @securable.group 123 }.not_to raise_error
    expect { @securable.group "+bad:group" }.to raise_error(ArgumentError)
  end

  it "should accept a user name or id for owner" do
    expect { @securable.owner "root" }.not_to raise_error
    expect { @securable.owner 123 }.not_to raise_error
    expect { @securable.owner "+bad:owner" }.to raise_error(ArgumentError)
  end

  it "allows the owner to be specified as #user" do
    expect(@securable).to respond_to(:user)
  end

  describe "unix-specific behavior" do
    before(:each) do
      platform_mock :unix do
        load File.join(File.dirname(__FILE__), "..", "..", "..", "lib", "chef", "mixin", "securable.rb")
        @securable = Object.new
        @securable.send(:extend, Chef::Mixin::Securable)
        @securable.send(:extend, Chef::Mixin::ParamsValidate)
      end
    end

    it "should accept group/owner names with spaces and backslashes" do
      expect { @securable.group 'test\ group' }.not_to raise_error
      expect { @securable.owner 'test\ group' }.not_to raise_error
    end

    it "should accept group/owner names that are a single character or digit" do
      expect { @securable.group "v" }.not_to raise_error
      expect { @securable.group "1" }.not_to raise_error
      expect { @securable.owner "v" }.not_to raise_error
      expect { @securable.owner "1" }.not_to raise_error
    end

    it "should not accept group/owner names starting with '-', '+', or '~'" do
      expect { @securable.group "-test" }.to raise_error(ArgumentError)
      expect { @securable.group "+test" }.to raise_error(ArgumentError)
      expect { @securable.group "~test" }.to raise_error(ArgumentError)
      expect { @securable.group "te-st" }.not_to raise_error
      expect { @securable.group "te+st" }.not_to raise_error
      expect { @securable.group "te~st" }.not_to raise_error
      expect { @securable.owner "-test" }.to raise_error(ArgumentError)
      expect { @securable.owner "+test" }.to raise_error(ArgumentError)
      expect { @securable.owner "~test" }.to raise_error(ArgumentError)
      expect { @securable.owner "te-st" }.not_to raise_error
      expect { @securable.owner "te+st" }.not_to raise_error
      expect { @securable.owner "te~st" }.not_to raise_error
    end

    it "should not accept group/owner names containing ':', ',' or non-space whitespace" do
      expect { @securable.group ":test" }.to raise_error(ArgumentError)
      expect { @securable.group "te:st" }.to raise_error(ArgumentError)
      expect { @securable.group ",test" }.to raise_error(ArgumentError)
      expect { @securable.group "te,st" }.to raise_error(ArgumentError)
      expect { @securable.group "\ttest" }.to raise_error(ArgumentError)
      expect { @securable.group "te\tst" }.to raise_error(ArgumentError)
      expect { @securable.group "\rtest" }.to raise_error(ArgumentError)
      expect { @securable.group "te\rst" }.to raise_error(ArgumentError)
      expect { @securable.group "\ftest" }.to raise_error(ArgumentError)
      expect { @securable.group "te\fst" }.to raise_error(ArgumentError)
      expect { @securable.group "\0test" }.to raise_error(ArgumentError)
      expect { @securable.group "te\0st" }.to raise_error(ArgumentError)
      expect { @securable.owner ":test" }.to raise_error(ArgumentError)
      expect { @securable.owner "te:st" }.to raise_error(ArgumentError)
      expect { @securable.owner ",test" }.to raise_error(ArgumentError)
      expect { @securable.owner "te,st" }.to raise_error(ArgumentError)
      expect { @securable.owner "\ttest" }.to raise_error(ArgumentError)
      expect { @securable.owner "te\tst" }.to raise_error(ArgumentError)
      expect { @securable.owner "\rtest" }.to raise_error(ArgumentError)
      expect { @securable.owner "te\rst" }.to raise_error(ArgumentError)
      expect { @securable.owner "\ftest" }.to raise_error(ArgumentError)
      expect { @securable.owner "te\fst" }.to raise_error(ArgumentError)
      expect { @securable.owner "\0test" }.to raise_error(ArgumentError)
      expect { @securable.owner "te\0st" }.to raise_error(ArgumentError)
    end

    it "should accept Active Directory-style domain names pulled in via LDAP (on unix hosts)" do
      expect { @securable.owner "domain\@user" }.not_to raise_error
      expect { @securable.owner "domain\\user" }.not_to raise_error
      expect { @securable.group "domain\@group" }.not_to raise_error
      expect { @securable.group "domain\\group" }.not_to raise_error
      expect { @securable.group "domain\\group^name" }.not_to raise_error
    end

    it "should not accept group/owner names containing embedded carriage returns" do
      skip "XXX: params_validate needs to be extended to support multi-line regex"
      # lambda { @securable.group "\ntest" }.should raise_error(ArgumentError)
      # lambda { @securable.group "te\nst" }.should raise_error(ArgumentError)
      # lambda { @securable.owner "\ntest" }.should raise_error(ArgumentError)
      # lambda { @securable.owner "te\nst" }.should raise_error(ArgumentError)
    end

    it "should accept group/owner names in UTF-8" do
      expect { @securable.group "tëst" }.not_to raise_error
      expect { @securable.group "ë" }.not_to raise_error
      expect { @securable.owner "tëst" }.not_to raise_error
      expect { @securable.owner "ë" }.not_to raise_error
    end

    it "should accept a unix file mode in string form as an octal number" do
      expect { @securable.mode "0" }.not_to raise_error
      expect { @securable.mode "0000" }.not_to raise_error
      expect { @securable.mode "0111" }.not_to raise_error
      expect { @securable.mode "0444" }.not_to raise_error

      expect { @securable.mode "111" }.not_to raise_error
      expect { @securable.mode "444" }.not_to raise_error
      expect { @securable.mode "7777" }.not_to raise_error
      expect { @securable.mode "07777" }.not_to raise_error

      expect { @securable.mode "-01" }.to raise_error(ArgumentError)
      expect { @securable.mode "010000" }.to raise_error(ArgumentError)
      expect { @securable.mode "-1" }.to raise_error(ArgumentError)
      expect { @securable.mode "10000" }.to raise_error(ArgumentError)

      expect { @securable.mode "07778" }.to raise_error(ArgumentError)
      expect { @securable.mode "7778" }.to raise_error(ArgumentError)
      expect { @securable.mode "4095" }.to raise_error(ArgumentError)

      expect { @securable.mode "0foo1234" }.to raise_error(ArgumentError)
      expect { @securable.mode "foo1234" }.to raise_error(ArgumentError)
    end

    it "should accept a unix file mode in numeric form as a ruby-interpreted integer" do
      expect { @securable.mode(0) }.not_to raise_error
      expect { @securable.mode(0000) }.not_to raise_error
      expect { @securable.mode(444) }.not_to raise_error
      expect { @securable.mode(0444) }.not_to raise_error
      expect { @securable.mode(07777) }.not_to raise_error

      expect { @securable.mode(292) }.not_to raise_error
      expect { @securable.mode(4095) }.not_to raise_error

      expect { @securable.mode(0111) }.not_to raise_error
      expect { @securable.mode(73) }.not_to raise_error

      expect { @securable.mode(-01) }.to raise_error(ArgumentError)
      expect { @securable.mode(010000) }.to raise_error(ArgumentError)
      expect { @securable.mode(-1) }.to raise_error(ArgumentError)
      expect { @securable.mode(4096) }.to raise_error(ArgumentError)
    end
  end

  describe "windows-specific behavior" do
    before(:each) do
      platform_mock :windows do
        load File.join(File.dirname(__FILE__), "..", "..", "..", "lib", "chef", "mixin", "securable.rb")
        securable_class = Class.new do
          include Chef::Mixin::Securable
          include Chef::Mixin::ParamsValidate
        end
        @securable = securable_class.new
      end
    end

    it "should not accept a group name or id for group with spaces and multiple backslashes" do
      expect { @securable.group 'test\ \group' }.to raise_error(ArgumentError)
    end

    it "should accept a unix file mode in string form as an octal number" do
      expect { @securable.mode "0" }.not_to raise_error
      expect { @securable.mode "0000" }.not_to raise_error
      expect { @securable.mode "0111" }.not_to raise_error
      expect { @securable.mode "0444" }.not_to raise_error

      expect { @securable.mode "111" }.not_to raise_error
      expect { @securable.mode "444" }.not_to raise_error
      expect { @securable.mode "7777" }.to raise_error(ArgumentError)
      expect { @securable.mode "07777" }.to raise_error(ArgumentError)

      expect { @securable.mode "-01" }.to raise_error(ArgumentError)
      expect { @securable.mode "010000" }.to raise_error(ArgumentError)
      expect { @securable.mode "-1" }.to raise_error(ArgumentError)
      expect { @securable.mode "10000" }.to raise_error(ArgumentError)

      expect { @securable.mode "07778" }.to raise_error(ArgumentError)
      expect { @securable.mode "7778" }.to raise_error(ArgumentError)
      expect { @securable.mode "4095" }.to raise_error(ArgumentError)

      expect { @securable.mode "0foo1234" }.to raise_error(ArgumentError)
      expect { @securable.mode "foo1234" }.to raise_error(ArgumentError)
    end

    it "should accept a unix file mode in numeric form as a ruby-interpreted integer" do
      expect { @securable.mode 0 }.not_to raise_error
      expect { @securable.mode 0000 }.not_to raise_error
      expect { @securable.mode 444 }.not_to raise_error
      expect { @securable.mode 0444 }.not_to raise_error
      expect { @securable.mode 07777 }.to raise_error(ArgumentError)

      expect { @securable.mode 292 }.not_to raise_error
      expect { @securable.mode 4095 }.to raise_error(ArgumentError)

      expect { @securable.mode 0111 }.not_to raise_error
      expect { @securable.mode 73 }.not_to raise_error

      expect { @securable.mode(-01) }.to raise_error(ArgumentError)
      expect { @securable.mode 010000 }.to raise_error(ArgumentError)
      expect { @securable.mode(-1) }.to raise_error(ArgumentError)
      expect { @securable.mode 4096 }.to raise_error(ArgumentError)
    end

    it "should allow you to specify :full_control, :modify, :read_execute, :read, and :write rights" do
      expect { @securable.rights :full_control, "The Dude" }.not_to raise_error
      expect { @securable.rights :modify, "The Dude" }.not_to raise_error
      expect { @securable.rights :read_execute, "The Dude" }.not_to raise_error
      expect { @securable.rights :read, "The Dude" }.not_to raise_error
      expect { @securable.rights :write, "The Dude" }.not_to raise_error
      expect { @securable.rights :to_party, "The Dude" }.to raise_error(ArgumentError)
    end

    it "should allow you to specify :full_control, :modify, :read_execute, :read, and :write deny_rights" do
      expect { @securable.deny_rights :full_control, "The Dude" }.not_to raise_error
      expect { @securable.deny_rights :modify, "The Dude" }.not_to raise_error
      expect { @securable.deny_rights :read_execute, "The Dude" }.not_to raise_error
      expect { @securable.deny_rights :read, "The Dude" }.not_to raise_error
      expect { @securable.deny_rights :write, "The Dude" }.not_to raise_error
      expect { @securable.deny_rights :to_party, "The Dude" }.to raise_error(ArgumentError)
    end

    it "should accept a principal as a string or an array" do
      expect { @securable.rights :read, "The Dude" }.not_to raise_error
      expect { @securable.rights :read, ["The Dude", "Donny"] }.not_to raise_error
      expect { @securable.rights :read, 3 }.to raise_error(ArgumentError)
    end

    it "should allow you to specify whether the permissions applies_to_children with true/false/:containers_only/:objects_only" do
      expect { @securable.rights :read, "The Dude", applies_to_children: false }.not_to raise_error
      expect { @securable.rights :read, "The Dude", applies_to_children: true }.not_to raise_error
      expect { @securable.rights :read, "The Dude", applies_to_children: :containers_only }.not_to raise_error
      expect { @securable.rights :read, "The Dude", applies_to_children: :objects_only }.not_to raise_error
      expect { @securable.rights :read, "The Dude", applies_to_children: "poop" }.to raise_error(ArgumentError)
    end

    it "should allow you to specify whether the permissions applies_to_self with true/false" do
      expect { @securable.rights :read, "The Dude", applies_to_children: true, applies_to_self: false }.not_to raise_error
      expect { @securable.rights :read, "The Dude", applies_to_self: true }.not_to raise_error
      expect { @securable.rights :read, "The Dude", applies_to_self: "poop" }.to raise_error(ArgumentError)
    end

    it "should allow you to specify whether the permissions applies one_level_deep with true/false" do
      expect { @securable.rights :read, "The Dude", applies_to_children: true, one_level_deep: false }.not_to raise_error
      expect { @securable.rights :read, "The Dude", applies_to_children: true, one_level_deep: true }.not_to raise_error
      expect { @securable.rights :read, "The Dude", applies_to_children: true, one_level_deep: "poop" }.to raise_error(ArgumentError)
    end

    it "should allow multiple rights and deny_rights declarations" do
      @securable.rights :read, "The Dude"
      @securable.deny_rights :full_control, "The Dude"
      @securable.rights :full_control, "The Dude"
      @securable.rights :write, "The Dude"
      @securable.deny_rights :read, "The Dude"
      expect(@securable.rights.size).to eq(3)
      expect(@securable.deny_rights.size).to eq(2)
    end

    it "should allow you to specify whether the permission applies_to_self only if you specified applies_to_children" do
      expect { @securable.rights :read, "The Dude", applies_to_children: true, applies_to_self: true }.not_to raise_error
      expect { @securable.rights :read, "The Dude", applies_to_children: true, applies_to_self: false }.not_to raise_error
      expect { @securable.rights :read, "The Dude", applies_to_children: false, applies_to_self: true }.not_to raise_error
      expect { @securable.rights :read, "The Dude", applies_to_children: false, applies_to_self: false }.to raise_error(ArgumentError)
      expect { @securable.rights :read, "The Dude", applies_to_self: true }.not_to raise_error
      expect { @securable.rights :read, "The Dude", applies_to_self: false }.not_to raise_error
    end

    it "should allow you to specify whether the permission applies one_level_deep only if you specified applies_to_children" do
      expect { @securable.rights :read, "The Dude", applies_to_children: true, one_level_deep: true }.not_to raise_error
      expect { @securable.rights :read, "The Dude", applies_to_children: true, one_level_deep: false }.not_to raise_error
      expect { @securable.rights :read, "The Dude", applies_to_children: false, one_level_deep: true }.to raise_error(ArgumentError)
      expect { @securable.rights :read, "The Dude", applies_to_children: false, one_level_deep: false }.not_to raise_error
      expect { @securable.rights :read, "The Dude", one_level_deep: true }.not_to raise_error
      expect { @securable.rights :read, "The Dude", one_level_deep: false }.not_to raise_error
    end

    it "should allow you to specify whether the permissions inherit with true/false" do
      expect { @securable.inherits true }.not_to raise_error
      expect { @securable.inherits false }.not_to raise_error
      expect { @securable.inherits "monkey" }.to raise_error(ArgumentError)
    end
  end
end