From e08b1c624665160bc530c0600293c2d715cfe41e Mon Sep 17 00:00:00 2001 From: "Dzmitry_Tamashevich@epam.com" Date: Thu, 5 Nov 2020 23:25:17 +0300 Subject: [PATCH] refactoring code --- media-store/server.js | 2 +- media-store/srv/browse-invoices-service.cds | 12 +++-- media-store/srv/browse-tracks-service.cds | 10 ++-- media-store/srv/manage-store-service.cds | 8 +-- media-store/srv/manage-store-service.js | 22 ++------ media-store/srv/user-service.cds | 56 ++++++++++----------- media-store/srv/user-service.js | 32 ++---------- media-store/util/importData.js | 4 +- 8 files changed, 56 insertions(+), 90 deletions(-) diff --git a/media-store/server.js b/media-store/server.js index 88235cba..3148ec82 100644 --- a/media-store/server.js +++ b/media-store/server.js @@ -7,7 +7,7 @@ cds.on("bootstrap", (app) => { res.header("Access-Control-Allow-Origin", "*"); res.header( "Access-Control-Allow-Methods", - "GET, PUT, POST, DELETE, OPTIONS" + "GET, PUT, PATCH, POST, DELETE, OPTIONS" ); res.header( "Access-Control-Allow-Headers", diff --git a/media-store/srv/browse-invoices-service.cds b/media-store/srv/browse-invoices-service.cds index 56bf1f94..8305d806 100644 --- a/media-store/srv/browse-invoices-service.cds +++ b/media-store/srv/browse-invoices-service.cds @@ -3,6 +3,10 @@ using {BrowseTracks.Tracks} from './browse-tracks-service'; service BrowseInvoices @(requires : 'customer') { + /** + * Invoices entity also restricted programmatically Only owned + * invoices youser can access + */ @readonly entity Invoices as projection on my.Invoices; @@ -13,10 +17,10 @@ service BrowseInvoices @(requires : 'customer') { action cancelInvoice(ID : Integer); - /* - Below entities exposed - due to 'navigation property errors' when expanding with odata - */ + /** + * Below entities exposed due to 'navigation property errors' + * when expanding with odata + */ @readonly entity Tracks as projection on my.Tracks excluding { alreadyOrdered diff --git a/media-store/srv/browse-tracks-service.cds b/media-store/srv/browse-tracks-service.cds index 868338cb..3663b445 100644 --- a/media-store/srv/browse-tracks-service.cds +++ b/media-store/srv/browse-tracks-service.cds @@ -8,14 +8,14 @@ service BrowseTracks { @readonly entity MarkedTracks @(restrict : [{ - grant : ['*', ], + grant : ['*'], to : 'customer' }]) as projection on my.Tracks; - /* - Below entities exposed - due to 'navigation property errors' when expanding with odata - */ + /** + * Below entities exposed due to 'navigation property errors' + * when expanding with odata + */ @readonly entity Genres as projection on my.Genres { * , tracks : redirected to Tracks diff --git a/media-store/srv/manage-store-service.cds b/media-store/srv/manage-store-service.cds index 7528693f..cff55c18 100644 --- a/media-store/srv/manage-store-service.cds +++ b/media-store/srv/manage-store-service.cds @@ -4,10 +4,10 @@ service ManageStore @(requires : 'employee') { entity Tracks as projection on my.Tracks; entity Albums as projection on my.Albums; entity Artists as projection on my.Artists; - /* - Below entities exposed - due to errors when creating Tracks/Albums/Artists - */ + /** + * Below entities exposed due to errors when creating + * Tracks/Albums/Artists + */ entity MediaTypes as projection on my.MediaTypes; entity Genres as projection on my.Genres; } diff --git a/media-store/srv/manage-store-service.js b/media-store/srv/manage-store-service.js index d6675f93..e2b4a89b 100644 --- a/media-store/srv/manage-store-service.js +++ b/media-store/srv/manage-store-service.js @@ -3,24 +3,10 @@ const cds = require("@sap/cds"); module.exports = async function () { const db = await cds.connect.to("db"); // connect to database service - const { Albums, Tracks, Artists } = db.entities; - - this.before("CREATE", "Tracks", async (req) => { - let { ID: lastTrackId } = await db.run( - SELECT.one(Tracks).columns("ID").orderBy({ ID: "desc" }) + this.before("CREATE", "*", async (req) => { + let { ID: lastEntityID } = await db.run( + SELECT.one(req.entity).columns("ID").orderBy({ ID: "desc" }) ); - req.data = { ...req.data, ID: ++lastTrackId }; - }); - this.before("CREATE", "Artists", async (req) => { - let { ID: lastArtistId } = await db.run( - SELECT.one(Artists).columns("ID").orderBy({ ID: "desc" }) - ); - req.data = { ...req.data, ID: ++lastArtistId }; - }); - this.before("CREATE", "Albums", async (req) => { - let { ID: lastAlbumId } = await db.run( - SELECT.one(Albums).columns("ID").orderBy({ ID: "desc" }) - ); - req.data = { ...req.data, ID: ++lastAlbumId }; + req.data = { ...req.data, ID: ++lastEntityID }; }); }; diff --git a/media-store/srv/user-service.cds b/media-store/srv/user-service.cds index 9f6f41c3..f30b3148 100644 --- a/media-store/srv/user-service.cds +++ b/media-store/srv/user-service.cds @@ -1,35 +1,19 @@ using {sap.capire.media.store as my} from '../db/schema'; service Users { - // redundant entity - // We need actions without exposing entity for now. - // But we forced to expose for make actions work. - entity Customers @(restrict : [{ - grant : [ - 'READ', - 'WRITE' - ], - to : 'employee' - }, ]) as projection on my.Customers; + /** + * Below entities also restricted programmatically. Only User + * can only access to yours record + */ + entity Customers as projection on my.Customers excluding { + password, + supportRep + }; - type Person { - lastName : String(20); - firstName : String(40); - city : String(40); - state : String(40); - address : String(70); - country : String(40); - postalCode : String(10); - phone : String(24); - fax : String(24); - email : String(60); - } - - @(requires : 'authenticated-user') - action updatePerson(person : Person); - - @(requires : 'authenticated-user') - function getPerson() returns Person; + entity Employees as projection on my.Customers excluding { + password, + supportRep + }; action login(email : String(111), password : String(200)) returns { roles : array of String(111); @@ -38,3 +22,19 @@ service Users { ID : Integer; }; } + +annotate Users.Customers with @(restrict : [{ + grant : [ + 'READ', + 'UPDATE' + ], + to : 'customer' +}]); + +annotate Users.Employees with @(restrict : [{ + grant : [ + 'READ', + 'UPDATE' + ], + to : 'employee' +}]); diff --git a/media-store/srv/user-service.js b/media-store/srv/user-service.js index 9993b305..3634e3b6 100644 --- a/media-store/srv/user-service.js +++ b/media-store/srv/user-service.js @@ -9,35 +9,12 @@ module.exports = async function () { const db = await cds.connect.to("db"); const { Employees, Customers } = db.entities; - const getUserEntity = (isCustomer) => (isCustomer ? Customers : Employees); - - this.on("updatePerson", async (req) => { - await UPDATE( - getUserEntity(req.user && req.user._roles && req.user.is("customer")) - ) - .set(req.data.person) - .where({ ID: req.user.attr.ID }); + this.before("UPDATE", "*", async (req) => { + req.query = req.query.where({ ID: req.user.attr.ID }); }); - this.on("getPerson", async (req) => { - return await db.run( - SELECT.one( - getUserEntity(req.user && req.user._roles && req.user.is("customer")) - ) - .columns( - "lastName", - "firstName", - "city", - "state", - "address", - "country", - "postalCode", - "phone", - "fax", - "email" - ) - .where({ email: req.user.id }) - ); + this.before("READ", "*", async (req) => { + req.query = req.query.where({ ID: req.user.attr.ID }); }); this.on("login", async (req) => { @@ -49,7 +26,6 @@ module.exports = async function () { userFromDb = await db.run(SELECT.one(Customers).where({ email })); roles = ["customer"]; } - const userEqualPassword = await bcrypt.compare( password, userFromDb.password diff --git a/media-store/util/importData.js b/media-store/util/importData.js index 1725fbed..e4d4e517 100644 --- a/media-store/util/importData.js +++ b/media-store/util/importData.js @@ -66,8 +66,6 @@ const constructInsertQuery = (targetEntityName) => { */ async function importData(targetDb) { try { - const srcStorage = await cds.connect.to(SRC_STORAGE_NAME); - const targetCSNEntities = Object.values(targetDb.entities); const targetCSNEntitiesNames = Object.keys(targetDb.entities); const someEntry = await targetDb.run( @@ -77,6 +75,8 @@ async function importData(targetDb) { return; } + const targetCSNEntities = Object.values(targetDb.entities); + const srcStorage = await cds.connect.to(SRC_STORAGE_NAME); const hashedPassword = await new Promise((resolve, reject) => bcrypt.hash("some", saltRounds, (error, hash) => { if (error) {