Compare commits

..
3 changed files with 24 additions and 79 deletions
@@ -1,57 +0,0 @@
import { HttpException, HttpStatus } from '@nestjs/common';
import { Metadata } from '@grpc/grpc-js';
import { of } from 'rxjs';
import { AuthClientService } from './auth.service';
describe('AuthClientService.resetUsers', () => {
const logger = {
info: jest.fn(),
debug: jest.fn(),
error: jest.fn(),
};
const resetUser = jest.fn();
let service: AuthClientService;
beforeEach(() => {
jest.clearAllMocks();
service = new AuthClientService({ logger } as any, {} as any);
(service as any).authService = { ResetUser: resetUser };
});
it('returns the DUC response when every requested user was reset', async () => {
const response = {
message: 'Users reset successfully',
successfulUsers: ['user-1'],
failedUsers: [],
};
resetUser.mockReturnValue(of(response));
await expect(
service.resetUsers(['user-1'], new Metadata()),
).resolves.toEqual(response);
});
it('returns a non-2xx error instead of masking failed resets', async () => {
const response = {
message: 'Some users failed',
successfulUsers: ['user-1'],
failedUsers: ['user-2'],
};
resetUser.mockReturnValue(of(response));
try {
await service.resetUsers(['user-1', 'user-2'], new Metadata());
fail('Expected resetUsers to reject');
} catch (error) {
expect(error).toBeInstanceOf(HttpException);
expect((error as HttpException).getStatus()).toBe(HttpStatus.BAD_GATEWAY);
expect((error as HttpException).getResponse()).toEqual({
statusCode: HttpStatus.BAD_GATEWAY,
message: 'Failed to reset MFA for one or more users.',
successfulUsers: ['user-1'],
failedUsers: ['user-2'],
});
}
});
});
-16
View File
@@ -295,22 +295,6 @@ export class AuthClientService implements OnModuleInit {
this.authService.ResetUser({ users }, metadata),
);
if (response.failedUsers?.length > 0) {
this.logger.error('resetUsers - Partial or total failure', {
successfulUsers: response.successfulUsers,
failedUsers: response.failedUsers,
});
throw new HttpException(
{
statusCode: HttpStatus.BAD_GATEWAY,
message: 'Failed to reset MFA for one or more users.',
successfulUsers: response.successfulUsers,
failedUsers: response.failedUsers,
},
HttpStatus.BAD_GATEWAY,
);
}
this.logger.info('resetUsers - Success', { response });
return response;
} catch (error) {
@@ -187,6 +187,20 @@ export class ConnectionTestService {
body: GetTableMetadataReq,
user: RequestUser,
): Promise<GetTableMetadataRes> {
// Columns eligible as the incremental reference field are the ones whose
// data type is allowed for this engine (e.g. int/date/timestamp). The
// allowlist is owned by the platform API, keyed by engine === plugin.
const allowedByEngine = await this.platformApiService
.proxy('GET', '/jobs/jdbc/configs/allowed_datatypes', user)
.catch(() => null);
const allowedDataTypes: string[] =
allowedByEngine?.allowed_datatypes?.find(
(datatypes) => datatypes.engine === body.plugin,
)?.allowed_datatypes ?? [];
const allowedSet = new Set(
allowedDataTypes.map((type) => type.toLowerCase()),
);
const tables_metadata = await Promise.all(
body.table_list.map(async (table_name) => {
const result = await this.connectionsApiService.proxy(
@@ -196,14 +210,18 @@ export class ConnectionTestService {
`/tables/${encodeURIComponent(table_name)}/columns`,
user,
);
const columns = result.columns.map((column) => ({
name: column.column_name,
type: column.data_type,
is_primary_key: column.is_primary_key,
}));
const references = columns.filter((column) =>
allowedSet.has(String(column.type).toLowerCase()),
);
return {
table_name,
columns: result.columns.map((column) => ({
name: column.column_name,
type: column.data_type,
is_primary_key: column.is_primary_key,
})),
references: [],
columns,
references,
};
}),
);