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:
parent
f9e68cdc54
commit
68617180a2
6 changed files with 40 additions and 1 deletions
|
@ -33,6 +33,7 @@ public class UserSessionRepresentation {
|
||||||
private long lastAccess;
|
private long lastAccess;
|
||||||
private boolean rememberMe;
|
private boolean rememberMe;
|
||||||
private Map<String, String> clients = new HashMap<>();
|
private Map<String, String> clients = new HashMap<>();
|
||||||
|
private boolean transientUser;
|
||||||
|
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return id;
|
return id;
|
||||||
|
@ -97,4 +98,12 @@ public class UserSessionRepresentation {
|
||||||
public void setClients(Map<String, String> clients) {
|
public void setClients(Map<String, String> clients) {
|
||||||
this.clients = clients;
|
this.clients = clients;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isTransientUser() {
|
||||||
|
return transientUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTransientUser(boolean transientUser) {
|
||||||
|
this.transientUser = transientUser;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
import type UserSessionRepresentation from "@keycloak/keycloak-admin-client/lib/defs/userSessionRepresentation";
|
import type UserSessionRepresentation from "@keycloak/keycloak-admin-client/lib/defs/userSessionRepresentation";
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
|
Label,
|
||||||
List,
|
List,
|
||||||
ListItem,
|
ListItem,
|
||||||
ListVariant,
|
ListVariant,
|
||||||
ToolbarItem,
|
ToolbarItem,
|
||||||
|
Tooltip,
|
||||||
} from "@patternfly/react-core";
|
} 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 { MouseEvent, ReactNode, useMemo, useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { Link, useMatch, useNavigate } from "react-router-dom";
|
import { Link, useMatch, useNavigate } from "react-router-dom";
|
||||||
|
@ -50,9 +52,24 @@ export type SessionsTableProps = {
|
||||||
|
|
||||||
const UsernameCell = (row: UserSessionRepresentation) => {
|
const UsernameCell = (row: UserSessionRepresentation) => {
|
||||||
const { realm } = useRealm();
|
const { realm } = useRealm();
|
||||||
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<Link to={toUser({ realm, id: row.userId!, tab: "sessions" })}>
|
<Link to={toUser({ realm, id: row.userId!, tab: "sessions" })}>
|
||||||
{row.username}
|
{row.username}
|
||||||
|
{row.transientUser && (
|
||||||
|
<>
|
||||||
|
{" "}
|
||||||
|
<Tooltip content={t("transientUserTooltip")}>
|
||||||
|
<Label
|
||||||
|
data-testid="user-details-label-transient-user"
|
||||||
|
icon={<InfoCircleIcon />}
|
||||||
|
isCompact
|
||||||
|
>
|
||||||
|
{t("transientUser")}
|
||||||
|
</Label>
|
||||||
|
</Tooltip>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</Link>
|
</Link>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,4 +6,5 @@ export default interface UserSessionRepresentation {
|
||||||
start?: number;
|
start?: number;
|
||||||
userId?: string;
|
userId?: string;
|
||||||
username?: string;
|
username?: string;
|
||||||
|
transientUser?: boolean;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import org.keycloak.models.ClientModel;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.UserSessionModel;
|
import org.keycloak.models.UserSessionModel;
|
||||||
|
import org.keycloak.models.light.LightweightUserAdapter;
|
||||||
import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
|
import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
|
||||||
|
|
||||||
import jakarta.ws.rs.Consumes;
|
import jakarta.ws.rs.Consumes;
|
||||||
|
@ -118,6 +119,7 @@ public class SessionsResource {
|
||||||
ClientModel client = clientSession.getClient();
|
ClientModel client = clientSession.getClient();
|
||||||
rep.getClients().put(client.getId(), client.getClientId());
|
rep.getClients().put(client.getId(), client.getClientId());
|
||||||
}
|
}
|
||||||
|
rep.setTransientUser(LightweightUserAdapter.isLightweightUser(session.getUser().getId()));
|
||||||
return rep;
|
return rep;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ public class SessionRepresentation {
|
||||||
private String ipAddress;
|
private String ipAddress;
|
||||||
private long start;
|
private long start;
|
||||||
private long lastAccess;
|
private long lastAccess;
|
||||||
|
private boolean transientUser;
|
||||||
|
|
||||||
private SessionType type;
|
private SessionType type;
|
||||||
private Map<String, String> clients = new HashMap<>();
|
private Map<String, String> clients = new HashMap<>();
|
||||||
|
@ -81,6 +82,14 @@ public class SessionRepresentation {
|
||||||
this.clients = clients;
|
this.clients = clients;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isTransientUser() {
|
||||||
|
return transientUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTransientUser(boolean transientUser) {
|
||||||
|
this.transientUser = transientUser;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
|
|
|
@ -679,6 +679,7 @@ public class ModelToRepresentation {
|
||||||
ClientModel client = clientSession.getClient();
|
ClientModel client = clientSession.getClient();
|
||||||
rep.getClients().put(client.getId(), client.getClientId());
|
rep.getClients().put(client.getId(), client.getClientId());
|
||||||
}
|
}
|
||||||
|
rep.setTransientUser(LightweightUserAdapter.isLightweightUser(session.getUser().getId()));
|
||||||
return rep;
|
return rep;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue