Skip to content

Commit

Permalink
chore: update authenticator, mock with AccountId.
Browse files Browse the repository at this point in the history
  • Loading branch information
benoitdevos committed Apr 9, 2024
1 parent 81e79d8 commit b00cf3e
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 28 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@logion/rest-api-core",
"version": "0.4.8-4",
"version": "0.4.8-5",
"repository": {
"type": "git",
"url": "git+https://github.com/logion-network/logion-rest-api-core.git"
Expand All @@ -26,7 +26,7 @@
"coverage": "nyc yarn run test"
},
"dependencies": {
"@logion/authenticator": "^0.5.6-3",
"@logion/authenticator": "^0.5.6-4",
"dinoloop": "^2.4.0",
"express": "^4.18.2",
"express-fileupload": "^1.4.0",
Expand Down
5 changes: 3 additions & 2 deletions src/AuthenticationService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { injectable } from "inversify";
import { Request } from "express";
import { UnauthorizedException } from "dinoloop/modules/builtin/exceptions/exceptions.js";
import { AuthenticationSystemFactory, unauthorized } from "./AuthenticationSystemFactory.js";
import { ValidAccountId } from "@logion/node-api";

@injectable()
export class AuthenticationService {
Expand All @@ -17,7 +18,7 @@ export class AuthenticationService {
return authenticator.ensureAuthenticatedUserOrThrow(jwtToken);
}

async authenticatedUserIs(request: Request, address: string | undefined | null): Promise<AuthenticatedUser> {
async authenticatedUserIs(request: Request, address: ValidAccountId | undefined | null): Promise<AuthenticatedUser> {
const user = await this.authenticatedUser(request);
user.require(user => user.is(address), "User has not access to this resource");
return user;
Expand All @@ -28,7 +29,7 @@ export class AuthenticationService {
return user.requireLegalOfficerOnNode();
}

async authenticatedUserIsOneOf(request: Request, ...addresses: (string | undefined | null)[]): Promise<AuthenticatedUser> {
async authenticatedUserIsOneOf(request: Request, ...addresses: (ValidAccountId | undefined | null)[]): Promise<AuthenticatedUser> {
const user = await this.authenticatedUser(request);
user.require(user => user.isOneOf(addresses), "User has not access to this resource");
return user;
Expand Down
50 changes: 31 additions & 19 deletions src/TestApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ import { Mock } from "moq.ts";
import { AuthenticationService } from "./AuthenticationService.js";
import { UnauthorizedException } from "dinoloop/modules/builtin/exceptions/exceptions.js";
import { buildBaseExpress } from "./Express.js";
import { AccountId, AnyAccountId } from "@logion/node-api";

export const ALICE = "vQx5kESPn8dWyX4KxMCKqUyCaWUwtui1isX6PVNcZh2Ghjitr";
export const BOB = "vQvWaxNDdzuX5N3qSvGMtjdHcQdw1TAcPNgx4S1Utd3MTxYeN";
const ALICE_ACCOUNT = new AnyAccountId(ALICE, "Polkadot").toValidAccountId();

export * from "./TestUtil.js";

Expand Down Expand Up @@ -68,8 +70,8 @@ export interface AuthenticationServiceMock {
ensureAuthorizationBearer: () => void;
}

export function mockAuthenticationWithCondition(conditionFulfilled: boolean, address?: string): AuthenticationServiceMock {
const authenticatedUser = mockAuthenticatedUser(conditionFulfilled, address);
export function mockAuthenticationWithCondition(conditionFulfilled: boolean, account?: AccountId): AuthenticationServiceMock {
const authenticatedUser = mockAuthenticatedUser(conditionFulfilled, account);
const ensureAuthorizationBearerMock = () => {
if (!conditionFulfilled) {
throw new UnauthorizedException();
Expand Down Expand Up @@ -112,13 +114,16 @@ export function mockAuthenticationFailureWithInvalidSignature(): AuthenticationS
}
}

export function mockAuthenticationForUserOrLegalOfficer(isLegalOfficer: boolean, address?: string) {
export function mockAuthenticationForUserOrLegalOfficer(isLegalOfficer: boolean, account?: AccountId) {
const authenticatedUser = new Mock<AuthenticatedUser>();
authenticatedUser.setup(instance => instance.address).returns(address || ALICE);
authenticatedUser.setup(instance => instance.type).returns("Polkadot");
authenticatedUser.setup(instance => instance.isPolkadot()).returns(true);
authenticatedUser.setup(instance => instance.is).returns(() => true);
authenticatedUser.setup(instance => instance.isOneOf).returns(() => true);
const validAccount = account ?
new AnyAccountId(account.address, account.type).toValidAccountId() :
ALICE_ACCOUNT;
authenticatedUser.setup(instance => instance.address).returns(validAccount.address);
authenticatedUser.setup(instance => instance.type).returns(validAccount.type);
authenticatedUser.setup(instance => instance.isPolkadot()).returns(validAccount.type === "Polkadot");
authenticatedUser.setup(instance => instance.is).returns(account => account !== undefined && account !== null && account.equals(validAccount));
authenticatedUser.setup(instance => instance.isOneOf).returns(accounts => accounts.some(account => account !== undefined && account !== null && account.equals(validAccount)));
authenticatedUser.setup(instance => instance.require).returns((predicate) => {
if(!predicate(authenticatedUser.object())) {
throw new UnauthorizedException();
Expand All @@ -135,6 +140,7 @@ export function mockAuthenticationForUserOrLegalOfficer(isLegalOfficer: boolean,
throw new UnauthorizedException();
}
})
authenticatedUser.setup(instance => instance.toValidAccountId()).returns(validAccount)
return mockAuthenticationWithAuthenticatedUser(authenticatedUser.object());
}

Expand All @@ -151,11 +157,14 @@ function mockAuthenticationService(mock: AuthenticationServiceMock): Authenticat
return authenticationService.object();
}

export function mockAuthenticatedUser(conditionFulfilled: boolean, address?: string): AuthenticatedUser {
export function mockAuthenticatedUser(conditionFulfilled: boolean, account?: AccountId): AuthenticatedUser {
const authenticatedUser = new Mock<AuthenticatedUser>();
authenticatedUser.setup(instance => instance.address).returns(address || ALICE);
authenticatedUser.setup(instance => instance.type).returns("Polkadot");
authenticatedUser.setup(instance => instance.isPolkadot()).returns(true);
const validAccount = account ?
new AnyAccountId(account.address, account.type).toValidAccountId() :
ALICE_ACCOUNT;
authenticatedUser.setup(instance => instance.address).returns(validAccount.address);
authenticatedUser.setup(instance => instance.type).returns(validAccount.type);
authenticatedUser.setup(instance => instance.isPolkadot()).returns(validAccount.type === "Polkadot");
authenticatedUser.setup(instance => instance.is).returns(() => conditionFulfilled);
authenticatedUser.setup(instance => instance.isOneOf).returns(() => conditionFulfilled);
authenticatedUser.setup(instance => instance.require).returns((predicate) => {
Expand All @@ -168,22 +177,24 @@ export function mockAuthenticatedUser(conditionFulfilled: boolean, address?: str
authenticatedUser.setup(instance => instance.isNodeOwner).returns(() => conditionFulfilled);
authenticatedUser.setup(instance => instance.isLegalOfficer()).returnsAsync(conditionFulfilled);
authenticatedUser.setup(instance => instance.requireLegalOfficerOnNode).returns(() => {
if (address === ALICE) {
if (account?.address === ALICE) {
return Promise.resolve(authenticatedUser.object());
} else {
throw new UnauthorizedException();
}
});
authenticatedUser.setup(instance => instance.toValidAccountId()).returns(validAccount)
return authenticatedUser.object();
}

export function mockLegalOfficerOnNode(address: string): AuthenticatedUser {
export function mockLegalOfficerOnNode(account: AccountId): AuthenticatedUser {
const authenticatedUser = new Mock<AuthenticatedUser>();
authenticatedUser.setup(instance => instance.address).returns(address);
authenticatedUser.setup(instance => instance.type).returns("Polkadot");
authenticatedUser.setup(instance => instance.isPolkadot()).returns(true);
authenticatedUser.setup(instance => instance.is).returns((param) => param === address);
authenticatedUser.setup(instance => instance.isOneOf).returns(addresses => addresses.indexOf(address) >= 0);
const validAccount = new AnyAccountId(account.address, account.type).toValidAccountId();
authenticatedUser.setup(instance => instance.address).returns(validAccount.address);
authenticatedUser.setup(instance => instance.type).returns(validAccount.type);
authenticatedUser.setup(instance => instance.isPolkadot()).returns(validAccount.type === "Polkadot");
authenticatedUser.setup(instance => instance.is).returns(account => account !== undefined && account !== null && account.equals(validAccount));
authenticatedUser.setup(instance => instance.isOneOf).returns(accounts => accounts.some(account => account !== undefined && account !== null && account.equals(validAccount)));
authenticatedUser.setup(instance => instance.require).returns((predicate) => {
if (!predicate(authenticatedUser.object())) {
throw new UnauthorizedException();
Expand All @@ -194,6 +205,7 @@ export function mockLegalOfficerOnNode(address: string): AuthenticatedUser {
authenticatedUser.setup(instance => instance.isNodeOwner()).returns(true);
authenticatedUser.setup(instance => instance.isLegalOfficer()).returnsAsync(true);
authenticatedUser.setup(instance => instance.requireLegalOfficerOnNode()).returns(Promise.resolve(authenticatedUser.object()));
authenticatedUser.setup(instance => instance.toValidAccountId()).returns(validAccount)
return authenticatedUser.object();
}

Expand Down
10 changes: 5 additions & 5 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -564,9 +564,9 @@ __metadata:
languageName: node
linkType: hard

"@logion/authenticator@npm:^0.5.6-3":
version: 0.5.6-3
resolution: "@logion/authenticator@npm:0.5.6-3"
"@logion/authenticator@npm:^0.5.6-4":
version: 0.5.6-4
resolution: "@logion/authenticator@npm:0.5.6-4"
dependencies:
"@ethersproject/transactions": ^5.7.0
"@logion/node-api": ^0.29.0-2
Expand All @@ -579,7 +579,7 @@ __metadata:
web3-utils: ^4.2.1
peerDependencies:
"@logion/node-api": 0.x
checksum: 3b0e5892303c5910c081b1c3afdbe7f642282ec8ac598dbe909d6eb42739fdcbabd9d7c104efcf5c0b9b8066d8403860fa706a7e3824af2a766456644e31e83c
checksum: 43568b5446ccdfe7b9d0eedc526caa7e2dda64702f83ebe7a326d3c9480d17214b6c06cf3e964dcec98c9c472f7efbb35de6715fb888303c310ff98938217580
languageName: node
linkType: hard

Expand All @@ -602,7 +602,7 @@ __metadata:
resolution: "@logion/rest-api-core@workspace:."
dependencies:
"@istanbuljs/nyc-config-typescript": ^1.0.2
"@logion/authenticator": ^0.5.6-3
"@logion/authenticator": ^0.5.6-4
"@logion/node-api": ^0.29.0-2
"@tsconfig/node16": ^16.1.1
"@types/express": ^4.17.14
Expand Down

0 comments on commit b00cf3e

Please sign in to comment.