[New] Implemented opt-in audit trail in Strolch

The audit trail has its own map on the Realm and a trail is written by
realm at the end of the transaction.

You can write your own audit trail using tx.getAuditTrail().

Enable the audit trail by setting the realm configuration value
'enableAuditTrail'.
This commit is contained in:
Robert von Burg 2014-08-23 20:50:01 +02:00
parent 78cc555141
commit 72ff553e74
20 changed files with 630 additions and 13 deletions

View File

@ -0,0 +1,197 @@
/*
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
*
* 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 li.strolch.persistence.xml;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import li.strolch.model.Tags;
import li.strolch.model.audit.Audit;
import li.strolch.model.audit.AuditQuery;
import li.strolch.model.audit.AuditVisitor;
import li.strolch.persistence.api.AuditDao;
import li.strolch.persistence.api.StrolchTransaction;
import ch.eitchnet.utils.collections.DateRange;
import ch.eitchnet.xmlpers.api.PersistenceContext;
import ch.eitchnet.xmlpers.api.PersistenceTransaction;
import ch.eitchnet.xmlpers.objref.IdOfSubTypeRef;
import ch.eitchnet.xmlpers.objref.ObjectRef;
import ch.eitchnet.xmlpers.objref.SubTypeRef;
import ch.eitchnet.xmlpers.objref.TypeRef;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public class XmlAuditDao implements AuditDao {
private PersistenceTransaction tx;
public XmlAuditDao(StrolchTransaction tx) {
XmlStrolchTransaction strolchTx = (XmlStrolchTransaction) tx;
this.tx = strolchTx.getTx();
}
protected String getClassType() {
return Tags.AUDIT;
}
protected IdOfSubTypeRef getIdRef(String type, Long id) {
IdOfSubTypeRef idRef = this.tx.getObjectRefCache().getIdOfSubTypeRef(getClassType(), type, id.toString());
return idRef;
}
protected SubTypeRef getTypeRef(String type) {
SubTypeRef typeRef = this.tx.getObjectRefCache().getSubTypeRef(getClassType(), type);
return typeRef;
}
@Override
public boolean hasElement(String type, Long id) {
IdOfSubTypeRef ref = getIdRef(type, id);
return this.tx.getObjectDao().hasElement(ref);
}
@Override
public long querySize(DateRange dateRange) {
long size = 0;
Set<String> types = queryTypes();
for (String type : types) {
// SubTypeRef subTypeRef = getTypeRef(type);
// size += this.tx.getMetadataDao().querySize(subTypeRef);
size += querySize(type, dateRange);
}
return size;
}
@Override
public long querySize(String type, DateRange dateRange) {
long size = 0;
// TODO re-think this nonsense... this has a huge performance penalty
SubTypeRef subTypeRef = getTypeRef(type);
Set<String> keySet = this.tx.getMetadataDao().queryKeySet(subTypeRef);
for (String key : keySet) {
ObjectRef objectRef = subTypeRef.getChildIdRef(tx, key);
Audit audit = this.tx.getObjectDao().queryById(objectRef);
if (dateRange.contains(audit.getDate()))
size++;
}
// return this.tx.getMetadataDao().querySize(subTypeRef);
return size;
}
@Override
public Set<String> queryTypes() {
TypeRef typeRef = this.tx.getObjectRefCache().getTypeRef(getClassType());
Set<String> types = this.tx.getMetadataDao().queryTypeSet(typeRef);
return types;
}
@Override
public Audit queryBy(String type, Long id) {
Audit t = this.tx.getObjectDao().queryById(getIdRef(type, id));
return t;
}
@Override
public List<Audit> queryAll(String type, DateRange dateRange) {
List<Audit> audits = new ArrayList<>();
SubTypeRef subTypeRef = getTypeRef(type);
Set<String> keySet = this.tx.getMetadataDao().queryKeySet(subTypeRef);
for (String key : keySet) {
ObjectRef objectRef = subTypeRef.getChildIdRef(tx, key);
Audit audit = this.tx.getObjectDao().queryById(objectRef);
if (dateRange.contains(audit.getDate()))
audits.add(audit);
}
// this.tx.getObjectDao().queryAll(getTypeRef(type));
return audits;
}
@Override
public void save(Audit audit) {
PersistenceContext<Audit> ctx = this.tx.getObjectDao().createCtx(audit);
this.tx.getFileDao().performCreate(ctx);
}
@Override
public void saveAll(List<Audit> audits) {
for (Audit audit : audits) {
PersistenceContext<Audit> ctx = this.tx.getObjectDao().createCtx(audit);
this.tx.getFileDao().performCreate(ctx);
}
}
@Override
public void update(Audit audit) {
PersistenceContext<Audit> ctx = this.tx.getObjectDao().createCtx(audit);
this.tx.getFileDao().performUpdate(ctx);
}
@Override
public void updateAll(List<Audit> audits) {
for (Audit audit : audits) {
PersistenceContext<Audit> ctx = this.tx.getObjectDao().createCtx(audit);
this.tx.getFileDao().performUpdate(ctx);
}
}
@Override
public void remove(Audit audit) {
PersistenceContext<Audit> ctx = this.tx.getObjectDao().createCtx(audit);
this.tx.getFileDao().performDelete(ctx);
}
@Override
public void removeAll(List<Audit> audits) {
for (Audit audit : audits) {
PersistenceContext<Audit> ctx = this.tx.getObjectDao().createCtx(audit);
this.tx.getFileDao().performDelete(ctx);
}
}
@Override
public long removeAll(String type, DateRange dateRange) {
long removed = 0L;
SubTypeRef subTypeRef = getTypeRef(type);
Set<String> keySet = this.tx.getMetadataDao().queryKeySet(subTypeRef);
for (String key : keySet) {
ObjectRef objectRef = subTypeRef.getChildIdRef(tx, key);
Audit audit = this.tx.getObjectDao().queryById(objectRef);
if (dateRange.contains(audit.getDate())) {
PersistenceContext<Audit> ctx = this.tx.getObjectDao().createCtx(objectRef);
this.tx.getFileDao().performDelete(ctx);
removed++;
}
}
return removed;
}
@Override
public <U> List<U> doQuery(AuditQuery query, AuditVisitor<U> auditVisitor) {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -24,14 +24,18 @@ import li.strolch.agent.api.StrolchRealm;
import li.strolch.model.Order;
import li.strolch.model.Resource;
import li.strolch.model.Tags;
import li.strolch.model.audit.Audit;
import li.strolch.persistence.api.AuditDao;
import li.strolch.persistence.api.OrderDao;
import li.strolch.persistence.api.PersistenceHandler;
import li.strolch.persistence.api.ResourceDao;
import li.strolch.persistence.api.StrolchTransaction;
import li.strolch.persistence.xml.model.AuditContextFactory;
import li.strolch.persistence.xml.model.OrderContextFactory;
import li.strolch.persistence.xml.model.ResourceContextFactory;
import li.strolch.runtime.configuration.ComponentConfiguration;
import li.strolch.runtime.observer.ObserverHandler;
import ch.eitchnet.privilege.model.Certificate;
import ch.eitchnet.xmlpers.api.IoMode;
import ch.eitchnet.xmlpers.api.PersistenceConstants;
import ch.eitchnet.xmlpers.api.PersistenceManager;
@ -67,14 +71,16 @@ public class XmlPersistenceHandler extends StrolchComponent implements Persisten
new ResourceContextFactory());
this.persistenceManager.getCtxFactory().registerPersistenceContextFactory(Order.class, Tags.ORDER,
new OrderContextFactory());
this.persistenceManager.getCtxFactory().registerPersistenceContextFactory(Audit.class, Tags.AUDIT,
new AuditContextFactory());
super.initialize(componentConfiguration);
}
@Override
public StrolchTransaction openTx(StrolchRealm realm) {
public StrolchTransaction openTx(StrolchRealm realm, Certificate certificate, String action) {
PersistenceTransaction tx = this.persistenceManager.openTx(realm.getRealm());
XmlStrolchTransaction strolchTx = new XmlStrolchTransaction(realm, tx, this);
XmlStrolchTransaction strolchTx = new XmlStrolchTransaction(realm, certificate, action, tx, this);
if (getContainer().hasComponent(ObserverHandler.class)) {
strolchTx.setObserverHandler(getContainer().getComponent(ObserverHandler.class));
}
@ -90,4 +96,9 @@ public class XmlPersistenceHandler extends StrolchComponent implements Persisten
public ResourceDao getResourceDao(StrolchTransaction tx) {
return new XmlResourceDao(tx);
}
@Override
public AuditDao getAuditDao(StrolchTransaction tx) {
return new XmlAuditDao(tx);
}
}

View File

@ -15,12 +15,17 @@
*/
package li.strolch.persistence.xml;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import li.strolch.agent.api.StrolchRealm;
import li.strolch.model.StrolchRootElement;
import li.strolch.persistence.api.AbstractTransaction;
import li.strolch.persistence.api.PersistenceHandler;
import ch.eitchnet.privilege.model.Certificate;
import ch.eitchnet.xmlpers.api.ModificationResult;
import ch.eitchnet.xmlpers.api.PersistenceContext;
import ch.eitchnet.xmlpers.api.PersistenceTransaction;
import ch.eitchnet.xmlpers.api.TransactionResult;
@ -29,8 +34,9 @@ public class XmlStrolchTransaction extends AbstractTransaction {
private XmlPersistenceHandler persistenceHandler;
private PersistenceTransaction tx;
public XmlStrolchTransaction(StrolchRealm realm, PersistenceTransaction tx, XmlPersistenceHandler persistenceHandler) {
super(realm);
public XmlStrolchTransaction(StrolchRealm realm, Certificate certificate, String action, PersistenceTransaction tx,
XmlPersistenceHandler persistenceHandler) {
super(realm, certificate, action);
this.persistenceHandler = persistenceHandler;
this.tx = tx;
}
@ -40,15 +46,43 @@ public class XmlStrolchTransaction extends AbstractTransaction {
}
@Override
protected void commit(li.strolch.persistence.api.TransactionResult txResult) throws Exception {
protected void writeChanges(li.strolch.persistence.api.TransactionResult txResult) throws Exception {
TransactionResult result = new TransactionResult();
this.tx.setTransactionResult(result);
this.tx.autoCloseableCommit();
Set<String> keys = result.getKeys();
for (String key : keys) {
ModificationResult modificationResult = result.getModificationResult(key);
List<StrolchRootElement> created = new ArrayList<>();
List<StrolchRootElement> updated = new ArrayList<>();
List<StrolchRootElement> deleted = new ArrayList<>();
List<Object> createdCtx = modificationResult.getCreated();
for (Object object : createdCtx) {
@SuppressWarnings("unchecked")
PersistenceContext<StrolchRootElement> ctx = (PersistenceContext<StrolchRootElement>) object;
if (ctx.getObject() != null)
created.add(ctx.getObject());
}
List<Object> updatedCtx = modificationResult.getUpdated();
for (Object object : updatedCtx) {
@SuppressWarnings("unchecked")
PersistenceContext<StrolchRootElement> ctx = (PersistenceContext<StrolchRootElement>) object;
if (ctx.getObject() != null)
updated.add(ctx.getObject());
}
List<Object> deletedCtx = modificationResult.getDeleted();
for (Object object : deletedCtx) {
@SuppressWarnings("unchecked")
PersistenceContext<StrolchRootElement> ctx = (PersistenceContext<StrolchRootElement>) object;
if (ctx.getObject() != null)
deleted.add(ctx.getObject());
}
li.strolch.persistence.api.ModificationResult mr = new li.strolch.persistence.api.ModificationResult(key,
modificationResult.getCreated(), modificationResult.getUpdated(), modificationResult.getDeleted());
created, updated, deleted);
txResult.addModificationResult(mr);
}
}
@ -58,6 +92,11 @@ public class XmlStrolchTransaction extends AbstractTransaction {
this.tx.autoCloseableRollback();
}
@Override
protected void commit() throws Exception {
// no-op
}
@Override
public PersistenceHandler getPersistenceHandler() {
return this.persistenceHandler;

View File

@ -0,0 +1,43 @@
/*
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
*
* 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 li.strolch.persistence.xml.model;
import li.strolch.model.Tags;
import li.strolch.model.audit.Audit;
import ch.eitchnet.xmlpers.api.PersistenceContext;
import ch.eitchnet.xmlpers.api.PersistenceContextFactory;
import ch.eitchnet.xmlpers.objref.IdOfSubTypeRef;
import ch.eitchnet.xmlpers.objref.ObjectRef;
import ch.eitchnet.xmlpers.objref.ObjectReferenceCache;
public class AuditContextFactory implements PersistenceContextFactory<Audit> {
@Override
public PersistenceContext<Audit> createCtx(ObjectRef objectRef) {
PersistenceContext<Audit> ctx = new PersistenceContext<>(objectRef);
ctx.setParserFactory(new AuditParserFactory());
return ctx;
}
@Override
public PersistenceContext<Audit> createCtx(ObjectReferenceCache objectRefCache, Audit audit) {
IdOfSubTypeRef objectRef = objectRefCache.getIdOfSubTypeRef(Tags.AUDIT, audit.getElementType(), audit.getId()
.toString());
PersistenceContext<Audit> ctx = createCtx(objectRef);
ctx.setObject(audit);
return ctx;
}
}

View File

@ -0,0 +1,53 @@
/*
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
*
* 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 li.strolch.persistence.xml.model;
import li.strolch.model.audit.Audit;
import li.strolch.model.audit.AuditFromDomReader;
import li.strolch.model.audit.AuditToDomVisitor;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import ch.eitchnet.xmlpers.api.DomParser;
public class AuditDomParser implements DomParser<Audit> {
private Audit audit;
@Override
public Audit getObject() {
return this.audit;
}
@Override
public void setObject(Audit audit) {
this.audit = audit;
}
@Override
public Document toDom() {
AuditToDomVisitor auditDomVisitor = new AuditToDomVisitor();
return auditDomVisitor.visitAudit(this.audit);
}
@Override
public void fromDom(Document document) {
Element rootElement = document.getDocumentElement();
Audit audit = new AuditFromDomReader().from(rootElement);
this.audit = audit;
}
}

View File

@ -0,0 +1,34 @@
/*
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
*
* 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 li.strolch.persistence.xml.model;
import li.strolch.model.audit.Audit;
import ch.eitchnet.xmlpers.api.DomParser;
import ch.eitchnet.xmlpers.api.ParserFactory;
import ch.eitchnet.xmlpers.api.SaxParser;
public class AuditParserFactory implements ParserFactory<Audit> {
@Override
public DomParser<Audit> getDomParser() {
return new AuditDomParser();
}
@Override
public SaxParser<Audit> getSaxParser() {
throw new UnsupportedOperationException("Not yet implemented!"); //$NON-NLS-1$
}
}

View File

@ -35,7 +35,8 @@ public class OrderContextFactory implements PersistenceContextFactory<Order> {
@Override
public PersistenceContext<Order> createCtx(ObjectReferenceCache objectRefCache, Order t) {
IdOfSubTypeRef objectRef = objectRefCache.getIdOfSubTypeRef(Tags.ORDER, t.getType(), t.getId());
return createCtx(objectRef);
PersistenceContext<Order> ctx = createCtx(objectRef);
ctx.setObject(t);
return ctx;
}
}

View File

@ -35,7 +35,6 @@ public class OrderDomParser implements DomParser<Order> {
@Override
public void setObject(Order object) {
this.order = object;
}
@Override

View File

@ -35,6 +35,8 @@ public class ResourceContextFactory implements PersistenceContextFactory<Resourc
@Override
public PersistenceContext<Resource> createCtx(ObjectReferenceCache objectRefCache, Resource t) {
IdOfSubTypeRef objectRef = objectRefCache.getIdOfSubTypeRef(Tags.RESOURCE, t.getType(), t.getId());
return createCtx(objectRef);
PersistenceContext<Resource> ctx = createCtx(objectRef);
ctx.setObject(t);
return ctx;
}
}

View File

@ -23,12 +23,15 @@ import li.strolch.model.Order;
import li.strolch.model.Resource;
import li.strolch.persistence.api.StrolchTransaction;
import li.strolch.runtime.StrolchConstants;
import li.strolch.runtime.privilege.PrivilegeHandler;
import li.strolch.testbase.runtime.RuntimeMock;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import ch.eitchnet.privilege.model.Certificate;
public class ExistingDbTest {
public static final String RUNTIME_PATH = "target/existingDbRuntime/"; //$NON-NLS-1$
@ -55,7 +58,10 @@ public class ExistingDbTest {
@Test
public void shouldQueryExistingData() {
try (StrolchTransaction tx = runtimeMock.getRealm(StrolchConstants.DEFAULT_REALM).openTx()) {
PrivilegeHandler privilegeHandler = runtimeMock.getAgent().getContainer().getPrivilegeHandler();
Certificate certificate = privilegeHandler.authenticate("test", "test".getBytes());
try (StrolchTransaction tx = runtimeMock.getRealm(StrolchConstants.DEFAULT_REALM).openTx(certificate, "test")) {
Resource resource = tx.getResourceMap().getBy(tx, "MyType", "@1");
assertNotNull("Should be able to read existing element from db", resource);

View File

@ -34,12 +34,14 @@ import li.strolch.persistence.api.StrolchTransaction;
import li.strolch.runtime.StrolchConstants;
import li.strolch.runtime.observer.Observer;
import li.strolch.runtime.observer.ObserverHandler;
import li.strolch.runtime.privilege.PrivilegeHandler;
import li.strolch.testbase.runtime.RuntimeMock;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import ch.eitchnet.privilege.model.Certificate;
import ch.eitchnet.xmlpers.api.ModificationResult;
/**
@ -110,15 +112,18 @@ public class ObserverUpdateTest {
runtimeMock.getContainer().getComponent(ObserverHandler.class).registerObserver(Tags.ORDER, observer); //$NON-NLS-1$
runtimeMock.getContainer().getComponent(ObserverHandler.class).registerObserver(Tags.RESOURCE, observer); //$NON-NLS-1$
PrivilegeHandler privilegeHandler = runtimeMock.getAgent().getContainer().getPrivilegeHandler();
Certificate certificate = privilegeHandler.authenticate("test", "test".getBytes());
// create order
Order newOrder = createOrder("MyTestOrder", "Test Name", "TestType", new Date(), State.CREATED); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
try (StrolchTransaction tx = runtimeMock.getRealm(StrolchConstants.DEFAULT_REALM).openTx()) {
try (StrolchTransaction tx = runtimeMock.getRealm(StrolchConstants.DEFAULT_REALM).openTx(certificate, "test")) {
tx.getOrderMap().add(tx, newOrder);
}
// create resource
Resource newResource = createResource("MyTestResource", "Test Name", "TestType"); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
try (StrolchTransaction tx = runtimeMock.getRealm(StrolchConstants.DEFAULT_REALM).openTx()) {
try (StrolchTransaction tx = runtimeMock.getRealm(StrolchConstants.DEFAULT_REALM).openTx(certificate, "test")) {
tx.getResourceMap().add(tx, newResource);
}

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<Privilege>
<Container>
<Parameters>
<!-- parameters for the container itself -->
<Parameter name="autoPersistOnPasswordChange" value="true" />
</Parameters>
<EncryptionHandler class="ch.eitchnet.privilege.handler.DefaultEncryptionHandler">
<Parameters>
<Parameter name="hashAlgorithm" value="SHA-256" />
</Parameters>
</EncryptionHandler>
<PersistenceHandler class="ch.eitchnet.privilege.handler.XmlPersistenceHandler">
<Parameters>
<Parameter name="basePath" value="target/strolchRuntime/config" />
<Parameter name="modelXmlFile" value="PrivilegeModel.xml" />
</Parameters>
</PersistenceHandler>
</Container>
<Policies>
<Policy name="DefaultPrivilege" class="ch.eitchnet.privilege.policy.DefaultPrivilege" />
</Policies>
</Privilege>

View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<UsersAndRoles>
<Users>
<User userId="1" username="agent">
<State>SYSTEM</State>
<Roles>
<Role>agent</Role>
</Roles>
</User>
<User userId="2" username="test" password="9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08">
<Firstname>Application</Firstname>
<Lastname>Administrator</Lastname>
<State>ENABLED</State>
<Locale>en_GB</Locale>
<Roles>
<Role>PrivilegeAdmin</Role>
<Role>AppUser</Role>
</Roles>
</User>
</Users>
<Roles>
<Role name="PrivilegeAdmin" />
<Role name="agent">
<Privilege name="li.strolch.agent.impl.StartRealms" policy="DefaultPrivilege">
<AllAllowed>true</AllAllowed>
</Privilege>
</Role>
<Role name="AppUser">
<Privilege name="li.strolch.service.api.Service" policy="DefaultPrivilege">
<AllAllowed>true</AllAllowed>
</Privilege>
</Role>
</Roles>
</UsersAndRoles>

View File

@ -7,13 +7,23 @@
<verbose>true</verbose>
</Properties>
</Runtime>
<Component>
<name>PrivilegeHandler</name>
<api>li.strolch.runtime.privilege.PrivilegeHandler</api>
<impl>li.strolch.runtime.privilege.DefaultStrolchPrivilegeHandler</impl>
<Properties>
<privilegeConfigFile>PrivilegeConfig.xml</privilegeConfigFile>
</Properties>
</Component>
<Component>
<name>RealmHandler</name>
<api>li.strolch.agent.api.RealmHandler</api>
<impl>li.strolch.agent.impl.DefaultRealmHandler</impl>
<depends>PrivilegeHandler</depends>
<depends>PersistenceHandler</depends>
<Properties>
<dataStoreMode>CACHED</dataStoreMode>
<enableAuditTrail>true</enableAuditTrail>
</Properties>
</Component>
<Component>

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<Privilege>
<Container>
<Parameters>
<!-- parameters for the container itself -->
<Parameter name="autoPersistOnPasswordChange" value="true" />
</Parameters>
<EncryptionHandler class="ch.eitchnet.privilege.handler.DefaultEncryptionHandler">
<Parameters>
<Parameter name="hashAlgorithm" value="SHA-256" />
</Parameters>
</EncryptionHandler>
<PersistenceHandler class="ch.eitchnet.privilege.handler.XmlPersistenceHandler">
<Parameters>
<Parameter name="basePath" value="target/strolchRuntime/config" />
<Parameter name="modelXmlFile" value="PrivilegeModel.xml" />
</Parameters>
</PersistenceHandler>
</Container>
<Policies>
<Policy name="DefaultPrivilege" class="ch.eitchnet.privilege.policy.DefaultPrivilege" />
</Policies>
</Privilege>

View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<UsersAndRoles>
<Users>
<User userId="1" username="agent">
<State>SYSTEM</State>
<Roles>
<Role>agent</Role>
</Roles>
</User>
<User userId="2" username="test" password="9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08">
<Firstname>Application</Firstname>
<Lastname>Administrator</Lastname>
<State>ENABLED</State>
<Locale>en_GB</Locale>
<Roles>
<Role>PrivilegeAdmin</Role>
<Role>AppUser</Role>
</Roles>
</User>
</Users>
<Roles>
<Role name="PrivilegeAdmin" />
<Role name="agent">
<Privilege name="li.strolch.agent.impl.StartRealms" policy="DefaultPrivilege">
<AllAllowed>true</AllAllowed>
</Privilege>
</Role>
<Role name="AppUser">
<Privilege name="li.strolch.service.api.Service" policy="DefaultPrivilege">
<AllAllowed>true</AllAllowed>
</Privilege>
</Role>
</Roles>
</UsersAndRoles>

View File

@ -7,10 +7,19 @@
<verbose>true</verbose>
</Properties>
</Runtime>
<Component>
<name>PrivilegeHandler</name>
<api>li.strolch.runtime.privilege.PrivilegeHandler</api>
<impl>li.strolch.runtime.privilege.DefaultStrolchPrivilegeHandler</impl>
<Properties>
<privilegeConfigFile>PrivilegeConfig.xml</privilegeConfigFile>
</Properties>
</Component>
<Component>
<name>RealmHandler</name>
<api>li.strolch.agent.api.RealmHandler</api>
<impl>li.strolch.agent.impl.DefaultRealmHandler</impl>
<depends>PrivilegeHandler</depends>
<depends>PersistenceHandler</depends>
<Properties>
<dataStoreMode>CACHED</dataStoreMode>

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<Privilege>
<Container>
<Parameters>
<!-- parameters for the container itself -->
<Parameter name="autoPersistOnPasswordChange" value="true" />
</Parameters>
<EncryptionHandler class="ch.eitchnet.privilege.handler.DefaultEncryptionHandler">
<Parameters>
<Parameter name="hashAlgorithm" value="SHA-256" />
</Parameters>
</EncryptionHandler>
<PersistenceHandler class="ch.eitchnet.privilege.handler.XmlPersistenceHandler">
<Parameters>
<Parameter name="basePath" value="target/strolchRuntime/config" />
<Parameter name="modelXmlFile" value="PrivilegeModel.xml" />
</Parameters>
</PersistenceHandler>
</Container>
<Policies>
<Policy name="DefaultPrivilege" class="ch.eitchnet.privilege.policy.DefaultPrivilege" />
</Policies>
</Privilege>

View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<UsersAndRoles>
<Users>
<User userId="1" username="agent">
<State>SYSTEM</State>
<Roles>
<Role>agent</Role>
</Roles>
</User>
<User userId="2" username="test" password="9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08">
<Firstname>Application</Firstname>
<Lastname>Administrator</Lastname>
<State>ENABLED</State>
<Locale>en_GB</Locale>
<Roles>
<Role>PrivilegeAdmin</Role>
<Role>AppUser</Role>
</Roles>
</User>
</Users>
<Roles>
<Role name="PrivilegeAdmin" />
<Role name="agent">
<Privilege name="li.strolch.agent.impl.StartRealms" policy="DefaultPrivilege">
<AllAllowed>true</AllAllowed>
</Privilege>
</Role>
<Role name="AppUser">
<Privilege name="li.strolch.service.api.Service" policy="DefaultPrivilege">
<AllAllowed>true</AllAllowed>
</Privilege>
</Role>
</Roles>
</UsersAndRoles>

View File

@ -7,13 +7,23 @@
<verbose>true</verbose>
</Properties>
</Runtime>
<Component>
<name>PrivilegeHandler</name>
<api>li.strolch.runtime.privilege.PrivilegeHandler</api>
<impl>li.strolch.runtime.privilege.DefaultStrolchPrivilegeHandler</impl>
<Properties>
<privilegeConfigFile>PrivilegeConfig.xml</privilegeConfigFile>
</Properties>
</Component>
<Component>
<name>RealmHandler</name>
<api>li.strolch.agent.api.RealmHandler</api>
<impl>li.strolch.agent.impl.DefaultRealmHandler</impl>
<depends>PrivilegeHandler</depends>
<depends>PersistenceHandler</depends>
<Properties>
<dataStoreMode>TRANSACTIONAL</dataStoreMode>
<enableAuditTrail>true</enableAuditTrail>
</Properties>
</Component>
<Component>