-
Notifications
You must be signed in to change notification settings - Fork 0
/
psql-store-credential
executable file
·134 lines (120 loc) · 4.19 KB
/
psql-store-credential
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#!/bin/sh
set -e
set -u
fn_help() { (
echo "psql-store-credential v1.0.0 - stores a credential in ~/.pgpass"
echo ""
echo "USAGE"
echo " [space] pg-addpass [pg-url]"
echo ""
echo "EXAMPLES"
echo " Prompt for PG_URL string"
echo " pg-addpass"
echo " Prefix with space and give PG_URL string"
echo " pg-addpass 'postgress://user:pass@host:port/db?sslmode=verify-full'"
echo " Parse PG_URL from .env file"
echo " cat .env | grep PG_URL | cut -d'=' -f2- | pg-addpass"
echo ""
echo "NOTES"
echo " - query parameters will be *ignored* (ex: ?sslmode=)"
echo " - passwords with ':' or '@' will not be parsed correctly"
echo " (you may be able to enter them into ~/.pgpass manually)"
echo ""
echo "WARNING"
echo " remember to clear this command from your shell history if"
echo " you don't want the password to be saved there"
echo " (some shells omit commands if you prefix them with a space)"
echo ""
echo "COPYING"
echo " Copyright (c) 2024 AJ ONeal <[email protected]>"
echo " Licensed under the MPL-2.0"
); }
fn_init_pgpass() { (
if ! test -e ~/.pgpass; then
touch ~/.pgpass
fi
if ! grep -q -i '^\s*#.*port:d' ~/.pgpass; then
echo '# hostname:port:database:username:password' >> ~/.pgpass.header.txt
mv ~/.pgpass ~/.pgpass.noheader.bak
cat ~/.pgpass.header.txt ~/.pgpass.noheader.bak > ~/.pgpass
rm ~/.pgpass.header.txt ~/.pgpass.noheader.bak
fi
if ! grep -q '^\s*#\s*export\s\+PGPASSFILE=' ~/.pgpass; then
echo "# export PGPASSFILE='${HOME}/.pgpass'" >> ~/.pgpass.header.txt
mv ~/.pgpass ~/.pgpass.noheader.bak
cat ~/.pgpass.header.txt ~/.pgpass.noheader.bak > ~/.pgpass
rm ~/.pgpass.header.txt ~/.pgpass.noheader.bak
fi
chmod 0600 ~/.pgpass
); }
fn_add_pgpass() { (
b_url="${1}"
if echo "${b_url}" | grep -q -v '?'; then
b_url="${b_url}?"
fi
b_params="$(echo "${b_url}" | cut -d'@' -f2 | cut -d'?' -f2-)"
b_host_port="$(echo "${b_url}" | cut -d'@' -f2 | cut -d'/' -f1)"
b_host="$(echo "${b_host_port}" | cut -d':' -f1)"
b_db="$(echo "${b_url}" | rev | cut -d'/' -f1 | rev | cut -d'?' -f1)"
b_user_pass="$(echo "${b_url}" | cut -d'@' -f1 | sed 's;://;:;g' | cut -d':' -f2-)"
b_user="$(echo "${b_user_pass}" | cut -d':' -f1)"
b_pass="$(echo "${b_user_pass}" | cut -d':' -f2-)"
b_mask="$(printf '%s' "${b_pass}" | tr '[:graph:]' '*')" # omit newline
if grep -q -F "${b_host_port}:${b_db}:${b_user_pass}" ~/.pgpass; then
echo "'${b_host_port}:${b_db}:${b_user}:${b_mask}' found in ~/.pgpass"
return 0
fi
if grep -q -F "${b_host_port}:${b_db}:${b_user}:" ~/.pgpass; then
echo "${b_host_port}:${b_db}:${b_user} already exists in ~/.pgpass"
{
echo ""
echo " PLEASE UPDATE PASSWORD MANUALLY"
echo ""
} >&2
return 1
fi
{
echo ""
echo "Saved to ~/.pgpass:"
} >&2
echo "${b_host_port}:${b_db}:${b_user_pass}" >> ~/.pgpass
echo "${b_host_port}:${b_db}:${b_user}:${b_mask}"
if ! grep -q -F "*:*:${b_db}:${b_user}:" ~/.pgpass; then
echo "*:*:${b_db}:${b_user_pass}" >> ~/.pgpass
echo "*:*:${b_db}:${b_user}:${b_mask}"
fi
{
echo ""
echo "The password will be matched by host (or localhost), dbname, and username"
} >&2
echo " psql --host ${b_host} --dbname ${b_db} --username ${b_user}"
echo " psql 'postgres://${b_user}@${b_host}/${b_db}?${b_params}'"
); }
main() { (
b_url=""
case ${1:-} in
--help | help)
fn_help
return 0
;;
-V | --version | version)
fn_help
return 0
;;
"")
echo 'Example: postgres://user:pass@host:port/db?params'
printf 'PG_URL: '
read -r b_url
;;
*)
b_url="${1}"
;;
esac
if test -z "${b_url}"; then
echo "error: no url provided and failed to read url from tty" >&2
return 1
fi
fn_init_pgpass
fn_add_pgpass "${b_url}" >&2
); }
main "${@}"