mirror of
https://github.com/QRouland/UTPass.git
synced 2025-06-24 22:42:28 +00:00
Add support for ssh clone
This commit is contained in:
@ -12,8 +12,15 @@ extern "C" {
|
||||
#include "jobs/gitjob.h"
|
||||
|
||||
Git::Git():
|
||||
m_sem(std::unique_ptr<QSemaphore>(new QSemaphore(1)))
|
||||
m_sem(std::unique_ptr<QSemaphore>(new QSemaphore(1))),
|
||||
m_ssh_homedir (QStandardPaths::writableLocation(
|
||||
QStandardPaths::AppDataLocation).append("/.ssh"))
|
||||
{
|
||||
qDebug() << "[Git] SSH Home is " << m_ssh_homedir.absolutePath();
|
||||
QDir m_ssh_homedir(this->m_ssh_homedir);
|
||||
if (!m_ssh_homedir.exists()) {
|
||||
m_ssh_homedir.mkpath(".");
|
||||
}
|
||||
git_libgit2_init();
|
||||
}
|
||||
|
||||
@ -26,7 +33,7 @@ Git::~Git()
|
||||
bool Git::clone(QString url, QString path, cred_type mode)
|
||||
{
|
||||
if (!this->m_sem->tryAcquire(1, 500)) {
|
||||
qWarning() << "Can acquire git semaphore a command is already running ";
|
||||
qWarning() << "[Git] Can acquire git semaphore a command is already running ";
|
||||
return false;
|
||||
}
|
||||
auto v = overload {
|
||||
@ -44,18 +51,26 @@ bool Git::clone(QString url, QString path, cred_type mode)
|
||||
|
||||
bool Git::cloneHttp(QString url, QString path)
|
||||
{
|
||||
qInfo() << "Call clone command Http " << url << " " << path;
|
||||
qInfo() << "[Git] Call clone command Http " << url << " " << path;
|
||||
HTTP mode = {};
|
||||
return this->clone(url, path, mode);
|
||||
}
|
||||
|
||||
bool Git::cloneHttpPass(QString url, QString path, QString pass)
|
||||
{
|
||||
qInfo() << "Call clone command HttpPass " << url << " " << path;
|
||||
qInfo() << "[Git] Call clone command HttpPass " << url << " " << path;
|
||||
HTTPUserPass mode = { pass };
|
||||
return this->clone(url, path, mode);
|
||||
}
|
||||
|
||||
bool Git::cloneSshKey(QString url, QString path, QString passphrase)
|
||||
{
|
||||
qInfo() << "[Git] Call clone command HttpPass " << url << " " << path;
|
||||
|
||||
SSHKey mode = { this->pubKeyPath(), this->privKeyPath(), passphrase };
|
||||
return this->clone(url, path, mode);
|
||||
}
|
||||
|
||||
void Git::cloneResult(const bool err)
|
||||
{
|
||||
|
||||
@ -66,3 +81,23 @@ void Git::cloneResult(const bool err)
|
||||
}
|
||||
this->m_sem->release();
|
||||
}
|
||||
|
||||
bool Git::importSshKey(QUrl source_path, bool is_private){
|
||||
auto destination_path = is_private ? this->privKeyPath() : this->pubKeyPath();
|
||||
|
||||
QFile source_file(source_path.toLocalFile());
|
||||
|
||||
if (!source_file.exists()) {
|
||||
qWarning() << "[Git] Source file does not exist.";
|
||||
return false;
|
||||
}
|
||||
|
||||
QDir target_dir = QFileInfo(destination_path).absoluteDir();
|
||||
if (!target_dir.exists()) {
|
||||
if (!target_dir.mkpath(".")) {
|
||||
qWarning() << "[Git] Failed to create target directory.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return source_file.copy(destination_path);
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define GIT_H
|
||||
|
||||
#include "jobs/gitjob.h"
|
||||
#include "qdebug.h"
|
||||
#include <QUrl>
|
||||
#include <QObject>
|
||||
#include <QSemaphore>
|
||||
@ -16,6 +17,8 @@
|
||||
class Git : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QString privKey READ pubKeyPath)
|
||||
Q_PROPERTY(QString pubKey READ privKeyPath)
|
||||
|
||||
private slots:
|
||||
/**
|
||||
@ -47,6 +50,7 @@ signals:
|
||||
|
||||
private:
|
||||
std::unique_ptr<QSemaphore> m_sem; /**< Semaphore for managing concurrent operations. */
|
||||
QDir m_ssh_homedir; /**< Directory that contains the SSH keys (public and private). */
|
||||
|
||||
/**
|
||||
* @brief Clones a repository from a specified URL.
|
||||
@ -61,6 +65,27 @@ private:
|
||||
*/
|
||||
bool clone(QString url, QString path, cred_type mode);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief Get the path to the public keyring.
|
||||
*
|
||||
* @return The file path to the public key.
|
||||
*/
|
||||
QString pubKeyPath()
|
||||
{
|
||||
return this->m_ssh_homedir.filePath("id_rsa.pub");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the path to the secret keyring.
|
||||
*
|
||||
* @return The file path to the private key.
|
||||
*/
|
||||
QString privKeyPath()
|
||||
{
|
||||
return this->m_ssh_homedir.filePath("id_rsa");
|
||||
}
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor for the Git class.
|
||||
@ -76,6 +101,9 @@ public:
|
||||
*/
|
||||
~Git() override;
|
||||
|
||||
|
||||
Q_INVOKABLE bool importSshKey(QUrl source_path, bool is_private);
|
||||
|
||||
/**
|
||||
* @brief Clones a repository over HTTP.
|
||||
*
|
||||
@ -97,13 +125,22 @@ public:
|
||||
* @param url The HTTP URL of the Git repository to clone.
|
||||
* @param path The destination path for the cloned repository.
|
||||
* @param pass The password used for HTTP authentication.
|
||||
* @return `true` if the clone operation was successful, `false` otherwise.
|
||||
* @return `true` if the clone job operation was successfully started, `false` otherwise.
|
||||
*/
|
||||
Q_INVOKABLE bool cloneHttpPass(QString url, QString path, QString pass);
|
||||
|
||||
// Future SSH support methods:
|
||||
// Q_INVOKABLE bool clone_ssh_pass(QString url, QString path, QString pass);
|
||||
// Q_INVOKABLE bool clone_ssh_key(QString url, QString path, QString pub_key, QString priv_key, QString passphrase);
|
||||
/**
|
||||
* @brief Clones a repository over SSH with a key for authentication.
|
||||
*
|
||||
* This method clones a Git repository from the specified ssh URL using the provided password for authentication,
|
||||
* and saves it to the given destination path.
|
||||
*
|
||||
* @param url The HTTP URL of the Git repository to clone.
|
||||
* @param path The destination path for the cloned repository.
|
||||
* @param passphrase The passphrase used for SSH authentication.
|
||||
* @return `true` if the clone job operation was successfully started, `false` otherwise.
|
||||
*/
|
||||
Q_INVOKABLE bool cloneSshKey(QString url, QString path, QString passphrase);
|
||||
|
||||
// Q_INVOKABLE bool update(QUrl url, QString path);
|
||||
// ....
|
||||
|
@ -18,17 +18,7 @@ GitJob::~GitJob()
|
||||
git_libgit2_shutdown();
|
||||
}
|
||||
|
||||
bool GitJob::getUsername(char **username, QString maybe_username, const char *username_from_url)
|
||||
{
|
||||
if (username_from_url) {
|
||||
*username = strdup(username_from_url);
|
||||
return true;
|
||||
} else if (!maybe_username.isNull()) {
|
||||
*username = maybe_username.toLocal8Bit().data();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int GitJob::credentialsCB(git_cred **out, const char *url, const char *username_from_url,
|
||||
unsigned int allowed_types, void *payload)
|
||||
|
@ -1,6 +1,7 @@
|
||||
#ifndef GITJOB_H
|
||||
#define GITJOB_H
|
||||
|
||||
#include <QDir>
|
||||
#include <QThread>
|
||||
extern "C" {
|
||||
#include <git2.h>
|
||||
|
@ -9,5 +9,4 @@ void GitPlugin::registerTypes(const char *uri)
|
||||
{
|
||||
//@uri Git
|
||||
qmlRegisterSingletonType<Git>(uri, 1, 0, "Git", [](QQmlEngine *, QJSEngine *) -> QObject * { return new Git; });
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user