Files
gitea.nvim/lua/gitea/auth.lua
2024-12-23 19:09:51 +01:00

109 lines
3.5 KiB
Lua

local config = require("gitea.config")
local uv = vim.loop
local M = {}
local token_cached = nil
-- Read token file from disk (if present)
local function read_token_file(path)
local fd = uv.fs_open(path, "r", 438)
if not fd then return nil end
local stat = uv.fs_fstat(fd)
local data = uv.fs_read(fd, stat.size, 0)
uv.fs_close(fd)
return data
end
-- Write token file to disk with restricted permissions
local function write_token_file(path, token)
local fd = uv.fs_open(path, "w", 384) -- 0600 decimal
if not fd then
error("[gitea.nvim] Failed to open token file for writing: " .. path)
end
uv.fs_write(fd, token, -1)
uv.fs_close(fd)
end
----------------------------------------------------------------------------
--- Attempt to detect the Gitea server from remote.origin.url or fail
----------------------------------------------------------------------------
local function detect_gitea_server()
-- Use `git config remote.origin.url`
local cmd = "git config remote.origin.url"
local url = vim.fn.systemlist(cmd)[1]
if vim.v.shell_error ~= 0 or not url or url == "" then
return nil, "No valid remote.origin.url found"
end
-- Remove trailing ".git" if present
url = url:gsub("%.git$", "")
-- Check for HTTPS style: https://my.gitea.com/owner/repo
local protocol, domain_and_path = url:match("^(https?://)(.*)$")
if protocol and domain_and_path then
local server = domain_and_path:match("^([^/]+)")
if server and server ~= "" then
return protocol .. server
end
end
-- Check for SSH style: git@my.gitea.com:owner/repo
local user_host, path = url:match("^(.-):(.*)$")
if user_host and user_host:match(".*@") then
local host = user_host:match("@(.*)")
if host and host ~= "" then
-- We'll assume https for Gitea, if your instance is not https,
-- you can adapt or forcibly use "http://" below
return "https://" .. host
end
end
return nil, "Unable to parse Gitea host from remote.origin.url: " .. url
end
----------------------------------------------------------------------------
--- DO NOT PROMPT for server_url, do not fallback to "gitea.example.com"
--- If we cannot auto-detect, we throw an error.
----------------------------------------------------------------------------
local function ensure_server_url()
local server, err = detect_gitea_server()
if not server then
error(string.format("[gitea.nvim] Failed to auto-detect Gitea server: %s", err))
end
config.values.server_url = server
end
----------------------------------------------------------------------------
--- The user must have a Gitea token, we read from disk or error if missing
----------------------------------------------------------------------------
local function ensure_token_file()
local token_file = config.values.config_file
local token_data = read_token_file(token_file)
if token_data and token_data ~= "" then
token_cached = token_data
return
end
error(
"[gitea.nvim] No token found in " .. token_file ..
". Please manually create and store your Gitea token there with mode 600."
)
end
----------------------------------------------------------------------------
--- Called by the plugin during setup or first usage
----------------------------------------------------------------------------
function M.ensure_token()
if token_cached then
return token_cached
end
ensure_server_url()
ensure_token_file()
return token_cached
end
function M.get_token()
return token_cached
end
return M