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