userdb: add birthDate field to JSON user records (#40954)

Add an optional field that can be used to store a user's birth date.
userdb already stores personal metadata (`emailAddress`, `realName`,
`location`) so `birthDate` is a natural fit.
This commit is contained in:
Luca Boccassi
2026-03-18 23:04:03 +00:00
committed by GitHub
11 changed files with 199 additions and 18 deletions
+58
View File
@@ -1281,4 +1281,62 @@ static int intro(void) {
return EXIT_SUCCESS;
}
TEST(parse_calendar_date) {
usec_t usec;
/* Valid dates */
ASSERT_OK(parse_calendar_date("2000-01-01", &usec));
ASSERT_OK(parse_calendar_date("1970-01-01", &usec));
ASSERT_EQ(usec, 0u); /* epoch */
ASSERT_OK(parse_calendar_date("2000-02-29", &usec)); /* leap year */
/* NULL ret is allowed (validation only) */
ASSERT_OK(parse_calendar_date("2000-06-15", NULL));
/* Non-normalized dates */
ASSERT_ERROR(parse_calendar_date("2023-02-29", &usec), EINVAL); /* not a leap year */
ASSERT_ERROR(parse_calendar_date("2023-04-31", &usec), EINVAL); /* April has 30 days */
ASSERT_ERROR(parse_calendar_date("2023-13-01", &usec), EINVAL); /* month 13 */
ASSERT_ERROR(parse_calendar_date("2023-00-01", &usec), EINVAL); /* month 0 */
/* Malformed input */
ASSERT_ERROR(parse_calendar_date("", &usec), EINVAL);
ASSERT_ERROR(parse_calendar_date("not-a-date", &usec), EINVAL);
ASSERT_ERROR(parse_calendar_date("2023-06-15T00:00:00", &usec), EINVAL); /* trailing time */
ASSERT_ERROR(parse_calendar_date("2023/06/15", &usec), EINVAL); /* wrong separator */
ASSERT_ERROR(parse_calendar_date("06-15-2023", &usec), EINVAL); /* wrong order */
}
TEST(parse_birth_date) {
struct tm tm;
/* Valid dates */
ASSERT_OK(parse_birth_date("2000-06-15", &tm));
ASSERT_EQ(tm.tm_year, 100); /* 2000 - 1900 */
ASSERT_EQ(tm.tm_mon, 5); /* June, 0-indexed */
ASSERT_EQ(tm.tm_mday, 15);
/* Pre-epoch dates */
ASSERT_OK(parse_birth_date("1960-03-25", &tm));
ASSERT_EQ(tm.tm_year, 60);
ASSERT_EQ(tm.tm_mon, 2);
ASSERT_EQ(tm.tm_mday, 25);
/* NULL ret is allowed (validation only) */
ASSERT_OK(parse_birth_date("2000-01-01", NULL));
/* Non-date fields should not be relied upon */
ASSERT_OK(parse_birth_date("2000-06-15", &tm));
ASSERT_FALSE(BIRTH_DATE_IS_SET(BIRTH_DATE_UNSET));
/* Non-normalized dates */
ASSERT_ERROR(parse_birth_date("2023-02-29", &tm), EINVAL);
ASSERT_ERROR(parse_birth_date("2023-04-31", &tm), EINVAL);
/* Malformed input */
ASSERT_ERROR(parse_birth_date("", &tm), EINVAL);
ASSERT_ERROR(parse_birth_date("not-a-date", &tm), EINVAL);
ASSERT_ERROR(parse_birth_date("2023-06-15T00:00:00", &tm), EINVAL);
}
DEFINE_TEST_MAIN_WITH_INTRO(LOG_INFO, intro);
+9
View File
@@ -96,6 +96,15 @@ TEST(self_changes) {
SD_JSON_BUILD_PAIR_OBJECT("privileged",
SD_JSON_BUILD_PAIR_UNSIGNED("notInHardCodedList", 99999)));
ASSERT_TRUE(user_record_self_changes_allowed(curr, new));
/* birthDate is NOT self-modifiable (admin-only) */
USER(&curr,
SD_JSON_BUILD_PAIR_STRING("userName", "test"),
SD_JSON_BUILD_PAIR_STRING("birthDate", "1990-01-01"));
USER(&new,
SD_JSON_BUILD_PAIR_STRING("userName", "test"),
SD_JSON_BUILD_PAIR_STRING("birthDate", "1990-06-15"));
ASSERT_FALSE(user_record_self_changes_allowed(curr, new));
}
DEFINE_TEST_MAIN(LOG_INFO);