Skip to content

Commit b388cee

Browse files
feat: interpret basic authorization token
Add request hook to convert "Authorization: Basic username:passeord" to "Authorization: Basic <base64-encoded>" before reqeust.
1 parent 2ded89d commit b388cee

File tree

9 files changed

+87
-4
lines changed

9 files changed

+87
-4
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,9 @@ local default_config = {
125125
user_agent = "rest.nvim v" .. require("rest-nvim.api").VERSION,
126126
---@type boolean Set `Content-Type` header when it is empty and body is provided
127127
set_content_type = true,
128+
---@type boolean Interpret `Authorization` header when it is set in form of
129+
---"Basic username:password" or "Basic username password"
130+
interpret_basic_auth = true,
128131
},
129132
},
130133
---@class rest.Config.Response

doc/rest-nvim.txt

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,14 @@ rest.Opts.Request *rest.Opts.Request*
149149
rest.Opts.Request.Hooks *rest.Opts.Request.Hooks*
150150

151151
Fields: ~
152-
{encode_url?} (boolean) Encode URL before making request (Default: `true`)
153-
{user_agent?} (string) Set `User-Agent` header when it is empty. Set as empty string to disable.
154-
(Default: `rest.nvim {version}`)
155-
{set_content_type?} (boolean) Set `Content-Type` header when it is empty but request body is provided
152+
{encode_url?} (boolean) Encode URL before making request (Default: `true`)
153+
{user_agent?} (string) Set `User-Agent` header when it is empty. Set as empty string to disable.
154+
(Default: `rest.nvim {version}`)
155+
{set_content_type?} (boolean) Set `Content-Type` header when it is empty but request body is provided
156+
{interpret_basic_auth?} (boolean) Interpret `Authorization` header when it is set in form of
157+
"Basic username:password" or "Basic username password"
158+
It will convert header to "Basic <base64-encoded-username:password>"
159+
(Default: `true`)
156160

157161

158162
rest.Opts.Response *rest.Opts.Response*

lua/rest-nvim/autocmds.lua

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,14 @@ function autocmds.setup()
8181
end
8282
end
8383
end
84+
if hooks.interpret_basic_auth then
85+
local auth_header = req.headers["authorization"]
86+
if auth_header then
87+
local auth_header_value = auth_header[#auth_header]
88+
local id, pw = auth_header_value:match("Basic%s+([^:%s]+)%s*[:(%s+)]%s*(.*)")
89+
auth_header[#auth_header] = "Basic " .. require("base64").encode(id .. ":" .. pw)
90+
end
91+
end
8492
end,
8593
})
8694
vim.api.nvim_create_autocmd("User", {

lua/rest-nvim/config/default.lua

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ local default_config = {
1919
user_agent = "rest.nvim v" .. require("rest-nvim.api").VERSION,
2020
---@type boolean Set `Content-Type` header when it is empty and body is provided
2121
set_content_type = true,
22+
---@type boolean Interpret `Authorization` header when it is set in form of
23+
---"Basic username:password" or "Basic username password"
24+
interpret_basic_auth = true,
2225
},
2326
},
2427
---@class rest.Config.Response

lua/rest-nvim/config/init.lua

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ local config
4343
---@field user_agent? string
4444
--- Set `Content-Type` header when it is empty but request body is provided
4545
---@field set_content_type? boolean
46+
--- Interpret `Authorization` header when it is set in form of
47+
--- "Basic username:password" or "Basic username password"
48+
--- It will convert header to "Basic <base64-encoded-username:password>"
49+
--- (Default: `true`)
50+
---@field interpret_basic_auth? boolean
4651

4752
---@class rest.Opts.Response
4853
--- Default response hooks (aka. request handlers) configuration

nix/plugin-overlay.nix

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,25 @@
11
{ self }: final: prev: let
22
luaPackages-override = luaself: luaprev: {
33
tree-sitter-http = luaself.callPackage ./tree-sitter-http.nix {};
4+
base64 = luaself.callPackage ({
5+
buildLuarocksPackage,
6+
fetchurl,
7+
fetchzip,
8+
luaOlder,
9+
}:
10+
buildLuarocksPackage {
11+
pname = "base64";
12+
version = "1.5-3";
13+
knownRockspec = (fetchurl {
14+
url = "mirror://luarocks/base64-1.5-3.rockspec";
15+
sha256 = "sha256-jMWugDDJMOfapPyEWVrC2frF24MSr8pLsNtwK9ejLwM=";
16+
}).outPath;
17+
src = fetchzip {
18+
url = "https://github.com/iskolbin/lbase64/archive/c261320edbdf82c16409d893a96c28c704aa0ab8.zip";
19+
sha256 = "sha256-Ucu7pxEbyeUyV12+FeFbGNhXiKsGYlXFMrb1Vhsnfrc=";
20+
};
21+
disabled = luaOlder "5.1";
22+
}) {};
423
rest-nvim = luaself.callPackage ({
524
buildLuarocksPackage,
625
fetchurl,
@@ -19,6 +38,7 @@
1938
mimetypes
2039
xml2lua
2140
fidget-nvim
41+
base64
2242
tree-sitter-http
2343
];
2444
}) {};

nix/test-overlay.nix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
mimetypes
1515
xml2lua
1616
fidget-nvim
17+
final.lua51Packages.base64
1718
final.lua51Packages.tree-sitter-http
1819
];
1920
extraPackages = [

rest.nvim-scm-1.rockspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ dependencies = {
2525
"mimetypes",
2626
"xml2lua",
2727
"fidget.nvim",
28+
"base64",
2829
"tree-sitter-http == 0.0.35",
2930
}
3031

spec/examples/examples_spec.lua

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,4 +119,42 @@ describe("builtin request hooks", function()
119119
assert.same({ "application/json" }, req.headers["content-type"])
120120
end)
121121
end)
122+
---@return rest.Request
123+
local function sample_request(opts)
124+
return vim.tbl_deep_extend("keep", opts, {
125+
method = "GET",
126+
url = "https://example.com",
127+
headers = {},
128+
cookies = {},
129+
handlers = {},
130+
})
131+
end
132+
describe("interpret_basic_auth", function()
133+
it("with valid vscode style token", function()
134+
local req = sample_request({
135+
headers = {
136+
["authorization"] = { "Basic username:password" },
137+
},
138+
})
139+
_G.rest_request = req
140+
vim.api.nvim_exec_autocmds("User", {
141+
pattern = { "RestRequest", "RestRequestPre" },
142+
})
143+
_G.rest_request = nil
144+
assert.same({ "Basic dXNlcm5hbWU6cGFzc3dvcmQ=" }, req.headers["authorization"])
145+
end)
146+
it("with valid intellij style token", function()
147+
local req = sample_request({
148+
headers = {
149+
["authorization"] = { "Basic username password" },
150+
},
151+
})
152+
_G.rest_request = req
153+
vim.api.nvim_exec_autocmds("User", {
154+
pattern = { "RestRequest", "RestRequestPre" },
155+
})
156+
_G.rest_request = nil
157+
assert.same({ "Basic dXNlcm5hbWU6cGFzc3dvcmQ=" }, req.headers["authorization"])
158+
end)
159+
end)
122160
end)

0 commit comments

Comments
 (0)