cloudcms-server 0.9.262 → 0.9.265
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/locks/locks.js +49 -4
- package/locks/providers/memory.js +9 -6
- package/locks/providers/redis.js +1 -1
- package/middleware/authentication/adapters/session.js +18 -8
- package/middleware/authentication/authentication.js +28 -16
- package/middleware/authentication/authenticators/default.js +5 -2
- package/middleware/authentication/authenticators/session.js +5 -2
- package/middleware/authorization/authorization.js +11 -8
- package/middleware/awareness/providers/abstract-async.js +33 -26
- package/middleware/cloudcms/cloudcms.js +17 -15
- package/package.json +2 -2
- package/server/index.js +413 -403
- package/temp/clusterlock/index.js +3 -5
- package/temp/clusterlock/package.json +1 -1
- package/util/cloudcms.js +65 -86
package/locks/locks.js
CHANGED
|
@@ -25,6 +25,8 @@ var async = require("async");
|
|
|
25
25
|
*/
|
|
26
26
|
exports = module.exports = function()
|
|
27
27
|
{
|
|
28
|
+
var lockTimeoutMs = 120000; // two minutes
|
|
29
|
+
|
|
28
30
|
var provider = null;
|
|
29
31
|
|
|
30
32
|
var r = {};
|
|
@@ -72,12 +74,55 @@ exports = module.exports = function()
|
|
|
72
74
|
*/
|
|
73
75
|
var lock = r.lock = function(key, fn)
|
|
74
76
|
{
|
|
75
|
-
|
|
77
|
+
var __log = function(key, text) {
|
|
78
|
+
// var skip = false;
|
|
79
|
+
// if (key === "channels") { skip = true; }
|
|
80
|
+
// if (!skip) {
|
|
81
|
+
// console.log("[LOCK: " + key + "] " + text);
|
|
82
|
+
// }
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
__log(key, "request");
|
|
86
|
+
provider.lock(key, function(err, _releaseFn) {
|
|
87
|
+
|
|
88
|
+
// wrap the releaseFn with a wrapper that can only fire once
|
|
89
|
+
var releaseFn = function(_releaseFn)
|
|
90
|
+
{
|
|
91
|
+
var triggered = false;
|
|
92
|
+
return function() {
|
|
93
|
+
if (!triggered) {
|
|
94
|
+
triggered = true;
|
|
95
|
+
_releaseFn();
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
}(_releaseFn);
|
|
102
|
+
|
|
103
|
+
// after 120 seconds, we force release lock (if it hasn't already been released)
|
|
104
|
+
(function(key, releaseFn) {
|
|
105
|
+
setTimeout(function() {
|
|
106
|
+
var released = releaseFn();
|
|
107
|
+
if (released) {
|
|
108
|
+
__log(key, "timed out, released");
|
|
109
|
+
}
|
|
110
|
+
}, lockTimeoutMs);
|
|
111
|
+
})(key, releaseFn);
|
|
112
|
+
|
|
113
|
+
__log(key, "taken");
|
|
114
|
+
|
|
76
115
|
fn(err, function(afterReleaseCallback) {
|
|
116
|
+
__log(key, "pre-release");
|
|
77
117
|
|
|
78
|
-
releaseFn();
|
|
79
|
-
|
|
80
|
-
|
|
118
|
+
var released = releaseFn();
|
|
119
|
+
if (released) {
|
|
120
|
+
__log(key, "released");
|
|
121
|
+
} else {
|
|
122
|
+
__log(key, "not released, was previously released on timeout");
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (released && afterReleaseCallback)
|
|
81
126
|
{
|
|
82
127
|
afterReleaseCallback();
|
|
83
128
|
}
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
var
|
|
2
|
-
|
|
3
|
-
var ReadWriteLock = require("rwlock");
|
|
1
|
+
var AsyncLock = require('async-lock');
|
|
4
2
|
|
|
5
3
|
/**
|
|
6
4
|
* Simple in-memory lock service.
|
|
@@ -12,8 +10,8 @@ var ReadWriteLock = require("rwlock");
|
|
|
12
10
|
exports = module.exports = function(lockConfig)
|
|
13
11
|
{
|
|
14
12
|
var r = {};
|
|
15
|
-
|
|
16
|
-
var
|
|
13
|
+
|
|
14
|
+
var lock = new AsyncLock();
|
|
17
15
|
|
|
18
16
|
r.init = function(callback)
|
|
19
17
|
{
|
|
@@ -22,8 +20,13 @@ exports = module.exports = function(lockConfig)
|
|
|
22
20
|
|
|
23
21
|
r.lock = function(key, fn)
|
|
24
22
|
{
|
|
25
|
-
|
|
23
|
+
lock.acquire(key, function(releaseCallbackFn) {
|
|
26
24
|
fn(null, releaseCallbackFn);
|
|
25
|
+
}, function(err, ret) {
|
|
26
|
+
// lock was released
|
|
27
|
+
if (err) {
|
|
28
|
+
console.error("Memory Lock heard error: ", err, " return value: ", ret);
|
|
29
|
+
}
|
|
27
30
|
});
|
|
28
31
|
};
|
|
29
32
|
|
package/locks/providers/redis.js
CHANGED
|
@@ -13,7 +13,7 @@ exports = module.exports = function(locksConfig)
|
|
|
13
13
|
var redlock = null;
|
|
14
14
|
var client = null;
|
|
15
15
|
|
|
16
|
-
var logger = redisHelper.redisLogger("REDIS_LOCKS", "CLOUDCMS_LOCKS_", "
|
|
16
|
+
var logger = redisHelper.redisLogger("REDIS_LOCKS", "CLOUDCMS_LOCKS_", "debug")
|
|
17
17
|
|
|
18
18
|
var r = {};
|
|
19
19
|
|
|
@@ -9,15 +9,25 @@ class SessionAdapter extends AbstractAdapter
|
|
|
9
9
|
|
|
10
10
|
identify(req, callback)
|
|
11
11
|
{
|
|
12
|
-
if (req.session
|
|
12
|
+
if (req.session)
|
|
13
13
|
{
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
14
|
+
return req.session.reload(function() {
|
|
15
|
+
|
|
16
|
+
if (req.session._auth_profile)
|
|
17
|
+
{
|
|
18
|
+
var properties = {
|
|
19
|
+
"token": req.session._auth_profile.unique_name,
|
|
20
|
+
"trusted": true,
|
|
21
|
+
"profile": req.session._auth_profile
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
return callback(null, properties);
|
|
25
|
+
}
|
|
26
|
+
else
|
|
27
|
+
{
|
|
28
|
+
return super.identify(req, callback);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
21
31
|
}
|
|
22
32
|
|
|
23
33
|
return super.identify(req, callback);
|
|
@@ -436,15 +436,21 @@ exports = module.exports = function()
|
|
|
436
436
|
}
|
|
437
437
|
else
|
|
438
438
|
{
|
|
439
|
-
req.session.
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
439
|
+
return req.session.reload(function() {
|
|
440
|
+
|
|
441
|
+
req.session.registration_strategy_id = strategyId;
|
|
442
|
+
req.session.registration_user_object = userObject;
|
|
443
|
+
req.session.registration_user_identifier = userIdentifier;
|
|
444
|
+
req.session.registration_groups_array = groupsArray;
|
|
445
|
+
req.session.registration_mandatory_groups_array = mandatoryGroupsArray;
|
|
446
|
+
req.session.registration_token = info.token;
|
|
447
|
+
req.session.registration_refresh_token = info.refresh_token;
|
|
448
|
+
|
|
449
|
+
req.session.save(function() {
|
|
450
|
+
res.redirect(registrationRedirectUrl);
|
|
451
|
+
});
|
|
452
|
+
|
|
453
|
+
});
|
|
448
454
|
}
|
|
449
455
|
});
|
|
450
456
|
}
|
|
@@ -765,13 +771,19 @@ exports = module.exports = function()
|
|
|
765
771
|
}
|
|
766
772
|
else
|
|
767
773
|
{
|
|
768
|
-
req.session.
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
774
|
+
return req.session.reload(function() {
|
|
775
|
+
|
|
776
|
+
req.session.registration_strategy_id = strategyId;
|
|
777
|
+
req.session.registration_user_object = properties.user_object;
|
|
778
|
+
req.session.registration_user_identifier = properties.user_identifier;
|
|
779
|
+
req.session.registration_token = properties.token;
|
|
780
|
+
req.session.registration_refresh_token = properties.refresh_token;
|
|
781
|
+
|
|
782
|
+
req.session.save(function() {
|
|
783
|
+
res.redirect(registrationRedirect);
|
|
784
|
+
});
|
|
785
|
+
|
|
786
|
+
});
|
|
775
787
|
}
|
|
776
788
|
}
|
|
777
789
|
|
|
@@ -15,8 +15,11 @@ class DefaultAuthenticator extends AbstractAuthenticator
|
|
|
15
15
|
{
|
|
16
16
|
return req.logIn(gitanaUser, function() {
|
|
17
17
|
|
|
18
|
-
if (req.session
|
|
19
|
-
|
|
18
|
+
if (req.session)
|
|
19
|
+
{
|
|
20
|
+
return req.session.save(function() {
|
|
21
|
+
callback();
|
|
22
|
+
});
|
|
20
23
|
}
|
|
21
24
|
|
|
22
25
|
callback();
|
|
@@ -25,8 +25,11 @@ class SessionAuthenticator extends DefaultAuthenticator
|
|
|
25
25
|
|
|
26
26
|
req.user = gitanaUser;
|
|
27
27
|
|
|
28
|
-
if (req.session
|
|
29
|
-
|
|
28
|
+
if (req.session)
|
|
29
|
+
{
|
|
30
|
+
return req.session.save(function() {
|
|
31
|
+
callback();
|
|
32
|
+
});
|
|
30
33
|
}
|
|
31
34
|
|
|
32
35
|
callback();
|
|
@@ -41,17 +41,20 @@ exports = module.exports = function()
|
|
|
41
41
|
}
|
|
42
42
|
*/
|
|
43
43
|
|
|
44
|
-
if (pathRequiresAuthorization)
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
-
else {
|
|
49
|
-
res.redirect("/login");
|
|
50
|
-
}
|
|
44
|
+
if (!pathRequiresAuthorization)
|
|
45
|
+
{
|
|
46
|
+
return next();
|
|
51
47
|
}
|
|
52
|
-
|
|
48
|
+
|
|
49
|
+
if (req.session && req.session.requestContext)
|
|
50
|
+
{
|
|
53
51
|
next();
|
|
54
52
|
}
|
|
53
|
+
else
|
|
54
|
+
{
|
|
55
|
+
res.redirect("/login");
|
|
56
|
+
}
|
|
57
|
+
|
|
55
58
|
});
|
|
56
59
|
};
|
|
57
60
|
|
|
@@ -52,9 +52,14 @@ class AbstractAsyncProvider extends AbstractProvider
|
|
|
52
52
|
{
|
|
53
53
|
var self = this;
|
|
54
54
|
|
|
55
|
+
//console.log("a1");
|
|
55
56
|
self._lock("channels", function(err, releaseLockFn) {
|
|
57
|
+
// console.log("a2: ", err);
|
|
58
|
+
// console.log("a3: ", releaseLockFn);
|
|
56
59
|
self.doRegister(channelId, user, function(err) {
|
|
60
|
+
// console.log("a4 ", err);
|
|
57
61
|
callback(err);
|
|
62
|
+
// console.log("a5: ", releaseLockFn);
|
|
58
63
|
return releaseLockFn();
|
|
59
64
|
});
|
|
60
65
|
});
|
|
@@ -206,38 +211,40 @@ class AbstractAsyncProvider extends AbstractProvider
|
|
|
206
211
|
return done();
|
|
207
212
|
}
|
|
208
213
|
|
|
209
|
-
if (channel.users
|
|
214
|
+
if (!channel.users || Object.keys(channel.users).length === 0)
|
|
210
215
|
{
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
216
|
+
return done();
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// populate all of the user IDs that need to be removed
|
|
220
|
+
var userIdsToRemove = [];
|
|
221
|
+
for (var userId in channel.users)
|
|
222
|
+
{
|
|
223
|
+
var entry = channel.users[userId];
|
|
224
|
+
if (entry.time < beforeMs)
|
|
214
225
|
{
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
var expiredUserIds = expiredUserIdsByChannelId[channelId]
|
|
222
|
-
if (!expiredUserIds) {
|
|
223
|
-
expiredUserIds = expiredUserIdsByChannelId[channelId] = [];
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
expiredUserIds.push(userId);
|
|
226
|
+
updatedMembershipChannelIds.push(channelId);
|
|
227
|
+
userIdsToRemove.push(userId);
|
|
228
|
+
|
|
229
|
+
var expiredUserIds = expiredUserIdsByChannelId[channelId]
|
|
230
|
+
if (!expiredUserIds) {
|
|
231
|
+
expiredUserIds = expiredUserIdsByChannelId[channelId] = [];
|
|
227
232
|
}
|
|
233
|
+
|
|
234
|
+
expiredUserIds.push(userId);
|
|
228
235
|
}
|
|
229
|
-
|
|
230
|
-
// remove the user IDs
|
|
231
|
-
for (var i = 0; i < userIdsToRemove.length; i++)
|
|
232
|
-
{
|
|
233
|
-
delete channel.users[userIdsToRemove[i]];
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
self.writeChannel(channelId, channel, function() {
|
|
237
|
-
done();
|
|
238
|
-
});
|
|
239
236
|
}
|
|
240
237
|
|
|
238
|
+
// remove the user IDs
|
|
239
|
+
for (var i = 0; i < userIdsToRemove.length; i++)
|
|
240
|
+
{
|
|
241
|
+
delete channel.users[userIdsToRemove[i]];
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
self.writeChannel(channelId, channel, function() {
|
|
245
|
+
done();
|
|
246
|
+
});
|
|
247
|
+
|
|
241
248
|
});
|
|
242
249
|
};
|
|
243
250
|
}(channelId, updatedMembershipChannelIds, expiredUserIdsByChannelId, beforeMs);
|
|
@@ -441,7 +441,13 @@ exports = module.exports = function()
|
|
|
441
441
|
if (err) {
|
|
442
442
|
return callback(err);
|
|
443
443
|
}
|
|
444
|
-
|
|
444
|
+
|
|
445
|
+
var branch = CACHED_BRANCHES[cacheKey];
|
|
446
|
+
if (branch) {
|
|
447
|
+
callback(null, Chain(branch));
|
|
448
|
+
return releaseLockFn();
|
|
449
|
+
}
|
|
450
|
+
|
|
445
451
|
var loadFn = function(finished) {
|
|
446
452
|
|
|
447
453
|
Chain(repository).trap(function(e) {
|
|
@@ -468,23 +474,21 @@ exports = module.exports = function()
|
|
|
468
474
|
|
|
469
475
|
if (err) {
|
|
470
476
|
|
|
477
|
+
callback(err);
|
|
478
|
+
|
|
471
479
|
// release the lock
|
|
472
|
-
releaseLockFn();
|
|
473
|
-
|
|
474
|
-
// do the callback
|
|
475
|
-
return callback(err);
|
|
480
|
+
return releaseLockFn();
|
|
476
481
|
}
|
|
477
482
|
|
|
478
483
|
// success!
|
|
479
484
|
|
|
480
485
|
// store in cache
|
|
481
486
|
CACHED_BRANCHES[cacheKey] = branch;
|
|
482
|
-
|
|
487
|
+
|
|
488
|
+
callback(null, branch);
|
|
489
|
+
|
|
483
490
|
// release the lock
|
|
484
|
-
releaseLockFn();
|
|
485
|
-
|
|
486
|
-
// do the callback
|
|
487
|
-
return callback(null, branch);
|
|
491
|
+
return releaseLockFn();
|
|
488
492
|
});
|
|
489
493
|
}
|
|
490
494
|
|
|
@@ -1443,11 +1447,10 @@ exports = module.exports = function()
|
|
|
1443
1447
|
|
|
1444
1448
|
// the range requested (for streaming)
|
|
1445
1449
|
//var range = req.headers["range"];
|
|
1446
|
-
|
|
1450
|
+
|
|
1447
1451
|
cloudcmsUtil.preview(contentStore, gitana, repositoryId, branchId, nodeId, nodePath, attachmentId, locale, previewId, size, mimetype, forceReload, function(err, filePath, cacheInfo, releaseLock) {
|
|
1448
1452
|
|
|
1449
|
-
if (err)
|
|
1450
|
-
{
|
|
1453
|
+
if (err) {
|
|
1451
1454
|
req.log("Error on preview node: " + err.message + ", err: " + JSON.stringify(err));
|
|
1452
1455
|
}
|
|
1453
1456
|
|
|
@@ -1479,8 +1482,7 @@ exports = module.exports = function()
|
|
|
1479
1482
|
// UZI: file deleted by invalidate before this gets called
|
|
1480
1483
|
contentStore.sendFile(res, filePath, cacheInfo, function(err) {
|
|
1481
1484
|
|
|
1482
|
-
if (err)
|
|
1483
|
-
{
|
|
1485
|
+
if (err) {
|
|
1484
1486
|
util.handleSendFileError(req, res, filePath, cacheInfo, req.log, err);
|
|
1485
1487
|
}
|
|
1486
1488
|
|
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
},
|
|
7
7
|
"name": "cloudcms-server",
|
|
8
8
|
"description": "Cloud CMS Application Server Module",
|
|
9
|
-
"version": "0.9.
|
|
9
|
+
"version": "0.9.265",
|
|
10
10
|
"repository": {
|
|
11
11
|
"type": "git",
|
|
12
12
|
"url": "git://github.com/gitana/cloudcms-server.git"
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"alpaca": "^1.5.27",
|
|
21
21
|
"archiver": "^1.3.0",
|
|
22
22
|
"async": "^3.2.3",
|
|
23
|
+
"async-lock": "^1.3.2",
|
|
23
24
|
"aws-sdk": "^2.544.0",
|
|
24
25
|
"basic-auth": "^1.1.0",
|
|
25
26
|
"body-parser": "^1.19.0",
|
|
@@ -79,7 +80,6 @@
|
|
|
79
80
|
"request": "^2.88.0",
|
|
80
81
|
"request-param": "^1.0.1",
|
|
81
82
|
"response-time": "^2.3.2",
|
|
82
|
-
"rwlock": "^5.0.0",
|
|
83
83
|
"semver": "^5.7.1",
|
|
84
84
|
"serve-favicon": "^2.5.0",
|
|
85
85
|
"session-file-store": "^0.2.2",
|