Skip to content

Commit 3a3b386

Browse files
committed
A htpasswd import script, for the transition from basic http auth to Django native authentication.
- Legacy-Id: 7578
1 parent 5549088 commit 3a3b386

1 file changed

Lines changed: 61 additions & 0 deletions

File tree

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import sys
2+
3+
from optparse import make_option
4+
from textwrap import dedent
5+
6+
from django.conf import settings
7+
from django.contrib.auth.models import User
8+
from django.core.management.base import BaseCommand
9+
10+
class Command(BaseCommand):
11+
"""
12+
Import passwords from one or more htpasswd files to Django's auth_user table.
13+
14+
This command only imports passwords; it does not import usernames, as that
15+
would leave usernames without associated Person records in the database,
16+
something which is undesirable.
17+
18+
By default the command won't overwrite existing password entries, but
19+
given the --force switch, it will overwrite existing entries too. Without
20+
the --force switch, the command is safe to run repeatedly.
21+
"""
22+
23+
help = dedent(__doc__).strip()
24+
25+
option_list = BaseCommand.option_list + (
26+
make_option('--force',
27+
action='store_true', dest='overwrite', default=False,
28+
help='Overwrite existing passwords in the auth_user table.'),
29+
)
30+
31+
args = '[path [path [...]]]'
32+
33+
def handle(self, *filenames, **options):
34+
overwrite = options.get('overwrite', False)
35+
verbosity = int(options.get('verbosity'))
36+
for fn in filenames:
37+
with open(fn) as file:
38+
for line in file:
39+
if not ':' in line:
40+
raise ValueError('Found a line without colon separator in the htpassword file %s:'+
41+
' "%s"' % (file.name, line))
42+
username, password = line.strip().split(':', 1)
43+
try:
44+
user = User.objects.get(username=username)
45+
if overwrite == True or not user.password:
46+
if password.startswith('{SHA}'):
47+
user.password = "sha1$$%s" % password[len('{SHA}'):]
48+
elif password.startswith('$apr1$'):
49+
user.password = "md5$%s" % password[len('$apr1$'):]
50+
else: # Assume crypt
51+
user.password = "crypt$$%s" % password
52+
user.save()
53+
if verbosity > 0:
54+
sys.stderr.write('.')
55+
if verbosity > 1:
56+
sys.stderr.write(' %s\n' % username)
57+
except User.DoesNotExist:
58+
if verbosity > 1:
59+
sys.stderr.write('\nNo such user: %s\n' % username)
60+
61+

0 commit comments

Comments
 (0)