Skip to content

Commit 8d78a70

Browse files
authored
Merge pull request #13 from dotenv-org/find-dotenv-vault-file
allow to find .env.vault
2 parents 1475d88 + 8b9b1aa commit 8d78a70

File tree

5 files changed

+44
-6
lines changed

5 files changed

+44
-6
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. See [standa
44

55
## [Unreleased](https://github.com/dotenv-org/python-dotenv-vault/compare/v0.5.1...master)
66

7+
## 0.6.2
8+
9+
### Changed
10+
11+
- Look for .env.vault file at same location as .env file. Finds .env file anywhere in app (just like original python lib) [#13](https://github.com/dotenv-org/python-dotenv-vault/pull/13)
12+
713
## 0.6.1
814

915
### Changed

setup.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import os
2-
import sys
32
from setuptools import setup, find_packages
43

54
src = {}

src/dotenv_vault/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
__title__ = "python-dotenv-vault"
22
__description__ = "Decrypt .env.vault file."
33
__url__ = "https://github.com/dotenv-org/python-dotenv-vault"
4-
__version__ = "0.6.1"
4+
__version__ = "0.6.2"
55
__author__ = "dotenv"
66
__author_email__ = "mot@dotenv.org"
77
__license__ = "MIT"

src/dotenv_vault/main.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,28 @@
33
from base64 import b64decode
44
import io
55
import os
6+
import logging
7+
68
from typing import (IO, Optional, Union)
79
from urllib.parse import urlparse, parse_qsl
810

911
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
1012
from cryptography.exceptions import InvalidTag
1113
import dotenv.main as dotenv
1214

15+
logger = logging.getLogger(__name__)
16+
17+
def load_dotenv_vault() -> str:
18+
path = dotenv.find_dotenv()
19+
if not path:
20+
return path
21+
path = os.path.dirname(path)
22+
if '.env.vault' not in os.listdir(path):
23+
# we fall back to .env
24+
logger.warning(f"You set DOTENV_KEY but you are missing a .env.vault file at {path}. Did you forget to build it?")
25+
return f"{path}/.env"
26+
return f"{path}/.env.vault"
27+
1328

1429
def load_dotenv(
1530
dotenv_path: Union[str, os.PathLike, None] = None,
@@ -40,7 +55,7 @@ def load_dotenv(
4055
4156
"""
4257
if "DOTENV_KEY" in os.environ:
43-
vault_stream = parse_vault(open(".env.vault"))
58+
vault_stream = parse_vault(open(load_dotenv_vault()))
4459
return dotenv.load_dotenv(
4560
stream=vault_stream,
4661
verbose=verbose,
@@ -75,7 +90,7 @@ def parse_vault(vault_stream: io.IOBase) -> io.StringIO:
7590
raise DotEnvVaultError("NOT_FOUND_DOTENV_KEY: Cannot find ENV['DOTENV_KEY']")
7691

7792
# Use the python-dotenv library to read the .env.vault file.
78-
vault = dotenv.DotEnv(dotenv_path=".env.vault", stream=vault_stream)
93+
vault = dotenv.DotEnv(dotenv_path=load_dotenv_vault(), stream=vault_stream)
7994

8095
# Extract segments from the DOTENV_KEY environment variable one by
8196
# one and retrieve the corresponding ciphertext from the vault

src/dotenv_vault/test_vault.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
from io import StringIO
22
import os
33
import unittest
4+
from unittest import mock
45

56
from dotenv.main import load_dotenv
67

78
import dotenv_vault.main as vault
89

910
class TestParsing(unittest.TestCase):
11+
1012
TEST_KEYS = [
1113
# OK.
1214
["dotenv://:key_0dec82bea24ada79a983dcc11b431e28838eae59a07a8f983247c7ca9027a925@dotenv.local/vault/.env.vault?environment=development",
@@ -23,7 +25,7 @@ class TestParsing(unittest.TestCase):
2325
# Missing environment.
2426
["dotenv://:key_1234@dotenv.org/vault/.env.vault", False, ""]
2527
]
26-
28+
2729
def test_key_parsing(self):
2830
for test in self.TEST_KEYS:
2931
dotenv_key, should_pass, environment_key_check = test
@@ -49,7 +51,7 @@ def test_key_parsing(self):
4951
DOTENV_VAULT_STAGING="uGHOx986lAWGU9s5mN5+b0jl0HAvNj4Mqs/zwN7Bl8UeV+C6hBg5JuKdi2AGGLka5g=="
5052
DOTENV_VAULT_PRODUCTION="YpDpGGf+eqiOPibziIQQbw4gBW/zfOBR6jow5B1UHYTTu6Kak6xy+qP/vXZWaPp4HOh2/Nu7gRK2CWfrbtk="
5153
"""
52-
54+
5355
def test_vault_parsing(self):
5456
old_dotenv_key = os.environ.get("DOTENV_KEY")
5557
os.environ["DOTENV_KEY"] = self.PARSE_TEST_KEY
@@ -61,3 +63,19 @@ def test_vault_parsing(self):
6163
os.unsetenv("DOTENV_KEY")
6264
if old_dotenv_key:
6365
os.environ["DOTENV_KEY"] = old_dotenv_key
66+
67+
@mock.patch("dotenv.main.find_dotenv")
68+
def test_load_dotenv_vault(self, find_dotenv):
69+
find_dotenv.return_value = '/some/path/'
70+
with mock.patch('os.listdir') as mocked_listdir:
71+
mocked_listdir.return_value = ['.env', '.env.vault', 'some_file']
72+
path = vault.load_dotenv_vault()
73+
self.assertEqual(path, '/some/path/.env.vault')
74+
75+
@mock.patch("dotenv.main.find_dotenv")
76+
def test_load_dotenv_vault_not_there(self, find_dotenv):
77+
find_dotenv.return_value = '/some/path/'
78+
with mock.patch('os.listdir') as mocked_listdir:
79+
mocked_listdir.return_value = ['.env', 'some_file']
80+
path = vault.load_dotenv_vault()
81+
self.assertEqual(path, '/some/path/.env')

0 commit comments

Comments
 (0)