meadow-endpoints 3.0.2 → 3.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/source/Meadow-Authorizers.js +9 -1
- package/source/Meadow-Endpoints.js +35 -1
- package/source/crud/Meadow-Operation-Create.js +1 -1
- package/source/crud/Meadow-Operation-Update.js +1 -1
- package/source/crud/Meadow-Operation-Upsert.js +1 -1
- package/test/MeadowEndpoints_basic_tests.js +77 -0
package/package.json
CHANGED
|
@@ -46,6 +46,14 @@ var MeadowAuthorizers = function()
|
|
|
46
46
|
_AuthorizerFunctions[pAuthorizerHash] = fAuthorizer;
|
|
47
47
|
};
|
|
48
48
|
|
|
49
|
+
/**
|
|
50
|
+
* Get a specific authorizer.
|
|
51
|
+
*/
|
|
52
|
+
var getAuthorizer = function(pAuthorizerHash)
|
|
53
|
+
{
|
|
54
|
+
return _AuthorizerFunctions[pAuthorizerHash];
|
|
55
|
+
};
|
|
56
|
+
|
|
49
57
|
if (_AuthorizationMode === 'SimpleOwnership')
|
|
50
58
|
{
|
|
51
59
|
// Map in the authorizers for simple ownership mode
|
|
@@ -55,7 +63,6 @@ var MeadowAuthorizers = function()
|
|
|
55
63
|
setAuthorizer('MyCustomer', require(__dirname+'/authorizers/Meadow-Authorizer-MyCustomer.js'));
|
|
56
64
|
}
|
|
57
65
|
|
|
58
|
-
|
|
59
66
|
/**
|
|
60
67
|
* This method runs a authorizer at a specific hash, and returns true.
|
|
61
68
|
* Or it returns false if there was no authorizer there.
|
|
@@ -191,6 +198,7 @@ var MeadowAuthorizers = function()
|
|
|
191
198
|
var tmpNewMeadowAuthorizer = (
|
|
192
199
|
{
|
|
193
200
|
setAuthorizer: setAuthorizer,
|
|
201
|
+
getAuthorizer: getAuthorizer,
|
|
194
202
|
authorize: authorize,
|
|
195
203
|
authorizeRequest: authorizeRequest,
|
|
196
204
|
|
|
@@ -420,6 +420,17 @@ var MeadowEndpoints = function()
|
|
|
420
420
|
return fCallback();
|
|
421
421
|
};
|
|
422
422
|
|
|
423
|
+
var _InvokeSetupCallback;
|
|
424
|
+
var getInvokeSetupCallback = function()
|
|
425
|
+
{
|
|
426
|
+
return _InvokeSetupCallback;
|
|
427
|
+
};
|
|
428
|
+
|
|
429
|
+
var setInvokeSetupCallback = function(fCallback)
|
|
430
|
+
{
|
|
431
|
+
_InvokeSetupCallback = fCallback;
|
|
432
|
+
};
|
|
433
|
+
|
|
423
434
|
/**
|
|
424
435
|
* Invoke a meadow endpoint programmatically
|
|
425
436
|
*
|
|
@@ -435,8 +446,13 @@ var MeadowEndpoints = function()
|
|
|
435
446
|
return tmpCallback('Endpoint \'' + pMethod + '\' does not exist!'); //might be better as an exception
|
|
436
447
|
}
|
|
437
448
|
|
|
438
|
-
//TODO: should switch depending on type
|
|
449
|
+
// TODO: should switch depending on type
|
|
450
|
+
// TODO: should we keep this around, just make a deep copy of 'pOptions'
|
|
439
451
|
var pRequest = {params: pData, formattedParams: pData, body: pData};
|
|
452
|
+
if (typeof(pOptions) === 'object' && typeof(pOptions.header) === 'function') {
|
|
453
|
+
// carry over header function
|
|
454
|
+
pRequest.header = pOptions.header.bind(pOptions);
|
|
455
|
+
}
|
|
440
456
|
var pResponse = {};
|
|
441
457
|
|
|
442
458
|
libAsync.waterfall([
|
|
@@ -467,6 +483,10 @@ var MeadowEndpoints = function()
|
|
|
467
483
|
//internal invoke mark as authenticated (because this is not called via webservice)
|
|
468
484
|
pRequest.EndpointAuthenticated = true;
|
|
469
485
|
|
|
486
|
+
if (_InvokeSetupCallback && typeof(_InvokeSetupCallback) == 'function')
|
|
487
|
+
{
|
|
488
|
+
_InvokeSetupCallback(pRequest, pResponse, typeof(pOptions) === 'object' && pOptions);
|
|
489
|
+
}
|
|
470
490
|
return fStageComplete();
|
|
471
491
|
},
|
|
472
492
|
function(fStageComplete)
|
|
@@ -511,6 +531,8 @@ var MeadowEndpoints = function()
|
|
|
511
531
|
// Expose the DAL
|
|
512
532
|
DAL: _Meadow,
|
|
513
533
|
|
|
534
|
+
getInvokeSetupCallback: getInvokeSetupCallback,
|
|
535
|
+
setInvokeSetupCallback: setInvokeSetupCallback,
|
|
514
536
|
invokeEndpoint: invokeEndpoint,
|
|
515
537
|
|
|
516
538
|
// Factory
|
|
@@ -541,6 +563,18 @@ var MeadowEndpoints = function()
|
|
|
541
563
|
enumerable: true
|
|
542
564
|
});
|
|
543
565
|
|
|
566
|
+
/**
|
|
567
|
+
* EndpointAuthenticators
|
|
568
|
+
*
|
|
569
|
+
* @property endpointAuthorizers
|
|
570
|
+
* @type object
|
|
571
|
+
*/
|
|
572
|
+
Object.defineProperty(tmpNewMeadowEndpointObject, 'endpointAuthorizers',
|
|
573
|
+
{
|
|
574
|
+
get: function() { return _Authorizers; },
|
|
575
|
+
enumerable: true
|
|
576
|
+
});
|
|
577
|
+
|
|
544
578
|
/**
|
|
545
579
|
* EndpointAuthenticators
|
|
546
580
|
*
|
|
@@ -95,7 +95,7 @@ var doCreate = function(pRecord, pRequest, pResponse, fCallback)
|
|
|
95
95
|
pRequest.RecordCreateErrorMessage = pError;
|
|
96
96
|
// Also push the record to the created record stack with an error message
|
|
97
97
|
pRequest.CreatedRecords.push(pRecord);
|
|
98
|
-
pRequest.CommonServices.log.error('Error creating record:'+pError, {SessionID:pRequest.UserSession.SessionID, RequestID:pRequest.RequestUUID, RequestURL:pRequest.url, Action:pRequest.DAL.scope+'-'+pRequest.MeadowOperation}, pRequest);
|
|
98
|
+
pRequest.CommonServices.log.error('Error creating record:'+pError, {SessionID:pRequest.UserSession.SessionID, RequestID:pRequest.RequestUUID, RequestURL:pRequest.url, Action:pRequest.DAL.scope+'-'+pRequest.MeadowOperation, Stack: pError.stack }, pRequest);
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
return fCallback();
|
|
@@ -135,7 +135,7 @@ var doUpdate = function(pRecordToModify, pRequest, pResponse, fCallback, pOption
|
|
|
135
135
|
pRequest.RecordUpdateError = true;
|
|
136
136
|
pRequest.RecordUpdateErrorMessage = pError;
|
|
137
137
|
pRequest.UpdatedRecords.push(pRecordToModify);
|
|
138
|
-
pRequest.CommonServices.log.error('Error updating record:'+pError, {SessionID:pRequest.UserSession.SessionID, RequestID:pRequest.RequestUUID, RequestURL:pRequest.url, Action:pRequest.DAL.scope+'-'+pRequest.MeadowOperation}, pRequest);
|
|
138
|
+
pRequest.CommonServices.log.error('Error updating record:'+pError, {SessionID:pRequest.UserSession.SessionID, RequestID:pRequest.RequestUUID, RequestURL:pRequest.url, Action:pRequest.DAL.scope+'-'+pRequest.MeadowOperation, Stack: pError.stack }, pRequest);
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
return fCallback();
|
|
@@ -96,7 +96,7 @@ var doUpsert = function(pRecordToUpsert, pRequest, pResponse, fCallback)
|
|
|
96
96
|
pRequest.RecordUpsertError = true;
|
|
97
97
|
pRequest.RecordUpsertErrorMessage = pError;
|
|
98
98
|
pRequest.UpsertedRecords.push(pRecordToUpsert);
|
|
99
|
-
pRequest.CommonServices.log.error('Error upserting record:'+pError, {SessionID:pRequest.UserSession.SessionID, RequestID:pRequest.RequestUUID, RequestURL:pRequest.url, Action:pRequest.DAL.scope+'-'+pRequest.MeadowOperation}, pRequest);
|
|
99
|
+
pRequest.CommonServices.log.error('Error upserting record:'+pError, {SessionID:pRequest.UserSession.SessionID, RequestID:pRequest.RequestUUID, RequestURL:pRequest.url, Action:pRequest.DAL.scope+'-'+pRequest.MeadowOperation, Stack: pError.stack }, pRequest);
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
return fCallback();
|
|
@@ -467,6 +467,28 @@ suite
|
|
|
467
467
|
}
|
|
468
468
|
);
|
|
469
469
|
test
|
|
470
|
+
(
|
|
471
|
+
'read: define a custom authorization behavior',
|
|
472
|
+
function(fDone)
|
|
473
|
+
{
|
|
474
|
+
const defaultAuthorizer = _MeadowEndpoints.endpointAuthorizers.getAuthorizer('Allow');
|
|
475
|
+
_MeadowEndpoints.endpointAuthorizers.setAuthorizer('Allow', function(req, next) { req.MeadowAuthorization = false; return next(); });
|
|
476
|
+
_Orator.webServer.get('/CustomHotRodRoute/:IDRecord', _MeadowEndpoints.endpointAuthenticators.Read, _MeadowEndpoints.wireState, _MeadowEndpoints.endpoints.Read);
|
|
477
|
+
libSuperTest('http://localhost:9080/')
|
|
478
|
+
.get('CustomHotRodRoute/2')
|
|
479
|
+
.end(
|
|
480
|
+
function (pError, pResponse)
|
|
481
|
+
{
|
|
482
|
+
_MeadowEndpoints.endpointAuthorizers.setAuthorizer('Allow', defaultAuthorizer);
|
|
483
|
+
//TODO: it's weird that we don't get an error here for access denied...
|
|
484
|
+
var tmpResult = JSON.parse(pResponse.text);
|
|
485
|
+
Expect(tmpResult.Error).to.equal('UNAUTHORIZED ACCESS IS NOT ALLOWED');
|
|
486
|
+
fDone();
|
|
487
|
+
}
|
|
488
|
+
);
|
|
489
|
+
}
|
|
490
|
+
);
|
|
491
|
+
test
|
|
470
492
|
(
|
|
471
493
|
'read: define a custom route and get a record with it',
|
|
472
494
|
function(fDone)
|
|
@@ -506,6 +528,32 @@ suite
|
|
|
506
528
|
}
|
|
507
529
|
);
|
|
508
530
|
test
|
|
531
|
+
(
|
|
532
|
+
'read: get a specific record which resolved to Deny authorization, but with a Deny authorizer that just allows',
|
|
533
|
+
function(fDone)
|
|
534
|
+
{
|
|
535
|
+
_Meadow.schemaFull.authorizer.Manager = {};
|
|
536
|
+
_Meadow.schemaFull.authorizer.Manager.Read = 'Deny';
|
|
537
|
+
const defaultAuthorizer = _MeadowEndpoints.endpointAuthorizers.getAuthorizer('Deny');
|
|
538
|
+
_MeadowEndpoints.endpointAuthorizers.setAuthorizer('Deny', function(req, next) { req.MeadowAuthorization = true; return next(); });
|
|
539
|
+
|
|
540
|
+
libSuperTest('http://localhost:9080/')
|
|
541
|
+
.get('1.0/FableTest/2')
|
|
542
|
+
.end(
|
|
543
|
+
function (pError, pResponse)
|
|
544
|
+
{
|
|
545
|
+
// Reset authorization
|
|
546
|
+
_Meadow.schemaFull.authorizer.Manager.Read = 'Allow';
|
|
547
|
+
_MeadowEndpoints.endpointAuthorizers.setAuthorizer('Deny', defaultAuthorizer);
|
|
548
|
+
|
|
549
|
+
const responseBody = JSON.parse(pResponse.text);
|
|
550
|
+
Expect(responseBody.IDAnimal).to.equal(2);
|
|
551
|
+
fDone();
|
|
552
|
+
}
|
|
553
|
+
);
|
|
554
|
+
}
|
|
555
|
+
);
|
|
556
|
+
test
|
|
509
557
|
(
|
|
510
558
|
'read: get a specific record with a bad parameter',
|
|
511
559
|
function(fDone)
|
|
@@ -1492,6 +1540,35 @@ suite
|
|
|
1492
1540
|
{
|
|
1493
1541
|
var tmpCreatedRecordGUID;
|
|
1494
1542
|
|
|
1543
|
+
test
|
|
1544
|
+
(
|
|
1545
|
+
'invoke: setup method is called',
|
|
1546
|
+
function(fDone)
|
|
1547
|
+
{
|
|
1548
|
+
_MockSessionValidUser.UserRoleIndex = 2;
|
|
1549
|
+
let setupCallCount = 0;
|
|
1550
|
+
let passedRequest, passedResponse, passedOriginalRequest;
|
|
1551
|
+
_MeadowEndpoints.setInvokeSetupCallback((req, res, origReq) =>
|
|
1552
|
+
{
|
|
1553
|
+
++setupCallCount;
|
|
1554
|
+
passedRequest = req;
|
|
1555
|
+
passedResponse = res;
|
|
1556
|
+
passedOriginalRequest = origReq;
|
|
1557
|
+
});
|
|
1558
|
+
const originalRequest = {UserSession: _MockSessionValidUser};
|
|
1559
|
+
_MeadowEndpoints.invokeEndpoint('Read', {IDRecord: 2}, originalRequest,
|
|
1560
|
+
function(pError, pResponse)
|
|
1561
|
+
{
|
|
1562
|
+
Expect(setupCallCount).to.equal(1);
|
|
1563
|
+
Expect(passedOriginalRequest).to.equal(originalRequest);
|
|
1564
|
+
Expect(passedRequest).to.be.an('object');
|
|
1565
|
+
Expect(passedResponse).to.be.an('object');
|
|
1566
|
+
|
|
1567
|
+
fDone();
|
|
1568
|
+
}
|
|
1569
|
+
);
|
|
1570
|
+
}
|
|
1571
|
+
);
|
|
1495
1572
|
test
|
|
1496
1573
|
(
|
|
1497
1574
|
'invoke create: create a record',
|