Skip to content
Snippets Groups Projects
Commit 38e7d072 authored by Michael Simon's avatar Michael Simon
Browse files

ISSUE-197 add oauth for account linking pages

parent c34baee4
No related branches found
No related tags found
No related merge requests found
...@@ -154,10 +154,10 @@ public class OAuthClientCallbackServiceImpl implements OAuthClientCallbackServic ...@@ -154,10 +154,10 @@ public class OAuthClientCallbackServiceImpl implements OAuthClientCallbackServic
// Store OIDC Data temporarily in Session // Store OIDC Data temporarily in Session
logger.debug("Storing relevant Oidc data in session"); logger.debug("Storing relevant Oidc data in session");
session.setSubjectId(userId); session.setOauthId(userId);
session.setAttributeMap(attributeMap); session.setAttributeMap(attributeMap);
httpServletResponse.sendRedirect("/user/connect-account-oidc.xhtml"); httpServletResponse.sendRedirect("/user/connect-account-oauth.xhtml");
return; return;
} }
} }
......
...@@ -32,6 +32,7 @@ import edu.kit.scc.webreg.entity.UserEntity; ...@@ -32,6 +32,7 @@ import edu.kit.scc.webreg.entity.UserEntity;
import edu.kit.scc.webreg.entity.UserEntity_; import edu.kit.scc.webreg.entity.UserEntity_;
import edu.kit.scc.webreg.entity.UserProvisionerEntity; import edu.kit.scc.webreg.entity.UserProvisionerEntity;
import edu.kit.scc.webreg.entity.identity.IdentityEntity; import edu.kit.scc.webreg.entity.identity.IdentityEntity;
import edu.kit.scc.webreg.entity.oauth.OAuthRpConfigurationEntity;
import edu.kit.scc.webreg.entity.oidc.OidcRpConfigurationEntity; import edu.kit.scc.webreg.entity.oidc.OidcRpConfigurationEntity;
import edu.kit.scc.webreg.entity.oidc.OidcUserEntity; import edu.kit.scc.webreg.entity.oidc.OidcUserEntity;
import edu.kit.scc.webreg.service.SamlSpConfigurationService; import edu.kit.scc.webreg.service.SamlSpConfigurationService;
...@@ -144,6 +145,14 @@ public class ConnectAccountBean implements Serializable { ...@@ -144,6 +145,14 @@ public class ConnectAccountBean implements Serializable {
} catch (IOException e) { } catch (IOException e) {
messageGenerator.addErrorMessage("Ein Fehler ist aufgetreten", e.toString()); messageGenerator.addErrorMessage("Ein Fehler ist aufgetreten", e.toString());
} }
} else if (userProvisioner instanceof OAuthRpConfigurationEntity) {
OAuthRpConfigurationEntity rp = (OAuthRpConfigurationEntity) userProvisioner;
sessionManager.setOauthRelyingPartyId(rp.getId());
try {
externalContext.redirect("/rpoauth/login");
} catch (IOException e) {
messageGenerator.addErrorMessage("Ein Fehler ist aufgetreten", e.toString());
}
} else { } else {
messageGenerator.addWarningMessage("Keine Auswahl getroffen", "Bitte wählen Sie Ihre Heimatorganisation"); messageGenerator.addWarningMessage("Keine Auswahl getroffen", "Bitte wählen Sie Ihre Heimatorganisation");
} }
......
/*******************************************************************************
* Copyright (c) 2014 Michael Simon.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*
* Contributors:
* Michael Simon - initial
******************************************************************************/
package edu.kit.scc.webreg.bean;
import static edu.kit.scc.webreg.dao.ops.PaginateBy.unlimited;
import static edu.kit.scc.webreg.dao.ops.RqlExpressions.equal;
import static edu.kit.scc.webreg.dao.ops.SortBy.ascendingBy;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.slf4j.Logger;
import edu.kit.scc.webreg.entity.SamlUserEntity_;
import edu.kit.scc.webreg.entity.UserEntity;
import edu.kit.scc.webreg.entity.UserEntity_;
import edu.kit.scc.webreg.entity.identity.IdentityEntity;
import edu.kit.scc.webreg.entity.oauth.OAuthRpConfigurationEntity;
import edu.kit.scc.webreg.entity.oauth.OAuthUserEntity;
import edu.kit.scc.webreg.exc.UserUpdateException;
import edu.kit.scc.webreg.service.UserService;
import edu.kit.scc.webreg.service.identity.IdentityService;
import edu.kit.scc.webreg.service.oauth.OAuthRpConfigurationService;
import edu.kit.scc.webreg.service.oauth.client.OAuthUserCreateService;
import edu.kit.scc.webreg.session.SessionManager;
import edu.kit.scc.webreg.util.FacesMessageGenerator;
import jakarta.faces.event.ComponentSystemEvent;
import jakarta.faces.view.ViewScoped;
import jakarta.inject.Inject;
import jakarta.inject.Named;
@Named
@ViewScoped
public class ConnectAccountOAuthBean implements Serializable {
private static final long serialVersionUID = 1L;
@Inject
private Logger logger;
@Inject
private UserService userService;
@Inject
private IdentityService identityService;
@Inject
private SessionManager sessionManager;
@Inject
private FacesMessageGenerator messageGenerator;
@Inject
private OAuthRpConfigurationService rpConfigService;
@Inject
private OAuthUserCreateService userCreateService;
private IdentityEntity identity;
private List<UserEntity> userList;
private OAuthRpConfigurationEntity rpConfig;
private String pin;
private Boolean errorState = false;
private Map<String, String> printableAttributesMap;
private Map<String, String> unprintableAttributesMap;
private List<String> printableAttributesList;
private OAuthUserEntity entity;
public void preRenderView(ComponentSystemEvent ev) {
if (identity == null) {
identity = identityService.fetch(sessionManager.getIdentityId());
}
if (sessionManager.getOauthRelyingPartyId() == null) {
errorState = true;
messageGenerator.addResolvedErrorMessage("page-not-directly-accessible",
"page-not-directly-accessible-text", true);
return;
}
rpConfig = rpConfigService.fetch(sessionManager.getOauthRelyingPartyId());
if (rpConfig == null) {
errorState = true;
messageGenerator.addResolvedErrorMessage("page-not-directly-accessible",
"page-not-directly-accessible-text", true);
return;
}
printableAttributesMap = new HashMap<String, String>();
unprintableAttributesMap = new HashMap<String, String>();
printableAttributesList = new ArrayList<String>();
try {
entity = userCreateService.preCreateUser(rpConfig.getId(), sessionManager.getLocale(),
sessionManager.getAttributeMap());
} catch (UserUpdateException e) {
errorState = true;
messageGenerator.addResolvedErrorMessage("missing-mandatory-attributes", e.getMessage(), true);
return;
}
printableAttributesList.add("subject_id");
printableAttributesMap.put("subject_id", entity.getOauthId());
printableAttributesList.add("issuer");
printableAttributesMap.put("issuer", rpConfig.getServiceUrl());
printableAttributesList.add("name");
printableAttributesMap.put("name", entity.getName());
@SuppressWarnings("unchecked")
HashMap<String, Object> userMap = (HashMap<String, Object>) sessionManager.getAttributeMap().get("user").get(0);
for (Entry<String, Object> entry : userMap.entrySet()) {
if (entry.getValue() != null)
unprintableAttributesMap.put(entry.getKey(), entry.getValue().toString());
}
}
public String save() {
try {
entity = userCreateService.createAndLinkUser(identity, entity, sessionManager.getAttributeMap(), null);
entity = userCreateService.postCreateUser(entity, sessionManager.getAttributeMap(), "user-" + entity.getId());
} catch (UserUpdateException e) {
logger.warn("An error occured whilst creating user", e);
messageGenerator.addResolvedErrorMessage("error_msg", e.toString(), false);
return null;
}
return "/user/index.xhtml";
}
public IdentityEntity getIdentity() {
return identity;
}
public List<UserEntity> getUserList() {
if (userList == null)
userList = userService.findAllEagerly(unlimited(), Arrays.asList(ascendingBy(UserEntity_.id)),
equal(UserEntity_.identity, getIdentity()), UserEntity_.genericStore, UserEntity_.attributeStore,
SamlUserEntity_.idp);
return userList;
}
public String getPin() {
return pin;
}
public void setPin(String pin) {
this.pin = pin;
}
public Map<String, String> getPrintableAttributesMap() {
return printableAttributesMap;
}
public List<String> getPrintableAttributesList() {
return printableAttributesList;
}
public OAuthUserEntity getEntity() {
return entity;
}
public Map<String, String> getUnprintableAttributesMap() {
return unprintableAttributesMap;
}
public Boolean getErrorState() {
return errorState;
}
}
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="jakarta.faces.core"
xmlns:h="jakarta.faces.html"
xmlns:ui="jakarta.faces.facelets"
xmlns:bw="http://www.scc.kit.edu/bwfacelets"
xmlns:p="http://primefaces.org/ui"
xmlns:of="http://omnifaces.org/functions">
<head>
<title></title>
</head>
<body>
<f:view>
<f:metadata>
<f:event type="jakarta.faces.event.PreRenderViewEvent"
listener="#{connectAccountOAuthBean.preRenderView}" />
</f:metadata>
<ui:composition template="/template/default.xhtml">
<ui:param name="title" value="#{messages.title}"/>
<ui:define name="content">
<h:form id="form" prependId="false" class="full">
<h3><h:outputText value="#{messages['connect_account.heading']}" /></h3>
<div>
<h:outputText value="#{messages['connect_account.intro2']}" />
</div>
<p:messages id="messageBox" showDetail="true" />
<div class="text">
<ul>
<ui:repeat var="user" value="#{connectAccountOAuthBean.userList}">
<li>
<h:panelGroup rendered="#{user.class.simpleName eq 'SamlUserEntity'}">
<h:outputText value="#{user.idp.displayName}" />
<h:outputText value=" (#{messages.currently_logged_id})" rendered="#{sessionManager.loggedInUserList.contains(user.id)}"/>
</h:panelGroup>
<h:panelGroup rendered="#{user.class.simpleName eq 'OidcUserEntity'}">
<h:outputText value="#{user.issuer.displayName}" />
<h:outputText value=" (#{messages.currently_logged_id})" rendered="#{sessionManager.loggedInUserList.contains(user.id)}"/>
</h:panelGroup>
<h:panelGroup rendered="#{user.class.simpleName eq 'OAuthUserEntity'}">
<h:outputText value="#{user.oauthIssuer.displayName}" />
<h:outputText value=" (#{messages.currently_logged_id})" rendered="#{sessionManager.loggedInUserList.contains(user.id)}"/>
</h:panelGroup>
</li>
</ui:repeat>
</ul>
</div>
<div>
<h:outputText value="#{messages['connect_account.intro3']}" escape="false"/>
</div>
<p:dataTable var="key" value="#{connectAccountOAuthBean.printableAttributesList}">
<p:column headerText="#{messages.name}">
#{resourceBundleHelper.resolveMessage(key)}
</p:column>
<p:column headerText="#{messages.value}">
#{connectAccountOAuthBean.printableAttributesMap[key]}
</p:column>
</p:dataTable>
<p:dataList var="key" value="#{connectAccountOAuthBean.unprintableAttributesMap.keySet().toArray()}">
#{key}: #{connectAccountOAuthBean.unprintableAttributesMap[key]}
</p:dataList>
<div class="form">
<p:commandButton id="save" action="#{connectAccountOAuthBean.save}" value="#{messages['connect_account.commit']}" ajax="false"
disabled="#{connectAccountOAuthBean.errorState}" update=":form"/>
</div>
</h:form>
</ui:define>
</ui:composition>
</f:view>
</body>
</html>
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
<ui:param name="title" value="#{messages.title}"/> <ui:param name="title" value="#{messages.title}"/>
<ui:define name="content"> <ui:define name="content">
<h:form id="form" prependId="false" class="full form"> <h:form id="form" prependId="false" class="full">
<h3><h:outputText value="#{messages['connect_account.heading']}" /></h3> <h3><h:outputText value="#{messages['connect_account.heading']}" /></h3>
...@@ -32,17 +32,27 @@ ...@@ -32,17 +32,27 @@
</div> </div>
<p:messages id="messageBox" showDetail="true" /> <p:messages id="messageBox" showDetail="true" />
<p:dataList var="user" value="#{connectAccountOidcBean.userList}" type="unordered"> <div class="text">
<p:outputPanel rendered="#{user.class.simpleName eq 'SamlUserEntity'}"> <ul>
<h:outputText value="#{user.idp.displayName}" /> <ui:repeat var="user" value="#{connectAccountOidcBean.userList}">
<h:outputText value=" (#{messages.currently_logged_id})" rendered="#{sessionManager.loggedInUserList.contains(user.id)}"/> <li>
</p:outputPanel> <h:panelGroup rendered="#{user.class.simpleName eq 'SamlUserEntity'}">
<p:outputPanel rendered="#{user.class.simpleName eq 'OidcUserEntity'}"> <h:outputText value="#{user.idp.displayName}" />
<h:outputText value="#{user.issuer.displayName}" /> <h:outputText value=" (#{messages.currently_logged_id})" rendered="#{sessionManager.loggedInUserList.contains(user.id)}"/>
<h:outputText value=" (#{messages.currently_logged_id})" rendered="#{sessionManager.loggedInUserList.contains(user.id)}"/> </h:panelGroup>
</p:outputPanel> <h:panelGroup rendered="#{user.class.simpleName eq 'OidcUserEntity'}">
</p:dataList> <h:outputText value="#{user.issuer.displayName}" />
<h:outputText value=" (#{messages.currently_logged_id})" rendered="#{sessionManager.loggedInUserList.contains(user.id)}"/>
</h:panelGroup>
<h:panelGroup rendered="#{user.class.simpleName eq 'OAuthUserEntity'}">
<h:outputText value="#{user.oauthIssuer.displayName}" />
<h:outputText value=" (#{messages.currently_logged_id})" rendered="#{sessionManager.loggedInUserList.contains(user.id)}"/>
</h:panelGroup>
</li>
</ui:repeat>
</ul>
</div>
<div> <div>
<h:outputText value="#{messages['connect_account.intro3']}" escape="false"/> <h:outputText value="#{messages['connect_account.intro3']}" escape="false"/>
...@@ -61,9 +71,10 @@ ...@@ -61,9 +71,10 @@
#{key}: #{connectAccountOidcBean.unprintableAttributesMap[key]} #{key}: #{connectAccountOidcBean.unprintableAttributesMap[key]}
</p:dataList> </p:dataList>
<p:commandButton id="save" action="#{connectAccountOidcBean.save}" value="#{messages['connect_account.commit']}" ajax="false" <div class="form">
disabled="#{connectAccountOidcBean.errorState}" update=":form"/> <p:commandButton id="save" action="#{connectAccountOidcBean.save}" value="#{messages['connect_account.commit']}" ajax="false"
disabled="#{connectAccountOidcBean.errorState}" update=":form"/>
</div>
</h:form> </h:form>
</ui:define> </ui:define>
</ui:composition> </ui:composition>
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
<ui:param name="title" value="#{messages.title}"/> <ui:param name="title" value="#{messages.title}"/>
<ui:define name="content"> <ui:define name="content">
<h:form id="form" prependId="false" class="full form"> <h:form id="form" prependId="false" class="full">
<h3><h:outputText value="#{messages['connect_account.heading']}" /></h3> <h3><h:outputText value="#{messages['connect_account.heading']}" /></h3>
...@@ -32,17 +32,27 @@ ...@@ -32,17 +32,27 @@
</div> </div>
<p:messages id="messageBox" showDetail="true" /> <p:messages id="messageBox" showDetail="true" />
<p:dataList var="user" value="#{connectAccountSamlBean.userList}" type="unordered"> <div class="text">
<p:outputPanel rendered="#{user.class.simpleName eq 'SamlUserEntity'}"> <ul>
<h:outputText value="#{user.idp.displayName}" /> <ui:repeat var="user" value="#{connectAccountSamlBean.userList}">
<h:outputText value=" (#{messages.currently_logged_id})" rendered="#{sessionManager.loggedInUserList.contains(user.id)}"/> <li>
</p:outputPanel> <h:panelGroup rendered="#{user.class.simpleName eq 'SamlUserEntity'}">
<p:outputPanel rendered="#{user.class.simpleName eq 'OidcUserEntity'}"> <h:outputText value="#{user.idp.displayName}" />
<h:outputText value="#{user.issuer.displayName}" /> <h:outputText value=" (#{messages.currently_logged_id})" rendered="#{sessionManager.loggedInUserList.contains(user.id)}"/>
<h:outputText value=" (#{messages.currently_logged_id})" rendered="#{sessionManager.loggedInUserList.contains(user.id)}"/> </h:panelGroup>
</p:outputPanel> <h:panelGroup rendered="#{user.class.simpleName eq 'OidcUserEntity'}">
</p:dataList> <h:outputText value="#{user.issuer.displayName}" />
<h:outputText value=" (#{messages.currently_logged_id})" rendered="#{sessionManager.loggedInUserList.contains(user.id)}"/>
</h:panelGroup>
<h:panelGroup rendered="#{user.class.simpleName eq 'OAuthUserEntity'}">
<h:outputText value="#{user.oauthIssuer.displayName}" />
<h:outputText value=" (#{messages.currently_logged_id})" rendered="#{sessionManager.loggedInUserList.contains(user.id)}"/>
</h:panelGroup>
</li>
</ui:repeat>
</ul>
</div>
<div> <div>
<h:outputText value="#{messages['connect_account.intro3']}" escape="false"/> <h:outputText value="#{messages['connect_account.intro3']}" escape="false"/>
...@@ -61,9 +71,10 @@ ...@@ -61,9 +71,10 @@
#{key}: #{connectAccountSamlBean.unprintableAttributesMap[key]} #{key}: #{connectAccountSamlBean.unprintableAttributesMap[key]}
</p:dataList> </p:dataList>
<p:commandButton id="save" action="#{connectAccountSamlBean.save}" value="#{messages['connect_account.commit']}" ajax="false" <div class="form">
disabled="#{connectAccountSamlBean.errorState}" update=":form"/> <p:commandButton id="save" action="#{connectAccountSamlBean.save}" value="#{messages['connect_account.commit']}" ajax="false"
disabled="#{connectAccountSamlBean.errorState}" update=":form"/>
</div>
</h:form> </h:form>
</ui:define> </ui:define>
</ui:composition> </ui:composition>
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
<ui:param name="title" value="#{messages.title}"/> <ui:param name="title" value="#{messages.title}"/>
<ui:define name="content"> <ui:define name="content">
<h:form id="form" prependId="false" class="full form"> <h:form id="form" prependId="false" class="full">
<h3><h:outputText value="#{messages['connect_account.heading']}" /></h3> <h3><h:outputText value="#{messages['connect_account.heading']}" /></h3>
...@@ -34,15 +34,28 @@ ...@@ -34,15 +34,28 @@
<div style="margin-top: 1em;"> <div style="margin-top: 1em;">
<h:outputText value="#{messages['connect_account.list_accounts']}:" /> <h:outputText value="#{messages['connect_account.list_accounts']}:" />
</div> </div>
<div class="text">
<ul>
<ui:repeat var="user" value="#{connectAccountBean.userList}">
<li>
<h:panelGroup rendered="#{user.class.simpleName eq 'SamlUserEntity'}">
<h:outputText value="#{user.idp.displayName}" />
<h:outputText value=" (#{messages.currently_logged_id})" rendered="#{sessionManager.loggedInUserList.contains(user.id)}"/>
</h:panelGroup>
<h:panelGroup rendered="#{user.class.simpleName eq 'OidcUserEntity'}">
<h:outputText value="#{user.issuer.displayName}" />
<h:outputText value=" (#{messages.currently_logged_id})" rendered="#{sessionManager.loggedInUserList.contains(user.id)}"/>
</h:panelGroup>
<h:panelGroup rendered="#{user.class.simpleName eq 'OAuthUserEntity'}">
<h:outputText value="#{user.oauthIssuer.displayName}" />
<h:outputText value=" (#{messages.currently_logged_id})" rendered="#{sessionManager.loggedInUserList.contains(user.id)}"/>
</h:panelGroup>
</li>
</ui:repeat>
</ul>
</div>
<p:dataList var="user" value="#{connectAccountBean.userList}" type="unordered"> <p:dataList var="user" value="#{connectAccountBean.userList}" type="unordered">
<p:outputPanel rendered="#{user.class.simpleName eq 'SamlUserEntity'}">
<h:outputText value="#{user.idp.displayName}" />
<h:outputText value=" (#{messages.currently_logged_id})" rendered="#{sessionManager.loggedInUserList.contains(user.id)}"/>
</p:outputPanel>
<p:outputPanel rendered="#{user.class.simpleName eq 'OidcUserEntity'}">
<h:outputText value="#{user.issuer.displayName}" />
<h:outputText value=" (#{messages.currently_logged_id})" rendered="#{sessionManager.loggedInUserList.contains(user.id)}"/>
</p:outputPanel>
</p:dataList> </p:dataList>
<div class="grid"> <div class="grid">
...@@ -70,10 +83,10 @@ ...@@ -70,10 +83,10 @@
</p:selectOneListbox> </p:selectOneListbox>
</p:outputPanel> </p:outputPanel>
<p:outputPanel id="btnPanel"> <h:panelGroup id="btnPanel" style="block" styleClass="form">
<p:commandButton id="login" action="#{connectAccountBean.startConnect()}" value="#{messages.proceed}" disabled="#{empty connectAccountBean.selected}" <p:commandButton id="login" action="#{connectAccountBean.startConnect()}" value="#{messages.proceed}" disabled="#{empty connectAccountBean.selected}"
update=":form" /> update=":form" />
</p:outputPanel> </h:panelGroup>
</div> </div>
......
...@@ -44,6 +44,13 @@ ...@@ -44,6 +44,13 @@
<h:outputText value="#{u.issuer.displayName}" /> <h:outputText value="#{u.issuer.displayName}" />
<h:outputText value=" (#{messages.currently_logged_id})" rendered="#{sessionManager.loggedInUserList.contains(u.id)}"/> <h:outputText value=" (#{messages.currently_logged_id})" rendered="#{sessionManager.loggedInUserList.contains(u.id)}"/>
</p:outputPanel> </p:outputPanel>
<p:outputPanel rendered="#{u.class.simpleName eq 'OAuthUserEntity'}">
<h:outputText value="#{u.eppn} - " rendered="#{u.eppn != null}"/>
<h:outputText value="#{u.email} - " rendered="#{u.eppn == null and u.email != null}"/>
<h:outputText value="#{u.oauthId} - " rendered="#{u.eppn == null and u.email == null}"/>
<h:outputText value="#{u.oauthIssuer.displayName}" />
<h:outputText value=" (#{messages.currently_logged_id})" rendered="#{sessionManager.loggedInUserList.contains(u.id)}"/>
</p:outputPanel>
</p:column> </p:column>
<f:ajax render=":form:tabVw" execute="@this" /> <f:ajax render=":form:tabVw" execute="@this" />
</p:selectOneListbox> </p:selectOneListbox>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment