Refactor plugin to not rely on caching for writing anymore

Also test if the buffer is backed by a file, and fail if not
This commit is contained in:
Olivier Perret 2019-01-24 10:22:11 +01:00
parent f9bbf4606b
commit 9a11b5c8c2
2 changed files with 42 additions and 33 deletions

View File

@ -10,8 +10,6 @@ Add `sudo-write.kak` to your autoload dir: `~/.config/kak/autoload/`, or source
Call the `sudo-write` command. If your password has not been cached by `sudo`, you will be prompted to input it. Upon success, the buffer is written to the file. Call the `sudo-write` command. If your password has not been cached by `sudo`, you will be prompted to input it. Upon success, the buffer is written to the file.
Note that the plugin will not work if you do not use any cache for `sudo`.
**Warning**: while the input is hidden, the password is still passed through stdin to `sudo`. Do not use this plugin if you are not comfortable with this idea. **Warning**: while the input is hidden, the password is still passed through stdin to `sudo`. Do not use this plugin if you are not comfortable with this idea.
## License ## License

View File

@ -1,9 +1,9 @@
# save the current buffer to its file as root # save the current buffer to its file as root using `sudo`
# (optionally pass the user password to sudo if not cached) # (optionally pass the user password to sudo if not cached)
define-command -hidden sudo-write-impl %{ define-command -hidden sudo-write-cached-password %{
# easy case: the password was already cached, so we don't need any tricky handling
eval -save-regs f %{ eval -save-regs f %{
# TOOD this could take the content of the buffer from stdin instead
reg f %sh{ mktemp --tmpdir XXXXX } reg f %sh{ mktemp --tmpdir XXXXX }
write %reg{f} write %reg{f}
eval %sh{ eval %sh{
@ -11,49 +11,60 @@ define-command -hidden sudo-write-impl %{
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
echo "edit!" echo "edit!"
else else
echo "echo -markup '{Error}Something went wrong'" echo 'fail "Unknown failure"'
fi fi
rm -f "$kak_main_reg_f" rm -f "$kak_main_reg_f"
} }
} }
} }
define-command -hidden -params 1 sudo-cache-password %{ define-command -hidden sudo-write-prompt-password %{
eval -no-hooks -save-regs '"c' %{
eval -draft %{
edit -scratch *sudo-write-pass*
reg '"' %arg{1}
exec "<a-p>|sudo -S echo ok<ret>"
try %{
exec '%H<a-k>ok<ret>'
reg c nop
} catch %{
reg c fail
}
}
delete-buffer *sudo-write-pass*
eval %reg{c}
}
}
define-command -hidden sudo-prompt-password %{
prompt -password 'Password:' %{ prompt -password 'Password:' %{
try %{ eval -save-regs r %{
sudo-cache-password %val{text} eval -draft -save-regs 'tf|"' %{
sudo-write-impl reg t %val{buffile}
} catch %{ reg f %sh{ mktemp --tmpdir XXXXX }
echo -markup '{Error}Incorrect password' write %reg{f}
# write the password in a buffer in order to pass it through STDIN to sudo
# somewhat dangerous, but better than passing the password
# through the shell scope's environment or interpolating it inside the shell string
# 'exec |' is pretty much the only way to pass data over STDIN
edit -scratch '*sudo-password-tmp*'
reg '"' "%val{text}"
exec <a-P>
reg | %{
sudo -S -- dd if="$kak_main_reg_f" of="$kak_main_reg_t" > /dev/null 2>&1
if [ $? -eq 0 ]; then
printf 'edit!'
else
printf 'fail "Incorrect password?"'
fi
rm -f "$kak_main_reg_f"
}
exec '|<ret>'
exec -save-regs '' '%"ry'
delete-buffer! '*sudo-password-tmp*'
}
eval %reg{r}
} }
} }
} }
define-command sudo-write -docstring "Write the content of the buffer using sudo" %{ define-command sudo-write -docstring "Write the content of the buffer using sudo" %{
%sh{ eval %sh{
# tricky posix-way of getting the first character of a variable
# no subprocess!
if [ "${kak_buffile%"${kak_buffile#?}"}" != "/" ]; then
# not entirely foolproof as a scratch buffer may start with '/', but good enough
printf 'fail "Not a file"'
exit
fi
# check if the password is cached # check if the password is cached
if sudo -n true > /dev/null 2>&1; then if sudo -n true > /dev/null 2>&1; then
echo sudo-write-impl printf sudo-write-cached-password
else else
echo sudo-prompt-password printf sudo-write-prompt-password
fi fi
} }
} }