From e53244a62e22537ea863bc5a802019477f9f46e5 Mon Sep 17 00:00:00 2001 From: jcbarnett <35613458+jcbarnett@users.noreply.github.com> Date: Mon, 4 Apr 2022 21:12:09 -0700 Subject: [PATCH 1/3] Add code owners file. --- .github/CODEOWNERS | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..40b0ee8 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @jcbarnett @kdallan-ol From da34b7c4f7376653a1cb98b5e894ecd11a6d3698 Mon Sep 17 00:00:00 2001 From: jcbarnett <35613458+jcbarnett@users.noreply.github.com> Date: Wed, 7 Jun 2023 16:17:30 -0700 Subject: [PATCH 2/3] Update code owners file. --- .github/CODEOWNERS | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 40b0ee8..e392973 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1 +1,2 @@ -* @jcbarnett @kdallan-ol +* @vshrenikraj @RobEppsQuest @eriktalvi @PavelSedliar + From 93a20aec571761f552e30e4ae58c52073a1f3cd8 Mon Sep 17 00:00:00 2001 From: Will Munslow Date: Tue, 17 Mar 2026 10:38:12 -0700 Subject: [PATCH 3/3] fix: add SerializedName annotations to UserInfo and fix updatedAt type UserInfo fields with snake_case JSON keys (preferred_username, given_name, family_name, updated_at) were silently deserializing as null because Gson performs exact name matching against the camelCase Kotlin property names. Also changes updatedAt from String? to Long? to match the OIDC spec (updated_at is a Unix epoch timestamp), adds ProGuard consumer rules to prevent R8 from stripping Gson model fields, and adds deserialization tests. Supersedes #6, #13, #16. [no-ado] --- .../oidc/appjava/UserInfoFragment.java | 2 +- oneloginoidc/consumer-rules.pro | 6 ++ .../com/onelogin/oidc/userInfo/UserInfo.kt | 12 +++- .../userInfo/UserInfoDeserializationTest.kt | 59 +++++++++++++++++++ 4 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 oneloginoidc/src/test/java/com/onelogin/oidc/userInfo/UserInfoDeserializationTest.kt diff --git a/appjava/src/main/java/com/onelogin/oidc/appjava/UserInfoFragment.java b/appjava/src/main/java/com/onelogin/oidc/appjava/UserInfoFragment.java index 14ea06c..7111723 100644 --- a/appjava/src/main/java/com/onelogin/oidc/appjava/UserInfoFragment.java +++ b/appjava/src/main/java/com/onelogin/oidc/appjava/UserInfoFragment.java @@ -50,7 +50,7 @@ public void onSuccess(UserInfo userInfo) { userId.setText(userInfo.getSub()); email.setText(userInfo.getEmail()); preferredName.setText(userInfo.getPreferredUsername() != null ? userInfo.getPreferredUsername() : "Empty"); - updatedAt.setText(userInfo.getUpdatedAt() != null ? userInfo.getUpdatedAt() : "Empty"); + updatedAt.setText(userInfo.getUpdatedAt() != null ? String.valueOf(userInfo.getUpdatedAt()) : "Empty"); animator.setDisplayedChild(1); } diff --git a/oneloginoidc/consumer-rules.pro b/oneloginoidc/consumer-rules.pro index e69de29..20ef5fe 100644 --- a/oneloginoidc/consumer-rules.pro +++ b/oneloginoidc/consumer-rules.pro @@ -0,0 +1,6 @@ +# Keep Gson model classes used for OIDC response deserialization +-keepclassmembers class com.onelogin.oidc.userInfo.UserInfo { *; } +-keepclassmembers class com.onelogin.oidc.introspect.TokenIntrospection { *; } +-keepclassmembers class com.onelogin.oidc.data.network.ErrorResponse { *; } +-keepattributes Signature +-keepattributes *Annotation* diff --git a/oneloginoidc/src/main/java/com/onelogin/oidc/userInfo/UserInfo.kt b/oneloginoidc/src/main/java/com/onelogin/oidc/userInfo/UserInfo.kt index 787dd9d..f42076b 100644 --- a/oneloginoidc/src/main/java/com/onelogin/oidc/userInfo/UserInfo.kt +++ b/oneloginoidc/src/main/java/com/onelogin/oidc/userInfo/UserInfo.kt @@ -1,12 +1,22 @@ package com.onelogin.oidc.userInfo +import com.google.gson.annotations.SerializedName + data class UserInfo( + @SerializedName("sub") val sub: String, + @SerializedName("email") val email: String, + @SerializedName("preferred_username") val preferredUsername: String?, + @SerializedName("name") val name: String?, - val updatedAt: String?, + @SerializedName("updated_at") + val updatedAt: Long?, + @SerializedName("given_name") val givenName: String?, + @SerializedName("family_name") val familyName: String?, + @SerializedName("groups") val groups: List? ) diff --git a/oneloginoidc/src/test/java/com/onelogin/oidc/userInfo/UserInfoDeserializationTest.kt b/oneloginoidc/src/test/java/com/onelogin/oidc/userInfo/UserInfoDeserializationTest.kt new file mode 100644 index 0000000..c38ba58 --- /dev/null +++ b/oneloginoidc/src/test/java/com/onelogin/oidc/userInfo/UserInfoDeserializationTest.kt @@ -0,0 +1,59 @@ +package com.onelogin.oidc.userInfo + +import com.google.gson.Gson +import junit.framework.TestCase.assertEquals +import junit.framework.TestCase.assertNull +import org.junit.Test + +class UserInfoDeserializationTest { + + private val gson = Gson() + + @Test + fun deserializesSnakeCaseFieldsCorrectly() { + val json = """ + { + "sub": "12345", + "email": "user@example.com", + "preferred_username": "jdoe", + "name": "Jane Doe", + "updated_at": 1710000000, + "given_name": "Jane", + "family_name": "Doe", + "groups": ["admins", "developers"] + } + """.trimIndent() + + val result = gson.fromJson(json, UserInfo::class.java) + + assertEquals("12345", result.sub) + assertEquals("user@example.com", result.email) + assertEquals("jdoe", result.preferredUsername) + assertEquals("Jane Doe", result.name) + assertEquals(1710000000L, result.updatedAt) + assertEquals("Jane", result.givenName) + assertEquals("Doe", result.familyName) + assertEquals(listOf("admins", "developers"), result.groups) + } + + @Test + fun handlesNullOptionalFields() { + val json = """ + { + "sub": "12345", + "email": "user@example.com" + } + """.trimIndent() + + val result = gson.fromJson(json, UserInfo::class.java) + + assertEquals("12345", result.sub) + assertEquals("user@example.com", result.email) + assertNull(result.preferredUsername) + assertNull(result.name) + assertNull(result.updatedAt) + assertNull(result.givenName) + assertNull(result.familyName) + assertNull(result.groups) + } +}