Skip to content

Commit

Permalink
Keyring Module (#2)
Browse files Browse the repository at this point in the history
* Keyring - Start Store and Keyring

* Keyring - Implement Store

* All - Cleanup

* Keyring - Make Store Thread Safe

* Revert "All - Cleanup"

This reverts commit 7f4292b.

* Keyring - Keyring Implementation

* Keyring - Better SystemCredentials API

* Keyring - Fix Linux Build

* Keyring - Blank KeyringDialogController + Enum Flag Macros

* Update appinfo.cpp

* All - Cleanup

* All - Don't Use Optional Everywhere + Ensure Thread Safety

* Keyring - Better Store and Keyring Handling

* Keyring - Store Overload =

* All - Add gtest

* Keyring - Implement KeyringDialogController

* Update .gitattributes

* Update .gitattributes
  • Loading branch information
nlogozzo authored Dec 5, 2023
1 parent 0da55c8 commit 3e3f76d
Show file tree
Hide file tree
Showing 28 changed files with 1,011 additions and 99 deletions.
9 changes: 8 additions & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
@@ -1,2 +1,9 @@
# Auto detect text files and perform LF normalization
* text=auto
* text eol=lf
*.c eol=crlf
*.json eol=crlf
*.png binary
*.jpg binary
*.ico binary
*.pdf binary
*.exe binary
6 changes: 4 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(SQLITE_HAS_CODEC ON)

if (POLICY CMP0141)
cmake_policy(SET CMP0141 NEW)
Expand All @@ -21,7 +22,10 @@ add_library (${PROJECT_NAME} SHARED
src/helpers/stringhelpers.cpp
src/helpers/webhelpers.cpp
src/keyring/credential.cpp
src/keyring/keyring.cpp
src/keyring/keyringdialogcontroller.cpp
src/keyring/passwordgenerator.cpp
src/keyring/store.cpp
src/keyring/systemcredentials.cpp
src/update/updater.cpp
src/appinfo.cpp
Expand All @@ -44,8 +48,6 @@ find_package(CURL REQUIRED)
target_link_libraries(${PROJECT_NAME} PUBLIC CURL::libcurl)
find_package(maddy REQUIRED)
target_link_libraries(${PROJECT_NAME} PUBLIC maddy::maddy)
find_package(sqlcipher REQUIRED)
target_link_libraries(${PROJECT_NAME} PUBLIC sqlcipher::sqlcipher)
find_package(SQLiteCpp REQUIRED)
target_link_libraries(${PROJECT_NAME} PUBLIC SQLiteCpp)
if(LINUX)
Expand Down
1 change: 1 addition & 0 deletions conanfile-linux.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ maddy/1.3.0
sqlcipher/4.5.1
sqlitecpp/3.3.1
libsecret/0.20.5
gtest/1.14.0

[generators]
CMakeDeps
Expand Down
1 change: 1 addition & 0 deletions conanfile-windows.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ libcurl/8.4.0
maddy/1.3.0
sqlcipher/4.5.1
sqlitecpp/3.3.1
gtest/1.14.0

[generators]
CMakeDeps
Expand Down
4 changes: 2 additions & 2 deletions include/aura.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#define AURA_H

#include <map>
#include <optional>
#include <memory>
#include <string>
#include "appinfo.h"
#include "configurationbase.h"
Expand Down Expand Up @@ -61,7 +61,7 @@ namespace Nickvision::Aura
static Aura& getActive();

private:
static std::optional<Aura> m_instance;
static std::unique_ptr<Aura> m_instance;
};
}

Expand Down
5 changes: 2 additions & 3 deletions include/dependencylocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,16 @@
#define DEPENDENCYLOCATOR_H

#include <filesystem>
#include <optional>
#include <string>

namespace Nickvision::Aura::DependencyLocator
{
/**
* @brief Finds the path of a given dependency.
* @param dependency The name of the dependency to find
* @return The path of the dependency if found, else std::nullopt
* @return The path of the dependency if found, else empty path
*/
const std::optional<std::filesystem::path>& find(std::string dependency);
const std::filesystem::path& find(std::string dependency);
}

