Repository: frispete/keyrings.cryptfile

Issue:
custom the data file path with KEYRING_PROPERTY_* property
Need an env switch to control the output keyring data path to a custom location, such as `KEYRING_PROPERTY_CRYPTFILE_PATH`

Discussion:

Patch:
diff --git a/CHANGES.md b/CHANGES.md
index b595910..ff5efde 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,6 +1,7 @@
 1.4.1 (unreleased)
 ==================
 - Support for pulling the database from from the environment variable `KEYRING_CRYPTFILE_PASSWORD`
+- Support for customizing the location of the encrypted file config with the environment variable `KEYRING_CRYPTFILE_PATH`
 
 1.4.0
 =====
diff --git a/README.md b/README.md
index ee74b54..08014af 100644
--- a/README.md
+++ b/README.md
@@ -180,6 +180,11 @@ kr = CryptFileKeyring()
 keyring.set_keyring(kr)
 ```
 
+Environment variables
+---------------------
+`KEYRING_CRYPTFILE_PATH` can be used to customize the location of the encrypted file config
+`KEYRING_CRYPTFILE_PASSWORD` can be used to provide the password for the encrypted keyring database
+
 Testing
 -------
 
diff --git a/keyrings/cryptfile/file_base.py b/keyrings/cryptfile/file_base.py
index 47695bd..8cc8c6c 100644
--- a/keyrings/cryptfile/file_base.py
+++ b/keyrings/cryptfile/file_base.py
@@ -11,6 +11,7 @@ from keyring.backend import KeyringBackend
 from keyring.util import platform_
 from .escape import escape as escape_for_ini
 
+KEYRING_CRYPTFILE_PATH  = 'KEYRING_CRYPTFILE_PATH'
 
 class FileBacked(object):
     @abc.abstractproperty
@@ -25,7 +26,8 @@ class FileBacked(object):
         The path to the file where passwords are stored. This property
         may be overridden by the subclass or at the instance level.
         """
-        return os.path.join(platform_.data_root(), self.filename)
+        default = os.path.join(platform_.data_root(), self.filename)
+        return os.environ.get(KEYRING_CRYPTFILE_PATH, default)
 
     @abc.abstractproperty
     def scheme(self):
@@ -141,7 +143,7 @@ class Keyring(FileBacked, KeyringBackend):
             joiner = '\0'
         else:
             version_tuple = tuple(int(segment) for segment in self.file_version.split('.'))
-    
+
             if version_tuple >= (1, 3, 9):
                 joiner = '\0'
             elif version_tuple >= (1, 3, 6):


Test patch:
diff --git a/keyrings/cryptfile/tests/test_cryptfile.py b/keyrings/cryptfile/tests/test_cryptfile.py
index 679d36c..5bab80b 100644
--- a/keyrings/cryptfile/tests/test_cryptfile.py
+++ b/keyrings/cryptfile/tests/test_cryptfile.py
@@ -3,6 +3,7 @@ import os
 import pathlib
 import shutil
 import sys
+import tempfile
 from unittest import mock
 
 import pytest
@@ -163,3 +164,15 @@ def test_new_file(monkeypatch, tmp_path):
 
     kr.set_password('test write', 'user', 'test password')
     assert kr.get_password('test write', 'user') == 'test password'
+
+
+def test_new_file_via_env(monkeypatch, tmp_path):
+    fake_getpass = mock.Mock(return_value='passwd')
+    monkeypatch.setattr(getpass, 'getpass', fake_getpass)
+
+    with tempfile.TemporaryDirectory() as tmpdir:
+        os.environ['KEYRING_CRYPTFILE_PATH'] = os.path.join(tmpdir, "cf_new.cfg")
+        kr = cryptfile.CryptFileKeyring()
+        kr.set_password('test write', 'user', 'test password')
+        assert kr.get_password('test write', 'user') == 'test password'
+        assert os.path.exists(os.environ['KEYRING_CRYPTFILE_PATH'])