mirror of
https://github.com/Infisical/infisical.git
synced 2026-01-10 16:08:20 -05:00
Merge pull request #4858 from Infisical/feat/adds-GETtokenAuthTokenById-api-endpoint
[ENG-4142] feat: adds GET endpoint for single auth token by ID
This commit is contained in:
@@ -186,6 +186,7 @@ export enum EventType {
|
||||
CREATE_TOKEN_IDENTITY_TOKEN_AUTH = "create-token-identity-token-auth",
|
||||
UPDATE_TOKEN_IDENTITY_TOKEN_AUTH = "update-token-identity-token-auth",
|
||||
GET_TOKENS_IDENTITY_TOKEN_AUTH = "get-tokens-identity-token-auth",
|
||||
GET_TOKEN_IDENTITY_TOKEN_AUTH = "get-token-identity-token-auth",
|
||||
|
||||
ADD_IDENTITY_TOKEN_AUTH = "add-identity-token-auth",
|
||||
UPDATE_IDENTITY_TOKEN_AUTH = "update-identity-token-auth",
|
||||
@@ -1029,6 +1030,15 @@ interface GetTokensIdentityTokenAuthEvent {
|
||||
};
|
||||
}
|
||||
|
||||
interface GetTokenIdentityTokenAuthEvent {
|
||||
type: EventType.GET_TOKEN_IDENTITY_TOKEN_AUTH;
|
||||
metadata: {
|
||||
identityId: string;
|
||||
identityName: string;
|
||||
tokenId: string;
|
||||
};
|
||||
}
|
||||
|
||||
interface AddIdentityTokenAuthEvent {
|
||||
type: EventType.ADD_IDENTITY_TOKEN_AUTH;
|
||||
metadata: {
|
||||
@@ -4214,6 +4224,7 @@ export type Event =
|
||||
| CreateTokenIdentityTokenAuthEvent
|
||||
| UpdateTokenIdentityTokenAuthEvent
|
||||
| GetTokensIdentityTokenAuthEvent
|
||||
| GetTokenIdentityTokenAuthEvent
|
||||
| AddIdentityTokenAuthEvent
|
||||
| UpdateIdentityTokenAuthEvent
|
||||
| GetIdentityTokenAuthEvent
|
||||
|
||||
@@ -584,6 +584,10 @@ export const TOKEN_AUTH = {
|
||||
offset: "The offset to start from. If you enter 10, it will start from the 10th token.",
|
||||
limit: "The number of tokens to return."
|
||||
},
|
||||
GET_TOKEN: {
|
||||
identityId: "The ID of the machine identity to get the token for.",
|
||||
tokenId: "The ID of the token to get metadata for."
|
||||
},
|
||||
CREATE_TOKEN: {
|
||||
identityId: "The ID of the machine identity to create the token for.",
|
||||
name: "The name of the token to create."
|
||||
|
||||
@@ -314,7 +314,8 @@ export const registerIdentityTokenAuthRouter = async (server: FastifyZodProvider
|
||||
accessToken: z.string(),
|
||||
expiresIn: z.coerce.number(),
|
||||
accessTokenMaxTTL: z.coerce.number(),
|
||||
tokenType: z.literal("Bearer")
|
||||
tokenType: z.literal("Bearer"),
|
||||
tokenData: IdentityAccessTokensSchema
|
||||
})
|
||||
}
|
||||
},
|
||||
@@ -346,7 +347,8 @@ export const registerIdentityTokenAuthRouter = async (server: FastifyZodProvider
|
||||
accessToken,
|
||||
tokenType: "Bearer" as const,
|
||||
expiresIn: identityTokenAuth.accessTokenTTL,
|
||||
accessTokenMaxTTL: identityTokenAuth.accessTokenMaxTTL
|
||||
accessTokenMaxTTL: identityTokenAuth.accessTokenMaxTTL,
|
||||
tokenData: identityAccessToken
|
||||
};
|
||||
}
|
||||
});
|
||||
@@ -406,6 +408,60 @@ export const registerIdentityTokenAuthRouter = async (server: FastifyZodProvider
|
||||
}
|
||||
});
|
||||
|
||||
server.route({
|
||||
method: "GET",
|
||||
url: "/token-auth/identities/:identityId/tokens/:tokenId",
|
||||
config: {
|
||||
rateLimit: readLimit
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||
schema: {
|
||||
hide: false,
|
||||
tags: [ApiDocsTags.TokenAuth],
|
||||
description: "Get token for machine identity with Token Auth",
|
||||
security: [
|
||||
{
|
||||
bearerAuth: []
|
||||
}
|
||||
],
|
||||
params: z.object({
|
||||
identityId: z.string().describe(TOKEN_AUTH.GET_TOKEN.identityId),
|
||||
tokenId: z.string().describe(TOKEN_AUTH.GET_TOKEN.tokenId)
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
token: IdentityAccessTokensSchema
|
||||
})
|
||||
}
|
||||
},
|
||||
handler: async (req) => {
|
||||
const { token, identityMembershipOrg } = await server.services.identityTokenAuth.getTokenAuthTokenById({
|
||||
identityId: req.params.identityId,
|
||||
tokenId: req.params.tokenId,
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
isActorSuperAdmin: isSuperAdmin(req.auth)
|
||||
});
|
||||
|
||||
await server.services.auditLog.createAuditLog({
|
||||
...req.auditLogInfo,
|
||||
orgId: identityMembershipOrg.scopeOrgId,
|
||||
event: {
|
||||
type: EventType.GET_TOKEN_IDENTITY_TOKEN_AUTH,
|
||||
metadata: {
|
||||
identityId: token.identityId,
|
||||
identityName: identityMembershipOrg.identity.name,
|
||||
tokenId: token.id
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return { token };
|
||||
}
|
||||
});
|
||||
|
||||
server.route({
|
||||
method: "PATCH",
|
||||
url: "/token-auth/tokens/:tokenId",
|
||||
|
||||
@@ -18,7 +18,6 @@ export const identityAccessTokenDALFactory = (db: TDbClient) => {
|
||||
.where(filter)
|
||||
.join(TableName.Identity, `${TableName.Identity}.id`, `${TableName.IdentityAccessToken}.identityId`)
|
||||
.select(selectAllTableCols(TableName.IdentityAccessToken))
|
||||
.select(db.ref("name").withSchema(TableName.Identity))
|
||||
.select(db.ref("orgId").withSchema(TableName.Identity).as("identityScopeOrgId"))
|
||||
.first();
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ import {
|
||||
TAttachTokenAuthDTO,
|
||||
TCreateTokenAuthTokenDTO,
|
||||
TGetTokenAuthDTO,
|
||||
TGetTokenAuthTokenByIdDTO,
|
||||
TGetTokenAuthTokensDTO,
|
||||
TRevokeTokenAuthDTO,
|
||||
TRevokeTokenAuthTokenDTO,
|
||||
@@ -618,6 +619,52 @@ export const identityTokenAuthServiceFactory = ({
|
||||
return { tokens, identityMembershipOrg };
|
||||
};
|
||||
|
||||
const getTokenAuthTokenById = async ({
|
||||
tokenId,
|
||||
identityId,
|
||||
isActorSuperAdmin,
|
||||
actorId,
|
||||
actor,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
}: TGetTokenAuthTokenByIdDTO) => {
|
||||
await validateIdentityUpdateForSuperAdminPrivileges(identityId, isActorSuperAdmin);
|
||||
|
||||
const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
|
||||
scopeData: {
|
||||
scope: AccessScope.Organization,
|
||||
orgId: actorOrgId
|
||||
},
|
||||
identityId
|
||||
});
|
||||
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
|
||||
|
||||
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.TOKEN_AUTH)) {
|
||||
throw new BadRequestError({
|
||||
message: "The identity does not have Token Auth"
|
||||
});
|
||||
}
|
||||
const { permission } = await permissionService.getOrgPermission({
|
||||
scope: OrganizationActionScope.Any,
|
||||
actor,
|
||||
actorId,
|
||||
orgId: identityMembershipOrg.scopeOrgId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
|
||||
|
||||
const token = await identityAccessTokenDAL.findOne({
|
||||
[`${TableName.IdentityAccessToken}.id` as "id"]: tokenId,
|
||||
[`${TableName.IdentityAccessToken}.authMethod` as "authMethod"]: IdentityAuthMethod.TOKEN_AUTH,
|
||||
[`${TableName.IdentityAccessToken}.identityId` as "identityId"]: identityId
|
||||
});
|
||||
|
||||
if (!token) throw new NotFoundError({ message: `Token with ID ${tokenId} not found` });
|
||||
|
||||
return { token, identityMembershipOrg };
|
||||
};
|
||||
|
||||
const updateTokenAuthToken = async ({
|
||||
tokenId,
|
||||
name,
|
||||
@@ -797,6 +844,7 @@ export const identityTokenAuthServiceFactory = ({
|
||||
revokeIdentityTokenAuth,
|
||||
createTokenAuthToken,
|
||||
getTokenAuthTokens,
|
||||
getTokenAuthTokenById,
|
||||
updateTokenAuthToken,
|
||||
revokeTokenAuthToken
|
||||
};
|
||||
|
||||
@@ -40,6 +40,12 @@ export type TGetTokenAuthTokensDTO = {
|
||||
isActorSuperAdmin?: boolean;
|
||||
} & Omit<TProjectPermission, "projectId">;
|
||||
|
||||
export type TGetTokenAuthTokenByIdDTO = {
|
||||
tokenId: string;
|
||||
identityId: string;
|
||||
isActorSuperAdmin?: boolean;
|
||||
} & Omit<TProjectPermission, "projectId">;
|
||||
|
||||
export type TUpdateTokenAuthTokenDTO = {
|
||||
tokenId: string;
|
||||
name?: string;
|
||||
|
||||
@@ -840,9 +840,7 @@ export type CreateTokenIdentityTokenAuthDTO = {
|
||||
|
||||
export type CreateTokenIdentityTokenAuthRes = {
|
||||
accessToken: string;
|
||||
tokenType: string;
|
||||
expiresIn: number;
|
||||
accessTokenMaxTTL: number;
|
||||
tokenData: IdentityAccessToken;
|
||||
};
|
||||
|
||||
export type UpdateTokenIdentityTokenAuthDTO = {
|
||||
|
||||
Reference in New Issue
Block a user