Skip to content

Commit

Permalink
Initial Dashlane C++ CLI prototype based on Dashlane CLI v1.5.0
Browse files Browse the repository at this point in the history
  • Loading branch information
uniflare committed Jun 13, 2023
0 parents commit c4a398f
Show file tree
Hide file tree
Showing 3,264 changed files with 231,889 additions and 0 deletions.
The diff you're trying to view is too large. We only load the first 3000 changed files.
59 changes: 59 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
cmake_minimum_required( VERSION 3.26.0 )

project(dccli)

# Set base directories
set(OCT_BASE_DIR ${CMAKE_CURRENT_LIST_DIR})
set(OCT_CMAKE_DIR ${OCT_BASE_DIR}/tools/cmake)
set(OCT_EXT_LIBS_DIR ${OCT_BASE_DIR}/code/libs)
set(OCT_SDKS_DIR ${OCT_BASE_DIR}/code/sdks)

message(STATUS "OCT_BASE_DIR = ${OCT_BASE_DIR}")
message(STATUS "OCT_CMAKE_DIR = ${OCT_CMAKE_DIR}")
message(STATUS "OCT_EXT_LIBS_DIR = ${OCT_EXT_LIBS_DIR}")
message(STATUS "OCT_SDKS_DIR = ${OCT_SDKS_DIR}")

# Set C++ feature level
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

# Set project configurations
if(NOT SETUP_CONFIGURATIONS_DONE)
set(SETUP_CONFIGURATIONS_DONE TRUE)

get_property(isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(isMultiConfig)
set(CMAKE_CONFIGURATION_TYPES "Debug;RelWithDebug;Release" CACHE STRING "" FORCE)
else()
if(NOT CMAKE_BUILD_TYPE)
message("Defaulting to release build.")
set(CMAKE_BUILD_TYPE Release CACHE STRING "" FORCE)
endif()
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY HELPSTRING "Choose the type of build")
# set the valid options for cmake-gui drop-down list
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug;RelWithDebug;Release")
endif()
endif()

# Run toolchain file every time
if( DEFINED CMAKE_TOOLCHAIN_FILE AND EXISTS "${CMAKE_TOOLCHAIN_FILE}" )
set(CMAKE_TOOLCHAIN_FILE "${CMAKE_TOOLCHAIN_FILE}" CACHE STRING "Toolchain File." FORCE)
elseif(NOT DEFINED CMAKE_TOOLCHAIN_FILE OR NOT EXISTS ${CMAKE_TOOLCHAIN_FILE})
message(FATAL_ERROR "Cannot find cached toolchain file (${CMAKE_TOOLCHAIN_FILE}).")
else()
include(${CMAKE_TOOLCHAIN_FILE})
endif()

message(STATUS "CMAKE_TOOLCHAIN_FILE = ${CMAKE_TOOLCHAIN_FILE}")
message(STATUS "CMAKE_C_COMPILER = ${CMAKE_C_COMPILER}")
message(STATUS "CMAKE_CXX_COMPILER = ${CMAKE_CXX_COMPILER}")
message(STATUS "OCT_TARGET_PLATFORM = ${OCT_TARGET_PLATFORM}")
message(STATUS "CMAKE_SYSTEM_VERSION = ${CMAKE_SYSTEM_VERSION}")

# CMake utilities
add_subdirectory(${OCT_CMAKE_DIR})
oct_setup_output_dirs()

# Project specific build chain
include(project.cmake)
537 changes: 537 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions README
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
C++ Library & Command-Line interface prototype for the Dashlane API based on the Dashlane CLI v1.5.0.
This is a personal hobby project.

Requirements for compiling:
- Visual Studio 2022
- Application Access and Secret keys (fill the strings in _private/AccessKeys.h)

CLI Interface:
dashlane-c-cli.exe help

Dashlane API Library:
Please see the cli project for implementation/usage example

--

More documentation may come if I get enough time to dedicate to this project.

--

This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/)
4 changes: 4 additions & 0 deletions _private/AccessKeys.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#pragma once

static constexpr char szAppAccessKey[] = "";
static constexpr char szAppSecretKey[] = "";
165 changes: 165 additions & 0 deletions code/dashlane-cli/Application.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
#include "Application.h"
#include "CommandRegistry.h"
#include "Commands/Command.h"
#include "Utility/UserInput.h"

