feat(BRIDGE-14): HV3 implementation - GUI & CLI; ownership verification & CAPTCHA are supported

This commit is contained in:
Atanas Janeshliev
2024-04-01 16:29:15 +02:00
parent c692c21b87
commit 9552e72ba8
24 changed files with 1853 additions and 1151 deletions

View File

@ -29,13 +29,11 @@ using namespace bridgepp;
namespace {
QString const defaultKeychain = "defaultKeychain"; ///< The default keychain.
QString const HV_ERROR_TEMPLATE = "failed to create new API client: 422 POST https://mail-api.proton.me/auth/v4: CAPTCHA validation failed (Code=12087, Status=422)";
}
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
@ -349,6 +347,7 @@ Status GRPCService::ForceLauncher(ServerContext *, StringValue const *request, E
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::SetMainExecutable(ServerContext *, StringValue const *request, Empty *) {
resetHv();
app().log().debug(__FUNCTION__);
app().log().info(QString("SetMainExecutable: %1").arg(QString::fromStdString(request->value())));
return Status::OK;
@ -418,7 +417,19 @@ Status GRPCService::Login(ServerContext *, LoginRequest const *request, Empty *)
return Status::OK;
}
if (usersTab.nextUserHvRequired() && !hvWasRequested_ && previousHvUsername_ != QString::fromStdString(request->username())) {
hvWasRequested_ = true;
previousHvUsername_ = QString::fromStdString(request->username());
qtProxy_.sendDelayedEvent(newLoginHvRequestedEvent());
return Status::OK;
} else {
hvWasRequested_ = false;
previousHvUsername_ = "";
}
if (usersTab.nextUserHvError()) {
qtProxy_.sendDelayedEvent(newLoginError(LoginErrorType::HV_ERROR, HV_ERROR_TEMPLATE));
return Status::OK;
}
if (usersTab.nextUserUsernamePasswordError()) {
qtProxy_.sendDelayedEvent(newLoginError(LoginErrorType::USERNAME_PASSWORD_ERROR, usersTab.usernamePasswordErrorMessage()));
return Status::OK;
@ -495,6 +506,7 @@ Status GRPCService::Login2Passwords(ServerContext *, LoginRequest const *request
//****************************************************************************************************************************************************
Status GRPCService::LoginAbort(ServerContext *, LoginAbortRequest const *request, Empty *) {
app().log().debug(__FUNCTION__);
this->resetHv();
loginUsername_ = QString();
return Status::OK;
}
@ -953,3 +965,11 @@ void GRPCService::finishLogin() {
qtProxy_.sendDelayedEvent(newLoginFinishedEvent(user->id(), alreadyExist));
}
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
void GRPCService::resetHv() {
hvWasRequested_ = false;
previousHvUsername_ = "";
}

View File

@ -106,6 +106,7 @@ public: // member functions.
private: // member functions
void finishLogin(); ///< finish the login procedure once the credentials have been validated.
void resetHv(); ///< Resets the human verification state.
private: // data member
mutable QMutex eventStreamMutex_; ///< Mutex used to access eventQueue_, isStreaming_ and shouldStopStreaming_;
@ -113,6 +114,8 @@ private: // data member
bool isStreaming_; ///< Is the gRPC stream running. Access protected by eventStreamMutex_;
bool eventStreamShouldStop_; ///< Should the stream be stopped? Access protected by eventStreamMutex
QString loginUsername_; ///< The username used for the current login procedure.
QString previousHvUsername_; ///< The previous username used for HV.
bool hvWasRequested_ {false}; ///< Was human verification requested.
GRPCQtProxy qtProxy_; ///< Qt Proxy used to send signals, as this class is not a QObject.
};

View File

@ -277,6 +277,22 @@ bridgepp::SPUser UsersTab::userWithUsernameOrEmail(QString const &username) {
}
//****************************************************************************************************************************************************
/// \return true if the next login attempt should trigger a human verification request
//****************************************************************************************************************************************************
bool UsersTab::nextUserHvRequired() const {
return ui_.checkHV3Required->isChecked();
}
//****************************************************************************************************************************************************
/// \return true if the next login attempt should trigger a human verification error
//****************************************************************************************************************************************************
bool UsersTab::nextUserHvError() const {
return ui_.checkHV3Error->isChecked();
}
//****************************************************************************************************************************************************
/// \return true iff the next login attempt should trigger a username/password error.
//****************************************************************************************************************************************************

View File

@ -39,6 +39,8 @@ public: // member functions.
UserTable &userTable(); ///< Returns a reference to the user table.
bridgepp::SPUser userWithID(QString const &userID); ///< Get the user with the given ID.
bridgepp::SPUser userWithUsernameOrEmail(QString const &username); ///< Get the user with the given username.
bool nextUserHvRequired() const; ///< Check if next user login should trigger HV
bool nextUserHvError() const; ///< Check if next user login should trigger HV error
bool nextUserUsernamePasswordError() const; ///< Check if next user login should trigger a username/password error.
bool nextUserFreeUserError() const; ///< Check if next user login should trigger a Free user error.
bool nextUserTFARequired() const; ///< Check if next user login should requires 2FA.

View File

@ -290,6 +290,20 @@
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="checkHV3Required">
<property name="text">
<string>HV3 required</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkHV3Error">
<property name="text">
<string>HV3 error</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkFreeUserError">
<property name="text">