Update login mapping rendering on ssh hosts

This commit is contained in:
Tuan Dang
2025-05-02 13:37:39 -07:00
parent d5246c2891
commit 9ec7d0d03e
@@ -91,34 +91,69 @@ export const SshHostsTable = ({ handlePopUpOpen }: Props) => {
{host.loginMappings.length === 0 ? ( {host.loginMappings.length === 0 ? (
<span className="italic text-mineshaft-400">None</span> <span className="italic text-mineshaft-400">None</span>
) : ( ) : (
Object.entries( (() => {
host.loginMappings.reduce( const hostMappings = host.loginMappings.filter(
(acc, mapping) => { (m) => m.source !== LoginMappingSource.HOST_GROUP
const key = `${mapping.loginUser}|${mapping.source}|${mapping.allowedPrincipals.usernames.sort().join(",")}`; );
acc[key] = mapping; const groupMappings = host.loginMappings.filter(
(m) => m.source === LoginMappingSource.HOST_GROUP
);
const hostLoginUserToPrincipals = hostMappings.reduce(
(acc, { loginUser, allowedPrincipals }) => {
acc[loginUser] = new Set(allowedPrincipals.usernames);
return acc; return acc;
}, },
{} as Record<string, (typeof host.loginMappings)[number]> {} as Record<string, Set<string>>
) );
)
.sort(([a], [b]) => a.localeCompare(b)) const entriesFromHost = hostMappings.map(({ loginUser, allowedPrincipals }) => ({
.map(([key, { loginUser, allowedPrincipals, source }]) => ( loginUser,
<div key={`${host.id}-${key}`} className="mb-2"> source: LoginMappingSource.HOST,
<div className="text-mineshaft-200"> usernames: allowedPrincipals.usernames
{loginUser} }));
{source === LoginMappingSource.HOST_GROUP && (
<span className="ml-2 text-xs text-mineshaft-400"> const entriesFromGroup = groupMappings
(inherited from host group) .map(({ loginUser, allowedPrincipals }) => {
</span> const existing = hostLoginUserToPrincipals[loginUser] || new Set();
)} const filteredUsernames = allowedPrincipals.usernames.filter((u) => !existing.has(u));
</div> return filteredUsernames.length > 0
{allowedPrincipals.usernames.map((username) => ( ? {
<div key={`${host.id}-${key}-${username}`} className="ml-4"> loginUser,
└─ {username} source: LoginMappingSource.HOST_GROUP,
usernames: filteredUsernames
}
: null;
})
.filter(Boolean) as {
loginUser: string;
source: LoginMappingSource;
usernames: string[];
}[];
return [...entriesFromHost, ...entriesFromGroup]
.sort((a, b) => a.loginUser.localeCompare(b.loginUser))
.map(({ loginUser, usernames, source }) => (
<div key={`${host.id}-${loginUser}-${source}`} className="mb-2">
<div className="text-mineshaft-200">
{loginUser}
{source === LoginMappingSource.HOST_GROUP && (
<span className="ml-2 text-xs text-mineshaft-400">
(inherited from host group)
</span>
)}
</div> </div>
))} {usernames.map((username) => (
</div> <div
)) key={`${host.id}-${loginUser}-${source}-${username}`}
className="ml-4"
>
└─ {username}
</div>
))}
</div>
));
})()
)} )}
</Td> </Td>
<Td className="text-right align-middle"> <Td className="text-right align-middle">
@@ -198,4 +233,8 @@ export const SshHostsTable = ({ handlePopUpOpen }: Props) => {
</TableContainer> </TableContainer>
</div> </div>
); );
};
</TableContainer>
</div>
);
}; };