#include <strutil.h>

namespace Dashlane
{
std::string HeadlessParameters::s_email = "";
std::string HeadlessParameters::s_masterPassword = "";
std::string HeadlessParameters::s_otpCode = "";

CApplication::CApplication()
: m_app{ "Dashlane C++ CLI Interface by uniflare (Based on Dashlane's Command Line Interface project)" }
{}

CApplication::~CApplication()
{}

bool CApplication::Initialize()
{
m_app.require_subcommand();
CCommandRegistry::VisitCommands([this](const CCommand& cmd)
{
// Get the parent App pointer if this is a child command
CLI::App* pParentCommand = GetParentAppByChildName(cmd.GetName());

// Get the child command name, from the fully qualified name
std::string commandName = cmd.GetName();
if (strutil::contains(commandName, "::"))
{
auto split = strutil::split(commandName, "::");
commandName = split[split.size() - 1];
}

CLI::App* pCommand = pParentCommand->add_subcommand(commandName, cmd.GetDesc());
const CommandRegistrator& pAdditionalRegistrator = cmd.GetAdditionalRegistrator();
if (pAdditionalRegistrator)
{
pAdditionalRegistrator(pCommand);
}
return EVisitorState::Continue;
});

// Add global options
m_app.add_option_function<std::string>("--masterpass", [](const std::string& masterPassword)
{
HeadlessParameters::s_masterPassword = masterPassword;
}, "Pre-set the master password prior to invocation.");

m_app.add_option_function<std::string>("--email", [](const std::string& email)
{
HeadlessParameters::s_email = email;
}, "Pre-set the email prior to invocation.");

m_app.add_option_function<std::string>("--otp", [](const std::string& otpCode)
{
HeadlessParameters::s_otpCode = otpCode;
}, "Pre-set the OTP code prior to invocation.");

return true;
}

int CApplication::Run(int argc, char** argv)
{
// Parse command-line
std::vector<CLI::App*> subcommands;
try
{
m_app.parse(argc, argv);
subcommands = m_app.get_subcommands();
if (subcommands.size() > 1)
{
throw(CLI::ParseError("Only one command can be specified on the command-line", -1));
}
}
catch (const CLI::ParseError& e)
{
return m_app.exit(e);
}

// Traverse and execute command hierarchy
try
{
CLI::App* pSubCommand = subcommands[0];
while (pSubCommand != nullptr)
{
const CCommand* pCommand = GetCommandByName(GetFullyQualifiedCommandName(pSubCommand));
if (pCommand != nullptr)
pSubCommand = (*pCommand)(pSubCommand);
}
}
catch (const std::exception& e)
{
std::cout << "Error: " << e.what() << std::endl;
return 1;
}

return 0;
}

const CCommand* CApplication::GetCommandByName(const std::string& name) const
{
const CCommand* pCommand = nullptr;

CCommandRegistry::VisitCommands([&name, &pCommand](const CCommand& cmd)
{
if (name == cmd.GetName())
{
pCommand = &cmd;
return EVisitorState::Stop;
}
return EVisitorState::Continue;
});

return pCommand;
}

const std::string CApplication::GetFullyQualifiedCommandName(CLI::App* pCommand) const
{
std::vector<std::string> namesReversed;

CLI::App* pParent = pCommand;
while (pParent != nullptr && pParent != &m_app)
{
namesReversed.emplace_back(pParent->get_name());
pParent = pParent->get_parent();
}

std::string fullName = *namesReversed.crbegin();
for (auto it = namesReversed.crbegin()+1; it != namesReversed.crend(); it++)
{
fullName += "::";
fullName += *it;
}
return fullName;
}

CLI::App* CApplication::GetParentAppByChildName(const std::string& childName)
{
std::vector<std::string> names = strutil::split(childName, "::");

CLI::App* pParentApp = &m_app;
for (const std::string& name : names)
{
if (name == *names.crbegin())
{
break;
}

for (CLI::App* pApp : pParentApp->get_subcommands(nullptr))
{
if (pApp->get_name() == name)
{
pParentApp = pApp;
break;
}
}
}

return pParentApp;
}

}
31 changes: 31 additions & 0 deletions code/dashlane-cli/Application.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#pragma once

#include <dashlane/dashlane.h>
#include <dashlane/test/serialization.h>

