Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#5662: Experimental GitFetch command added. Credential storage and re…
…trieval needs to be more sophisticated than that.
- Loading branch information
1 parent
60c4712
commit 22375f3
Showing
9 changed files
with
263 additions
and
35 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 |
---|---|---|
|
@@ -3,6 +3,7 @@ | |
#include <string> | ||
#include <codecvt> | ||
#include <locale> | ||
#include <vector> | ||
|
||
namespace string | ||
{ | ||
|
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,42 @@ | ||
#pragma once | ||
|
||
#include <string> | ||
|
||
#ifdef _MSC_VER | ||
#define WIN32_LEAN_AND_MEAN | ||
#include <windows.h> | ||
#include <wincred.h> | ||
#include <tchar.h> | ||
#include "string/encoding.h" | ||
#endif | ||
|
||
namespace vcs | ||
{ | ||
|
||
class CredentialManager | ||
{ | ||
public: | ||
static std::pair<std::string, std::string> RetrievePassword(const std::wstring& accountName) | ||
{ | ||
#ifdef _MSC_VER | ||
PCREDENTIALW pcred; | ||
BOOL ok = ::CredReadW(accountName.c_str(), CRED_TYPE_GENERIC, 0, &pcred); | ||
|
||
if (!ok) | ||
{ | ||
return std::make_pair("", ""); | ||
} | ||
|
||
auto user = string::unicode_to_utf8(pcred->UserName); | ||
auto pw = string::unicode_to_utf8((const wchar_t*)pcred->CredentialBlob); | ||
|
||
::CredFree(pcred); | ||
|
||
return std::make_pair(user, pw); | ||
#else | ||
return ""; | ||
#endif | ||
} | ||
}; | ||
|
||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,29 @@ | ||
#pragma once | ||
|
||
#include "imodule.h" | ||
#include "icommandsystem.h" | ||
#include "Repository.h" | ||
|
||
namespace vcs | ||
{ | ||
|
||
class GitModule : | ||
public RegisterableModule | ||
{ | ||
private: | ||
std::unique_ptr<git::Repository> _repository; | ||
|
||
public: | ||
// RegisterableModule implementation | ||
const std::string& getName() const override; | ||
const StringSet& getDependencies() const override; | ||
void initialiseModule(const IApplicationContext& ctx) override; | ||
void shutdownModule() override; | ||
|
||
private: | ||
void registerCommands(); | ||
|
||
void fetch(const cmd::ArgumentList& args); | ||
}; | ||
|
||
} |
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,94 @@ | ||
#pragma once | ||
|
||
#include <git2.h> | ||
#include "Repository.h" | ||
#include "CredentialManager.h" | ||
|
||
namespace vcs | ||
{ | ||
|
||
namespace git | ||
{ | ||
|
||
class Remote | ||
{ | ||
private: | ||
git_remote* _remote; | ||
|
||
public: | ||
using Ptr = std::shared_ptr<Remote>; | ||
|
||
Remote(git_remote* remote) : | ||
_remote(remote) | ||
{} | ||
|
||
~Remote() | ||
{ | ||
git_remote_free(_remote); | ||
} | ||
|
||
void fetch() | ||
{ | ||
if (!_remote) | ||
{ | ||
rError() << "Not a valid remote" << std::endl; | ||
return; | ||
} | ||
|
||
git_fetch_options options; | ||
git_fetch_options_init(&options, GIT_FETCH_OPTIONS_VERSION); | ||
|
||
git_credential* credentials = nullptr; | ||
auto userAndPass = CredentialManager::RetrievePassword(L"git:https://gitlab.com"); | ||
|
||
if (!userAndPass.first.empty() && !userAndPass.second.empty()) | ||
{ | ||
if (git_credential_userpass_plaintext_new(&credentials, userAndPass.first.c_str(), userAndPass.second.c_str()) < 0) | ||
{ | ||
rError() << "Unable to create credentials" << std::endl; | ||
return; | ||
} | ||
|
||
options.callbacks.credentials = AcquireCredentials; | ||
options.callbacks.payload = credentials; | ||
} | ||
|
||
auto remoteName = git_remote_name(_remote); | ||
|
||
rMessage() << "Fetching from remote " << remoteName << std::endl; | ||
|
||
if (git_remote_fetch(_remote, nullptr, &options, "fetch") < 0) | ||
{ | ||
const auto* error = git_error_last(); | ||
|
||
rError() << "Fetch error " << error->message << std::endl; | ||
return; | ||
} | ||
|
||
rMessage() << "Fetch complete"; | ||
} | ||
|
||
static Ptr CreateFromName(Repository& repository, const std::string& name) | ||
{ | ||
git_remote* remote; | ||
|
||
if (git_remote_lookup(&remote, repository._get(), name.c_str()) < 0) | ||
{ | ||
rWarning() << "Failed to look up the remote " << name << std::endl; | ||
return Ptr(); | ||
} | ||
|
||
return std::make_shared<Remote>(remote); | ||
} | ||
|
||
private: | ||
static int AcquireCredentials(git_cred** out, const char* url, const char* username_from_url, unsigned int allowed_types, void* payload) | ||
{ | ||
*out = reinterpret_cast<git_credential*>(payload); | ||
return 0; | ||
} | ||
}; | ||
|
||
} | ||
|
||
} |
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,49 @@ | ||
#include "Repository.h" | ||
|
||
#include <git2.h> | ||
#include "itextstream.h" | ||
#include "Remote.h" | ||
|
||
namespace vcs | ||
{ | ||
|
||
namespace git | ||
{ | ||
|
||
Repository::Repository(const std::string& path) : | ||
_repository(nullptr), | ||
_isOk(false) | ||
{ | ||
if (git_repository_open(&_repository, path.c_str()) == 0) | ||
{ | ||
_isOk = true; | ||
} | ||
else | ||
{ | ||
rMessage() << "Failed to open repository at " << path << std::endl; | ||
} | ||
} | ||
|
||
bool Repository::isOk() const | ||
{ | ||
return _isOk; | ||
} | ||
|
||
Repository::~Repository() | ||
{ | ||
git_repository_free(_repository); | ||
} | ||
|
||
std::shared_ptr<Remote> Repository::getRemote(const std::string& name) | ||
{ | ||
return Remote::CreateFromName(*this, name); | ||
} | ||
|
||
git_repository* Repository::_get() | ||
{ | ||
return _repository; | ||
} | ||
|
||
} | ||
|
||
} |
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.