mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-07 01:27:41 +00:00
Add groups to ssh hosts allowed principals bot improvements
This commit is contained in:
@@ -160,11 +160,7 @@ export const groupDALFactory = (db: TDbClient) => {
|
|||||||
const findGroupsByProjectId = async (projectId: string, tx?: Knex) => {
|
const findGroupsByProjectId = async (projectId: string, tx?: Knex) => {
|
||||||
try {
|
try {
|
||||||
const docs = await (tx || db.replicaNode())(TableName.Groups)
|
const docs = await (tx || db.replicaNode())(TableName.Groups)
|
||||||
.leftJoin(
|
.join(TableName.GroupProjectMembership, `${TableName.Groups}.id`, `${TableName.GroupProjectMembership}.groupId`)
|
||||||
TableName.GroupProjectMembership,
|
|
||||||
`${TableName.Groups}.id`,
|
|
||||||
`${TableName.GroupProjectMembership}.groupId`
|
|
||||||
)
|
|
||||||
.where(`${TableName.GroupProjectMembership}.projectId`, projectId)
|
.where(`${TableName.GroupProjectMembership}.projectId`, projectId)
|
||||||
.select(selectAllTableCols(TableName.Groups));
|
.select(selectAllTableCols(TableName.Groups));
|
||||||
return docs;
|
return docs;
|
||||||
|
|||||||
@@ -262,16 +262,15 @@ export const sshHostServiceFactory = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (allowedPrincipals.groups && allowedPrincipals.groups.length > 0) {
|
if (allowedPrincipals.groups && allowedPrincipals.groups.length > 0) {
|
||||||
const groups = await groupDAL.findGroupsByProjectId(projectId);
|
const projectGroups = await groupDAL.findGroupsByProjectId(projectId);
|
||||||
|
const groups = projectGroups.filter((g) => allowedPrincipals.groups?.includes(g.slug));
|
||||||
|
|
||||||
const foundGroupSlugs = new Set(groups.map((g) => g.slug));
|
if (groups.length !== allowedPrincipals.groups?.length) {
|
||||||
|
throw new BadRequestError({
|
||||||
for (const slug of allowedPrincipals.groups) {
|
message: `Invalid group slugs: ${allowedPrincipals.groups
|
||||||
if (!foundGroupSlugs.has(slug)) {
|
.filter((g) => !projectGroups.some((pg) => pg.slug === g))
|
||||||
throw new BadRequestError({
|
.join(", ")}`
|
||||||
message: `Invalid group slug: ${slug}`
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for await (const group of groups) {
|
for await (const group of groups) {
|
||||||
|
|||||||
@@ -49,11 +49,11 @@ const schema = z
|
|||||||
loginMappings: z
|
loginMappings: z
|
||||||
.object({
|
.object({
|
||||||
loginUser: z.string().trim().min(1),
|
loginUser: z.string().trim().min(1),
|
||||||
principals: z
|
allowedPrincipals: z
|
||||||
.array(
|
.array(
|
||||||
z.object({
|
z.object({
|
||||||
type: z.enum(["user", "group"]),
|
type: z.enum(["user", "group"]),
|
||||||
value: z.string().trim()
|
value: z.string().trim().min(1)
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
.default([])
|
.default([])
|
||||||
@@ -110,7 +110,7 @@ export const SshHostModal = ({ popUp, handlePopUpToggle }: Props) => {
|
|||||||
userCertTtl: sshHost.userCertTtl,
|
userCertTtl: sshHost.userCertTtl,
|
||||||
loginMappings: sshHost.loginMappings.map(({ loginUser, allowedPrincipals }) => ({
|
loginMappings: sshHost.loginMappings.map(({ loginUser, allowedPrincipals }) => ({
|
||||||
loginUser,
|
loginUser,
|
||||||
principals: [
|
allowedPrincipals: [
|
||||||
...(allowedPrincipals.usernames || []).map((username) => ({
|
...(allowedPrincipals.usernames || []).map((username) => ({
|
||||||
type: "user" as const,
|
type: "user" as const,
|
||||||
value: username
|
value: username
|
||||||
@@ -169,10 +169,14 @@ export const SshHostModal = ({ popUp, handlePopUpToggle }: Props) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const transformedLoginMappings = loginMappings.map(({ loginUser, principals }) => {
|
const transformedLoginMappings = loginMappings.map(({ loginUser, allowedPrincipals }) => {
|
||||||
const usernames = principals.filter((p) => p.type === "user").map((p) => p.value);
|
const usernames = allowedPrincipals
|
||||||
|
.filter((p) => p.type === "user" && p.value)
|
||||||
|
.map((p) => p.value);
|
||||||
|
|
||||||
const groupNames = principals.filter((p) => p.type === "group").map((p) => p.value);
|
const groupNames = allowedPrincipals
|
||||||
|
.filter((p) => p.type === "group" && p.value)
|
||||||
|
.map((p) => p.value);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
loginUser,
|
loginUser,
|
||||||
@@ -182,7 +186,6 @@ export const SshHostModal = ({ popUp, handlePopUpToggle }: Props) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
console.log(transformedLoginMappings);
|
|
||||||
|
|
||||||
if (sshHost) {
|
if (sshHost) {
|
||||||
await updateMutateAsync({
|
await updateMutateAsync({
|
||||||
@@ -230,7 +233,7 @@ export const SshHostModal = ({ popUp, handlePopUpToggle }: Props) => {
|
|||||||
principalType: string,
|
principalType: string,
|
||||||
principalValue: string
|
principalValue: string
|
||||||
) => {
|
) => {
|
||||||
const principals = getValues(`loginMappings.${mappingIndex}.principals`) || [];
|
const principals = getValues(`loginMappings.${mappingIndex}.allowedPrincipals`) || [];
|
||||||
return principals.some((p) => p.type === principalType && p.value === principalValue);
|
return principals.some((p) => p.type === principalType && p.value === principalValue);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -297,7 +300,7 @@ export const SshHostModal = ({ popUp, handlePopUpToggle }: Props) => {
|
|||||||
variant="outline_bg"
|
variant="outline_bg"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const newIndex = loginMappingsFormFields.fields.length;
|
const newIndex = loginMappingsFormFields.fields.length;
|
||||||
loginMappingsFormFields.append({ loginUser: "", principals: [] });
|
loginMappingsFormFields.append({ loginUser: "", allowedPrincipals: [] });
|
||||||
setExpandedMappings((prev) => ({
|
setExpandedMappings((prev) => ({
|
||||||
...prev,
|
...prev,
|
||||||
[newIndex]: true
|
[newIndex]: true
|
||||||
@@ -392,8 +395,8 @@ export const SshHostModal = ({ popUp, handlePopUpToggle }: Props) => {
|
|||||||
size="xs"
|
size="xs"
|
||||||
variant="outline_bg"
|
variant="outline_bg"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const current = getValues(`loginMappings.${i}.principals`) ?? [];
|
const current = getValues(`loginMappings.${i}.allowedPrincipals`) ?? [];
|
||||||
setValue(`loginMappings.${i}.principals`, [
|
setValue(`loginMappings.${i}.allowedPrincipals`, [
|
||||||
...current,
|
...current,
|
||||||
{ type: "user", value: "" }
|
{ type: "user", value: "" }
|
||||||
]);
|
]);
|
||||||
@@ -404,7 +407,7 @@ export const SshHostModal = ({ popUp, handlePopUpToggle }: Props) => {
|
|||||||
</div>
|
</div>
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
name={`loginMappings.${i}.principals`}
|
name={`loginMappings.${i}.allowedPrincipals`}
|
||||||
render={({ field: { value = [], onChange }, fieldState: { error } }) => (
|
render={({ field: { value = [], onChange }, fieldState: { error } }) => (
|
||||||
<div className="flex flex-col space-y-2">
|
<div className="flex flex-col space-y-2">
|
||||||
{value.map((principal, principalIndex) => (
|
{value.map((principal, principalIndex) => (
|
||||||
|
|||||||
Reference in New Issue
Block a user