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 05:56:10 UTC

[isis] 05/10: 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-2779
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 9094e296829903bb9d6f4d16eee6d1479909592a
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)
---
 .../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 &quot;Memento&quot; 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";
+    }
+
+
+
+
+}