From 3c6c255a3aaeaa69ba592e74ddf9580639f23d2a Mon Sep 17 00:00:00 2001 From: Dimitris ZARRAS Date: Mon, 25 Nov 2024 10:04:24 +0200 Subject: [PATCH] Model OIDC Gender as a simple string. --- .../realms/pid-issuer-realm-realm.json | 36 ++++++++++++++++++- .../realms/pid-issuer-realm-users-0.json | 3 ++ .../adapter/out/pid/EncodePidInSdJwtVc.kt | 15 +------- .../out/pid/GetPidDataFromAuthServer.kt | 3 ++ .../adapter/out/pid/IssueSdJwtVcPid.kt | 3 +- .../ec/eudi/pidissuer/adapter/out/pid/Pid.kt | 19 +--------- 6 files changed, 44 insertions(+), 35 deletions(-) diff --git a/docker-compose/keycloak/realms/pid-issuer-realm-realm.json b/docker-compose/keycloak/realms/pid-issuer-realm-realm.json index a3a0a582..4c443ced 100644 --- a/docker-compose/keycloak/realms/pid-issuer-realm-realm.json +++ b/docker-compose/keycloak/realms/pid-issuer-realm-realm.json @@ -1228,6 +1228,23 @@ "jsonType.label": "String" } }, + { + "id": "5343c74e-e247-4b85-bf79-3ff843aee565", + "name": "gender_as_string", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "introspection.token.claim": "false", + "userinfo.token.claim": "true", + "user.attribute": "gender_as_string", + "id.token.claim": "false", + "lightweight.claim": "false", + "access.token.claim": "false", + "claim.name": "gender_as_string", + "jsonType.label": "String" + } + }, { "id": "73819e2a-eed3-428c-911c-47b1077af59e", "name": "birth_place", @@ -1536,6 +1553,23 @@ "jsonType.label": "String" } }, + { + "id": "0bba757d-b188-4434-8f10-ed760d266dc4", + "name": "gender_as_string", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "introspection.token.claim": "false", + "userinfo.token.claim": "true", + "user.attribute": "gender_as_string", + "id.token.claim": "false", + "lightweight.claim": "false", + "access.token.claim": "false", + "claim.name": "gender_as_string", + "jsonType.label": "String" + } + }, { "id": "eb7435a1-ffa0-4d60-b14d-f26706b2872a", "name": "birth_place", @@ -1916,7 +1950,7 @@ "subComponents": {}, "config": { "kc.user.profile.config": [ - "{\"attributes\":[{\"name\":\"username\",\"displayName\":\"${username}\",\"validations\":{\"length\":{\"min\":3,\"max\":255},\"username-prohibited-characters\":{},\"up-username-not-idn-homograph\":{}},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"credentials\",\"multivalued\":false},{\"name\":\"email\",\"displayName\":\"${email}\",\"validations\":{\"email\":{},\"length\":{\"max\":255}},\"annotations\":{},\"required\":{\"roles\":[\"user\"]},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"credentials\",\"multivalued\":false},{\"name\":\"firstName\",\"displayName\":\"${firstName}\",\"validations\":{\"length\":{\"max\":255},\"person-name-prohibited-characters\":{}},\"annotations\":{},\"required\":{\"roles\":[\"user\"]},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"profile\",\"multivalued\":false},{\"name\":\"lastName\",\"displayName\":\"${lastName}\",\"validations\":{\"length\":{\"max\":255},\"person-name-prohibited-characters\":{}},\"annotations\":{},\"required\":{\"roles\":[\"user\"]},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"profile\",\"multivalued\":false},{\"name\":\"birth_given_name\",\"displayName\":\"First name given at birth\",\"validations\":{},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"profile\",\"multivalued\":false},{\"name\":\"birth_family_name\",\"displayName\":\"Last name given at birth\",\"validations\":{},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"profile\",\"multivalued\":false},{\"name\":\"gender\",\"displayName\":\"Gender\",\"validations\":{\"options\":{\"options\":[\"0\",\"1\",\"2\",\"9\"]}},\"annotations\":{\"inputOptionLabels\":{\"0\":\"Not known\",\"1\":\"Male\",\"2\":\"Female\",\"9\":\"Not applicable\"},\"inputType\":\"select-radiobuttons\"},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"profile\",\"multivalued\":false},{\"name\":\"birthdate\",\"displayName\":\"Birthdate\",\"validations\":{\"iso-date\":{}},\"annotations\":{\"inputType\":\"html5-date\"},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"profile\",\"multivalued\":false},{\"name\":\"age_over_18\",\"displayName\":\"Age over 18\",\"validations\":{\"options\":{\"options\":[\"true\",\"false\"]}},\"annotations\":{\"inputOptionLabels\":{\"true\":\"Yes\",\"false\":\"No\"},\"inputType\":\"select\"},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"profile\",\"multivalued\":false},{\"name\":\"picture\",\"displayName\":\"Picture\",\"validations\":{},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"profile\",\"multivalued\":false},{\"name\":\"street\",\"displayName\":\"Street\",\"validations\":{},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"address\",\"multivalued\":false},{\"name\":\"address_house_number\",\"displayName\":\"House Number\",\"validations\":{},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"address\",\"multivalued\":false},{\"name\":\"locality\",\"displayName\":\"Locality\",\"validations\":{},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"address\",\"multivalued\":false},{\"name\":\"region\",\"displayName\":\"Region\",\"validations\":{},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"address\",\"multivalued\":false},{\"name\":\"postal_code\",\"displayName\":\"Postal Code\",\"validations\":{},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"address\",\"multivalued\":false},{\"name\":\"country\",\"displayName\":\"Country\",\"validations\":{},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"address\",\"multivalued\":false},{\"name\":\"formatted\",\"displayName\":\"Formatted\",\"validations\":{},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"address\",\"multivalued\":false},{\"name\":\"birth_place\",\"displayName\":\"Place\",\"validations\":{},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"birth_place\",\"multivalued\":false},{\"name\":\"birth_city\",\"displayName\":\"City\",\"validations\":{},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"birth_place\",\"multivalued\":false},{\"name\":\"birth_state\",\"displayName\":\"State\",\"validations\":{},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"birth_place\",\"multivalued\":false},{\"name\":\"birth_country\",\"displayName\":\"Country\",\"validations\":{},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"birth_place\",\"multivalued\":false},{\"name\":\"nationality\",\"displayName\":\"Nationality\",\"validations\":{},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"profile\",\"multivalued\":false}],\"groups\":[{\"name\":\"user-metadata\",\"displayHeader\":\"User metadata\",\"displayDescription\":\"Attributes, which refer to user metadata\"},{\"name\":\"address\",\"displayHeader\":\"Address\",\"displayDescription\":\"\",\"annotations\":{}},{\"name\":\"credentials\",\"displayHeader\":\"Credentials\",\"displayDescription\":\"\",\"annotations\":{}},{\"name\":\"profile\",\"displayHeader\":\"Profile\",\"displayDescription\":\"\",\"annotations\":{}},{\"name\":\"birth_place\",\"displayHeader\":\"Birth Place\",\"displayDescription\":\"\",\"annotations\":{}}]}" + "{\"attributes\":[{\"name\":\"username\",\"displayName\":\"${username}\",\"validations\":{\"length\":{\"min\":3,\"max\":255},\"username-prohibited-characters\":{},\"up-username-not-idn-homograph\":{}},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"credentials\",\"multivalued\":false},{\"name\":\"email\",\"displayName\":\"${email}\",\"validations\":{\"email\":{},\"length\":{\"max\":255}},\"annotations\":{},\"required\":{\"roles\":[\"user\"]},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"credentials\",\"multivalued\":false},{\"name\":\"firstName\",\"displayName\":\"${firstName}\",\"validations\":{\"length\":{\"max\":255},\"person-name-prohibited-characters\":{}},\"annotations\":{},\"required\":{\"roles\":[\"user\"]},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"profile\",\"multivalued\":false},{\"name\":\"lastName\",\"displayName\":\"${lastName}\",\"validations\":{\"length\":{\"max\":255},\"person-name-prohibited-characters\":{}},\"annotations\":{},\"required\":{\"roles\":[\"user\"]},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"profile\",\"multivalued\":false},{\"name\":\"birth_given_name\",\"displayName\":\"First name given at birth\",\"validations\":{},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"profile\",\"multivalued\":false},{\"name\":\"birth_family_name\",\"displayName\":\"Last name given at birth\",\"validations\":{},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"profile\",\"multivalued\":false},{\"name\":\"gender\",\"displayName\":\"Gender\",\"validations\":{\"options\":{\"options\":[\"0\",\"1\",\"2\",\"9\"]}},\"annotations\":{\"inputOptionLabels\":{\"0\":\"Not known\",\"1\":\"Male\",\"2\":\"Female\",\"9\":\"Not applicable\"},\"inputHelperTextAfter\":\"Select one of the above\",\"inputType\":\"select-radiobuttons\"},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"profile\",\"multivalued\":false},{\"name\":\"gender_as_string\",\"displayName\":\"Gender\",\"validations\":{},\"annotations\":{\"inputTypePlaceholder\":\"gender\",\"inputHelperTextAfter\":\"Or provide your own\"},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"profile\",\"multivalued\":false},{\"name\":\"birthdate\",\"displayName\":\"Birthdate\",\"validations\":{\"iso-date\":{}},\"annotations\":{\"inputType\":\"html5-date\"},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"profile\",\"multivalued\":false},{\"name\":\"age_over_18\",\"displayName\":\"Age over 18\",\"validations\":{\"options\":{\"options\":[\"true\",\"false\"]}},\"annotations\":{\"inputOptionLabels\":{\"true\":\"Yes\",\"false\":\"No\"},\"inputType\":\"select\"},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"profile\",\"multivalued\":false},{\"name\":\"picture\",\"displayName\":\"Picture\",\"validations\":{},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"profile\",\"multivalued\":false},{\"name\":\"street\",\"displayName\":\"Street\",\"validations\":{},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"address\",\"multivalued\":false},{\"name\":\"address_house_number\",\"displayName\":\"House Number\",\"validations\":{},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"address\",\"multivalued\":false},{\"name\":\"locality\",\"displayName\":\"Locality\",\"validations\":{},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"address\",\"multivalued\":false},{\"name\":\"region\",\"displayName\":\"Region\",\"validations\":{},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"address\",\"multivalued\":false},{\"name\":\"postal_code\",\"displayName\":\"Postal Code\",\"validations\":{},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"address\",\"multivalued\":false},{\"name\":\"country\",\"displayName\":\"Country\",\"validations\":{},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"address\",\"multivalued\":false},{\"name\":\"formatted\",\"displayName\":\"Formatted\",\"validations\":{},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"address\",\"multivalued\":false},{\"name\":\"birth_place\",\"displayName\":\"Place\",\"validations\":{},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"birth_place\",\"multivalued\":false},{\"name\":\"birth_city\",\"displayName\":\"City\",\"validations\":{},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"birth_place\",\"multivalued\":false},{\"name\":\"birth_state\",\"displayName\":\"State\",\"validations\":{},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"birth_place\",\"multivalued\":false},{\"name\":\"birth_country\",\"displayName\":\"Country\",\"validations\":{},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"birth_place\",\"multivalued\":false},{\"name\":\"nationality\",\"displayName\":\"Nationality\",\"validations\":{},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"group\":\"profile\",\"multivalued\":false}],\"groups\":[{\"name\":\"user-metadata\",\"displayHeader\":\"User metadata\",\"displayDescription\":\"Attributes, which refer to user metadata\"},{\"name\":\"address\",\"displayHeader\":\"Address\",\"displayDescription\":\"\",\"annotations\":{}},{\"name\":\"credentials\",\"displayHeader\":\"Credentials\",\"displayDescription\":\"\",\"annotations\":{}},{\"name\":\"profile\",\"displayHeader\":\"Profile\",\"displayDescription\":\"\",\"annotations\":{}},{\"name\":\"birth_place\",\"displayHeader\":\"Birth Place\",\"displayDescription\":\"\",\"annotations\":{}}]}" ] } } diff --git a/docker-compose/keycloak/realms/pid-issuer-realm-users-0.json b/docker-compose/keycloak/realms/pid-issuer-realm-users-0.json index 7aeae85a..32c75dbe 100644 --- a/docker-compose/keycloak/realms/pid-issuer-realm-users-0.json +++ b/docker-compose/keycloak/realms/pid-issuer-realm-users-0.json @@ -15,6 +15,9 @@ "gender": [ "1" ], + "gender_as_string": [ + "male" + ], "birthdate": [ "1955-04-12" ], diff --git a/src/main/kotlin/eu/europa/ec/eudi/pidissuer/adapter/out/pid/EncodePidInSdJwtVc.kt b/src/main/kotlin/eu/europa/ec/eudi/pidissuer/adapter/out/pid/EncodePidInSdJwtVc.kt index 16f62876..36b93020 100644 --- a/src/main/kotlin/eu/europa/ec/eudi/pidissuer/adapter/out/pid/EncodePidInSdJwtVc.kt +++ b/src/main/kotlin/eu/europa/ec/eudi/pidissuer/adapter/out/pid/EncodePidInSdJwtVc.kt @@ -39,7 +39,6 @@ import org.slf4j.LoggerFactory import java.time.Clock import java.time.Instant import java.time.ZonedDateTime -import eu.europa.ec.eudi.pidissuer.adapter.out.oauth.OidcGender as OidcGenderAttribute private val log = LoggerFactory.getLogger(EncodePidInSdJwtVc::class.java) @@ -157,7 +156,7 @@ private fun selectivelyDisclosed( address.houseNumber?.let { sd("house_number", it) } } } - pid.gender?.let { sd(OidcGenderAttribute.name, it.toOidGender().value) } + pid.genderAsString?.let { sd(OidcGender.name, it) } pid.nationality?.let { val nationalities = buildJsonArray { add(it.value) } sd(OidcAssuranceNationalities.name, nationalities) @@ -218,15 +217,3 @@ private object Printer { return str } } - -/** - * Converts an [IsoGender] to an [OidcGender]. - */ -private fun IsoGender.toOidGender(): OidcGender = - when (value) { - 0u -> OidcGender("not known") - 1u -> OidcGender.Male - 2u -> OidcGender.Female - 9u -> OidcGender("not applicable") - else -> OidcGender(value.toString()) - } diff --git a/src/main/kotlin/eu/europa/ec/eudi/pidissuer/adapter/out/pid/GetPidDataFromAuthServer.kt b/src/main/kotlin/eu/europa/ec/eudi/pidissuer/adapter/out/pid/GetPidDataFromAuthServer.kt index 58c70831..77626f81 100644 --- a/src/main/kotlin/eu/europa/ec/eudi/pidissuer/adapter/out/pid/GetPidDataFromAuthServer.kt +++ b/src/main/kotlin/eu/europa/ec/eudi/pidissuer/adapter/out/pid/GetPidDataFromAuthServer.kt @@ -124,6 +124,7 @@ class GetPidDataFromAuthServer( address = user.address(), birthDate = user.attributes["birthdate"]?.firstOrNull(), gender = user.attributes["gender"]?.firstOrNull()?.toUInt(), + genderAsString = user.attributes["gender_as_string"]?.firstOrNull(), placeOfBirth = user.birthPlace(), ageOver18 = user.attributes["age_over_18"]?.firstOrNull()?.toBoolean(), picture = null, @@ -174,6 +175,7 @@ class GetPidDataFromAuthServer( residentPostalCode = userInfo.address?.postalCode?.let { PostalCode(it) }, residentHouseNumber = userInfo.address?.houseNumber, gender = userInfo.gender?.let { IsoGender(it) }, + genderAsString = userInfo.genderAsString, nationality = userInfo.nationality?.let { IsoCountry(it) }, ) @@ -194,6 +196,7 @@ private data class UserInfo( @SerialName(OidcAddressClaim.NAME) val address: OidcAddressClaim? = null, @SerialName("birthdate") val birthDate: String? = null, @SerialName("gender") val gender: UInt? = null, + @SerialName("gender_as_string") val genderAsString: String? = null, @SerialName(OidcAssurancePlaceOfBirth.NAME) val placeOfBirth: OidcAssurancePlaceOfBirth? = null, @SerialName("age_over_18") val ageOver18: Boolean? = null, val picture: String? = null, diff --git a/src/main/kotlin/eu/europa/ec/eudi/pidissuer/adapter/out/pid/IssueSdJwtVcPid.kt b/src/main/kotlin/eu/europa/ec/eudi/pidissuer/adapter/out/pid/IssueSdJwtVcPid.kt index f964860d..6bc9ca9e 100644 --- a/src/main/kotlin/eu/europa/ec/eudi/pidissuer/adapter/out/pid/IssueSdJwtVcPid.kt +++ b/src/main/kotlin/eu/europa/ec/eudi/pidissuer/adapter/out/pid/IssueSdJwtVcPid.kt @@ -40,7 +40,6 @@ import java.time.Clock import java.time.Instant import java.time.ZonedDateTime import java.util.* -import eu.europa.ec.eudi.pidissuer.adapter.out.oauth.OidcGender as OidcGenderAttribute val PidSdJwtVcScope: Scope = Scope("eu.europa.ec.eudi.pid_vc_sd_jwt") @@ -76,7 +75,7 @@ internal object Attributes { OidcAssuranceBirthGivenName, OidcAssurancePlaceOfBirth.attribute, OidcAddressClaim.attribute, - OidcGenderAttribute, + OidcGender, OidcAssuranceNationalities, IssuingAuthorityAttribute, DocumentNumberAttribute, diff --git a/src/main/kotlin/eu/europa/ec/eudi/pidissuer/adapter/out/pid/Pid.kt b/src/main/kotlin/eu/europa/ec/eudi/pidissuer/adapter/out/pid/Pid.kt index b1a8fabd..95c9e236 100644 --- a/src/main/kotlin/eu/europa/ec/eudi/pidissuer/adapter/out/pid/Pid.kt +++ b/src/main/kotlin/eu/europa/ec/eudi/pidissuer/adapter/out/pid/Pid.kt @@ -52,24 +52,6 @@ typealias Address = String @JvmInline value class IsoGender(val value: UInt) -/** - * Gender, using a value as defined in OpenID Connect Core 1.0. - */ -@JvmInline -value class OidcGender private constructor(val value: String) { - companion object { - val Male: OidcGender = OidcGender("male") - val Female: OidcGender = OidcGender("female") - - operator fun invoke(value: String): OidcGender = - when (value) { - "male" -> Male - "female" -> Female - else -> OidcGender(value) - } - } -} - typealias Nationality = IsoCountry /** @@ -122,6 +104,7 @@ data class Pid( val residentPostalCode: PostalCode? = null, val residentHouseNumber: String? = null, val gender: IsoGender? = null, + val genderAsString: String? = null, val nationality: Nationality? = null, ) { init {