aboutsummaryrefslogtreecommitdiff
path: root/contrib/libeufin-dbconfig
blob: 80e258d544127d83d9814035c3a7b096d6484e1e (plain)
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#!/bin/bash
# This file is part of GNU TALER.
# Copyright (C) 2023 Taler Systems SA
#
# TALER is free software; you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free Software
# Foundation; either version 2.1, or (at your option) any later version.
#
# TALER is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along with
# TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
#
# @author Christian Grothoff
# @author Florian Dold

# Error checking on
set -eu

# 1 is true, 0 is false
RESET_DB=0
SKIP_DBINIT=0
FORCE_PERMS=0
NEXUS_DBUSER="libeufin-nexus"
BANK_DBUSER="libeufin-bank"
NEXUS_CFGFILE="/etc/libeufin/libeufin-nexus.conf"
BANK_CFGFILE="/etc/libeufin/libeufin-bank.conf"

function exit_fail() {
  echo "$@" >&2
  exit 1
}

# Parse command-line options
while getopts ':hn:b:d:rsu:v:' OPTION; do
  case "$OPTION" in
  h)
    echo 'Supported options:'
    echo "  -r                 -- reset database (dangerous)"
    echo "  -s                 -- skip database initialization"
    echo "  -p           -- force permission setup even without database initialization"
    echo "  -u NEXUS_USER      -- libeufin-nexus to be run by USER (default: $NEXUS_DBUSER)"
    echo "  -v BANK_USER       -- libeufin-bank to be run by USER (default: $BANK_DBUSER)"
    exit 0
    ;;
  r)
    RESET_DB="1"
    ;;
  s)
    SKIP_DBINIT="1"
    ;;
  u)
    NEXUS_DBUSER="$OPTARG"
    ;;
  v)
    BANK_DBUSER="$OPTARG"
    ;;

  ?)
    exit_fail "Unrecognized command line option"
    ;;
  esac
done

if ! id postgres >/dev/null; then
  exit_fail "Could not find 'postgres' user. Please install Postgresql first"
fi

if [ "$(id -u)" -ne 0 ]; then
  exit_fail "This script must be run as root"
fi

# If dbinit, then check if the tools are available.
if [ 0 = "$SKIP_DBINIT" ]; then
  if ! libeufin-nexus-dbinit --help 1>/dev/null; then
    exit_fail "Required 'libeufin-nexus-dbinit' not found. Please fix your installation."
  fi
  NEXUS_DBINIT=$(which libeufin-nexus-dbinit)
  if ! libeufin-bank-dbinit --help 1>/dev/null; then
    exit_fail "Required 'libeufin-bank-dbinit' not found. Please fix your installation."
  fi
  BANK_DBINIT=$(which libeufin-bank-dbinit)
fi

# Before running the tools, check if the OS users exist.
if ! id "$NEXUS_DBUSER" >/dev/null; then
  echo "Could not find '$NEXUS_DBUSER' user.  Cannot continue"
fi
if ! id "$BANK_DBUSER" >/dev/null; then
  exit_fail "Could not find '$BANK_DBUSER' user. Cannot continue"
fi

# Now provide the DB users, whose names match the OS users.
echo "Setting up database user $NEXUS_DBUSER." 1>&2
if ! sudo -i -u postgres createuser "$NEXUS_DBUSER" 2>/dev/null; then
  echo "Database user '$NEXUS_DBUSER' already existed. Continuing anyway." 1>&2
fi

echo "Setting up database user $BANK_DBUSER." 1>&2
if ! sudo -i -u postgres createuser "$BANK_DBUSER" 2>/dev/null; then
  echo "Database user '$BANK_DBUSER' already existed. Continuing anyway." 1>&2
fi

# When using this dbconfig script, the libeufin-bank and libeufin-nexus
# databases *must* match.

NEXUS_DBPATH=$(libeufin-nexus config get nexus-postgres CONFIG)

if ! echo "$NEXUS_DBPATH" | grep "postgres://" >/dev/null; then
  echo "Invalid libeufin-nexus database configuration value '$NEXUS_DBPATH'." 1>&2
  exit 1
fi

# Remove URI, host and query from postgres URI.
NEXUS_DBNAME=$(echo "$NEXUS_DBPATH" | sed -e 's|postgres://.*/||' -e 's|?.*||')

BANK_DBPATH=$(libeufin-bank config get libeufin-bankdb-postgres CONFIG)

if ! echo "$BANK_DBPATH" | grep "postgres://" >/dev/null; then
  echo "Invalid libeufin-bank database configuration value '$BANK_DBPATH'." 1>&2
  exit 1
fi

