UNPKG

@sap/cds

Version:

SAP Cloud Application Programming Model - CDS for Node.js

85 lines (75 loc) 3.12 kB
const cds = require('../../../cds') const serviceHandler = require('./service') const requiresHandler = require('./requires') const readOnlyHandler = require('./readOnly') const insertOnlyHandler = require('./insertOnly') const capabilitiesHandler = require('./capabilities') const autoexposeHandler = require('./autoexpose') const restrictHandler = require('./restrict') const restrictExpandHandler = require('./expand') module.exports = function () { // REVISIT: general approach to dependent auth: // add restrictions to auth-dependent entities as if modeled to allow static access during request processing // // TODO: where to do? // // add restrictions to auth-dependent entities // const defs = this.model.definitions // const deps = [] // for (const each of this.entities) { // for (const k in each.compositions) { // const c = each.compositions[k] // const ct = defs[c.target] // if (defs[ct?.elements.up_?.target] === each && !ct['@requires'] && !ct['@restrict']) { // deps.push(c.target) // } // } // } // for (const each of deps) { // const e = defs[each] // let rstr // let cur = defs[e.elements.up_.target] // while (cur && !rstr) { // rstr = cur['@requires'] || cur['@restrict'] // cur = defs[cur.elements.up_?.target] // } // if (rstr) { // // TODO: normalize restriction to @restrict syntax // // TODO: add rewrite paths in instance-based auth // e['@restrict'] = rstr // } // } // mark entities that depend on ancestor for auth with that ancestor const defs = this.model?.definitions for (const each of this.entities) { for (const k in each.compositions) { const c = each.compositions[k] const ct = defs[c.target] if (defs[ct?.elements.up_?.target] === each && !ct['@requires'] && !ct['@restrict']) { let rstr let cur = defs[ct.elements.up_.target] while (!rstr && cur) { if (cur['@requires'] || cur['@restrict']) rstr = cur cur = defs[cur.elements.up_?.target] } if (rstr) Object.defineProperty(ct, '_auth_depends_on', { value: rstr }) } } } // service-level restrictions (not all requests are dispatched by protocol adapter with its early access check) // REVISIT cds^11: remove opt-out const roles = cds.env.features.service_level_restrictions !== false && this.definition && serviceHandler.roles4(this) return async function handle_authorization(req) { // check service-level restrictions on local calls //> REVISIT: does that mean we check the same twice below? if (roles) serviceHandler.check(roles, req, this.definition) // @requires requiresHandler.call(this, req) // access control (cheaper than @restrict -> do first) readOnlyHandler.call(this, req) insertOnlyHandler.call(this, req) capabilitiesHandler.call(this, req) autoexposeHandler.call(this, req) // @restrict await restrictHandler.call(this, req) // expand restrictions if (req.event === 'READ') restrictExpandHandler.call(this, req) } }