#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# vim:fenc=utf-8

# This file is part of the  X2Go Project - https://www.x2go.org
# Copyright (C) 2012-2019 by Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
#
# X2Go Session Broker is free software; you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# X2Go Session Broker is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.

import os
import sys
import setproctitle
import argparse
import logging
import getpass

# perform an authentication against the authentication mechanism configured for WSGI
try:
    import x2gobroker.defaults
except ImportError:
    sys.path.insert(0, os.path.join(os.getcwd(), '..'))
    import x2gobroker.defaults
import x2gobroker.loggers

PROG_NAME = os.path.basename(sys.argv[0])
PROG_OPTIONS = sys.argv[1:]
try:
    _password_index = PROG_OPTIONS.index('--password')+1
    PROG_OPTIONS[_password_index] = "XXXXXXXX"
except ValueError:
    # ignore if --password option is not specified
    pass
setproctitle.setproctitle("%s %s" % (PROG_NAME, " ".join(PROG_OPTIONS)))

if __name__ == "__main__":

    auth_options = [
        {'args':['-u','--username', '--user'], 'default': None, 'metavar': 'USERNAME', 'help': 'Test authentication for the account with this username', },
        {'args':['-p', '--password'], 'default': None, 'metavar': 'PASSWORD', 'help': 'Test authentication using this password (Not recommended!!! Please prefer using the provided password prompt instead)', },
    ]
    misc_options = [
        {'args':['-C','--config-file'], 'default': None, 'metavar': 'CONFIG_FILE', 'help': 'Specify a special configuration file name, default is: {default}'.format(default=x2gobroker.defaults.X2GOBROKER_CONFIG), },
        {'args':['-b','--backend'], 'default': x2gobroker.defaults.X2GOBROKER_DEFAULT_BACKEND, 'metavar': 'BACKEND', 'help': 'Use this specific backend for testing authentication, see x2gobroker.conf for a list of configured and enabled backends, default is: {default_backend}'.format(default_backend=x2gobroker.defaults.X2GOBROKER_DEFAULT_BACKEND), },
        {'args':['-d','--debug'], 'default': False, 'action': 'store_true', 'help': 'enable debugging code', },
    ]
    p = argparse.ArgumentParser(description='X2Go Session Broker (Authentication Test Utility)',\
                                formatter_class=argparse.RawDescriptionHelpFormatter, \
                                add_help=True, argument_default=None)
    p_auth = p.add_argument_group('authentication parameters')
    p_misc = p.add_argument_group('miscellaneous parameters')

    for (p_group, opts) in ( (p_auth, auth_options), (p_misc, misc_options), ):
        for opt in opts:
            args = opt['args']
            del opt['args']
            p_group.add_argument(*args, **opt)

    cmdline_args = p.parse_args()

    if cmdline_args.username is None:
        p.print_help()
        print()
        print("*** Cannot continue without username... ***")
        print()
        sys.exit(-1)

    if cmdline_args.config_file is not None:
        x2gobroker.defaults.X2GOBROKER_CONFIG = cmdline_args.config_file

    if cmdline_args.debug:
        x2gobroker.defaults.X2GOBROKER_DEBUG = cmdline_args.debug
        # raise log level to DEBUG if requested...
        if x2gobroker.defaults.X2GOBROKER_DEBUG and not x2gobroker.defaults.X2GOBROKER_TESTSUITE:
            x2gobroker.loggers.logger_broker.setLevel(logging.DEBUG)
            x2gobroker.loggers.logger_error.setLevel(logging.DEBUG)

    username = cmdline_args.username
    password = cmdline_args.password

config_file = x2gobroker.defaults.X2GOBROKER_CONFIG
config_defaults = x2gobroker.defaults.X2GOBROKER_CONFIG_DEFAULTS

try:
    namespace = {}
    exec("import x2gobroker.brokers.{backend}_broker as _backend".format(backend=cmdline_args.backend), namespace)
    _backend = namespace['_backend']
except ImportError:
        p.print_help()
        print()
        print("*** No such backend: {backend} ***".format(backend=cmdline_args.backend))
        print()
        sys.exit(-2)

broker = _backend.X2GoBroker(config_file=config_file, config_defaults=config_defaults)
if not broker.is_enabled():
        p.print_help()
        print()
        print("*** Backend not enabled: {backend} ***".format(backend=cmdline_args.backend))
        print()
        sys.exit(-3)

def check_password(username, password):
    return broker._do_authenticate(username=username, password=password)

if __name__ == "__main__":

    if password is None:
        password = getpass.getpass()

    if check_password(username, password):
        print("Authentication succeeded.")
        sys.exit(0)
    else:
        print("Authentication failed!")
        sys.exit(-1)