# Remove URI, host and query from postgres URI.
BANK_DBNAME=$(echo "$BANK_DBPATH" | sed -e 's|postgres://.*/||' -e 's|?.*||')

if [[ $NEXUS_DBNAME != "$BANK_DBNAME" ]]; then
  echo "Database names for libeufin-bank and libeufin-nexus must match ($NEXUS_DBNAME vs $BANK_DBNAME)" 1>&2
  exit 1
fi

# Both are the same now!
DBNAME=$BANK_DBNAME
# The DB is created by the nexus user.
# This is an arbitrary choice we make here.
DBUSER=$NEXUS_DBUSER

if sudo -i -u postgres psql "$DBNAME" </dev/null 2>/dev/null; then
  if [ 1 = "$RESET_DB" ]; then
    echo "Deleting existing database '$DBNAME'." 1>&2
    if ! sudo -i -u postgres dropdb "$DBNAME"; then
      echo "Failed to delete existing database '$DBNAME'"
      exit 1
    fi
    DO_CREATE=1
  else
    echo "Database '$DBNAME' already exists, continuing anyway."
    DO_CREATE=0
  fi
else
  DO_CREATE=1
fi

if [ 1 = "$DO_CREATE" ]; then
  echo "Creating database '$DBNAME'." 1>&2
  if ! sudo -i -u postgres createdb -O "$DBUSER" "$DBNAME"; then
    echo "Failed to create database '$DBNAME'"
    exit 1
  fi
fi

# We first initialize the libeufin-nexus DB
# and then adjust permissions for the _v schema,
# so that libeufin-bank can properly initialize
# its DB without running into permission problems.

if [ 0 = "$SKIP_DBINIT" ]; then
  echo "Initializing database '$DBNAME' for libeufin-nexus." 1>&2
  sudo -u "$NEXUS_DBUSER" "$NEXUS_DBINIT" -c "$NEXUS_CFGFILE"
fi

if [ 0 = "$SKIP_DBINIT" ] || [ 1 = "$FORCE_PERMS" ]; then
  echo "Setting postgres permissions for $BANK_DBUSER" 1>&2
  if ! echo "GRANT ALL PRIVILEGES ON DATABASE $DBNAME TO \"$BANK_DBUSER\"" |
    sudo -i -u postgres psql "$DBNAME"; then
    exit_fail "Failed to grant access to database '$DBNAME' to '$BANK_DBUSER'."
  fi
  if ! echo "GRANT USAGE ON SCHEMA _v TO \"$BANK_DBUSER\"" |
    sudo -i -u postgres psql "$DBNAME"; then
    exit_fail "Failed to grant usage privilege on schema '_v' to '$BANK_DBUSER'."
  fi
  if ! echo "GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA _v TO \"$BANK_DBUSER\"" |
    sudo -i -u postgres psql "$DBNAME"; then
    exit_fail "Failed to grant access to schema '_v' to '$BANK_DBUSER'."
  fi
  if ! echo "GRANT USAGE ON SCHEMA libeufin_nexus TO \"$BANK_DBUSER\"" |
    sudo -i -u postgres psql "$DBNAME"; then
    exit_fail "Failed to grant usage privilege on schema 'libeufin_nexus' to '$BANK_DBUSER'."
  fi
  if ! echo "GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA libeufin_nexus TO \"$BANK_DBUSER\"" |
    sudo -i -u postgres psql "$DBNAME"; then
    exit_fail "Failed to grant all privileges on schema 'libeufin_nexus' to '$BANK_DBUSER'."
  fi
fi

if [ 0 = "$SKIP_DBINIT" ]; then
  echo "Initializing database '$DBNAME' for libeufin-bank." 1>&2
  sudo -u "$BANK_DBUSER" "$BANK_DBINIT" -c "$BANK_CFGFILE"
fi

if [ 0 = "$SKIP_DBINIT" ] || [ 1 = "$FORCE_PERMS" ]; then
  echo "Setting postgres permissions for $NEXUS_DBUSER" 1>&2
  if ! echo "GRANT USAGE ON SCHEMA libeufin_bank TO \"$NEXUS_DBUSER\"" |
    sudo -i -u postgres psql "$DBNAME"; then
    exit_fail "Failed to grant usage privilege on schema 'libeufin_bank' to '$NEXUS_DBUSER'."
  fi
  if ! echo "GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA libeufin_bank TO \"$NEXUS_DBUSER\"" |
    sudo -i -u postgres psql "$DBNAME"; then
    exit_fail "Failed to grant all privileges on schema 'libeufin_bank' to '$NEXUS_DBUSER'."
  fi
fi

echo "Database configuration finished." 1>&2