Browse Source

Merge branch 'mh/credential-password-expiry-libsecret' into next

The libsecret credential helper learns to handle the password
expiry time information.

* mh/credential-password-expiry-libsecret:
  credential/libsecret: support password_expiry_utc
next
Junio C Hamano 2 years ago
parent
commit
fd898e3756
  1. 39
      contrib/credential/libsecret/git-credential-libsecret.c
  2. 30
      t/lib-credential.sh
  3. 2
      t/t0301-credential-cache.sh
  4. 2
      t/t0303-credential-external.sh

39
contrib/credential/libsecret/git-credential-libsecret.c

@ -39,6 +39,7 @@ struct credential { @@ -39,6 +39,7 @@ struct credential {
char *path;
char *username;
char *password;
char *password_expiry_utc;
};

#define CREDENTIAL_INIT { 0 }
@ -54,6 +55,21 @@ struct credential_operation { @@ -54,6 +55,21 @@ struct credential_operation {

/* ----------------- Secret Service functions ----------------- */

static const SecretSchema schema = {
"org.git.Password",
/* Ignore schema name for backwards compatibility with previous versions */
SECRET_SCHEMA_DONT_MATCH_NAME,
{
{ "user", SECRET_SCHEMA_ATTRIBUTE_STRING },
{ "object", SECRET_SCHEMA_ATTRIBUTE_STRING },
{ "protocol", SECRET_SCHEMA_ATTRIBUTE_STRING },
{ "port", SECRET_SCHEMA_ATTRIBUTE_INTEGER },
{ "server", SECRET_SCHEMA_ATTRIBUTE_STRING },
{ "password_expiry_utc", SECRET_SCHEMA_ATTRIBUTE_INTEGER },
{ NULL, 0 },
}
};

static char *make_label(struct credential *c)
{
if (c->port)
@ -78,6 +94,9 @@ static GHashTable *make_attr_list(struct credential *c) @@ -78,6 +94,9 @@ static GHashTable *make_attr_list(struct credential *c)
g_hash_table_insert(al, "port", g_strdup_printf("%hu", c->port));
if (c->path)
g_hash_table_insert(al, "object", g_strdup(c->path));
if (c->password_expiry_utc)
g_hash_table_insert(al, "password_expiry_utc",
g_strdup(c->password_expiry_utc));

return al;
}
@ -101,7 +120,7 @@ static int keyring_get(struct credential *c) @@ -101,7 +120,7 @@ static int keyring_get(struct credential *c)

attributes = make_attr_list(c);
items = secret_service_search_sync(service,
SECRET_SCHEMA_COMPAT_NETWORK,
&schema,
attributes,
SECRET_SEARCH_LOAD_SECRETS | SECRET_SEARCH_UNLOCK,
NULL,
@ -128,6 +147,12 @@ static int keyring_get(struct credential *c) @@ -128,6 +147,12 @@ static int keyring_get(struct credential *c)
c->username = g_strdup(s);
}

s = g_hash_table_lookup(attributes, "password_expiry_utc");
if (s) {
g_free(c->password_expiry_utc);
c->password_expiry_utc = g_strdup(s);
}

s = secret_value_get_text(secret);
if (s) {
g_free(c->password);
@ -162,7 +187,7 @@ static int keyring_store(struct credential *c) @@ -162,7 +187,7 @@ static int keyring_store(struct credential *c)

label = make_label(c);
attributes = make_attr_list(c);
secret_password_storev_sync(SECRET_SCHEMA_COMPAT_NETWORK,
secret_password_storev_sync(&schema,
attributes,
NULL,
label,
@ -198,7 +223,7 @@ static int keyring_erase(struct credential *c) @@ -198,7 +223,7 @@ static int keyring_erase(struct credential *c)
return EXIT_FAILURE;

attributes = make_attr_list(c);
secret_password_clearv_sync(SECRET_SCHEMA_COMPAT_NETWORK,
secret_password_clearv_sync(&schema,
attributes,
NULL,
&error);
@ -238,6 +263,7 @@ static void credential_clear(struct credential *c) @@ -238,6 +263,7 @@ static void credential_clear(struct credential *c)
g_free(c->path);
g_free(c->username);
g_free(c->password);
g_free(c->password_expiry_utc);

credential_init(c);
}
@ -284,6 +310,9 @@ static int credential_read(struct credential *c) @@ -284,6 +310,9 @@ static int credential_read(struct credential *c)
} else if (!strcmp(key, "username")) {
g_free(c->username);
c->username = g_strdup(value);
} else if (!strcmp(key, "password_expiry_utc")) {
g_free(c->password_expiry_utc);
c->password_expiry_utc = g_strdup(value);
} else if (!strcmp(key, "password")) {
g_free(c->password);
c->password = g_strdup(value);
@ -311,9 +340,11 @@ static void credential_write_item(FILE *fp, const char *key, const char *value) @@ -311,9 +340,11 @@ static void credential_write_item(FILE *fp, const char *key, const char *value)

static void credential_write(const struct credential *c)
{
/* only write username/password, if set */
/* only write username/password/expiry, if set */
credential_write_item(stdout, "username", c->username);
credential_write_item(stdout, "password", c->password);
credential_write_item(stdout, "password_expiry_utc",
c->password_expiry_utc);
}

static void usage(const char *name)

30
t/lib-credential.sh

@ -43,6 +43,7 @@ helper_test_clean() { @@ -43,6 +43,7 @@ helper_test_clean() {
reject $1 https example.com store-user
reject $1 https example.com user1
reject $1 https example.com user2
reject $1 https example.com user3
reject $1 https example.com user4
reject $1 http path.tld user
reject $1 https timeout.tld user
@ -357,6 +358,35 @@ helper_test_oauth_refresh_token() { @@ -357,6 +358,35 @@ helper_test_oauth_refresh_token() {
'
}

helper_test_password_expiry_utc() {
HELPER=$1

test_expect_success "helper ($HELPER) stores password_expiry_utc" '
check approve $HELPER <<-\EOF
protocol=https
host=example.com
username=user3
password=pass
password_expiry_utc=9999999999
EOF
'

test_expect_success "helper ($HELPER) gets password_expiry_utc" '
check fill $HELPER <<-\EOF
protocol=https
host=example.com
username=user3
--
protocol=https
host=example.com
username=user3
password=pass
password_expiry_utc=9999999999
--
EOF
'
}

write_script askpass <<\EOF
echo >&2 askpass: $*
what=$(echo $1 | cut -d" " -f1 | tr A-Z a-z | tr -cd a-z)

2
t/t0301-credential-cache.sh

@ -31,6 +31,8 @@ test_atexit 'git credential-cache exit' @@ -31,6 +31,8 @@ test_atexit 'git credential-cache exit'
helper_test cache
helper_test_oauth_refresh_token cache

helper_test_password_expiry_utc cache

test_expect_success 'socket defaults to ~/.cache/git/credential/socket' '
test_when_finished "
git credential-cache exit &&

2
t/t0303-credential-external.sh

@ -52,6 +52,8 @@ else @@ -52,6 +52,8 @@ else
helper_test_timeout "$GIT_TEST_CREDENTIAL_HELPER_TIMEOUT"
fi

helper_test_password_expiry_utc "$GIT_TEST_CREDENTIAL_HELPER"

# clean afterwards so that we are good citizens
# and don't leave cruft in the helper's storage, which
# might be long-term system storage

Loading…
Cancel
Save