-
-
Notifications
You must be signed in to change notification settings - Fork 67
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
auth: add an interface for different authentication methods (#578)
* auth: add an interface for different authentication methods * auth: pick inline feedback based on last active implementation * config: move auth options to auth:<auth_impl> BREAKING: - general:pam_module -> auth:pam:module - general:enable_fingerprint -> auth:fingerprint:enabled - general:fingerprint_ready_message -> auth:fingerprint:ready_message - general:fingerprint_present_message -> auth:fingerprint:present_message * auth: don't clear password input for fingerprint auth check * fingerprint: checkAuthenticated when handling verfiy status * Revert conditionally clearing the password input buffer Makes sure the input field can show the fail text for fingerprint auth. * auth: virtual instead of override, remove braces * pam: join the thread * auth: remove isAuthenticated and switch to a control flow based unlock * auth: initialize authentication before aquiring the session lock
- Loading branch information
1 parent
4681f8f
commit a4b0562
Showing
12 changed files
with
355 additions
and
174 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
#include "Auth.hpp" | ||
#include "Pam.hpp" | ||
#include "Fingerprint.hpp" | ||
#include "../config/ConfigManager.hpp" | ||
#include "../core/hyprlock.hpp" | ||
#include "src/helpers/Log.hpp" | ||
|
||
#include <hyprlang.hpp> | ||
#include <memory> | ||
|
||
CAuth::CAuth() { | ||
static auto* const PENABLEPAM = (Hyprlang::INT* const*)g_pConfigManager->getValuePtr("auth:pam:enabled"); | ||
if (**PENABLEPAM) | ||
m_vImpls.push_back(std::make_shared<CPam>()); | ||
static auto* const PENABLEFINGERPRINT = (Hyprlang::INT* const*)g_pConfigManager->getValuePtr("auth:fingerprint:enabled"); | ||
if (**PENABLEFINGERPRINT) | ||
m_vImpls.push_back(std::make_shared<CFingerprint>()); | ||
|
||
RASSERT(!m_vImpls.empty(), "At least one authentication method must be enabled!"); | ||
} | ||
|
||
void CAuth::start() { | ||
for (const auto& i : m_vImpls) { | ||
i->init(); | ||
} | ||
} | ||
|
||
void CAuth::submitInput(const std::string& input) { | ||
for (const auto& i : m_vImpls) { | ||
i->handleInput(input); | ||
} | ||
} | ||
|
||
bool CAuth::checkWaiting() { | ||
for (const auto& i : m_vImpls) { | ||
if (i->checkWaiting()) | ||
return true; | ||
} | ||
|
||
return false; | ||
} | ||
|
||
std::string CAuth::getInlineFeedback() { | ||
std::optional<std::string> firstFeedback = std::nullopt; | ||
for (const auto& i : m_vImpls) { | ||
const auto FEEDBACK = (m_bDisplayFailText) ? i->getLastFailText() : i->getLastPrompt(); | ||
if (!FEEDBACK.has_value()) | ||
continue; | ||
|
||
if (!firstFeedback.has_value()) | ||
firstFeedback = FEEDBACK; | ||
|
||
if (i->getImplType() == m_eLastActiveImpl) | ||
return FEEDBACK.value(); | ||
} | ||
|
||
return firstFeedback.value_or("Ups, no authentication feedack"); | ||
} | ||
|
||
std::optional<std::string> CAuth::getFailText(eAuthImplementations implType) { | ||
for (const auto& i : m_vImpls) { | ||
if (i->getImplType() == implType) | ||
return i->getLastFailText(); | ||
} | ||
return std::nullopt; | ||
} | ||
|
||
std::optional<std::string> CAuth::getPrompt(eAuthImplementations implType) { | ||
for (const auto& i : m_vImpls) { | ||
if (i->getImplType() == implType) | ||
return i->getLastPrompt(); | ||
} | ||
return std::nullopt; | ||
} | ||
|
||
std::shared_ptr<IAuthImplementation> CAuth::getImpl(eAuthImplementations implType) { | ||
for (const auto& i : m_vImpls) { | ||
if (i->getImplType() == implType) | ||
return i; | ||
} | ||
|
||
return nullptr; | ||
} | ||
|
||
void CAuth::terminate() { | ||
for (const auto& i : m_vImpls) { | ||
i->terminate(); | ||
} | ||
} | ||
|
||
static void passwordFailCallback(std::shared_ptr<CTimer> self, void* data) { | ||
g_pHyprlock->clearPasswordBuffer(); | ||
g_pAuth->m_iFailedAttempts++; | ||
Debug::log(LOG, "Failed attempts: {}", g_pAuth->m_iFailedAttempts); | ||
|
||
g_pAuth->m_bDisplayFailText = true; | ||
g_pHyprlock->enqueueForceUpdateTimers(); | ||
|
||
g_pHyprlock->renderAllOutputs(); | ||
} | ||
|
||
static void passwordUnlockCallback(std::shared_ptr<CTimer> self, void* data) { | ||
g_pHyprlock->unlock(); | ||
} | ||
|
||
void CAuth::enqueueFail() { | ||
g_pHyprlock->addTimer(std::chrono::milliseconds(0), passwordFailCallback, nullptr); | ||
} | ||
|
||
void CAuth::enqueueUnlock() { | ||
g_pHyprlock->addTimer(std::chrono::milliseconds(0), passwordUnlockCallback, nullptr); | ||
} | ||
|
||
void CAuth::postActivity(eAuthImplementations implType) { | ||
m_eLastActiveImpl = implType; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
#pragma once | ||
|
||
#include <memory> | ||
#include <optional> | ||
#include <vector> | ||
|
||
enum eAuthImplementations { | ||
AUTH_IMPL_PAM = 0, | ||
AUTH_IMPL_FINGERPRINT = 1, | ||
}; | ||
|
||
class IAuthImplementation { | ||
public: | ||
virtual ~IAuthImplementation() = default; | ||
|
||
virtual eAuthImplementations getImplType() = 0; | ||
virtual void init() = 0; | ||
virtual void handleInput(const std::string& input) = 0; | ||
virtual bool checkWaiting() = 0; | ||
virtual std::optional<std::string> getLastFailText() = 0; | ||
virtual std::optional<std::string> getLastPrompt() = 0; | ||
virtual void terminate() = 0; | ||
|
||
friend class CAuth; | ||
}; | ||
|
||
class CAuth { | ||
public: | ||
CAuth(); | ||
|
||
void start(); | ||
|
||
void submitInput(const std::string& input); | ||
bool checkWaiting(); | ||
|
||
// Used by the PasswordInput field. We are constraint to a single line for the authentication feedback there. | ||
// Based on m_bDisplayFailText, this will return either the fail text or the prompt. | ||
// Based on m_eLastActiveImpl, it will select the implementation. | ||
std::string getInlineFeedback(); | ||
|
||
std::optional<std::string> getFailText(eAuthImplementations implType); | ||
std::optional<std::string> getPrompt(eAuthImplementations implType); | ||
|
||
std::shared_ptr<IAuthImplementation> getImpl(eAuthImplementations implType); | ||
|
||
void terminate(); | ||
|
||
// Should only be set via the main thread | ||
bool m_bDisplayFailText = false; | ||
size_t m_iFailedAttempts = 0; | ||
|
||
void enqueueUnlock(); | ||
void enqueueFail(); | ||
void postActivity(eAuthImplementations implType); | ||
|
||
private: | ||
std::vector<std::shared_ptr<IAuthImplementation>> m_vImpls; | ||
std::optional<eAuthImplementations> m_eLastActiveImpl = std::nullopt; | ||
}; | ||
|
||
inline std::unique_ptr<CAuth> g_pAuth; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.