You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ma...@apache.org on 2024/01/03 23:51:22 UTC

(camel-karavan) branch main updated: Fix #1044

This is an automated email from the ASF dual-hosted git repository.

marat pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-karavan.git


The following commit(s) were added to refs/heads/main by this push:
     new e5f5989a Fix #1044
e5f5989a is described below

commit e5f5989a227c9f0630d46fba3ef3b83b25844db0
Author: Marat Gubaidullin <ma...@talismancloud.io>
AuthorDate: Wed Jan 3 18:51:15 2024 -0500

    Fix #1044
---
 .../apache/camel/karavan/api/UsersResource.java    | 17 ++++--
 .../apache/camel/karavan/service/AuthService.java  |  3 +-
 .../karavan-app/src/main/webui/src/api/SsoApi.tsx  | 13 +++++
 .../src/main/webui/src/main/PageNavigation.tsx     | 65 +++++++++++++++++++---
 4 files changed, 83 insertions(+), 15 deletions(-)

diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/UsersResource.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/UsersResource.java
index fbf6e61e..f63c1eb0 100644
--- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/UsersResource.java
+++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/UsersResource.java
@@ -17,6 +17,7 @@
 
 package org.apache.camel.karavan.api;
 
+import io.quarkus.oidc.UserInfo;
 import io.quarkus.security.identity.SecurityIdentity;
 import jakarta.inject.Inject;
 import jakarta.ws.rs.GET;
