This is an automated email from the ASF dual-hosted git repository. danhaywood pushed a commit to branch jdo-SNAPSHOT in repository https://gitbox.apache.org/repos/asf/isis-app-simpleapp.git
commit 616005786d9ecf8a177d1e68a110d2990f65a984 Author: Dan Haywood <[email protected]> AuthorDate: Sat Aug 27 18:16:48 2022 +0100 enables secman --- README.adoc | 22 ++++++-- webapp/pom.xml | 14 +++-- .../main/java/domainapp/webapp/AppManifest.java | 6 ++- .../application/seed/CustomRolesAndUsers.java | 61 ++++++++++++++++++++++ .../application/seed/SeedSecurityService.java | 38 ++++++++++++++ webapp/src/main/resources/application.yml | 14 +++++ .../main/resources/config/application.properties | 3 +- webapp/src/main/resources/menubars.layout.xml | 28 +++++++++- 8 files changed, 173 insertions(+), 13 deletions(-) diff --git a/README.adoc b/README.adoc index 48f2a5e..07843b8 100644 --- a/README.adoc +++ b/README.adoc @@ -7,9 +7,16 @@ image:https://github.com/apache/isis-app-simpleapp/workflows/Build%20w/%20Maven% This is a simple link:http://isis.apache.org[Apache Isis] application, structured so that it can be used as a starting point for developing your own applications. +It consists of: + +* a single module, which you can refactor for your own domain, or take a copy of in order to ensure that your application is properly modular +* configuration to bring in some of the more commonly used extensions: secman, command log, audit trail, execution log, session logger, flyway,quartz and excel download. + +You can easily remove these extensions (or add others) in the `AppManifest`. + [TIP] ==== -If all you want is get a feel for what the framework is all about, then take a look at the link:https://github.com/apache/isis-app-helloworld[HelloWorld] starter app, which is even simpler. +If all you want is get a feel for what the framework is all about, then take a look at the link:https://github.com/apache/isis-app-helloworld[HelloWorld] starter app, which has the bare minimum of configuration. ==== toc::[] @@ -60,8 +67,15 @@ mvn -pl webapp spring-boot:run * Login using: -** username: `sven` -** password: `pass` +** either the secman superuser: + +*** username: `secman-admin` +*** password: `pass` + +** or as a regular user: + +*** username: `sven` +*** password: `pass` + The app runs with H2 running in-memory, with sample data set up using fixture scripts. @@ -194,7 +208,7 @@ Apache Isis supports i18n using link:https://www.gnu.org/software/gettext/manual The `WEB-INF/translations.po` is the fallback (an empty value means that the key is used "as-is"), while `WEB-INF/translations-XX.po` files provide translations for each "XX" locale. Translations are required for all domain classes and all members (actions, properties and collections) of all classes. -This information is available from the metamodel, and so a new template `translations.po` is generated as a side-effect of running the integration tests (through a log4j2 logger). +This information is available from the metamodel, and so a new template `translations.po` is generated as a side effect of running the integration tests (through a log4j2 logger). A good integration test to run is `ValidateDomainModel_IntegTest`. In addition, translations are required for any validation messages triggered by the test. diff --git a/webapp/pom.xml b/webapp/pom.xml index e1d6bce..40f59b1 100644 --- a/webapp/pom.xml +++ b/webapp/pom.xml @@ -71,11 +71,6 @@ <type>pom</type> </dependency> - <dependency> - <groupId>org.apache.isis.security</groupId> - <artifactId>isis-security-shiro</artifactId> - </dependency> - <dependency> <groupId>org.apache.isis.persistence</groupId> <artifactId>isis-persistence-jpa-eclipselink</artifactId> @@ -105,6 +100,15 @@ <artifactId>isis-valuetypes-asciidoc-ui-wkt</artifactId> </dependency> + <dependency> + <groupId>org.apache.isis.extensions</groupId> + <artifactId>isis-extensions-secman-encryption-jbcrypt</artifactId> <!--.--> + </dependency> + <dependency> + <groupId>org.apache.isis.extensions</groupId> + <artifactId>isis-extensions-secman-persistence-jpa</artifactId> + </dependency> + <dependency> <groupId>org.apache.isis.extensions</groupId> <artifactId>isis-extensions-sessionlog-persistence-jpa</artifactId> diff --git a/webapp/src/main/java/domainapp/webapp/AppManifest.java b/webapp/src/main/java/domainapp/webapp/AppManifest.java index 3d34d8f..440e6a6 100644 --- a/webapp/src/main/java/domainapp/webapp/AppManifest.java +++ b/webapp/src/main/java/domainapp/webapp/AppManifest.java @@ -14,9 +14,10 @@ import org.apache.isis.extensions.commandlog.jpa.IsisModuleExtCommandLogPersiste import org.apache.isis.extensions.executionlog.jpa.IsisModuleExtExecutionLogPersistenceJpa; import org.apache.isis.extensions.executionoutbox.jpa.IsisModuleExtExecutionOutboxPersistenceJpa; import org.apache.isis.extensions.flyway.impl.IsisModuleExtFlywayImpl; +import org.apache.isis.extensions.secman.encryption.jbcrypt.IsisModuleExtSecmanEncryptionJbcrypt; +import org.apache.isis.extensions.secman.jpa.IsisModuleExtSecmanPersistenceJpa; import org.apache.isis.extensions.sessionlog.jpa.IsisModuleExtSessionLogPersistenceJpa; import org.apache.isis.persistence.jpa.eclipselink.IsisModulePersistenceJpaEclipselink; -import org.apache.isis.security.shiro.IsisModuleSecurityShiro; import org.apache.isis.testing.fixtures.applib.IsisModuleTestingFixturesApplib; import org.apache.isis.testing.h2console.ui.IsisModuleTestingH2ConsoleUi; import org.apache.isis.valuetypes.asciidoc.metamodel.IsisModuleValAsciidocMetaModel; @@ -36,7 +37,6 @@ import domainapp.webapp.quartz.QuartzModule; IsisModuleApplibChangeAndExecutionLoggers.class, IsisModuleCoreRuntimeServices.class, - IsisModuleSecurityShiro.class, IsisModulePersistenceJpaEclipselink.class, IsisModuleViewerRestfulObjectsJaxrsResteasy4.class, IsisModuleViewerWicketApplibMixins.class, @@ -47,6 +47,8 @@ import domainapp.webapp.quartz.QuartzModule; IsisModuleExtFlywayImpl.class, + IsisModuleExtSecmanPersistenceJpa.class, + IsisModuleExtSecmanEncryptionJbcrypt.class, IsisModuleExtSessionLogPersistenceJpa.class, IsisModuleExtAuditTrailPersistenceJpa.class, IsisModuleExtCommandLogPersistenceJpa.class, diff --git a/webapp/src/main/java/domainapp/webapp/application/seed/CustomRolesAndUsers.java b/webapp/src/main/java/domainapp/webapp/application/seed/CustomRolesAndUsers.java new file mode 100644 index 0000000..83b21b0 --- /dev/null +++ b/webapp/src/main/java/domainapp/webapp/application/seed/CustomRolesAndUsers.java @@ -0,0 +1,61 @@ +package domainapp.webapp.application.seed; + +import java.util.function.Supplier; + +import javax.inject.Inject; + +import org.apache.isis.applib.services.appfeat.ApplicationFeatureId; +import org.apache.isis.commons.collections.Can; +import org.apache.isis.core.config.IsisConfiguration; +import org.apache.isis.extensions.secman.applib.permission.dom.ApplicationPermissionMode; +import org.apache.isis.extensions.secman.applib.permission.dom.ApplicationPermissionRule; +import org.apache.isis.extensions.secman.applib.role.fixtures.AbstractRoleAndPermissionsFixtureScript; +import org.apache.isis.extensions.secman.applib.user.dom.AccountType; +import org.apache.isis.extensions.secman.applib.user.fixtures.AbstractUserAndRolesFixtureScript; +import org.apache.isis.testing.fixtures.applib.fixturescripts.FixtureScript; + +public class CustomRolesAndUsers extends FixtureScript { + + @Override + protected void execute(ExecutionContext executionContext) { + executionContext.executeChildren(this, + new SimpleModuleSuperuserRole(), + new SvenUser()); + } + + private static class SimpleModuleSuperuserRole extends AbstractRoleAndPermissionsFixtureScript { + + public static final String ROLE_NAME = "simple-superuser"; + + public SimpleModuleSuperuserRole() { + super(ROLE_NAME, "Permission to use everything in the 'simple' module"); + } + + @Override + protected void execute(ExecutionContext executionContext) { + newPermissions( + ApplicationPermissionRule.ALLOW, + ApplicationPermissionMode.CHANGING, + Can.of(ApplicationFeatureId.newNamespace("simple")) + ); + } + } + + private static class SvenUser extends AbstractUserAndRolesFixtureScript { + public SvenUser() { + super(() -> "sven", () -> "pass", () -> AccountType.LOCAL, new RoleSupplier()); + } + + private static class RoleSupplier implements Supplier<Can<String>> { + @Override + public Can<String> get() { + return Can.of( + isisConfiguration.getExtensions().getSecman().getSeed().getRegularUser().getRoleName(), // built-in stuff + SimpleModuleSuperuserRole.ROLE_NAME + ); + } + @Inject IsisConfiguration isisConfiguration; + } + } + +} diff --git a/webapp/src/main/java/domainapp/webapp/application/seed/SeedSecurityService.java b/webapp/src/main/java/domainapp/webapp/application/seed/SeedSecurityService.java new file mode 100644 index 0000000..f94898d --- /dev/null +++ b/webapp/src/main/java/domainapp/webapp/application/seed/SeedSecurityService.java @@ -0,0 +1,38 @@ +package domainapp.webapp.application.seed; + +import javax.annotation.Priority; +import javax.inject.Inject; + +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Service; + +import org.apache.isis.applib.annotation.PriorityPrecedence; +import org.apache.isis.applib.events.metamodel.MetamodelEvent; +import org.apache.isis.applib.services.xactn.TransactionService; +import org.apache.isis.core.config.IsisConfiguration; +import org.apache.isis.core.config.environment.IsisSystemEnvironment; +import org.apache.isis.testing.fixtures.applib.fixturescripts.FixtureScripts; + +import lombok.RequiredArgsConstructor; + +@Service +@Priority(PriorityPrecedence.MIDPOINT + 10) +@RequiredArgsConstructor(onConstructor_ = {@Inject}) +public class SeedSecurityService { + + private final FixtureScripts fixtureScripts; + private final TransactionService transactionService; + private final IsisSystemEnvironment isisSystemEnvironment; + + @EventListener(MetamodelEvent.class) + public void onMetamodelEvent(final MetamodelEvent event) { + if (event.isPostMetamodel() && isisSystemEnvironment.isPrototyping()) { + runScripts(); + transactionService.flushTransaction(); + } + } + + private void runScripts() { + fixtureScripts.run(new CustomRolesAndUsers()); + } +} diff --git a/webapp/src/main/resources/application.yml b/webapp/src/main/resources/application.yml index 47bd995..38a09a9 100644 --- a/webapp/src/main/resources/application.yml +++ b/webapp/src/main/resources/application.yml @@ -42,6 +42,20 @@ isis: command-log: publish-policy: only_if_system_changed + secman: + seed: + admin: + user-name: "secman-admin" + password: "pass" + role-name: "isis-ext-secman-admin" + namespace-permissions: + sticky: "simple" +# additional: ... + regular-user: + role-name: "isis-ext-secman-user" + permissions-evaluation-policy: allow_beats_veto + user-menu-me-action-policy: hide + viewer: wicket: application: diff --git a/webapp/src/main/resources/config/application.properties b/webapp/src/main/resources/config/application.properties index 93148bb..4d5b3ec 100644 --- a/webapp/src/main/resources/config/application.properties +++ b/webapp/src/main/resources/config/application.properties @@ -15,7 +15,8 @@ spring.datasource.url=jdbc:h2:mem:simple;DATABASE_TO_UPPER=false;IGNORECASE=TRUE spring.datasource.driver-class-name=org.h2.Driver isis.persistence.schema.create-schema-sql-template=CREATE SCHEMA IF NOT EXISTS %s -isis.persistence.schema.auto-create-schemas=simple,isisExtAuditTrail,isisExtCommandLog,isisExtExecutionLog,isisExtExecutionOutbox,isisExtSessionLog +isis.persistence.schema.auto-create-schemas=simple,isisExtSecman,isisExtAuditTrail,isisExtCommandLog,isisExtExecutionLog,isisExtExecutionOutbox,isisExtSessionLog + isis.core.meta-model.introspector.policy=encapsulation_enabled diff --git a/webapp/src/main/resources/menubars.layout.xml b/webapp/src/main/resources/menubars.layout.xml index c4e823f..b350884 100644 --- a/webapp/src/main/resources/menubars.layout.xml +++ b/webapp/src/main/resources/menubars.layout.xml @@ -125,6 +125,31 @@ </mb3:serviceAction> </mb3:section> </mb3:menu> + <mb3:menu> + <mb3:named>Security</mb3:named> + <mb3:section> + <mb3:named>Users</mb3:named> + <mb3:serviceAction objectType="isis.ext.secman.ApplicationUserMenu" id="userManager"/> + <mb3:serviceAction objectType="isis.ext.secman.ApplicationUserMenu" id="findUsers"/> + </mb3:section> + <mb3:section> + <mb3:named>Roles</mb3:named> + <mb3:serviceAction objectType="isis.ext.secman.ApplicationRoleMenu" id="findRoles"/> + <mb3:serviceAction objectType="isis.ext.secman.ApplicationRoleMenu" id="newRole"/> + <mb3:serviceAction objectType="isis.ext.secman.ApplicationRoleMenu" id="allRoles"/> + </mb3:section> + <mb3:section> + <mb3:named>Permissions</mb3:named> + <mb3:serviceAction objectType="isis.ext.secman.ApplicationPermissionMenu" id="allPermissions"/> + <mb3:serviceAction objectType="isis.ext.secman.ApplicationPermissionMenu" id="findOrphanedPermissions"/> + </mb3:section> + <mb3:section> + <mb3:named>Tenancies</mb3:named> + <mb3:serviceAction objectType="isis.ext.secman.ApplicationTenancyMenu" id="findTenancies"/> + <mb3:serviceAction objectType="isis.ext.secman.ApplicationTenancyMenu" id="newTenancy"/> + <mb3:serviceAction objectType="isis.ext.secman.ApplicationTenancyMenu" id="allTenancies"/> + </mb3:section> + </mb3:menu> </mb3:secondary> <mb3:tertiary> <mb3:menu> @@ -141,7 +166,8 @@ </mb3:section> <mb3:section> <mb3:named>Security</mb3:named> - <mb3:serviceAction objectType="isis.applib.UserMenu" id="me"/> + <mb3:serviceAction objectType="isis.applib.UserMenu" id="me"/> <!-- this is hidden by secman --> + <mb3:serviceAction objectType="isis.ext.secman.MeService" id="me"/> <mb3:serviceAction objectType="isis.security.LogoutMenu" id="logout"/> </mb3:section> </mb3:menu>
