# -*- coding: utf-8 -*-

# Copyright 2020 TATA ELXSI
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
# For those usages not covered by the Apache License, Version 2.0 please
# contact: saikiran.k@tataelxsi.co.in
##


""" 
AuthconnTacacs implements implements the connector for TACACS.
Leverages AuthconnInternal for token lifecycle management and the RBAC model.

When NBI bootstraps, it tries to create admin user with admin role associated to admin project.
Hence, the TACACS server should contain admin user.
""" 

__author__ = "K Sai Kiran <saikiran.k@tataelxsi.co.in>"
__date__ = "$11-Nov-2020 11:04:00$"


from osm_nbi.authconn import Authconn, AuthException  
from osm_nbi.authconn_internal import AuthconnInternal
from osm_nbi.base_topic import BaseTopic

import logging
from time import time
from http import HTTPStatus

# TACACS+ Library
from tacacs_plus.client import TACACSClient


class AuthconnTacacs(AuthconnInternal):
    token_time_window = 2
    token_delay = 1

    tacacs_def_port = 49
    tacacs_def_timeout = 10
    users_collection = "users_tacacs"
    roles_collection = "roles_tacacs"
    projects_collection = "projects_tacacs"
    tokens_collection = "tokens_tacacs"

    def __init__(self, config, db, role_permissions):
        """
        Constructor to initialize db and TACACS server attributes to members.
        """
        Authconn.__init__(self, config, db, role_permissions)
        self.logger = logging.getLogger("nbi.authenticator.tacacs")
        self.db = db
        self.tacacs_host = config["tacacs_host"]
        self.tacacs_secret = config["tacacs_secret"]
        self.tacacs_port = config["tacacs_port"] if config.get("tacacs_port") else self.tacacs_def_port
        self.tacacs_timeout = config["tacacs_timeout"] if config.get("tacacs_timeout") else self.tacacs_def_timeout
        self.tacacs_cli = TACACSClient(self.tacacs_host, self.tacacs_port, self.tacacs_secret,
                                       self.tacacs_timeout)

    def validate_user(self, user, password):
        """
        """
        now = time()
        try:
            tacacs_authen = self.tacacs_cli.authenticate(user, password)
        except Exception as e:
            raise AuthException("TACACS server error: {}".format(e), http_code=HTTPStatus.UNAUTHORIZED)
        user_content = None
        user_rows = self.db.get_list(self.users_collection, {BaseTopic.id_field("users", user): user})
        if not tacacs_authen.valid:
            if user_rows:
                # To remove TACACS stale user from system.
                self.delete_user(user_rows[0][BaseTopic.id_field("users", user)])
            return user_content
        if user_rows:
            user_content = user_rows[0]
        else:
            new_user = {'username': user,
                        'password': password,
                        '_admin': {
                            'created': now,
                            'modified': now
                        },
                        'project_role_mappings': []
                        }
            user_content = self.create_user(new_user)
        return user_content

    def create_user(self, user_info):
        """
        Validates user credentials in TACACS and add user.

        :param user_info: Full user information in dict.
        :return: returns username and id if credentails are valid. Otherwise, raise exception
        """
        BaseTopic.format_on_new(user_info, make_public=False)
        try:
            authen = self.tacacs_cli.authenticate(user_info["username"], user_info["password"])
            if authen.valid:
                user_info.pop("password")
                self.db.create(self.users_collection, user_info)
            else:
                raise AuthException("TACACS server error: Invalid credentials", http_code=HTTPStatus.FORBIDDEN)
        except Exception as e:
            raise AuthException("TACACS server error: {}".format(e), http_code=HTTPStatus.BAD_REQUEST)
        return {"username": user_info["username"], "_id": user_info["_id"]}

    def update_user(self, user_info):
        """
        Updates user information, in particular for add/remove of project and role mappings.
        Does not allow change of username or password.

        :param user_info: Full user information in dict.
        :return: returns None for successful add/remove of project and role map.
        """
        if(user_info.get("username")):
            raise AuthException("Can not update username of this user", http_code=HTTPStatus.FORBIDDEN)
        if(user_info.get("password")):
            raise AuthException("Can not update password of this user", http_code=HTTPStatus.FORBIDDEN)
        super(AuthconnTacacs, self).update_user(user_info)
