Commit 4e2e0a90 authored by michael.simon's avatar michael.simon
Browse files

add first token admin interface

parent 8b348234
......@@ -115,6 +115,7 @@ public class ApplicationBootstrap {
checkRole("TimerAdmin");
checkRole("AuditAdmin");
checkRole("MailAdmin");
checkRole("TokenAdmin");
checkRole("User");
checkRole("AttributeSourceAdmin");
checkRole("ExternalUserAdmin");
......
......@@ -66,6 +66,10 @@ public class TwoFaServiceImpl implements TwoFaService {
resultList.setManagementUrl(configMap.get("managementUrl"));
}
if (configMap.containsKey("adminRole")) {
resultList.setAdminRole(configMap.get("adminRole"));
}
return resultList;
}
......
......@@ -13,6 +13,8 @@ public class LinotpTokenResultList extends ArrayList<LinotpToken> {
private String managementUrl;
private String adminRole;
public LinotpTokenResultList() {
super();
}
......@@ -47,4 +49,12 @@ public class LinotpTokenResultList extends ArrayList<LinotpToken> {
public void setStatusMessage(String statusMessage) {
this.statusMessage = statusMessage;
}
public String getAdminRole() {
return adminRole;
}
public void setAdminRole(String adminRole) {
this.adminRole = adminRole;
}
}
/*******************************************************************************
* 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.tadm;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.event.ComponentSystemEvent;
import javax.inject.Inject;
import edu.kit.scc.webreg.dao.GenericSortOrder;
import edu.kit.scc.webreg.entity.UserEntity;
import edu.kit.scc.webreg.sec.AuthorizationBean;
import edu.kit.scc.webreg.service.UserService;
import edu.kit.scc.webreg.service.twofa.TwoFaException;
import edu.kit.scc.webreg.service.twofa.TwoFaService;
import edu.kit.scc.webreg.service.twofa.linotp.LinotpTokenResultList;
import edu.kit.scc.webreg.session.SessionManager;
import edu.kit.scc.webreg.util.FacesMessageGenerator;
@ManagedBean
@ViewScoped
public class TokenAdminIndexBean implements Serializable {
private static final long serialVersionUID = 1L;
@Inject
private UserService userService;
@Inject
private TwoFaService twoFaService;
@Inject
private SessionManager session;
@Inject
private FacesMessageGenerator messageGenerator;
@Inject
private AuthorizationBean authBean;
private UserEntity selectedUser;
private LinotpTokenResultList userTokenList;
public void preRenderView(ComponentSystemEvent ev) {
}
public void searchToken() {
if (selectedUser == null) {
messageGenerator.addErrorMessage("Error", "User not found");
userTokenList = null;
}
else {
try {
userTokenList = twoFaService.findByUserId(selectedUser.getId());
if (userTokenList.getReadOnly()) {
messageGenerator.addWarningMessage("Warning", "User is in read only realm");
}
if (userTokenList.getAdminRole() != null &&
(! authBean.isUserInRole(userTokenList.getAdminRole()))) {
messageGenerator.addWarningMessage("Warning", "You are not admin for this realm");
userTokenList = null;
}
} catch (TwoFaException e) {
messageGenerator.addErrorMessage("Error", "Can't load token list for user: " + e.getMessage());
}
}
}
public List<UserEntity> completeUser(String part) {
Map<String, Object> filterMap = new HashMap<String, Object>();
filterMap.put("eppn", part);
return userService.findAllPaging(0, 10, "eppn", GenericSortOrder.ASC, filterMap);
}
public Boolean getReadOnly() {
if (userTokenList != null)
return userTokenList.getReadOnly();
else
return true;
}
public LinotpTokenResultList getUserTokenList() {
return userTokenList;
}
public UserEntity getSelectedUser() {
return selectedUser;
}
public void setSelectedUser(UserEntity selectedUser) {
this.selectedUser = selectedUser;
}
}
/*******************************************************************************
* 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.converter;
import javax.inject.Inject;
import javax.inject.Named;
import edu.kit.scc.webreg.entity.BaseEntity;
import edu.kit.scc.webreg.service.BaseService;
import edu.kit.scc.webreg.service.UserService;
@Named("userConverter")
public class UserConverter extends AbstractConverter {
private static final long serialVersionUID = 1L;
@Inject
private UserService service;
@Override
protected BaseService<? extends BaseEntity<Long>, Long> getService() {
return service;
}
}
......@@ -50,6 +50,8 @@ public class AccessChecker {
addAccessNode(root, "service-approver", true);
addAccessNode(root, "service-group-admin", true);
addAccessNode(root, "token-admin", false, "TokenAdmin");
addDenyNode(root, "register", false, "User");
AccessNode adminNode = addAccessNode(root, "admin", false, "MasterAdmin");
......
......@@ -11,6 +11,7 @@ import org.slf4j.Logger;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.CacheLoader.InvalidCacheLoadException;
import com.google.common.cache.LoadingCache;
import com.google.common.cache.RemovalListener;
import com.google.common.cache.RemovalNotification;
......@@ -47,6 +48,9 @@ public class RoleCache {
} catch (ExecutionException e) {
logger.info("Execution Exception on cache", e);
return null;
} catch (InvalidCacheLoadException e) {
// if a role does not exist ist database, this excpetion is thrown
return null;
}
}
......
<!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="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/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="javax.faces.event.PreRenderViewEvent"
listener="#{tokenAdminIndexBean.preRenderView}" />
</f:metadata>
<ui:composition template="/template/default.xhtml">
<ui:param name="title" value="#{messages.title}"/>
<ui:define name="content">
<h:form id="form">
<p:panel id="tokenPanel" header="Token Admin">
<p:panelGrid columns="2">
<h:outputLabel value="Eppn" for="@next" />
<p:autoComplete id="userAutocompl" multiple="false" value="#{tokenAdminIndexBean.selectedUser}"
completeMethod="#{tokenAdminIndexBean.completeUser}"
var="u" itemLabel="#{u.eppn}" itemValue="#{u}" converter="#{userConverter}"
forceSelection="true">
<p:column style="width:20%">
<h:outputText value="#{u.id}" />
</p:column>
<p:column>
<h:outputText value="#{u.eppn}" />
</p:column>
<p:column>
<h:outputText value="#{u.surName}" />
</p:column>
<p:column>
<h:outputText value="#{u.givenName}" />
</p:column>
</p:autoComplete>
</p:panelGrid>
<p:outputPanel style="margin-bottom: 16px;">
<p:commandButton action="#{tokenAdminIndexBean.searchToken()}" value="Search" update="tokenPanel,messageBox"/>
</p:outputPanel>
<p:panel rendered="#{tokenAdminIndexBean.readOnly}">
<h:outputText value="No User selected, or Token read only" />
</p:panel>
<p:messages id="messageBox" showDetail="true" escape="false" />
<p:dataGrid var="token" value="#{tokenAdminIndexBean.userTokenList}" columns="2" styleClass="whitefoot"
layout="grid" style="margin-bottom: 16px;"
rendered="#{not tokenAdminIndexBean.readOnly}">
<f:facet name="header">#{messages.twofa_list} (#{tokenAdminIndexBean.selectedUser.eppn})</f:facet>
<p:panel styleClass="grayback" style="margin-bottom: 0px;">
<f:facet name="header">
<i class="fa fa-fw fa-key"></i>
<b><h:outputText value="#{token.serial}" /></b>
</f:facet>
<p:panelGrid columns="2">
<p:outputPanel>
<h:graphicImage width="60px" value="#{resource['img/smartphone.svg']}" alt="Smartphone" rendered="#{token.tokenType == 'TOTP' and token.serial.startsWith('TOTP')}"/>
<h:graphicImage width="60px" value="#{resource['img/kittoken_small.png']}" alt="Hardware Token" rendered="#{token.tokenType == 'TOTP' and not token.serial.startsWith('TOTP')}"/>
<h:graphicImage width="60px" value="#{resource['img/yubikey_small.png']}" alt="Yubikey" rendered="#{token.tokenType == 'yubico'}"/>
<h:graphicImage width="60px" value="#{resource['img/tanlist.svg']}" alt="Backup TAN List" rendered="#{token.tokenType == 'HMAC'}"/>
</p:outputPanel>
<p:outputPanel>
<h:panelGrid columns="2" style="margin-bottom: 16px;">
<p:outputLabel for="@next" value="#{messages.twofa_tokentype}:" />
<h:panelGroup>
<h:outputText value="#{messages.twofa_tokentype_totp}" rendered="#{token.tokenType == 'TOTP' and token.serial.startsWith('TOTP')}"/>
<h:outputText value="#{messages.twofa_tokentype_totp_hardware}" rendered="#{token.tokenType == 'TOTP' and not token.serial.startsWith('TOTP')}"/>
<h:outputText value="#{messages.twofa_tokentype_tanlist}" rendered="#{token.tokenType == 'HMAC'}"/>
<h:outputText value="#{messages.twofa_tokentype_yubikey}" rendered="#{token.tokenType == 'yubico'}"/>
</h:panelGroup>
<p:outputLabel for="@next" value="#{messages.twofa_active}:" />
<h:outputText value="#{token.isactive ? messages.yes : messages.no}" />
</h:panelGrid>
<p:panel style="margin: 8px;" rendered="#{! token.isactive and (token.tokenDesc.contains('INIT'))}">
<h:outputText value="#{messages.twofa_token_not_init}" style="color:red;" />
</p:panel>
<p:commandButton action="#{twoFaUserBean.disableToken(token.serial)}" value="#{messages.disable}"
update="@form" rendered="#{token.isactive}"/>
<p:commandButton action="#{twoFaUserBean.enableToken(token.serial)}" value="#{messages.enable}"
update="@form" rendered="#{! token.isactive and (! token.tokenDesc.contains('INIT'))}"/>
<p:commandButton action="#{twoFaUserBean.deleteToken(token.serial)}" value="#{messages.delete}"
update="@form" rendered="#{! token.isactive and (token.tokenDesc.contains('DELABLE'))}" style="color:red;">
<p:confirm header="#{messages.confirm_header}" message="#{messages.confirm}" />
</p:commandButton>
<p:commandButton action="#{twoFaUserBean.getBackupTanList(token.serial)}" value="#{messages.token_get_tanlist_values}"
update="@form" rendered="#{token.isactive and token.tokenType == 'HMAC'}"
oncomplete="PF('showBackupTanDlg').show();"/>
</p:outputPanel>
</p:panelGrid>
</p:panel>
</p:dataGrid>
</p:panel>
</h:form>
</ui:define>
</ui:composition>
</f:view>
</body>
</html>
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment