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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "meadow-endpoints",
3
- "version": "3.0.2",
3
+ "version": "3.0.6",
4
4
  "description": "Automatic API endpoints for Meadow data.",
5
5
  "main": "source/Meadow-Endpoints.js",
6
6
  "scripts": {
@@ -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',