Show indicator for transient user in user sessions list in admin ui (28879)

For transient users a transient label is now shown in the realm sessions and client sessions list in the admin ui.

Fixes #28879

Co-authored-by: Thomas Darimont <thomas.darimont@googlemail.com>
Co-authored-by: Hynek Mlnařík <hmlnarik@users.noreply.github.com>
Signed-off-by: Thomas Darimont <thomas.darimont@googlemail.com>
This commit is contained in:
Thomas Darimont 2024-04-18 11:16:28 +02:00 committed by Hynek Mlnařík
parent f9e68cdc54
commit 68617180a2
6 changed files with 40 additions and 1 deletions

View file

@ -33,6 +33,7 @@ public class UserSessionRepresentation {
private long lastAccess;
private boolean rememberMe;
private Map<String, String> clients = new HashMap<>();
private boolean transientUser;
public String getId() {
return id;
@ -97,4 +98,12 @@ public class UserSessionRepresentation {
public void setClients(Map<String, String> clients) {
this.clients = clients;
}
public boolean isTransientUser() {
return transientUser;
}
public void setTransientUser(boolean transientUser) {
this.transientUser = transientUser;
}
}

View file

@ -1,12 +1,14 @@
import type UserSessionRepresentation from "@keycloak/keycloak-admin-client/lib/defs/userSessionRepresentation";
import {
Button,
Label,
List,
ListItem,
ListVariant,
ToolbarItem,
Tooltip,
} from "@patternfly/react-core";
import { CubesIcon } from "@patternfly/react-icons";
import { CubesIcon, InfoCircleIcon } from "@patternfly/react-icons";
import { MouseEvent, ReactNode, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { Link, useMatch, useNavigate } from "react-router-dom";
@ -50,9 +52,24 @@ export type SessionsTableProps = {
const UsernameCell = (row: UserSessionRepresentation) => {
const { realm } = useRealm();
const { t } = useTranslation();
return (
<Link to={toUser({ realm, id: row.userId!, tab: "sessions" })}>
{row.username}
{row.transientUser && (
<>
{" "}
<Tooltip content={t("transientUserTooltip")}>
<Label
data-testid="user-details-label-transient-user"
icon={<InfoCircleIcon />}
isCompact
>
{t("transientUser")}
</Label>
</Tooltip>
</>
)}
</Link>
);
};

View file

@ -6,4 +6,5 @@ export default interface UserSessionRepresentation {
start?: number;
userId?: string;
username?: string;
transientUser?: boolean;
}

View file

@ -14,6 +14,7 @@ import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserSessionModel;
import org.keycloak.models.light.LightweightUserAdapter;
import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
import jakarta.ws.rs.Consumes;
@ -118,6 +119,7 @@ public class SessionsResource {
ClientModel client = clientSession.getClient();
rep.getClients().put(client.getId(), client.getClientId());
}
rep.setTransientUser(LightweightUserAdapter.isLightweightUser(session.getUser().getId()));
return rep;
}
}

View file

@ -13,6 +13,7 @@ public class SessionRepresentation {
private String ipAddress;
private long start;
private long lastAccess;
private boolean transientUser;
private SessionType type;
private Map<String, String> clients = new HashMap<>();
@ -81,6 +82,14 @@ public class SessionRepresentation {
this.clients = clients;
}
public boolean isTransientUser() {
return transientUser;
}
public void setTransientUser(boolean transientUser) {
this.transientUser = transientUser;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;

View file

@ -679,6 +679,7 @@ public class ModelToRepresentation {
ClientModel client = clientSession.getClient();
rep.getClients().put(client.getId(), client.getClientId());
}
rep.setTransientUser(LightweightUserAdapter.isLightweightUser(session.getUser().getId()));
return rep;
}