Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PIN-5849 - restrict agreements visibility only to allowed tenants #1526

Open
wants to merge 14 commits into
base: develop
Choose a base branch
from
Open
2 changes: 1 addition & 1 deletion collections/agreement/Compute Agreeements State.bru
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ meta {
}

post {
url: {{host-agreement}}/compute/agreementsState
url: {{host-agreement}}/internal/compute/agreementsState
body: json
auth: none
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,13 +181,15 @@ export const assertRequesterCanActAsConsumerOrProducer = (
}
};

export const assertRequesterCanRetrieveConsumerDocuments = async (
export const assertRequesterCanRetrieveAgreement = async (
agreement: Agreement,
authData: AuthData,
readModelService: ReadModelService
): Promise<void> => {
// This operation has a dedicated assertion because it's the only operation that
// can be performed also by the producer/consumer even when active producer/consumer delegations exist
// This validator is for retrieval operations that can be performed by all the tenants involved:
// the consumer, the producer, the consumer delegate, and the producer delegate.
// Consumers and producers can retrieve agreements even if delegations exist.

try {
assertRequesterIsConsumer(agreement.consumerId, authData);
} catch {
Expand Down
26 changes: 11 additions & 15 deletions packages/agreement-process/src/routers/AgreementRouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ const agreementRouter = (
},
req.query.limit,
req.query.offset,
ctx.logger
ctx
);

return res.status(200).send(
Expand Down Expand Up @@ -411,11 +411,11 @@ const agreementRouter = (
const ctx = fromAppContext(req.ctx);

try {
const producers = await agreementService.getAgreementProducers(
const producers = await agreementService.getAgreementsProducers(
req.query.producerName,
req.query.limit,
req.query.offset,
ctx.logger
ctx
);

return res.status(200).send(
Expand Down Expand Up @@ -448,11 +448,11 @@ const agreementRouter = (
const ctx = fromAppContext(req.ctx);

try {
const consumers = await agreementService.getAgreementConsumers(
const consumers = await agreementService.getAgreementsConsumers(
req.query.consumerName,
req.query.limit,
req.query.offset,
ctx.logger
ctx
);

return res.status(200).send(
Expand Down Expand Up @@ -480,7 +480,6 @@ const agreementRouter = (
API_ROLE,
SECURITY_ROLE,
M2M_ROLE,
INTERNAL_ROLE,
SUPPORT_ROLE,
]),
async (req, res) => {
Expand All @@ -489,7 +488,7 @@ const agreementRouter = (
try {
const agreement = await agreementService.getAgreementById(
unsafeBrandId(req.params.agreementId),
ctx.logger
ctx
);
return res
.status(200)
Expand Down Expand Up @@ -673,13 +672,13 @@ const agreementRouter = (
);

agreementRouter.post(
"/compute/agreementsState",
authorizationMiddleware([ADMIN_ROLE, INTERNAL_ROLE, M2M_ROLE]),
"/internal/compute/agreementsState",
authorizationMiddleware([INTERNAL_ROLE]),
async (req, res) => {
const ctx = fromAppContext(req.ctx);

try {
await agreementService.computeAgreementsStateByAttribute(
await agreementService.internalComputeAgreementsStateByAttribute(
unsafeBrandId(req.body.attributeId),
fromApiCompactTenant(req.body.consumer),
ctx
Expand Down Expand Up @@ -710,18 +709,15 @@ const agreementRouter = (
const ctx = fromAppContext(req.ctx);

try {
const eservices = await agreementService.getAgreementEServices(
const eservices = await agreementService.getAgreementsEServices(
{
eserviceName: req.query.eServiceName,
consumerIds: req.query.consumersIds.map(unsafeBrandId<TenantId>),
producerIds: req.query.producersIds.map(unsafeBrandId<TenantId>),
agreeementStates: req.query.states.map(
apiAgreementStateToAgreementState
),
},
req.query.limit,
req.query.offset,
ctx.logger
ctx
);

return res.status(200).send(
Expand Down
66 changes: 50 additions & 16 deletions packages/agreement-process/src/services/agreementService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ import {
assertActivableState,
assertRequesterCanActAsProducer,
assertRequesterCanActAsConsumerOrProducer,
assertRequesterCanRetrieveConsumerDocuments,
assertRequesterCanRetrieveAgreement,
assertCanWorkOnConsumerDocuments,
assertExpectedState,
assertRequesterIsDelegateConsumer,
Expand Down Expand Up @@ -232,18 +232,34 @@ export function agreementServiceBuilder(
filters: AgreementQueryFilters,
limit: number,
offset: number,
logger: Logger
{ authData, logger }: WithLogger<AppContext>
): Promise<ListResult<Agreement>> {
logger.info("Retrieving agreements");
return await readModelService.getAgreements(filters, limit, offset);
logger.info(
`Getting agreements with filters: ${JSON.stringify(
filters
)}, offset = ${offset}, limit = ${limit}`
);

// Permissions are checked in the readModelService
return await readModelService.getAgreements(
authData.organizationId,
filters,
limit,
offset
);
},
async getAgreementById(
agreementId: AgreementId,
logger: Logger
{ authData, logger }: WithLogger<AppContext>
): Promise<Agreement> {
logger.info(`Retrieving agreement by id ${agreementId}`);

const agreement = await retrieveAgreement(agreementId, readModelService);
await assertRequesterCanRetrieveAgreement(
agreement.data,
authData,
readModelService
);
return agreement.data;
},
async createAgreement(
Expand Down Expand Up @@ -306,27 +322,41 @@ export function agreementServiceBuilder(

return agreement;
},
async getAgreementProducers(
async getAgreementsProducers(
producerName: string | undefined,
limit: number,
offset: number,
logger: Logger
{ authData, logger }: WithLogger<AppContext>
): Promise<ListResult<CompactOrganization>> {
logger.info(
`Retrieving producers from agreements with producer name ${producerName}`
);
return await readModelService.getProducers(producerName, limit, offset);

// Permissions are checked in the readModelService
return await readModelService.getAgreementsProducers(
authData.organizationId,
producerName,
limit,
offset
);
},
async getAgreementConsumers(
async getAgreementsConsumers(
consumerName: string | undefined,
limit: number,
offset: number,
logger: Logger
{ authData, logger }: WithLogger<AppContext>
): Promise<ListResult<CompactOrganization>> {
logger.info(
`Retrieving consumers from agreements with consumer name ${consumerName}`
);
return await readModelService.getConsumers(consumerName, limit, offset);

// Permissions are checked in the readModelService
return await readModelService.getAgreementsConsumers(
authData.organizationId,
consumerName,
limit,
offset
);
},
async updateAgreement(
agreementId: AgreementId,
Expand Down Expand Up @@ -876,7 +906,7 @@ export function agreementServiceBuilder(

const agreement = await retrieveAgreement(agreementId, readModelService);

await assertRequesterCanRetrieveConsumerDocuments(
await assertRequesterCanRetrieveAgreement(
agreement.data,
authData,
readModelService
Expand Down Expand Up @@ -943,17 +973,21 @@ export function agreementServiceBuilder(

return updatedAgreement;
},
async getAgreementEServices(
async getAgreementsEServices(
filters: AgreementEServicesQueryFilters,
limit: number,
offset: number,
logger: Logger
{ authData, logger }: WithLogger<AppContext>
): Promise<ListResult<CompactEService>> {
logger.info(
`Retrieving EServices with consumers ${filters.consumerIds}, producers ${filters.producerIds}, states ${filters.agreeementStates}, offset ${offset}, limit ${limit} and name matching ${filters.eserviceName}`
`Retrieving EServices from agreements with filters: ${JSON.stringify(
filters
)}, offset ${offset}, limit ${limit}`
);

// Permissions are checked in the readModelService
return await readModelService.getAgreementsEServices(
authData.organizationId,
filters,
limit,
offset
Expand Down Expand Up @@ -1332,7 +1366,7 @@ export function agreementServiceBuilder(
)
);
},
async computeAgreementsStateByAttribute(
async internalComputeAgreementsStateByAttribute(
attributeId: AttributeId,
consumer: CompactTenant,
{ logger, correlationId }: WithLogger<AppContext>
Expand Down
Loading