From 47287be5bf071247150d46d078c7b0bb13779a10 Mon Sep 17 00:00:00 2001 From: Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> Date: Tue, 12 Mar 2024 14:18:46 +0100 Subject: [PATCH] Feat: Scoped JWT to organization, add authMethod to request --- backend/src/@types/fastify.d.ts | 3 +- .../server/plugins/auth/inject-identity.ts | 24 +++++++++++--- .../server/plugins/auth/inject-permission.ts | 32 ++++++++++++++++--- 3 files changed, 49 insertions(+), 10 deletions(-) diff --git a/backend/src/@types/fastify.d.ts b/backend/src/@types/fastify.d.ts index 649c54c54..8c048481c 100644 --- a/backend/src/@types/fastify.d.ts +++ b/backend/src/@types/fastify.d.ts @@ -19,7 +19,7 @@ import { TApiKeyServiceFactory } from "@app/services/api-key/api-key-service"; import { TAuthLoginFactory } from "@app/services/auth/auth-login-service"; import { TAuthPasswordFactory } from "@app/services/auth/auth-password-service"; import { TAuthSignupFactory } from "@app/services/auth/auth-signup-service"; -import { ActorType } from "@app/services/auth/auth-type"; +import { ActorAuthMethod } from "@app/services/auth/auth-type"; import { TAuthTokenServiceFactory } from "@app/services/auth-token/auth-token-service"; import { TIdentityServiceFactory } from "@app/services/identity/identity-service"; import { TIdentityAccessTokenServiceFactory } from "@app/services/identity-access-token/identity-access-token-service"; @@ -59,6 +59,7 @@ declare module "fastify" { // identity injection. depending on which kinda of token the information is filled in auth auth: TAuthMode; permission: { + authMethod: ActorAuthMethod; type: ActorType; id: string; orgId?: string; diff --git a/backend/src/server/plugins/auth/inject-identity.ts b/backend/src/server/plugins/auth/inject-identity.ts index ab70118cf..95deb78a5 100644 --- a/backend/src/server/plugins/auth/inject-identity.ts +++ b/backend/src/server/plugins/auth/inject-identity.ts @@ -6,7 +6,7 @@ import { TServiceTokens, TUsers } from "@app/db/schemas"; import { TScimTokenJwtPayload } from "@app/ee/services/scim/scim-types"; import { getConfig } from "@app/lib/config/env"; import { UnauthorizedError } from "@app/lib/errors"; -import { ActorType, AuthMode, AuthModeJwtTokenPayload, AuthTokenType } from "@app/services/auth/auth-type"; +import { ActorType, AuthMethod, AuthMode, AuthModeJwtTokenPayload, AuthTokenType } from "@app/services/auth/auth-type"; import { TIdentityAccessTokenJwtPayload } from "@app/services/identity-access-token/identity-access-token-types"; export type TAuthMode = @@ -17,6 +17,7 @@ export type TAuthMode = tokenVersionId: string; // the session id of token used user: TUsers; orgId?: string; + authMethod: AuthMethod; } // | { // authMode: AuthMode.API_KEY; @@ -31,6 +32,7 @@ export type TAuthMode = actor: ActorType.SERVICE; serviceTokenId: string; orgId: string; + authMethod: null; } | { authMode: AuthMode.IDENTITY_ACCESS_TOKEN; @@ -38,12 +40,14 @@ export type TAuthMode = identityId: string; identityName: string; orgId: string; + authMethod: null; } | { authMode: AuthMode.SCIM_TOKEN; actor: ActorType.SCIM_CLIENT; scimTokenId: string; orgId: string; + authMethod: null; }; const extractAuth = async (req: FastifyRequest, jwtSecret: string) => { @@ -108,7 +112,15 @@ export const injectIdentity = fp(async (server: FastifyZodProvider) => { switch (authMode) { case AuthMode.JWT: { const { user, tokenVersionId, orgId } = await server.services.authToken.fnValidateJwtIdentity(token); - req.auth = { authMode: AuthMode.JWT, user, userId: user.id, tokenVersionId, actor, orgId }; + req.auth = { + authMode: AuthMode.JWT, + user, + userId: user.id, + tokenVersionId, + actor, + orgId, + authMethod: token.authMethod + }; break; } // Will always contain an orgId. @@ -119,7 +131,8 @@ export const injectIdentity = fp(async (server: FastifyZodProvider) => { actor, orgId: identity.orgId, identityId: identity.identityId, - identityName: identity.name + identityName: identity.name, + authMethod: null }; break; } @@ -130,7 +143,8 @@ export const injectIdentity = fp(async (server: FastifyZodProvider) => { authMode: AuthMode.SERVICE_TOKEN as const, serviceToken, serviceTokenId: serviceToken.id, - actor + actor, + authMethod: null }; break; } @@ -141,7 +155,7 @@ export const injectIdentity = fp(async (server: FastifyZodProvider) => { // } case AuthMode.SCIM_TOKEN: { const { orgId, scimTokenId } = await server.services.scim.fnValidateScimToken(token); - req.auth = { authMode: AuthMode.SCIM_TOKEN, actor, scimTokenId, orgId }; + req.auth = { authMode: AuthMode.SCIM_TOKEN, actor, scimTokenId, orgId, authMethod: null }; break; } default: diff --git a/backend/src/server/plugins/auth/inject-permission.ts b/backend/src/server/plugins/auth/inject-permission.ts index 02cc842d6..b76c735f0 100644 --- a/backend/src/server/plugins/auth/inject-permission.ts +++ b/backend/src/server/plugins/auth/inject-permission.ts @@ -8,14 +8,38 @@ export const injectPermission = fp(async (server) => { server.addHook("onRequest", async (req) => { if (!req.auth) return; + // if (!req.auth.authMethod) { + // throw new Error("THIS SHOULD NOT HAPPEN"); + // } + if (req.auth.actor === ActorType.USER) { - req.permission = { type: ActorType.USER, id: req.auth.userId, orgId: req.auth.orgId }; + req.permission = { + type: ActorType.USER, + id: req.auth.userId, + orgId: req.auth.orgId, + authMethod: req.auth.authMethod + }; } else if (req.auth.actor === ActorType.IDENTITY) { - req.permission = { type: ActorType.IDENTITY, id: req.auth.identityId, orgId: req.auth.orgId }; + req.permission = { + type: ActorType.IDENTITY, + id: req.auth.identityId, + orgId: req.auth.orgId, + authMethod: null + }; } else if (req.auth.actor === ActorType.SERVICE) { - req.permission = { type: ActorType.SERVICE, id: req.auth.serviceTokenId, orgId: req.auth.orgId }; + req.permission = { + type: ActorType.SERVICE, + id: req.auth.serviceTokenId, + orgId: req.auth.orgId, + authMethod: null + }; } else if (req.auth.actor === ActorType.SCIM_CLIENT) { - req.permission = { type: ActorType.SCIM_CLIENT, id: req.auth.scimTokenId, orgId: req.auth.orgId }; + req.permission = { + type: ActorType.SCIM_CLIENT, + id: req.auth.scimTokenId, + orgId: req.auth.orgId, + authMethod: null + }; } }); });