- {!user?.isAuthenticated &&
}
+ {!user?.isAuthenticated &&
}
+ {!user?.isAuthenticated &&
}
{ user?.isAuthenticated &&
}
@@ -92,7 +98,7 @@ export default function App() {
ChatGPT PromptOptimizer
- }/>
+ }/>
}>
}/>
diff --git a/frontend/src/pages/Main/MainPage.tsx b/frontend/src/pages/Main/MainPage.tsx
index 4e23af8..6d21063 100644
--- a/frontend/src/pages/Main/MainPage.tsx
+++ b/frontend/src/pages/Main/MainPage.tsx
@@ -5,14 +5,22 @@ import {MainCard} from "../../components/StandardStyledComponents.tsx";
type Props = {
user?: UserInfo
- login: ()=>void
+ logins: {
+ github: ()=>void,
+ google: ()=>void,
+ }
logout: ()=>void
}
export default function MainPage( props: Readonly ) {
if (!props.user?.isAuthenticated)
- return Please
+ return
+ Please
+
+ or
+
+
if (!props.user.isUser && !props.user.isAdmin)
return
From 3cdbce150d107f0c744cf821b71b96240001736c Mon Sep 17 00:00:00 2001
From: Hendrik Scholtz <135076120+Hendrik2319@users.noreply.github.com>
Date: Thu, 30 Nov 2023 11:24:33 +0100
Subject: [PATCH 03/19] feat: added basic functions for Google login
tests compile, but are not tested
---
.../backend/security/SecurityConfig.java | 17 +++-
.../services/StoredUserInfoService.java | 85 +++++++++++++------
.../security/services/UserService.java | 45 +++++++---
.../src/main/resources/application.properties | 2 +-
.../backend/security/SecurityConfigTest.java | 15 ++--
.../services/StoredUserInfoServiceTest.java | 11 +--
frontend/src/pages/Main/MainPage.tsx | 4 +-
7 files changed, 123 insertions(+), 56 deletions(-)
diff --git a/backend/src/main/java/net/schwarzbaer/spring/promptoptimizer/backend/security/SecurityConfig.java b/backend/src/main/java/net/schwarzbaer/spring/promptoptimizer/backend/security/SecurityConfig.java
index 6f35be1..6744f5f 100644
--- a/backend/src/main/java/net/schwarzbaer/spring/promptoptimizer/backend/security/SecurityConfig.java
+++ b/backend/src/main/java/net/schwarzbaer/spring/promptoptimizer/backend/security/SecurityConfig.java
@@ -3,6 +3,8 @@
import net.schwarzbaer.spring.promptoptimizer.backend.security.models.Role;
import net.schwarzbaer.spring.promptoptimizer.backend.security.models.StoredUserInfo;
import net.schwarzbaer.spring.promptoptimizer.backend.security.services.StoredUserInfoService;
+import net.schwarzbaer.spring.promptoptimizer.backend.security.services.UserService;
+
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -92,14 +94,21 @@ DefaultOAuth2User configureUserData(StoredUserInfoService storedUserInfoService,
String registrationId = request.getClientRegistration().getRegistrationId();
String userDbId = registrationId + user.getName();
- newAttributes.put("UserDbId", userDbId);
+
+ System.out.println("User: ["+ registrationId +"] "+ user.getName());
+ newAttributes.forEach((key, value) ->
+ System.out.println(" ["+key+"]: "+value+ (value==null ? "" : " { Class:"+value.getClass().getName()+" }"))
+ );
+
+ newAttributes.put(UserService.ATTR_USER_DB_ID, userDbId);
+ newAttributes.put(UserService.ATTR_REGISTRATION_ID, registrationId);
Role role = null;
final Optional storedUserInfoOpt = storedUserInfoService.getUserById(userDbId);
if (storedUserInfoOpt.isPresent()) {
final StoredUserInfo storedUserInfo = storedUserInfoOpt.get();
role = storedUserInfo.role();
- storedUserInfoService.updateUserIfNeeded(storedUserInfo, newAttributes);
+ storedUserInfoService.updateUserIfNeeded(storedUserInfo, registrationId, newAttributes);
}
if (role==null && initialAdmin.equals(userDbId))
@@ -109,10 +118,10 @@ DefaultOAuth2User configureUserData(StoredUserInfoService storedUserInfoService,
role = Role.UNKNOWN_ACCOUNT;
if (storedUserInfoOpt.isEmpty())
- storedUserInfoService.addUser(role, registrationId, newAttributes);
+ storedUserInfoService.addUser(userDbId, registrationId, role, newAttributes);
newAuthorities.add(new SimpleGrantedAuthority(role.getLong()));
- return new DefaultOAuth2User(newAuthorities, newAttributes, "id");
+ return new DefaultOAuth2User(newAuthorities, newAttributes, UserService.ATTR_USER_DB_ID);
}
}
diff --git a/backend/src/main/java/net/schwarzbaer/spring/promptoptimizer/backend/security/services/StoredUserInfoService.java b/backend/src/main/java/net/schwarzbaer/spring/promptoptimizer/backend/security/services/StoredUserInfoService.java
index f686207..a5981b2 100644
--- a/backend/src/main/java/net/schwarzbaer/spring/promptoptimizer/backend/security/services/StoredUserInfoService.java
+++ b/backend/src/main/java/net/schwarzbaer/spring/promptoptimizer/backend/security/services/StoredUserInfoService.java
@@ -26,35 +26,66 @@ public Optional getUserById(String userDbId) {
return storedUserInfoRepository.findById(userDbId);
}
- public void addUser(Role role, String registrationId, Map newAttributes) {
- storedUserInfoRepository.save(new StoredUserInfo(
- Objects.toString(newAttributes.get(UserService.ATTR_USER_DB_ID ), null),
- role,
- registrationId,
- Objects.toString(newAttributes.get(UserService.ATTR_ORIGINAL_ID), null),
- Objects.toString(newAttributes.get(UserService.ATTR_LOGIN ), null),
- Objects.toString(newAttributes.get(UserService.ATTR_NAME ), null),
- Objects.toString(newAttributes.get(UserService.ATTR_LOCATION ), null),
- Objects.toString(newAttributes.get(UserService.ATTR_URL ), null),
- Objects.toString(newAttributes.get(UserService.ATTR_AVATAR_URL ), null),
- null
- ));
+ public void addUser(@NonNull String userDbId, String registrationId, @NonNull Role role, @NonNull Map newAttributes) {
+ StoredUserInfo storedUserInfo = null;
+
+ if (registrationId!=null)
+ switch (registrationId) {
+ case "github":
+ storedUserInfo = new StoredUserInfo(
+ userDbId,
+ role,
+ registrationId,
+ Objects.toString(newAttributes.get(UserService.ATTR_ORIGINAL_ID), null),
+ Objects.toString(newAttributes.get(UserService.ATTR_LOGIN ), null),
+ Objects.toString(newAttributes.get(UserService.ATTR_NAME ), null),
+ Objects.toString(newAttributes.get(UserService.ATTR_LOCATION ), null),
+ Objects.toString(newAttributes.get(UserService.ATTR_URL ), null),
+ Objects.toString(newAttributes.get(UserService.ATTR_AVATAR_URL ), null),
+ null
+ );
+ break;
+ }
+
+ if (storedUserInfo==null)
+ storedUserInfo = new StoredUserInfo(
+ userDbId,
+ role,
+ registrationId,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null
+ );
+
+ storedUserInfoRepository.save(storedUserInfo);
}
- public void updateUserIfNeeded(StoredUserInfo storedUserInfo, Map newAttributes) {
- StoredUserInfo updatedUserInfo = new StoredUserInfo(
- storedUserInfo.id(),
- storedUserInfo.role(),
- storedUserInfo.registrationId(),
- Objects.toString(newAttributes.get(UserService.ATTR_ORIGINAL_ID), storedUserInfo.originalId()),
- Objects.toString(newAttributes.get(UserService.ATTR_LOGIN ), storedUserInfo.login ()),
- Objects.toString(newAttributes.get(UserService.ATTR_NAME ), storedUserInfo.name ()),
- Objects.toString(newAttributes.get(UserService.ATTR_LOCATION ), storedUserInfo.location ()),
- Objects.toString(newAttributes.get(UserService.ATTR_URL ), storedUserInfo.url ()),
- Objects.toString(newAttributes.get(UserService.ATTR_AVATAR_URL ), storedUserInfo.avatar_url()),
- storedUserInfo.denialReason()
- );
- if (!updatedUserInfo.equals(storedUserInfo))
+ public void updateUserIfNeeded(StoredUserInfo storedUserInfo, String registrationId, Map newAttributes) {
+ StoredUserInfo updatedUserInfo = null;
+
+ if (registrationId!=null)
+ switch (registrationId) {
+ case "github":
+ updatedUserInfo = new StoredUserInfo(
+ storedUserInfo.id(),
+ storedUserInfo.role(),
+ storedUserInfo.registrationId(),
+ Objects.toString(newAttributes.get(UserService.ATTR_ORIGINAL_ID), storedUserInfo.originalId()),
+ Objects.toString(newAttributes.get(UserService.ATTR_LOGIN ), storedUserInfo.login ()),
+ Objects.toString(newAttributes.get(UserService.ATTR_NAME ), storedUserInfo.name ()),
+ Objects.toString(newAttributes.get(UserService.ATTR_LOCATION ), storedUserInfo.location ()),
+ Objects.toString(newAttributes.get(UserService.ATTR_URL ), storedUserInfo.url ()),
+ Objects.toString(newAttributes.get(UserService.ATTR_AVATAR_URL ), storedUserInfo.avatar_url()),
+ storedUserInfo.denialReason()
+ );
+ break;
+ }
+
+ if (updatedUserInfo!=null && !updatedUserInfo.equals(storedUserInfo))
storedUserInfoRepository.save(updatedUserInfo);
}
diff --git a/backend/src/main/java/net/schwarzbaer/spring/promptoptimizer/backend/security/services/UserService.java b/backend/src/main/java/net/schwarzbaer/spring/promptoptimizer/backend/security/services/UserService.java
index b7060fa..cb099bc 100644
--- a/backend/src/main/java/net/schwarzbaer/spring/promptoptimizer/backend/security/services/UserService.java
+++ b/backend/src/main/java/net/schwarzbaer/spring/promptoptimizer/backend/security/services/UserService.java
@@ -16,8 +16,10 @@
@RequiredArgsConstructor
public class UserService {
+ public static final String ATTR_USER_DB_ID = "UserDbId";
+ public static final String ATTR_REGISTRATION_ID = "RegistrationId";
+
static final String ATTR_ORIGINAL_ID = "id";
- static final String ATTR_USER_DB_ID = "UserDbId";
static final String ATTR_LOGIN = "login";
static final String ATTR_NAME = "name";
static final String ATTR_LOCATION = "location";
@@ -37,22 +39,43 @@ public class UserService {
// if (principal!=null) DEBUG_OUT.println("Principal: "+principal.getClass()+" -> "+principal);
if (principal instanceof OAuth2AuthenticatedPrincipal user) {
-// DEBUG_OUT.println("User Attributes:");
-// user.getAttributes().forEach((key, value) ->
-// DEBUG_OUT.println(" ["+key+"]: "+value+ (value==null ? "" : " { Class:"+value.getClass().getName()+" }"))
-// );
+ /*
+ DEBUG_OUT.println("User Attributes:");
+ user.getAttributes().forEach((key, value) ->
+ DEBUG_OUT.println(" ["+key+"]: "+value+ (value==null ? "" : " { Class:"+value.getClass().getName()+" }"))
+ );
+ */
+
+ String registrationId = Objects.toString( user.getAttribute(ATTR_REGISTRATION_ID), null );
+
+ if (registrationId!=null)
+ switch (registrationId) {
+ case "github":
+ return new UserInfo(
+ true,
+ hasRole(user, Role.USER),
+ hasRole(user, Role.ADMIN),
+ Objects.toString( user.getAttribute(ATTR_ORIGINAL_ID), null ),
+ Objects.toString( user.getAttribute(ATTR_USER_DB_ID ), null ),
+ Objects.toString( user.getAttribute(ATTR_LOGIN ), null ),
+ Objects.toString( user.getAttribute(ATTR_NAME ), null ),
+ Objects.toString( user.getAttribute(ATTR_LOCATION ), null ),
+ Objects.toString( user.getAttribute(ATTR_URL ), null ),
+ Objects.toString( user.getAttribute(ATTR_AVATAR_URL ), null )
+ );
+ }
return new UserInfo(
true,
hasRole(user, Role.USER),
hasRole(user, Role.ADMIN),
- Objects.toString( user.getAttribute(ATTR_ORIGINAL_ID), null ),
+ null,
Objects.toString( user.getAttribute(ATTR_USER_DB_ID ), null ),
- Objects.toString( user.getAttribute(ATTR_LOGIN ), null ),
- Objects.toString( user.getAttribute(ATTR_NAME ), null ),
- Objects.toString( user.getAttribute(ATTR_LOCATION ), null ),
- Objects.toString( user.getAttribute(ATTR_URL ), null ),
- Objects.toString( user.getAttribute(ATTR_AVATAR_URL ), null )
+ null,
+ null,
+ null,
+ null,
+ null
);
}
diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties
index f304dbf..89711df 100644
--- a/backend/src/main/resources/application.properties
+++ b/backend/src/main/resources/application.properties
@@ -8,5 +8,5 @@ spring.security.oauth2.client.registration.github.client-secret=${OAUTH_GITHUB_C
spring.security.oauth2.client.registration.github.scope=none
spring.security.oauth2.client.registration.google.client-id=${OAUTH_GOOGLE_CLIENT_ID}
spring.security.oauth2.client.registration.google.client-secret=${OAUTH_GOOGLE_CLIENT_SECRET}
-spring.security.oauth2.client.registration.google.scope=none
+spring.security.oauth2.client.registration.google.scope=https://www.googleapis.com/auth/userinfo.email, https://www.googleapis.com/auth/userinfo.profile
app.security.initial-admin=${INITIAL_ADMIN}
\ No newline at end of file
diff --git a/backend/src/test/java/net/schwarzbaer/spring/promptoptimizer/backend/security/SecurityConfigTest.java b/backend/src/test/java/net/schwarzbaer/spring/promptoptimizer/backend/security/SecurityConfigTest.java
index 38772fe..193b9fb 100644
--- a/backend/src/test/java/net/schwarzbaer/spring/promptoptimizer/backend/security/SecurityConfigTest.java
+++ b/backend/src/test/java/net/schwarzbaer/spring/promptoptimizer/backend/security/SecurityConfigTest.java
@@ -10,6 +10,7 @@
import org.junit.jupiter.params.provider.ArgumentsSource;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.springframework.lang.NonNull;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService;
@@ -18,6 +19,7 @@
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Optional;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -46,7 +48,7 @@ void setup() {
@Test void whenConfigureUserData_isCalledWithEmptyDbByAnotherUser() {
whenConfigureUserData_isCalledWithEmptyDb("UserID", Role.UNKNOWN_ACCOUNT);
}
- private void whenConfigureUserData_isCalledWithEmptyDb(String userID, Role expectedRole) {
+ private void whenConfigureUserData_isCalledWithEmptyDb(String userID, @NonNull Role expectedRole) {
//Given
when(delegate.loadUser(oAuth2UserRequest)).thenReturn(new DefaultOAuth2User(
List.of(), Map.of("id", userID), "id"
@@ -59,13 +61,13 @@ private void whenConfigureUserData_isCalledWithEmptyDb(String userID, Role expec
DefaultOAuth2User actual = securityConfig.configureUserData(storedUserInfoService, delegate, oAuth2UserRequest);
//Then
- Map newAttributes = Map.of(
+ Map newAttributes = Objects.requireNonNull( Map.of(
"id", userID,
"UserDbId", "RegistrationId" + userID
- );
+ ) );
verify(storedUserInfoService).getUserById("RegistrationId" + userID);
- verify(storedUserInfoService, times(0)).updateUserIfNeeded(any(),any());
- verify(storedUserInfoService).addUser(expectedRole, "RegistrationId", newAttributes);
+ verify(storedUserInfoService, times(0)).updateUserIfNeeded(any(),any(),any());
+ verify(storedUserInfoService).addUser("RegistrationId" + userID, "RegistrationId", expectedRole, newAttributes);
DefaultOAuth2User expected = new DefaultOAuth2User(
List.of(new SimpleGrantedAuthority(expectedRole.getLong())),
newAttributes,
@@ -96,9 +98,10 @@ void whenConfigureUserData_isCalledStoredUser(Role expectedRole) {
verify(storedUserInfoService).getUserById("RegistrationId" + "userID");
verify(storedUserInfoService).updateUserIfNeeded(
createStoredUserInfo(expectedRole),
+ "RegistrationId",
newAttributes
);
- verify(storedUserInfoService, times(0)).addUser(any(),any(),any());
+ verify(storedUserInfoService, times(0)).addUser(any(),any(),any(),any());
DefaultOAuth2User expected = new DefaultOAuth2User(
List.of(new SimpleGrantedAuthority(expectedRole.getLong())),
newAttributes,
diff --git a/backend/src/test/java/net/schwarzbaer/spring/promptoptimizer/backend/security/services/StoredUserInfoServiceTest.java b/backend/src/test/java/net/schwarzbaer/spring/promptoptimizer/backend/security/services/StoredUserInfoServiceTest.java
index d33d9b6..3c6a647 100644
--- a/backend/src/test/java/net/schwarzbaer/spring/promptoptimizer/backend/security/services/StoredUserInfoServiceTest.java
+++ b/backend/src/test/java/net/schwarzbaer/spring/promptoptimizer/backend/security/services/StoredUserInfoServiceTest.java
@@ -16,6 +16,7 @@
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
+import java.util.Objects;
import java.util.Optional;
import static org.junit.jupiter.api.Assertions.*;
@@ -87,7 +88,7 @@ void whenGetUserById_getsKnownId_returnsOptionalWithData() {
void whenAddUser_isCalled() {
// Given
// When
- Map attrs = Map.of(
+ Map attrs = Objects.requireNonNull( Map.of(
"UserDbId" , "RegistrationIDuserID1",
"id" , "userID1" ,
"login" , "login1" ,
@@ -95,8 +96,8 @@ void whenAddUser_isCalled() {
"location" , "location1",
"html_url" , "url1" ,
"avatar_url", "avatarUrl1"
- );
- storedUserInfoService.addUser(Role.UNKNOWN_ACCOUNT, "RegistrationID", attrs);
+ ) );
+ storedUserInfoService.addUser("RegistrationIDuserID1", "RegistrationID", Role.UNKNOWN_ACCOUNT, attrs);
// Then
verify(storedUserInfoRepository).save(new StoredUserInfo(
@@ -128,7 +129,7 @@ void whenUpdateUserIfNeeded_isCalledWithNewData() {
"userID1", "login2",
"name2", "location2", "url2", "avatarUrl2", "reason1"
);
- storedUserInfoService.updateUserIfNeeded(storedUserInfo, attrs);
+ storedUserInfoService.updateUserIfNeeded(storedUserInfo, "RegistrationID", attrs);
// Then
verify(storedUserInfoRepository).save(new StoredUserInfo(
@@ -161,7 +162,7 @@ private void whenUpdateUserIfNeeded_isCalled_andNothingIsWrittenToRepo(Map ) {
if (!props.user?.isAuthenticated)
return
- Please
+ {"Please "}
- or
+ {" or "}
From 1981b7a3fc8809ef513fdb71e483ad4a64181a16 Mon Sep 17 00:00:00 2001
From: Hendrik Scholtz <135076120+Hendrik2319@users.noreply.github.com>
Date: Thu, 30 Nov 2023 12:27:23 +0100
Subject: [PATCH 04/19] feat: added field definition for user data from Google
---
.../backend/security/SecurityConfig.java | 23 ++---
.../backend/security/UserAttributes.java | 89 +++++++++++++++++++
.../services/StoredUserInfoService.java | 83 ++++++-----------
.../security/services/UserService.java | 62 +++----------
4 files changed, 141 insertions(+), 116 deletions(-)
create mode 100644 backend/src/main/java/net/schwarzbaer/spring/promptoptimizer/backend/security/UserAttributes.java
diff --git a/backend/src/main/java/net/schwarzbaer/spring/promptoptimizer/backend/security/SecurityConfig.java b/backend/src/main/java/net/schwarzbaer/spring/promptoptimizer/backend/security/SecurityConfig.java
index 6744f5f..e63275d 100644
--- a/backend/src/main/java/net/schwarzbaer/spring/promptoptimizer/backend/security/SecurityConfig.java
+++ b/backend/src/main/java/net/schwarzbaer/spring/promptoptimizer/backend/security/SecurityConfig.java
@@ -1,9 +1,12 @@
package net.schwarzbaer.spring.promptoptimizer.backend.security;
-import net.schwarzbaer.spring.promptoptimizer.backend.security.models.Role;
-import net.schwarzbaer.spring.promptoptimizer.backend.security.models.StoredUserInfo;
-import net.schwarzbaer.spring.promptoptimizer.backend.security.services.StoredUserInfoService;
-import net.schwarzbaer.spring.promptoptimizer.backend.security.services.UserService;
+import static org.springframework.security.config.Customizer.withDefaults;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
@@ -24,9 +27,9 @@
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.HttpStatusEntryPoint;
-import java.util.*;
-
-import static org.springframework.security.config.Customizer.withDefaults;
+import net.schwarzbaer.spring.promptoptimizer.backend.security.models.Role;
+import net.schwarzbaer.spring.promptoptimizer.backend.security.models.StoredUserInfo;
+import net.schwarzbaer.spring.promptoptimizer.backend.security.services.StoredUserInfoService;
@Configuration
@EnableWebSecurity
@@ -100,8 +103,8 @@ DefaultOAuth2User configureUserData(StoredUserInfoService storedUserInfoService,
System.out.println(" ["+key+"]: "+value+ (value==null ? "" : " { Class:"+value.getClass().getName()+" }"))
);
- newAttributes.put(UserService.ATTR_USER_DB_ID, userDbId);
- newAttributes.put(UserService.ATTR_REGISTRATION_ID, registrationId);
+ newAttributes.put(UserAttributes.ATTR_USER_DB_ID, userDbId);
+ newAttributes.put(UserAttributes.ATTR_REGISTRATION_ID, registrationId);
Role role = null;
final Optional storedUserInfoOpt = storedUserInfoService.getUserById(userDbId);
@@ -121,7 +124,7 @@ DefaultOAuth2User configureUserData(StoredUserInfoService storedUserInfoService,
storedUserInfoService.addUser(userDbId, registrationId, role, newAttributes);
newAuthorities.add(new SimpleGrantedAuthority(role.getLong()));
- return new DefaultOAuth2User(newAuthorities, newAttributes, UserService.ATTR_USER_DB_ID);
+ return new DefaultOAuth2User(newAuthorities, newAttributes, UserAttributes.ATTR_USER_DB_ID);
}
}
diff --git a/backend/src/main/java/net/schwarzbaer/spring/promptoptimizer/backend/security/UserAttributes.java b/backend/src/main/java/net/schwarzbaer/spring/promptoptimizer/backend/security/UserAttributes.java
new file mode 100644
index 0000000..f3cc6fb
--- /dev/null
+++ b/backend/src/main/java/net/schwarzbaer/spring/promptoptimizer/backend/security/UserAttributes.java
@@ -0,0 +1,89 @@
+package net.schwarzbaer.spring.promptoptimizer.backend.security;
+
+import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+import org.springframework.lang.NonNull;
+import org.springframework.security.oauth2.core.OAuth2AuthenticatedPrincipal;
+
+public class UserAttributes {
+
+ public static final String ATTR_USER_DB_ID = "UserDbId";
+ public static final String ATTR_REGISTRATION_ID = "RegistrationId";
+ public static final String REGID_GITHUB = "github";
+ public static final String REGID_GOOGLE = "google";
+
+ public enum Field {
+ ORIGINAL_ID,
+ LOGIN ,
+ NAME ,
+ LOCATION ,
+ URL ,
+ AVATAR_URL ,
+ }
+
+
+ private static final Map> config = createConfig();
+
+ private static Map> createConfig() {
+ HashMap> newConfig = new HashMap<>();
+ EnumMap fields;
+
+ newConfig.put(REGID_GITHUB, fields = new EnumMap<>(Field.class));
+ fields.put( Field.ORIGINAL_ID, "id" );
+ fields.put( Field.LOGIN , "login" );
+ fields.put( Field.NAME , "name" );
+ fields.put( Field.LOCATION , "location" );
+ fields.put( Field.URL , "html_url" );
+ fields.put( Field.AVATAR_URL , "avatar_url" );
+
+ newConfig.put(REGID_GOOGLE, fields = new EnumMap<>(Field.class));
+ fields.put( Field.ORIGINAL_ID, "sub" );
+ fields.put( Field.LOGIN , "email" );
+ fields.put( Field.NAME , "name" );
+ fields.put( Field.LOCATION , "locale" );
+ // fields.put( Field.URL , "html_url" );
+ fields.put( Field.AVATAR_URL , "picture" );
+
+ return newConfig;
+ }
+
+
+ public static String getAttribute( @NonNull OAuth2AuthenticatedPrincipal user, @NonNull String field, String nullDefault )
+ {
+ return Objects.toString( user.getAttribute(field), nullDefault );
+ }
+
+ public static String getAttribute( @NonNull Map userAttributes, @NonNull String field, String nullDefault )
+ {
+ return Objects.toString( userAttributes.get(field), nullDefault );
+ }
+
+ public static String getAttribute( @NonNull OAuth2AuthenticatedPrincipal user, String registrationId, Field field, String nullDefault )
+ {
+ return getAttribute( user, registrationId, field, nullDefault, UserAttributes::getAttribute );
+ }
+
+ public static String getAttribute( @NonNull Map userAttributes, String registrationId, Field field, String nullDefault )
+ {
+ return getAttribute( userAttributes, registrationId, field, nullDefault, UserAttributes::getAttribute );
+ }
+
+
+ private interface GetAttributeFunction