Skip to content

Commit 9463576

Browse files
committed
added marty component (user and team management) Issue #32
1 parent 502d2ae commit 9463576

24 files changed

Lines changed: 1942 additions & 2077 deletions

docker/Dockerfile

Lines changed: 0 additions & 32 deletions
This file was deleted.

docker/README.md

Lines changed: 0 additions & 15 deletions
This file was deleted.

docker/configuration/wildfly/standalone.xml

Lines changed: 382 additions & 281 deletions
Large diffs are not rendered by default.
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
/*******************************************************************************
2+
* Imixs Workflow
3+
* Copyright (C) 2001, 2011 Imixs Software Solutions GmbH,
4+
* http://www.imixs.com
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU General Public License
8+
* as published by the Free Software Foundation; either version 2
9+
* of the License, or (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
* General Public License for more details.
15+
*
16+
* You can receive a copy of the GNU General Public
17+
* License at http://www.gnu.org/licenses/gpl.html
18+
*
19+
* Project:
20+
* http://www.imixs.org
21+
* http://java.net/projects/imixs-workflow
22+
*
23+
* Contributors:
24+
* Imixs Software Solutions GmbH - initial API and implementation
25+
* Ralph Soika - Software Developer
26+
*******************************************************************************/
27+
28+
package org.imixs.application.config;
29+
30+
import java.io.Serializable;
31+
import java.util.ArrayList;
32+
import java.util.Arrays;
33+
import java.util.List;
34+
import java.util.logging.Logger;
35+
36+
import org.imixs.marty.security.UserGroupService;
37+
import org.imixs.workflow.exceptions.AccessDeniedException;
38+
import org.imixs.workflow.exceptions.ModelException;
39+
import org.imixs.workflow.faces.data.WorkflowController;
40+
import org.imixs.workflow.faces.data.WorkflowEvent;
41+
42+
import jakarta.enterprise.context.SessionScoped;
43+
import jakarta.enterprise.event.Observes;
44+
import jakarta.inject.Inject;
45+
import jakarta.inject.Named;
46+
47+
/**
48+
* This AccessRoleController
49+
*
50+
* @author rsoika
51+
*
52+
*/
53+
@Named
54+
@SessionScoped
55+
public class AccessRoleController implements Serializable {
56+
57+
private static final long serialVersionUID = 1L;
58+
59+
@Inject
60+
UserGroupService userGroupService;
61+
62+
@Inject
63+
WorkflowController workflowController;
64+
65+
private String role;
66+
67+
public final static String[] ACCESS_ROLES = { "org.imixs.ACCESSLEVEL.MANAGERACCESS",
68+
"org.imixs.ACCESSLEVEL.EDITORACCESS", "org.imixs.ACCESSLEVEL.AUTHORACCESS",
69+
"org.imixs.ACCESSLEVEL.READERACCESS", "org.imixs.ACCESSLEVEL.NOACCESS"
70+
};
71+
72+
private static Logger logger = Logger.getLogger(AccessRoleController.class.getName());
73+
74+
public AccessRoleController() {
75+
super();
76+
}
77+
78+
/**
79+
* WorkflowEvent listener to update the current FormDefinition.
80+
*
81+
* @param workflowEvent
82+
* @throws AccessDeniedException
83+
* @throws ModelException
84+
*/
85+
@SuppressWarnings("unchecked")
86+
public void onWorkflowEvent(@Observes WorkflowEvent workflowEvent) {
87+
if (workflowEvent == null || workflowEvent.getWorkitem() == null) {
88+
return;
89+
}
90+
91+
// skip if not a profile...
92+
if (!workflowEvent.getWorkitem().getItemValueString("type").startsWith("profile")) {
93+
return;
94+
}
95+
96+
int eventType = workflowEvent.getEventType();
97+
if (WorkflowEvent.WORKITEM_CHANGED == eventType) {
98+
// extract the core role (migration from old usergroup names)
99+
List<String> groups = workflowEvent.getWorkitem().getItemValue("txtgroups");
100+
List<String> accessGroupList = new ArrayList<String>(Arrays.asList(ACCESS_ROLES));
101+
// test if we already have new role name.
102+
if (groups.size() == 1 && accessGroupList.contains(groups.get(0))) {
103+
setUserRole(groups.get(0));
104+
return;
105+
} else {
106+
// we need to extract the role. Frist try to find a core role
107+
for (String coreRole : accessGroupList) {
108+
if (groups.contains(coreRole)) {
109+
setUserRole(coreRole);
110+
return;
111+
}
112+
}
113+
logger.warning("profile does not contain new core role! - trying migration....");
114+
for (String group : groups) {
115+
// get the new core role.
116+
String newrole = userGroupService.getCoreGroupName(group);
117+
if (newrole != null) {
118+
setUserRole(newrole);
119+
return;
120+
}
121+
}
122+
logger.severe("unable to detect a valid group!");
123+
}
124+
}
125+
126+
if (WorkflowEvent.WORKITEM_BEFORE_PROCESS == eventType) {
127+
// add the new core gorup to txtgroups
128+
workflowEvent.getWorkitem().setItemValue("txtGroups", getUserRole());
129+
}
130+
131+
}
132+
133+
public void setUserRole(String role) {
134+
this.role = role;
135+
}
136+
137+
public String getUserRole() {
138+
return this.role;
139+
}
140+
141+
public String[] getAccessRoles() {
142+
return ACCESS_ROLES;
143+
}
144+
145+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package org.imixs.application.config;
2+
3+
import java.util.Map;
4+
import java.util.Set;
5+
6+
import org.eclipse.microprofile.config.spi.ConfigSource;
7+
8+
/**
9+
* The Marty PropertiesConfigSource is a custom config source based on
10+
* Microprofile Config API.
11+
* <p>
12+
* The properties of this config source are loaded by the Marty PropertiesLoader
13+
* EJB.
14+
* <p>
15+
* As per SPI it is necessary to register the implementation in
16+
* META-INF/services by adding an entry in a file called
17+
* 'org.eclipse.microprofile.config.spi.ConfigSource'
18+
* <p>
19+
* See implementation details here:
20+
* https://stackoverflow.com/questions/52117613/microprofile-config-custom-configsource-using-jpa/56498321#56498321
21+
*
22+
* @see PropertiesLoader
23+
* @author rsoika
24+
*
25+
*/
26+
public class PropertiesConfigSource implements ConfigSource {
27+
28+
public static final String NAME = "MartyConfigSource";
29+
public static Map<String, String> properties = null; // use static to overwrite early registered properties
30+
31+
@Override
32+
public int getOrdinal() {
33+
return 910;
34+
}
35+
36+
@Override
37+
public String getValue(String key) {
38+
if (properties != null) {
39+
return properties.get(key);
40+
} else {
41+
return null;
42+
}
43+
}
44+
45+
@Override
46+
public String getName() {
47+
return NAME;
48+
}
49+
50+
@Override
51+
public Map<String, String> getProperties() {
52+
return properties;
53+
}
54+
55+
@Override
56+
public Set<String> getPropertyNames() {
57+
if (properties != null) {
58+
return properties.keySet();
59+
} else {
60+
return null;
61+
}
62+
}
63+
64+
}
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
package org.imixs.application.config;
2+
3+
import java.util.Collection;
4+
import java.util.HashMap;
5+
import java.util.List;
6+
import java.util.Map;
7+
import java.util.logging.Logger;
8+
9+
import org.imixs.workflow.ItemCollection;
10+
import org.imixs.workflow.engine.jpa.Document;
11+
12+
import jakarta.annotation.PostConstruct;
13+
import jakarta.ejb.Singleton;
14+
import jakarta.ejb.Startup;
15+
import jakarta.persistence.EntityManager;
16+
import jakarta.persistence.PersistenceContext;
17+
import jakarta.persistence.Query;
18+
19+
/**
20+
* The MartyConfigLoader is a singleton EJB loading the marty properties from
21+
* the configuration entity 'BASIC' and provides the properties to the
22+
* MartyConfigSource
23+
* <p>
24+
* See implementation details here:
25+
* https://stackoverflow.com/questions/52117613/microprofile-config-custom-configsource-using-jpa/56498321#56498321
26+
*
27+
* @author rsoika
28+
* @see PropertiesConfigSource
29+
*/
30+
@Startup
31+
@Singleton
32+
public class PropertiesLoader {
33+
34+
@PersistenceContext(unitName = "org.imixs.workflow.jpa")
35+
private EntityManager manager;
36+
37+
private static Logger logger = Logger.getLogger(PropertiesLoader.class.getName());
38+
39+
/**
40+
* This method loads the properties after the EJB is constructed and overwrites
41+
* the properties of the PropertiesConfigSource
42+
*/
43+
@PostConstruct
44+
void init() {
45+
reset();
46+
}
47+
48+
/**
49+
* This method reset the properties from the PropertiesConfigSource
50+
*/
51+
public void reset() {
52+
PropertiesConfigSource.properties = loadProperties();
53+
}
54+
55+
/**
56+
* This method is used to load a imixs.property file into the property
57+
* Map<String,String>
58+
* <p>
59+
* The imixs.property file is loaded from the current threads classpath.
60+
*
61+
*/
62+
public Map<String, String> loadProperties() {
63+
ItemCollection basicConfig = getBasicConfigurationDocument();
64+
if (basicConfig != null) {
65+
Map<String, String> properties = new HashMap<String, String>();
66+
67+
// read properties
68+
List<?> v = (List<?>) basicConfig.getItemValue("properties");
69+
if (v.size() > 0) {
70+
logger.fine("...Update imixs.properties");
71+
for (Object o : v) {
72+
String sProperty = (String) o;
73+
int ipos = sProperty.indexOf('=');
74+
if (ipos > 0) {
75+
String sKey = sProperty.substring(0, sProperty.indexOf('='));
76+
77+
String sValue = sProperty.substring(sProperty.indexOf('=') + 1);
78+
79+
logger.fine("Overwrite property/value: " + sKey + "=" + sValue);
80+
properties.put(sKey, sValue);
81+
}
82+
}
83+
}
84+
return properties;
85+
} else {
86+
return null;
87+
}
88+
89+
}
90+
91+
/**
92+
* Returns the 'BASIC' configuration Document entity by using the EntityManager
93+
* native.
94+
*
95+
* @param query
96+
* - JPQL statement
97+
* @return
98+
*
99+
*/
100+
private ItemCollection getBasicConfigurationDocument() {
101+
if (manager == null) {
102+
return null; // happens during deployment
103+
}
104+
// select all documenty by type
105+
String query = "SELECT document FROM Document AS document ";
106+
query += " WHERE document.type = 'configuration'";
107+
query += " ORDER BY document.created DESC";
108+
Query q = manager.createQuery(query);
109+
110+
@SuppressWarnings("unchecked")
111+
Collection<Document> documentList = q.getResultList();
112+
if (documentList != null) {
113+
114+
// filter resultset by read access
115+
for (Document doc : documentList) {
116+
// check name = "BASIC"
117+
ItemCollection configDocument = new ItemCollection(doc.getData());
118+
if (configDocument.getItemValueString("txtname").equals("BASIC")) {
119+
return configDocument;
120+
}
121+
}
122+
}
123+
logger.fine("BASIC configuration not found.");
124+
return null;
125+
}
126+
127+
}

0 commit comments

Comments
 (0)