mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-08 14:28:20 +00:00
Update login mapping rendering on ssh hosts
This commit is contained in:
@@ -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>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user