From 65c53dbe4f2140236590a7568a5f22a77d16be39 Mon Sep 17 00:00:00 2001 From: DerpDays <34582078+DerpDays@users.noreply.github.com> Date: Fri, 21 Jun 2024 14:07:03 +0100 Subject: [PATCH] fix: correctly check group permissions in unix (#428) * fix: set modifiable when user in group * feat: add mode caching, fallback to previous, and better checking of permissions * fix: make is_modifiable check group permissions even if the user is owner of the directory * refactor: simplify group ID caching --------- Co-authored-by: Steven Arcangeli --- lua/oil/adapters/files.lua | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/lua/oil/adapters/files.lua b/lua/oil/adapters/files.lua index d502c90..e007423 100644 --- a/lua/oil/adapters/files.lua +++ b/lua/oil/adapters/files.lua @@ -412,6 +412,26 @@ M.list = function(url, column_defs, cb) end, 10000) end +---@type nil|integer[] +local _group_ids +---@return integer[] +local function get_group_ids() + if not _group_ids then + local output = vim.fn.system({ "id", "-G" }) + if vim.v.shell_error == 0 then + _group_ids = vim.tbl_map(tonumber, vim.split(output, "%s+", { trimempty = true })) + else + -- If the id command fails, fall back to just using the process group + _group_ids = { uv.getgid() } + vim.notify( + "[oil] missing the `id` command. Some directories may not be modifiable even if you have group access.", + vim.log.levels.WARN + ) + end + end + return _group_ids +end + ---@param bufnr integer ---@return boolean M.is_modifiable = function(bufnr) @@ -433,14 +453,12 @@ M.is_modifiable = function(bufnr) end local uid = uv.getuid() - local gid = uv.getgid() - local rwx + local rwx = stat.mode if uid == stat.uid then - rwx = bit.rshift(stat.mode, 6) - elseif gid == stat.gid then - rwx = bit.rshift(stat.mode, 3) - else - rwx = stat.mode + rwx = bit.bor(rwx, bit.rshift(stat.mode, 6)) + end + if vim.tbl_contains(get_group_ids(), stat.gid) then + rwx = bit.bor(rwx, bit.rshift(stat.mode, 3)) end return bit.band(rwx, 2) ~= 0 end