Skip to content

Commit

Permalink
Merge pull request #70 from logion-network/feature/submitter-impl
Browse files Browse the repository at this point in the history
fix: implement submitter persistence.
  • Loading branch information
benoitdevos authored Jan 13, 2022
2 parents bfa2403 + 38021af commit 4f445fd
Show file tree
Hide file tree
Showing 11 changed files with 133 additions and 49 deletions.
8 changes: 0 additions & 8 deletions resources/schemas.json
Original file line number Diff line number Diff line change
Expand Up @@ -864,10 +864,6 @@
"nature": {
"type": "string",
"description": "The file's nature"
},
"submitter": {
"type": "string",
"description": "The SS58 address of the file submitter"
}
}
},
Expand Down Expand Up @@ -905,10 +901,6 @@
"value": {
"type": "string",
"description": "The item's value"
},
"submitter": {
"type": "string",
"description": "The SS58 address of the metadata item submitter"
}
}
},
Expand Down
29 changes: 16 additions & 13 deletions src/logion/controllers/locrequest.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,13 +166,13 @@ export class LocRequestController extends ApiController {
hash: file.hash,
nature: file.nature,
addedOn: file.addedOn?.toISOString() || undefined,
submitter: locDescription.ownerAddress // TODO Change me
submitter: file.submitter,
})),
metadata: request.getMetadataItems().map(item => ({
name: item.name,
value: item.value,
addedOn: item.addedOn?.toISOString() || undefined,
submitter: locDescription.ownerAddress // TODO Change me
submitter: item.submitter,
})),
links: request.getLinks().map(link => ({
target: link.target,
Expand Down Expand Up @@ -315,13 +315,13 @@ export class LocRequestController extends ApiController {
hash: file.hash,
nature: file.nature,
addedOn: file.addedOn?.toISOString() || undefined,
submitter: locDescription.ownerAddress // TODO Change me
submitter: file.submitter,
})),
metadata: request.getMetadataItems(false).map(item => ({
name: item.name,
value: item.value,
addedOn: item.addedOn?.toISOString() || undefined,
submitter: locDescription.ownerAddress // TODO Change me
submitter: item.submitter,
})),
links: request.getLinks(false).map(link => ({
target: link.target,
Expand Down Expand Up @@ -390,8 +390,9 @@ export class LocRequestController extends ApiController {
@Async()
async addFile(addFileView: AddFileView, requestId: string): Promise<AddFileResultView> {
const request = requireDefined(await this.locRequestRepository.findById(requestId));
this.authenticationService.authenticatedUser(this.request)
.requireNodeOwner();
const submitter = this.authenticationService.authenticatedUser(this.request)
.require(user => user.isNodeOwner() || user.is(request.requesterAddress), "Only LOC owner or requester can submit a file")
.address

const files: fileUpload.FileArray = this.request.files;
if(files === undefined || files === null) {
Expand All @@ -416,7 +417,8 @@ export class LocRequestController extends ApiController {
contentType: file.mimetype,
hash,
oid,
nature: addFileView.nature || ""
nature: addFileView.nature || "",
submitter,
});
await this.locRequestRepository.save(request);

Expand All @@ -438,7 +440,7 @@ export class LocRequestController extends ApiController {
async downloadFile(_body: any, requestId: string, hash: string): Promise<void> {
const request = requireDefined(await this.locRequestRepository.findById(requestId));
this.authenticationService.authenticatedUser(this.request)
.requireNodeOwner();
.require(user => user.isNodeOwner() || user.is(request.requesterAddress), "Only LOC owner or requester can download a file")

const file = request.getFile(hash);
const tempFilePath = "/tmp/download-" + requestId + "-" + hash;
Expand All @@ -465,7 +467,7 @@ export class LocRequestController extends ApiController {
async deleteFile(_body: any, requestId: string, hash: string): Promise<void> {
const request = requireDefined(await this.locRequestRepository.findById(requestId));
this.authenticationService.authenticatedUser(this.request)
.requireNodeOwner();
.require(user => user.isNodeOwner() || user.is(request.requesterAddress), "Only LOC owner or requester can delete a file")

const file = request.removeFile(hash);
await this.locRequestRepository.save(request);
Expand Down Expand Up @@ -624,11 +626,12 @@ export class LocRequestController extends ApiController {
@SendsResponse()
async addMetadata(addMetadataView: AddMetadataView, requestId: string): Promise<void> {
const request = requireDefined(await this.locRequestRepository.findById(requestId));
this.authenticationService.authenticatedUser(this.request)
.requireNodeOwner();
const submitter = this.authenticationService.authenticatedUser(this.request)
.require(user => user.isNodeOwner() || user.is(request.requesterAddress), "Only LOC owner or requester can submit metadata")
.address
const name = requireLength(addMetadataView, "name", 3, 40)
const value = requireLength(addMetadataView, "value", 1, 4096)
request.addMetadataItem({ name, value })
request.addMetadataItem({ name, value, submitter })
await this.locRequestRepository.save(request)
this.response.sendStatus(204);
}
Expand All @@ -647,7 +650,7 @@ export class LocRequestController extends ApiController {
async deleteMetadata(_body: any, requestId: string, name: string): Promise<void> {
const request = requireDefined(await this.locRequestRepository.findById(requestId));
this.authenticationService.authenticatedUser(this.request)
.requireNodeOwner();
.require(user => user.isNodeOwner() || user.is(request.requesterAddress), "Only LOC owner or requester can delete metadata")

const decodedName = decodeURIComponent(name);
request.removeMetadataItem(decodedName);
Expand Down
27 changes: 27 additions & 0 deletions src/logion/migration/1641978274519-AddItemSubmitter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import {MigrationInterface, QueryRunner} from "typeorm";

export class AddItemSubmitter1641978274519 implements MigrationInterface {
name = 'AddItemSubmitter1641978274519'

public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "public"."loc_request_file" ADD "submitter" character varying(255)`);
await queryRunner.query(`
UPDATE loc_request_file item
SET submitter = (SELECT owner_address FROM loc_request request where item.request_id = request.id)
`);
await queryRunner.query(`ALTER TABLE "public"."loc_request_file" ALTER COLUMN "submitter" SET NOT NULL`);

await queryRunner.query(`ALTER TABLE "public"."loc_metadata_item" ADD "submitter" character varying(255)`);
await queryRunner.query(`
UPDATE loc_metadata_item item
SET submitter = (SELECT owner_address FROM loc_request request where item.request_id = request.id )
`);
await queryRunner.query(`ALTER TABLE "public"."loc_metadata_item" ALTER COLUMN "submitter" SET NOT NULL`);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "public"."loc_metadata_item" DROP COLUMN "submitter"`);
await queryRunner.query(`ALTER TABLE "public"."loc_request_file" DROP COLUMN "submitter"`);
}

}
12 changes: 12 additions & 0 deletions src/logion/model/locrequest.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,14 @@ export interface FileDescription {
readonly contentType: string;
readonly nature: string;
readonly addedOn?: Moment;
readonly submitter: string;
}

export interface MetadataItemDescription {
readonly name: string;
readonly value: string;
readonly addedOn?: Moment;
readonly submitter: string;
}

export interface LinkDescription {
Expand Down Expand Up @@ -128,6 +130,7 @@ export class LocRequestAggregateRoot {
file.contentType = fileDescription.contentType;
file.draft = true;
file.nature = fileDescription.nature;
file.submitter = fileDescription.submitter
file._toAdd = true;
this.files!.push(file);
}
Expand Down Expand Up @@ -167,6 +170,7 @@ export class LocRequestAggregateRoot {
hash: file!.hash!,
oid: file!.oid!,
nature: file!.nature!,
submitter: file!.submitter!,
addedOn: file!.addedOn !== undefined ? moment(file!.addedOn) : undefined,
};
}
Expand Down Expand Up @@ -215,6 +219,7 @@ export class LocRequestAggregateRoot {
item.name = itemDescription.name;
item.value = itemDescription.value;
item.draft = true;
item.submitter = itemDescription.submitter;
item._toAdd = true;
this.metadata!.push(item);
}
Expand All @@ -227,6 +232,7 @@ export class LocRequestAggregateRoot {
return ({
name: item.name!,
value: item.value!,
submitter: item.submitter!,
addedOn: item.addedOn ? moment(item.addedOn) : undefined,
})
}
Expand Down Expand Up @@ -509,6 +515,9 @@ export class LocFile extends Child implements HasIndex {
@Column({ length: 255, nullable: true })
nature?: string;

@Column({ length: 255 })
submitter?: string;

@ManyToOne(() => LocRequestAggregateRoot, request => request.files)
@JoinColumn({ name: "request_id", referencedColumnName: "id" })
request?: LocRequestAggregateRoot;
Expand Down Expand Up @@ -540,6 +549,9 @@ export class LocMetadataItem extends Child implements HasIndex {
@Column("boolean", { default: false })
draft?: boolean;

@Column({ length: 255 })
submitter?: string;

@ManyToOne(() => LocRequestAggregateRoot, request => request.metadata)
@JoinColumn({ name: "request_id" })
request?: LocRequestAggregateRoot;
Expand Down
3 changes: 2 additions & 1 deletion src/logion/services/authentication.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,11 @@ export class LogionUserCheck implements AuthenticatedUser {
&& address === this.address;
}

require(predicate: (check: LogionUserCheck) => boolean, message?: string): void {
require(predicate: (check: LogionUserCheck) => boolean, message?: string): LogionUserCheck {
if(!predicate(this)) {
throw unauthorized(message || "Unauthorized");
}
return this;
}

isOneOf(addresses: (string | undefined | null)[]): boolean {
Expand Down
5 changes: 4 additions & 1 deletion src/logion/services/polkadot.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ export class PolkadotService {
},
MetadataItem: {
name: "Vec<u8>",
value: "Vec<u8>"
value: "Vec<u8>",
submitter: "AccountId",
},
LocType: {
_enum: [
Expand All @@ -77,6 +78,7 @@ export class PolkadotService {
File: {
hash: "Hash",
nature: "Vec<u8>",
submitter: "AccountId",
},
LocVoidInfo: {
"replacer": "Option<LocId>"
Expand All @@ -86,6 +88,7 @@ export class PolkadotService {
"V1",
"V2MakeLocVoid",
"V3RequesterEnum",
"V4ItemSubmitter",
]
},
Requester: {
Expand Down
20 changes: 15 additions & 5 deletions test/helpers/testapp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export function setupApp<T>(
mockBinder: (container: Container) => void,
authSucceed: boolean = true,
isNodeOwner: boolean = true,
conditionFulfilled: boolean = true
): Express {

const app = express();
Expand All @@ -36,7 +37,7 @@ export function setupApp<T>(
let container = new Container({ defaultScope: "Singleton" });

container.bind(AuthenticationService)
.toConstantValue(authSucceed ? mockAuthenticationSuccess(isNodeOwner) : mockAuthenticationFailure());
.toConstantValue(authSucceed ? mockAuthenticationSuccess(isNodeOwner, conditionFulfilled) : mockAuthenticationFailure());

mockBinder(container);

Expand All @@ -50,13 +51,22 @@ export function setupApp<T>(
return app;
}

function mockAuthenticationSuccess(isNodeOwner: boolean): AuthenticationService {
function mockAuthenticationSuccess(isNodeOwner: boolean, conditionFulfilled: boolean): AuthenticationService {

const authenticatedUser = new Mock<LogionUserCheck>();
authenticatedUser.setup(instance => instance.legalOfficer).returns(true);
authenticatedUser.setup(instance => instance.is).returns(() => true);
authenticatedUser.setup(instance => instance.require).returns(() => {});
authenticatedUser.setup(instance => instance.requireIs).returns(() => {});
authenticatedUser.setup(instance => instance.is).returns(() => conditionFulfilled);
authenticatedUser.setup(instance => instance.require).returns(() => {
if (!conditionFulfilled) {
throw new UnauthorizedException("")
}
return authenticatedUser.object()
});
authenticatedUser.setup(instance => instance.requireIs).returns(() => {
if (!conditionFulfilled) {
throw new UnauthorizedException("")
}
});
authenticatedUser.setup(instance => instance.requireLegalOfficer).returns(() => {});
authenticatedUser.setup(instance => instance.requireNodeOwner).returns(() => {
if (!isNodeOwner) {
Expand Down
8 changes: 4 additions & 4 deletions test/integration/model/loc_requests.sql
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ VALUES (md5(random()::text || clock_timestamp()::text)::uuid, '5FHneW46xGXgs5mUi
-- Loc with files, metadata and links
INSERT INTO loc_request (id, owner_address, requester_address, description, status, loc_type)
VALUES ('2b287596-f9d5-8030-b606-d1da538cb37f', '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY', '5CXLTF2PFBE89tTYsrofGPkSfGTdmW4ciw4vAfgcKhjggRgZ', 'loc-10', 'OPEN', 'Transaction');
INSERT INTO loc_request_file (request_id, hash, name, oid, content_type, added_on, "index", draft, nature)
VALUES ('2b287596-f9d5-8030-b606-d1da538cb37f', '0x1307990e6ba5ca145eb35e99182a9bec46531bc54ddf656a602c780fa0240dee', 'a file', 123456, 'text/plain', '2021-10-06T11:16:00.000', 0, TRUE, 'some nature');
INSERT INTO loc_metadata_item (request_id, "index", name, "value_text", added_on, draft)
VALUES ('2b287596-f9d5-8030-b606-d1da538cb37f', 0, 'a name', 'a value', '2021-10-06T11:16:00.000', true);
INSERT INTO loc_request_file (request_id, hash, name, oid, content_type, added_on, "index", draft, nature, submitter)
VALUES ('2b287596-f9d5-8030-b606-d1da538cb37f', '0x1307990e6ba5ca145eb35e99182a9bec46531bc54ddf656a602c780fa0240dee', 'a file', 123456, 'text/plain', '2021-10-06T11:16:00.000', 0, TRUE, 'some nature', '5DDGQertEH5qvKVXUmpT3KNGViCX582Qa2WWb8nGbkmkRHvw');
INSERT INTO loc_metadata_item (request_id, "index", name, "value_text", added_on, draft, submitter)
VALUES ('2b287596-f9d5-8030-b606-d1da538cb37f', 0, 'a name', 'a value', '2021-10-06T11:16:00.000', true, '5DDGQertEH5qvKVXUmpT3KNGViCX582Qa2WWb8nGbkmkRHvw');
INSERT INTO loc_link (request_id, "index", target, added_on, draft, nature)
VALUES ('2b287596-f9d5-8030-b606-d1da538cb37f', 0, 'ec126c6c-64cf-4eb8-bfa6-2a98cd19ad5d', '2021-10-06T11:16:00.000', true, 'link-nature');
-- Open Polkadot Identity locs
Expand Down
6 changes: 5 additions & 1 deletion test/integration/model/locrequest.model.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import {
import { ALICE, BOB } from "../../helpers/addresses";
import { v4 as uuid } from "uuid";

const SUBMITTER = "5DDGQertEH5qvKVXUmpT3KNGViCX582Qa2WWb8nGbkmkRHvw";

describe('LocRequestRepository - read accesses', () => {

beforeAll(async () => {
Expand Down Expand Up @@ -169,12 +171,14 @@ function givenOpenLoc(id: string): LocRequestAggregateRoot {
oid: 123,
contentType: "content/type",
nature: "nature1",
submitter: SUBMITTER,
})
locRequest.metadata = []
locRequest.addMetadataItem({
name: "itemName",
addedOn: moment(),
value: "something valuable"
value: "something valuable",
submitter: SUBMITTER,
})
return locRequest;
}
Expand Down
Loading

0 comments on commit 4f445fd

Please sign in to comment.