#endif //DEPENDENCYLOCATOR_H
34 changes: 34 additions & 0 deletions include/enumflags.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#ifndef ENUMFLAGS_H
#define ENUMFLAGS_H

#define DEFINE_ENUM_FLAG_OPERATORS(T) \
inline T operator~(T a) \
{ \
return (T)~(int)a; \
} \
inline T operator|(T a, T b) \
{ \
return (T)((int)a | (int)b); \
} \
inline T operator&(T a, T b) \
{ \
return (T)((int)a & (int)b); \
} \
inline T operator^(T a, T b) \
{ \
return (T)((int)a ^ (int)b); \
} \
inline T& operator|=(T& a, T b) \
{ \
return (T&)((int&)a |= (int)b); \
} \
inline T& operator&=(T& a, T b) \
{ \
return (T&)((int&)a &= (int)b); \
} \
inline T& operator^=(T& a, T b) \
{ \
return (T&)((int&)a ^= (int)b); \
} \

#endif //ENUMFLAGS_H
6 changes: 5 additions & 1 deletion include/events/event.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ namespace Nickvision::Aura::Events
/**
* @brief Constructs an Event via move.
*/
Event(Event&& e)
Event(Event&& e) noexcept
{
std::lock_guard<std::mutex> lock{ e.m_mutex };
m_handlers = std::move(e.m_handlers);
Expand Down Expand Up @@ -96,6 +96,8 @@ namespace Nickvision::Aura::Events
}
/**
* @brief Copies an Event
* @param e The Event to copy
* @return this
*/
Event& operator=(const Event& e)
{
Expand All @@ -109,6 +111,8 @@ namespace Nickvision::Aura::Events
}
/**
* @brief Moves an Event
* @param e The Event to move
* @return this
*/
Event& operator=(Event&& e)
{
Expand Down
6 changes: 6 additions & 0 deletions include/helpers/stringhelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ namespace Nickvision::Aura::StringHelpers
* @return The guid value
*/
std::string newGuid();
/**
* @brief Gets whether or not the provided string is a valid url
* @param s The string to check
* @return True if the string is a valid url, else false
*/
bool isValidUrl(const std::string& s);

}

Expand Down
22 changes: 22 additions & 0 deletions include/keyring/credentialcheckstatus.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#ifndef CREDENTIALCHECKSTATUS_H
#define CREDENTIALCHECKSTATUS_H

#include "enumflags.h"

namespace Nickvision::Aura::Keyring
{
/**
* @brief Flags to describe the status of a validated credential
*/
enum class CredentialCheckStatus
{
Valid = 1,
EmptyName = 2,
EmptyUsernamePassword = 4,
InvalidUri = 8
};

DEFINE_ENUM_FLAG_OPERATORS(CredentialCheckStatus);
}

#endif //CREDENTIALCHECKSTATUS_H
94 changes: 94 additions & 0 deletions include/keyring/keyring.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#ifndef KEYRING_H
#define KEYRING_H

#include <optional>
#include <string>
#include <vector>
#include "credential.h"
#include "store.h"

