added frist draft of account ui
This commit is contained in:
6
account-ui/faces-config.NavData
Normal file
6
account-ui/faces-config.NavData
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Scene Scope="Project" version="2">
|
||||||
|
<Scope Scope="Faces Configuration Only"/>
|
||||||
|
<Scope Scope="Project"/>
|
||||||
|
<Scope Scope="All Faces Configurations"/>
|
||||||
|
</Scene>
|
||||||
22
account-ui/nb-configuration.xml
Normal file
22
account-ui/nb-configuration.xml
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project-shared-configuration>
|
||||||
|
<!--
|
||||||
|
This file contains additional configuration written by modules in the NetBeans IDE.
|
||||||
|
The configuration is intended to be shared among all the users of project and
|
||||||
|
therefore it is assumed to be part of version control checkout.
|
||||||
|
Without this configuration present, some functionality in the IDE may be limited or fail altogether.
|
||||||
|
-->
|
||||||
|
<libraries xmlns="http://www.netbeans.org/ns/cdnjs-libraries/1"/>
|
||||||
|
<properties xmlns="http://www.netbeans.org/ns/maven-properties-data/1">
|
||||||
|
<!--
|
||||||
|
Properties that influence various parts of the IDE, especially code formatting and the like.
|
||||||
|
You can copy and paste the single properties, into the pom.xml file and the IDE will pick them up.
|
||||||
|
That way multiple projects can share the same settings (useful for formatting rules for example).
|
||||||
|
Any value defined here will override the pom.xml file value but is only applicable to the current project.
|
||||||
|
-->
|
||||||
|
<org-netbeans-modules-projectapi.jsf_2e_language>Facelets</org-netbeans-modules-projectapi.jsf_2e_language>
|
||||||
|
<org-netbeans-modules-maven-j2ee.netbeans_2e_hint_2e_deploy_2e_server>WildFly</org-netbeans-modules-maven-j2ee.netbeans_2e_hint_2e_deploy_2e_server>
|
||||||
|
<netbeans.hint.license>apache20</netbeans.hint.license>
|
||||||
|
<org-netbeans-modules-web-clientproject-api.js_2e_libs_2e_folder>js/libs</org-netbeans-modules-web-clientproject-api.js_2e_libs_2e_folder>
|
||||||
|
</properties>
|
||||||
|
</project-shared-configuration>
|
||||||
108
account-ui/pom.xml
Normal file
108
account-ui/pom.xml
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<artifactId>shared</artifactId>
|
||||||
|
<groupId>de.muehlencord</groupId>
|
||||||
|
<version>1.1-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<groupId>de.muehlencord</groupId>
|
||||||
|
<artifactId>account-ui</artifactId>
|
||||||
|
<version>1.1-SNAPSHOT</version>
|
||||||
|
<packaging>war</packaging>
|
||||||
|
|
||||||
|
<name>shared-account-ui</name>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<timestamp>${maven.build.timestamp}</timestamp>
|
||||||
|
<maven.compiler.source>10</maven.compiler.source>
|
||||||
|
<maven.compiler.target>10</maven.compiler.target>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.primefaces</groupId>
|
||||||
|
<artifactId>primefaces</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- Admin faces template -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.adminfaces</groupId>
|
||||||
|
<artifactId>admin-template</artifactId>
|
||||||
|
<version>1.0.0-RC19</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- Omnifaces, faces utils -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.omnifaces</groupId>
|
||||||
|
<artifactId>omnifaces</artifactId>
|
||||||
|
<version>2.7</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- Apache Shiro, Security API -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.shiro</groupId>
|
||||||
|
<artifactId>shiro-core</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.shiro</groupId>
|
||||||
|
<artifactId>shiro-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>de.muehlencord.shared</groupId>
|
||||||
|
<artifactId>shared-shiro-faces</artifactId>
|
||||||
|
<version>1.1-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>de.muehlencord.shared</groupId>
|
||||||
|
<artifactId>shared-account</artifactId>
|
||||||
|
<version>1.1-SNAPSHOT</version>
|
||||||
|
<type>jar</type>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>de.muehlencord.sf</groupId>
|
||||||
|
<artifactId>filter</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax</groupId>
|
||||||
|
<artifactId>javaee-web-api</artifactId>
|
||||||
|
<version>7.0</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<resources>
|
||||||
|
<!-- fill buildinformation file -->
|
||||||
|
<resource>
|
||||||
|
<directory>src/main/resources</directory>
|
||||||
|
<filtering>true</filtering>
|
||||||
|
<includes>
|
||||||
|
<include>**/*.properties</include>
|
||||||
|
<include>**/*.xml</include>
|
||||||
|
</includes>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
|
||||||
|
<finalName>account</finalName>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.8.0</version>
|
||||||
|
<configuration>
|
||||||
|
<source>10</source>
|
||||||
|
<target>10</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-war-plugin</artifactId>
|
||||||
|
<version>3.2.2</version>
|
||||||
|
<configuration>
|
||||||
|
<failOnMissingWebXml>false</failOnMissingWebXml>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
@ -0,0 +1,91 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Joern Muehlencord <joern at muehlencord.de>.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package de.muehlencord.shared.account.web;
|
||||||
|
|
||||||
|
import de.muehlencord.shared.account.business.account.boundary.AccountControl;
|
||||||
|
import de.muehlencord.shared.account.business.account.entity.Account;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import javax.annotation.ManagedBean;
|
||||||
|
import javax.ejb.EJB;
|
||||||
|
import javax.enterprise.context.SessionScoped;
|
||||||
|
import javax.enterprise.inject.Produces;
|
||||||
|
import org.apache.shiro.SecurityUtils;
|
||||||
|
import org.apache.shiro.subject.Subject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Joern Muehlencord <joern at muehlencord.de>
|
||||||
|
*/
|
||||||
|
@ManagedBean
|
||||||
|
@SessionScoped
|
||||||
|
public class AccountProducer implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -3806204732038165311L;
|
||||||
|
private final Map<String, Object> objectMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
@EJB
|
||||||
|
AccountControl accountController;
|
||||||
|
|
||||||
|
private Account account = null;
|
||||||
|
|
||||||
|
@Produces
|
||||||
|
public Account getAccount() {
|
||||||
|
String accountName;
|
||||||
|
if (account == null) {
|
||||||
|
Subject subject = SecurityUtils.getSubject();
|
||||||
|
if (subject == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((subject.isAuthenticated() == false) && (subject.isRemembered() == false)) {
|
||||||
|
accountName = "web";
|
||||||
|
} else {
|
||||||
|
accountName = subject.getPrincipal().toString();
|
||||||
|
}
|
||||||
|
account = accountController.getAccountEntity(accountName, true);
|
||||||
|
}
|
||||||
|
return account;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> T getValue(String key, Class<T> clazz) {
|
||||||
|
if (objectMap.containsKey(key)) {
|
||||||
|
Object obj = objectMap.get(key);
|
||||||
|
if (obj == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return clazz.cast(obj);
|
||||||
|
} catch (ClassCastException ex) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(String key, Object obj) {
|
||||||
|
objectMap.put(key, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Produces
|
||||||
|
public Locale getLocale() {
|
||||||
|
return Locale.ENGLISH; // TODO depend lcoale on account or on incoming request
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,59 @@
|
|||||||
|
package de.muehlencord.shared.account.web;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Properties;
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
import javax.enterprise.context.ApplicationScoped;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author joern.muehlencord
|
||||||
|
*/
|
||||||
|
@Named(value = "applicationController")
|
||||||
|
@ApplicationScoped
|
||||||
|
public class ApplicationController {
|
||||||
|
|
||||||
|
private final static Logger LOGGER = LoggerFactory.getLogger(ApplicationController.class.getName());
|
||||||
|
|
||||||
|
private String version;
|
||||||
|
private String buildDate;
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void init() {
|
||||||
|
InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("buildInfo.properties");
|
||||||
|
if (in == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Properties props = new Properties();
|
||||||
|
try {
|
||||||
|
props.load(in);
|
||||||
|
|
||||||
|
version = props.getProperty("build.version");
|
||||||
|
buildDate = props.getProperty("build.timestamp");
|
||||||
|
|
||||||
|
if (LOGGER.isDebugEnabled()) {
|
||||||
|
LOGGER.debug("buildInfo.properties read successfully");
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (IOException ex) {
|
||||||
|
LOGGER.error("Cannot find buildInfo.properties. ", ex);
|
||||||
|
version = "??";
|
||||||
|
buildDate = "??";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* *** getter / setter *** */
|
||||||
|
public String getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBuildDate() {
|
||||||
|
return buildDate;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package de.muehlencord.shared.account.web;
|
||||||
|
|
||||||
|
import de.muehlencord.shared.account.business.config.boundary.ConfigService;
|
||||||
|
import de.muehlencord.shared.account.business.accountcounfig.entity.AccountConfigurationKey;
|
||||||
|
import de.muehlencord.shared.account.business.accountcounfig.entity.AccountConfigurationValue;
|
||||||
|
import de.muehlencord.shared.account.business.config.entity.ConfigException;
|
||||||
|
import javax.ejb.EJB;
|
||||||
|
import javax.enterprise.context.Dependent;
|
||||||
|
import javax.enterprise.inject.Produces;
|
||||||
|
import javax.enterprise.inject.spi.Annotated;
|
||||||
|
import javax.enterprise.inject.spi.InjectionPoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Joern Muehlencord <joern at muehlencord.de>
|
||||||
|
*/
|
||||||
|
@Dependent
|
||||||
|
public class ConfigurationProducer {
|
||||||
|
|
||||||
|
@EJB
|
||||||
|
ConfigService configService;
|
||||||
|
|
||||||
|
@Produces
|
||||||
|
@AccountConfigurationValue(key = AccountConfigurationKey.Producer)
|
||||||
|
public String produceConfigurationValue(InjectionPoint injectionPoint) {
|
||||||
|
Annotated annotated = injectionPoint.getAnnotated();
|
||||||
|
AccountConfigurationValue annotation = annotated.getAnnotation(AccountConfigurationValue.class);
|
||||||
|
if (annotation != null) {
|
||||||
|
AccountConfigurationKey key = annotation.key();
|
||||||
|
if (key != null) {
|
||||||
|
try {
|
||||||
|
switch (key) {
|
||||||
|
case BaseUrl:
|
||||||
|
return configService.getConfigValue("base.url");
|
||||||
|
case PasswordResetUrl:
|
||||||
|
return configService.getConfigValue("base.url") + "/login.xhtml";
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException("Invalid key " + key + " for injection point: " + injectionPoint);
|
||||||
|
}
|
||||||
|
} catch (ConfigException ex) {
|
||||||
|
throw new IllegalStateException("Invalid key " + key + " for injection point: " + injectionPoint + ". Exception: " + ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalStateException("No key for injection point: " + injectionPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Joern Muehlencord <joern at muehlencord.de>.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package de.muehlencord.shared.account.web;
|
||||||
|
|
||||||
|
import javax.enterprise.context.ContextNotActiveException;
|
||||||
|
import javax.enterprise.context.RequestScoped;
|
||||||
|
import javax.enterprise.inject.Produces;
|
||||||
|
import javax.faces.context.FacesContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Joern Muehlencord <joern at muehlencord.de>
|
||||||
|
*/
|
||||||
|
public class FacesContextProducer {
|
||||||
|
|
||||||
|
@Produces
|
||||||
|
@RequestScoped
|
||||||
|
public FacesContext getFacesContext() {
|
||||||
|
FacesContext ctx = FacesContext.getCurrentInstance();
|
||||||
|
if (ctx == null) {
|
||||||
|
throw new ContextNotActiveException("FacesContext is not active");
|
||||||
|
}
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,42 @@
|
|||||||
|
package de.muehlencord.shared.account.web;
|
||||||
|
|
||||||
|
import javax.enterprise.context.ApplicationScoped;
|
||||||
|
import javax.enterprise.context.RequestScoped;
|
||||||
|
import javax.enterprise.inject.Disposes;
|
||||||
|
import javax.enterprise.inject.Produces;
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.EntityManagerFactory;
|
||||||
|
import javax.persistence.PersistenceUnit;
|
||||||
|
import javax.persistence.SynchronizationType;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Joern Muehlencord <joern at muehlencord.de>
|
||||||
|
*/
|
||||||
|
@ApplicationScoped
|
||||||
|
public class PersistenceContextFactory {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(PersistenceContextFactory.class);
|
||||||
|
|
||||||
|
@PersistenceUnit
|
||||||
|
EntityManagerFactory emf;
|
||||||
|
|
||||||
|
@Produces
|
||||||
|
@RequestScoped
|
||||||
|
public EntityManager getEntityManager() {
|
||||||
|
if (LOGGER.isTraceEnabled()) {
|
||||||
|
LOGGER.trace("getting entityManager");
|
||||||
|
}
|
||||||
|
return emf.createEntityManager(SynchronizationType.UNSYNCHRONIZED);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void closeEntityManager (@Disposes EntityManager em) {
|
||||||
|
if (LOGGER.isTraceEnabled()) {
|
||||||
|
LOGGER.trace("closing entityManager");
|
||||||
|
}
|
||||||
|
em.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Joern Muehlencord <joern at muehlencord.de>.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package de.muehlencord.shared.account.web;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.ResourceBundle;
|
||||||
|
import javax.enterprise.context.RequestScoped;
|
||||||
|
import javax.enterprise.inject.Produces;
|
||||||
|
import javax.faces.context.FacesContext;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Joern Muehlencord <joern at muehlencord.de>
|
||||||
|
*/
|
||||||
|
@RequestScoped
|
||||||
|
public class ResourceBundleProducer implements Serializable {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(ResourceBundleProducer.class);
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 3764096270387408239L;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private Locale locale;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private FacesContext facesContext;
|
||||||
|
|
||||||
|
@Produces
|
||||||
|
public ResourceBundle getResourceBundle() {
|
||||||
|
ResourceBundle rb = ResourceBundle.getBundle("de.muehlencord.shared.account.web.presentation.messages", facesContext.getViewRoot().getLocale());
|
||||||
|
if (LOGGER.isDebugEnabled()) {
|
||||||
|
LOGGER.debug("ResourceBundle = "+rb);
|
||||||
|
}
|
||||||
|
return rb;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
package de.muehlencord.shared.account.web;
|
||||||
|
|
||||||
|
import javax.annotation.Priority;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.interceptor.AroundInvoke;
|
||||||
|
import javax.interceptor.Interceptor;
|
||||||
|
import javax.interceptor.InvocationContext;
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.transaction.Transactional;
|
||||||
|
import static javax.transaction.Transactional.TxType.REQUIRED;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Joern Muehlencord <joern at muehlencord.de>
|
||||||
|
*/
|
||||||
|
@Transactional(value = REQUIRED)
|
||||||
|
@Interceptor
|
||||||
|
@Priority(value=TransactionJoinInterceptor.PRIORITY)
|
||||||
|
public class TransactionJoinInterceptor {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(TransactionJoinInterceptor.class);
|
||||||
|
|
||||||
|
// attach behind the interceptor of the container
|
||||||
|
public static final int PRIORITY = Interceptor.Priority.PLATFORM_BEFORE+250;
|
||||||
|
|
||||||
|
private final EntityManager em;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public TransactionJoinInterceptor(@NotNull EntityManager em) {
|
||||||
|
this.em = em;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@AroundInvoke
|
||||||
|
public Object joinTransaction(InvocationContext context) throws Exception {
|
||||||
|
if (em.isJoinedToTransaction()) {
|
||||||
|
LOGGER.info("transaction already joined");
|
||||||
|
} else {
|
||||||
|
LOGGER.info("joining transaction");
|
||||||
|
em.joinTransaction();
|
||||||
|
}
|
||||||
|
return context.proceed();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,180 @@
|
|||||||
|
package de.muehlencord.shared.account.web.presentation;
|
||||||
|
|
||||||
|
import de.muehlencord.shared.account.business.account.boundary.AccountControl;
|
||||||
|
import de.muehlencord.shared.account.business.account.boundary.ApplicationRoleControl;
|
||||||
|
import de.muehlencord.shared.account.business.account.entity.AccountEntity;
|
||||||
|
import de.muehlencord.shared.account.business.account.entity.AccountException;
|
||||||
|
import de.muehlencord.shared.account.business.account.entity.AccountStatus;
|
||||||
|
import de.muehlencord.shared.account.business.account.entity.ApplicationRoleEntity;
|
||||||
|
import de.muehlencord.shared.jeeutil.FacesUtil;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.ejb.EJB;
|
||||||
|
import javax.enterprise.context.SessionScoped;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jomu
|
||||||
|
*/
|
||||||
|
@SessionScoped
|
||||||
|
@Named
|
||||||
|
public class AccountView implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -8050582392249849438L;
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(AccountView.class);
|
||||||
|
|
||||||
|
@EJB
|
||||||
|
private AccountControl accountService;
|
||||||
|
@EJB
|
||||||
|
private ApplicationRoleControl appliationRoleService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* boolean flag to determine wether disabled accounts should be shown
|
||||||
|
* accounts are not deleted but disabled and can be activated in case
|
||||||
|
*/
|
||||||
|
private boolean showDisabledAccounts = false;
|
||||||
|
|
||||||
|
// cached accounts
|
||||||
|
private List<AccountEntity> accountList = null;
|
||||||
|
// cached application roles
|
||||||
|
private List<ApplicationRoleEntity> applicationRoles = null;
|
||||||
|
|
||||||
|
// account currently on edit
|
||||||
|
private AccountEntity currentAccount;
|
||||||
|
private List<ApplicationRoleEntity> currentAccountRoles = null;
|
||||||
|
// boolean flag to toggle buttons which require an account to be selected
|
||||||
|
private boolean accountSelected = false;
|
||||||
|
|
||||||
|
public List<AccountEntity> getAccounts() {
|
||||||
|
if (accountList == null) {
|
||||||
|
accountList = accountService.getAccounts(showDisabledAccounts);
|
||||||
|
}
|
||||||
|
return accountList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ApplicationRoleEntity> getAllApplicationRoles() {
|
||||||
|
if (applicationRoles == null) {
|
||||||
|
applicationRoles = appliationRoleService.getAllRoles();
|
||||||
|
}
|
||||||
|
return applicationRoles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void newAccount() {
|
||||||
|
currentAccount = new AccountEntity();
|
||||||
|
currentAccount.setUsername(null);
|
||||||
|
currentAccount.setStatus("NEW"); // TODO add status enum
|
||||||
|
currentAccountRoles = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void editAccount() {
|
||||||
|
// function called by webpage
|
||||||
|
if (currentAccount == null) {
|
||||||
|
currentAccountRoles = null;
|
||||||
|
} else {
|
||||||
|
currentAccount = accountService.getAccountEntity(currentAccount.getUsername(), true);
|
||||||
|
this.currentAccountRoles = new ArrayList<>();
|
||||||
|
if (currentAccount.getApplicationRoleList() != null) {
|
||||||
|
currentAccountRoles.addAll(currentAccount.getApplicationRoleList());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cancelEditAccount() {
|
||||||
|
currentAccount = null;
|
||||||
|
currentAccountRoles = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveEditAccount() {
|
||||||
|
String username = currentAccount.getUsername();
|
||||||
|
AccountEntity existingEntity = accountService.getAccountEntity(username, true);
|
||||||
|
// check if it is a new user (createdBy == null) but a user with same name already exists
|
||||||
|
if ((currentAccount.getCreatedBy() == null) && (existingEntity != null)) {
|
||||||
|
currentAccount.setUsername(null);
|
||||||
|
FacesUtil.addErrorMessage("editDialogMessaegs", "Create new account failed", "Account with username " + username + " already exists");
|
||||||
|
} else {
|
||||||
|
accountService.saveAccount(currentAccount, currentAccountRoles);
|
||||||
|
selectAccount();
|
||||||
|
if (currentAccount.getId() == null) {
|
||||||
|
// this was a new account
|
||||||
|
// force accounts to be loaded from database again
|
||||||
|
accountList = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteAccount() {
|
||||||
|
try {
|
||||||
|
accountService.deleteAccount(currentAccount);
|
||||||
|
accountList.remove(currentAccount);
|
||||||
|
FacesUtil.addGlobalInfoMessage("Info", "Account " + currentAccount.getUsername() + " deleted");
|
||||||
|
currentAccount = null;
|
||||||
|
currentAccountRoles = null;
|
||||||
|
deselectAccount();
|
||||||
|
} catch (AccountException ex) {
|
||||||
|
if (LOGGER.isDebugEnabled()) {
|
||||||
|
LOGGER.debug(ex.toString(), ex);
|
||||||
|
} else {
|
||||||
|
LOGGER.error(ex.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
FacesUtil.addGlobalErrorMessage("Error deleting account", ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void selectAccount() {
|
||||||
|
this.accountSelected = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deselectAccount() {
|
||||||
|
this.accountSelected = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void showDisabledAccountsChange() {
|
||||||
|
if (LOGGER.isDebugEnabled()) {
|
||||||
|
LOGGER.debug("show diabled accounts changed to {}", showDisabledAccounts);
|
||||||
|
}
|
||||||
|
this.accountList = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getStatusList() {
|
||||||
|
return AccountStatus.getAllStatusNames();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* **** getter / setter **** */
|
||||||
|
public AccountEntity getCurrentAccount() {
|
||||||
|
return currentAccount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCurrentAccount(AccountEntity currentAccount) {
|
||||||
|
this.currentAccount = currentAccount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAccountSelected() {
|
||||||
|
return accountSelected;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAccountSelected(boolean accountSelected) {
|
||||||
|
this.accountSelected = accountSelected;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isShowDisabledAccounts() {
|
||||||
|
return showDisabledAccounts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setShowDisabledAccounts(boolean showDisabledAccounts) {
|
||||||
|
this.showDisabledAccounts = showDisabledAccounts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ApplicationRoleEntity> getCurrentAccountRoles() {
|
||||||
|
return currentAccountRoles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCurrentAccountRoles(List<ApplicationRoleEntity> currentAccountRoles) {
|
||||||
|
this.currentAccountRoles = currentAccountRoles;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,99 @@
|
|||||||
|
package de.muehlencord.shared.account.web.presentation;
|
||||||
|
|
||||||
|
import de.muehlencord.shared.account.business.application.boundary.ApplicationService;
|
||||||
|
import de.muehlencord.shared.account.business.application.entity.ApplicationEntity;
|
||||||
|
import de.muehlencord.shared.jeeutil.FacesUtil;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
import javax.enterprise.context.SessionScoped;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Joern Muehlencord <joern at muehlencord.de>
|
||||||
|
*/
|
||||||
|
@Named(value = "applicationView")
|
||||||
|
@SessionScoped
|
||||||
|
public class ApplicationView implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -5515249316880163539L;
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationView.class);
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
ApplicationService applicationService;
|
||||||
|
|
||||||
|
private ApplicationEntity currentApplication = null;
|
||||||
|
private List<ApplicationEntity> applicationList = null;
|
||||||
|
private ApplicationEntity editApplication = null;
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void selectDefaultCurrentApplication() {
|
||||||
|
// force applications to be loaded from database
|
||||||
|
getAllApplications();
|
||||||
|
if ((applicationList != null) && (!applicationList.isEmpty())) {
|
||||||
|
currentApplication = applicationList.get(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ApplicationEntity> getAllApplications() {
|
||||||
|
if (applicationList == null) {
|
||||||
|
applicationList = applicationService.getAllApplications();
|
||||||
|
}
|
||||||
|
return applicationList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void selectApplication() {
|
||||||
|
if (currentApplication != null) {
|
||||||
|
LOGGER.info("selected application: {}", currentApplication.getApplicationName());
|
||||||
|
FacesUtil.addGlobalInfoMessage("Success", "Selected application " + currentApplication.getApplicationName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void newApplication() {
|
||||||
|
this.editApplication = new ApplicationEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cancelEditApplication() {
|
||||||
|
this.editApplication = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveEditApplication() {
|
||||||
|
if (editApplication == null) {
|
||||||
|
FacesUtil.addGlobalErrorMessage("Error", "Need to provide data");
|
||||||
|
} else if ((editApplication.getApplicationName() == null) || (editApplication.getApplicationName().trim().equals(""))) {
|
||||||
|
String hint;
|
||||||
|
if (editApplication.getId() == null) {
|
||||||
|
hint = "Cannot create application";
|
||||||
|
} else {
|
||||||
|
hint = "Cannot save application";
|
||||||
|
}
|
||||||
|
FacesUtil.addGlobalErrorMessage(hint, "Application name must not be empty");
|
||||||
|
} else {
|
||||||
|
currentApplication = applicationService.createOrUpdate(editApplication);
|
||||||
|
// force reload of to update view
|
||||||
|
applicationList = null;
|
||||||
|
FacesUtil.addGlobalInfoMessage("Info", "Application saved");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* *** getter / setter *** */
|
||||||
|
public ApplicationEntity getCurrentApplication() {
|
||||||
|
return currentApplication;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCurrentApplication(ApplicationEntity currentApplication) {
|
||||||
|
this.currentApplication = currentApplication;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ApplicationEntity getEditApplication() {
|
||||||
|
return editApplication;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEditApplication(ApplicationEntity editApplication) {
|
||||||
|
this.editApplication = editApplication;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,252 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Joern Muehlencord <joern at muehlencord.de>.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package de.muehlencord.shared.account.web.presentation;
|
||||||
|
|
||||||
|
import de.muehlencord.shared.account.business.account.boundary.ApplicationRoleControl;
|
||||||
|
import de.muehlencord.shared.account.business.account.entity.AccountException;
|
||||||
|
import de.muehlencord.shared.account.business.account.entity.ApplicationPermissionEntity;
|
||||||
|
import de.muehlencord.shared.account.business.account.entity.ApplicationRoleEntity;
|
||||||
|
import de.muehlencord.shared.jeeutil.FacesUtil;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.ejb.EJB;
|
||||||
|
import javax.enterprise.context.SessionScoped;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.validation.constraints.Size;
|
||||||
|
import org.primefaces.event.SelectEvent;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Joern Muehlencord <joern at muehlencord.de>
|
||||||
|
*/
|
||||||
|
@SessionScoped
|
||||||
|
@Named
|
||||||
|
public class GroupView implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1669321020398119007L;
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(GroupView.class);
|
||||||
|
|
||||||
|
@EJB
|
||||||
|
ApplicationRoleControl applicationRoleControl;
|
||||||
|
|
||||||
|
@Size(max = 80)
|
||||||
|
private String newRoleName;
|
||||||
|
@Size(max = 200)
|
||||||
|
private String newRoleDescription;
|
||||||
|
// flag to determine whether a role is selected or not
|
||||||
|
private boolean isPermissionSelected = false;
|
||||||
|
|
||||||
|
private List<ApplicationRoleEntity> allRoles = null;
|
||||||
|
private List<ApplicationPermissionEntity> currentRolePermissions = null;
|
||||||
|
private List<ApplicationPermissionEntity> missingApplicationsPermissions = null;
|
||||||
|
|
||||||
|
private ApplicationRoleEntity currentRole;
|
||||||
|
private ApplicationPermissionEntity currentPermission;
|
||||||
|
private ApplicationPermissionEntity newPermission;
|
||||||
|
|
||||||
|
public List<ApplicationRoleEntity> getAllRoles() {
|
||||||
|
if (allRoles == null) {
|
||||||
|
allRoles = applicationRoleControl.getAllRoles();
|
||||||
|
}
|
||||||
|
return allRoles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void newRole() {
|
||||||
|
if ((newRoleName == null) || (newRoleName.trim().length() == 0)) {
|
||||||
|
FacesUtil.addGlobalErrorMessage("Error", "Permission name must not be null");
|
||||||
|
} else if ((newRoleDescription == null) || (newRoleDescription.trim().length() == 0)) {
|
||||||
|
FacesUtil.addGlobalErrorMessage("Error", "Permission name must not be null");
|
||||||
|
} else {
|
||||||
|
applicationRoleControl.createOrUpdate(newRoleName, newRoleDescription);
|
||||||
|
allRoles = null; // force reload
|
||||||
|
newRoleName = null;
|
||||||
|
newRoleDescription = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void editRole() {
|
||||||
|
if (currentRole == null) {
|
||||||
|
FacesUtil.addGlobalErrorMessage("Error", "Please select a permission to edit");
|
||||||
|
} else {
|
||||||
|
allRoles = null; // force reload
|
||||||
|
newRoleName = currentRole.getRoleName();
|
||||||
|
newRoleDescription = currentRole.getRoleDescription();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteRole() {
|
||||||
|
if (currentRole == null) {
|
||||||
|
FacesUtil.addGlobalErrorMessage("Error", "Please select a permission to edit");
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
applicationRoleControl.delete(currentRole);
|
||||||
|
allRoles = null; // force reload
|
||||||
|
currentRole = null;
|
||||||
|
currentRolePermissions = null;
|
||||||
|
} catch (AccountException ex) {
|
||||||
|
if (LOGGER.isDebugEnabled()) {
|
||||||
|
LOGGER.debug(ex.toString(), ex);
|
||||||
|
} else {
|
||||||
|
LOGGER.debug(ex.toString());
|
||||||
|
}
|
||||||
|
FacesUtil.addGlobalErrorMessage("Error while deleting permission.", ex.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onRoleSelect(SelectEvent event) {
|
||||||
|
currentRolePermissions = null;
|
||||||
|
currentRolePermissions = getRolePermissions();
|
||||||
|
missingApplicationsPermissions = null;
|
||||||
|
missingApplicationsPermissions = getMissingPermissions();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ApplicationPermissionEntity> getRolePermissions() {
|
||||||
|
if (currentRole == null) {
|
||||||
|
currentRolePermissions = new ArrayList<>();
|
||||||
|
return currentRolePermissions;
|
||||||
|
} else {
|
||||||
|
if (currentRolePermissions == null) {
|
||||||
|
try {
|
||||||
|
currentRolePermissions = applicationRoleControl.getRolePermissions(currentRole);
|
||||||
|
} catch (AccountException ex) {
|
||||||
|
if (LOGGER.isDebugEnabled()) {
|
||||||
|
LOGGER.debug(ex.toString(), ex);
|
||||||
|
} else {
|
||||||
|
LOGGER.debug(ex.toString());
|
||||||
|
}
|
||||||
|
FacesUtil.addGlobalErrorMessage("Error while fetching role permissions", "see log for details");
|
||||||
|
currentRolePermissions = new ArrayList<>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return currentRolePermissions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ApplicationPermissionEntity> getMissingPermissions() {
|
||||||
|
if (currentRole == null) {
|
||||||
|
missingApplicationsPermissions = new ArrayList<>();
|
||||||
|
return missingApplicationsPermissions;
|
||||||
|
} else {
|
||||||
|
if (missingApplicationsPermissions == null) {
|
||||||
|
missingApplicationsPermissions = applicationRoleControl.getNotAssignedApplicationPermissions(currentRole);
|
||||||
|
|
||||||
|
}
|
||||||
|
return missingApplicationsPermissions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addRolePermission() {
|
||||||
|
if (newPermission == null) {
|
||||||
|
FacesUtil.addGlobalErrorMessage("Error", "Please select a new permission first");
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
applicationRoleControl.addPermission(currentRole, newPermission);
|
||||||
|
currentRolePermissions = null;
|
||||||
|
missingApplicationsPermissions = null;
|
||||||
|
} catch (AccountException ex) {
|
||||||
|
if (LOGGER.isDebugEnabled()) {
|
||||||
|
LOGGER.debug(ex.toString(), ex);
|
||||||
|
} else {
|
||||||
|
LOGGER.debug(ex.toString());
|
||||||
|
}
|
||||||
|
FacesUtil.addGlobalErrorMessage("Error while adding permission", ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeRolePermission() {
|
||||||
|
if (currentPermission == null) {
|
||||||
|
FacesUtil.addGlobalErrorMessage("Error", "Please select a permission first");
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
applicationRoleControl.removePermission(currentRole, currentPermission);
|
||||||
|
currentRolePermissions = null;
|
||||||
|
missingApplicationsPermissions = null;
|
||||||
|
} catch (AccountException ex) {
|
||||||
|
if (LOGGER.isDebugEnabled()) {
|
||||||
|
LOGGER.debug(ex.toString(), ex);
|
||||||
|
} else {
|
||||||
|
LOGGER.debug(ex.toString());
|
||||||
|
}
|
||||||
|
FacesUtil.addGlobalErrorMessage("Error while adding permission", ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void selectPermission() {
|
||||||
|
this.isPermissionSelected = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deselectPermission() {
|
||||||
|
this.isPermissionSelected = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* *** getter / setter *** */
|
||||||
|
public ApplicationRoleEntity getCurrentRole() {
|
||||||
|
return currentRole;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCurrentRole(ApplicationRoleEntity currentRole) {
|
||||||
|
this.currentRole = currentRole;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ApplicationPermissionEntity getCurrentPermission() {
|
||||||
|
return currentPermission;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCurrentPermission(ApplicationPermissionEntity currentPermission) {
|
||||||
|
this.currentPermission = currentPermission;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNewRoleName() {
|
||||||
|
return newRoleName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNewRoleName(String newRoleName) {
|
||||||
|
this.newRoleName = newRoleName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNewRoleDescription() {
|
||||||
|
return newRoleDescription;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNewRoleDescription(String newRoleDescription) {
|
||||||
|
this.newRoleDescription = newRoleDescription;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ApplicationPermissionEntity getNewPermission() {
|
||||||
|
return newPermission;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNewPermission(ApplicationPermissionEntity newPermission) {
|
||||||
|
this.newPermission = newPermission;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isIsPermissionSelected() {
|
||||||
|
return isPermissionSelected;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIsPermissionSelected(boolean isPermissionSelected) {
|
||||||
|
this.isPermissionSelected = isPermissionSelected;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,46 @@
|
|||||||
|
package de.muehlencord.shared.account.web.presentation;
|
||||||
|
|
||||||
|
import de.muehlencord.shared.account.business.config.boundary.ConfigService;
|
||||||
|
import de.muehlencord.shared.account.business.config.entity.ConfigException;
|
||||||
|
import javax.ejb.EJB;
|
||||||
|
import javax.enterprise.context.ApplicationScoped;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Joern Muehlencord <joern at muehlencord.de>
|
||||||
|
*/
|
||||||
|
@Named(value = "instanceView")
|
||||||
|
@ApplicationScoped
|
||||||
|
public class InstanceView {
|
||||||
|
|
||||||
|
private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(InstanceView.class);
|
||||||
|
|
||||||
|
@EJB
|
||||||
|
ConfigService configService;
|
||||||
|
|
||||||
|
public boolean isDevelopmentVersion() {
|
||||||
|
String instanceName = getInstanceName();
|
||||||
|
return !instanceName.equals("Production");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getInstanceName() {
|
||||||
|
String instanceName;
|
||||||
|
try {
|
||||||
|
instanceName = configService.getConfigValue("base.instance");
|
||||||
|
} catch (ConfigException ex) {
|
||||||
|
if (LOGGER.isDebugEnabled()) {
|
||||||
|
LOGGER.debug(ex.toString(), ex);
|
||||||
|
} else {
|
||||||
|
LOGGER.error(ex.toString());
|
||||||
|
}
|
||||||
|
instanceName = "unknown (" + ex.toString() + ")";
|
||||||
|
}
|
||||||
|
if (instanceName == null) {
|
||||||
|
return "unknown";
|
||||||
|
} else {
|
||||||
|
return instanceName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,167 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Joern Muehlencord <joern at muehlencord.de>.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package de.muehlencord.shared.account.web.presentation;
|
||||||
|
|
||||||
|
import de.muehlencord.shared.account.business.account.boundary.ApplicationPermissionControl;
|
||||||
|
import de.muehlencord.shared.account.business.account.entity.AccountException;
|
||||||
|
import de.muehlencord.shared.account.business.account.entity.ApplicationPermissionEntity;
|
||||||
|
import de.muehlencord.shared.jeeutil.FacesUtil;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.ejb.EJB;
|
||||||
|
import javax.enterprise.context.SessionScoped;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.validation.constraints.Size;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Joern Muehlencord <joern at muehlencord.de>
|
||||||
|
*/
|
||||||
|
@SessionScoped
|
||||||
|
@Named
|
||||||
|
public class PermissionView implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -1469453490360990772L;
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(PermissionView.class);
|
||||||
|
|
||||||
|
@EJB
|
||||||
|
ApplicationPermissionControl applicationPermissionService;
|
||||||
|
|
||||||
|
@Size(max = 80)
|
||||||
|
private String newPermissionName;
|
||||||
|
|
||||||
|
@Size(max = 200)
|
||||||
|
private String newPermissionDescription;
|
||||||
|
|
||||||
|
private ApplicationPermissionEntity currentPermission;
|
||||||
|
|
||||||
|
// flag if a permission is selected - used to control button state
|
||||||
|
private boolean permissionSelected;
|
||||||
|
|
||||||
|
public List<ApplicationPermissionEntity> getAppPermissions() {
|
||||||
|
return applicationPermissionService.getApplicationPermissions();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void savePermission() {
|
||||||
|
if ((newPermissionName == null) || (newPermissionName.trim().length() == 0)) {
|
||||||
|
FacesUtil.addGlobalErrorMessage("Error", "Permission name must not be null");
|
||||||
|
} else if ((newPermissionDescription == null) || (newPermissionDescription.trim().length() == 0)) {
|
||||||
|
FacesUtil.addGlobalErrorMessage("Error", "Permission name must not be null");
|
||||||
|
} else {
|
||||||
|
applicationPermissionService.createOrUpdate(newPermissionName, newPermissionDescription);
|
||||||
|
FacesUtil.addGlobalInfoMessage("Pemissin updated", "Permission "+newPermissionName+" updated");
|
||||||
|
newPermissionName = null;
|
||||||
|
newPermissionDescription = null;
|
||||||
|
deselectPermission();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void editPermission() {
|
||||||
|
if (currentPermission == null) {
|
||||||
|
FacesUtil.addGlobalErrorMessage("Error", "Please select a permission to edit");
|
||||||
|
} else {
|
||||||
|
newPermissionName = currentPermission.getPermissionName();
|
||||||
|
newPermissionDescription = currentPermission.getPermissionDescription();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deletePermission() {
|
||||||
|
if (currentPermission == null) {
|
||||||
|
FacesUtil.addGlobalErrorMessage("Error", "Please select a permission to edit");
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
applicationPermissionService.delete(currentPermission);
|
||||||
|
currentPermission = null;
|
||||||
|
} catch (AccountException ex) {
|
||||||
|
if (LOGGER.isDebugEnabled()) {
|
||||||
|
LOGGER.debug(ex.toString(), ex);
|
||||||
|
} else {
|
||||||
|
LOGGER.debug(ex.toString());
|
||||||
|
}
|
||||||
|
FacesUtil.addGlobalErrorMessage("Error while deleting permission.", ex.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void selectPermission() {
|
||||||
|
this.permissionSelected = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deselectPermission() {
|
||||||
|
this.permissionSelected = false;
|
||||||
|
this.newPermissionName = null;
|
||||||
|
this.newPermissionDescription = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean getCanEdit() {
|
||||||
|
if (!isPermissionSelected()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getCanDelete() {
|
||||||
|
if (!isPermissionSelected()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (newPermissionName == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* *** getter / setter *** */
|
||||||
|
public ApplicationPermissionEntity getCurrentPermission() {
|
||||||
|
return currentPermission;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCurrentPermission(ApplicationPermissionEntity newCurrentPermission) {
|
||||||
|
if ((currentPermission == null) || (newCurrentPermission == null) || (!currentPermission.equals(newCurrentPermission))) {
|
||||||
|
this.newPermissionName = null;
|
||||||
|
this.newPermissionDescription = null;
|
||||||
|
}
|
||||||
|
this.currentPermission = newCurrentPermission;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNewPermissionName() {
|
||||||
|
return newPermissionName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNewPermissionName(String newPermissionName) {
|
||||||
|
this.newPermissionName = newPermissionName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNewPermissionDescription() {
|
||||||
|
return newPermissionDescription;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNewPermissionDescription(String newPermissionDescription) {
|
||||||
|
this.newPermissionDescription = newPermissionDescription;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isPermissionSelected() {
|
||||||
|
return permissionSelected;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPermissionSelected(boolean permissionSelected) {
|
||||||
|
this.permissionSelected = permissionSelected;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
package de.muehlencord.shared.account.web.presentation;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import javax.faces.component.UIComponent;
|
||||||
|
import javax.faces.context.FacesContext;
|
||||||
|
import javax.faces.validator.FacesValidator;
|
||||||
|
import javax.faces.validator.Validator;
|
||||||
|
import javax.faces.validator.ValidatorException;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Joern Muehlencord <joern at muehlencord.de>
|
||||||
|
*/
|
||||||
|
@FacesValidator("uniqueApplicationValidator")
|
||||||
|
public class UniqueApplicationValidator implements Validator, Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 2526409681909574670L;
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(UniqueApplicationValidator.class);
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
EntityManager em;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
|
||||||
|
String name = (String) value;
|
||||||
|
LOGGER.info("Name = {}", name) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
22
account-ui/src/main/resources/META-INF/persistence.xml
Normal file
22
account-ui/src/main/resources/META-INF/persistence.xml
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
|
||||||
|
<persistence-unit name="com.wincornixdorf.pcd_pu" transaction-type="JTA">
|
||||||
|
<jta-data-source>java:/jboss/accountTestDs</jta-data-source>
|
||||||
|
<class>de.muehlencord.shared.account.business.account.entity.AccountEntity</class>
|
||||||
|
<class>de.muehlencord.shared.account.business.account.entity.AccountHistoryEntity</class>
|
||||||
|
<class>de.muehlencord.shared.account.business.account.entity.ApplicationPermissionEntity</class>
|
||||||
|
<class>de.muehlencord.shared.account.business.account.entity.ApplicationRoleEntity</class>
|
||||||
|
<class>de.muehlencord.shared.account.business.config.entity.ConfigEntity</class>
|
||||||
|
<class>de.muehlencord.shared.account.business.mail.entity.MailTemplateEntity</class>
|
||||||
|
<class>de.muehlencord.shared.account.business.application.entity.ApplicationEntity</class>
|
||||||
|
<exclude-unlisted-classes>true</exclude-unlisted-classes>
|
||||||
|
<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
|
||||||
|
<validation-mode>NONE</validation-mode>
|
||||||
|
<properties>
|
||||||
|
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL94Dialect"/>
|
||||||
|
<property name="hibernate.show_sql" value="true"/>
|
||||||
|
<property name="hibernate.cache.use_second_level_cache" value="true"/>
|
||||||
|
<property name="hibernate.cache.use_query_cache" value="true"/>
|
||||||
|
</properties>
|
||||||
|
</persistence-unit>
|
||||||
|
</persistence>
|
||||||
32
account-ui/src/main/resources/admin-config.properties
Normal file
32
account-ui/src/main/resources/admin-config.properties
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
admin.loginPage=/login.xhtml
|
||||||
|
admin.indexPage=/web/account.xhtml
|
||||||
|
#admin.dateFormat=
|
||||||
|
#admin.breadcrumbSize=5
|
||||||
|
admin.renderMessages=true
|
||||||
|
#admin.renderAjaxStatus=true
|
||||||
|
## disable filter to redirect to login page - shiro security filter is already doing this
|
||||||
|
admin.disableFilter=true
|
||||||
|
#admin.renderBreadCrumb=true
|
||||||
|
#admin.enableSlideMenu=true
|
||||||
|
#admin.enableRipple=true
|
||||||
|
#admin.rippleElements= .ripplelink,button.ui-button,.ui-selectlistbox-item,.ui-multiselectlistbox-item,.ui-selectonemenu-label,.ui-selectcheckboxmenu,\
|
||||||
|
#.ui-autocomplete-dropdown, .ui-autocomplete-item ... (the list goes on)
|
||||||
|
admin.skin=skin-purple-light
|
||||||
|
#admin.autoShowNavbar=true
|
||||||
|
#admin.ignoredResources=
|
||||||
|
#admin.loadingImage=ajaxloadingbar.gif
|
||||||
|
#admin.extensionLessUrls=false
|
||||||
|
admin.renderControlSidebar=false
|
||||||
|
#admin.controlSidebar.showOnMobile=false
|
||||||
|
#admin.controlSidebar.leftMenuTemplate=true
|
||||||
|
#admin.controlSidebar.fixedLayout=false
|
||||||
|
#admin.controlSidebar.boxedLayout=false
|
||||||
|
#admin.controlSidebar.sidebarCollapsed=false
|
||||||
|
#admin.controlSidebar.expandOnHover=false
|
||||||
|
#admin.controlSidebar.fixed=false
|
||||||
|
#admin.controlSidebar.darkSkin=true
|
||||||
|
#admin.rippleMobileOnly=true
|
||||||
|
admin.renderMenuSearch=false
|
||||||
|
## do not autohide
|
||||||
|
admin.autoHideMessages=false
|
||||||
|
#admin.messagesHideTimeout=2500
|
||||||
2
account-ui/src/main/resources/buildInfo.properties
Normal file
2
account-ui/src/main/resources/buildInfo.properties
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
build.version=${project.version}
|
||||||
|
build.timestamp=${timestamp}
|
||||||
@ -0,0 +1,131 @@
|
|||||||
|
header_login=Login
|
||||||
|
header_reset_password=Reset password
|
||||||
|
message_username_password=Please enter your user name and a new password
|
||||||
|
button_login=Login
|
||||||
|
button_cancel=Cancel
|
||||||
|
button_password_lost=Password lost?
|
||||||
|
label_username=Username
|
||||||
|
label_password=Password
|
||||||
|
label_new_password=New Password
|
||||||
|
button_password_reset=Reset password
|
||||||
|
header_passwort_lost=Lost password
|
||||||
|
message_start_password_reset=Please enter your username to start the password recovery procedure
|
||||||
|
menu_dashboard=Dashboard
|
||||||
|
menu_events=Events
|
||||||
|
menu_administration=Administration
|
||||||
|
menu_overview=Overview
|
||||||
|
menu_emails=Emails
|
||||||
|
menu_account=Account
|
||||||
|
menu_config=Config
|
||||||
|
menu_logout=Logout
|
||||||
|
button_new=New
|
||||||
|
button_delete=Delete
|
||||||
|
button_edit=Edit
|
||||||
|
button_reload=Reload
|
||||||
|
label_name=Name
|
||||||
|
label_description=Description
|
||||||
|
label_event_date=Event Date
|
||||||
|
label_reservation=Reservation
|
||||||
|
label_reservation_from_to=Reservation from/to
|
||||||
|
label_actions=Actions
|
||||||
|
message_confirm=Are you sure?
|
||||||
|
button_setup=Setup
|
||||||
|
button_reservations=Reservations
|
||||||
|
label_event_name=Event Name
|
||||||
|
label_event_item_desc=Event Item Description
|
||||||
|
label_timezone=Timezone
|
||||||
|
label_event_start=Event Start
|
||||||
|
label_event_end=Event End
|
||||||
|
label_reservation_autostart=Reservation start
|
||||||
|
label_reservation_autoend=Reservation end
|
||||||
|
label_reservation_active=Reservation active
|
||||||
|
label_reservation_max_items=Max Items
|
||||||
|
label_booking_deadline=Booking deadline
|
||||||
|
label_template_validation=Email validation mail template
|
||||||
|
label_template_confirmation=Event confirmation mail template
|
||||||
|
label_template_waitlist=Event waitlist mail template
|
||||||
|
message_event_not_found=Event not found
|
||||||
|
label_items=Items
|
||||||
|
label_costs=Costs
|
||||||
|
label_all=All
|
||||||
|
label_yes=Yes
|
||||||
|
label_no=No
|
||||||
|
label_status=Status
|
||||||
|
label_firstname=Firstname
|
||||||
|
label_lastname=Lastname
|
||||||
|
label_emailaddress=Emailaddress
|
||||||
|
label_comment=Comment
|
||||||
|
label_email_confirmed=Email confirmed
|
||||||
|
label_booking_number=Booking Number
|
||||||
|
label_booking_executed=booking executed
|
||||||
|
tt_log_entries=Show log entries
|
||||||
|
tt_cancel_reservation=Cancel the current reservation
|
||||||
|
tt_send_email_again=Send email again
|
||||||
|
tt_move_from_wl=Move from waitlist
|
||||||
|
tt_fix_reservation=Try to fix the current reservation
|
||||||
|
tt_edit_reservation=Edit the reservation
|
||||||
|
button_refresh_free=Refresh free
|
||||||
|
button_manual_reserve=Reserve
|
||||||
|
button_export=Export
|
||||||
|
label_amount=Amount
|
||||||
|
label_select=Select
|
||||||
|
label_created_by=Created by
|
||||||
|
label_ip=IP
|
||||||
|
label_ip_forwarded=IP (forwarded)
|
||||||
|
label_value=Value
|
||||||
|
label_useragent=Useragent
|
||||||
|
button_ok=Ok
|
||||||
|
message_comment=Please add a comment
|
||||||
|
menu_help=Help
|
||||||
|
label_event=Event
|
||||||
|
label_active=Active
|
||||||
|
label_waitlist=Waitlist
|
||||||
|
label_is_waitlist=Is waitlist
|
||||||
|
label_order=Order
|
||||||
|
message_dynamic_numbering=dynamic numbering (put %n as placeholder)
|
||||||
|
label_start_number=Start Number
|
||||||
|
label_end_number=End Number
|
||||||
|
header_item_def=Define items for event
|
||||||
|
message_no_event_items=No event item defined
|
||||||
|
button_overview=Overview
|
||||||
|
label_reservation_auto_start=Automatically switch on/off
|
||||||
|
label_item_public=Item public?
|
||||||
|
label_is_publicitem=Is public
|
||||||
|
label_customer_comment=Customer comment
|
||||||
|
label_change_comment=Change comment
|
||||||
|
label_existing_items=current items
|
||||||
|
label_new_items=new items
|
||||||
|
label_available_items=available items
|
||||||
|
label_no_records=No records found.
|
||||||
|
button_mail=Mail
|
||||||
|
header_email_distribution=Email distribution
|
||||||
|
label_template=Template
|
||||||
|
label_demomode=Demo mode
|
||||||
|
message_invalid_email=Please provide a valid email address
|
||||||
|
menu_permissions=Permissions
|
||||||
|
button_save=Save
|
||||||
|
menu_groups=Groups
|
||||||
|
message_email_sent=email sent
|
||||||
|
message_email_with_error=emails with error
|
||||||
|
message_no_email=no email address defined
|
||||||
|
message_email_not_sent=Error while sending emails
|
||||||
|
label_seating=Seating
|
||||||
|
label_attachments=Attachments
|
||||||
|
label_language=Language
|
||||||
|
label_subject=Subject
|
||||||
|
label_bytes=Bytes
|
||||||
|
label_upload=Upload
|
||||||
|
header_export=Export
|
||||||
|
label_export_type=Export Type
|
||||||
|
label_filtered=Filtered
|
||||||
|
label_include_deleted=Include deleted
|
||||||
|
label_include_log=Include Logs
|
||||||
|
label_template_booking_executed=Booking executed template
|
||||||
|
label_street=Street
|
||||||
|
label_zipCode=ZIP Code
|
||||||
|
label_city=City
|
||||||
|
label_groupName=Groupname
|
||||||
|
label_phoneNumber=Phone Number
|
||||||
|
label_template_waitlist_cancelled=Waitlist cancelled mail template
|
||||||
|
msgs_menu_status=Status
|
||||||
|
menu_status=Status
|
||||||
@ -0,0 +1,132 @@
|
|||||||
|
|
||||||
|
header_login=Anmeldung
|
||||||
|
header_reset_password=Passwort zur\u00fccksetzten
|
||||||
|
message_username_password=Bitte geben Deinen Benutzernamen und dein Passwort ein
|
||||||
|
button_login=Anmelden
|
||||||
|
button_cancel=Abbruch
|
||||||
|
button_password_lost=Passwort vergessen?
|
||||||
|
label_username=Benutzername
|
||||||
|
label_password=Passwort
|
||||||
|
label_new_password=Neues Passwort
|
||||||
|
button_password_reset=Passwort zur\u00fccksetzten
|
||||||
|
header_passwort_lost=Passwort vergessen
|
||||||
|
message_start_password_reset=Bitte gib deinen Benutzernamen ein um das Zur\u00fccksetzten des Passworts zu starten.
|
||||||
|
menu_dashboard=Dashbaord
|
||||||
|
menu_events=Veranstaltungen
|
||||||
|
menu_administration=Administration
|
||||||
|
menu_overview=\u00dcbersicht
|
||||||
|
menu_emails=E-Mails
|
||||||
|
menu_account=Benutzer
|
||||||
|
menu_config=Konfiguration
|
||||||
|
menu_logout=Abmelden
|
||||||
|
button_new=Neu
|
||||||
|
button_delete=L\u00f6schen
|
||||||
|
button_edit=Bearbeiten
|
||||||
|
button_reload=Aktualisieren
|
||||||
|
label_name=Name
|
||||||
|
label_description=Beschreibung
|
||||||
|
label_event_date=Veranstaltungsdatum
|
||||||
|
label_reservation=Reservierung
|
||||||
|
label_reservation_from_to=Reservierung von/bis
|
||||||
|
label_actions=Aktionen
|
||||||
|
message_confirm=Bist du sicher?
|
||||||
|
button_setup=Setup
|
||||||
|
button_reservations=Reservierungen
|
||||||
|
label_event_name=Veranstaltungsname
|
||||||
|
label_event_item_desc=Veranstaltungsobjekte
|
||||||
|
label_timezone=Zeitzone
|
||||||
|
label_event_start=Veranstaltungsbeginn
|
||||||
|
label_event_end=Veranstaltungsende
|
||||||
|
label_reservation_autostart=Reservierung von
|
||||||
|
label_reservation_autoend=Reservierung bis
|
||||||
|
label_reservation_active=Reservierung aktiv
|
||||||
|
label_reservation_max_items=Maximale Objekte
|
||||||
|
label_booking_deadline=Buchungsfrist
|
||||||
|
label_template_validation=Vorlage Emailvalidierung
|
||||||
|
label_template_confirmation=Vorlage Reservierungsbest\u00e4tigung
|
||||||
|
label_template_waitlist=Vorlage Wartelist
|
||||||
|
message_event_not_found=Veranstaltung nicht gefunden
|
||||||
|
label_items=Objekte
|
||||||
|
label_costs=Kosten
|
||||||
|
label_all=Alle
|
||||||
|
label_yes=Ja
|
||||||
|
label_no=Nein
|
||||||
|
label_status=Status
|
||||||
|
label_firstname=Vorname
|
||||||
|
label_lastname=Nachname
|
||||||
|
label_emailaddress=E-Mail-Adresse
|
||||||
|
label_comment=Kommentar
|
||||||
|
label_email_confirmed=E-Mail best\u00e4tigt
|
||||||
|
label_booking_number=Buchungsnummer
|
||||||
|
label_booking_executed=Buchungs ausgef\u00fchrt
|
||||||
|
tt_log_entries=Logbucheintr\u00e4ge
|
||||||
|
tt_cancel_reservation=Storniere die Reservierung
|
||||||
|
tt_send_email_again=Sende E-Mail erneut
|
||||||
|
tt_move_from_wl=Schiebe von Warteliste
|
||||||
|
tt_fix_reservation=Versuche den Fehler zu beheben
|
||||||
|
tt_edit_reservation=Bearbeite die Reservierung
|
||||||
|
button_refresh_free=Frei aktualisieren
|
||||||
|
button_manual_reserve=Reservieren
|
||||||
|
button_export=Exportieren
|
||||||
|
label_amount=Anzahl
|
||||||
|
label_select=W\u00e4hlen
|
||||||
|
label_created_by=Erzeugt durch
|
||||||
|
label_ip=IP
|
||||||
|
label_ip_forwarded=IP (forwarded)
|
||||||
|
label_value=Wert
|
||||||
|
label_useragent=Useragent
|
||||||
|
button_ok=Ok
|
||||||
|
message_comment=Bitte geben Sie einen Kommentar an
|
||||||
|
menu_help=Hilfe
|
||||||
|
label_event=Veranstaltung
|
||||||
|
label_active=Aktiv
|
||||||
|
label_waitlist=Warteliste
|
||||||
|
label_is_waitlist=Ist Warteliste
|
||||||
|
label_order=Reihenfolge
|
||||||
|
message_dynamic_numbering=Dynamische Nummerierung (%n als Platzhalter)
|
||||||
|
label_start_number=Startnummer
|
||||||
|
label_end_number=Endnummer
|
||||||
|
header_item_def=Objekte f\u00fcr Veranstaltung
|
||||||
|
message_no_event_items=Keine Objekte definiert
|
||||||
|
button_overview=\u00dcbersicht
|
||||||
|
label_reservation_auto_start=Automatisch ein/ausschalten
|
||||||
|
label_item_public=\u00d6ffentlich verf\u00fcgar?
|
||||||
|
label_is_publicitem=\u00d6ffentlich
|
||||||
|
label_customer_comment=Kundenkommentar
|
||||||
|
label_change_comment=\u00c4nderungskommentar
|
||||||
|
label_existing_items=aktuelle Objekte
|
||||||
|
label_new_items=neue Objekte
|
||||||
|
label_available_items=verf\u00fcgbare Objekte
|
||||||
|
label_no_records=Keine Daten gefunden.
|
||||||
|
button_mail=E-Mail
|
||||||
|
header_email_distribution=Emailversand
|
||||||
|
label_template=Vorlage
|
||||||
|
label_demomode=Demomodus
|
||||||
|
message_invalid_email=Bitte geben Sie eine g\u00fcltige Emailadresse an
|
||||||
|
menu_permissions=Berechtigungen
|
||||||
|
button_save=Speichern
|
||||||
|
menu_groups=Gruppen
|
||||||
|
message_email_sent=Email gesendet
|
||||||
|
message_email_with_error=Emails mit Fehler
|
||||||
|
message_no_email=keine Emailadresse verf\u00fcgbar
|
||||||
|
message_email_not_sent=Fehler beim Versenden der Email
|
||||||
|
label_seating=Saalplan Platz
|
||||||
|
label_attachments=Attachments
|
||||||
|
label_language=Sprache
|
||||||
|
label_subject=Betreff
|
||||||
|
label_bytes=Bytes
|
||||||
|
label_upload=Upload
|
||||||
|
header_export=Exportieren
|
||||||
|
label_export_type=Export Art
|
||||||
|
label_filtered=Gefiltert
|
||||||
|
label_include_deleted=Einschlie\u00dflich gel\u00f6scht
|
||||||
|
label_include_log=mit Logbuch
|
||||||
|
label_template_booking_executed=Vorlage Buchung durchgef\u00fchrt
|
||||||
|
label_street=Stra\u00dfe
|
||||||
|
label_zipCode=PLZ
|
||||||
|
label_city=Ort
|
||||||
|
label_groupName=Gruppenname
|
||||||
|
label_phoneNumber=Telefonnummer
|
||||||
|
label_template_waitlist_cancelled=Vorlage Warteliste Abbruch
|
||||||
|
msgs_menu_status=Status
|
||||||
|
menu_status=Status
|
||||||
@ -0,0 +1,132 @@
|
|||||||
|
|
||||||
|
header_login=Login
|
||||||
|
header_reset_password=Reset password
|
||||||
|
message_username_password=Please enter your user name and a new password
|
||||||
|
button_login=Login
|
||||||
|
button_cancel=Cancel
|
||||||
|
button_password_lost=Password lost?
|
||||||
|
label_username=Username
|
||||||
|
label_password=Password
|
||||||
|
label_new_password=New Password
|
||||||
|
button_password_reset=Reset password
|
||||||
|
header_passwort_lost=Lost password
|
||||||
|
message_start_password_reset=Please enter your username to start the password recovery procedure
|
||||||
|
menu_dashboard=Dashboard
|
||||||
|
menu_events=Events
|
||||||
|
menu_administration=Administration
|
||||||
|
menu_overview=Overview
|
||||||
|
menu_emails=Emails
|
||||||
|
menu_account=Account
|
||||||
|
menu_config=Config
|
||||||
|
menu_logout=Logout
|
||||||
|
button_new=New
|
||||||
|
button_delete=Delete
|
||||||
|
button_edit=Edit
|
||||||
|
button_reload=Reload
|
||||||
|
label_name=Name
|
||||||
|
label_description=Description
|
||||||
|
label_event_date=Event Date
|
||||||
|
label_reservation=Reservation
|
||||||
|
label_reservation_from_to=Reservation from/to
|
||||||
|
label_actions=Actions
|
||||||
|
message_confirm=Are you sure?
|
||||||
|
button_setup=Setup
|
||||||
|
button_reservations=Reservations
|
||||||
|
label_event_name=Event Name
|
||||||
|
label_event_item_desc=Event Item Description
|
||||||
|
label_timezone=Timezone
|
||||||
|
label_event_start=Event Start
|
||||||
|
label_event_end=Event End
|
||||||
|
label_reservation_autostart=Reservation Start
|
||||||
|
label_reservation_autoend=Reservation End
|
||||||
|
label_reservation_active=Reservation active
|
||||||
|
label_reservation_max_items=Max Items
|
||||||
|
label_booking_deadline=Booking deadline
|
||||||
|
label_template_validation=Email validation mail template
|
||||||
|
label_template_confirmation=Event confirmation mail template
|
||||||
|
label_template_waitlist=Event waitlist mail template
|
||||||
|
message_event_not_found=Event not found
|
||||||
|
label_items=Items
|
||||||
|
label_costs=Costs
|
||||||
|
label_all=All
|
||||||
|
label_yes=Yes
|
||||||
|
label_no=No
|
||||||
|
label_status=Status
|
||||||
|
label_firstname=Firstname
|
||||||
|
label_lastname=Lastname
|
||||||
|
label_emailaddress=Emailaddress
|
||||||
|
label_comment=Comment
|
||||||
|
label_email_confirmed=Email confirmed
|
||||||
|
label_booking_number=Booking Number
|
||||||
|
label_booking_executed=booking executed
|
||||||
|
tt_log_entries=Show log entries
|
||||||
|
tt_cancel_reservation=Cancel the current reservation
|
||||||
|
tt_send_email_again=Send email again
|
||||||
|
tt_move_from_wl=Move from waitlist
|
||||||
|
tt_fix_reservation=Try to fix the current reservation
|
||||||
|
tt_edit_reservation=Edit the reservation
|
||||||
|
button_refresh_free=Refresh free
|
||||||
|
button_manual_reserve=Reserve
|
||||||
|
button_export=Export
|
||||||
|
label_amount=Amount
|
||||||
|
label_select=Select
|
||||||
|
label_created_by=Created by
|
||||||
|
label_ip=IP
|
||||||
|
label_ip_forwarded=IP (forwarded)
|
||||||
|
label_value=Value
|
||||||
|
label_useragent=Useragent
|
||||||
|
button_ok=Ok
|
||||||
|
message_comment=Please add a comment
|
||||||
|
menu_help=Help
|
||||||
|
label_event=Event
|
||||||
|
label_active=Active
|
||||||
|
label_waitlist=Waitlist
|
||||||
|
label_is_waitlist=Is waitlist
|
||||||
|
label_order=Reservation Order
|
||||||
|
message_dynamic_numbering=dynamic numbering (put %n as placeholder)
|
||||||
|
label_start_number=Start Number
|
||||||
|
label_end_number=End Number
|
||||||
|
header_item_def=Define items for event
|
||||||
|
message_no_event_items=No event item defined
|
||||||
|
button_overview=Overview
|
||||||
|
label_reservation_auto_start=Automatically switch on/off
|
||||||
|
label_item_public=Item public?
|
||||||
|
label_is_publicitem=Is public
|
||||||
|
label_customer_comment=Customer comment
|
||||||
|
label_change_comment=Change comment
|
||||||
|
label_existing_items=current items
|
||||||
|
label_new_items=new items
|
||||||
|
label_available_items=available items
|
||||||
|
label_no_records=No records found.
|
||||||
|
button_mail=Mail
|
||||||
|
header_email_distribution=Email distribution
|
||||||
|
label_template=Template
|
||||||
|
label_demomode=Demo mode
|
||||||
|
message_invalid_email=Please provide a valid email address
|
||||||
|
menu_permissions=Permissions
|
||||||
|
button_save=Save
|
||||||
|
menu_groups=Groups
|
||||||
|
message_email_sent=email sent
|
||||||
|
message_email_with_error=emails with error
|
||||||
|
message_no_email=no email address defined
|
||||||
|
message_email_not_sent=Error while sending emails
|
||||||
|
label_seating=Seating
|
||||||
|
label_attachments=Anh\u00e4nge
|
||||||
|
label_language=Language
|
||||||
|
label_subject=Subject
|
||||||
|
label_bytes=Bytes
|
||||||
|
label_upload=Hochladen
|
||||||
|
header_export=Export
|
||||||
|
label_export_type=Export Type
|
||||||
|
label_filtered=Filtered
|
||||||
|
label_include_deleted=Include deleted
|
||||||
|
label_include_log=Include Logs
|
||||||
|
label_template_booking_executed=Booking executed template
|
||||||
|
label_street=Street
|
||||||
|
label_zipCode=ZIP Code
|
||||||
|
label_city=City
|
||||||
|
label_groupName=Groupname
|
||||||
|
label_phoneNumber=Phone Number
|
||||||
|
label_template_waitlist_cancelled=Waitlist cancelled mail template
|
||||||
|
msgs_menu_status=Status
|
||||||
|
menu_status=Status
|
||||||
7
account-ui/src/main/webapp/WEB-INF/beans.xml
Normal file
7
account-ui/src/main/webapp/WEB-INF/beans.xml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
|
||||||
|
version="1.1"
|
||||||
|
bean-discovery-mode="all">
|
||||||
|
</beans>
|
||||||
26
account-ui/src/main/webapp/WEB-INF/faces-config.xml
Normal file
26
account-ui/src/main/webapp/WEB-INF/faces-config.xml
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
|
<faces-config version="2.2"
|
||||||
|
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd">
|
||||||
|
|
||||||
|
<application>
|
||||||
|
<el-resolver>org.primefaces.application.exceptionhandler.PrimeExceptionHandlerELResolver</el-resolver>
|
||||||
|
|
||||||
|
<locale-config>
|
||||||
|
<default-locale>en</default-locale>
|
||||||
|
<supported-locale>en</supported-locale>
|
||||||
|
<supported-locale>de</supported-locale>
|
||||||
|
</locale-config>
|
||||||
|
<!-- register own messages for general i18n support -->
|
||||||
|
<resource-bundle>
|
||||||
|
<base-name>de.muehlencord.shared.account.web.presentation.messages</base-name>
|
||||||
|
<var>msgs</var>
|
||||||
|
</resource-bundle>
|
||||||
|
</application>
|
||||||
|
<factory>
|
||||||
|
<exception-handler-factory>org.omnifaces.exceptionhandler.FullAjaxExceptionHandlerFactory</exception-handler-factory>
|
||||||
|
</factory>
|
||||||
|
|
||||||
|
|
||||||
|
</faces-config>
|
||||||
57
account-ui/src/main/webapp/WEB-INF/shiro.ini
Normal file
57
account-ui/src/main/webapp/WEB-INF/shiro.ini
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
[main]
|
||||||
|
cacheManager = org.apache.shiro.cache.MemoryConstrainedCacheManager
|
||||||
|
securityManager.cacheManager = $cacheManager
|
||||||
|
|
||||||
|
# DataSource Setup
|
||||||
|
datasource = org.apache.shiro.jndi.JndiObjectFactory
|
||||||
|
datasource.resourceName = java:/jboss/accountTestDs
|
||||||
|
# TODO - change to accountDs
|
||||||
|
datasource.resourceRef = true
|
||||||
|
|
||||||
|
# HashService
|
||||||
|
hashService = org.apache.shiro.crypto.hash.DefaultHashService
|
||||||
|
hashService.hashIterations = 500000
|
||||||
|
hashService.hashAlgorithmName = SHA-512
|
||||||
|
hashService.generatePublicSalt = true
|
||||||
|
|
||||||
|
# Password service
|
||||||
|
passwordService = org.apache.shiro.authc.credential.DefaultPasswordService
|
||||||
|
passwordService.hashService = $hashService
|
||||||
|
|
||||||
|
# Required password matcher
|
||||||
|
passwordMatcher = org.apache.shiro.authc.credential.PasswordMatcher
|
||||||
|
passwordMatcher.passwordService = $passwordService
|
||||||
|
|
||||||
|
# JDBC Realm setup
|
||||||
|
jdbcRealm = org.apache.shiro.realm.jdbc.JdbcRealm
|
||||||
|
jdbcRealm.permissionsLookupEnabled=false
|
||||||
|
jdbcRealm.authenticationQuery = select account_password from account where username = ? and status not in ('LOCKED','DELETED')
|
||||||
|
jdbcRealm.userRolesQuery = select r.role_name from application_role r, account_role ar, account a WHERE a.username = ? AND a.id = ar.account AND ar.account_role = r.id
|
||||||
|
jdbcRealm.credentialsMatcher = $passwordMatcher
|
||||||
|
jdbcRealm.dataSource = $datasource
|
||||||
|
|
||||||
|
# Activate realms
|
||||||
|
authcStrategy = org.apache.shiro.authc.pam.AllSuccessfulStrategy
|
||||||
|
securityManager.realms = $jdbcRealm
|
||||||
|
securityManager.authenticator.authenticationStrategy = $authcStrategy
|
||||||
|
|
||||||
|
# Setup authentication filter
|
||||||
|
authc = de.muehlencord.shirofaces.filter.FacesAjaxAwarePassThruAuthenticationFilter
|
||||||
|
authc.loginUrl = /login.xhtml
|
||||||
|
authc.successUrl = /web/account.xhtml
|
||||||
|
|
||||||
|
roles.unauthorizedUrl = /error/accessDenied.xhtml
|
||||||
|
|
||||||
|
#
|
||||||
|
# filter setup
|
||||||
|
#
|
||||||
|
[urls]
|
||||||
|
/public/**=anon
|
||||||
|
/resources/**=anon
|
||||||
|
/fonts/**=anon
|
||||||
|
/javax.faces.resource/**=anon
|
||||||
|
/=anon
|
||||||
|
/index.html=anon
|
||||||
|
/login.xhtml=authc
|
||||||
|
/logout.xhtml=logout
|
||||||
|
/web/**=authc
|
||||||
123
account-ui/src/main/webapp/WEB-INF/web.xml
Normal file
123
account-ui/src/main/webapp/WEB-INF/web.xml
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
|
||||||
|
<display-name>reservation-system-backed</display-name>
|
||||||
|
<context-param>
|
||||||
|
<param-name>javax.faces.PROJECT_STAGE</param-name>
|
||||||
|
<param-value>${jsf.projectStage}</param-value>
|
||||||
|
</context-param>
|
||||||
|
<context-param>
|
||||||
|
<param-name>javax.faces.FACELETS_BUFFER_SIZE</param-name>
|
||||||
|
<param-value>1048576</param-value>
|
||||||
|
</context-param>
|
||||||
|
<context-param>
|
||||||
|
<param-name>primefaces.THEME</param-name>
|
||||||
|
<param-value>admin</param-value>
|
||||||
|
</context-param>
|
||||||
|
<context-param>
|
||||||
|
<param-name>primefaces.FONT_AWESOME</param-name>
|
||||||
|
<param-value>true</param-value>
|
||||||
|
</context-param>
|
||||||
|
<context-param>
|
||||||
|
<param-name>primefaces.MOVE_SCRIPTS_TO_BOTTOM</param-name>
|
||||||
|
<param-value>true</param-value>
|
||||||
|
</context-param>
|
||||||
|
<servlet>
|
||||||
|
<servlet-name>FacesServlet</servlet-name>
|
||||||
|
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
|
||||||
|
<load-on-startup>1</load-on-startup>
|
||||||
|
</servlet>
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>FacesServlet</servlet-name>
|
||||||
|
<url-pattern>*.xhtml</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
<session-config>
|
||||||
|
<session-timeout>
|
||||||
|
30
|
||||||
|
</session-timeout>
|
||||||
|
</session-config>
|
||||||
|
<welcome-file-list>
|
||||||
|
<welcome-file>web/account.xhtml</welcome-file>
|
||||||
|
</welcome-file-list>
|
||||||
|
<!-- Shiro Web Environment -->
|
||||||
|
<listener>
|
||||||
|
<listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
|
||||||
|
</listener>
|
||||||
|
<filter>
|
||||||
|
<display-name>ShiroFilter</display-name>
|
||||||
|
<filter-name>shiroFilter</filter-name>
|
||||||
|
<filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
|
||||||
|
</filter>
|
||||||
|
<filter-mapping>
|
||||||
|
<filter-name>shiroFilter</filter-name>
|
||||||
|
<url-pattern>/*</url-pattern>
|
||||||
|
<dispatcher>REQUEST</dispatcher>
|
||||||
|
<dispatcher>FORWARD</dispatcher>
|
||||||
|
<dispatcher>INCLUDE</dispatcher>
|
||||||
|
<dispatcher>ERROR</dispatcher>
|
||||||
|
</filter-mapping>
|
||||||
|
<!-- Faces Exception Filter -->
|
||||||
|
<filter>
|
||||||
|
<display-name>FacesExceptionFilter</display-name>
|
||||||
|
<filter-name>facesExceptionFilter</filter-name>
|
||||||
|
<filter-class>org.omnifaces.filter.FacesExceptionFilter</filter-class>
|
||||||
|
</filter>
|
||||||
|
<filter-mapping>
|
||||||
|
<filter-name>facesExceptionFilter</filter-name>
|
||||||
|
<servlet-name>FacesServlet</servlet-name>
|
||||||
|
</filter-mapping>
|
||||||
|
<!-- Content Security Policy headers -->
|
||||||
|
<filter>
|
||||||
|
<filter-name>contentSecurityFilter</filter-name>
|
||||||
|
<filter-class>de.muehlencord.sf.filter.ContentSecurityPolicyFilter</filter-class>
|
||||||
|
<init-param>
|
||||||
|
<param-name>report-only</param-name>
|
||||||
|
<param-value>false</param-value>
|
||||||
|
</init-param>
|
||||||
|
<init-param>
|
||||||
|
<param-name>default-src</param-name>
|
||||||
|
<param-value>'none'</param-value>
|
||||||
|
</init-param>
|
||||||
|
<init-param>
|
||||||
|
<param-name>img-src</param-name>
|
||||||
|
<param-value>'self'</param-value>
|
||||||
|
</init-param>
|
||||||
|
<init-param>
|
||||||
|
<param-name>script-src</param-name>
|
||||||
|
<param-value>'self' 'unsafe-inline' 'unsafe-eval'</param-value>
|
||||||
|
</init-param>
|
||||||
|
<init-param>
|
||||||
|
<param-name>style-src</param-name>
|
||||||
|
<param-value>'self' 'unsafe-inline'</param-value>
|
||||||
|
</init-param>
|
||||||
|
<init-param>
|
||||||
|
<param-name>connect-src</param-name>
|
||||||
|
<param-value>'self'</param-value>
|
||||||
|
</init-param>
|
||||||
|
<init-param>
|
||||||
|
<param-name>font-src</param-name>
|
||||||
|
<param-value>'self'</param-value>
|
||||||
|
</init-param>
|
||||||
|
<init-param>
|
||||||
|
<param-name>object-src</param-name>
|
||||||
|
<param-value>'none'</param-value>
|
||||||
|
</init-param>
|
||||||
|
<init-param>
|
||||||
|
<param-name>media-src</param-name>
|
||||||
|
<param-value>'none'</param-value>
|
||||||
|
</init-param>
|
||||||
|
<init-param>
|
||||||
|
<param-name>child-src</param-name>
|
||||||
|
<param-value>'none'</param-value>
|
||||||
|
</init-param>
|
||||||
|
</filter>
|
||||||
|
<!-- Security related headers -->
|
||||||
|
<filter>
|
||||||
|
<display-name>OwaspStandardFilter</display-name>
|
||||||
|
<filter-name>owaspStandardFilter</filter-name>
|
||||||
|
<filter-class>de.muehlencord.sf.filter.OwaspStandardFilter</filter-class>
|
||||||
|
</filter>
|
||||||
|
<filter-mapping>
|
||||||
|
<filter-name>owaspStandardFilter</filter-name>
|
||||||
|
<url-pattern>/*</url-pattern>
|
||||||
|
</filter-mapping>
|
||||||
|
</web-app>
|
||||||
99
account-ui/src/main/webapp/login.xhtml
Normal file
99
account-ui/src/main/webapp/login.xhtml
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
<?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:h="http://java.sun.com/jsf/html"
|
||||||
|
xmlns:f="http://java.sun.com/jsf/core"
|
||||||
|
xmlns:p="http://primefaces.org/ui">
|
||||||
|
<h:head>
|
||||||
|
<title>Login Page</title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
|
<link rel="shortcut icon" href="#{resource['images/favicon/favicon.ico']}" />
|
||||||
|
<h:outputStylesheet name="css/admin.css" />
|
||||||
|
|
||||||
|
<style type="text/css">
|
||||||
|
/* below css hides growls in small screens and makes messages visible */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
|
||||||
|
body div.ui-growl {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
body div.ui-messages {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* below css hides messages in medium/big devices and makes growl visible in such devices */
|
||||||
|
@media (min-width: 769px) {
|
||||||
|
body div.ui-growl {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
body div.ui-messages {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
body.login-page {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
html {
|
||||||
|
background: url(#{resource[ 'images:login-bg.png' ]}) no-repeat center center fixed;
|
||||||
|
-webkit-background-size: cover;
|
||||||
|
-moz-background-size: cover;
|
||||||
|
-o-background-size: cover;
|
||||||
|
background-size: cover;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</h:head>
|
||||||
|
<h:body styleClass="hold-transition login-page">
|
||||||
|
<p:growl sticky="true">
|
||||||
|
<p:autoUpdate />
|
||||||
|
</p:growl>
|
||||||
|
<div id="loader" class="load-bar" style="display: none">
|
||||||
|
<div class="bar"></div>
|
||||||
|
<div class="bar"></div>
|
||||||
|
<div class="bar"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="login-box">
|
||||||
|
<div class="login-logo">
|
||||||
|
<p:link href="/web/account.xhtml"><b>Account </b>Management</p:link>
|
||||||
|
<h:outputLabel rendered="#{instanceView.developmentVersion}" value="#{instanceView.instanceName}" />
|
||||||
|
</div>
|
||||||
|
<!-- /.login-logo -->
|
||||||
|
<div class="box login-box-body">
|
||||||
|
<h:form>
|
||||||
|
<p:focus context="panel" for="username" />
|
||||||
|
|
||||||
|
<p class="login-box-msg">Sign in to start your session</p>
|
||||||
|
<p:messages closable="true" />
|
||||||
|
|
||||||
|
|
||||||
|
<div id="panel" class="form-group has-feedback">
|
||||||
|
<p:inputText id="username" value="#{loginView.username}" styleClass="form-control" placeholder="Username"
|
||||||
|
required="true" autocomplete="off"
|
||||||
|
requiredMessage="Username is required."/>
|
||||||
|
<i class="fa fa-user form-control-feedback"></i>
|
||||||
|
</div>
|
||||||
|
<div class="form-group has-feedback">
|
||||||
|
<p:inputText value="#{loginView.password}" type="password" styleClass="form-control"
|
||||||
|
placeholder="Password" required="true" autocomplete="off" size="40"
|
||||||
|
requiredMessage="Password is required."/>
|
||||||
|
<i class="fa fa-lock form-control-feedback" style="font-size: 18px" ></i>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<p:spacer height="10"/>
|
||||||
|
<div class="col-xs-12">
|
||||||
|
<p:commandButton styleClass="btn btn-success btn-block" onclick="showBar()"
|
||||||
|
action="#{loginView.authenticate}" oncomplete="if(args.validationFailed) { hideBar()}"
|
||||||
|
value="Sign In" process="@form" update="@form" icon="fa fa-sign-in" iconPos="left"/>
|
||||||
|
<p> </p>
|
||||||
|
<p:commandButton styleClass="btn btn-primary btn-block" action="#{menuView.publicHome}"
|
||||||
|
value="Home" immediate="true" icon="fa fa-home" iconPos="left" ajax="false"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</h:form>
|
||||||
|
</div>
|
||||||
|
<!-- /.login-box-body -->
|
||||||
|
</div>
|
||||||
|
</h:body>
|
||||||
|
</html>
|
||||||
15
account-ui/src/main/webapp/logout.xhtml
Normal file
15
account-ui/src/main/webapp/logout.xhtml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns:ui="http://java.sun.com/jsf/facelets"
|
||||||
|
xmlns:p="http://primefaces.org/ui"
|
||||||
|
template="/resources/template/template.xhtml">
|
||||||
|
|
||||||
|
<ui:define name="title">
|
||||||
|
Logout
|
||||||
|
</ui:define>
|
||||||
|
|
||||||
|
<ui:define name="body">
|
||||||
|
<h2>You are logged out. </h2>
|
||||||
|
</ui:define>
|
||||||
|
|
||||||
|
</ui:composition>
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
To change this license header, choose License Headers in Project Properties.
|
||||||
|
To change this template file, choose Tools | Templates
|
||||||
|
and open the template in the editor.
|
||||||
|
-->
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns:composite="http://java.sun.com/jsf/composite"
|
||||||
|
xmlns:p="http://primefaces.org/ui">
|
||||||
|
<composite:interface />
|
||||||
|
|
||||||
|
<composite:implementation>
|
||||||
|
<p:confirmDialog global="true" showEffect="fade" hideEffect="fade" styleClass="box-solid box-danger">
|
||||||
|
<p:commandButton value="Yes" type="button" styleClass="btn-material btn-primary ui-confirmdialog-yes"
|
||||||
|
icon="fa fa-check"/>
|
||||||
|
<p:commandButton value="No" type="button" styleClass="btn-material btn-danger ui-confirmdialog-no"
|
||||||
|
icon="fa fa-close"/>
|
||||||
|
</p:confirmDialog>
|
||||||
|
</composite:implementation>
|
||||||
|
</html>
|
||||||
18
account-ui/src/main/webapp/resources/css/admin.css
Normal file
18
account-ui/src/main/webapp/resources/css/admin.css
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
To change this license header, choose License Headers in Project Properties.
|
||||||
|
To change this template file, choose Tools | Templates
|
||||||
|
and open the template in the editor.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
Created on : 24.10.2018, 19:31:57
|
||||||
|
Author : Joern Muehlencord <joern at muehlencord.de>
|
||||||
|
*/
|
||||||
|
|
||||||
|
.watermark {
|
||||||
|
position: absolute;
|
||||||
|
opacity: 0.25;
|
||||||
|
font-size: 3em;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
15
account-ui/src/main/webapp/resources/template/footer.xhtml
Normal file
15
account-ui/src/main/webapp/resources/template/footer.xhtml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||||
|
<!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:h="http://java.sun.com/jsf/html"
|
||||||
|
xmlns:ui="http://java.sun.com/jsf/facelets">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
|
||||||
|
<title>Account Management</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<ui:composition>
|
||||||
|
© Joern Muehlencord - Account Management - version ${applicationController.version} - build date ${applicationController.buildDate}
|
||||||
|
</ui:composition>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
46
account-ui/src/main/webapp/resources/template/leftmenu.xhtml
Normal file
46
account-ui/src/main/webapp/resources/template/leftmenu.xhtml
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns:h="http://java.sun.com/jsf/html"
|
||||||
|
xmlns:ui="http://java.sun.com/jsf/facelets"
|
||||||
|
xmlns:p="http://primefaces.org/ui"
|
||||||
|
xmlns:shiro="http://shiro.apache.org/tags">
|
||||||
|
|
||||||
|
|
||||||
|
<shiro:authenticated>
|
||||||
|
<ul class="sidebar-menu tree" data-widget="tree">
|
||||||
|
<li>
|
||||||
|
<p:link outcome="/web/index.xhtml">
|
||||||
|
<i class="fa fa-tablet"></i>
|
||||||
|
<span>Application</span>
|
||||||
|
</p:link>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p:link outcome="/web/permissions.xhtml">
|
||||||
|
<i class="fa fa-list-ul"></i>
|
||||||
|
<span>Permissions</span>
|
||||||
|
</p:link>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p:link outcome="/web/roles.xhtml">
|
||||||
|
<i class="fa fa-circle"></i>
|
||||||
|
<span>Roles</span>
|
||||||
|
</p:link>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p:link outcome="/web/account.xhtml">
|
||||||
|
<i class="fa fa-user"></i>
|
||||||
|
<span>Accounts</span>
|
||||||
|
</p:link>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<p:commandLink target="/logout.xhtml" actionListener="#{loginView.logout}">
|
||||||
|
<i class="fa fa-sign-out"></i>
|
||||||
|
<span>Logout</span>
|
||||||
|
</p:commandLink>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</shiro:authenticated>
|
||||||
|
</ui:composition>
|
||||||
50
account-ui/src/main/webapp/resources/template/template.xhtml
Normal file
50
account-ui/src/main/webapp/resources/template/template.xhtml
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright 2018 joern@muehlencord.de
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns:ui="http://java.sun.com/jsf/facelets"
|
||||||
|
xmlns:p="http://primefaces.org/ui"
|
||||||
|
template="/admin.xhtml"
|
||||||
|
xmlns:h="http://xmlns.jcp.org/jsf/html">
|
||||||
|
|
||||||
|
<ui:define name="head">
|
||||||
|
<title>Product Catalog Designer</title>
|
||||||
|
<link rel="shortcut icon" href="#{resource['images/favicon/favicon.ico']}" />
|
||||||
|
<h:outputStylesheet name="css/admin.css" />
|
||||||
|
</ui:define>
|
||||||
|
|
||||||
|
<ui:define name="logo-lg">
|
||||||
|
Account Management
|
||||||
|
</ui:define>
|
||||||
|
|
||||||
|
<ui:define name="logo-mini">
|
||||||
|
AM
|
||||||
|
</ui:define>
|
||||||
|
|
||||||
|
<ui:define name="menu">
|
||||||
|
<ui:include src="/resources/template/leftmenu.xhtml"/>
|
||||||
|
</ui:define>
|
||||||
|
|
||||||
|
<ui:define name="footer">
|
||||||
|
<ui:include src="/resources/template/footer.xhtml"/>
|
||||||
|
</ui:define>
|
||||||
|
|
||||||
|
<ui:define name="content-end">
|
||||||
|
<h:outputLabel styleClass="watermark" rendered="#{instanceView.developmentVersion}" value="#{instanceView.instanceName}" />
|
||||||
|
</ui:define>
|
||||||
|
|
||||||
|
|
||||||
|
</ui:composition>
|
||||||
251
account-ui/src/main/webapp/web/account.xhtml
Normal file
251
account-ui/src/main/webapp/web/account.xhtml
Normal file
@ -0,0 +1,251 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns:ui="http://java.sun.com/jsf/facelets"
|
||||||
|
xmlns:p="http://primefaces.org/ui"
|
||||||
|
template="/resources/template/template.xhtml"
|
||||||
|
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||||
|
xmlns:f="http://xmlns.jcp.org/jsf/core"
|
||||||
|
xmlns:co="http://java.sun.com/jsf/composite/composite"
|
||||||
|
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
|
||||||
|
xmlns:composite="http://xmlns.jcp.org/jsf/composite/composite">
|
||||||
|
|
||||||
|
<ui:define name="title">
|
||||||
|
Account Overview
|
||||||
|
</ui:define>
|
||||||
|
|
||||||
|
<ui:define name="description">
|
||||||
|
List all accounts
|
||||||
|
</ui:define>
|
||||||
|
|
||||||
|
<ui:define name="body">
|
||||||
|
<h:form id="accountForm">
|
||||||
|
<p:dataTable id="accountTable" value="#{accountView.accounts}" var="account" rowKey="#{account.username}" selectionMode="single" selection="#{accountView.currentAccount}"
|
||||||
|
styleClass="box-primary">
|
||||||
|
<p:ajax event="rowSelect" update="deleteButton,editButton" listener="#{accountView.selectAccount}" />
|
||||||
|
<p:ajax event="rowUnselect" update="deleteButton,editButton" listener="#{accountView.deselectAccount}" />
|
||||||
|
<p:column headerText="Username">
|
||||||
|
<h:outputText value="#{account.username}" />
|
||||||
|
</p:column>
|
||||||
|
<p:column headerText="Lastname">
|
||||||
|
<h:outputText value="#{account.lastname}" />
|
||||||
|
</p:column>
|
||||||
|
<p:column headerText="Firstname">
|
||||||
|
<h:outputText value="#{account.firstname}" />
|
||||||
|
</p:column>
|
||||||
|
<p:column headerText="Email">
|
||||||
|
<h:outputText value="#{account.emailaddress}" />
|
||||||
|
</p:column>
|
||||||
|
<p:column headerText="Last login">
|
||||||
|
<h:outputText value="#{account.lastLogin}" />
|
||||||
|
</p:column>
|
||||||
|
<p:column headerText="Status">
|
||||||
|
<h:outputText value="#{account.status}" />
|
||||||
|
</p:column>
|
||||||
|
<p:column headerText="CreatedOn">
|
||||||
|
<h:outputText value="#{account.createdOn}" >
|
||||||
|
<f:convertDateTime type="both" dateStyle="full" timeStyle="short" timeZone="Europe/Berlin"/>
|
||||||
|
</h:outputText>
|
||||||
|
</p:column>
|
||||||
|
<p:column headerText="CreatedBy">
|
||||||
|
<h:outputText value="#{account.createdBy}" />
|
||||||
|
</p:column>
|
||||||
|
<p:column headerText="LastUpdatedOn">
|
||||||
|
<h:outputText value="#{account.lastUpdatedOn}">
|
||||||
|
<f:convertDateTime type="both" dateStyle="full" timeStyle="short" timeZone="Europe/Berlin"/>
|
||||||
|
</h:outputText>
|
||||||
|
</p:column>
|
||||||
|
<p:column headerText="LastUpdatedBy">
|
||||||
|
<h:outputText value="#{account.lastUpdatedBy}" />
|
||||||
|
</p:column>
|
||||||
|
<f:facet name="footer" >
|
||||||
|
|
||||||
|
<div class="col-sm-12 col-md-3" style="margin-top:10px">
|
||||||
|
<p:spacer height="10px" />
|
||||||
|
<div class="ui-inputgroup" >
|
||||||
|
<h:outputLabel for="includeDisabledCheckbox" value="Include disabled accounts?" />
|
||||||
|
<p:inputSwitch id="includeDisabledCheckbox" value="#{accountView.showDisabledAccounts}" styleClass="btn-teal btn-block" >
|
||||||
|
<p:ajax listener="#{accountView.showDisabledAccountsChange}" update="accountTable" />
|
||||||
|
</p:inputSwitch>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-12 col-md-3">
|
||||||
|
<p:spacer height="10px" />
|
||||||
|
<p:commandButton value="New" id="newButton" icon="fa fa-plus"
|
||||||
|
update="editDialog" oncomplete="PF('editDialogVar').show();"
|
||||||
|
actionListener="#{accountView.newAccount}" styleClass="btn-primary btn-block" />
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12 col-md-3">
|
||||||
|
<p:spacer height="10px" />
|
||||||
|
<p:commandButton value="Edit" id="editButton" icon="fa fa-pencil"
|
||||||
|
update="editDialog" oncomplete="PF('editDialogVar').show();"
|
||||||
|
actionListener="#{accountView.editAccount}" disabled="#{!accountView.accountSelected}" styleClass="btn-teal btn-block" />
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12 col-md-3">
|
||||||
|
<p:spacer height="10px" />
|
||||||
|
<p:commandButton value="Delete" id="deleteButton" icon="fa fa-fw fa-trash-o"
|
||||||
|
update=":accountForm:accountTable" action="#{accountView.deleteAccount}" disabled="#{!accountView.accountSelected}" styleClass="btn-danger btn-block">
|
||||||
|
<p:confirm header="Confirmation" message="Are you sure?" icon="fa fa-exclamation-triangle" />
|
||||||
|
</p:commandButton>
|
||||||
|
</div>
|
||||||
|
</f:facet>
|
||||||
|
</p:dataTable>
|
||||||
|
|
||||||
|
<composite:confirmationDialog />
|
||||||
|
</h:form>
|
||||||
|
|
||||||
|
|
||||||
|
<p:dialog id="editDialog" widgetVar="editDialogVar" header="Edit account" width="600"
|
||||||
|
modal="true" appendTo="@(body)" showEffect="fade" hideEffect="fade" styleClass="box-solid box-primary" >
|
||||||
|
<h:form id="editDialogForm">
|
||||||
|
<p:messages id="editDialogMessages" showDetail="true" showIcon="true" showSummary="true">
|
||||||
|
<p:autoUpdate />
|
||||||
|
</p:messages>
|
||||||
|
|
||||||
|
<div class="ui-g ui-fluid">
|
||||||
|
<div class="col-sm-12 col-md-3">
|
||||||
|
<p:outputLabel for="username" value="Username" />
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12 col-md-6">
|
||||||
|
<c:if test="#{accountView.currentAccount.createdBy != null}">
|
||||||
|
<h:outputText id="username" value="#{accountView.currentAccount.username}" />
|
||||||
|
</c:if>
|
||||||
|
<c:if test="#{accountView.currentAccount.createdBy == null}">
|
||||||
|
<p:inputText id="username" value="#{accountView.currentAccount.username}" />
|
||||||
|
</c:if>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12 col-md-3">
|
||||||
|
<p:message for="username"><p:autoUpdate /></p:message>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-12 col-md-3">
|
||||||
|
<p:outputLabel for="lastname" value="Lastname" />
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12 col-md-6">
|
||||||
|
<p:inputText id="lastname" value="#{accountView.currentAccount.lastname}" size="40" maxlength="100"/>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12 col-md-3 ">
|
||||||
|
<p:message for="lastname"> <p:autoUpdate /></p:message>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-12 col-md-3">
|
||||||
|
<p:outputLabel for="firstname" value="Firstname" />
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12 col-md-6">
|
||||||
|
<p:inputText id="firstname" value="#{accountView.currentAccount.firstname}" size="40" maxlength="100" />
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12 col-md-3">
|
||||||
|
<p:message for="firstname"> <p:autoUpdate /></p:message>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-12 col-md-3">
|
||||||
|
<p:outputLabel for="emailaddress" value="emailaddress" />
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12 col-md-6">
|
||||||
|
<p:inputText id="emailaddress" value="#{accountView.currentAccount.emailaddress}" size="40" maxlength="200">
|
||||||
|
<f:validator validatorId="de.muehlencord.shared.jeeutil.validator.EmailValidator" />
|
||||||
|
</p:inputText>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12 col-md-3">
|
||||||
|
<p:message for="emailaddress"> <p:autoUpdate /></p:message>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<c:if test="#{accountView.currentAccount.username != null}">
|
||||||
|
|
||||||
|
<div class="col-sm-12 col-md-3">
|
||||||
|
<p:outputLabel for="status" value="Status" />
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12 col-md-6">
|
||||||
|
<p:selectOneMenu id="status" value="#{accountView.currentAccount.status}" >
|
||||||
|
<f:selectItems value="#{accountView.statusList}" />
|
||||||
|
</p:selectOneMenu>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12 col-md-3">
|
||||||
|
<p:message for="status" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-12 col-md-3">
|
||||||
|
<p:outputLabel for="lastlogin" value="Lastlogin" />
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12 col-md-3">
|
||||||
|
<h:outputText id="lastlogin" value="#{accountView.currentAccount.lastLogin}" />
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12 col-md-6">
|
||||||
|
<p:message for="lastlogin" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-12 col-md-3">
|
||||||
|
<p:outputLabel for="createdon" value="Created on" />
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12 col-md-6">
|
||||||
|
<h:outputText id="createdon" value="#{accountView.currentAccount.createdOn}" />
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12 col-md-3">
|
||||||
|
<p:message for="createdon" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-12 col-md-3">
|
||||||
|
<p:outputLabel for="createdby" value="Created by" />
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12 col-md-6">
|
||||||
|
<h:outputText id="createdby" value="#{accountView.currentAccount.createdBy}" />
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12 col-md-3">
|
||||||
|
<p:message for="createdby" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-12 col-md-3">
|
||||||
|
<p:outputLabel for="lastupdatedon" value="Last updated on" />
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12 col-md-6">
|
||||||
|
<h:outputText id="lastupdatedon" value="#{accountView.currentAccount.lastUpdatedOn}" />
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12 col-md-3">
|
||||||
|
<p:message for="lastupdatedon" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-12 col-md-3">
|
||||||
|
<p:outputLabel for="lastupdatedby" value="Last updated by" />
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12 col-md-6">
|
||||||
|
<h:outputText id="lastupdatedby" value="#{accountView.currentAccount.lastUpdatedBy}" />
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12 col-md-3">
|
||||||
|
<p:message for="lastupdatedby" />
|
||||||
|
</div>
|
||||||
|
</c:if>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="col-sm-12 col-md-3">
|
||||||
|
<p:outputLabel for="roles" value="Roles" />
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12 col-md-6">
|
||||||
|
<p:selectManyMenu id="roles" var="role" label="#{role.roleName}" value="#{accountView.currentAccountRoles}" converter="omnifaces.SelectItemsConverter" required="true" >
|
||||||
|
<f:selectItems value="#{accountView.allApplicationRoles}" var="roleItem" itemLabel="#{roleItem.roleName}" itemValue="#{role}" />
|
||||||
|
<p:column>
|
||||||
|
<h:outputText value="#{role.roleName}"/>
|
||||||
|
</p:column>
|
||||||
|
</p:selectManyMenu>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12 col-md-3">
|
||||||
|
<p:message for="roles" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="col-sm-12 col-md-6">
|
||||||
|
<p:spacer height="10px" />
|
||||||
|
<p:commandButton value="Save" action="#{accountView.saveEditAccount}" styleClass="btn-primary btn-block"
|
||||||
|
oncomplete="if (args && !args.validationFailed) PF('editDialogVar').hide();" update=":accountForm:accountTable" />
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12 col-md-6">
|
||||||
|
<p:spacer height="10px" />
|
||||||
|
<p:commandButton value="Cancel" action="#{accountView.cancelEditAccount}" immediate="true" styleClass="btn-teal btn-block"
|
||||||
|
oncomplete="PF('editDialogVar').hide();" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</h:form>
|
||||||
|
</p:dialog>
|
||||||
|
|
||||||
|
</ui:define>
|
||||||
|
|
||||||
|
</ui:composition>
|
||||||
76
account-ui/src/main/webapp/web/index.xhtml
Normal file
76
account-ui/src/main/webapp/web/index.xhtml
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns:ui="http://java.sun.com/jsf/facelets"
|
||||||
|
xmlns:p="http://primefaces.org/ui"
|
||||||
|
template="/resources/template/template.xhtml"
|
||||||
|
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||||
|
xmlns:f="http://xmlns.jcp.org/jsf/core"
|
||||||
|
xmlns:co="http://java.sun.com/jsf/composite/composite"
|
||||||
|
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
|
||||||
|
xmlns:composite="http://xmlns.jcp.org/jsf/composite/composite">
|
||||||
|
|
||||||
|
<ui:define name="title">
|
||||||
|
Applications
|
||||||
|
</ui:define>
|
||||||
|
|
||||||
|
<ui:define name="body" >
|
||||||
|
|
||||||
|
<h:form id="applicationForm">
|
||||||
|
<p:panel styleClass="box-solid">
|
||||||
|
<div class="ui-g ui-fluid">
|
||||||
|
<div class="col-sm-12 col-md-6">
|
||||||
|
<p:selectOneMenu id="applicationSelect" value="#{applicationView.currentApplication}" converter="omnifaces.SelectItemsConverter" required="true">
|
||||||
|
<f:selectItems value="#{applicationView.allApplications}" var="app" itemLabel="#{app.applicationName}" itemValue="#{app}" />
|
||||||
|
</p:selectOneMenu>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12 col-md-3">
|
||||||
|
<p:commandButton value="Select" styleClass="btn-primary btn-solid}" actionListener="#{applicationView.selectApplication}" />
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12 col-md-3">
|
||||||
|
<p:commandButton value="New" id="newButton" icon="fa fa-plus"
|
||||||
|
update="editDialog" oncomplete="PF('editDialogVar').show();"
|
||||||
|
actionListener="#{applicationView.newApplication}" styleClass="btn-teal btn-block" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</p:panel>
|
||||||
|
</h:form>
|
||||||
|
|
||||||
|
<p:dialog id="editDialog" widgetVar="editDialogVar" header="Edit account" width="600"
|
||||||
|
modal="true" appendTo="@(body)" showEffect="fade" hideEffect="fade" styleClass="box-solid box-primary" >
|
||||||
|
<h:form id="editDialogForm">
|
||||||
|
<p:messages id="editDialogMessages" showDetail="true" showIcon="true" showSummary="true">
|
||||||
|
<p:autoUpdate />
|
||||||
|
</p:messages>
|
||||||
|
|
||||||
|
<div class="ui-g ui-fluid">
|
||||||
|
<div class="col-sm-12 col-md-3">
|
||||||
|
<p:outputLabel for="applicationName" value="Application name" />
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12 col-md-6">
|
||||||
|
<p:inputText id="applicationName" value="#{applicationView.editApplication.applicationName}">
|
||||||
|
<f:validator validatorId="uniqueApplicationValidator"/>
|
||||||
|
<f:attribute name="applicationName" value="#{applicationView.editApplication.applicationName}" />
|
||||||
|
</p:inputText>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12 col-md-3">
|
||||||
|
<p:message for="applicationName"><p:autoUpdate /></p:message>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-12 col-md-6">
|
||||||
|
<p:spacer height="10px" />
|
||||||
|
<p:commandButton value="Save" action="#{applicationView.saveEditApplication}" styleClass="btn-primary btn-block"
|
||||||
|
oncomplete="if (args && !args.validationFailed) PF('editDialogVar').hide();" update=":applicationForm" />
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12 col-md-6">
|
||||||
|
<p:spacer height="10px" />
|
||||||
|
<p:commandButton value="Cancel" action="#{applicationView.cancelEditApplication}" immediate="true" styleClass="btn-teal btn-block"
|
||||||
|
oncomplete="PF('editDialogVar').hide();" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</h:form>
|
||||||
|
</p:dialog>
|
||||||
|
|
||||||
|
</ui:define>
|
||||||
|
</ui:composition>
|
||||||
73
account-ui/src/main/webapp/web/permissions.xhtml
Normal file
73
account-ui/src/main/webapp/web/permissions.xhtml
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns:ui="http://java.sun.com/jsf/facelets"
|
||||||
|
xmlns:p="http://primefaces.org/ui"
|
||||||
|
template="/resources/template/template.xhtml"
|
||||||
|
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||||
|
xmlns:f="http://xmlns.jcp.org/jsf/core"
|
||||||
|
xmlns:co="http://java.sun.com/jsf/composite/composite"
|
||||||
|
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
|
||||||
|
xmlns:composite="http://xmlns.jcp.org/jsf/composite/composite">
|
||||||
|
|
||||||
|
<ui:define name="title">
|
||||||
|
Permissions
|
||||||
|
</ui:define>
|
||||||
|
|
||||||
|
<ui:define name="description">
|
||||||
|
Edit permissions
|
||||||
|
</ui:define>
|
||||||
|
|
||||||
|
<ui:define name="body">
|
||||||
|
<h:form id="permissionForm">
|
||||||
|
<p:panel styleClass="card no-border">
|
||||||
|
<div class="ui-g ui-fluid">
|
||||||
|
<div class="ui-g-12 ui-md-3">
|
||||||
|
<div class="ui-inputgroup">
|
||||||
|
<span class="ui-inputgroup-addon"><i style="font-size: 20px" class="fa fa-edit"></i></span>
|
||||||
|
<p:inputText id="newName" value="#{permissionView.newPermissionName}" maxlength="80" size="30" placeholder="#{msgs.label_name}" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="ui-g-12 ui-md-3">
|
||||||
|
<div class="ui-inputgroup">
|
||||||
|
<span class="ui-inputgroup-addon"><i style="font-size: 20px" class="fa fa-edit"></i></span>
|
||||||
|
<p:inputText id="newDescription" value="#{permissionView.newPermissionDescription}" maxlength="200" size="30" placeholder="#{msgs.label_description}" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="ui-g-12 ui-md-2">
|
||||||
|
<p:commandButton icon="fa fa-fw fa-save" value="#{msgs.button_save}" action="#{permissionView.savePermission}"
|
||||||
|
update="permissionForm" styleClass="btn-primary btn-block" />
|
||||||
|
</div>
|
||||||
|
<div class="ui-g-12 ui-md-2">
|
||||||
|
<p:commandButton id="editPermissionButton" icon="fa fa-fw fa-pencil" value="#{msgs.button_edit}" action="#{permissionView.editPermission}"
|
||||||
|
update="permissionForm" styleClass="btn-teal btn-block" disabled="#{!permissionView.canEdit}" />
|
||||||
|
</div>
|
||||||
|
<div class="ui-g-12 ui-md-2">
|
||||||
|
<p:commandButton id="deletePermissionButton" icon="fa fa-fw fa-trash-o" value="#{msgs.button_delete}" action="#{permissionView.deletePermission}"
|
||||||
|
update="permissionForm" styleClass="btn-danger btn-block" disabled="#{!permissionView.canDelete}">
|
||||||
|
<p:confirm header="Confirmation" message="Are you sure?" icon="fa fa-fw fa-exclamation-triangle" />
|
||||||
|
</p:commandButton>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p:dataTable id="permissionTable" value="#{permissionView.appPermissions}" var="permission" rowKey="#{permission.id}"
|
||||||
|
selectionMode="single" selection="#{permissionView.currentPermission}" styleClass="box-primary">
|
||||||
|
<p:ajax event="rowSelect" update=":permissionForm" listener="#{permissionView.selectPermission}" />
|
||||||
|
<p:ajax event="rowUnselect" update=":permissionForm" listener="#{permissionView.deselectPermission}" />
|
||||||
|
|
||||||
|
<p:column headerText="Permission name">
|
||||||
|
<h:outputText value="#{permission.permissionName}" />
|
||||||
|
</p:column>
|
||||||
|
<p:column headerText="Permission description">
|
||||||
|
<h:outputText value="#{permission.permissionDescription}" />
|
||||||
|
</p:column>
|
||||||
|
</p:dataTable>
|
||||||
|
|
||||||
|
<composite:confirmationDialog />
|
||||||
|
</p:panel>
|
||||||
|
</h:form>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</ui:define>
|
||||||
|
|
||||||
|
</ui:composition>
|
||||||
96
account-ui/src/main/webapp/web/roles.xhtml
Normal file
96
account-ui/src/main/webapp/web/roles.xhtml
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns:ui="http://java.sun.com/jsf/facelets"
|
||||||
|
xmlns:p="http://primefaces.org/ui"
|
||||||
|
template="/resources/template/template.xhtml"
|
||||||
|
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||||
|
xmlns:co="http://java.sun.com/jsf/composite/composite"
|
||||||
|
xmlns:f="http://xmlns.jcp.org/jsf/core"
|
||||||
|
xmlns:composite="http://xmlns.jcp.org/jsf/composite/composite">
|
||||||
|
|
||||||
|
<ui:define name="title">
|
||||||
|
Group Overview
|
||||||
|
</ui:define>
|
||||||
|
|
||||||
|
<ui:define name="description">
|
||||||
|
List all groups
|
||||||
|
</ui:define>
|
||||||
|
|
||||||
|
<ui:define name="body">
|
||||||
|
<h:form id="groupForm">
|
||||||
|
<p:panel styleClass="card no-border">
|
||||||
|
<div class="ui-g ui-fluid">
|
||||||
|
<div class="ui-g-12 ui-md-3">
|
||||||
|
<div class="ui-inputgroup">
|
||||||
|
<span class="ui-inputgroup-addon"><i style="font-size: 20px" class="fa fa-user"></i></span>
|
||||||
|
<p:inputText id="newName" value="#{groupView.newRoleName}" placeholder="#{msgs.label_name}" maxlength="80" size="30" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="ui-g-12 ui-md-3">
|
||||||
|
<div class="ui-inputgroup">
|
||||||
|
<span class="ui-inputgroup-addon"><i style="font-size: 20px" class="fa fa-user"></i></span>
|
||||||
|
<p:inputText id="newDescription" value="#{groupView.newRoleDescription}" placeholder="#{msgs.label_description}" maxlength="200" size="40" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="ui-g-12 ui-md-2">
|
||||||
|
<p:commandButton icon="fa fa-fw fa-plus" value="#{msgs.button_save}" action="#{groupView.newRole}" update="groupForm" styleClass="btn-primary btn-block"/>
|
||||||
|
</div>
|
||||||
|
<div class="ui-g-12 ui-md-2">
|
||||||
|
<p:commandButton icon="fa fa-fw fa-pencil" value="#{msgs.button_edit}" action="#{groupView.editRole}" update="groupForm" styleClass="btn-teal btn-block"/>
|
||||||
|
</div>
|
||||||
|
<div class="ui-g-12 ui-md-2">
|
||||||
|
<p:commandButton icon="fa fa-fw fa-trash-o" value="#{msgs.button_delete}" action="#{groupView.deleteRole}" update="groupForm" styleClass="btn-danger btn-block">
|
||||||
|
<p:confirm header="Confirmation" message="Are you sure?" icon="fa fa-fw fa-exclamation-triangle" />
|
||||||
|
</p:commandButton>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</p:panel>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<p:dataTable id="groupTable" value="#{groupView.allRoles}" var="role" rowKey="#{role.id}" styleClass="box-solid box-primary"
|
||||||
|
selectionMode="single" selection="#{groupView.currentRole}">
|
||||||
|
<p:ajax event="rowSelect" update=":groupForm:permissionTable" listener="#{groupView.onRoleSelect}" />
|
||||||
|
<p:column headerText="Role name">
|
||||||
|
<h:outputText value="#{role.roleName}" />
|
||||||
|
</p:column>
|
||||||
|
<p:column headerText="Role description">
|
||||||
|
<h:outputText value="#{role.roleDescription}" />
|
||||||
|
</p:column>
|
||||||
|
</p:dataTable>
|
||||||
|
|
||||||
|
<p:dataTable id="permissionTable" value="#{groupView.rolePermissions}" var="permission" rowKey="#{permission.id}" styleClass="box-teal"
|
||||||
|
selectionMode="single" selection="#{groupView.currentPermission}">
|
||||||
|
<p:ajax event="rowSelect" update="deletePermissionButton" listener="#{groupView.selectPermission}" />
|
||||||
|
<p:ajax event="rowUnselect" update="deletePermissionButton" listener="#{groupView.deselectPermission}" />
|
||||||
|
|
||||||
|
<p:column headerText="Permission name">
|
||||||
|
<h:outputText value="#{permission.permissionName}" />
|
||||||
|
</p:column>
|
||||||
|
<p:column headerText="Permission description">
|
||||||
|
<h:outputText value="#{permission.permissionDescription}" />
|
||||||
|
</p:column>
|
||||||
|
<f:facet name="footer" >
|
||||||
|
<p:selectOneMenu value="#{groupView.newPermission}" converter="omnifaces.SelectItemsConverter" >
|
||||||
|
<f:selectItems id="permissionListItems" value="#{groupView.missingPermissions}" var="missingPermission" itemLabel="#{missingPermission.permissionName}" itemValue="#{missingPermission}" />
|
||||||
|
</p:selectOneMenu>
|
||||||
|
<div class="ui-g-12 ui-md-2">
|
||||||
|
<p:commandButton id="addPermissionButton" icon="fa fa-plus" value="#{msgs.button_new}" action="#{groupView.addRolePermission}"
|
||||||
|
update=":groupForm:permissionTable" styleClass="btn-primary btn-block"/>
|
||||||
|
</div>
|
||||||
|
<div class="ui-g-12 ui-md-2">
|
||||||
|
<p:commandButton id="deletePermissionButton" icon="fa fa-trash-o" value="Delete" update=":groupForm:groupTable,:groupForm:permissionTable"
|
||||||
|
action="#{groupView.removeRolePermission}" styleClass="btn-danger btn-block"
|
||||||
|
disabled="#{!groupView.isPermissionSelected}" >
|
||||||
|
<p:confirm header="Confirmation" message="Are you sure?" icon="fa fa-fw fa-exclamation-triangle" />
|
||||||
|
</p:commandButton>
|
||||||
|
</div>
|
||||||
|
</f:facet>
|
||||||
|
</p:dataTable>
|
||||||
|
|
||||||
|
<composite:confirmationDialog />
|
||||||
|
|
||||||
|
</h:form>
|
||||||
|
</ui:define>
|
||||||
|
|
||||||
|
</ui:composition>
|
||||||
Reference in New Issue
Block a user