mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-10 12:28:56 +00:00
improvements: address feedback
This commit is contained in:
@@ -249,7 +249,9 @@ export enum EventType {
|
|||||||
DELETE_SECRET_SYNC = "delete-secret-sync",
|
DELETE_SECRET_SYNC = "delete-secret-sync",
|
||||||
SECRET_SYNC_SYNC_SECRETS = "secret-sync-sync-secrets",
|
SECRET_SYNC_SYNC_SECRETS = "secret-sync-sync-secrets",
|
||||||
SECRET_SYNC_IMPORT_SECRETS = "secret-sync-import-secrets",
|
SECRET_SYNC_IMPORT_SECRETS = "secret-sync-import-secrets",
|
||||||
SECRET_SYNC_REMOVE_SECRETS = "secret-sync-remove-secrets"
|
SECRET_SYNC_REMOVE_SECRETS = "secret-sync-remove-secrets",
|
||||||
|
OIDC_GROUP_MEMBERSHIP_MAPPING_ASSIGN_USER = "oidc-group-membership-mapping-assign-user",
|
||||||
|
OIDC_GROUP_MEMBERSHIP_MAPPING_REMOVE_USER = "oidc-group-membership-mapping-remove-user"
|
||||||
}
|
}
|
||||||
|
|
||||||
interface UserActorMetadata {
|
interface UserActorMetadata {
|
||||||
@@ -2044,6 +2046,26 @@ interface SecretSyncRemoveSecretsEvent {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface OidcGroupMembershipMappingAssignUserEvent {
|
||||||
|
type: EventType.OIDC_GROUP_MEMBERSHIP_MAPPING_ASSIGN_USER;
|
||||||
|
metadata: {
|
||||||
|
assignedToGroups: { id: string; name: string }[];
|
||||||
|
userId: string;
|
||||||
|
userEmail: string;
|
||||||
|
userGroupsClaim: string[];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
interface OidcGroupMembershipMappingRemoveUserEvent {
|
||||||
|
type: EventType.OIDC_GROUP_MEMBERSHIP_MAPPING_REMOVE_USER;
|
||||||
|
metadata: {
|
||||||
|
removedFromGroups: { id: string; name: string }[];
|
||||||
|
userId: string;
|
||||||
|
userEmail: string;
|
||||||
|
userGroupsClaim: string[];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export type Event =
|
export type Event =
|
||||||
| GetSecretsEvent
|
| GetSecretsEvent
|
||||||
| GetSecretEvent
|
| GetSecretEvent
|
||||||
@@ -2232,4 +2254,6 @@ export type Event =
|
|||||||
| DeleteSecretSyncEvent
|
| DeleteSecretSyncEvent
|
||||||
| SecretSyncSyncSecretsEvent
|
| SecretSyncSyncSecretsEvent
|
||||||
| SecretSyncImportSecretsEvent
|
| SecretSyncImportSecretsEvent
|
||||||
| SecretSyncRemoveSecretsEvent;
|
| SecretSyncRemoveSecretsEvent
|
||||||
|
| OidcGroupMembershipMappingAssignUserEvent
|
||||||
|
| OidcGroupMembershipMappingRemoveUserEvent;
|
||||||
|
|||||||
@@ -320,7 +320,10 @@ export const groupServiceFactory = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (oidcConfig?.manageGroupMemberships) {
|
if (oidcConfig?.manageGroupMemberships) {
|
||||||
throw new BadRequestError({ message: "Cannot add user to group: OIDC group membership mapping is enabled." });
|
throw new BadRequestError({
|
||||||
|
message:
|
||||||
|
"Cannot add user to group: OIDC group membership mapping is enabled - user must be assigned to this group in your OIDC provider."
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const { permission: groupRolePermission } = await permissionService.getOrgPermissionByRole(group.role, actorOrgId);
|
const { permission: groupRolePermission } = await permissionService.getOrgPermissionByRole(group.role, actorOrgId);
|
||||||
@@ -385,7 +388,8 @@ export const groupServiceFactory = ({
|
|||||||
|
|
||||||
if (oidcConfig?.manageGroupMemberships) {
|
if (oidcConfig?.manageGroupMemberships) {
|
||||||
throw new BadRequestError({
|
throw new BadRequestError({
|
||||||
message: "Cannot remove user from group: OIDC group membership mapping is enabled."
|
message:
|
||||||
|
"Cannot remove user from group: OIDC group membership mapping is enabled - user must be removed from this group in your OIDC provider."
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import { Issuer, Issuer as OpenIdIssuer, Strategy as OpenIdStrategy, TokenSet }
|
|||||||
|
|
||||||
import { OrgMembershipStatus, SecretKeyEncoding, TableName, TUsers } from "@app/db/schemas";
|
import { OrgMembershipStatus, SecretKeyEncoding, TableName, TUsers } from "@app/db/schemas";
|
||||||
import { TOidcConfigsUpdate } from "@app/db/schemas/oidc-configs";
|
import { TOidcConfigsUpdate } from "@app/db/schemas/oidc-configs";
|
||||||
|
import { TAuditLogServiceFactory } from "@app/ee/services/audit-log/audit-log-service";
|
||||||
|
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
|
||||||
import { TGroupDALFactory } from "@app/ee/services/group/group-dal";
|
import { TGroupDALFactory } from "@app/ee/services/group/group-dal";
|
||||||
import { addUsersToGroupByUserIds, removeUsersFromGroupByUserIds } from "@app/ee/services/group/group-fns";
|
import { addUsersToGroupByUserIds, removeUsersFromGroupByUserIds } from "@app/ee/services/group/group-fns";
|
||||||
import { TUserGroupMembershipDALFactory } from "@app/ee/services/group/user-group-membership-dal";
|
import { TUserGroupMembershipDALFactory } from "@app/ee/services/group/user-group-membership-dal";
|
||||||
@@ -22,7 +24,7 @@ import {
|
|||||||
} from "@app/lib/crypto/encryption";
|
} from "@app/lib/crypto/encryption";
|
||||||
import { BadRequestError, ForbiddenRequestError, NotFoundError, OidcAuthError } from "@app/lib/errors";
|
import { BadRequestError, ForbiddenRequestError, NotFoundError, OidcAuthError } from "@app/lib/errors";
|
||||||
import { OrgServiceActor } from "@app/lib/types";
|
import { OrgServiceActor } from "@app/lib/types";
|
||||||
import { AuthMethod, AuthTokenType } from "@app/services/auth/auth-type";
|
import { ActorType, AuthMethod, AuthTokenType } from "@app/services/auth/auth-type";
|
||||||
import { TAuthTokenServiceFactory } from "@app/services/auth-token/auth-token-service";
|
import { TAuthTokenServiceFactory } from "@app/services/auth-token/auth-token-service";
|
||||||
import { TokenType } from "@app/services/auth-token/auth-token-types";
|
import { TokenType } from "@app/services/auth-token/auth-token-types";
|
||||||
import { TGroupProjectDALFactory } from "@app/services/group-project/group-project-dal";
|
import { TGroupProjectDALFactory } from "@app/services/group-project/group-project-dal";
|
||||||
@@ -88,6 +90,7 @@ type TOidcConfigServiceFactoryDep = {
|
|||||||
projectKeyDAL: Pick<TProjectKeyDALFactory, "find" | "findLatestProjectKey" | "insertMany" | "delete">;
|
projectKeyDAL: Pick<TProjectKeyDALFactory, "find" | "findLatestProjectKey" | "insertMany" | "delete">;
|
||||||
projectDAL: Pick<TProjectDALFactory, "findProjectGhostUser">;
|
projectDAL: Pick<TProjectDALFactory, "findProjectGhostUser">;
|
||||||
projectBotDAL: Pick<TProjectBotDALFactory, "findOne">;
|
projectBotDAL: Pick<TProjectBotDALFactory, "findOne">;
|
||||||
|
auditLogService: Pick<TAuditLogServiceFactory, "createAuditLog">;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TOidcConfigServiceFactory = ReturnType<typeof oidcConfigServiceFactory>;
|
export type TOidcConfigServiceFactory = ReturnType<typeof oidcConfigServiceFactory>;
|
||||||
@@ -108,7 +111,8 @@ export const oidcConfigServiceFactory = ({
|
|||||||
groupProjectDAL,
|
groupProjectDAL,
|
||||||
projectKeyDAL,
|
projectKeyDAL,
|
||||||
projectDAL,
|
projectDAL,
|
||||||
projectBotDAL
|
projectBotDAL,
|
||||||
|
auditLogService
|
||||||
}: TOidcConfigServiceFactoryDep) => {
|
}: TOidcConfigServiceFactoryDep) => {
|
||||||
const getOidc = async (dto: TGetOidcCfgDTO) => {
|
const getOidc = async (dto: TGetOidcCfgDTO) => {
|
||||||
const org = await orgDAL.findOne({ slug: dto.orgSlug });
|
const org = await orgDAL.findOne({ slug: dto.orgSlug });
|
||||||
@@ -382,6 +386,25 @@ export const oidcConfigServiceFactory = ({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (groupsToAddUserTo.length) {
|
||||||
|
await auditLogService.createAuditLog({
|
||||||
|
actor: {
|
||||||
|
type: ActorType.PLATFORM,
|
||||||
|
metadata: {}
|
||||||
|
},
|
||||||
|
orgId,
|
||||||
|
event: {
|
||||||
|
type: EventType.OIDC_GROUP_MEMBERSHIP_MAPPING_ASSIGN_USER,
|
||||||
|
metadata: {
|
||||||
|
userId: user.id,
|
||||||
|
userEmail: user.email ?? user.username,
|
||||||
|
assignedToGroups: groupsToAddUserTo.map(({ id, name }) => ({ id, name })),
|
||||||
|
userGroupsClaim: groups
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const membershipsToRemove = userGroups
|
const membershipsToRemove = userGroups
|
||||||
.filter((membership) => !groups.includes(membership.groupName))
|
.filter((membership) => !groups.includes(membership.groupName))
|
||||||
.map((membership) => membership.groupId);
|
.map((membership) => membership.groupId);
|
||||||
@@ -397,6 +420,25 @@ export const oidcConfigServiceFactory = ({
|
|||||||
projectKeyDAL
|
projectKeyDAL
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (groupsToRemoveUserFrom.length) {
|
||||||
|
await auditLogService.createAuditLog({
|
||||||
|
actor: {
|
||||||
|
type: ActorType.PLATFORM,
|
||||||
|
metadata: {}
|
||||||
|
},
|
||||||
|
orgId,
|
||||||
|
event: {
|
||||||
|
type: EventType.OIDC_GROUP_MEMBERSHIP_MAPPING_REMOVE_USER,
|
||||||
|
metadata: {
|
||||||
|
userId: user.id,
|
||||||
|
userEmail: user.email ?? user.username,
|
||||||
|
removedFromGroups: groupsToRemoveUserFrom.map(({ id, name }) => ({ id, name })),
|
||||||
|
userGroupsClaim: groups
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await licenseService.updateSubscriptionOrgMemberCount(organization.id);
|
await licenseService.updateSubscriptionOrgMemberCount(organization.id);
|
||||||
|
|||||||
@@ -1344,7 +1344,8 @@ export const registerRoutes = async (
|
|||||||
projectDAL,
|
projectDAL,
|
||||||
userGroupMembershipDAL,
|
userGroupMembershipDAL,
|
||||||
groupProjectDAL,
|
groupProjectDAL,
|
||||||
groupDAL
|
groupDAL,
|
||||||
|
auditLogService
|
||||||
});
|
});
|
||||||
|
|
||||||
const userEngagementService = userEngagementServiceFactory({
|
const userEngagementService = userEngagementServiceFactory({
|
||||||
|
|||||||
@@ -16,7 +16,8 @@ Infisical groups not present in their groups claim.
|
|||||||
|
|
||||||
<Warning>
|
<Warning>
|
||||||
Group membership changes in the Keycloak only sync with Infisical when a
|
Group membership changes in the Keycloak only sync with Infisical when a
|
||||||
user logs in. For example, if you remove a user from a group in Keycloak, this change will not be reflected in Infisical until their next login.
|
user logs in via OIDC. For example, if you remove a user from a group in Keycloak, this change will not be reflected in Infisical until their next OIDC login. To ensure this behavior, Infisical recommends enabling Enforce OIDC
|
||||||
|
SSO in the OIDC settings.
|
||||||
</Warning>
|
</Warning>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -114,7 +114,11 @@ export const eventToNameMap: { [K in EventType]: string } = {
|
|||||||
[EventType.DELETE_SECRET_SYNC]: "Delete Secret Sync",
|
[EventType.DELETE_SECRET_SYNC]: "Delete Secret Sync",
|
||||||
[EventType.SECRET_SYNC_SYNC_SECRETS]: "Secret Sync synced secrets",
|
[EventType.SECRET_SYNC_SYNC_SECRETS]: "Secret Sync synced secrets",
|
||||||
[EventType.SECRET_SYNC_IMPORT_SECRETS]: "Secret Sync imported secrets",
|
[EventType.SECRET_SYNC_IMPORT_SECRETS]: "Secret Sync imported secrets",
|
||||||
[EventType.SECRET_SYNC_REMOVE_SECRETS]: "Secret Sync removed secrets"
|
[EventType.SECRET_SYNC_REMOVE_SECRETS]: "Secret Sync removed secrets",
|
||||||
|
[EventType.OIDC_GROUP_MEMBERSHIP_MAPPING_ASSIGN_USER]:
|
||||||
|
"OIDC group membership mapping assigned user to groups",
|
||||||
|
[EventType.OIDC_GROUP_MEMBERSHIP_MAPPING_REMOVE_USER]:
|
||||||
|
"OIDC group membership mapping removed user from groups"
|
||||||
};
|
};
|
||||||
|
|
||||||
export const userAgentTTypeoNameMap: { [K in UserAgentType]: string } = {
|
export const userAgentTTypeoNameMap: { [K in UserAgentType]: string } = {
|
||||||
|
|||||||
@@ -127,5 +127,7 @@ export enum EventType {
|
|||||||
DELETE_SECRET_SYNC = "delete-secret-sync",
|
DELETE_SECRET_SYNC = "delete-secret-sync",
|
||||||
SECRET_SYNC_SYNC_SECRETS = "secret-sync-sync-secrets",
|
SECRET_SYNC_SYNC_SECRETS = "secret-sync-sync-secrets",
|
||||||
SECRET_SYNC_IMPORT_SECRETS = "secret-sync-import-secrets",
|
SECRET_SYNC_IMPORT_SECRETS = "secret-sync-import-secrets",
|
||||||
SECRET_SYNC_REMOVE_SECRETS = "secret-sync-remove-secrets"
|
SECRET_SYNC_REMOVE_SECRETS = "secret-sync-remove-secrets",
|
||||||
|
OIDC_GROUP_MEMBERSHIP_MAPPING_ASSIGN_USER = "oidc-group-membership-mapping-assign-user",
|
||||||
|
OIDC_GROUP_MEMBERSHIP_MAPPING_REMOVE_USER = "oidc-group-membership-mapping-remove-user"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,12 @@ export const LogsTableRow = ({ auditLog, isOrgAuditLogs, showActorColumn }: Prop
|
|||||||
<p>Machine Identity</p>
|
<p>Machine Identity</p>
|
||||||
</Td>
|
</Td>
|
||||||
);
|
);
|
||||||
|
case ActorType.PLATFORM:
|
||||||
|
return (
|
||||||
|
<Td>
|
||||||
|
<p>Platform</p>
|
||||||
|
</Td>
|
||||||
|
);
|
||||||
case ActorType.UNKNOWN_USER:
|
case ActorType.UNKNOWN_USER:
|
||||||
return (
|
return (
|
||||||
<Td>
|
<Td>
|
||||||
|
|||||||
+2
-2
@@ -82,9 +82,9 @@ export const AddGroupMembersModal = ({ popUp, handlePopUpToggle }: Props) => {
|
|||||||
text: "Successfully assigned user to the group",
|
text: "Successfully assigned user to the group",
|
||||||
type: "success"
|
type: "success"
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch {
|
||||||
createNotification({
|
createNotification({
|
||||||
text: (error as Error)?.message ?? "Failed to assign user to the group",
|
text: "Failed to assign user to the group",
|
||||||
type: "error"
|
type: "error"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-2
@@ -203,8 +203,10 @@ export const OrgOIDCSection = (): JSX.Element => {
|
|||||||
<p className="mt-4 text-yellow">
|
<p className="mt-4 text-yellow">
|
||||||
<FontAwesomeIcon className="mr-1" icon={faWarning} />
|
<FontAwesomeIcon className="mr-1" icon={faWarning} />
|
||||||
Group membership changes in the OIDC provider only sync with Infisical when a
|
Group membership changes in the OIDC provider only sync with Infisical when a
|
||||||
user logs in. For example, if you remove a user from a group in the OIDC
|
user logs in via OIDC. For example, if you remove a user from a group in the
|
||||||
provider, this change will not be reflected in Infisical until their next login.
|
OIDC provider, this change will not be reflected in Infisical until their next
|
||||||
|
OIDC login. To ensure this behavior, Infisical recommends enabling Enforce OIDC
|
||||||
|
SSO.
|
||||||
</p>
|
</p>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user