summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSven Schwyn <schwyn@bitcetera.com>2017-01-24 23:00:31 +0100
committerSven Schwyn <schwyn@bitcetera.com>2017-02-08 21:29:26 +0100
commit2dfb263b0f90a1d30b04cd13263428137e5ef92c (patch)
treefe22b049d05c4000fbc5d3d180a89ac83c504b9b
parent6e69db334661fd31f559fb72463e7911b6f9c6a1 (diff)
downloadbundler-2dfb263b0f90a1d30b04cd13263428137e5ef92c.tar.gz
Permissive temporary home directory
When falling back to a temporary home directory, make sure the "home" directory has mode 0777 to prevent "permission denied" when this mechanism is used by more than one login.
-rw-r--r--lib/bundler.rb45
-rw-r--r--spec/bundler/bundler_spec.rb39
2 files changed, 63 insertions, 21 deletions
diff --git a/lib/bundler.rb b/lib/bundler.rb
index 2cd8d9916b..c98dece747 100644
--- a/lib/bundler.rb
+++ b/lib/bundler.rb
@@ -146,34 +146,37 @@ module Bundler
def user_home
@user_home ||= begin
home = Bundler.rubygems.user_home
- warning = "Your home directory is not set properly:"
- if home.nil?
- warning += "\n * It is not set at all"
+
+ warning = if home.nil?
+ "Your home directory is not set."
elsif !File.directory?(home)
- warning += "\n * `#{home}` is not a directory"
+ "`#{home}` is not a directory."
elsif !File.writable?(home)
- warning += "\n * `#{home}` is not writable"
- else
- return @user_home = Pathname.new(home)
+ "`#{home}` is not writable."
end
- login = Etc.getlogin || "unknown"
-
- tmp_home = Pathname.new(Dir.tmpdir).join("bundler", "home", login)
- begin
- SharedHelpers.filesystem_access(tmp_home, :write) do |p|
- FileUtils.mkdir_p(p)
- end
- rescue => e
- warning += "\n\nBundler also failed to create a temporary home directory at `#{tmp_home}`:\n#{e}"
- raise warning
+ if warning
+ user_home = tmp_home_path(Etc.getlogin, warning)
+ Bundler.ui.warn "#{warning}\nBundler will use `#{user_home}' as your home directory temporarily.\n"
+ user_home
+ else
+ Pathname.new(home)
end
+ end
+ end
- warning += "\n\nBundler will use `#{tmp_home}` as your home directory temporarily"
-
- Bundler.ui.warn(warning)
- tmp_home
+ def tmp_home_path(login, warning)
+ login ||= "unknown"
+ path = Pathname.new(Dir.tmpdir).join("bundler", "home")
+ SharedHelpers.filesystem_access(path) do |tmp_home_path|
+ unless tmp_home_path.exist?
+ tmp_home_path.mkpath
+ tmp_home_path.chmod(0o777)
+ end
+ tmp_home_path.join(login).tap(&:mkpath)
end
+ rescue => e
+ raise "#{warning}\nBundler also failed to create a temporary home directory at `#{path}':\n#{e}"
end
def user_bundle_path
diff --git a/spec/bundler/bundler_spec.rb b/spec/bundler/bundler_spec.rb
index 4458efce6a..268c0d99ac 100644
--- a/spec/bundler/bundler_spec.rb
+++ b/spec/bundler/bundler_spec.rb
@@ -170,4 +170,43 @@ EOF
end
end
end
+
+ describe "#user_home" do
+ context "home directory is set" do
+ it "should return the user home" do
+ path = "/home/oggy"
+ allow(Bundler.rubygems).to receive(:user_home).and_return(path)
+ allow(File).to receive(:directory?).with(path).and_return true
+ allow(File).to receive(:writable?).with(path).and_return true
+ expect(Bundler.user_home).to eq(Pathname(path))
+ end
+ end
+
+ context "home directory is not set" do
+ it "should issue warning and return a temporary user home" do
+ allow(Bundler.rubygems).to receive(:user_home).and_return(nil)
+ allow(Etc).to receive(:getlogin).and_return("USER")
+ allow(Dir).to receive(:tmpdir).and_return("/TMP")
+ allow(FileTest).to receive(:exist?).with("/TMP/bundler/home").and_return(true)
+ expect(FileUtils).to receive(:mkpath).with("/TMP/bundler/home/USER")
+ message = <<EOF
+Your home directory is not set.
+Bundler will use `/TMP/bundler/home/USER' as your home directory temporarily.
+EOF
+ expect(Bundler.ui).to receive(:warn).with(message)
+ expect(Bundler.user_home).to eq(Pathname("/TMP/bundler/home/USER"))
+ end
+ end
+ end
+
+ describe "#tmp_home_path" do
+ it "should create temporary user home" do
+ allow(Dir).to receive(:tmpdir).and_return("/TMP")
+ allow(FileTest).to receive(:exist?).with("/TMP/bundler/home").and_return(false)
+ expect(FileUtils).to receive(:mkpath).once.ordered.with("/TMP/bundler/home")
+ expect(FileUtils).to receive(:mkpath).once.ordered.with("/TMP/bundler/home/USER")
+ expect(File).to receive(:chmod).with(0o777, "/TMP/bundler/home")
+ expect(Bundler.tmp_home_path("USER", "")).to eq(Pathname("/TMP/bundler/home/USER"))
+ end
+ end
end