#include <CLI/CLI.hpp>

namespace Dashlane
{
class CCommand;

class CApplication
{
public:
CApplication();
~CApplication();

bool Initialize();
int Run(int argc, char** argv);

protected:

const CCommand* GetCommandByName(const std::string& name) const;
const std::string GetFullyQualifiedCommandName(CLI::App* pCommand) const;
CLI::App* GetParentAppByChildName(const std::string& childName);

private:
CLI::App m_app;
};

}
71 changes: 71 additions & 0 deletions code/dashlane-cli/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
cmake_minimum_required( VERSION 3.26.0 )

if(EXISTS "${OCT_BASE_DIR}/LICENSE")
set(CONTENTS "")
file(READ "${OCT_BASE_DIR}/LICENSE" CONTENTS)
string(REGEX REPLACE "([\\\$\"])" "\\\\\\1" CONTENTS "${CONTENTS}")
string(REGEX REPLACE "[\r\n]+" "\\\\n\"\n\"" CONTENTS "${CONTENTS}")
set(CONTENTS "#pragma once\ninline const std::string g_licenseText = \"${CONTENTS}\"\;")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/generated/License-Gen.h" ${CONTENTS})
set(GENERATED_LICENSE_HEADER "${CMAKE_CURRENT_BINARY_DIR}/generated/License-Gen.h")
else()
endif()

oct_define_sources(
PLATFORM ALL

"CMakeLists.txt"

GROUP "Header Files"
"Application.h"
"CommandRegistry.h"
"CoreConfig.h"

GROUP "Source Files"
"Application.cpp"
"CommandRegistry.cpp"
"main.cpp"

GROUP "Commands"
"Commands/Command.h"
"Commands/Common.h"
"Commands/Configure.cpp"
"Commands/License.cpp"
"Commands/Password.cpp"
"Commands/Reset.cpp"
"Commands/ResetAll.cpp"
"Commands/Sync.cpp"

GROUP "Utility"
"Utility/DashlaneContext.h"
"Utility/UserInput.h"

GROUP "Generated"
${GENERATED_LICENSE_HEADER}
)

oct_project(dashlane-cli TYPE EXECUTABLE FOLDER "Dashlane")

target_include_directories(${THIS_PROJECT}
PUBLIC ${CMAKE_CURRENT_LIST_DIR}
PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/generated
PRIVATE ${OCT_SDKS_DIR}/CLI11/_src/include
PRIVATE ${OCT_SDKS_DIR}/strutil/_src
PRIVATE ${OCT_SDKS_DIR}/json/_src/include
)

target_link_libraries(${THIS_PROJECT}
dashlane-lib
clip
)

set_directory_properties(PROPERTIES CMAKE_CONFIGURE_DEPENDS "${OCT_BASE_DIR}/_private/AccessKeys.h")
if(EXISTS "${OCT_BASE_DIR}/_private/AccessKeys.h")
target_compile_definitions(${THIS_PROJECT} PRIVATE DCCLI_ACCESS_KEYS)
target_include_directories(${THIS_PROJECT}
PUBLIC "${OCT_BASE_DIR}/_private"
)
endif()

set_property(DIRECTORY ${OCT_BASE_DIR} PROPERTY VS_STARTUP_PROJECT ${THIS_PROJECT})
32 changes: 32 additions & 0 deletions code/dashlane-cli/CommandRegistry.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include "CommandRegistry.h"
#include <Commands/Command.h>

namespace Dashlane
{

std::vector<CCommand> CCommandRegistry::s_registry = {};

void CCommandRegistry::Register(CCommand&& cmd)
{
s_registry.emplace_back(std::move(cmd));
}

void CCommandRegistry::VisitCommands(std::function<EVisitorState(const CCommand&)> visitor)
{
for (auto& command : s_registry)
{
const EVisitorState state = visitor(command);
if (state == EVisitorState::Stop)
break;
}
}

CSubRegistrator COMMAND(const std::string& name, std::string&& desc, CLICommand&& cmd, CommandRegistrator additionalRegistrator)
{
CCommandRegistry::Register(
CCommand(name, std::move(desc), std::move(cmd), std::move(additionalRegistrator))
);
return CSubRegistrator(name);
}

}

0 comments on commit c4a398f

Please sign in to comment.