You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2021/06/29 06:01:51 UTC
[isis] 02/06: ISIS-2733: surfaces UserMemento via new "me" action.
This is an automated email from the ASF dual-hosted git repository.
danhaywood pushed a commit to branch ISIS-2733
in repository https://gitbox.apache.org/repos/asf/isis.git
commit 6feb2040f0a36c5cc8b6bb4b5e8cc22ee1c3daa7
Author: danhaywood <da...@haywood-associates.co.uk>
AuthorDate: Mon Jun 28 19:39:33 2021 +0100
ISIS-2733: surfaces UserMemento via new "me" action.
(cherry picked from commit 4fc27cfb8657ab3656429c67942695a503af35c8)
(cherry picked from commit 9094e296829903bb9d6f4d16eee6d1479909592a)
---
.../org/apache/isis/applib/IsisModuleApplib.java | 4 +-
.../isis/applib/services/user/RoleMemento.java | 32 +++++++--
.../services/user/RoleMemento.layout.fallback.xml | 48 +++++++++++++
.../isis/applib/services/user/UserMemento.java | 46 +++++++++++--
.../services/user/UserMemento.layout.fallback.xml | 75 ++++++++++++++++++++
.../isis/applib/services/user/package-info.java | 37 ----------
.../applib/services/userprof/package-info.java | 28 --------
.../isis/applib/services/userui/UserMenu.java | 79 ++++++++++++++++++++++
8 files changed, 271 insertions(+), 78 deletions(-)
diff --git a/api/applib/src/main/java/org/apache/isis/applib/IsisModuleApplib.java b/api/applib/src/main/java/org/apache/isis/applib/IsisModuleApplib.java
index 9f0fd67..1b36fea 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/IsisModuleApplib.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/IsisModuleApplib.java
@@ -59,6 +59,7 @@ import org.apache.isis.applib.services.user.ImpersonateStopMenu;
import org.apache.isis.applib.services.user.RoleMemento;
import org.apache.isis.applib.services.user.UserMemento;
import org.apache.isis.applib.services.user.UserService;
+import org.apache.isis.applib.services.userui.UserMenu;
import org.apache.isis.schema.IsisModuleSchema;
/**
@@ -104,8 +105,8 @@ import org.apache.isis.schema.IsisModuleSchema;
ImpersonateStopMenu.class,
MetaModelServiceMenu.class,
QueryResultsCache.class,
- UserService.class,
ApplicationFeatureMenu.class,
+ UserMenu.class,
// @Service(s)
@@ -118,6 +119,7 @@ import org.apache.isis.schema.IsisModuleSchema;
ExecutionLogger.class,
SessionLoggingServiceLogging.class,
SudoService.class,
+ UserService.class,
})
public class IsisModuleApplib {
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/user/RoleMemento.java b/api/applib/src/main/java/org/apache/isis/applib/services/user/RoleMemento.java
index 7cec066..e2e28b6 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/user/RoleMemento.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/user/RoleMemento.java
@@ -18,24 +18,39 @@
*/
package org.apache.isis.applib.services.user;
-import lombok.Getter;
-import lombok.Value;
+import java.io.Serializable;
+
+import org.springframework.context.event.EventListener;
+import org.springframework.core.annotation.Order;
+
import org.apache.isis.applib.IsisModuleApplib;
import org.apache.isis.applib.annotation.DomainObject;
+import org.apache.isis.applib.annotation.DomainObjectLayout;
import org.apache.isis.applib.annotation.Nature;
+import org.apache.isis.applib.annotation.PriorityPrecedence;
import org.apache.isis.applib.annotation.PropertyLayout;
-import java.io.Serializable;
+import lombok.Getter;
+import lombok.Value;
+import lombok.val;
/**
* Immutable serializable value held by {@link UserMemento}.
*
* @since 1.x revised for 2.0 {@index}
*/
-@DomainObject(nature = Nature.VIEW_MODEL, logicalTypeName = RoleMemento.LOGICAL_TYPE_NAME)
+@DomainObject(
+ nature = Nature.VIEW_MODEL,
+ logicalTypeName = RoleMemento.LOGICAL_TYPE_NAME
+)
+@DomainObjectLayout(
+ titleUiEvent = RoleMemento.TitleUiEvent.class
+)
@Value
public class RoleMemento implements Serializable {
+ public static class TitleUiEvent extends IsisModuleApplib.TitleUiEvent<RoleMemento> {}
+
public static final String LOGICAL_TYPE_NAME = IsisModuleApplib.NAMESPACE + ".RoleMemento";
private static final long serialVersionUID = -3876856609238378274L;
@@ -61,8 +76,13 @@ public class RoleMemento implements Serializable {
this.description = description;
}
- public String title() {
- return name;
+ public static class UiSubscriber {
+ @Order(PriorityPrecedence.LATE)
+ @EventListener(RoleMemento.TitleUiEvent.class)
+ public void on(RoleMemento.TitleUiEvent ev) {
+ val roleMemento = ev.getSource();
+ ev.setTitle(roleMemento.getName());
+ }
}
@PropertyLayout(sequence = "1.1")
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/user/RoleMemento.layout.fallback.xml b/api/applib/src/main/java/org/apache/isis/applib/services/user/RoleMemento.layout.fallback.xml
new file mode 100644
index 0000000..c683599
--- /dev/null
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/user/RoleMemento.layout.fallback.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you 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.
+-->
+<bs3:grid
+ xsi:schemaLocation="http://isis.apache.org/applib/layout/component http://isis.apache.org/applib/layout/component/component.xsd http://isis.apache.org/applib/layout/grid/bootstrap3 http://isis.apache.org/applib/layout/grid/bootstrap3/bootstrap3.xsd"
+ xmlns:bs3="http://isis.apache.org/applib/layout/grid/bootstrap3"
+ xmlns:cpt="http://isis.apache.org/applib/layout/component"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <bs3:row>
+ <bs3:col span="12" unreferencedActions="true">
+ <cpt:domainObject/>
+ </bs3:col>
+ </bs3:row>
+ <bs3:row>
+ <bs3:col span="6">
+ <cpt:fieldSet name="Identity" id="identity">
+ <cpt:property id="name"/>
+ </cpt:fieldSet>
+ <cpt:fieldSet name="Details" id="details">
+ <cpt:property id="description"/>
+ </cpt:fieldSet>
+ <cpt:fieldSet name="Other" id="other" unreferencedProperties="true"/>
+ </bs3:col>
+ <bs3:col span="6">
+ </bs3:col>
+ </bs3:row>
+ <bs3:row>
+ <bs3:col span="12">
+ <bs3:tabGroup unreferencedCollections="true"/>
+ </bs3:col>
+ </bs3:row>
+</bs3:grid>
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/user/UserMemento.java b/api/applib/src/main/java/org/apache/isis/applib/services/user/UserMemento.java
index cee114f..5cae480 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/user/UserMemento.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/user/UserMemento.java
@@ -18,6 +18,8 @@
*/
package org.apache.isis.applib.services.user;
+import java.io.IOException;
+import java.io.ObjectInputStream;
import java.io.Serializable;
import java.net.URL;
import java.util.List;
@@ -25,8 +27,21 @@ import java.util.stream.Stream;
import javax.annotation.Nullable;
+import org.springframework.context.event.EventListener;
+import org.springframework.core.annotation.Order;
+
import org.apache.isis.applib.IsisModuleApplib;
-import org.apache.isis.applib.annotation.*;
+import org.apache.isis.applib.annotation.Collection;
+import org.apache.isis.applib.annotation.CollectionLayout;
+import org.apache.isis.applib.annotation.DomainObject;
+import org.apache.isis.applib.annotation.DomainObjectLayout;
+import org.apache.isis.applib.annotation.Nature;
+import org.apache.isis.applib.annotation.Optionality;
+import org.apache.isis.applib.annotation.PriorityPrecedence;
+import org.apache.isis.applib.annotation.Programmatic;
+import org.apache.isis.applib.annotation.Property;
+import org.apache.isis.applib.annotation.PropertyLayout;
+import org.apache.isis.applib.annotation.Where;
import org.apache.isis.applib.services.iactnlayer.InteractionContext;
import org.apache.isis.commons.collections.Can;
import org.apache.isis.commons.internal.base._Strings;
@@ -35,16 +50,29 @@ import lombok.Builder;
import lombok.Getter;
import lombok.NonNull;
import lombok.With;
+import lombok.val;
/**
* Immutable serializable value holding details about a user and its roles.
*
* @since 1.x revised for 2.0 {@index}
*/
-@DomainObject(nature = Nature.VIEW_MODEL, logicalTypeName = UserMemento.LOGICAL_TYPE_NAME)
+@DomainObject(
+ nature = Nature.VIEW_MODEL,
+ logicalTypeName = UserMemento.LOGICAL_TYPE_NAME
+)
+@DomainObjectLayout(
+ titleUiEvent = UserMemento.TitleUiEvent.class
+)
@lombok.Value @lombok.Builder
public class UserMemento implements Serializable {
+ public static class TitleUiEvent extends IsisModuleApplib.TitleUiEvent<UserMemento> {}
+
+ private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
+ ois.defaultReadObject();
+ }
+
public static final String LOGICAL_TYPE_NAME = IsisModuleApplib.NAMESPACE + ".UserMemento";
private static final long serialVersionUID = 7190090455587885367L;
@@ -116,8 +144,14 @@ public class UserMemento implements Serializable {
// -- UI TITLE
- public String title() {
- return name;
+ public static class UiSubscriber {
+ @Order(PriorityPrecedence.LATE)
+ @EventListener(UserMemento.TitleUiEvent.class)
+ public void on(UserMemento.TitleUiEvent ev) {
+ val userMemento = ev.getSource();
+ val title = String.format("%s %s", userMemento.getName(), userMemento.isImpersonating() ? " (impersonating)" : null);
+ ev.setTitle(title);
+ }
}
// -- PROPERTIES
@@ -202,6 +236,7 @@ public class UserMemento implements Serializable {
@Getter @Builder.Default @With(onMethod_ = {@Programmatic})
@NonNull AuthenticationSource authenticationSource = AuthenticationSource.DEFAULT;
+
public enum AuthenticationSource {
DEFAULT,
/**
@@ -227,8 +262,7 @@ public class UserMemento implements Serializable {
* It should return an empty string {@literal ""}
* if this is an anonymous (unauthenticated) user.
*/
- @Property
- @PropertyLayout(sequence = "2.1")
+ @Property(hidden = Where.EVERYWHERE)
@Getter @Builder.Default @With(onMethod_ = {@Programmatic})
@NonNull String authenticationCode = DEFAULT_AUTH_VALID_CODE;
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/user/UserMemento.layout.fallback.xml b/api/applib/src/main/java/org/apache/isis/applib/services/user/UserMemento.layout.fallback.xml
new file mode 100644
index 0000000..507e0b7
--- /dev/null
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/user/UserMemento.layout.fallback.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you 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.
+-->
+<bs3:grid
+ xsi:schemaLocation="http://isis.apache.org/applib/layout/component http://isis.apache.org/applib/layout/component/component.xsd http://isis.apache.org/applib/layout/grid/bootstrap3 http://isis.apache.org/applib/layout/grid/bootstrap3/bootstrap3.xsd"
+ xmlns:bs3="http://isis.apache.org/applib/layout/grid/bootstrap3"
+ xmlns:cpt="http://isis.apache.org/applib/layout/component"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <bs3:row>
+ <bs3:col span="12" unreferencedActions="true">
+ <cpt:domainObject/>
+ </bs3:col>
+ </bs3:row>
+ <bs3:row>
+ <bs3:col span="6">
+ <bs3:tabGroup>
+ <bs3:tab name="Identity">
+ <bs3:row>
+ <bs3:col span="12">
+ <cpt:fieldSet name="Identity" id="identity">
+ <cpt:property id="name"/>
+ </cpt:fieldSet>
+ </bs3:col>
+ </bs3:row>
+ </bs3:tab>
+ <bs3:tab name="Other">
+ <bs3:row>
+ <bs3:col span="12">
+ <cpt:fieldSet name="Other" id="other" unreferencedProperties="true"/>
+ </bs3:col>
+ </bs3:row>
+ </bs3:tab>
+ <bs3:tab name="Metadata">
+ <bs3:row>
+ <bs3:col span="12">
+ <cpt:fieldSet name="Metadata" id="metadata"/>
+ </bs3:col>
+ </bs3:row>
+ </bs3:tab>
+ </bs3:tabGroup>
+ <cpt:fieldSet name="Details" id="details">
+ <cpt:property id="realName"/>
+ <cpt:property id="avatarUrl"/>
+ </cpt:fieldSet>
+ <cpt:fieldSet name="Authentication" id="authentication">
+ <cpt:property id="authenticationSource"/>
+ <cpt:property id="impersonating"/>
+ </cpt:fieldSet>
+ </bs3:col>
+ <bs3:col span="6">
+ <cpt:collection id="roles"/>
+ </bs3:col>
+ </bs3:row>
+ <bs3:row>
+ <bs3:col span="12">
+ <bs3:tabGroup unreferencedCollections="true"/>
+ </bs3:col>
+ </bs3:row>
+</bs3:grid>
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/user/package-info.java b/api/applib/src/main/java/org/apache/isis/applib/services/user/package-info.java
deleted file mode 100644
index 3fd69e1..0000000
--- a/api/applib/src/main/java/org/apache/isis/applib/services/user/package-info.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-/**
- * This package defines types that represent the
- * currently logged-in {@link org.apache.isis.applib.services.user.UserMemento user}
- * and their {@link org.apache.isis.applib.services.user.RoleMemento role}s, as well as
- * {@link org.apache.isis.applib.services.user.UserService} to obtain the current user.
- *
- * <p>
- * Typically domain objects do not need to have any knowledge of <i>who</i>
- * is using them, because authorization is provided declaratively by the
- * framework and is type-based. However, there are occasions; for example,
- * only an <tt>Employee</tt> and his superiors might be allowed to view their salary.
- *
- * <p>
- * The types are suffixed "Memento" because they snapshot the user
- * and roles at the time that the user logs in, but are not updated after that
- * point.
- */
-package org.apache.isis.applib.services.user;
\ No newline at end of file
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/userprof/package-info.java b/api/applib/src/main/java/org/apache/isis/applib/services/userprof/package-info.java
deleted file mode 100644
index ac15bb5..0000000
--- a/api/applib/src/main/java/org/apache/isis/applib/services/userprof/package-info.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-/**
- * The {@link org.apache.isis.applib.services.userprof.UserProfileService} provides the ability for the domain
- * application to return supplementary metadata about the current user. This information is used (by the Wicket viewer)
- * to customize the appearance of the tertiary "Me" menu bar (top right). For example, rather than display the
- * username, instead the user’s first and last name could be displayed.
- *
- *
- */
-package org.apache.isis.applib.services.userprof;
\ No newline at end of file
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/userui/UserMenu.java b/api/applib/src/main/java/org/apache/isis/applib/services/userui/UserMenu.java
new file mode 100644
index 0000000..09d4cfe
--- /dev/null
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/userui/UserMenu.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.isis.applib.services.userui;
+
+import javax.inject.Inject;
+
+import org.apache.isis.applib.IsisModuleApplib;
+import org.apache.isis.applib.annotation.Action;
+import org.apache.isis.applib.annotation.ActionLayout;
+import org.apache.isis.applib.annotation.DomainService;
+import org.apache.isis.applib.annotation.DomainServiceLayout;
+import org.apache.isis.applib.annotation.NatureOfService;
+import org.apache.isis.applib.annotation.PriorityPrecedence;
+import org.apache.isis.applib.annotation.SemanticsOf;
+import org.apache.isis.applib.services.user.UserMemento;
+import org.apache.isis.applib.services.user.UserService;
+
+import lombok.RequiredArgsConstructor;
+
+/**
+ * @since 2.0 {@index}
+ */
+@DomainService(
+ nature = NatureOfService.VIEW,
+ logicalTypeName = UserMenu.LOGICAL_TYPE_NAME
+)
+@DomainServiceLayout(
+ menuBar = DomainServiceLayout.MenuBar.TERTIARY
+)
+@javax.annotation.Priority(PriorityPrecedence.EARLY)
+@RequiredArgsConstructor(onConstructor_ = { @Inject })
+public class UserMenu {
+
+ public static final String LOGICAL_TYPE_NAME = IsisModuleApplib.NAMESPACE + ".UserMenu";
+
+ public static abstract class ActionDomainEvent extends IsisModuleApplib.ActionDomainEvent<UserMenu> {}
+
+ final UserService userService;
+
+
+ public static class MeDomainEvent extends ActionDomainEvent {}
+
+ @Action(
+ domainEvent = MeDomainEvent.class,
+ semantics = SemanticsOf.SAFE
+ )
+ @ActionLayout(
+ cssClassFa = "fa-user",
+ describedAs = "Returns your user account details",
+ sequence = "100"
+ )
+ public UserMemento me() {
+ return userService.currentUser().orElse(null);
+ }
+
+ public String disableMe() {
+ return userService.currentUser().isPresent() ? null : "Current user not available";
+ }
+
+
+
+
+}