add mocked auth

This commit is contained in:
Dzmitry_Tamashevich@epam.com
2020-10-15 01:24:12 +03:00
committed by Daniel Hutzel
parent 937d9caf2b
commit 49f6b8c060
30 changed files with 151 additions and 271 deletions

View File

@@ -1,25 +0,0 @@
{
"files": {
"main.css": "/static/css/main.e90d22b3.chunk.css",
"main.js": "/static/js/main.d9e24f2b.chunk.js",
"main.js.map": "/static/js/main.d9e24f2b.chunk.js.map",
"runtime-main.js": "/static/js/runtime-main.83c3e0c4.js",
"runtime-main.js.map": "/static/js/runtime-main.83c3e0c4.js.map",
"static/css/2.220ccb42.chunk.css": "/static/css/2.220ccb42.chunk.css",
"static/js/2.ab28bc83.chunk.js": "/static/js/2.ab28bc83.chunk.js",
"static/js/2.ab28bc83.chunk.js.map": "/static/js/2.ab28bc83.chunk.js.map",
"index.html": "/index.html",
"precache-manifest.885c6b213da9fa02f43df473848c3210.js": "/precache-manifest.885c6b213da9fa02f43df473848c3210.js",
"service-worker.js": "/service-worker.js",
"static/css/2.220ccb42.chunk.css.map": "/static/css/2.220ccb42.chunk.css.map",
"static/css/main.e90d22b3.chunk.css.map": "/static/css/main.e90d22b3.chunk.css.map",
"static/js/2.ab28bc83.chunk.js.LICENSE.txt": "/static/js/2.ab28bc83.chunk.js.LICENSE.txt"
},
"entrypoints": [
"static/js/runtime-main.83c3e0c4.js",
"static/css/2.220ccb42.chunk.css",
"static/js/2.ab28bc83.chunk.js",
"static/css/main.e90d22b3.chunk.css",
"static/js/main.d9e24f2b.chunk.js"
]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -1 +0,0 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="/logo192.png"/><link rel="manifest" href="/manifest.json"/><title>React App</title><link href="/static/css/2.220ccb42.chunk.css" rel="stylesheet"><link href="/static/css/main.e90d22b3.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function r(r){for(var n,p,l=r[0],a=r[1],f=r[2],c=0,s=[];c<l.length;c++)p=l[c],Object.prototype.hasOwnProperty.call(o,p)&&o[p]&&s.push(o[p][0]),o[p]=0;for(n in a)Object.prototype.hasOwnProperty.call(a,n)&&(e[n]=a[n]);for(i&&i(r);s.length;)s.shift()();return u.push.apply(u,f||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,l=1;l<t.length;l++){var a=t[l];0!==o[a]&&(n=!1)}n&&(u.splice(r--,1),e=p(p.s=t[0]))}return e}var n={},o={1:0},u=[];function p(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,p),t.l=!0,t.exports}p.m=e,p.c=n,p.d=function(e,r,t){p.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},p.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},p.t=function(e,r){if(1&r&&(e=p(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(p.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)p.d(t,n,function(r){return e[r]}.bind(null,n));return t},p.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return p.d(r,"a",r),r},p.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},p.p="/";var l=this["webpackJsonpmy-app"]=this["webpackJsonpmy-app"]||[],a=l.push.bind(l);l.push=r,l=l.slice();for(var f=0;f<l.length;f++)r(l[f]);var i=a;t()}([])</script><script src="/static/js/2.ab28bc83.chunk.js"></script><script src="/static/js/main.d9e24f2b.chunk.js"></script></body></html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

View File

@@ -1,25 +0,0 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

View File

@@ -1,30 +0,0 @@
self.__precacheManifest = (self.__precacheManifest || []).concat([
{
"revision": "ea9b879c690850337bdad632cc09abeb",
"url": "/index.html"
},
{
"revision": "68209aa39c38a26d9644",
"url": "/static/css/2.220ccb42.chunk.css"
},
{
"revision": "8e49ec2f91bb7a406dc4",
"url": "/static/css/main.e90d22b3.chunk.css"
},
{
"revision": "68209aa39c38a26d9644",
"url": "/static/js/2.ab28bc83.chunk.js"
},
{
"revision": "117d65892edc8adcd29d4a0d57b5a80a",
"url": "/static/js/2.ab28bc83.chunk.js.LICENSE.txt"
},
{
"revision": "8e49ec2f91bb7a406dc4",
"url": "/static/js/main.d9e24f2b.chunk.js"
},
{
"revision": "73635f645c271e35ff15",
"url": "/static/js/runtime-main.83c3e0c4.js"
}
]);

View File

@@ -1,3 +0,0 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:

View File

@@ -1,39 +0,0 @@
/**
* Welcome to your Workbox-powered service worker!
*
* You'll need to register this file in your web app and you should
* disable HTTP caching for this file too.
* See https://goo.gl/nhQhGp
*
* The rest of the code is auto-generated. Please don't update this file
* directly; instead, make changes to your Workbox build configuration
* and re-run your build process.
* See https://goo.gl/2aRDsh
*/
importScripts("https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js");
importScripts(
"/precache-manifest.885c6b213da9fa02f43df473848c3210.js"
);
self.addEventListener('message', (event) => {
if (event.data && event.data.type === 'SKIP_WAITING') {
self.skipWaiting();
}
});
workbox.core.clientsClaim();
/**
* The workboxSW.precacheAndRoute() method efficiently caches and responds to
* requests for URLs in the manifest.
* See https://goo.gl/S9QRab
*/
self.__precacheManifest = [].concat(self.__precacheManifest || []);
workbox.precaching.precacheAndRoute(self.__precacheManifest, {});
workbox.routing.registerNavigationRoute(workbox.precaching.getCacheKeyForURL("/index.html"), {
blacklist: [/^\/_/,/\/[^/?]+\.[^/]+$/],
});

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,2 +0,0 @@
html{overflow:hidden}#root{height:100%}section.ant-layout{height:100vh;overflow:auto}.site-layout .site-layout-background{background:#fff}.App{text-align:center}.App-logo{height:40vmin;pointer-events:none}@media (prefers-reduced-motion:no-preference){.App-logo{-webkit-animation:App-logo-spin 20s linear infinite;animation:App-logo-spin 20s linear infinite}}.App-header{background-color:#282c34;min-height:100vh;display:flex;flex-direction:column;align-items:center;justify-content:center;font-size:calc(10px + 2vmin);color:#fff}.App-link{color:#61dafb}@-webkit-keyframes App-logo-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}@keyframes App-logo-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}div.ant-select-dropdown.ant-select-dropdown-placement-bottomLeft,div.ant-select.ant-select-multiple.ant-select-show-search>div{border-radius:6px}.ant-select>div.ant-select-selector{padding:5px;min-width:300px}
/*# sourceMappingURL=main.e90d22b3.chunk.css.map */

View File

@@ -1 +0,0 @@
{"version":3,"sources":["index.css","App.css","TracksPage.css"],"names":[],"mappings":"AAEA,KACE,eACF,CACA,MACE,WACF,CACA,mBACE,YAAa,CACb,aACF,CAIA,qCACE,eACF,CCjBA,KACE,iBACF,CAEA,UACE,aAAc,CACd,mBACF,CAEA,8CACE,UACE,mDAA4C,CAA5C,2CACF,CACF,CAEA,YACE,wBAAyB,CACzB,gBAAiB,CACjB,YAAa,CACb,qBAAsB,CACtB,kBAAmB,CACnB,sBAAuB,CACvB,4BAA6B,CAC7B,UACF,CAEA,UACE,aACF,CAEA,iCACE,GACE,sBACF,CACA,GACE,uBACF,CACF,CAPA,yBACE,GACE,sBACF,CACA,GACE,uBACF,CACF,CCrCA,+HAEE,iBACF,CAEA,oCACE,WAAY,CACZ,eACF","file":"main.e90d22b3.chunk.css","sourcesContent":["@import \"~antd/dist/antd.css\";\n\nhtml {\n overflow: hidden;\n}\n#root {\n height: 100%;\n}\nsection.ant-layout {\n height: 100vh;\n overflow: auto;\n}\n\n/* Layout\n*/\n.site-layout .site-layout-background {\n background: #fff;\n}\n",".App {\n text-align: center;\n}\n\n.App-logo {\n height: 40vmin;\n pointer-events: none;\n}\n\n@media (prefers-reduced-motion: no-preference) {\n .App-logo {\n animation: App-logo-spin infinite 20s linear;\n }\n}\n\n.App-header {\n background-color: #282c34;\n min-height: 100vh;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n font-size: calc(10px + 2vmin);\n color: white;\n}\n\n.App-link {\n color: #61dafb;\n}\n\n@keyframes App-logo-spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n","div.ant-select.ant-select-multiple.ant-select-show-search > div,\r\ndiv.ant-select-dropdown.ant-select-dropdown-placement-bottomLeft {\r\n border-radius: 6px;\r\n}\r\n\r\n.ant-select > div.ant-select-selector {\r\n padding: 5px;\r\n min-width: 300px;\r\n}\r\n"]}

File diff suppressed because one or more lines are too long

View File

@@ -1,56 +0,0 @@
/*
object-assign
(c) Sindre Sorhus
@license MIT
*/
/*!
Copyright (c) 2017 Jed Watson.
Licensed under the MIT License (MIT), see
http://jedwatson.github.io/classnames
*/
/**
* @license
* Lodash <https://lodash.com/>
* Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
* Released under MIT license <https://lodash.com/license>
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
*/
/** @license React v0.19.1
* scheduler.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/** @license React v16.13.1
* react-dom.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/** @license React v16.13.1
* react-is.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/** @license React v16.13.1
* react.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,2 +0,0 @@
!function(e){function r(r){for(var n,p,l=r[0],a=r[1],f=r[2],c=0,s=[];c<l.length;c++)p=l[c],Object.prototype.hasOwnProperty.call(o,p)&&o[p]&&s.push(o[p][0]),o[p]=0;for(n in a)Object.prototype.hasOwnProperty.call(a,n)&&(e[n]=a[n]);for(i&&i(r);s.length;)s.shift()();return u.push.apply(u,f||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,l=1;l<t.length;l++){var a=t[l];0!==o[a]&&(n=!1)}n&&(u.splice(r--,1),e=p(p.s=t[0]))}return e}var n={},o={1:0},u=[];function p(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,p),t.l=!0,t.exports}p.m=e,p.c=n,p.d=function(e,r,t){p.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},p.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},p.t=function(e,r){if(1&r&&(e=p(e)),8&r)return e;if(4&r&&"object"===typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(p.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)p.d(t,n,function(r){return e[r]}.bind(null,n));return t},p.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return p.d(r,"a",r),r},p.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},p.p="/";var l=this["webpackJsonpmy-app"]=this["webpackJsonpmy-app"]||[],a=l.push.bind(l);l.push=r,l=l.slice();for(var f=0;f<l.length;f++)r(l[f]);var i=a;t()}([]);
//# sourceMappingURL=runtime-main.83c3e0c4.js.map

File diff suppressed because one or more lines are too long

View File

@@ -17,6 +17,7 @@ aspect Persone {
phone : String(24); phone : String(24);
fax : String(24); fax : String(24);
email : String(60); email : String(60);
password : String(111);
} }
entity MediaTypes : Named {} entity MediaTypes : Named {}
@@ -82,15 +83,16 @@ entity InvoiceItems {
} }
entity Tracks { entity Tracks {
key ID : Integer; key ID : Integer;
name : String(200); name : String(200);
album : Association to Albums; album : Association to Albums;
mediaType : Association to MediaTypes; mediaType : Association to MediaTypes;
genre : Association to Genres; genre : Association to Genres;
composer : String(220); composer : String(220);
milliseconds : Integer; milliseconds : Integer;
bytes : Integer; bytes : Integer;
unitPrice : Decimal(10, 2); unitPrice : Decimal(10, 2);
invoices : Association to many InvoiceItems invoiceItems : Association to many InvoiceItems
on invoices.track = $self on invoiceItems.track = $self;
virtual alreadyOrdered : Boolean;
} }

View File

@@ -31,50 +31,24 @@
"auth": { "auth": {
"strategy": "mock", "strategy": "mock",
"users": { "users": {
"admin5": { "andrew@chinookcorp.com": {
"password": "some",
"roles": [ "roles": [
"admin", "employee"
"content-creator"
],
"userAttributes": {
"level": 5,
"ID": 8
}
},
"admin2": {
"roles": [
"admin"
],
"userAttributes": {
"level": 2,
"ID": 7
}
},
"content-creator1": {
"roles": [
"content-creator"
],
"userAttributes": {
"level": 2,
"ID": 5
}
},
"user1": {
"roles": [
"user"
], ],
"userAttributes": { "userAttributes": {
"level": 1, "level": 1,
"ID": 2 "ID": 1
} }
}, },
"user0": { "luisg@embraer.com.br": {
"password": "some",
"roles": [ "roles": [
"user" "customer"
], ],
"userAttributes": { "userAttributes": {
"level": 1, "level": 0,
"ID": 3 "ID": 1
} }
}, },
"*": true "*": true
@@ -82,4 +56,4 @@
} }
} }
} }
} }

View File

@@ -1,10 +1,17 @@
using {sap.capire.media.store as my} from '../db/schema'; using {sap.capire.media.store as my} from '../db/schema';
@(requires : ['identified-user'])
service BrowseTracks { service BrowseTracks {
@readonly @readonly
entity Tracks as projection on my.Tracks; entity Tracks as projection on my.Tracks excluding {
alreadyOrdered
};
@(requires : 'authenticated-user')
@readonly
entity MarkedTracks as projection on my.Tracks;
@readonly @readonly
entity Genres as projection on my.Genres; entity Genres as projection on my.Genres {
* , tracks : redirected to Tracks
};
} }

View File

@@ -1,5 +1,14 @@
const cds = require("@sap/cds"); const cds = require("@sap/cds");
// only for demo cds.run(string, args)
const SELECT_INVOICES_BY_EMAIL = `
select invoice.ID
from sap_capire_media_store_Invoices invoice
join sap_capire_media_store_Customers customer
on customer.ID = invoice.customer_ID
where customer.email=?
`;
module.exports = async function () { module.exports = async function () {
const db = await cds.connect.to("db"); // connect to database service const db = await cds.connect.to("db"); // connect to database service
const { Invoices } = db.entities; const { Invoices } = db.entities;
@@ -15,20 +24,21 @@ module.exports = async function () {
); );
}); });
this.on("READ", "Tracks", async (req, next) => { this.on("READ", "MarkedTracks", async (req) => {
if (!!req._query && "my" in req._query) { const myTrackIds = (
const myTrackEntries = await db.run( await db.run(
SELECT.from(Invoices) SELECT.from(Invoices)
.columns("ID") .columns("ID")
.where({ customer_ID: req.user.attr.ID }) .where({ customer_ID: req.user.attr.ID })
); )
const myTrackIdsSequence = myTrackEntries.map(({ ID }) => ID).join(); ).map(({ ID }) => ID);
const condition = cds.parse.expr(`ID in (${myTrackIdsSequence})`);
const query = SELECT.from(req.query).where(condition); const result = await db.run(req.query);
const result = await db.run(query); return result.map((columns) => {
result.$count = result.length; return {
return result; ...columns,
} alreadyOrdered: myTrackIds.includes(columns.ID),
return next(); };
});
}); });
}; };

View File

@@ -0,0 +1,12 @@
using {sap.capire.media.store as my} from '../db/schema';
@(requires : 'authenticated-user')
service InvoicesService {
@readonly
entity Invoices as projection on my.Invoices actions {
action invoice();
}
@readonly
entity InvoiceItems as projection on my.InvoiceItems;
}

View File

@@ -0,0 +1,20 @@
const cds = require("@sap/cds");
module.exports = async function () {
const db = await cds.connect.to("db"); // connect to database service
this.before("*", (req) => {
console.log(
"[USER]:",
req.user.id,
" [LEVEL]: ",
req.user.attr.level,
"[ROLE]",
req.user.is("user") ? "user" : "other"
);
});
this.on("READ", "Invoices", async (req) => {
return await db.run(req.query.where({ customer_ID: req.user.attr.ID }));
});
};

View File

@@ -11,10 +11,9 @@ service MediaService {
entity MediaTypes as projection on my.MediaTypes; entity MediaTypes as projection on my.MediaTypes;
entity PlaylistTrack as projection on my.PlaylistTrack; entity PlaylistTrack as projection on my.PlaylistTrack;
entity Playlists as projection on my.Playlists; entity Playlists as projection on my.Playlists;
// @(restrict : [{
@(restrict : [{ // grant : '*',
grant : '*', // where : '$user.level > 1'
where : '$user.level > 1' // }])
}])
entity Tracks as projection on my.Tracks; entity Tracks as projection on my.Tracks;
} }

View File

@@ -0,0 +1,11 @@
using {sap.capire.media.store as my} from '../db/schema';
service UserService {
function mockLogin(email : String(111), password : String(200)) returns {
roles : array of String(111);
level : Integer;
mockedToken : String(500);
email : my.Persone.email;
ID : my.Persone.ID
}
}

View File

@@ -0,0 +1,39 @@
const cds = require("@sap/cds");
module.exports = async function () {
const db = await cds.connect.to("db"); // connect to database service
const { Employees, Customers } = db.entities;
this.before("*", (req) => {
console.log(
"[USER]:",
req.user.id,
" [LEVEL]: ",
req.user.attr.level,
"[ROLE]",
req.user.is("user") ? "user" : "other"
);
});
this.on("mockLogin", async (req) => {
const { email, password } = req.data;
let userFromDb = await db.run(SELECT.one(Employees).where({ email }));
let role = "employee";
if (!userFromDb) {
userFromDb = await db.run(SELECT.one(Customers).where({ email }));
role = "customer";
}
if (!userFromDb || password !== userFromDb.password) {
req.reject(401);
}
return {
mockedToken: Buffer.from(`${email}:${password}`).toString("base64"),
level: role === "customer" ? 1 : 2,
email: userFromDb.email,
ID: userFromDb.ID,
roles: [role],
};
});
};

View File

@@ -89,7 +89,7 @@ const logProcessArgs = () => {
const insertQuery = constructInsertQuery(targetEntityName, targetColumns); const insertQuery = constructInsertQuery(targetEntityName, targetColumns);
const srcEntityName = camelCaseToSnake(targetEntityName.split(".").pop()); const srcEntityName = camelCaseToSnake(targetEntityName.split(".").pop());
const srcResultRows = await srcStorage.read(srcEntityName); // e.g. [ { AlbumId:1, ArtistId:1, Title:'some' }, ... ] let srcResultRows = await srcStorage.read(srcEntityName); // e.g. [ { AlbumId:1, ArtistId:1, Title:'some' }, ... ]
if (!srcResultRows || srcResultRows.length < ZERO_VALUE) { if (!srcResultRows || srcResultRows.length < ZERO_VALUE) {
console.log( console.log(
`[LOG] Skipping ${targetEntityName}. `[LOG] Skipping ${targetEntityName}.
@@ -106,6 +106,15 @@ const logProcessArgs = () => {
); );
} }
// for mock auth
if (srcEntityName === "Employees" || srcEntityName === "Customers") {
columns.push("password");
srcResultRows = srcResultRows.map((row) => ({
...row,
password: "some",
}));
}
const transaction = await targetStorage.tx(); const transaction = await targetStorage.tx();
await transaction.run( await transaction.run(
srcResultRows.map((row) => insertQuery(Object.values(row), columns)) srcResultRows.map((row) => insertQuery(Object.values(row), columns))