meadow-endpoints 3.0.6 → 4.0.2

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.
Files changed (126) hide show
  1. package/{Dockerfile → Dockerfile_LUXURYCode} +43 -1
  2. package/README.md +48 -14
  3. package/debug/Animal.json +62 -0
  4. package/debug/Harness-Configuration.json +31 -0
  5. package/debug/Harness.js +7 -108
  6. package/debug/KillHarness.sh +10 -0
  7. package/dist/meadowendpoints.js +4402 -0
  8. package/dist/meadowendpoints.min.js +92 -0
  9. package/dist/meadowendpoints.min.js.map +1 -0
  10. package/gulpfile.js +83 -0
  11. package/package.json +29 -16
  12. package/source/Meadow-Endpoints-Browser-Shim.js +14 -0
  13. package/source/Meadow-Endpoints.js +176 -562
  14. package/source/controller/Meadow-Endpoints-Controller-Base.js +161 -0
  15. package/source/controller/components/Meadow-Endpoints-Controller-BehaviorInjection.js +125 -0
  16. package/source/controller/components/Meadow-Endpoints-Controller-Error-StatusCodes.txt +189 -0
  17. package/source/controller/components/Meadow-Endpoints-Controller-Error.js +118 -0
  18. package/source/controller/components/Meadow-Endpoints-Controller-Log.js +103 -0
  19. package/source/controller/utility/Meadow-Endpoints-Filter-Parser.js +225 -0
  20. package/source/controller/utility/Meadow-Endpoints-Session-Marshaler.js +48 -0
  21. package/source/controller/utility/Meadow-Endpoints-Stream-RecordArray.js +66 -0
  22. package/source/endpoints/count/Meadow-Endpoint-Count.js +49 -0
  23. package/source/endpoints/count/Meadow-Endpoint-CountBy.js +40 -0
  24. package/source/endpoints/create/Meadow-Endpoint-BulkCreate.js +53 -0
  25. package/source/endpoints/create/Meadow-Endpoint-Create.js +58 -0
  26. package/source/endpoints/create/Meadow-Operation-Create.js +83 -0
  27. package/source/endpoints/delete/Meadow-Endpoint-Delete.js +93 -0
  28. package/source/endpoints/delete/Meadow-Endpoint-Undelete.js +108 -0
  29. package/source/endpoints/read/Meadow-Endpoint-Read.js +72 -0
  30. package/source/endpoints/read/Meadow-Endpoint-ReadDistinctList.js +92 -0
  31. package/source/endpoints/read/Meadow-Endpoint-ReadLiteList.js +85 -0
  32. package/source/endpoints/read/Meadow-Endpoint-ReadMax.js +55 -0
  33. package/source/endpoints/read/Meadow-Endpoint-ReadSelectList.js +89 -0
  34. package/source/endpoints/read/Meadow-Endpoint-Reads.js +75 -0
  35. package/source/endpoints/read/Meadow-Endpoint-ReadsBy.js +100 -0
  36. package/source/{crud → endpoints/read}/Meadow-Marshal-DistinctList.js +4 -13
  37. package/source/{crud → endpoints/read}/Meadow-Marshal-LiteList.js +5 -14
  38. package/source/endpoints/schema/Meadow-Endpoint-New.js +36 -0
  39. package/source/endpoints/schema/Meadow-Endpoint-Schema.js +36 -0
  40. package/source/endpoints/schema/Meadow-Endpoint-Validate.js +41 -0
  41. package/source/endpoints/update/Meadow-Endpoint-BulkUpdate.js +50 -0
  42. package/source/endpoints/update/Meadow-Endpoint-Update.js +58 -0
  43. package/source/endpoints/update/Meadow-Operation-Update.js +115 -0
  44. package/source/endpoints/upsert/Meadow-Endpoint-BulkUpsert.js +52 -0
  45. package/source/endpoints/upsert/Meadow-Endpoint-Upsert.js +57 -0
  46. package/source/endpoints/upsert/Meadow-Operation-Upsert.js +137 -0
  47. package/test/MeadowEndpoints_basic_tests.js +50 -2375
  48. package/test_support/bookstore-api-endpoint-exercises.paw +0 -0
  49. package/test_support/bookstore-configuration.json +28 -0
  50. package/test_support/bookstore-import-books-run.js +1 -0
  51. package/test_support/bookstore-import-books.js +215 -0
  52. package/test_support/bookstore-serve-meadow-endpoint-apis-IPC.js +138 -0
  53. package/test_support/bookstore-serve-meadow-endpoint-apis-run.js +6 -0
  54. package/test_support/bookstore-serve-meadow-endpoint-apis.js +129 -0
  55. package/test_support/data/books.csv +10001 -0
  56. package/test_support/model/ddl/BookStore.ddl +66 -0
  57. package/test_support/model/generated_diagram/README.md +1 -0
  58. package/test_support/model/generated_diagram/Stricture_Output.dot +13 -0
  59. package/test_support/model/generated_diagram/Stricture_Output.png +0 -0
  60. package/test_support/model/generated_documentation/Dictionary.md +18 -0
  61. package/test_support/model/generated_documentation/Model-Author.md +20 -0
  62. package/test_support/model/generated_documentation/Model-Book.md +26 -0
  63. package/test_support/model/generated_documentation/Model-BookAuthorJoin.md +14 -0
  64. package/test_support/model/generated_documentation/Model-BookPrice.md +25 -0
  65. package/test_support/model/generated_documentation/Model-Review.md +22 -0
  66. package/test_support/model/generated_documentation/ModelChangeTracking.md +17 -0
  67. package/test_support/model/generated_documentation/README.md +1 -0
  68. package/test_support/model/manual_scripts/DropTables.sql +5 -0
  69. package/test_support/model/manual_scripts/README.md +2 -0
  70. package/test_support/model/sql_create/BookStore-CreateDatabase.mysql.sql +116 -0
  71. package/test_support/model/sql_create/README.md +1 -0
  72. package/test_support/test_old/Tests.js +3243 -0
  73. package/test_support/test_old/untitled.js +88 -0
  74. package/source/Meadow-Authenticator.js +0 -31
  75. package/source/Meadow-Authorizers.js +0 -214
  76. package/source/Meadow-BehaviorModifications.js +0 -170
  77. package/source/Meadow-CommonServices.js +0 -206
  78. package/source/Meadow-MarshallSessionData.js +0 -64
  79. package/source/Restify-RouteParser.js +0 -114
  80. package/source/authorizers/Meadow-Authorizer-Allow.js +0 -17
  81. package/source/authorizers/Meadow-Authorizer-Deny.js +0 -17
  82. package/source/authorizers/Meadow-Authorizer-Mine.js +0 -47
  83. package/source/authorizers/Meadow-Authorizer-MyCustomer.js +0 -48
  84. package/source/crud/Meadow-Endpoint-BulkCreate.js +0 -67
  85. package/source/crud/Meadow-Endpoint-BulkUpdate.js +0 -74
  86. package/source/crud/Meadow-Endpoint-BulkUpsert.js +0 -76
  87. package/source/crud/Meadow-Endpoint-Count.js +0 -93
  88. package/source/crud/Meadow-Endpoint-CountBy.js +0 -101
  89. package/source/crud/Meadow-Endpoint-Create.js +0 -77
  90. package/source/crud/Meadow-Endpoint-Delete.js +0 -139
  91. package/source/crud/Meadow-Endpoint-Read.js +0 -109
  92. package/source/crud/Meadow-Endpoint-ReadDistinctList.js +0 -146
  93. package/source/crud/Meadow-Endpoint-ReadLiteList.js +0 -139
  94. package/source/crud/Meadow-Endpoint-ReadMax.js +0 -86
  95. package/source/crud/Meadow-Endpoint-ReadSelectList.js +0 -145
  96. package/source/crud/Meadow-Endpoint-Reads.js +0 -129
  97. package/source/crud/Meadow-Endpoint-ReadsBy.js +0 -155
  98. package/source/crud/Meadow-Endpoint-Update.js +0 -80
  99. package/source/crud/Meadow-Endpoint-Upsert.js +0 -78
  100. package/source/crud/Meadow-Operation-Create.js +0 -105
  101. package/source/crud/Meadow-Operation-Update.js +0 -145
  102. package/source/crud/Meadow-Operation-Upsert.js +0 -106
  103. package/source/crud/Meadow-StreamRecordArray.js +0 -45
  104. package/source/schema/Meadow-Endpoint-New.js +0 -37
  105. package/source/schema/Meadow-Endpoint-Schema.js +0 -37
  106. package/source/schema/Meadow-Endpoint-Validate.js +0 -43
  107. package/test/Animal.json +0 -140
  108. package/test/MeadowEndpoints_disabledAuth_tests.js +0 -1325
  109. package/test/MeadowEndpoints_trustedSession_tests.js +0 -1731
  110. package/test/load/artillery-low.yml +0 -10
  111. package/test/load/cloud9setup.sh +0 -25
  112. package/test/load/package.json +0 -19
  113. package/test/load/test-schema-initializedatabase.sql +0 -29
  114. package/test/load/test-schema.json +0 -119
  115. package/test/load/test-server.js +0 -157
  116. package/test/scripts/InitializeDatabase-C9.sql +0 -7
  117. /package/{test/schemas → test_support/model}/json_schema/BookStore-Extended.json +0 -0
  118. /package/{test/schemas → test_support/model}/json_schema/BookStore-PICT.json +0 -0
  119. /package/{test/schemas → test_support/model}/json_schema/BookStore.json +0 -0
  120. /package/{test/schemas → test_support/model}/json_schema/README.md +0 -0
  121. /package/{test/schemas → test_support/model}/meadow_schema/BookStore-MeadowSchema-Author.json +0 -0
  122. /package/{test/schemas → test_support/model}/meadow_schema/BookStore-MeadowSchema-Book.json +0 -0
  123. /package/{test/schemas → test_support/model}/meadow_schema/BookStore-MeadowSchema-BookAuthorJoin.json +0 -0
  124. /package/{test/schemas → test_support/model}/meadow_schema/BookStore-MeadowSchema-BookPrice.json +0 -0
  125. /package/{test/schemas → test_support/model}/meadow_schema/BookStore-MeadowSchema-Review.json +0 -0
  126. /package/{test/schemas → test_support/model}/meadow_schema/README.md +0 -0
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Test Harness
3
+ *
4
+ * @license MIT
5
+ *
6
+ * @author Steven Velozo <steven@velozo.com>
7
+ */
8
+
9
+
10
+
11
+ ////////// Code can go here for easy debugging //////////
12
+
13
+
14
+ const tmpApplicationSettings = (
15
+ {
16
+ Product: 'MockEndpointServer',
17
+ ProductVersion: '0.0.0',
18
+
19
+ "UnauthorizedRequestDelay": 100,
20
+
21
+ APIServerPort: 8086,
22
+
23
+ MySQL:
24
+ {
25
+ // This is queued up for Travis defaults.
26
+ Server: "localhost",
27
+ Port: 3306,
28
+ User: "root",
29
+ Password: "123456789",
30
+ // Password: "",
31
+ Database: "FableTest",
32
+ ConnectionPoolLimit: 20
33
+ }
34
+ });
35
+
36
+ // Construct a fable.
37
+ const _Fable = new libFable(tmpApplicationSettings);
38
+ // Connect to SQL, put the connection in the magic location
39
+ _Fable.MeadowMySQLConnectionPool = libMySQL.createPool
40
+ (
41
+ {
42
+ connectionLimit: _Fable.settings.MySQL.ConnectionPoolLimit,
43
+ host: _Fable.settings.MySQL.Server,
44
+ port: _Fable.settings.MySQL.Port,
45
+ user: _Fable.settings.MySQL.User,
46
+ password: _Fable.settings.MySQL.Password,
47
+ database: _Fable.settings.MySQL.Database,
48
+ namedPlaceholders: true
49
+ }
50
+ );
51
+
52
+ // Load up a Meadow (pointing at the Animal database)
53
+ const _AnimalSchema = require('../test/Animal.json');
54
+ const _Meadow = libMeadow.new(_Fable, 'FableTest')
55
+ .setProvider('MySQL')
56
+ .setSchema(_AnimalSchema.Schema)
57
+ .setJsonSchema(_AnimalSchema.JsonSchema)
58
+ .setDefaultIdentifier(_AnimalSchema.DefaultIdentifier)
59
+ .setDefault(_AnimalSchema.DefaultObject);
60
+
61
+ // Instantiate the meadow endpoints with the DAL object constructed above
62
+ const _MeadowEndpoints = new libMeadowEndpoints(_Meadow);
63
+
64
+ // Instantiate the service server, using restify
65
+ const _Orator = new libOrator(_Fable, libOratorServiceServerRestify);
66
+ // Prepare the service server for mapping endpoints
67
+ _Orator.initializeServiceServer();
68
+
69
+ _MeadowEndpoints.controller.BehaviorInjection.setBehavior('Schema-PreOperation',
70
+ function (pRequest, pRequestState, fCallback)
71
+ {
72
+ this.log.info('I have access to state!', pRequestState);
73
+ return fCallback();
74
+ });
75
+
76
+ _MeadowEndpoints.controller.BehaviorInjection.setBehavior('Schema-PostOperation',
77
+ function (pRequest, pRequestState, fCallback)
78
+ {
79
+ pRequestState.JSONSchema.PLOT = `GODZILLA WILL EAT YOUR SOUL!`;
80
+ this.log.info('I can also mutate state before sending!', pRequestState);
81
+ return fCallback();
82
+ });
83
+
84
+ // Wire the endpoints up
85
+ _MeadowEndpoints.connectRoutes(_Orator.serviceServer);
86
+
87
+ // Now start the web server.
88
+ _Orator.startWebServer(_HarnessBehavior);
@@ -1,31 +0,0 @@
1
- /**
2
- * Check that a user is logged in, if enabled
3
- *
4
- * @method getAuthenticator
5
- */
6
- const getAuthenticator = (pAuthenticatorMode) =>
7
- {
8
- if (pAuthenticatorMode === 'Disabled')
9
- {
10
- return (pRequest, pResponse, fNext) =>
11
- {
12
- pRequest.EndpointAuthenticated = true;
13
- fNext();
14
- };
15
- }
16
- return (pRequest, pResponse, fNext) =>
17
- {
18
- if (!pRequest.UserSession.LoggedIn)
19
- {
20
- pRequest.EndpointAuthenticated = false;
21
- }
22
- else
23
- {
24
- pRequest.EndpointAuthenticated = true;
25
- }
26
-
27
- fNext();
28
- }
29
- };
30
-
31
- module.exports = getAuthenticator;
@@ -1,214 +0,0 @@
1
- /**
2
- * The Meadow Security Authorizor Collection
3
- *
4
- * Provide a set of security authorizers, and give the API consumer the ability to add to or modify them.
5
- *
6
- * @class MeadowAuthorizers
7
- * @constructor
8
- */
9
- var libUnderscore = require('underscore');
10
- var libAsync = require('async');
11
-
12
- var MeadowAuthorizers = function()
13
- {
14
- function createNew(pMeadow)
15
- {
16
- // If a valid fable object isn't passed in, return a constructor
17
- if ((typeof(pMeadow) !== 'object') || !('fable' in pMeadow))
18
- {
19
- return {new: createNew};
20
- }
21
-
22
- const _AuthorizationMode = pMeadow.fable.settings.MeadowAuthorizationMode || 'Disabled';
23
-
24
- // An object to hold modifications to specific authorizers.
25
- var _AuthorizerFunctions = {};
26
-
27
-
28
- /**
29
- * Set a specific authorizer.
30
- *
31
- * The anatomy of a authorizer function is as follows:
32
- *
33
- * var someAuthorizer = function(pRequest, fComplete)
34
- * {
35
- * // Do some stuff with pRequest...
36
- * if (pRequest.UserSession.UserRoleIndex < 5)
37
- * pRequest.MeadowAuthorization = pRequest.MeadowAuthorization && false;
38
- *
39
- * return fComplete(false);
40
- * }
41
- *
42
- * It is important to note that the fComplete function expects false if no error, or a string message if there is one.
43
- */
44
- var setAuthorizer = function(pAuthorizerHash, fAuthorizer)
45
- {
46
- _AuthorizerFunctions[pAuthorizerHash] = fAuthorizer;
47
- };
48
-
49
- /**
50
- * Get a specific authorizer.
51
- */
52
- var getAuthorizer = function(pAuthorizerHash)
53
- {
54
- return _AuthorizerFunctions[pAuthorizerHash];
55
- };
56
-
57
- if (_AuthorizationMode === 'SimpleOwnership')
58
- {
59
- // Map in the authorizers for simple ownership mode
60
- setAuthorizer('Allow', require(__dirname+'/authorizers/Meadow-Authorizer-Allow.js'));
61
- setAuthorizer('Deny', require(__dirname+'/authorizers/Meadow-Authorizer-Deny.js'));
62
- setAuthorizer('Mine', require(__dirname+'/authorizers/Meadow-Authorizer-Mine.js'));
63
- setAuthorizer('MyCustomer', require(__dirname+'/authorizers/Meadow-Authorizer-MyCustomer.js'));
64
- }
65
-
66
- /**
67
- * This method runs a authorizer at a specific hash, and returns true.
68
- * Or it returns false if there was no authorizer there.
69
- * Authorizers should expect their state to be in the pRequest object, per the example in setAuthorizer
70
- */
71
- var authorize = function(pAuthorizerHash, pRequest, fComplete)
72
- {
73
- // Add the authorization value to the request object if it doesn't exist yet
74
- if (!pRequest.hasOwnProperty('MeadowAuthorization'))
75
- {
76
- pRequest.MeadowAuthorization = true;
77
- }
78
-
79
- // authorize all behaviors if authorization is disabled
80
- if (_AuthorizationMode === 'Disabled')
81
- {
82
- return fComplete();
83
- }
84
-
85
- //FIXME: Get rid of this...
86
- if (pRequest.Satchel &&
87
- pRequest.Satchel.AuthorizeOverride)
88
- return fComplete(false);
89
-
90
- // Run an injected authorizer (if it exists)
91
- if (_AuthorizerFunctions.hasOwnProperty(pAuthorizerHash))
92
- {
93
- if (!pRequest.Record &&
94
- pRequest.Records)
95
- {
96
- // Run the authorizer for multiple records
97
-
98
- libAsync.eachSeries(pRequest.Records, function(pRecord, fNext)
99
- {
100
- pRequest.Record = pRecord;
101
-
102
- _AuthorizerFunctions[pAuthorizerHash](pRequest, function(err)
103
- {
104
- if (err)
105
- return fNext({Error: err});
106
-
107
- // If MeadowAuthorization fails, keep the state and pass it on
108
- return fNext(!pRequest.MeadowAuthorization);
109
- });
110
- },
111
- function(pCancelled)
112
- {
113
- delete pRequest['Record']; //remove this property as it should only contains 'Records'
114
-
115
- if (pCancelled &&
116
- pCancelled.Error)
117
- {
118
- return fComplete(pCancelled.Error);
119
- }
120
-
121
- return fComplete(false);
122
- });
123
- }
124
- else
125
- {
126
- // Run the authorizer for one record
127
- return _AuthorizerFunctions[pAuthorizerHash](pRequest, fComplete);
128
- }
129
- }
130
- else
131
- {
132
- return fComplete(false);
133
- }
134
- };
135
-
136
-
137
- // Try to execute any defined authorizers on the proper endpoint
138
- var authorizeRequest = function(pRequestHash, pRequest, fComplete)
139
- {
140
- // Add the authorization value to the request object if it doesn't exist yet
141
- if (!pRequest.hasOwnProperty('MeadowAuthorization'))
142
- {
143
- pRequest.MeadowAuthorization = true;
144
- }
145
-
146
- // authorize all behaviors if authorization is disabled
147
- if (_AuthorizationMode === 'Disabled')
148
- {
149
- return fComplete();
150
- }
151
-
152
- // Attach authorizer hash in case the invoked authorizer needs the endpoint context
153
- pRequest.EndpointHash = pRequestHash;
154
-
155
- // See if there is an authorizer collection for the role of the user
156
- var tmpRoleAuthorizer = pRequest.DAL.schemaFull.authorizer[pRequest.DAL.getRoleName(pRequest.UserSession.UserRoleIndex)];
157
- if (!tmpRoleAuthorizer)
158
- {
159
- // Fallback to default definition, if present
160
- tmpRoleAuthorizer = pRequest.DAL.schemaFull.authorizer['__DefaultAPISecurity'];
161
- }
162
-
163
- // Authorizing Endpoint
164
- //console.log(pRequestHash + ' >>> '+pRequest.DAL.getRoleName(pRequest.UserSession.UserRoleIndex)+' - '+pRequest.UserSession.UserRoleIndex+' Authorization Configuration: '+JSON.stringify(tmpRoleAuthorizer));
165
-
166
-
167
- if ((typeof(tmpRoleAuthorizer) === 'object') && tmpRoleAuthorizer.hasOwnProperty(pRequestHash))
168
- {
169
- // Authorizing Endpoint
170
- //console.log(' >>> Authorizing Endpoint: '+JSON.stringify(tmpRoleAuthorizer));
171
- // If there is an authorizer collection in the DAL and it has this request hash as a property in it, execute the authorizer(s)
172
- if (typeof(tmpRoleAuthorizer[pRequestHash]) === 'string')
173
- {
174
- // Execute the single authorizer
175
- authorize(tmpRoleAuthorizer[pRequestHash], pRequest, fComplete);
176
- }
177
- else
178
- {
179
- // Execute every authorizer in the array
180
- libAsync.eachSeries(tmpRoleAuthorizer[pRequestHash],
181
- function(pAuthorizerHash, fCallback)
182
- {
183
- authorize(pAuthorizerHash, pRequest, fCallback);
184
- },
185
- fComplete);
186
- }
187
- }
188
- else
189
- {
190
- fComplete();
191
- }
192
- }
193
-
194
-
195
- /**
196
- * Container Object for our Factory Pattern
197
- */
198
- var tmpNewMeadowAuthorizer = (
199
- {
200
- setAuthorizer: setAuthorizer,
201
- getAuthorizer: getAuthorizer,
202
- authorize: authorize,
203
- authorizeRequest: authorizeRequest,
204
-
205
- new: createNew
206
- });
207
-
208
- return tmpNewMeadowAuthorizer;
209
- }
210
-
211
- return createNew();
212
- };
213
-
214
- module.exports = new MeadowAuthorizers();
@@ -1,170 +0,0 @@
1
- /**
2
- * The Meadow Behavior Modification Object
3
- *
4
- * Provide a sane mechanism for overloading or injecting behaviors into request endpoints.
5
- *
6
- * @class MeadowBehaviorModifications
7
- * @constructor
8
- */
9
- var libUnderscore = require('underscore');
10
-
11
- var MeadowBehaviorModifications = function()
12
- {
13
- function createNew(pMeadow)
14
- {
15
- // If a valid fable object isn't passed in, return a constructor
16
- if ((typeof(pMeadow) !== 'object') || !('fable' in pMeadow))
17
- {
18
- return {new: createNew};
19
- }
20
-
21
- var libAsync = require('async');
22
-
23
- // An object to hold modifications to specific behaviors.
24
- var _BehaviorFunctions = {};
25
-
26
- // A set of objects to hold the specific templates and their compiled functions
27
- var _Templates = {};
28
- var _TemplateFunctions = {};
29
-
30
-
31
- /**
32
- * Set a specific behavior.
33
- *
34
- * The anatomy of a behavior function is as follows:
35
- *
36
- * var someBehavior = function(pRequest, fComplete)
37
- * {
38
- * // Do some stuff with pRequest...
39
- * if (pRequest.UserSession.UserRoleIndex < 5)
40
- * pRequest.Query.addFilter('Customer', pRequest.UserSession.IDCustomer);
41
- * return fComplete(false);
42
- * }
43
- *
44
- * It is important to note that the fComplete function expects false if no error, or a string message if there is one.
45
- */
46
- var setBehavior = function(pBehaviorHash, fBehavior)
47
- {
48
- _BehaviorFunctions[pBehaviorHash] = fBehavior;
49
- };
50
-
51
- /**
52
- * This method runs a behavior at a specific hash, and returns true.
53
- * Or it returns false if there was no behavior there.
54
- * Behaviors should expect their state to be in the pRequest object, per the example in setBehavior
55
- */
56
- var runBehavior = function(pBehaviorHash, pRequest, fComplete)
57
- {
58
- // Run an injected behavior (if it exists)
59
- if (_BehaviorFunctions.hasOwnProperty(pBehaviorHash) &&
60
- _BehaviorFunctions[pBehaviorHash])
61
- {
62
- //Array of functions. Aborts on first error.
63
- if (Array.isArray(_BehaviorFunctions[pBehaviorHash]))
64
- {
65
- libAsync.timesLimit(_BehaviorFunctions[pBehaviorHash].length, 1, function(idx, fNext)
66
- {
67
- _BehaviorFunctions[pBehaviorHash][idx](pRequest, fNext);
68
- },
69
- function complete(err)
70
- {
71
- return fComplete(err);
72
- });
73
- }
74
- else
75
- {
76
- //Single function
77
- return _BehaviorFunctions[pBehaviorHash](pRequest, fComplete);
78
- }
79
- }
80
- else
81
- {
82
- return fComplete(false);
83
- }
84
- };
85
-
86
-
87
- /**
88
- * Set a template.
89
- */
90
- var setTemplate = function(pTemplateHash, pTemplate)
91
- {
92
- // Store both the cached text as well as the function
93
- _Templates[pTemplateHash] = pTemplate;
94
- _TemplateFunctions[pTemplateHash] = libUnderscore.template(pTemplate);
95
- };
96
-
97
- /**
98
- * Get a template.
99
- */
100
- var getTemplate = function(pTemplateHash)
101
- {
102
- if (_Templates.hasOwnProperty(pTemplateHash))
103
- {
104
- return _Templates[pTemplateHash];
105
- }
106
- else
107
- {
108
- return false;
109
- }
110
- };
111
-
112
- /**
113
- * Get a template function.
114
- */
115
- var getTemplateFunction = function(pTemplateHash)
116
- {
117
- if (_TemplateFunctions.hasOwnProperty(pTemplateHash))
118
- {
119
- return _TemplateFunctions[pTemplateHash];
120
- }
121
- else
122
- {
123
- return false;
124
- }
125
- };
126
-
127
- /**
128
- * Process a template at a hash, and return the result.
129
- */
130
- var processTemplate = function(pTemplateHash, pTemplateData, pDefaultTemplate)
131
- {
132
- var tmpTemplateFunction = getTemplateFunction(pTemplateHash);
133
- var tmpTemplateData = (typeof(pTemplateData) === 'undefined') ? {} : pTemplateData;
134
-
135
- // This makes the function fairly laziliy loading.
136
- if (tmpTemplateFunction === false)
137
- {
138
- // If the template doesn't exist, try to use the passed-in default and set that as the template.
139
- // Otherwise make it empty.
140
- setTemplate(pTemplateHash, (typeof(pDefaultTemplate) === 'undefined') ? '' : pDefaultTemplate);
141
- tmpTemplateFunction = getTemplateFunction(pTemplateHash);
142
- }
143
-
144
- // Now process and return the underscore template.
145
- return tmpTemplateFunction(tmpTemplateData);
146
- };
147
-
148
- /**
149
- * Container Object for our Factory Pattern
150
- */
151
- var tmpNewMeadowBehaviorModifications = (
152
- {
153
- setBehavior: setBehavior,
154
- runBehavior: runBehavior,
155
-
156
- setTemplate: setTemplate,
157
- getTemplate: getTemplate,
158
- getTemplateFunction: getTemplateFunction,
159
- processTemplate: processTemplate,
160
-
161
- new: createNew
162
- });
163
-
164
- return tmpNewMeadowBehaviorModifications;
165
- }
166
-
167
- return createNew();
168
- };
169
-
170
- module.exports = new MeadowBehaviorModifications();
@@ -1,206 +0,0 @@
1
- /**
2
- * The Meadow Common Services Provider
3
- *
4
- * This class aims to provide anything that every request will need.
5
- *
6
- * @class MeadowCommonServices
7
- * @constructor
8
- */
9
- var MeadowCommonServices = function()
10
- {
11
- function createNew(pMeadow, pAuthenticationMode)
12
- {
13
- // If a valid fable object isn't passed in, return a constructor
14
- if ((typeof(pMeadow) !== 'object') || !('fable' in pMeadow))
15
- {
16
- return {new: createNew};
17
- }
18
-
19
- var _Meadow = pMeadow;
20
- const _AuthenticationMode = pAuthenticationMode;
21
- var _Log = _Meadow.fable.log;
22
-
23
- var libRestify = require('restify');
24
-
25
- /**
26
- * Send an Error Code and Error Message to the client, and log it as an error in the log files.
27
- *
28
- * @method sendCodedError
29
- */
30
- var sendCodedError = function(pDefaultMessage, pError, pRequest, pResponse, fNext)
31
- {
32
- var tmpErrorMessage = pDefaultMessage;
33
- var tmpErrorCode = 1;
34
- var tmpScope = null;
35
- var tmpParams = null;
36
- var tmpSessionID = null;
37
-
38
- if (typeof(pError) === 'object')
39
- {
40
- tmpErrorMessage = pError.Message;
41
- if (pError.Code)
42
- tmpErrorCode = pError.Code;
43
- }
44
- else if (typeof(pError) === 'string')
45
- {
46
- tmpErrorMessage += ' ' + pError;
47
- }
48
- if (pRequest.DAL)
49
- {
50
- tmpScope = pRequest.DAL.scope;
51
- }
52
- if (pRequest.params)
53
- {
54
- tmpParams = pRequest.params;
55
- }
56
- if (pRequest.UserSession)
57
- {
58
- tmpSessionID = pRequest.UserSession.SessionID;
59
- }
60
-
61
- _Log.warn('API Error: '+tmpErrorMessage, {SessionID: tmpSessionID, RequestID:pRequest.RequestUUID, RequestURL:pRequest.url, Scope: tmpScope, Parameters: tmpParams, Action:'APIError'}, pRequest);
62
- pResponse.send({Error:tmpErrorMessage, ErrorCode: tmpErrorCode});
63
-
64
- return fNext();
65
- };
66
-
67
-
68
- /**
69
- * Send an Error to the client, and log it as an error in the log files.
70
- *
71
- * @method sendError
72
- */
73
- var sendError = function(pMessage, pRequest, pResponse, fNext)
74
- {
75
- var tmpSessionID = null;
76
- if (pRequest.UserSession)
77
- {
78
- tmpSessionID = pRequest.UserSession.SessionID;
79
- }
80
-
81
- _Log.warn('API Error: '+pMessage, {SessionID: tmpSessionID, RequestID:pRequest.RequestUUID, RequestURL:pRequest.url, Action:'APIError'}, pRequest);
82
- pResponse.send({Error:pMessage});
83
-
84
- return fNext();
85
- };
86
-
87
-
88
- /**
89
- * Check that the user has an appropriate user level to use the current endpoint
90
- *
91
- * @method authorizeEndpoint
92
- */
93
- var authorizeEndpoint = function(pRequest, pResponse, fNext)
94
- {
95
- if (!pRequest.EndpointAuthenticated)
96
- {
97
- pRequest.CommonServices.log.warn('Unauthenticated user attempting to get a secured resource.', {RequestID:pRequest.RequestUUID}, pRequest);
98
- sendNotAuthorized('You must be authenticated to access this resource.', pRequest, pResponse, fNext);
99
- return false;
100
- }
101
-
102
- //Check if endpoint is being invoked programmatically, in which case
103
- // we bypass session authentication checks
104
- if (pRequest.EndpointInvoked)
105
- {
106
- return true;
107
- }
108
-
109
- // Check that the user has a valid ID.
110
- if (_AuthenticationMode !== 'Disabled')
111
- {
112
- //TODO: do we need this code anymore?
113
- const tmpIDUser = pRequest.UserSession.UserID;
114
- if (tmpIDUser < 1)
115
- {
116
- _Log.warn('Invalid session when attempting to get a secured resource - IDUser is not valid.', {SessionID:pRequest.UserSession.SessionID, RequestID:pRequest.RequestUUID, RequestURL:pRequest.url, Action:'APISecurity'}, pRequest);
117
- sendNotAuthorized('You must be authenticated to access this resource.', pRequest, pResponse, fNext);
118
- return false;
119
- }
120
-
121
- // Check that the authentication level is valid.
122
- if (pRequest.UserSession.UserRoleIndex < pRequest.EndpointAuthorizationRequirement)
123
- {
124
- _Log.warn('Invalid permission level when attempting to get a secured resource.', {SessionID:pRequest.UserSession.SessionID, RequestID:pRequest.RequestUUID, RequestURL:pRequest.url, Action:'APISecurity', RequiredUserLevel:pRequest.EndpointAuthorizationRequirement, ActualUserLevel:pRequest.UserSession.UserRoleIndex}, pRequest);
125
- // TODO: Send the proper http status code
126
- sendNotAuthorized('You must be appropriately authenticated to access this resource.', pRequest, pResponse, fNext);
127
- return false;
128
- }
129
- }
130
-
131
- return true;
132
- };
133
-
134
-
135
- /**
136
- * Send a not authorized response to the client, and log it in the log files.
137
- *
138
- * @method sendNotAuthorized
139
- */
140
- var sendNotAuthorized = function(pMessage, pRequest, pResponse, fNext)
141
- {
142
- // TODO: Use the proper http code
143
- _Log.trace('API Unauthorized Attempt: '+pMessage, {SessionID:pRequest.UserSession.SessionID, RequestID:pRequest.RequestUUID, RequestURL:pRequest.url, Action:'APIUnauthorized'}, pRequest);
144
-
145
- //cause a delay to mitigate DoS type attacks against endpoints
146
- setTimeout(function()
147
- {
148
- pResponse.send({Error:pMessage});
149
-
150
- return fNext();
151
- }, (_Meadow.fable.settings.UnauthorizedRequestDelay ? _Meadow.fable.settings.UnauthorizedRequestDelay : 15000));
152
- };
153
-
154
-
155
- /**
156
- * Container Object for our Factory Pattern
157
- */
158
- var tmpNewMeadowCommonServices = (
159
- {
160
- authorizeEndpoint: authorizeEndpoint,
161
-
162
- sendCodedError: sendCodedError,
163
- sendError: sendError,
164
- sendNotAuthorized: sendNotAuthorized,
165
-
166
- // Restify body parser passed through, for any POST and PUT requests
167
- bodyParser: libRestify.plugins.bodyParser,
168
-
169
- new: createNew
170
- });
171
-
172
- // Turn the common services object into a first-class Fable object
173
- // addServices removed in fable 2.x
174
- if (typeof(_Meadow.fable.addServices) === 'function')
175
- {
176
- _Meadow.fable.addServices(tmpNewMeadowCommonServices);
177
- }
178
- else
179
- {
180
- // bring over addServices implementation from Fable 1.x for backward compatibility
181
- Object.defineProperty(tmpNewMeadowCommonServices, 'fable',
182
- {
183
- get: function() { return _Meadow.fable; },
184
- enumerable: false,
185
- });
186
-
187
- Object.defineProperty(tmpNewMeadowCommonServices, 'settings',
188
- {
189
- get: function() { return _Meadow.fable.settings; },
190
- enumerable: false,
191
- });
192
-
193
- Object.defineProperty(tmpNewMeadowCommonServices, 'log',
194
- {
195
- get: function() { return _Meadow.fable.log; },
196
- enumerable: false,
197
- });
198
- }
199
-
200
- return tmpNewMeadowCommonServices;
201
- }
202
-
203
- return createNew();
204
- };
205
-
206
- module.exports = new MeadowCommonServices();