namespace Nickvision::Aura::Keyring
{
/**
* @brief A model of a keyring object for managing credentials.
*/
class Keyring
{
public:
/**
* @brief Gets the name of the keyring.
* @return The name of the keyring
*/
const std::string& getName() const;
/**
* @brief Gets all credentials in the keyring.
* @return The list of all credentials
*/
std::vector<Credential> getAllCredentials() const;
/**
* @brief Gets the credential matching the provided id.
* @param id The id of the credential
* @return The credential matching the id, std::nullopt if no matching credential
*/
std::optional<Credential> getCredential(int id) const;
/**
* @brief Gets the credentials containing the provided name.
* @param name The name
* @return The list of credentials matching the name
*/
std::vector<Credential> getCredentials(const std::string& name) const;
/**
* @brief Adds a credential to the keyring.
* @param credential The Credential to add
* @return True if successful, else false
*/
bool addCredential(const Credential& credential);
/**
* @brief Updates a credential in the keyring.
* @param credential The Credential to update
* @return True if successful, else false
*/
bool updateCredential(const Credential& credential);
/**
* @brief Deletes a credential from the keyring.
* @param id The id of the credential to delete
* @return True if successful, else false
*/
bool deleteCredential(int id);
/**
* @brief Destroys the keyring and all of its data from disk. Once this method is called, the object should no longer be referenced, with or without success.
* @return True if successful, else false
*/
bool destroy();

private:
Keyring(const Store& store);
Store m_store;

public:
/**
* @brief Accesses a Keyring. The Keyring will first attempt to load the Store. If the Store doesn't exist, it will create a new Store.
* @param name The name of the store
* @param password The password to use for the store. If empty, the password will be fetched/created from the system's credential store
* @return The newly accessed keyring, std::nullopt if accessing failed
*/
static std::optional<Keyring> access(const std::string& name, std::string password = "");
/**
* @brief Gets whether or not a keyring exists with the provided name.
* @param name The name of the keyring to check
* @return True if a keyring with the provied name exists, else false
*/
static bool exists(const std::string& name);
/**
* @brief Destroys a keyring and all of its data from disk.
* @param The name of the keyring to destroy
* @return True if successful, else false
*/
static bool destroy(const std::string& name);

private:

};
}

#endif //KEYRING_H
89 changes: 89 additions & 0 deletions include/keyring/keyringdialogcontroller.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#ifndef KEYRINGDIALOGCONTROLLER_H
#define KEYRINGDIALOGCONTROLLER_H

#include <optional>
#include <string>
#include <vector>
#include "credential.h"
#include "credentialcheckstatus.h"
#include "keyring.h"

namespace Nickvision::Aura::Keyring
{
class KeyringDialogController
{
public:
/**
* @brief Constructs a KeyringDialogController.
* @param name The name of the controller
* @param keyring The keyring managed by the controller, if available
*/
KeyringDialogController(const std::string& name, const std::optional<Keyring>& keyring);
/**
* @brief Gets the keyring managed by the controller, if available.
* @return The keyring if available, else std::nullopt
*/
const std::optional<Keyring>& getKeyring();
/**
* @brief Gets whether or not the keyring is enabled (unlocked).
* @retrun True if enabled, else false
*/
bool isEnabled() const;
/**
* @brief Gets whether or not the keyring state is valid.
* @return True if valid, else false
*/
bool isValid() const;
/**
* @brief Enables the keyring.
* @param password The password of the keyring
* @return True if successful, else false
*/
bool enableKeyring(const std::string& password = "");
/**
* @brief Disables the keyring and destroys its data.
* @return True if successful, else false
*/
bool disableKeyring();
/**
* @brief Resets the keyring and destroys its data. To be used only if the keyring is locked. If unlocked, use disableKeyring() .
* @return True if successful, else false
*/
bool resetKeyring();
/**
* @brief Validates a Credential object.
* @param credential The credential to validate
* @return CredentialCheckStatus
*/
CredentialCheckStatus validateCredential(const Credential& credential) const;
/**
* @brief Gets all credentials in the keyring.
* @return The list of all credentials
*/
std::vector<Credential> getAllCredentials() const;
/**
* @brief Adds a credential to the keyring.
* @param credential The Credential to add
* @return True if successful, else false
*/
bool addCredential(const Credential& credential);
/**
* @brief Updates a credential in the keyring.
* @param credential The Credential to update
* @return True if successful, else false
*/
bool updateCredential(const Credential& credential);
/**
* @brief Deletes a credential from the keyring.
* @param id The id of the credential to delete
* @return True if successful, else false
*/
bool deleteCredential(int id);

private:
std::string m_name;
std::optional<Keyring> m_keyring;
};
}

#endif //KEYRINGDIALOGCONTROLLER_H
Loading

0 comments on commit 3e3f76d

Please sign in to comment.