From 15fa10e265067641df7d9331435fb61944d89b41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B0=B4=E6=9C=AC=20=E7=A5=90=E5=B8=8C?= Date: Thu, 30 Nov 2023 04:17:16 +0000 Subject: [PATCH] =?UTF-8?q?Merged=20PR=20595:=20=E5=90=84service.ts?= =?UTF-8?q?=E3=81=AEout=E3=83=AD=E3=82=B0=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 概要 [Task3162: licenses.service.tsのoutログ追加](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3162) - 何をどう変更したか、追加したライブラリなど ・licenses.service.tsのolicenseOrdersとissueCardLicenseKeysの[OUT]ログを追加 ・横展開として他のservice.tsでOUT、INログが不足している場合は追加する ## 動作確認状況 - ユニットテスト --- .../src/features/accounts/accounts.service.ts | 27 +++- .../src/features/auth/auth.service.ts | 116 +++++++++++------ .../src/features/licenses/licenses.service.ts | 9 +- .../src/features/tasks/tasks.service.ts | 8 +- .../src/features/users/users.service.ts | 119 ++++++++++++------ 5 files changed, 194 insertions(+), 85 deletions(-) diff --git a/dictation_server/src/features/accounts/accounts.service.ts b/dictation_server/src/features/accounts/accounts.service.ts index 0b59167..fda08e0 100644 --- a/dictation_server/src/features/accounts/accounts.service.ts +++ b/dictation_server/src/features/accounts/accounts.service.ts @@ -152,6 +152,10 @@ export class AccountsService { makeErrorResponse('E009999'), HttpStatus.INTERNAL_SERVER_ERROR, ); + } finally { + this.logger.log( + `[OUT] [${context.getTrackingId()}] ${this.getLicenseSummary.name}`, + ); } } /** @@ -179,7 +183,7 @@ export class AccountsService { } | params: { ` + `dealerAccountId: ${dealerAccountId}, ` + `role: ${role}, ` + - `acceptedEulaVersion: ${acceptedEulaVersion} }, ` + + `acceptedEulaVersion: ${acceptedEulaVersion}, ` + `acceptedDpaVersion: ${acceptedDpaVersion} };`, ); try { @@ -333,6 +337,11 @@ export class AccountsService { externalUserId: string, context: Context, ): Promise { + this.logger.log( + `[IN] [${context.getTrackingId()}] ${ + this.createAccount.name + } | params: { ` + `externalUserId: ${externalUserId}};`, + ); try { await this.adB2cService.deleteUser(externalUserId, context); this.logger.log( @@ -344,6 +353,10 @@ export class AccountsService { this.logger.error( `${MANUAL_RECOVERY_REQUIRED} [${context.getTrackingId()}] Failed to delete externalUser: ${externalUserId}`, ); + } finally { + this.logger.log( + `[OUT] [${context.getTrackingId()}] ${this.deleteAdB2cUser.name}`, + ); } } @@ -368,6 +381,10 @@ export class AccountsService { this.logger.error( `${MANUAL_RECOVERY_REQUIRED} [${context.getTrackingId()}] Failed to delete account: ${accountId}, user: ${userId}`, ); + } finally { + this.logger.log( + `[OUT] [${context.getTrackingId()}] ${this.deleteAccount.name}`, + ); } } @@ -396,6 +413,10 @@ export class AccountsService { this.logger.error( `${MANUAL_RECOVERY_REQUIRED} [${context.getTrackingId()}] Failed to delete container: ${accountId}, country: ${country}`, ); + } finally { + this.logger.log( + `[OUT] [${context.getTrackingId()}] ${this.deleteBlobContainer.name}`, + ); } } @@ -1184,6 +1205,10 @@ export class AccountsService { makeErrorResponse('E009999'), HttpStatus.INTERNAL_SERVER_ERROR, ); + } finally { + this.logger.log( + `[OUT] [${context.getTrackingId()}] ${this.createTypistGroup.name}`, + ); } } diff --git a/dictation_server/src/features/auth/auth.service.ts b/dictation_server/src/features/auth/auth.service.ts index 06404c7..543ca12 100644 --- a/dictation_server/src/features/auth/auth.service.ts +++ b/dictation_server/src/features/auth/auth.service.ts @@ -119,7 +119,7 @@ export class AuthService { const privateKey = getPrivateKey(this.configService); // ユーザーのロールを設定 - const role = this.getUserRole(user.role); + const role = this.getUserRole(context, user.role); const token = sign( { @@ -250,7 +250,7 @@ export class AuthService { const privateKey = getPrivateKey(this.configService); // ユーザーのロールを設定 - const role = this.getUserRole(adminUser.role); + const role = this.getUserRole(context, adminUser.role); const token = sign( { @@ -540,6 +540,7 @@ export class AuthService { case jwt.JsonWebTokenError: // メッセージごとにエラーを判定しHTTPエラーを生成 throw this.makeHttpErrorFromJsonWebTokenErrorMessage( + context, message, issuer, ); @@ -561,6 +562,9 @@ export class AuthService { } getPublicKeyFromJwk(context: Context, jwkKey: JwkSignKey): string { + this.logger.log( + `[IN] [${context.getTrackingId()}] ${this.getPublicKeyFromJwk.name}`, + ); try { // JWK形式のJSONなのでJWTの公開鍵として使えるようにPEM形式に変換 const publicKey = jwkToPem({ @@ -584,53 +588,83 @@ export class AuthService { * JWT検証時のError、JsonWebTokenErrorをメッセージごとに仕分けてHTTPエラーを生成 */ makeHttpErrorFromJsonWebTokenErrorMessage = ( + context: Context, message: string, issuer: string, ): Error => { - // 署名が不正 - if (message === 'invalid signature') { - return new HttpException( - makeErrorResponse('E000104'), - HttpStatus.UNAUTHORIZED, - ); - } - // 想定発行元と異なる - if (message === `jwt issuer invalid. expected: ${issuer}`) { - return new HttpException( - makeErrorResponse('E000105'), - HttpStatus.UNAUTHORIZED, - ); - } - // アルゴリズムが想定と異なる - if (message === 'invalid algorithm') { - return new HttpException( - makeErrorResponse('E000106'), - HttpStatus.UNAUTHORIZED, - ); - } - // トークンの形式が不正 - return new HttpException( - makeErrorResponse('E000101'), - HttpStatus.UNAUTHORIZED, + this.logger.log( + `[IN] [${context.getTrackingId()}] ${ + this.makeHttpErrorFromJsonWebTokenErrorMessage.name + }`, ); + try { + // 署名が不正 + if (message === 'invalid signature') { + return new HttpException( + makeErrorResponse('E000104'), + HttpStatus.UNAUTHORIZED, + ); + } + // 想定発行元と異なる + if (message === `jwt issuer invalid. expected: ${issuer}`) { + return new HttpException( + makeErrorResponse('E000105'), + HttpStatus.UNAUTHORIZED, + ); + } + // アルゴリズムが想定と異なる + if (message === 'invalid algorithm') { + return new HttpException( + makeErrorResponse('E000106'), + HttpStatus.UNAUTHORIZED, + ); + } + // トークンの形式が不正 + return new HttpException( + makeErrorResponse('E000101'), + HttpStatus.UNAUTHORIZED, + ); + } catch (e) { + this.logger.error(`[${context.getTrackingId()}] error=${e}`); + throw e; + } finally { + this.logger.log( + `[OUT] [${context.getTrackingId()}] ${ + this.makeHttpErrorFromJsonWebTokenErrorMessage.name + }`, + ); + } }; + /** * トークンに設定するユーザーのロールを取得 */ - getUserRole = (role: string): string => { - // ユーザーのロールを設定 - // 万一不正なRoleが登録されていた場合、そのままDBの値を使用すると不正なロールのリフレッシュトークンが発行されるため、 - // ロールの設定値はDBに保存したRoleの値を直接トークンに入れないように定数で設定する - // ※none/author/typist以外はロールに設定されない - if (role === USER_ROLES.NONE) { - return USER_ROLES.NONE; - } else if (role === USER_ROLES.AUTHOR) { - return USER_ROLES.AUTHOR; - } else if (role === USER_ROLES.TYPIST) { - return USER_ROLES.TYPIST; - } else { - throw new RoleUnexpectedError( - `Role from DB is unexpected value. role=${role}`, + getUserRole = (context: Context, role: string): string => { + this.logger.log( + `[IN] [${context.getTrackingId()}] ${this.getUserRole.name}`, + ); + try { + // ユーザーのロールを設定 + // 万一不正なRoleが登録されていた場合、そのままDBの値を使用すると不正なロールのリフレッシュトークンが発行されるため、 + // ロールの設定値はDBに保存したRoleの値を直接トークンに入れないように定数で設定する + // ※none/author/typist以外はロールに設定されない + if (role === USER_ROLES.NONE) { + return USER_ROLES.NONE; + } else if (role === USER_ROLES.AUTHOR) { + return USER_ROLES.AUTHOR; + } else if (role === USER_ROLES.TYPIST) { + return USER_ROLES.TYPIST; + } else { + throw new RoleUnexpectedError( + `Role from DB is unexpected value. role=${role}`, + ); + } + } catch (e) { + this.logger.error(`[${context.getTrackingId()}] error=${e}`); + throw e; + } finally { + this.logger.log( + `[OUT] [${context.getTrackingId()}] ${this.getUserRole.name}`, ); } }; diff --git a/dictation_server/src/features/licenses/licenses.service.ts b/dictation_server/src/features/licenses/licenses.service.ts index 4a87ed0..d6e1c5e 100644 --- a/dictation_server/src/features/licenses/licenses.service.ts +++ b/dictation_server/src/features/licenses/licenses.service.ts @@ -12,7 +12,6 @@ import { import { LicensesRepositoryService } from '../../repositories/licenses/licenses.repository.service'; import { UserNotFoundError } from '../../repositories/users/errors/types'; import { - DateWithZeroTime, GetAllocatableLicensesResponse, IssueCardLicensesResponse, } from './types/types'; @@ -113,6 +112,10 @@ export class LicensesService { HttpStatus.INTERNAL_SERVER_ERROR, ); } + } finally { + this.logger.log( + `[OUT] [${context.getTrackingId()}] ${this.licenseOrders.name}`, + ); } } async issueCardLicenseKeys( @@ -164,6 +167,10 @@ export class LicensesService { makeErrorResponse('E009999'), HttpStatus.INTERNAL_SERVER_ERROR, ); + } finally { + this.logger.log( + `[OUT] [${context.getTrackingId()}] ${this.issueCardLicenseKeys.name}`, + ); } } diff --git a/dictation_server/src/features/tasks/tasks.service.ts b/dictation_server/src/features/tasks/tasks.service.ts index 1a26637..200b00f 100644 --- a/dictation_server/src/features/tasks/tasks.service.ts +++ b/dictation_server/src/features/tasks/tasks.service.ts @@ -1,6 +1,5 @@ import { HttpException, HttpStatus, Injectable, Logger } from '@nestjs/common'; import { TasksRepositoryService } from '../../repositories/tasks/tasks.repository.service'; -import { AccessToken } from '../../common/token'; import { Assignee, Task } from './types/types'; import { Task as TaskEntity } from '../../repositories/tasks/entity/task.entity'; import { createTasks } from './types/convert'; @@ -625,6 +624,10 @@ export class TasksService { ...new Set(assigneesExternalIds.concat(typistExternalIds)), ]; + this.logger.log( + `[OUT] [${context.getTrackingId()}] ${this.getB2cUsers.name}`, + ); + // B2Cからユーザー名を取得する return await this.adB2cService.getUsers(context, distinctedExternalIds); } @@ -769,5 +772,8 @@ export class TasksService { priority: file.priority === '00' ? 'Normal' : 'High', uploadedAt: file.uploaded_at.toISOString(), }); + this.logger.log( + `[OUT] [${context.getTrackingId()}] ${this.sendNotify.name}`, + ); } } diff --git a/dictation_server/src/features/users/users.service.ts b/dictation_server/src/features/users/users.service.ts index 32e4d2d..cf82fd5 100644 --- a/dictation_server/src/features/users/users.service.ts +++ b/dictation_server/src/features/users/users.service.ts @@ -117,6 +117,10 @@ export class UsersService { makeErrorResponse('E009999'), HttpStatus.INTERNAL_SERVER_ERROR, ); + } finally { + this.logger.log( + `[OUT] [${context.getTrackingId()}] ${this.confirmUser.name}`, + ); } } @@ -313,6 +317,11 @@ export class UsersService { // Azure AD B2Cに登録したユーザー情報を削除する // TODO 「タスク 2452: リトライ処理を入れる箇所を検討し、実装する」の候補 private async deleteB2cUser(externalUserId: string, context: Context) { + this.logger.log( + `[IN] [${context.getTrackingId()}] ${ + this.deleteB2cUser.name + } | params: { externalUserId: ${externalUserId} }`, + ); try { await this.adB2cService.deleteUser(externalUserId, context); this.logger.log( @@ -323,11 +332,20 @@ export class UsersService { this.logger.error( `${MANUAL_RECOVERY_REQUIRED} [${context.getTrackingId()}] Failed to delete externalUser: ${externalUserId}`, ); + } finally { + this.logger.log( + `[OUT] [${context.getTrackingId()}] ${this.deleteB2cUser.name}`, + ); } } // DBに登録したユーザー情報を削除する private async deleteUser(userId: number, context: Context) { + this.logger.log( + `[IN] [${context.getTrackingId()}] ${ + this.deleteUser.name + } | params: { userId: ${userId} }`, + ); try { await this.usersRepository.deleteNormalUser(userId); this.logger.log(`[${context.getTrackingId()}] delete user: ${userId}`); @@ -336,6 +354,10 @@ export class UsersService { this.logger.error( `${MANUAL_RECOVERY_REQUIRED} [${context.getTrackingId()}] Failed to delete user: ${userId}`, ); + } finally { + this.logger.log( + `[OUT] [${context.getTrackingId()}] ${this.deleteUser.name}`, + ); } } @@ -368,47 +390,56 @@ export class UsersService { `encryption: ${encryption}, ` + `prompt: ${prompt} };`, ); - switch (role) { - case USER_ROLES.NONE: - case USER_ROLES.TYPIST: - return { - account_id: accountId, - external_id: externalId, - auto_renew: autoRenew, - license_alert: licenseAlert, - notification, - role, - accepted_dpa_version: null, - accepted_eula_version: null, - encryption: false, - encryption_password: null, - prompt: false, - author_id: null, - }; - case USER_ROLES.AUTHOR: - return { - account_id: accountId, - external_id: externalId, - auto_renew: autoRenew, - license_alert: licenseAlert, - notification, - role, - author_id: authorId ?? null, - encryption: encryption ?? false, - encryption_password: encryptionPassword ?? null, - prompt: prompt ?? false, - accepted_dpa_version: null, - accepted_eula_version: null, - }; - default: - //不正なroleが指定された場合はログを出力してエラーを返す - this.logger.error( - `[${context.getTrackingId()}] [NOT IMPLEMENT] [RECOVER] role: ${role}`, - ); - throw new HttpException( - makeErrorResponse('E009999'), - HttpStatus.INTERNAL_SERVER_ERROR, - ); + try { + switch (role) { + case USER_ROLES.NONE: + case USER_ROLES.TYPIST: + return { + account_id: accountId, + external_id: externalId, + auto_renew: autoRenew, + license_alert: licenseAlert, + notification, + role, + accepted_dpa_version: null, + accepted_eula_version: null, + encryption: false, + encryption_password: null, + prompt: false, + author_id: null, + }; + case USER_ROLES.AUTHOR: + return { + account_id: accountId, + external_id: externalId, + auto_renew: autoRenew, + license_alert: licenseAlert, + notification, + role, + author_id: authorId ?? null, + encryption: encryption ?? false, + encryption_password: encryptionPassword ?? null, + prompt: prompt ?? false, + accepted_dpa_version: null, + accepted_eula_version: null, + }; + default: + //不正なroleが指定された場合はログを出力してエラーを返す + this.logger.error( + `[${context.getTrackingId()}] [NOT IMPLEMENT] [RECOVER] role: ${role}`, + ); + throw new HttpException( + makeErrorResponse('E009999'), + HttpStatus.INTERNAL_SERVER_ERROR, + ); + } + } catch (e) { + this.logger.error(`[${context.getTrackingId()}] error=${e}`); + return e; + } finally { + this.logger.log( + `[OUT] [${context.getTrackingId()}] ${this.createNewUserInfo.name}`, + ); } } @@ -486,6 +517,12 @@ export class UsersService { ); } } + } finally { + this.logger.log( + `[OUT] [${context.getTrackingId()}] ${ + this.confirmUserAndInitPassword.name + }`, + ); } }