<commit_before># Copyright 2016 The Johns Hopkins University Applied Physics Laboratory
#
# 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.

"""Library for common methods that are used by the different configs scripts."""

import sys
import os
import json
import pprint
import time
import getpass
import string
import subprocess
import shlex
import traceback
from urllib.request import Request, urlopen
from urllib.parse import urlencode
from urllib.error import HTTPError


import hosts

# Add a reference to boss-manage/vault/ so that we can import those files
cur_dir = os.path.dirname(os.path.realpath(__file__))
vault_dir = os.path.normpath(os.path.join(cur_dir, "..", "vault"))
sys.path.append(vault_dir)
import bastion
import vault


def get_commit():
    try:
        cmd = "git rev-parse HEAD"
        result = subprocess.run(shlex.split(cmd), stdout=subprocess.PIPE)
        return result.stdout.decode("utf-8").strip()
    except:
        return "unknown"


def domain_to_stackname(domain):
    """Create a CloudFormation Stackname from domain name by removing '.' and
    capitalizing each part of the domain.
    """
    return "".join(map(lambda x: x.capitalize(), domain.split(".")))


def template_argument(key, value, use_previous=False):
    """Create a JSON dictionary formated as a CloudFlormation template
    argument.

    use_previous is passed as UserPreviousValue to CloudFlormation.
    """
    return {"ParameterKey": key, "ParameterValue": value, "UsePreviousValue": use_previous}


def keypair_to_file(keypair):
    """Look for a ssh key named <keypair> and alert if it does not exist."""
    file = os.path.expanduser("~/.ssh/{}.pem".format(keypair))
    if not os.path.exists(file):
        print("Error: SSH Key '{}' does not exist".format(file))
        return None
    return file


def password(what):
    """Prompt the user for a password and verify it."""
    while True:
        pass_ = getpass.getpass("{} Password: ".format(what))
        pass__ = getpass.getpass("Verify {} Password: ".format(what))
        if pass_ == pass__:
            return pass_
        else:
            print("Passwords didn't match, try again.")


def generate_password(length=16):
    """
    Generate an alphanumeric password of the given length.
    Args:
        length: length of the password to be generated

    Returns:
        password
    """
    chars = string.ascii_letters + string.digits  #+ string.punctuation
    return "".join([chars[c % len(chars)] for c in os.urandom(length)])


class KeyCloakClient:
    def __init__(self, url_base):
        self.url_base = url_base
        self.token = None

    def request(self, url, params=None, headers={}, convert=urlencode, method=None):
        request = Request(
            self.url_base + url,
            data=None if params is None else convert(params).encode("utf-8"),
            headers=headers,
            method=method
        )

        try:
            response = urlopen(request).read().decode("utf-8")
            if len(response) > 0:
                response = json.loads(response)
            return response
        except HTTPError as e:
            print("Error on '{}'".format(url))
            print(e)
            return None

    def login(self, username, password):
        self.token = self.request(
            "/auth/realms/master/protocol/openid-connect/token",
            params={
                "username": username,
                "password": password,
                "grant_type": "password",
                "client_id": "admin-cli",
            },
            headers={
                "Content-Type": "application/x-www-form-urlencoded",
            }
        )

        if self.token is None:
            print("Could not authenticate to KeyCloak Server")

    def logout(self):
        if self.token is None:
            return

        self.request(  # no response
            "/auth/realms/master/protocol/openid-connect/logout",<commit_msg>Updated KeyCloakClient to beable to disable ssl checking<commit_after># Copyright 2016 The Johns Hopkins University Applied Physics Laboratory
#
# 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.

"""Library for common methods that are used by the different configs scripts."""

import sys
import os
import json
import pprint
import time
import getpass
import string
import subprocess
import shlex
import traceback
import ssl
from urllib.request import Request, urlopen
from urllib.parse import urlencode
from urllib.error import HTTPError


import hosts

# Add a reference to boss-manage/vault/ so that we can import those files
cur_dir = os.path.dirname(os.path.realpath(__file__))
vault_dir = os.path.normpath(os.path.join(cur_dir, "..", "vault"))
sys.path.append(vault_dir)
import bastion
import vault


def get_commit():
    try:
        cmd = "git rev-parse HEAD"
        result = subprocess.run(shlex.split(cmd), stdout=subprocess.PIPE)
        return result.stdout.decode("utf-8").strip()
    except:
        return "unknown"


def domain_to_stackname(domain):
    """Create a CloudFormation Stackname from domain name by removing '.' and
    capitalizing each part of the domain.
    """
    return "".join(map(lambda x: x.capitalize(), domain.split(".")))


def template_argument(key, value, use_previous=False):
    """Create a JSON dictionary formated as a CloudFlormation template
    argument.

    use_previous is passed as UserPreviousValue to CloudFlormation.
    """
    return {"ParameterKey": key, "ParameterValue": value, "UsePreviousValue": use_previous}


def keypair_to_file(keypair):
    """Look for a ssh key named <keypair> and alert if it does not exist."""
    file = os.path.expanduser("~/.ssh/{}.pem".format(keypair))
    if not os.path.exists(file):
        print("Error: SSH Key '{}' does not exist".format(file))
        return None
    return file


def password(what):
    """Prompt the user for a password and verify it."""
    while True:
        pass_ = getpass.getpass("{} Password: ".format(what))
        pass__ = getpass.getpass("Verify {} Password: ".format(what))
        if pass_ == pass__:
            return pass_
        else:
            print("Passwords didn't match, try again.")


def generate_password(length=16):
    """
    Generate an alphanumeric password of the given length.
    Args:
        length: length of the password to be generated

    Returns:
        password
    """
    chars = string.ascii_letters + string.digits  #+ string.punctuation
    return "".join([chars[c % len(chars)] for c in os.urandom(length)])


class KeyCloakClient:
    def __init__(self, url_base, verify_ssl=True):
        self.url_base = url_base
        self.token = None

        if url.startswith("https") and not verify_ssl:
            self.ctx = ssl.create_default_context()
            self.ctx.check_hostname = False
            self.ctx.verify_mode = ssl.CERT_NONE
        else:
            self.ctx = None

    def request(self, url, params=None, headers={}, convert=urlencode, method=None):
        request = Request(
            self.url_base + url,
            data=None if params is None else convert(params).encode("utf-8"),
            headers=headers,
            method=method
        )

        try:
            response = urlopen(request, context=self.ctx).read().decode("utf-8")
            if len(response) > 0:
                response = json.loads(response)
            return response
        except HTTPError as e:
            print("Error on '{}'".format(url))
            print(e)
            return None

    def login(self, username, password):
        self.token = self.request(
            "/auth/realms/master/protocol/openid-connect/token",
            params={
                "username": username,
                "password": password,
                "grant_type": "password",
                "client_id": "admin-cli",
            },
            headers={
                "Content-Type": "application/x-www-form-urlencoded",
            }
        )

        if self.token is None:
            print("Could not authenticate to KeyCloak Server")

    def logout(self):
        if self.token is None:
            return

        self.request(  # no response
            "/auth/realms/master/protocol/openid-connect/logout",
{'fraction_non_alphanumeric': 0.10265830992003458, 'fraction_numerical': 0.0030257186081694403, 'mean_word_length': 2.6336866902237928, 'pattern_counts': {'":': 16, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7360151', 'n_tokens_mistral': 2642, 'n_tokens_neox': 2549, 'n_words': 838}