ungleich-otp/otpauth/management/commands/ungleichotpclient.py

98 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