Skip to content

Commit

Permalink
PRO-3083 & PRO-3102: Deprecate use of Bio Auth Service /templatizer &…
Browse files Browse the repository at this point in the history
… update comments (#71)

* Calls to Bio Auth Service should use /save instead of /templatizer.
* Update comments throughout the repo to reference Bio Auth Service instead of Identity Service.

Signed-off-by: Jeff Kennedy <[email protected]>
  • Loading branch information
Jeff Kennedy authored Jun 17, 2021
1 parent 86d38cc commit dc00ace
Show file tree
Hide file tree
Showing 11 changed files with 94 additions and 32 deletions.
25 changes: 13 additions & 12 deletions src/plugins/impl/fingerprint.plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import { ExternalIdDbGateway } from '../../db/external.id.db.gateway';
import { IsValidInstance } from 'protocol-common/validation/decorators/parameter/is.valid.instance.decorator';
import { ValidateParams } from 'protocol-common/validation/decorators/function/validate.params.decorator';
import { IsValidInstanceOf } from 'protocol-common/validation/decorators/parameter/is.valid.instance.of.decorator';
import { BioAuthSaveParamsDto } from '../../remote/dto/bio.auth.save.params.dto';
import { BioAuthSaveDto } from '../../remote/dto/bio.auth.save.dto';

export class FingerprintPlugin implements IPlugin {

Expand All @@ -23,9 +25,9 @@ export class FingerprintPlugin implements IPlugin {
) { }

/**
* The verify logic involves calling verify against the identity service, and then handling certain error codes
* by asking the identity service for the positions with the highest image quality
* TODO identity service could just handle both these tasks in one call.
* The verify logic involves calling verify against the Bio Auth Service, and then handling certain error codes by asking the Bio Auth Service for
* the positions with the highest image quality
* TODO - PRO-3134: Update this after Bio Auth Service handles both these tasks in one call.
*/
@ValidateParams
public async verify(
Expand Down Expand Up @@ -59,12 +61,12 @@ export class FingerprintPlugin implements IPlugin {
}
}

// The identity service should throw this error on no match, but just to be safe double check it and throw here
// Bio Auth Service should throw this error on no match, but just to be safe double check it and throw here
if (response.data.status !== 'matched') {
throw new ProtocolException(ProtocolErrorCode.FINGERPRINT_NO_MATCH, 'Fingerprint did not match stored records for citizen supplied through filters');
}

// TODO right now the data we get from identity service uses did we should change it to agent id and then we don't need this conversion
// TODO right now the data we get from Bio Auth Service uses did we should change it to agent id and then we don't need this conversion
return {
status: response.data.status,
id: response.data.did
Expand All @@ -77,17 +79,16 @@ export class FingerprintPlugin implements IPlugin {
e.details = e.details || {};
e.details.bestPositions = response.data;
} catch (ex) {
Logger.error('Error calling identity service position quality check', ex);
Logger.error('Error calling Bio Auth Service position quality check', ex);
}
return e;
}

public async save(id: string, params: any) {
// TEMP until the identity service is updated
public async save(id: string, params: BioAuthSaveParamsDto | BioAuthSaveParamsDto[]) {
const data = Array.isArray(params) ? params : [params];
for (const datum of data) {
datum.did = id;
}
await this.bioAuthService.templatize(data);
const fingerprints: BioAuthSaveDto[] = data.map((param: BioAuthSaveParamsDto) => {
return {id, params: param};
});
await this.bioAuthService.bulkSave({fingerprints});
}
}
4 changes: 3 additions & 1 deletion src/remote/bio.auth.service.interface.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { BioAuthBulkSaveDto } from './dto/bio.auth.bulk.save.dto';

export abstract class IBioAuthService {
abstract verifyFingerprint(position: number, image: string, dids: string): Promise<any>;
abstract verifyFingerprintTemplate(position: number, template: string, dids: string): Promise<any>;
abstract templatize(data: any): Promise<any>;
abstract bulkSave(dto: BioAuthBulkSaveDto): Promise<any>;
abstract qualityCheck(dids: string): Promise<any>;
}
9 changes: 9 additions & 0 deletions src/remote/dto/bio.auth.bulk.save.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { BioAuthSaveDto } from './bio.auth.save.dto';
import { ValidateNested } from 'class-validator';

/**
* DTO for each fingerprint in the body of the request sent to Bio Auth Service's /save endpoint
*/
export class BioAuthBulkSaveDto {
@ValidateNested() readonly fingerprints: Array<BioAuthSaveDto>;
}
11 changes: 11 additions & 0 deletions src/remote/dto/bio.auth.save.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { BioAuthSaveParamsDto } from './bio.auth.save.params.dto';
import { IsString, ValidateNested } from 'class-validator';
import { Type } from 'class-transformer';

/**
* DTO for the body of the request sent to Bio Auth Service's /save endpoint
*/
export class BioAuthSaveDto {
@IsString() readonly id: string;
@ValidateNested() @Type(() => BioAuthSaveParamsDto) readonly params: BioAuthSaveParamsDto;
}
17 changes: 17 additions & 0 deletions src/remote/dto/bio.auth.save.params.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { FingerprintTypeEnum } from '../fingerprint.type.enum';
import { IsEnum, IsInt, IsISO8601, IsNumber, IsOptional, IsString, Length } from 'class-validator';
import { FingerprintPositionEnum } from '../fingerprint.position.enum';

/**
* DTO for the params of each fingerprint in the body of the request sent to Bio Auth Service's /save endpoint
*/
export class BioAuthSaveParamsDto {
@IsInt() readonly type_id: number;
@IsISO8601() readonly capture_date: string;
@IsEnum(FingerprintPositionEnum) readonly position: FingerprintPositionEnum;
@IsOptional() @IsString() readonly image?: string;
@IsOptional() @IsString() readonly template?: string;
@IsOptional() @IsNumber() readonly quality_score?: number;
@IsOptional() @Length(2, 2) readonly missing_code?: string;
@IsEnum(FingerprintTypeEnum) readonly type: FingerprintTypeEnum;
}
15 changes: 15 additions & 0 deletions src/remote/fingerprint.position.enum.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* This enum is a simple way to capture which finger is represented by a given fingerprint.
*/
export enum FingerprintPositionEnum {
RIGHT_THUMB = '1',
RIGHT_INDEX = '2',
RIGHT_MIDDLE = '3',
RIGHT_RING = '4',
RIGHT_PINKY = '5',
LEFT_THUMB = '6',
LEFT_INDEX = '7',
LEFT_MIDDLE = '8',
LEFT_RING = '9',
LEFT_PINKY = '10'
}
7 changes: 7 additions & 0 deletions src/remote/fingerprint.type.enum.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/**
* Currently supported modes of interacting with Bio Auth Service via fingerprints
*/
export enum FingerprintTypeEnum {
IMAGE = 'IMAGE',
TEMPLATE = 'TEMPLATE'
}
31 changes: 15 additions & 16 deletions src/remote/impl/bio.auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ import { ProtocolHttpService } from 'protocol-common/protocol.http.service';
import { AxiosRequestConfig } from 'axios';
import { HttpService, Injectable } from '@nestjs/common';
import { IBioAuthService } from '../bio.auth.service.interface';
import { BioAuthBulkSaveDto } from '../dto/bio.auth.bulk.save.dto';
import { FingerprintTypeEnum } from '../fingerprint.type.enum';

/**
* This service class is a facade for the IdentityService HTTP API.
*
* Right now the backend (ie which fingerprint template db to connect to) is defined by an environment variable, eventually we'll want this to
* be set in a country profile, so the process of setting the backend will change.
* This service class is a facade for the Bio Auth Service HTTP API.
*/
@Injectable()
export class BioAuthService implements IBioAuthService {
Expand All @@ -21,12 +20,11 @@ export class BioAuthService implements IBioAuthService {
}

/**
* Send a request to IdentityService to verify a fingerprint image.
* TODO right now this keeps the identity service url the same, we probably want to change that so it better matches our plugin pattern
* Send a request to Bio Auth Service to verify a fingerprint image.
*
* @param position The position of the finger that the fingerprint template refers to.
* @param image The image of the fingerprint.
* @param dids A comma-separated list of dids that the fingerprint template may correspond to.
* @param dids A comma-separated list of dids that the fingerprint may correspond to.
*/
public async verifyFingerprint(position: number, image: string, dids: string): Promise<any> {
const request: AxiosRequestConfig = {
Expand All @@ -45,7 +43,7 @@ export class BioAuthService implements IBioAuthService {
}

/**
* Send a request to IdentityService to verify a fingerprint template.
* Send a request to Bio Auth Service to verify a fingerprint template.
*
* @param position The position of the finger that the fingerprint template refers to.
* @param template The template of the fingerprint.
Expand All @@ -62,28 +60,29 @@ export class BioAuthService implements IBioAuthService {
filters: {
dids
},
imageType: 'TEMPLATE',
imageType: FingerprintTypeEnum.TEMPLATE,
},
};
return this.http.requestWithRetry(request);
}

/**
* TODO the identity service should update the templatizer endpoint to accept data in the format { id, filters, params }
* Until it does, we just forward the params as the data it's currently expecting
* Send a request to Bio Auth Service to save one or more fingerprints. They may be fingerprint templates or images.
*
* @param dto Body of the request to be sent to Bio Auth Service. See the class definition for the shape.
*/
public async templatize(data: any): Promise<any> {
public async bulkSave(dto: BioAuthBulkSaveDto): Promise<any> {
const request: AxiosRequestConfig = {
method: 'POST',
url: `${this.baseUrl}/api/v1/templatizer/bulk/template`,
data,
url: `${this.baseUrl}/api/v1/save`,
data: dto,
};
return this.http.requestWithRetry(request);
}

/**
* Queries the identity service to get the finger positions with the best quality scores
* TODO the identity service should update the positions endpoint to accept data in the body instead of via url params
* Queries the Bio Auth Service to get the finger positions with the best quality scores
* TODO PRO-3084: use the Bio Auth Service POST /positions endpoint to accept data in the body instead of via url params
*/
public async qualityCheck(dids: string): Promise<any> {
const request: AxiosRequestConfig = {
Expand Down
2 changes: 1 addition & 1 deletion src/sms/sms.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export class SmsService {

const externalIds: ExternalId[] = await this.externalIdDbGateway.fetchExternalIds(VerifyFiltersDto.getIds(filters));
if (externalIds.some((id: ExternalId) => id.did !== externalIds[0].did)) {
throw new ProtocolException(ProtocolErrorCode.DUPLICATE_ENTRY, 'Provided filters did not uniquely identity a did');
throw new ProtocolException(ProtocolErrorCode.DUPLICATE_ENTRY, 'Provided filters did not uniquely identify a did');
}
const did: string = externalIds[0].did;

Expand Down
2 changes: 1 addition & 1 deletion test/e2e/escrow.fingerprint.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ describe('EscrowController (e2e) using fingerprint plugin', () => {
jest.setTimeout(10000);

status = 'matched';
did = 'agentId123'; // Right now identity service returns did, eventually it will return agentId
did = 'agentId123'; // Right now Bio Auth Service returns did, eventually it will return agentId

const mockAgencyService = new MockAgencyService('foo');
const mockBioAuthService = new MockBioAuthService(status, did);
Expand Down
3 changes: 2 additions & 1 deletion test/mock/mock.bio.auth.service.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { IBioAuthService } from '../../src/remote/bio.auth.service.interface';
import { BioAuthBulkSaveDto } from '../../src/remote/dto/bio.auth.bulk.save.dto';

export class MockBioAuthService implements IBioAuthService {

constructor(private readonly status: string, private readonly did: string) {}

async templatize(data: any): Promise<any> {
async bulkSave(dto: BioAuthBulkSaveDto): Promise<any> {
return Promise.resolve(undefined);
}

Expand Down

0 comments on commit dc00ace

Please sign in to comment.