Initial commit
This commit is contained in:
commit
eb360786be
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
*.swp
|
||||||
|
*.pyc
|
||||||
|
__pycache__/
|
||||||
|
build/
|
||||||
|
dist/
|
||||||
|
dbsettings.egg-info/
|
21
LICENSE
Normal file
21
LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
Copyright (c) 2021, Kumi Systems e.U.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
2
MANIFEST.in
Normal file
2
MANIFEST.in
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
include LICENSE
|
||||||
|
include README.md
|
77
README.md
Normal file
77
README.md
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
# django-autosecretkey
|
||||||
|
|
||||||
|
autosecretkey is a simple reusable Django app which will make it easier to
|
||||||
|
distribute your Django project by taking care of generating a secure SECRET_KEY
|
||||||
|
and storing it outside of your project's settings.py
|
||||||
|
|
||||||
|
## Quick start
|
||||||
|
|
||||||
|
1. In your project's settings.py, import the app like so:
|
||||||
|
|
||||||
|
```from autosecretkey import AutoSecretKey```
|
||||||
|
|
||||||
|
2. Still in the settings.py file, replace the existing SECRET_KEY line with
|
||||||
|
something like this:
|
||||||
|
|
||||||
|
```SECRET_KEY = AutoSecretKey(BASE_DIR / "config.ini").secret_key```
|
||||||
|
|
||||||
|
(N.B.: Of course, this line has to be after the BASE_DIR line.)
|
||||||
|
|
||||||
|
This will store the key in a file called `config.ini` in your project's base
|
||||||
|
directory (i.e. the one containing `manage.py`).
|
||||||
|
|
||||||
|
Make sure not to ship this file with your code distribution. For example,
|
||||||
|
you may want to add it to your .gitignore file if you publish the project in
|
||||||
|
a git repository.
|
||||||
|
|
||||||
|
## Additional configuration
|
||||||
|
|
||||||
|
For additional security, you may want to store your secret key in a different
|
||||||
|
location than your project's base directory. You could, for example, do
|
||||||
|
something like this:
|
||||||
|
|
||||||
|
```AutoSecretKey("/etc/your_project/configuration")```
|
||||||
|
|
||||||
|
You need to manually make sure that the user your Django project runs as has
|
||||||
|
the permission to read and write this file. Running something like this as
|
||||||
|
root should do the trick in Linux (replacing "djangouser" with the actual user
|
||||||
|
name):
|
||||||
|
|
||||||
|
```
|
||||||
|
mkdir /etc/your_project/
|
||||||
|
touch /etc/your_project/configuration
|
||||||
|
chown djangouser /etc/your_project/configuration
|
||||||
|
```
|
||||||
|
|
||||||
|
In the end, this is just a simple wrapper around configparser.ConfigParser, so
|
||||||
|
you can store custom configuration values in the file that holds your secret
|
||||||
|
key. You can access the ConfigParser object as the `config` attribute of your
|
||||||
|
AutoSecretKey object.
|
||||||
|
|
||||||
|
This is a simple example you could have in your `settings.py`:
|
||||||
|
|
||||||
|
```
|
||||||
|
from autosecretkey import AutoSecretKey
|
||||||
|
my_config_file = AutoSecretKey(BASE_DIR / "config.ini")
|
||||||
|
SECRET_KEY = my_config_file.secret_key
|
||||||
|
TIME_ZONE = my_config_file.config["MY_SETTINGS"]["TIME_ZONE"]
|
||||||
|
```
|
||||||
|
|
||||||
|
For reference, the corresponding `config.ini` might look like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
[AutoSecretKey]
|
||||||
|
SecretKey = WellThisIsWhereYouWillFindYourSecretKey
|
||||||
|
|
||||||
|
[MY_SETTINGS]
|
||||||
|
TIME_ZONE = UTC
|
||||||
|
```
|
||||||
|
|
||||||
|
All methods you can use on any other ConfigParser object can be used on that
|
||||||
|
object as well, of course, like get(), getboolean(), etc. For convenience, you
|
||||||
|
can use the AutoSecretKey object's update() method to re-read the contents of
|
||||||
|
the config file, and the write() method to write back any changes you have made
|
||||||
|
on the object to the configuration file.
|
||||||
|
|
||||||
|
Note that the ConfigParser behaves like a RawConfigParser in that it does not
|
||||||
|
support interpolation.
|
48
autosecretkey/__init__.py
Normal file
48
autosecretkey/__init__.py
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
import configparser
|
||||||
|
|
||||||
|
from django.core.management.utils import get_random_secret_key
|
||||||
|
|
||||||
|
class AutoSecretKey:
|
||||||
|
@staticmethod
|
||||||
|
def write_config_file(path, config):
|
||||||
|
with open(path, "w") as outfile:
|
||||||
|
config.write(outfile)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def read_config_file(cls, path, create=True):
|
||||||
|
config = configparser.ConfigParser(interpolation=None)
|
||||||
|
|
||||||
|
try:
|
||||||
|
config.read(path)
|
||||||
|
|
||||||
|
except FileNotFoundError:
|
||||||
|
if not create:
|
||||||
|
raise
|
||||||
|
|
||||||
|
cls.write_config_file(path, config)
|
||||||
|
|
||||||
|
return config
|
||||||
|
|
||||||
|
def write(self):
|
||||||
|
self.__class__.write_config_file(self.path, self.config)
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
self.config = self.__class__.read_config_file(self.path)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def secret_key(self):
|
||||||
|
try:
|
||||||
|
return self.config[self.section][self.config_key]
|
||||||
|
except (KeyError, TypeError):
|
||||||
|
new_key = get_random_secret_key()
|
||||||
|
|
||||||
|
self.config[self.section] = { self.config_key: new_key }
|
||||||
|
self.write()
|
||||||
|
|
||||||
|
return new_key
|
||||||
|
|
||||||
|
def __init__(self, path, section="AutoSecretKey", config_key="SecretKey"):
|
||||||
|
self.path = path
|
||||||
|
self.section = section
|
||||||
|
self.config_key = config_key
|
||||||
|
self.update()
|
32
setup.cfg
Normal file
32
setup.cfg
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
[metadata]
|
||||||
|
name = django-autosecretkey
|
||||||
|
version = 0.9
|
||||||
|
description = A simple Django app to store secret keys outside of settings.py
|
||||||
|
long_description = file: README.md
|
||||||
|
long_description_content_type = text/markdown
|
||||||
|
url = https://kumig.it/kumisystems/django-autosecretkey
|
||||||
|
author = Kumi Systems e.U.
|
||||||
|
author_email = support@kumi.systems
|
||||||
|
license = BSD-2-Clause
|
||||||
|
classifiers =
|
||||||
|
Environment :: Web Environment
|
||||||
|
Framework :: Django
|
||||||
|
Framework :: Django :: 3.0
|
||||||
|
Intended Audience :: Developers
|
||||||
|
License :: OSI Approved :: BSD License
|
||||||
|
Operating System :: OS Independent
|
||||||
|
Programming Language :: Python
|
||||||
|
Programming Language :: Python :: 3
|
||||||
|
Programming Language :: Python :: 3 :: Only
|
||||||
|
Programming Language :: Python :: 3.6
|
||||||
|
Programming Language :: Python :: 3.7
|
||||||
|
Programming Language :: Python :: 3.8
|
||||||
|
Programming Language :: Python :: 3.9
|
||||||
|
Topic :: Internet :: WWW/HTTP
|
||||||
|
Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
||||||
|
|
||||||
|
[options]
|
||||||
|
include_package_data = true
|
||||||
|
packages = find:
|
||||||
|
install_requires =
|
||||||
|
django
|
Loading…
Reference in a new issue