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 ...@@ -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, static int cred_acquire(git_cred **out,
const char * UNUSED(url), const char * UNUSED(url),
const char * UNUSED(username_from_url),
unsigned int UNUSED(allowed_types), unsigned int UNUSED(allowed_types),
void * UNUSED(payload)) void * UNUSED(payload))
{ {
......
...@@ -34,6 +34,8 @@ typedef struct git_cred_userpass_payload { ...@@ -34,6 +34,8 @@ typedef struct git_cred_userpass_payload {
* *
* @param cred The newly created credential object. * @param cred The newly created credential object.
* @param url The resource for which we are demanding a credential. * @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 allowed_types A bitmask stating which cred types are OK to return.
* @param payload The payload provided when specifying this callback. (This is * @param payload The payload provided when specifying this callback. (This is
* interpreted as a `git_cred_userpass_payload*`.) * interpreted as a `git_cred_userpass_payload*`.)
...@@ -41,6 +43,7 @@ typedef struct git_cred_userpass_payload { ...@@ -41,6 +43,7 @@ typedef struct git_cred_userpass_payload {
GIT_EXTERN(int) git_cred_userpass( GIT_EXTERN(int) git_cred_userpass(
git_cred **cred, git_cred **cred,
const char *url, const char *url,
const char *user_from_url,
unsigned int allowed_types, unsigned int allowed_types,
void *payload); void *payload);
......
...@@ -62,6 +62,8 @@ GIT_EXTERN(int) git_cred_userpass_plaintext_new( ...@@ -62,6 +62,8 @@ GIT_EXTERN(int) git_cred_userpass_plaintext_new(
* *
* @param cred The newly created credential object. * @param cred The newly created credential object.
* @param url The resource for which we are demanding a credential. * @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 allowed_types A bitmask stating which cred types are OK to return.
* @param payload The payload provided when specifying this callback. * @param payload The payload provided when specifying this callback.
* @return 0 for success or an error code for failure * @return 0 for success or an error code for failure
...@@ -69,6 +71,7 @@ GIT_EXTERN(int) git_cred_userpass_plaintext_new( ...@@ -69,6 +71,7 @@ GIT_EXTERN(int) git_cred_userpass_plaintext_new(
typedef int (*git_cred_acquire_cb)( typedef int (*git_cred_acquire_cb)(
git_cred **cred, git_cred **cred,
const char *url, const char *url,
const char *username_from_url,
unsigned int allowed_types, unsigned int allowed_types,
void *payload); void *payload);
......
...@@ -11,17 +11,34 @@ ...@@ -11,17 +11,34 @@
int git_cred_userpass( int git_cred_userpass(
git_cred **cred, git_cred **cred,
const char *url, const char *url,
const char *user_from_url,
unsigned int allowed_types, unsigned int allowed_types,
void *payload) void *payload)
{ {
git_cred_userpass_payload *userpass = (git_cred_userpass_payload*)payload; git_cred_userpass_payload *userpass = (git_cred_userpass_payload*)payload;
const char *effective_username = NULL;
GIT_UNUSED(url); 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 || 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 -1;
return 0; return 0;
......
...@@ -257,6 +257,7 @@ static int on_headers_complete(http_parser *parser) ...@@ -257,6 +257,7 @@ static int on_headers_complete(http_parser *parser)
if (t->owner->cred_acquire_cb(&t->cred, if (t->owner->cred_acquire_cb(&t->cred,
t->owner->url, t->owner->url,
t->user_from_url,
allowed_types, allowed_types,
t->owner->cred_acquire_payload) < 0) t->owner->cred_acquire_payload) < 0)
return PARSE_ERROR_GENERIC; return PARSE_ERROR_GENERIC;
......
...@@ -6,14 +6,14 @@ void test_network_cred__stock_userpass_validates_args(void) ...@@ -6,14 +6,14 @@ void test_network_cred__stock_userpass_validates_args(void)
{ {
git_cred_userpass_payload payload = {0}; 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"; 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 = NULL;
payload.username = "pass"; 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) 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) ...@@ -21,7 +21,30 @@ void test_network_cred__stock_userpass_validates_that_method_is_allowed(void)
git_cred *cred; git_cred *cred;
git_cred_userpass_payload payload = {"user", "pass"}; git_cred_userpass_payload payload = {"user", "pass"};
cl_git_fail(git_cred_userpass(&cred, NULL, 0, &payload)); cl_git_fail(git_cred_userpass(&cred, NULL, NULL, 0, &payload));
cl_git_pass(git_cred_userpass(&cred, NULL, GIT_CREDTYPE_USERPASS_PLAINTEXT, &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); cred->free(cred);
} }
...@@ -30,9 +30,15 @@ static git_oid _tag_tree; ...@@ -30,9 +30,15 @@ static git_oid _tag_tree;
static git_oid _tag_blob; static git_oid _tag_blob;
static git_oid _tag_lightweight; 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(url);
GIT_UNUSED(user_from_url);
*((bool*)payload) = true; *((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