97 lines
3.4 KiB
Python
97 lines
3.4 KiB
Python
from django.conf import settings
|
|
from django.core.management.base import BaseCommand
|
|
|
|
import pyotp
|
|
import json
|
|
import urllib.request
|
|
import urllib.error
|
|
import sys
|
|
|
|
class Command(BaseCommand):
|
|
help = 'Access ungleichotp'
|
|
|
|
def add_arguments(self, parser):
|
|
parser.add_argument('--server-url', required=True)
|
|
|
|
# For creating / verifying
|
|
parser.add_argument('--name', help="Name to create/verify")
|
|
parser.add_argument('--realm', help="Realm for create/verify")
|
|
parser.add_argument('--token', help="Token for create/verify")
|
|
parser.add_argument('--seed', help="Seed for create/verify")
|
|
|
|
# How to authenticate against ungleich-otp
|
|
parser.add_argument('--auth-name', required=True, help="Name for auth")
|
|
parser.add_argument('--auth-realm', required=True, help="Realm for auth")
|
|
parser.add_argument('--auth-token', help="Token for auth")
|
|
parser.add_argument('--auth-seed', help="Seed for auth")
|
|
|
|
parser.add_argument('command', choices=['create',
|
|
'delete',
|
|
'list',
|
|
'verify'], help='Action to take')
|
|
|
|
def handle(self, *args, **options):
|
|
command_to_verb = { 'create': 'POST',
|
|
'delete': 'DELETE',
|
|
'list': 'GET' }
|
|
|
|
method = 'POST'
|
|
|
|
if not options['auth_token']:
|
|
if not options['auth_seed']:
|
|
print("Either token or seed are required")
|
|
sys.exit(1)
|
|
else:
|
|
options['auth_token'] = pyotp.TOTP(options['auth_seed']).now()
|
|
|
|
to_send = {}
|
|
|
|
# Our credentials
|
|
to_send['auth_token'] = options['auth_token']
|
|
to_send['auth_name'] = options['auth_name']
|
|
to_send['auth_realm'] = options['auth_realm']
|
|
|
|
if options['command'] in ["list", "get"]:
|
|
method = 'GET'
|
|
|
|
if options['command'] in ["create", "verify"]:
|
|
if not options['name'] or not options['realm']:
|
|
print("Need to specify --name and --realm")
|
|
sys.exit(1)
|
|
|
|
if options['command'] == "verify" and not options['token']:
|
|
if not options['seed']:
|
|
print("Need to specify --token or --seed for verify")
|
|
sys.exit(1)
|
|
else:
|
|
options['token'] = pyotp.TOTP(options['seed']).now()
|
|
|
|
|
|
# Client credentials to be verified
|
|
to_send['name'] = options['name']
|
|
to_send['realm'] = options['realm']
|
|
to_send['token'] = options['token']
|
|
|
|
if options['command'] == "verify":
|
|
options['server_url'] = "{}verify/".format(options['server_url'])
|
|
|
|
|
|
|
|
self.rest_send(options['server_url'], to_send, method=method)
|
|
|
|
@staticmethod
|
|
def rest_send(serverurl, to_send, method='POST'):
|
|
data = json.dumps(to_send).encode("utf-8")
|
|
|
|
req = urllib.request.Request(url=serverurl,
|
|
data=data,
|
|
headers={'Content-Type': 'application/json'},
|
|
method=method)
|
|
|
|
f = urllib.request.urlopen(req)
|
|
|
|
if f.status == 200:
|
|
print("Response: {}: {}".format(f.msg, f.read()))
|
|
return True
|
|
|
|
return False
|