diff --git a/src/services/dataset/handler.ts b/src/services/dataset/handler.ts index 9bfaa7abb6797111252c6783871b40645017fa85..beb29e501df5ca255f4f96b39fb22003cf0a311f 100644 --- a/src/services/dataset/handler.ts +++ b/src/services/dataset/handler.ts @@ -109,11 +109,11 @@ export class DatasetHandler { const journalClient = JournalFactoryTenantClient.get(tenant); try { + const subprojectMetadata = await SubProjectDAO.get(journalClient, tenant.name, subproject.name); if (dataset.acls) { - const subprojectMetadata = await SubProjectDAO.get(journalClient, tenant.name, subproject.name); - const subprojectAccessPolicy = subprojectMetadata.access_policy; + const subprojectAccessPolicy = subprojectMetadata.access_policy; if (subprojectAccessPolicy === Config.UNIFORM_ACCESS_POLICY) { throw Error.make(Error.Status.BAD_REQUEST, 'Subproject access policy is set to uniform and so acls cannot be applied. Patch the subproject access policy to dataset and attempt this operation again.'); @@ -151,7 +151,7 @@ export class DatasetHandler { await Promise.all([ FeatureFlags.isEnabled(Feature.AUTHORIZATION) ? Auth.isWriteAuthorized(req.headers.authorization, - subproject.acls.admins, + subprojectMetadata.acls.admins, dataset.tenant, dataset.subproject, tenant.esd, req[Config.DE_FORWARD_APPKEY]) : undefined, FeatureFlags.isEnabled(Feature.LEGALTAG) ? dataset.ltag ? Auth.isLegalTagValid( @@ -277,15 +277,16 @@ export class DatasetHandler { tenant.esd, req[Config.DE_FORWARD_APPKEY]); } + const subprojectMetadata = await SubProjectDAO.get(journalClient, tenant.name, subproject.name); // Use the access policy to determine which groups to fetch for read authorization if (FeatureFlags.isEnabled(Feature.AUTHORIZATION)) { let authGroups = []; - if (subproject.access_policy === Config.UNIFORM_ACCESS_POLICY) { - authGroups = subproject.acls.viewers.concat(subproject.acls.admins); - } else if (subproject.access_policy === Config.DATASET_ACCESS_POLICY) { + if (subprojectMetadata.access_policy === Config.UNIFORM_ACCESS_POLICY) { + authGroups = subprojectMetadata.acls.viewers.concat(subprojectMetadata.acls.admins); + } else if (subprojectMetadata.access_policy === Config.DATASET_ACCESS_POLICY) { authGroups = datasetOUT.acls ? datasetOUT.acls.viewers.concat(datasetOUT.acls.admins) - : subproject.acls.viewers.concat(subproject.acls.admins); + : subprojectMetadata.acls.viewers.concat(subprojectMetadata.acls.admins); } else { throw (Error.make(Error.Status.PERMISSION_DENIED, 'Access policy for the subproject is neither uniform nor dataset' )); @@ -323,8 +324,9 @@ export class DatasetHandler { if (FeatureFlags.isEnabled(Feature.AUTHORIZATION)) { // Check authorizations + const subprojectMetadata = await SubProjectDAO.get(journalClient, tenant.name, subproject.name); await Auth.isReadAuthorized(req.headers.authorization, - subproject.acls.viewers.concat(subproject.acls.admins), + subprojectMetadata.acls.viewers.concat(subprojectMetadata.acls.admins), dataset.tenant, dataset.subproject, tenant.esd, req[Config.DE_FORWARD_APPKEY]); } @@ -362,6 +364,8 @@ export class DatasetHandler { // init datastore client const journalClient = JournalFactoryTenantClient.get(tenant); + const subprojectMetadata = await SubProjectDAO.get(journalClient, tenant.name, subproject.name); + // Retrieve the dataset metadata const dataset = subproject.enforce_key ? await DatasetDAO.getByKey(journalClient, datasetIn) : @@ -373,12 +377,12 @@ export class DatasetHandler { // check authorization (write) if (FeatureFlags.isEnabled(Feature.AUTHORIZATION)) { let authGroups = []; - const accessPolicy = subproject.access_policy; + const accessPolicy = subprojectMetadata.access_policy; if (accessPolicy === Config.UNIFORM_ACCESS_POLICY) { - authGroups = subproject.acls.admins; + authGroups = subprojectMetadata.acls.admins; } else if (accessPolicy === Config.DATASET_ACCESS_POLICY) { - authGroups = dataset.acls ? dataset.acls.admins : subproject.acls.admins; + authGroups = dataset.acls ? dataset.acls.admins : subprojectMetadata.acls.admins; } else { throw (Error.make(Error.Status.PERMISSION_DENIED, 'Access policy for the subproject is neither uniform nor dataset' )); @@ -431,19 +435,20 @@ export class DatasetHandler { // retrieve datastore client const journalClient = JournalFactoryTenantClient.get(tenant); + const subprojectMetadata = await SubProjectDAO.get(journalClient, tenant.name, subproject.name); // return immediately if it is a simple close with empty body (no patch to apply) if (Object.keys(req.body).length === 0 && req.body.constructor === Object && wid) { // Check authorizations if (FeatureFlags.isEnabled(Feature.AUTHORIZATION)) { - if(wid.startsWith('W')) { + if (wid.startsWith('W')) { await Auth.isWriteAuthorized(req.headers.authorization, - subproject.acls.admins, + subprojectMetadata.acls.admins, datasetIN.tenant, subproject.name, tenant.esd, req[Config.DE_FORWARD_APPKEY]); } else { await Auth.isReadAuthorized(req.headers.authorization, - subproject.acls.viewers.concat(subproject.acls.admins), + subprojectMetadata.acls.viewers.concat(subprojectMetadata.acls.admins), datasetIN.tenant, datasetIN.subproject, tenant.esd, req[Config.DE_FORWARD_APPKEY]); } } @@ -470,7 +475,6 @@ export class DatasetHandler { // Ensure subproject access policy is not set to uniform if (datasetIN.acls) { - const subprojectMetadata = await SubProjectDAO.get(journalClient, tenant.name, subproject.name); const subprojectAccessPolicy = subprojectMetadata.access_policy; if (subprojectAccessPolicy === Config.UNIFORM_ACCESS_POLICY) { @@ -518,12 +522,12 @@ export class DatasetHandler { // If the input request has dataset acls then the subproject access policy is always dataset if (FeatureFlags.isEnabled(Feature.AUTHORIZATION)) { let authGroups = []; - const accessPolicy = subproject.access_policy; + const accessPolicy = subprojectMetadata.access_policy; if (accessPolicy === Config.UNIFORM_ACCESS_POLICY) { - authGroups = subproject.acls.admins; + authGroups = subprojectMetadata.acls.admins; } else if (accessPolicy === Config.DATASET_ACCESS_POLICY) { - authGroups = datasetOUT.acls ? datasetOUT.acls.admins : subproject.acls.admins; + authGroups = datasetOUT.acls ? datasetOUT.acls.admins : subprojectMetadata.acls.admins; } else { throw (Error.make(Error.Status.PERMISSION_DENIED, 'Access policy is neither uniform nor dataset.' )); @@ -744,14 +748,15 @@ export class DatasetHandler { // Use the access policy to determine which groups to fetch for read authorization if (FeatureFlags.isEnabled(Feature.AUTHORIZATION)) { + const subprojectMetadata = await SubProjectDAO.get(journalClient, tenant.name, subproject.name); let authGroups = []; - const accessPolicy = subproject.access_policy; + const accessPolicy = subprojectMetadata.access_policy; if (open4write) { if (accessPolicy === Config.UNIFORM_ACCESS_POLICY) { - authGroups = subproject.acls.admins; + authGroups = subprojectMetadata.acls.admins; } else if (accessPolicy === Config.DATASET_ACCESS_POLICY) { - authGroups = datasetOUT.acls ? datasetOUT.acls.admins : subproject.acls.admins; + authGroups = datasetOUT.acls ? datasetOUT.acls.admins : subprojectMetadata.acls.admins; } else { throw (Error.make(Error.Status.PERMISSION_DENIED, 'Access policy is neither uniform nor dataset' )); @@ -764,10 +769,10 @@ export class DatasetHandler { } else { if (accessPolicy === Config.UNIFORM_ACCESS_POLICY) { - authGroups = subproject.acls.viewers.concat(subproject.acls.admins); + authGroups = subprojectMetadata.acls.viewers.concat(subprojectMetadata.acls.admins); } else if (accessPolicy === Config.DATASET_ACCESS_POLICY) { authGroups = datasetOUT.acls ? datasetOUT.acls.viewers.concat(datasetOUT.acls.admins) - : subproject.acls.viewers.concat(subproject.acls.admins); + : subprojectMetadata.acls.viewers.concat(subprojectMetadata.acls.admins); } else { throw (Error.make(Error.Status.PERMISSION_DENIED, 'Access policy is neither uniform nor dataset' )); @@ -833,14 +838,16 @@ export class DatasetHandler { datasetIN.subproject + datasetIN.path + datasetIN.name + ' does not exist')); } + const subprojectMetadata = await SubProjectDAO.get(journalClient, tenant.name, subproject.name); + // check if user is write authorized let authGroups = []; - const accessPolicy = subproject.access_policy; + const accessPolicy = subprojectMetadata.access_policy; if (accessPolicy === Config.UNIFORM_ACCESS_POLICY) { - authGroups = subproject.acls.admins; + authGroups = subprojectMetadata.acls.admins; } else if (accessPolicy === Config.DATASET_ACCESS_POLICY) { - authGroups = dataset.acls ? dataset.acls.admins : subproject.acls.admins; + authGroups = dataset.acls ? dataset.acls.admins : subprojectMetadata.acls.admins; } else { throw (Error.make(Error.Status.PERMISSION_DENIED, 'Access policy is neither uniform nor dataset' )); @@ -866,9 +873,9 @@ export class DatasetHandler { const journalClient = JournalFactoryTenantClient.get(tenant); if (FeatureFlags.isEnabled(Feature.AUTHORIZATION)) { - + const subprojectMetadata = await SubProjectDAO.get(journalClient, tenant.name, subproject.name); await Auth.isReadAuthorized(req.headers.authorization, - subproject.acls.viewers.concat(subproject.acls.admins), + subprojectMetadata.acls.viewers.concat(subprojectMetadata.acls.admins), datasets[0].tenant, datasets[0].subproject, tenant.esd, req[Config.DE_FORWARD_APPKEY]); } @@ -896,8 +903,9 @@ export class DatasetHandler { const journalClient = JournalFactoryTenantClient.get(tenant); if (FeatureFlags.isEnabled(Feature.AUTHORIZATION)) { + const subprojectMetadata = await SubProjectDAO.get(journalClient, tenant.name, subproject.name); await Auth.isReadAuthorized(req.headers.authorization, - subproject.acls.viewers.concat(subproject.acls.admins), + subprojectMetadata.acls.viewers.concat(subprojectMetadata.acls.admins), datasets[0].tenant, datasets[0].subproject, tenant.esd, req[Config.DE_FORWARD_APPKEY]); } @@ -937,9 +945,10 @@ export class DatasetHandler { const journalClient = JournalFactoryTenantClient.get(tenant); if (FeatureFlags.isEnabled(Feature.AUTHORIZATION)) { + const subprojectMetadata = await SubProjectDAO.get(journalClient, tenant.name, subproject.name); // Check authorizations await Auth.isReadAuthorized(req.headers.authorization, - subproject.acls.viewers.concat(subproject.acls.admins), + subprojectMetadata.acls.viewers.concat(subprojectMetadata.acls.admins), dataset.tenant, dataset.subproject, tenant.esd, req[Config.DE_FORWARD_APPKEY]); } @@ -1008,12 +1017,13 @@ export class DatasetHandler { if (FeatureFlags.isEnabled(Feature.AUTHORIZATION)) { let authGroups = []; - const accessPolicy = subproject.access_policy; + const subprojectMetadata = await SubProjectDAO.get(journalClient, tenant.name, subproject.name); + const accessPolicy = subprojectMetadata.access_policy; if (accessPolicy === Config.UNIFORM_ACCESS_POLICY) { - authGroups = subproject.acls.admins; + authGroups = subprojectMetadata.acls.admins; } else if (accessPolicy === Config.DATASET_ACCESS_POLICY) { - authGroups = datasetOUT.acls ? datasetOUT.acls.admins : subproject.acls.admins; + authGroups = datasetOUT.acls ? datasetOUT.acls.admins : subprojectMetadata.acls.admins; } else { throw (Error.make(Error.Status.PERMISSION_DENIED, 'Access policy is neither uniform nor dataset' )); @@ -1051,12 +1061,13 @@ export class DatasetHandler { if (FeatureFlags.isEnabled(Feature.AUTHORIZATION)) { let authGroups = []; - const accessPolicy = subproject.access_policy; + const subprojectMetadata = await SubProjectDAO.get(journalClient, tenant.name, subproject.name); + const accessPolicy = subprojectMetadata.access_policy; if (accessPolicy === Config.UNIFORM_ACCESS_POLICY) { - authGroups = subproject.acls.admins; + authGroups = subprojectMetadata.acls.admins; } else if (accessPolicy === Config.DATASET_ACCESS_POLICY) { - authGroups = dataset.acls ? dataset.acls.admins : subproject.acls.admins; + authGroups = dataset.acls ? dataset.acls.admins : subprojectMetadata.acls.admins; } else { throw (Error.make(Error.Status.PERMISSION_DENIED, 'Access policy is neither uniform nor dataset' )); @@ -1069,10 +1080,10 @@ export class DatasetHandler { // Check write authorization if (accessPolicy === Config.UNIFORM_ACCESS_POLICY) { - authGroups = subproject.acls.viewers.concat(subproject.acls.admins); + authGroups = subprojectMetadata.acls.viewers.concat(subprojectMetadata.acls.admins); } else if (accessPolicy === Config.DATASET_ACCESS_POLICY) { authGroups = dataset.acls ? dataset.acls.viewers.concat(dataset.acls.admins) - : subproject.acls.viewers.concat(subproject.acls.admins); + : subprojectMetadata.acls.viewers.concat(subprojectMetadata.acls.admins); } else { throw (Error.make(Error.Status.PERMISSION_DENIED, 'Access policy is neither uniform nor dataset' )); diff --git a/src/services/subproject/dao.ts b/src/services/subproject/dao.ts index cb4783e503da2bd26f196865229e4a14f779a2ca..08dd1f965456fef3f41016841d80ab698b045d2b 100644 --- a/src/services/subproject/dao.ts +++ b/src/services/subproject/dao.ts @@ -68,6 +68,10 @@ export class SubProjectDAO { entity.acls = await this.constructServiceGroupACLs(entity); } + if (!entity.access_policy) { + entity.access_policy = Config.UNIFORM_ACCESS_POLICY; + } + await this._cache.set(this.getCacheKey(entity.tenant, entity.name), entity); return entity;