mirror of
https://github.com/YunoHost-Apps/rocketchat_ynh.git
synced 2024-09-03 20:16:25 +02:00
343 lines
36 KiB
JavaScript
343 lines
36 KiB
JavaScript
(function () {
|
|
|
|
/* Imports */
|
|
var Meteor = Package.meteor.Meteor;
|
|
var check = Package.check.check;
|
|
var Match = Package.check.Match;
|
|
var _ = Package.underscore._;
|
|
var MongoInternals = Package.mongo.MongoInternals;
|
|
var Mongo = Package.mongo.Mongo;
|
|
var DDP = Package['ddp-client'].DDP;
|
|
var DDPServer = Package['ddp-server'].DDPServer;
|
|
|
|
/* Package-scope variables */
|
|
var DDPCommon;
|
|
|
|
(function(){
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// packages/dispatch_run-as-user/packages/dispatch_run-as-user.js //
|
|
// //
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
(function () { // 1
|
|
// 2
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////// // 3
|
|
// // // 4
|
|
// packages/dispatch:run-as-user/lib/pre.1.0.3.js // // 5
|
|
// // // 6
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////// // 7
|
|
// // 8
|
|
// This code will go away in later versions of Meteor, this is just a "polyfill" // 1 // 9
|
|
// until the next release of Meteor maybe 1.0.3? // 2 // 10
|
|
// // 3 // 11
|
|
if (typeof DDPCommon === 'undefined') { // 4 // 12
|
|
DDPCommon = {}; // 5 // 13
|
|
// 6 // 14
|
|
DDPCommon.MethodInvocation = function (options) { // 7 // 15
|
|
var self = this; // 8 // 16
|
|
// 9 // 17
|
|
// true if we're running not the actual method, but a stub (that is, // 10 // 18
|
|
// if we're on a client (which may be a browser, or in the future a // 11 // 19
|
|
// server connecting to another server) and presently running a // 12 // 20
|
|
// simulation of a server-side method for latency compensation // 13 // 21
|
|
// purposes). not currently true except in a client such as a browser, // 14 // 22
|
|
// since there's usually no point in running stubs unless you have a // 15 // 23
|
|
// zero-latency connection to the user. // 16 // 24
|
|
// 17 // 25
|
|
/** // 18 // 26
|
|
* @summary Access inside a method invocation. Boolean value, true if this invocation is a stub. // 19 // 27
|
|
* @locus Anywhere // 20 // 28
|
|
* @name isSimulation // 21 // 29
|
|
* @memberOf MethodInvocation // 22 // 30
|
|
* @instance // 23 // 31
|
|
* @type {Boolean} // 24 // 32
|
|
*/ // 25 // 33
|
|
this.isSimulation = options.isSimulation; // 26 // 34
|
|
// 27 // 35
|
|
// call this function to allow other method invocations (from the // 28 // 36
|
|
// same client) to continue running without waiting for this one to // 29 // 37
|
|
// complete. // 30 // 38
|
|
this._unblock = options.unblock || function () {}; // 31 // 39
|
|
this._calledUnblock = false; // 32 // 40
|
|
// 33 // 41
|
|
// current user id // 34 // 42
|
|
// 35 // 43
|
|
/** // 36 // 44
|
|
* @summary The id of the user that made this method call, or `null` if no user was logged in. // 37 // 45
|
|
* @locus Anywhere // 38 // 46
|
|
* @name userId // 39 // 47
|
|
* @memberOf MethodInvocation // 40 // 48
|
|
* @instance // 41 // 49
|
|
*/ // 42 // 50
|
|
this.userId = options.userId; // 43 // 51
|
|
// 44 // 52
|
|
// sets current user id in all appropriate server contexts and // 45 // 53
|
|
// reruns subscriptions // 46 // 54
|
|
this._setUserId = options.setUserId || function () {}; // 47 // 55
|
|
// 48 // 56
|
|
// On the server, the connection this method call came in on. // 49 // 57
|
|
// 50 // 58
|
|
/** // 51 // 59
|
|
* @summary Access inside a method invocation. The [connection](#meteor_onconnection) that this method was received on. `null` if the method is not associated with a connection, eg. a server initiated method call.
|
|
* @locus Server // 53 // 61
|
|
* @name connection // 54 // 62
|
|
* @memberOf MethodInvocation // 55 // 63
|
|
* @instance // 56 // 64
|
|
*/ // 57 // 65
|
|
this.connection = options.connection; // 58 // 66
|
|
// 59 // 67
|
|
// The seed for randomStream value generation // 60 // 68
|
|
this.randomSeed = options.randomSeed; // 61 // 69
|
|
// 62 // 70
|
|
// This is set by RandomStream.get; and holds the random stream state // 63 // 71
|
|
this.randomStream = null; // 64 // 72
|
|
}; // 65 // 73
|
|
// 66 // 74
|
|
_.extend(DDPCommon.MethodInvocation.prototype, { // 67 // 75
|
|
/** // 68 // 76
|
|
* @summary Call inside a method invocation. Allow subsequent method from this client to begin running in a new fiber.
|
|
* @locus Server // 70 // 78
|
|
* @memberOf MethodInvocation // 71 // 79
|
|
* @instance // 72 // 80
|
|
*/ // 73 // 81
|
|
unblock: function () { // 74 // 82
|
|
var self = this; // 75 // 83
|
|
self._calledUnblock = true; // 76 // 84
|
|
self._unblock(); // 77 // 85
|
|
}, // 78 // 86
|
|
// 79 // 87
|
|
/** // 80 // 88
|
|
* @summary Set the logged in user. // 81 // 89
|
|
* @locus Server // 82 // 90
|
|
* @memberOf MethodInvocation // 83 // 91
|
|
* @instance // 84 // 92
|
|
* @param {String | null} userId The value that should be returned by `userId` on this connection. // 85 // 93
|
|
*/ // 86 // 94
|
|
setUserId: function (userId) { // 87 // 95
|
|
var self = this; // 88 // 96
|
|
if (self._calledUnblock) // 89 // 97
|
|
throw new Error("Can't call setUserId in a method after calling unblock"); // 90 // 98
|
|
self.userId = userId; // 91 // 99
|
|
// self._setUserId(userId); // 92 // 100
|
|
} // 93 // 101
|
|
// 94 // 102
|
|
}); // 95 // 103
|
|
} // 96 // 104
|
|
// 97 // 105
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////// // 106
|
|
// 107
|
|
}).call(this); // 108
|
|
// 109
|
|
// 110
|
|
// 111
|
|
// 112
|
|
// 113
|
|
// 114
|
|
(function () { // 115
|
|
// 116
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////// // 117
|
|
// // // 118
|
|
// packages/dispatch:run-as-user/lib/common.js // // 119
|
|
// // // 120
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////// // 121
|
|
// // 122
|
|
// This file adds the actual "Meteor.runAsUser" and "Meteor.isRestricted" api // 1 // 123
|
|
// // 2 // 124
|
|
// It's done by using a DDP method invocation, setting a user id and a // 3 // 125
|
|
// "isRestricted" flag on it. // 4 // 126
|
|
// // 5 // 127
|
|
// If run inside of an existing DDP invocation a nested version will be created. // 6 // 128
|
|
// 7 // 129
|
|
var restrictedMode = new Meteor.EnvironmentVariable(); // 8 // 130
|
|
// 9 // 131
|
|
/** // 10 // 132
|
|
* Returns true if inside a runAsUser user scope // 11 // 133
|
|
* @return {Boolean} True if in a runAsUser user scope // 12 // 134
|
|
*/ // 13 // 135
|
|
Meteor.isRestricted = function () { // 14 // 136
|
|
return !!restrictedMode.get(); // 15 // 137
|
|
}; // 16 // 138
|
|
// 17 // 139
|
|
/** // 18 // 140
|
|
* Run code restricted // 19 // 141
|
|
* @param {Function} f Code to run in restricted mode // 20 // 142
|
|
* @return {Any} Result of code running // 21 // 143
|
|
*/ // 22 // 144
|
|
Meteor.runRestricted = function(f) { // 23 // 145
|
|
if (Meteor.isRestricted()) { // 24 // 146
|
|
return f(); // 25 // 147
|
|
} else { // 26 // 148
|
|
return restrictedMode.withValue(true, f); // 27 // 149
|
|
} // 28 // 150
|
|
}; // 29 // 151
|
|
// 30 // 152
|
|
/** // 31 // 153
|
|
* Run code unrestricted // 32 // 154
|
|
* @param {Function} f Code to run in restricted mode // 33 // 155
|
|
* @return {Any} Result of code running // 34 // 156
|
|
*/ // 35 // 157
|
|
Meteor.runUnrestricted = function(f) { // 36 // 158
|
|
if (Meteor.isRestricted()) { // 37 // 159
|
|
return restrictedMode.withValue(false, f); // 38 // 160
|
|
} else { // 39 // 161
|
|
f(); // 40 // 162
|
|
} // 41 // 163
|
|
}; // 42 // 164
|
|
// 43 // 165
|
|
/** // 44 // 166
|
|
* Run as a user // 45 // 167
|
|
* @param {String} userId The id of user to run as // 46 // 168
|
|
* @param {Function} f Function to run as user // 47 // 169
|
|
* @return {Any} Returns function result // 48 // 170
|
|
*/ // 49 // 171
|
|
Meteor.runAsUser = function (userId, f) { // 50 // 172
|
|
var currentInvocation = DDP._CurrentInvocation.get(); // 51 // 173
|
|
// 52 // 174
|
|
// Create a new method invocation // 53 // 175
|
|
var invocation = new DDPCommon.MethodInvocation( // 54 // 176
|
|
(currentInvocation) ? currentInvocation : { // 55 // 177
|
|
connection: null // 56 // 178
|
|
} // 57 // 179
|
|
); // 58 // 180
|
|
// 59 // 181
|
|
// Now run as user on this invocation // 60 // 182
|
|
invocation.setUserId(userId); // 61 // 183
|
|
// 62 // 184
|
|
return DDP._CurrentInvocation.withValue(invocation, function () { // 63 // 185
|
|
return f.apply(invocation, [userId]); // 64 // 186
|
|
}); // 65 // 187
|
|
}; // 66 // 188
|
|
// 67 // 189
|
|
/** // 68 // 190
|
|
* Run as restricted user // 69 // 191
|
|
* @param {Function} f Function to run unrestricted // 70 // 192
|
|
* @return {Any} Returns function result // 71 // 193
|
|
*/ // 72 // 194
|
|
Meteor.runAsRestrictedUser = function(userId, f) { // 73 // 195
|
|
return Meteor.runRestricted(function() { // 74 // 196
|
|
return Meteor.runAsUser(userId, f); // 75 // 197
|
|
}); // 76 // 198
|
|
}; // 77 // 199
|
|
// 78 // 200
|
|
var adminMode = new Meteor.EnvironmentVariable(); // 79 // 201
|
|
// 80 // 202
|
|
/** // 81 // 203
|
|
* Check if code is running isside an invocation / method // 82 // 204
|
|
*/ // 83 // 205
|
|
Meteor.isAdmin = function() { // 84 // 206
|
|
return !!adminMode.get(); // 85 // 207
|
|
}; // 86 // 208
|
|
// 87 // 209
|
|
/** // 88 // 210
|
|
* Make the function run outside invocation // 89 // 211
|
|
*/ // 90 // 212
|
|
Meteor.runAsAdmin = function(f) { // 91 // 213
|
|
if (Meteor.isAdmin()) { // 92 // 214
|
|
return f(); // 93 // 215
|
|
} else { // 94 // 216
|
|
return adminMode.withValue(false, f); // 95 // 217
|
|
} // 96 // 218
|
|
}; // 97 // 219
|
|
// 98 // 220
|
|
/** // 99 // 221
|
|
* Make sure code runs outside an invocation on the // 100
|
|
* server // 101
|
|
*/ // 102
|
|
Meteor.runOutsideInvocation = function(f) { // 103
|
|
if (Meteor.isServer && DDP._CurrentInvocation.get()) { // 104
|
|
DDP._CurrentInvocation.withValue(null, f); // 105
|
|
} else { // 106
|
|
f(); // 107
|
|
} // 108
|
|
}; // 109
|
|
// 110
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////// // 233
|
|
// 234
|
|
}).call(this); // 235
|
|
// 236
|
|
// 237
|
|
// 238
|
|
// 239
|
|
// 240
|
|
// 241
|
|
(function () { // 242
|
|
// 243
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////// // 244
|
|
// // // 245
|
|
// packages/dispatch:run-as-user/lib/collection.overwrites.js // // 246
|
|
// // // 247
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////// // 248
|
|
// // 249
|
|
// This file overwrites the default metoer Mongo.Collection modifiers: "insert", // 1 // 250
|
|
// "update", "remove" // 2 // 251
|
|
// // 3 // 252
|
|
// The new methods are checking if Meteor is in "restricted" mode to apply // 4 // 253
|
|
// allow and deny rules if needed. // 5 // 254
|
|
// // 6 // 255
|
|
// This will allow us to run the modifiers inside of a "Meteor.runAsUser" with // 7 // 256
|
|
// security checks. // 8 // 257
|
|
_.each(['insert', 'update', 'remove'], function (method) { // 9 // 258
|
|
// 10 // 259
|
|
var _super = Mongo.Collection.prototype[method]; // 11 // 260
|
|
// 12 // 261
|
|
Mongo.Collection.prototype[method] = function ( /* arguments */ ) { // 13 // 262
|
|
var self = this; // 14 // 263
|
|
var args = _.toArray(arguments); // 15 // 264
|
|
// 16 // 265
|
|
// Check if this method is run in restricted mode and collection is // 17 // 266
|
|
// restricted. // 18 // 267
|
|
if (Meteor.isRestricted() && self._restricted) { // 19 // 268
|
|
// 20 // 269
|
|
var generatedId = null; // 21 // 270
|
|
if (method === 'insert' && !_.has(args[0], '_id')) { // 22 // 271
|
|
generatedId = self._makeNewID(); // 23 // 272
|
|
} // 24 // 273
|
|
// 25 // 274
|
|
// short circuit if there is no way it will pass. // 26 // 275
|
|
if (self._validators[method].allow.length === 0) { // 27 // 276
|
|
throw new Meteor.Error( // 28 // 277
|
|
403, 'Access denied. No allow validators set on restricted ' + // 29 // 278
|
|
'collection for method \'' + method + '\'.'); // 30 // 279
|
|
} // 31 // 280
|
|
// 32 // 281
|
|
var validatedMethodName = // 33 // 282
|
|
'_validated' + method.charAt(0).toUpperCase() + method.slice(1); // 34 // 283
|
|
args.unshift(Meteor.userId()); // 35 // 284
|
|
// 36 // 285
|
|
if (method === 'insert') { // 37 // 286
|
|
args.push(generatedId); // 38 // 287
|
|
// 39 // 288
|
|
self[validatedMethodName].apply(self, args); // 40 // 289
|
|
// xxx: for now we return the id since self._validatedInsert doesn't // 41 // 290
|
|
// yet return the new id // 42 // 291
|
|
return generatedId || args[0]._id; // 43 // 292
|
|
// 44 // 293
|
|
} // 45 // 294
|
|
// 46 // 295
|
|
return self[validatedMethodName].apply(self, args); // 47 // 296
|
|
// 48 // 297
|
|
} // 49 // 298
|
|
// 50 // 299
|
|
return _super.apply(self, args); // 51 // 300
|
|
}; // 52 // 301
|
|
// 53 // 302
|
|
}); // 54 // 303
|
|
// 55 // 304
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////// // 305
|
|
// 306
|
|
}).call(this); // 307
|
|
// 308
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
}).call(this);
|
|
|
|
|
|
/* Exports */
|
|
if (typeof Package === 'undefined') Package = {};
|
|
Package['dispatch:run-as-user'] = {};
|
|
|
|
})();
|
|
|
|
//# sourceMappingURL=dispatch_run-as-user.js.map
|