summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Cragun <ryan@chef.io>2019-09-03 15:02:30 -0600
committerRyan Cragun <ryan@chef.io>2019-09-03 15:02:30 -0600
commit96802f1f07d205b82629cfe6fbfd466b3a153ab8 (patch)
treeef8b9934e053df65ce7e2ac7a3cae74c58738f2e
parentf8393130f604ae7bb0c2794a2e59e358ebfaaec3 (diff)
downloadchef-96802f1f07d205b82629cfe6fbfd466b3a153ab8.tar.gz
add functional testryancragun/mac_user
Signed-off-by: Ryan Cragun <ryan@chef.io>
-rw-r--r--lib/chef/provider/user/mac.rb8
-rw-r--r--spec/functional/resource/user/mac_user_spec.rb188
-rw-r--r--spec/spec_helper.rb1
-rw-r--r--spec/support/platform_helpers.rb10
4 files changed, 203 insertions, 4 deletions
diff --git a/lib/chef/provider/user/mac.rb b/lib/chef/provider/user/mac.rb
index 0416e72eb1..414445cfa1 100644
--- a/lib/chef/provider/user/mac.rb
+++ b/lib/chef/provider/user/mac.rb
@@ -134,11 +134,11 @@ class Chef
def create_user
cmd = [-"-addUser", new_resource.username]
- cmd += ["-fullName", new_resource.comment] if new_resource.property_is_set?(:comment)
- cmd += ["-UID", new_resource.uid] if new_resource.property_is_set?(:uid)
+ cmd += ["-fullName", new_resource.comment] if new_resource.property_is_set?(:comment)
+ cmd += ["-UID", new_resource.uid] if new_resource.property_is_set?(:uid)
cmd += ["-shell", new_resource.shell]
- cmd += ["-home", new_resource.home] if new_resource.property_is_set?(:home)
- cmd += ["-admin"] if new_resource.admin
+ cmd += ["-home", new_resource.home]
+ cmd += ["-admin"] if new_resource.admin
# We can technically create a new user without the admin credentials
# but without them the user cannot enable SecureToken, thus they cannot
diff --git a/spec/functional/resource/user/mac_user_spec.rb b/spec/functional/resource/user/mac_user_spec.rb
new file mode 100644
index 0000000000..d01b08616e
--- /dev/null
+++ b/spec/functional/resource/user/mac_user_spec.rb
@@ -0,0 +1,188 @@
+#
+# Copyright:: Copyright 2019, 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"
+require "chef/mixin/shell_out"
+
+metadata = {
+ macos_1014: true,
+ requires_root: true,
+}
+
+describe "Chef::Resource::User with Chef::Provider::User::MacUser provider", metadata do
+ include Chef::Mixin::ShellOut
+
+ def clean_user
+ shell_out!("/usr/bin/dscl . -delete '/Users/#{username}'")
+ rescue Mixlib::ShellOut::ShellCommandFailed
+ # Raised when the user is already cleaned
+ end
+
+ def user_should_exist
+ expect(shell_out("/usr/bin/dscl . -read /Users/#{username}").error?).to be(false)
+ end
+
+ def check_password(pass)
+ # In order to test the password we use dscl passwd command since
+ # that's the only command that gets the user password from CLI.
+ expect(shell_out("dscl . -passwd /Users/greatchef #{pass} new_password").exitstatus).to eq(0)
+ # Now reset the password back
+ expect(shell_out("dscl . -passwd /Users/greatchef new_password #{pass}").exitstatus).to eq(0)
+ end
+
+ let(:node) do
+ n = Chef::Node.new
+ n.consume_external_attrs(OHAI_SYSTEM.data.dup, {})
+ n
+ end
+
+ let(:events) do
+ Chef::EventDispatch::Dispatcher.new
+ end
+
+ let(:run_context) do
+ Chef::RunContext.new(node, {}, events)
+ end
+
+ let(:username) do
+ "greatchef"
+ end
+
+ let(:uid) { nil }
+ let(:gid) { 20 }
+ let(:home) { nil }
+ let(:manage_home) { false }
+ let(:password) { "XXXYYYZZZ" }
+ let(:comment) { "Great Chef" }
+ let(:shell) { "/bin/bash" }
+ let(:salt) { nil }
+ let(:iterations) { nil }
+
+ let(:user_resource) do
+ r = Chef::Resource::User::MacUser.new("TEST USER RESOURCE", run_context)
+ r.username(username)
+ r.uid(uid)
+ r.gid(gid)
+ r.home(home)
+ r.shell(shell)
+ r.comment(comment)
+ r.manage_home(manage_home)
+ r.password(password)
+ r.salt(salt)
+ r.iterations(iterations)
+ r
+ end
+
+ before do
+ clean_user
+ end
+
+ after(:each) do
+ clean_user
+ end
+
+ describe "action :create" do
+ it "should create the user" do
+ user_resource.run_action(:create)
+ user_should_exist
+ check_password(password)
+ end
+ end
+
+ describe "when user exists" do
+ before do
+ existing_resource = user_resource.dup
+ existing_resource.run_action(:create)
+ user_should_exist
+ end
+
+ describe "when password is updated" do
+ it "should update the password of the user" do
+ user_resource.password("mykitchen")
+ user_resource.run_action(:create)
+ check_password("mykitchen")
+ end
+ end
+ end
+
+ describe "when password is being set via shadow hash" do
+ let(:password) do
+ "c734b6e4787c3727bb35e29fdd92b97c\
+1de12df509577a045728255ec7c6c5f5\
+c18efa05ed02b682ffa7ebc05119900e\
+b1d4880833aa7a190afc13e2bf0936b8\
+20123e8c98f0f9bcac2a629d9163caac\
+9464a8c234f3919082400b4f939bb77b\
+c5adbbac718b7eb99463a7b679571e0f\
+1c9fef2ef08d0b9e9c2bcf644eed2ffc"
+ end
+
+ let(:iterations) { 25000 }
+ let(:salt) { "9e2e7d5ee473b496fd24cf0bbfcaedfcb291ee21740e570d1e917e874f8788ca" }
+
+ it "action :create should create the user" do
+ user_resource.run_action(:create)
+ user_should_exist
+ check_password("soawesome")
+ end
+
+ describe "when user exists" do
+ before do
+ existing_resource = user_resource.dup
+ existing_resource.run_action(:create)
+ user_should_exist
+ end
+
+ describe "when password is updated" do
+ it "should update the password of the user" do
+ user_resource.password("mykitchen")
+ user_resource.run_action(:create)
+ check_password("mykitchen")
+ end
+ end
+ end
+ end
+
+ describe "when a user is member of some groups" do
+ let(:groups) { %w{staff operator} }
+
+ before do
+ existing_resource = user_resource.dup
+ existing_resource.run_action(:create)
+
+ groups.each do |group|
+ shell_out!("/usr/bin/dscl . -append '/Groups/#{group}' GroupMembership #{username}")
+ end
+ end
+
+ after do
+ groups.each do |group|
+ # Do not raise an error when user is correctly removed
+ shell_out("/usr/bin/dscl . -delete '/Groups/#{group}' GroupMembership #{username}")
+ end
+ end
+
+ it ":remove action removes the user from the groups and deletes the user" do
+ user_resource.run_action(:remove)
+ groups.each do |group|
+ # Do not raise an error when group is empty
+ expect(shell_out("dscl . read /Groups/staff GroupMembership").stdout).not_to include(group)
+ end
+ end
+ end
+
+end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 9b54761df5..980b96ff59 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -145,6 +145,7 @@ RSpec.configure do |config|
config.filter_run_excluding not_supported_on_windows: true if windows?
config.filter_run_excluding not_supported_on_macos: true if mac_osx?
config.filter_run_excluding macos_only: true unless mac_osx?
+ config.filter_run_excluding macos_1014: true unless mac_osx_1014?
config.filter_run_excluding not_supported_on_aix: true if aix?
config.filter_run_excluding not_supported_on_solaris: true if solaris?
config.filter_run_excluding not_supported_on_gce: true if gce?
diff --git a/spec/support/platform_helpers.rb b/spec/support/platform_helpers.rb
index 509ca6e71e..5c54954565 100644
--- a/spec/support/platform_helpers.rb
+++ b/spec/support/platform_helpers.rb
@@ -3,6 +3,7 @@ require "chef/mixin/shell_out"
require "ohai/mixin/http_helper"
require "ohai/mixin/gce_metadata"
require "chef/mixin/powershell_out"
+require "chef/version_class"
class ShellHelpers
extend Chef::Mixin::ShellOut
@@ -110,6 +111,15 @@ def mac_osx_106?
false
end
+def mac_osx_1014?
+ if mac_osx?
+ ver = Chef::Version.new(ohai[:platform_version])
+ return ver.major == 10 && ver.minor == 14
+ end
+
+ false
+end
+
def mac_osx?
if File.exists? "/usr/bin/sw_vers"
result = ShellHelpers.shell_out("/usr/bin/sw_vers")