Commit 7602cb7c by Ben Straub

Add user-from-url param to auth callback

parent 2234b2b0
......@@ -61,6 +61,7 @@ static void checkout_progress(const char *path, size_t cur, size_t tot, void *pa
static int cred_acquire(git_cred **out,
const char * UNUSED(url),
const char * UNUSED(username_from_url),
unsigned int UNUSED(allowed_types),
void * UNUSED(payload))
{
......
......@@ -34,6 +34,8 @@ typedef struct git_cred_userpass_payload {
*
* @param cred The newly created credential object.
* @param url The resource for which we are demanding a credential.
* @param username_from_url The username that was embedded in a "user@host"
* remote url, or NULL if not included.
* @param allowed_types A bitmask stating which cred types are OK to return.
* @param payload The payload provided when specifying this callback. (This is
* interpreted as a `git_cred_userpass_payload*`.)
......@@ -41,6 +43,7 @@ typedef struct git_cred_userpass_payload {
GIT_EXTERN(int) git_cred_userpass(
git_cred **cred,
const char *url,
const char *user_from_url,
unsigned int allowed_types,
void *payload);
......
......@@ -62,6 +62,8 @@ GIT_EXTERN(int) git_cred_userpass_plaintext_new(
*
* @param cred The newly created credential object.
* @param url The resource for which we are demanding a credential.
* @param username_from_url The username that was embedded in a "user@host"
* remote url, or NULL if not included.
* @param allowed_types A bitmask stating which cred types are OK to return.
* @param payload The payload provided when specifying this callback.
* @return 0 for success or an error code for failure
......@@ -69,6 +71,7 @@ GIT_EXTERN(int) git_cred_userpass_plaintext_new(
typedef int (*git_cred_acquire_cb)(
git_cred **cred,
const char *url,
const char *username_from_url,
unsigned int allowed_types,
void *payload);
......
......@@ -11,17 +11,34 @@
int git_cred_userpass(
git_cred **cred,
const char *url,
const char *user_from_url,
unsigned int allowed_types,
void *payload)
{
git_cred_userpass_payload *userpass = (git_cred_userpass_payload*)payload;
const char *effective_username = NULL;
GIT_UNUSED(url);
if (!userpass || !userpass->username || !userpass->password) return -1;
if (!userpass || !userpass->password) return -1;
/* Username resolution: a username can be passed with the URL, the
* credentials payload, or both. Here's what we do.
*
* | Payload | URL | Used |
* +-------------+----------+-----------+
* | yes | no | payload |
* | yes | yes | payload |
* | no | yes | url |
* | no | no | FAIL |
*/
effective_username = userpass->username;
if (!userpass->username && user_from_url)
effective_username = user_from_url;
if (!effective_username) return -1;
if ((GIT_CREDTYPE_USERPASS_PLAINTEXT & allowed_types) == 0 ||
git_cred_userpass_plaintext_new(cred, userpass->username, userpass->password) < 0)
git_cred_userpass_plaintext_new(cred, effective_username, userpass->password) < 0)
return -1;
return 0;
......
......@@ -257,6 +257,7 @@ static int on_headers_complete(http_parser *parser)
if (t->owner->cred_acquire_cb(&t->cred,
t->owner->url,
t->user_from_url,
allowed_types,
t->owner->cred_acquire_payload) < 0)
return PARSE_ERROR_GENERIC;
......
......@@ -6,14 +6,14 @@ void test_network_cred__stock_userpass_validates_args(void)
{
git_cred_userpass_payload payload = {0};
cl_git_fail(git_cred_userpass(NULL, NULL, 0, NULL));
cl_git_fail(git_cred_userpass(NULL, NULL, NULL, 0, NULL));
payload.username = "user";
cl_git_fail(git_cred_userpass(NULL, NULL, 0, &payload));
cl_git_fail(git_cred_userpass(NULL, NULL, NULL, 0, &payload));
payload.username = NULL;
payload.username = "pass";
cl_git_fail(git_cred_userpass(NULL, NULL, 0, &payload));
cl_git_fail(git_cred_userpass(NULL, NULL, NULL, 0, &payload));
}
void test_network_cred__stock_userpass_validates_that_method_is_allowed(void)
......@@ -21,7 +21,30 @@ void test_network_cred__stock_userpass_validates_that_method_is_allowed(void)
git_cred *cred;
git_cred_userpass_payload payload = {"user", "pass"};
cl_git_fail(git_cred_userpass(&cred, NULL, 0, &payload));
cl_git_pass(git_cred_userpass(&cred, NULL, GIT_CREDTYPE_USERPASS_PLAINTEXT, &payload));
cl_git_fail(git_cred_userpass(&cred, NULL, NULL, 0, &payload));
cl_git_pass(git_cred_userpass(&cred, NULL, NULL, GIT_CREDTYPE_USERPASS_PLAINTEXT, &payload));
cred->free(cred);
}
void test_network_cred__stock_userpass_properly_handles_username_in_url(void)
{
git_cred *cred;
git_cred_userpass_plaintext *plain;
git_cred_userpass_payload payload = {"alice", "password"};
cl_git_pass(git_cred_userpass(&cred, NULL, NULL, GIT_CREDTYPE_USERPASS_PLAINTEXT, &payload));
plain = (git_cred_userpass_plaintext*)cred;
cl_assert_equal_s(plain->username, "alice");
cred->free(cred);
cl_git_pass(git_cred_userpass(&cred, NULL, "bob", GIT_CREDTYPE_USERPASS_PLAINTEXT, &payload));
plain = (git_cred_userpass_plaintext*)cred;
cl_assert_equal_s(plain->username, "alice");
cred->free(cred);
payload.username = NULL;
cl_git_pass(git_cred_userpass(&cred, NULL, "bob", GIT_CREDTYPE_USERPASS_PLAINTEXT, &payload));
plain = (git_cred_userpass_plaintext*)cred;
cl_assert_equal_s(plain->username, "bob");
cred->free(cred);
}
......@@ -30,9 +30,15 @@ static git_oid _tag_tree;
static git_oid _tag_blob;
static git_oid _tag_lightweight;
static int cred_acquire_cb(git_cred **cred, const char *url, unsigned int allowed_types, void *payload)
static int cred_acquire_cb(
git_cred **cred,
const char *url,
const char *user_from_url,
unsigned int allowed_types,
void *payload)
{
GIT_UNUSED(url);
GIT_UNUSED(user_from_url);
*((bool*)payload) = true;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment