commit ffee7b0325256ce79a349df2c982607ce5d6d6b1
Author: Dominik George <nik@naturalnet.de>
Date: Thu Feb 18 00:21:24 2021 +0100
Pass PostgreSQL password in a temporary .pgpass file
diff --git a/django/db/backends/base/client.py b/django/db/backends/base/client.py
index 339f1e863c..a9eb4f2149 100644
a
|
b
|
class BaseDatabaseClient:
|
20 | 20 | ) |
21 | 21 | |
22 | 22 | def runshell(self, parameters): |
23 | | args, env = self.settings_to_cmd_args_env(self.connection.settings_dict, parameters) |
24 | | if env: |
25 | | env = {**os.environ, **env} |
26 | | subprocess.run(args, env=env, check=True) |
| 23 | with self.settings_to_cmd_args_env(self.connection.settings_dict, parameters) as args, env: |
| 24 | if env: |
| 25 | env = {**os.environ, **env} |
| 26 | subprocess.run(args, env=env, check=True) |
diff --git a/django/db/backends/postgresql/client.py b/django/db/backends/postgresql/client.py
index 2339880967..73a2086017 100644
a
|
b
|
|
| 1 | import os |
1 | 2 | import signal |
| 3 | from contextlib import contextmanager |
| 4 | from tempfile import mkstemp |
2 | 5 | |
3 | 6 | from django.db.backends.base.client import BaseDatabaseClient |
4 | 7 | |
… |
… |
from django.db.backends.base.client import BaseDatabaseClient
|
6 | 9 | class DatabaseClient(BaseDatabaseClient): |
7 | 10 | executable_name = 'psql' |
8 | 11 | |
| 12 | @contextmanager |
9 | 13 | @classmethod |
10 | 14 | def settings_to_cmd_args_env(cls, settings_dict, parameters): |
11 | 15 | args = [cls.executable_name] |
… |
… |
class DatabaseClient(BaseDatabaseClient):
|
32 | 36 | args.extend(parameters) |
33 | 37 | |
34 | 38 | env = {} |
35 | | if passwd: |
36 | | env['PGPASSWORD'] = str(passwd) |
37 | 39 | if service: |
38 | 40 | env['PGSERVICE'] = str(service) |
39 | 41 | if sslmode: |
… |
… |
class DatabaseClient(BaseDatabaseClient):
|
44 | 46 | env['PGSSLCERT'] = str(sslcert) |
45 | 47 | if sslkey: |
46 | 48 | env['PGSSLKEY'] = str(sslkey) |
47 | | return args, env |
| 49 | if passwd: |
| 50 | pass_fd, pass_path = mkstemp() |
| 51 | os.close(pass_fd) |
| 52 | with open(pass_path, 'w') as pass_file: |
| 53 | pass_file.write(f'*:*:*:*:{passwd}\n') |
| 54 | env['PGPASSFILE'] = pass_path |
| 55 | else: |
| 56 | pass_path = '' |
| 57 | |
| 58 | try: |
| 59 | yield args, env |
| 60 | finally: |
| 61 | if pass_path: |
| 62 | os.unlink(pass_path) |
48 | 63 | |
49 | 64 | def runshell(self, parameters): |
50 | 65 | sigint_handler = signal.getsignal(signal.SIGINT) |