# Path: lib/credentials_adapters.py
# class St2UserCredentials(AbstractCredentials):
#     def __init__(self, username=None, password=None):
#         self.username = username
#         self.password = password
# 
#     def __repr__(self):
#         return "".join([self.username, " : ", "".join(["*" for c in self.password])])
# 
#     def requests(self, st2_x_auth=False):
#         # TODO: FIX: Find a cleaner way for requests to produce the header.
#         headers = (
#             HTTPBasicAuth(self.username, self.password)
#             .__call__(SimpleNamespace(**{"headers": {}}))
#             .headers
#         )
#         if st2_x_auth:
#             headers["X-Authenticate"] = headers["Authorization"]
#             del headers["Authorization"]
#         return headers
# 
#     def st2client(self):
#         raise NotImplementedError
# 
# class St2UserToken(AbstractCredentials):
#     def __init__(self, token=None):
#         self.token = None
#         if token:
#             self.token = token
# 
#     def __repr__(self):
#         return self.token
# 
#     def requests(self):
#         return {"X-Auth-Token": self.token}
# 
#     def st2client(self):
#         return {"token": self.token}
# 
# class St2ApiKey(AbstractCredentials):
#     def __init__(self, apikey=None):
#         self.apikey = None
#         if apikey:
#             self.apikey = apikey
# 
#     def __repr__(self):
#         return self.apikey
# 
#     def requests(self):
#         return {"St2-Api-Key": self.apikey}
# 
#     def st2client(self):
#         return {"api_key": self.apikey}
# 
# Path: lib/authentication_controller.py
# class BotPluginIdentity(object):
#     """
#     For internal use only by err-stackstorm.  The object is used by methods that will create a
#     session and authenticate err-stackstorm credentials with StackStorm.
#     """
# 
#     def __init__(self, name="errbot%service", secret=generate_password(16)):
#         self.name = name
#         self.secret = secret
# 
#     def __repr__(self):
#         return str(self.secret)
# 
# Path: lib/errors.py
# class SessionInvalidError(Error):
#     def __init__(self, message="Session is invalid."):
#         super(SessionInvalidError, self).__init__()
#         self.message = message


import abc
import requests
import logging
from urllib.parse import urlparse, urljoin
from lib.credentials_adapters import St2UserCredentials, St2UserToken, St2ApiKey
from lib.authentication_controller import BotPluginIdentity
from lib.errors import SessionInvalidError
# coding:utf-8

LOG = logging.getLogger("errbot.plugin.st2.auth_handler")


class AbstractAuthHandlerFactory(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def instantiate(self, handler_type):
        raise NotImplementedError


class AuthHandlerFactory(AbstractAuthHandlerFactory):
    def __init__(self):
        pass

    @staticmethod
    def instantiate(handler_type):
        handler_types = {
            "serverside": ServerSideAuthHandler,
            "clientside": ClientSideAuthHandler,
            "standalone": StandaloneAuthHandler,
        }

# Path: lib/credentials_adapters.py
# class St2UserCredentials(AbstractCredentials):
#     def __init__(self, username=None, password=None):
#         self.username = username
#         self.password = password
# 
#     def __repr__(self):
#         return "".join([self.username, " : ", "".join(["*" for c in self.password])])
# 
#     def requests(self, st2_x_auth=False):
#         # TODO: FIX: Find a cleaner way for requests to produce the header.
#         headers = (
#             HTTPBasicAuth(self.username, self.password)
#             .__call__(SimpleNamespace(**{"headers": {}}))
#             .headers
#         )
#         if st2_x_auth:
#             headers["X-Authenticate"] = headers["Authorization"]
#             del headers["Authorization"]
#         return headers
# 
#     def st2client(self):
#         raise NotImplementedError
# 
# class St2UserToken(AbstractCredentials):
#     def __init__(self, token=None):
#         self.token = None
#         if token:
#             self.token = token
# 
#     def __repr__(self):
#         return self.token
# 
#     def requests(self):
#         return {"X-Auth-Token": self.token}
# 
#     def st2client(self):
#         return {"token": self.token}
# 
# class St2ApiKey(AbstractCredentials):
#     def __init__(self, apikey=None):
#         self.apikey = None
#         if apikey:
#             self.apikey = apikey
# 
#     def __repr__(self):
#         return self.apikey
# 
#     def requests(self):
#         return {"St2-Api-Key": self.apikey}
# 
#     def st2client(self):
#         return {"api_key": self.apikey}
# 
# Path: lib/authentication_controller.py
# class BotPluginIdentity(object):
#     """
#     For internal use only by err-stackstorm.  The object is used by methods that will create a
#     session and authenticate err-stackstorm credentials with StackStorm.
#     """
# 
#     def __init__(self, name="errbot%service", secret=generate_password(16)):
#         self.name = name
#         self.secret = secret
# 
#     def __repr__(self):
#         return str(self.secret)
# 
# Path: lib/errors.py
# class SessionInvalidError(Error):
#     def __init__(self, message="Session is invalid."):
#         super(SessionInvalidError, self).__init__()
#         self.message = message


# Path: lib/authentication_handler.py
import abc
import requests
import logging
from urllib.parse import urlparse, urljoin
from lib.credentials_adapters import St2UserCredentials, St2UserToken, St2ApiKey
from lib.authentication_controller import BotPluginIdentity
from lib.errors import SessionInvalidError

# coding:utf-8

LOG = logging.getLogger("errbot.plugin.st2.auth_handler")


class AbstractAuthHandlerFactory(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def instantiate(self, handler_type):
        raise NotImplementedError


class AuthHandlerFactory(AbstractAuthHandlerFactory):
    def __init__(self):
        pass

    @staticmethod
    def instantiate(handler_type):
        handler_types = {
            "serverside": ServerSideAuthHandler,
            "clientside": ClientSideAuthHandler,
            "standalone": StandaloneAuthHandler,
        }

        if handler_type not in handler_types: