<commit_before>/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
 *     Copyright 2016 Couchbase, Inc.
 *
 *   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.
 */
#include "pwconv.h"
#include "user.h"

#include <fstream>
#include <iterator>
#include <platform/memorymap.h>
#include <sstream>

void cbsasl_pwconv(std::istream& is, std::ostream& os) {
    unique_cJSON_ptr root(cJSON_CreateObject());
    if (root.get() == nullptr) {
        throw std::bad_alloc();
    }
    auto* users = cJSON_CreateArray();
    if (users == nullptr) {
        throw std::bad_alloc();
    }
    cJSON_AddItemToObject(root.get(), "users", users);

    /* File has lines that are newline terminated.
     * File may have comment lines that must being with '#'.
     * Lines should look like...
     *   <NAME><whitespace><PASSWORD><whitespace><CONFIG><optional_whitespace>
     */
    std::vector<char> up(1024);

    while (is.getline(up.data(), up.size()).good()) {
        using std::istream_iterator;
        using std::vector;

        std::istringstream iss(up.data());
        vector<std::string> tokens{istream_iterator<std::string>{iss},
                                   istream_iterator<std::string>{}};

        if (tokens.empty()) {
            // empty line
            continue;
        }
        std::string passwd;
        if (tokens.size() > 1) {
            passwd = <PASSWORD>[1];
        }

        Couchbase::User u(Couchbase::User(tokens[0], passwd));
        cJSON_AddItemToArray(users, u.to_json().release());
    }

    os << to_string(root, true) << std::endl;
}

void cbsasl_pwconv(const std::string& ifile, const std::string& ofile) {
    std::stringstream inputstream(cbsasl_read_password_file(ifile));
    std::stringstream outputstream;

    cbsasl_pwconv(inputstream, outputstream);

    cbsasl_write_password_file(ofile, outputstream.str());
}

std::string cbsasl_read_password_file(const std::string& filename) {
    Couchbase::MemoryMappedFile map(filename.c_str(), false, true);
    map.open();
    std::string ret(reinterpret_cast<char*>(map.getRoot()),
                    map.getSize());
    map.close();

    // The password file may be encrypted
    auto* env = getenv("COUCHBASE_CBSASL_SECRETS");
    if (env == nullptr) {
        return ret;
    } else {
        using namespace Couchbase;

        unique_cJSON_ptr json(cJSON_Parse(env));
        if (json.get() == nullptr) {
            throw std::runtime_error("cbsasl_read_password_file: Invalid json"
                                         " specified in COUCHBASE_CBSASL_SECRETS");
        }

        auto decoded = Crypto::decrypt(json.get(),
                                       reinterpret_cast<const uint8_t*>(ret.data()),
                                       ret.size());

        return std::string{(const char*)decoded.data(), decoded.size()};<commit_msg>Couchbase::MemoryMappedFile is moved to cb::<commit_after>/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
 *     Copyright 2016 Couchbase, Inc.
 *
 *   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.
 */
#include "pwconv.h"
#include "user.h"

#include <fstream>
#include <iterator>
#include <platform/memorymap.h>
#include <sstream>

void cbsasl_pwconv(std::istream& is, std::ostream& os) {
    unique_cJSON_ptr root(cJSON_CreateObject());
    if (root.get() == nullptr) {
        throw std::bad_alloc();
    }
    auto* users = cJSON_CreateArray();
    if (users == nullptr) {
        throw std::bad_alloc();
    }
    cJSON_AddItemToObject(root.get(), "users", users);

    /* File has lines that are newline terminated.
     * File may have comment lines that must being with '#'.
     * Lines should look like...
     *   <NAME><whitespace><PASSWORD><whitespace><CONFIG><optional_whitespace>
     */
    std::vector<char> up(1024);

    while (is.getline(up.data(), up.size()).good()) {
        using std::istream_iterator;
        using std::vector;

        std::istringstream iss(up.data());
        vector<std::string> tokens{istream_iterator<std::string>{iss},
                                   istream_iterator<std::string>{}};

        if (tokens.empty()) {
            // empty line
            continue;
        }
        std::string passwd;
        if (tokens.size() > 1) {
            passwd = tokens[1];
        }

        Couchbase::User u(Couchbase::User(tokens[0], passwd));
        cJSON_AddItemToArray(users, u.to_json().release());
    }

    os << to_string(root, true) << std::endl;
}

void cbsasl_pwconv(const std::string& ifile, const std::string& ofile) {
    std::stringstream inputstream(cbsasl_read_password_file(ifile));
    std::stringstream outputstream;

    cbsasl_pwconv(inputstream, outputstream);

    cbsasl_write_password_file(ofile, outputstream.str());
}

std::string cbsasl_read_password_file(const std::string& filename) {
    cb::MemoryMappedFile map(filename.c_str(), false, true);
    map.open();
    std::string ret(reinterpret_cast<char*>(map.getRoot()),
                    map.getSize());
    map.close();

    // The password file may be encrypted
    auto* env = getenv("COUCHBASE_CBSASL_SECRETS");
    if (env == nullptr) {
        return ret;
    } else {
        using namespace Couchbase;

        unique_cJSON_ptr json(cJSON_Parse(env));
        if (json.get() == nullptr) {
            throw std::runtime_error("cbsasl_read_password_file: Invalid json"
                                         " specified in COUCHBASE_CBSASL_SECRETS");
        }

        auto decoded = Crypto::decrypt(json.get(),
                                       reinterpret_cast<const uint8_t*>(ret.data()),
                                       ret.size());

        return std::string{(const char*)decoded.data(), decoded.size()};
{'fraction_non_alphanumeric': 0.13093145869947276, 'fraction_numerical': 0.005272407732864675, 'mean_word_length': 2.673480365788058, 'pattern_counts': {'":': 0, '<': 44, '<?xml version=': 0, '>': 38, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2682802', 'n_tokens_mistral': 2095, 'n_tokens_neox': 2030, 'n_words': 503}