From e62c3969aaa1fbb8d74017df267430b7861360a9 Mon Sep 17 00:00:00 2001
From: Michael Simon <simon@kit.edu>
Date: Wed, 19 Jun 2024 08:22:20 +0200
Subject: [PATCH] ISSUE-197 make store op work for oauth, display name

---
 .../edu/kit/scc/webreg/entity/UserEntity.java | 11 +++
 .../oauth/client/OAuthUserUpdater.java        |  5 ++
 .../webreg/bean/disco/DiscoveryLoginBean.java | 10 +++
 .../main/resources/msg/messages_de.properties |  4 +-
 .../main/resources/msg/messages_en.properties |  4 +-
 .../main/resources/msg/messages_fr.properties |  4 +-
 bwreg-webapp/src/main/webapp/user/index.xhtml | 68 ++++++++++++++++++-
 7 files changed, 100 insertions(+), 6 deletions(-)

diff --git a/bwreg-entities/src/main/java/edu/kit/scc/webreg/entity/UserEntity.java b/bwreg-entities/src/main/java/edu/kit/scc/webreg/entity/UserEntity.java
index 80ffb5b1..f60d9d39 100644
--- a/bwreg-entities/src/main/java/edu/kit/scc/webreg/entity/UserEntity.java
+++ b/bwreg-entities/src/main/java/edu/kit/scc/webreg/entity/UserEntity.java
@@ -54,6 +54,9 @@ public class UserEntity extends AbstractBaseEntity {
 	@Column(name = "sur_name", length = 256)
 	private String surName;
 
+	@Column(name = "name", length = 1024)
+	private String name;
+
 	@Column(name = "last_login_host", length = 1024)
 	private String lastLoginHost;
 
@@ -296,5 +299,13 @@ public class UserEntity extends AbstractBaseEntity {
 
 	public void setRegistries(Set<RegistryEntity> registries) {
 		this.registries = registries;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
 	}	
 }
diff --git a/bwreg-service/src/main/java/edu/kit/scc/webreg/service/oauth/client/OAuthUserUpdater.java b/bwreg-service/src/main/java/edu/kit/scc/webreg/service/oauth/client/OAuthUserUpdater.java
index 051b69d6..5ef0d5a7 100644
--- a/bwreg-service/src/main/java/edu/kit/scc/webreg/service/oauth/client/OAuthUserUpdater.java
+++ b/bwreg-service/src/main/java/edu/kit/scc/webreg/service/oauth/client/OAuthUserUpdater.java
@@ -353,6 +353,11 @@ public class OAuthUserUpdater extends AbstractUserUpdater<OAuthUserEntity> {
 			else
 				changed |= compareAndChangeProperty(user, "email", null, auditor);
 
+			if (userMap.get("name") != null && (userMap.get("name") instanceof String))
+				changed |= compareAndChangeProperty(user, "name", (String) userMap.get("name"), auditor);
+			else
+				changed |= compareAndChangeProperty(user, "name", null, auditor);
+
 			if ((!withoutUidNumber) && (user.getUidNumber() == null)) {
 				user.setUidNumber(serialDao.nextUidNumber().intValue());
 				logger.info("Setting UID Number {} for user {}", user.getUidNumber(), user.getEppn());
diff --git a/bwreg-webapp/src/main/java/edu/kit/scc/webreg/bean/disco/DiscoveryLoginBean.java b/bwreg-webapp/src/main/java/edu/kit/scc/webreg/bean/disco/DiscoveryLoginBean.java
index 3964c464..ec5cf232 100644
--- a/bwreg-webapp/src/main/java/edu/kit/scc/webreg/bean/disco/DiscoveryLoginBean.java
+++ b/bwreg-webapp/src/main/java/edu/kit/scc/webreg/bean/disco/DiscoveryLoginBean.java
@@ -36,6 +36,7 @@ import edu.kit.scc.webreg.service.SamlSpMetadataService;
 import edu.kit.scc.webreg.service.disco.DiscoveryCacheService;
 import edu.kit.scc.webreg.service.disco.UserProvisionerCachedEntry;
 import edu.kit.scc.webreg.service.identity.UserProvisionerService;
+import edu.kit.scc.webreg.service.oauth.OAuthRpConfigurationService;
 import edu.kit.scc.webreg.service.oidc.OidcClientConfigurationService;
 import edu.kit.scc.webreg.service.oidc.OidcOpConfigurationService;
 import edu.kit.scc.webreg.service.oidc.OidcRpConfigurationService;
@@ -66,6 +67,9 @@ public class DiscoveryLoginBean implements Serializable {
 	@Inject
 	private OidcRpConfigurationService oidcRpService;
 
+	@Inject
+	private OAuthRpConfigurationService oauthRpService;
+
 	@Inject
 	private SessionManager sessionManager;
 
@@ -166,6 +170,12 @@ public class DiscoveryLoginBean implements Serializable {
 					if (op != null) {
 						selected = discoveryCache.getEntry(op.getId());
 						storeIdpSelection = true;
+					} else {
+						OAuthRpConfigurationEntity oauthOp = oauthRpService.fetch(idpId);
+						if (oauthOp != null) {
+							selected = discoveryCache.getEntry(oauthOp.getId());
+							storeIdpSelection = true;
+						}
 					}
 				}
 			}
diff --git a/bwreg-webapp/src/main/resources/msg/messages_de.properties b/bwreg-webapp/src/main/resources/msg/messages_de.properties
index 04a87e4f..58505ef9 100644
--- a/bwreg-webapp/src/main/resources/msg/messages_de.properties
+++ b/bwreg-webapp/src/main/resources/msg/messages_de.properties
@@ -734,6 +734,8 @@ no_registered_services = Noch keine Dienste registriert
 
 not_set = Nicht gesetzt
 
+oauth = OAuth
+
 object = Objekt
 
 oidc = OIDC
@@ -810,7 +812,7 @@ project.accept_invite.accept_txt_post                   = M\u00F6chten Sie die E
 project.accept_invite.accept_txt_pre                    = Sie wurden zur Teilnahme an einem Projekt eingeladen:
 project.accept_invite.already_project_member            = Bereits im Projekt
 project.accept_invite.already_project_member_detail     = Sie nehmen bereits an diesem Projekt teil.
-project.accept_invite.intro                             = Bitte kopieren Sie den Token aus der Einladungs-E-Mail, die Sie vom PI (Project Investigator) erhalten haben.
+project.accept_invite.intro                             = Bitte kopieren Sie den Token aus der Einladungs-E-Mail, die Sie vom PI (Principal Investigator) erhalten haben.
 project.accept_invite.token_already_accepted            = Die Einladung wurde bereits angenommen. Bitte wenden Sie sich an den PI des Projektes um eine neue Einladung zu erstellen.
 project.accept_invite.token_already_accepted_header     = Einladung bereits angenommen
 project.accept_invite.token_already_declined            = Die Einladung wurde bereits abgelehnt. Bitte wenden Sie sich an den PI des Projektes um eine neue Einladung zu erstellen.
diff --git a/bwreg-webapp/src/main/resources/msg/messages_en.properties b/bwreg-webapp/src/main/resources/msg/messages_en.properties
index 8c867dd4..e0389b32 100644
--- a/bwreg-webapp/src/main/resources/msg/messages_en.properties
+++ b/bwreg-webapp/src/main/resources/msg/messages_en.properties
@@ -734,6 +734,8 @@ no_registered_services = No service registered yet.
 
 not_set = Not set
 
+oauth = OAuth
+
 object = Object
 
 oidc = OIDC
@@ -810,7 +812,7 @@ project.accept_invite.accept_txt_post                   = Would you like to acce
 project.accept_invite.accept_txt_pre                    = You were invited to participate in a project:
 project.accept_invite.already_project_member            = Already in project
 project.accept_invite.already_project_member_detail     = You are already participating in this project.
-project.accept_invite.intro                             = Please copy the token from the invitation email you received from the PI (Project Investigator).
+project.accept_invite.intro                             = Please copy the token from the invitation email you received from the PI (Principal Investigator).
 project.accept_invite.token_already_accepted            = The invitation has already been accepted. Please contact the PI of the project to create a new invitation.
 project.accept_invite.token_already_accepted_header     = Invitation already accepted
 project.accept_invite.token_already_declined            = The invitation has already been declined. Please contact the PI of the project to create a new invitation.
diff --git a/bwreg-webapp/src/main/resources/msg/messages_fr.properties b/bwreg-webapp/src/main/resources/msg/messages_fr.properties
index 5dd2583d..61a27e34 100644
--- a/bwreg-webapp/src/main/resources/msg/messages_fr.properties
+++ b/bwreg-webapp/src/main/resources/msg/messages_fr.properties
@@ -734,6 +734,8 @@ no_registered_services = Aucun service enregistr\u00E9 pour le moment.
 
 not_set = Non d\u00E9fini
 
+oauth = OAuth
+
 object = Objet
 
 oidc = OIDC
@@ -810,7 +812,7 @@ project.accept_invite.accept_txt_post                   = Voulez-vous accepter l
 project.accept_invite.accept_txt_pre                    = Ils ont \u00E9t\u00E9 invit\u00E9s \u00E0 participer \u00E0 un projet :
 project.accept_invite.already_project_member            = D\u00E9j\u00E0 dans projet
 project.accept_invite.already_project_member_detail     = Vous participez d\u00E9j\u00E0 \u00E0 ce projet.
-project.accept_invite.intro                             = Veuillez copier le token de l'invitation que vous avez re\u00E7ue de la part du PI (Project Investigator).
+project.accept_invite.intro                             = Veuillez copier le token de l'invitation que vous avez re\u00E7ue de la part du PI (Principal Investigator).
 project.accept_invite.token_already_accepted            = L'invitation a d\u00E9j\u00E0 \u00E9t\u00E9 accept\u00E9e. Veuillez contacter le PI du projet pour cr\u00E9er une nouvelle invitation.
 project.accept_invite.token_already_accepted_header     = Invitation d\u00E9j\u00E0 accept\u00E9e
 project.accept_invite.token_already_declined            = L'invitation a d\u00E9j\u00E0 \u00E9t\u00E9 refus\u00E9e. Veuillez contacter le PI du projet pour cr\u00E9er une nouvelle invitation.
diff --git a/bwreg-webapp/src/main/webapp/user/index.xhtml b/bwreg-webapp/src/main/webapp/user/index.xhtml
index c744ce18..df263683 100644
--- a/bwreg-webapp/src/main/webapp/user/index.xhtml
+++ b/bwreg-webapp/src/main/webapp/user/index.xhtml
@@ -56,8 +56,11 @@
 				<div>#{messages.data_from}: <b>#{userPropertiesBean.user.idp.orgName}</b></div>
 				<br/>
 				<p:panelGrid columns="2" layout="flex" columnClasses="col-12 md:col-3 xl:col-3, col-12 md:col-9 xl:col-9">
-					<h:outputLabel value="#{messages.name}" for="@next" /> 
-					<h:outputText value="#{userPropertiesBean.user.surName}, #{userPropertiesBean.user.givenName}"/>
+					<h:outputLabel value="#{messages.name}" for="@next" />
+					<h:panelGroup>
+						<h:outputText value="#{userPropertiesBean.user.name}" rendered="#{userPropertiesBean.user.name != null}"/>
+						<h:outputText value="#{userPropertiesBean.user.surName}, #{userPropertiesBean.user.givenName}" rendered="#{userPropertiesBean.user.name == null}"/>
+					</h:panelGroup> 
 
 					<h:outputLabel value="#{messages.email_address}" for="@next" /> 
 					<h:outputText value="#{userPropertiesBean.user.email}"/>
@@ -91,7 +94,10 @@
 				<br/>
 				<p:panelGrid columns="2" layout="flex" columnClasses="col-12 md:col-3 xl:col-3, col-12 md:col-9 xl:col-9">
 					<h:outputLabel value="#{messages.name}" for="@next" /> 
-					<h:outputText value="#{userPropertiesBean.user.surName}, #{userPropertiesBean.user.givenName}"/>
+					<h:panelGroup>
+						<h:outputText value="#{userPropertiesBean.user.name}" rendered="#{userPropertiesBean.user.name != null}"/>
+						<h:outputText value="#{userPropertiesBean.user.surName}, #{userPropertiesBean.user.givenName}" rendered="#{userPropertiesBean.user.name == null}"/>
+					</h:panelGroup> 
 
 					<h:outputLabel value="#{messages.email_address}" for="@next" /> 
 					<h:outputText value="#{userPropertiesBean.user.email}"/>
@@ -119,6 +125,43 @@
 				</p:outputPanel>
 			</p:tab>
 
+			<p:tab id="tab1_2" title="#{messages.my_data}" rendered="#{userPropertiesBean.user.class.simpleName eq 'OAuthUserEntity'}">
+				<div>#{messages.my_data_explanation}</div>
+				<div>#{messages.data_from}: <b>#{userPropertiesBean.user.oauthIssuer.displayName}</b></div>
+				<br/>
+				<p:panelGrid columns="2" layout="flex" columnClasses="col-12 md:col-3 xl:col-3, col-12 md:col-9 xl:col-9">
+					<h:outputLabel value="#{messages.name}" for="@next" /> 
+					<h:panelGroup>
+						<h:outputText value="#{userPropertiesBean.user.name}" rendered="#{userPropertiesBean.user.name != null}"/>
+						<h:outputText value="#{userPropertiesBean.user.surName}, #{userPropertiesBean.user.givenName}" rendered="#{userPropertiesBean.user.name == null}"/>
+					</h:panelGroup> 
+
+					<h:outputLabel value="#{messages.email_address}" for="@next" /> 
+					<h:outputText value="#{userPropertiesBean.user.email}"/>
+
+					<h:outputLabel value="#{messages.eppn}" for="@next" /> 
+					<h:outputText value="#{userPropertiesBean.user.eppn}"/>
+
+					<h:outputLabel value="#{messages.subject_id}" for="@next" /> 
+					<h:outputText value="#{userPropertiesBean.user.oauthId}"/>
+
+					<h:outputLabel value="#{messages.uid_number}" for="@next" /> 
+					<h:outputText value="#{userPropertiesBean.user.uidNumber}"/>
+
+					<h:outputLabel value="#{messages.primary_group}" for="@next" /> 
+					<h:outputText value="#{userPropertiesBean.user.primaryGroup.name} (#{userPropertiesBean.user.primaryGroup.gidNumber})"/>
+
+					<h:outputLabel value="#{messages.oidc_op}" for="@next" /> 
+					<h:outputText value="#{userPropertiesBean.user.oauthIssuer.displayName}"/>
+				</p:panelGrid>
+				<p:outputPanel style="margin-top: 1em;" rendered="#{not sessionManager.loggedInUserList.contains(userPropertiesBean.user.id)}">
+					<h:outputText value="#{messages['my_data.unlink_and_delete_account']}: " />
+					<h:link outcome="/user/unlink-and-delete-account.xhtml" value="#{messages['my_data.unlink_and_delete_account_link']}" styleClass="link">
+      					<f:param name="id" value="#{userPropertiesBean.user.id}"/>
+					</h:link>
+				</p:outputPanel>
+			</p:tab>
+
 			<p:tab id="tab2" title="#{messages.shibboleth}" rendered="#{userPropertiesBean.user.class.simpleName eq 'SamlUserEntity'}">
 				<div class="panel">#{messages.my_data_from_saml} #{of:formatDate(userPropertiesBean.user.lastUpdate, 'dd.MM.yyyy HH:mm')}</div>
 				<p:dataTable style="min-width: 500px;" 
@@ -157,6 +200,25 @@
 				</p:dataTable>
 			</p:tab>
 
+			<p:tab id="tab2_2" title="#{messages.oauth}" rendered="#{userPropertiesBean.user.class.simpleName eq 'OAuthUserEntity'}">
+				<div class="panel">#{messages.my_data_from_oidc} #{of:formatDate(userPropertiesBean.user.lastUpdate, 'dd.MM.yyyy HH:mm')}</div>
+				<p:dataTable style="min-width: 500px;" 
+						value="#{userPropertiesBean.user.attributeStore.keySet().toArray()}" var="key">
+					<p:column>
+						<f:facet name="header">
+							<h:outputText value="#{messages.name}" />
+						</f:facet>
+						<h:outputText value="#{key}" style="font-size: 80%;" />
+					</p:column>
+					<p:column>
+						<f:facet name="header">
+							<h:outputText value="#{messages.value}" />
+						</f:facet>
+						<h:outputText value="#{userPropertiesBean.user.attributeStore.get(key)}" />
+					</p:column>						
+				</p:dataTable>
+			</p:tab>
+
 			<p:tab id="tab3" title="#{messages.groups}">
 				<div class="panel">#{messages.my_data_groups}</div>
 				<p:dataTable id="secGroupData" style="min-width: 500px;" 
-- 
GitLab