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 <stevearc@stevearc.com>
This commit is contained in:
DerpDays 2024-06-21 14:07:03 +01:00 committed by GitHub
parent f6df58ad37
commit 65c53dbe4f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -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