@@ -34,21 +35,29 @@ public class UsersResource {
     @Inject
     SecurityIdentity securityIdentity;
 
+
     @GET
     @Path("/me")
     @NoCache
-    public User me() {
-        return new User(securityIdentity);
+    public ProfileInfo me() {
+        return new ProfileInfo(securityIdentity);
     }
 
-    public static class User {
+    public static class ProfileInfo {
 
         private final String userName;
+        private final String displayName;
         private final Set<String> roles;
 
-        User(SecurityIdentity securityIdentity) {
+        ProfileInfo(SecurityIdentity securityIdentity) {
+            UserInfo userInfo = (UserInfo) securityIdentity.getAttributes().get("userinfo");
             this.userName = securityIdentity.getPrincipal().getName();
             this.roles = securityIdentity.getRoles();
+            this.displayName = userInfo.getName();
+        }
+
+        public String getDisplayName() {
+            return displayName;
         }
 
         public String getUserName() {
diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/AuthService.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/AuthService.java
index de6c3285..63abff24 100644
--- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/AuthService.java
+++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/AuthService.java
@@ -20,7 +20,6 @@ import jakarta.enterprise.context.ApplicationScoped;
 import org.eclipse.microprofile.config.ConfigProvider;
 import org.jboss.logging.Logger;
 
-import java.net.MalformedURLException;
 import java.util.Map;
 
 @ApplicationScoped
@@ -32,7 +31,7 @@ public class AuthService {
         return ConfigProvider.getConfig().getValue("karavan.auth", String.class);
     }
 
-    public Map<String, String> getSsoConfig() throws MalformedURLException {
+    public Map<String, String> getSsoConfig() {
         return Map.of(
                 "url", ConfigProvider.getConfig().getValue("karavan.keycloak.url", String.class),
                 "realm", ConfigProvider.getConfig().getValue("karavan.keycloak.realm", String.class),
diff --git a/karavan-web/karavan-app/src/main/webui/src/api/SsoApi.tsx b/karavan-web/karavan-app/src/main/webui/src/api/SsoApi.tsx
index 04ed5748..9ac7ed61 100644
--- a/karavan-web/karavan-app/src/main/webui/src/api/SsoApi.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/api/SsoApi.tsx
@@ -35,4 +35,17 @@ export class SsoApi {
             });
         });
     }
+
+    static logout(after: () => void) {
+        if (SsoApi.keycloak) {
+            SsoApi.keycloak.logout().then(value => {
+                console.log('SsoApi', 'User is now logout.');
+                KaravanApi.isAuthorized = false;
+                window.location.reload();
+            }).catch(reason => {
+                console.log('SsoApi', 'Error:', reason);
+                window.location.reload();
+            });
+        }
+    }
 }
\ No newline at end of file
diff --git a/karavan-web/karavan-app/src/main/webui/src/main/PageNavigation.tsx b/karavan-web/karavan-app/src/main/webui/src/main/PageNavigation.tsx
index fc2adfd8..cbe27f56 100644
--- a/karavan-web/karavan-app/src/main/webui/src/main/PageNavigation.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/main/PageNavigation.tsx
@@ -15,13 +15,21 @@
  * limitations under the License.
  */
 
-import React, { useState} from 'react';
+import React, {useState} from 'react';
 import {
     Button,
     Flex,
     FlexItem,
     Tooltip,
-    Divider, Popover, Badge, Spinner, Bullseye
+    Divider,
+    Popover,
+    Badge,
+    Spinner,
+    Bullseye,
+    DescriptionListDescription,
+    DescriptionListTerm,
+    DescriptionListGroup,
+    DescriptionList, Text, TextVariants, TextContent
 } from '@patternfly/react-core';
 import {KaravanApi} from "../api/KaravanApi";
 import '../designer/karavan.css';
@@ -36,6 +44,8 @@ import ServicesIcon from "@patternfly/react-icons/dist/js/icons/services-icon";
 import {useAppConfigStore, useDevModeStore, useFileStore} from "../api/ProjectStore";
 import {shallow} from "zustand/shallow";
 import {useNavigate} from "react-router-dom";
+import LogoutIcon from "@patternfly/react-icons/dist/js/icons/door-open-icon";
+import {SsoApi} from "../api/SsoApi";
 
 class MenuItem {
     pageId: string = '';
@@ -93,7 +103,7 @@ export function PageNavigation () {
                     <Button id={page.pageId} icon={page.icon} variant={"plain"}
                             className={pageId === page.pageId ? "nav-button-selected" : ""}
                             onClick={event => {
-                                setFile('none',undefined);
+                                setFile('none', undefined);
                                 setPodName(undefined);
                                 setStatus("none");
                                 setPageId(page.pageId);
@@ -109,19 +119,56 @@ export function PageNavigation () {
         {KaravanApi.authType !== 'public' &&
             <FlexItem alignSelf={{default: "alignSelfCenter"}}>
                 <Popover
+                    hasAutoWidth
                     aria-label="Current user"
                     position={"right-end"}
                     hideOnOutsideClick={false}
                     isVisible={showUser}
                     shouldClose={(_event, tip) => setShowUser(false)}
                     shouldOpen={(_event, tip) => setShowUser(true)}
-                    headerContent={<div>{KaravanApi.me?.userName}</div>}
+                    headerContent={
+                        <TextContent>
+                            <Text component={TextVariants.h3}>Profile</Text>
+                        </TextContent>
+                    }
                     bodyContent={
-                        <Flex direction={{default: "row"}}>
-                            {KaravanApi.me?.roles && Array.isArray(KaravanApi.me?.roles)
-                                && KaravanApi.me?.roles
-                                    .filter((r: string) => ['administrator', 'developer', 'viewer'].includes(r))
-                                    .map((role: string) => <Badge id={role} isRead>{role}</Badge>)}
+                        <DescriptionList isHorizontal>
+                            <DescriptionListGroup>
+                                <DescriptionListTerm>UserName</DescriptionListTerm>
+                                <DescriptionListDescription>{KaravanApi.me?.userName}</DescriptionListDescription>
+                            </DescriptionListGroup>
+                            <DescriptionListGroup>
+                                <DescriptionListTerm>Display Name</DescriptionListTerm>
+                                <DescriptionListDescription>{KaravanApi.me?.displayName}</DescriptionListDescription>
+                            </DescriptionListGroup>
+                            <DescriptionListGroup>
+                                <DescriptionListTerm>Roles</DescriptionListTerm>
+                                <DescriptionListDescription>
+                                    <Flex direction={{default: "row"}} gap={{default: "gapXs"}}>
+                                        {KaravanApi.me?.roles && Array.isArray(KaravanApi.me?.roles)
+                                            && KaravanApi.me?.roles
+                                                .filter((r: string) => ['administrator', 'developer', 'viewer'].includes(r))
+                                                .map((role: string) => <Badge key={role} id={role}
+                                                                              isRead>{role}</Badge>)}
+                                    </Flex>
+                                </DescriptionListDescription>
+                            </DescriptionListGroup>
+                        </DescriptionList>
+                    }
+                    footerContent={
+                        <Flex justifyContent={{default: "justifyContentFlexEnd"}}>
+                            <Button size="sm"
+                                    variant={"primary"}
+                                    icon={<LogoutIcon/>}
+                                // component={'a'}
+                                // href={KaravanApi.me.logoutUrl}
+                                    onClick={e => {
+                                        setShowUser(false);
+                                        SsoApi.logout(() => {});
+                                    }}
+                            >
+                                Logout
+                            </Button>
                         </Flex>
                     }
                 >