kopia lustrzana https://github.com/c9/core
Merge remote-tracking branch 'origin/master' into api-ratelimit-collab
Conflicts: plugins/c9.api/collab.jspull/365/head
commit
9e2b79031e
|
@ -1,7 +1,5 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
require("amd-loader");
|
|
||||||
|
|
||||||
var Fs = require("fs");
|
var Fs = require("fs");
|
||||||
var Path = require("path");
|
var Path = require("path");
|
||||||
var exec = require("child_process").exec;
|
var exec = require("child_process").exec;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "c9",
|
"name": "c9",
|
||||||
"description": "New Cloud9 Client",
|
"description": "New Cloud9 Client",
|
||||||
"version": "3.1.3131",
|
"version": "3.1.3140",
|
||||||
"author": "Ajax.org B.V. <info@ajax.org>",
|
"author": "Ajax.org B.V. <info@ajax.org>",
|
||||||
"private": true,
|
"private": true,
|
||||||
"main": "bin/c9",
|
"main": "bin/c9",
|
||||||
|
@ -71,7 +71,7 @@
|
||||||
"c9.ide.language.javascript.infer": "#b9c2e4bdb8",
|
"c9.ide.language.javascript.infer": "#b9c2e4bdb8",
|
||||||
"c9.ide.language.jsonalyzer": "#a0549e14ff",
|
"c9.ide.language.jsonalyzer": "#a0549e14ff",
|
||||||
"c9.ide.language.codeintel": "#0fe92d6f46",
|
"c9.ide.language.codeintel": "#0fe92d6f46",
|
||||||
"c9.ide.collab": "#54aa1cbee0",
|
"c9.ide.collab": "#f60595d380",
|
||||||
"c9.ide.local": "#9169fec157",
|
"c9.ide.local": "#9169fec157",
|
||||||
"c9.ide.find": "#e632ecf4be",
|
"c9.ide.find": "#e632ecf4be",
|
||||||
"c9.ide.find.infiles": "#ad9ff74638",
|
"c9.ide.find.infiles": "#ad9ff74638",
|
||||||
|
|
|
@ -196,12 +196,19 @@ define(function(require, exports, module) {
|
||||||
return "<" + tag + " " + plugin.toXmlAttributes(attrs) + (noclose ? ">" : " />");
|
return "<" + tag + " " + plugin.toXmlAttributes(attrs) + (noclose ? ">" : " />");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function isMd5String(str) {
|
||||||
|
return /^[0-9a-f]{32}$/.test(str);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the gravatar url for this user
|
* Returns the gravatar url for this user
|
||||||
* @param {Number} size the size of the image
|
* @param {Number} size the size of the image
|
||||||
*/
|
*/
|
||||||
plugin.getGravatarUrl = function getGravatarUrl(email, size, defaultImage) {
|
plugin.getGravatarUrl = function getGravatarUrl(email, size, defaultImage) {
|
||||||
var md5Email = apf.crypto.MD5.hex_md5((email || "").trim().toLowerCase());
|
var md5Email = email
|
||||||
|
if (!isMd5String(md5Email)) {
|
||||||
|
md5Email = apf.crypto.MD5.hex_md5((email || "").trim().toLowerCase());
|
||||||
|
}
|
||||||
return "https://secure.gravatar.com/avatar/"
|
return "https://secure.gravatar.com/avatar/"
|
||||||
+ md5Email + "?s=" + size + "&d=" + (defaultImage || "retro");
|
+ md5Email + "?s=" + size + "&d=" + (defaultImage || "retro");
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,6 +9,7 @@ require(["lib/architect/architect", "lib/chai/chai"], function (architect, chai)
|
||||||
expect.setupArchitectTest([
|
expect.setupArchitectTest([
|
||||||
"plugins/c9.core/ext",
|
"plugins/c9.core/ext",
|
||||||
"plugins/c9.core/util",
|
"plugins/c9.core/util",
|
||||||
|
"plugins/c9.ide.ui/lib_apf",
|
||||||
// Mock plugins
|
// Mock plugins
|
||||||
{
|
{
|
||||||
consumes: [],
|
consumes: [],
|
||||||
|
@ -32,6 +33,15 @@ require(["lib/architect/architect", "lib/chai/chai"], function (architect, chai)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("getGravatarUrl", function() {
|
||||||
|
it("Should hash a normal email", function() {
|
||||||
|
expect(util.getGravatarUrl("test@test.com", 32)).to.match(/^https:\/\/secure.gravatar.com\/avatar\/b642b4217b34b1e8d3bd915fc65c4452.*/);
|
||||||
|
});
|
||||||
|
it("Should use not re-hash an md5 passed in", function() {
|
||||||
|
expect(util.getGravatarUrl("b642b4217b34b1e8d3bd915fc65c4452", 32)).to.match(/^https:\/\/secure.gravatar.com\/avatar\/b642b4217b34b1e8d3bd915fc65c4452.*/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('normalizePath', function() {
|
describe('normalizePath', function() {
|
||||||
var normalizePath = util.normalizePath;
|
var normalizePath = util.normalizePath;
|
||||||
it('should handle home in workspaceDir', function() {
|
it('should handle home in workspaceDir', function() {
|
||||||
|
|
|
@ -336,9 +336,33 @@ function plugin(options, imports, register) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handlePublish(vfs, messageString) {
|
||||||
|
var message = JSON.parse(messageString);
|
||||||
|
switch (message.action) {
|
||||||
|
case "remove_member":
|
||||||
|
case "update_member_access":
|
||||||
|
handleProjectMemberAccessChange(vfs, message);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleProjectMemberAccessChange(vfs, message) {
|
||||||
|
if (vfs.uid !== message.body.uid) return;
|
||||||
|
|
||||||
|
console.log("Removing ", vfs.id, " for user ", vfs.uid, " project ", vfs.pid, " from the vfs connection cache");
|
||||||
|
|
||||||
|
// Remove next tick so client has time to recieve final "You've been removed" PubSub message.
|
||||||
|
setTimeout(function() {
|
||||||
|
cache.remove(vfs.id);
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
|
||||||
register(null, {
|
register(null, {
|
||||||
"vfs.server": {
|
"vfs.server": {
|
||||||
get section() { return section; }
|
get section() { return section; },
|
||||||
|
get handlePublish() { return handlePublish; }
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,122 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
"use strict";
|
||||||
|
"use server";
|
||||||
|
|
||||||
|
|
||||||
|
require("c9/inline-mocha")(module);
|
||||||
|
if (typeof define === "undefined") {
|
||||||
|
require("amd-loader");
|
||||||
|
}
|
||||||
|
|
||||||
|
var sinon = require("sinon");
|
||||||
|
var assert = require("assert");
|
||||||
|
var vfsServer = require("./vfs.server");
|
||||||
|
var mockDb = {};
|
||||||
|
var mockCache = {
|
||||||
|
remove: sinon.stub()
|
||||||
|
};
|
||||||
|
var mockApi = {
|
||||||
|
section: sinon.stub().returns({
|
||||||
|
registerType: sinon.stub(),
|
||||||
|
post: sinon.stub(),
|
||||||
|
get: sinon.stub(),
|
||||||
|
delete: sinon.stub(),
|
||||||
|
all: sinon.stub()
|
||||||
|
}),
|
||||||
|
use: sinon.stub(),
|
||||||
|
ensureAdmin: sinon.stub(),
|
||||||
|
get: sinon.stub(),
|
||||||
|
authenticate: sinon.stub()
|
||||||
|
};
|
||||||
|
var mockRender = {
|
||||||
|
setTemplatePath: sinon.stub()
|
||||||
|
};
|
||||||
|
var mockConnect = {
|
||||||
|
getModule: sinon.stub().returns({
|
||||||
|
compress: sinon.stub()
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
describe(__filename, function() {
|
||||||
|
var server;
|
||||||
|
beforeEach(function (done) {
|
||||||
|
vfsServer({testing: true}, {
|
||||||
|
"db": mockDb,
|
||||||
|
"vfs.cache": mockCache,
|
||||||
|
"api": mockApi,
|
||||||
|
"connect.render": mockRender,
|
||||||
|
"connect": mockConnect,
|
||||||
|
}, function (err, _server) {
|
||||||
|
if (err) return done(err);
|
||||||
|
server = _server["vfs.server"];
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("handlePublish", function() {
|
||||||
|
beforeEach(function() {
|
||||||
|
mockCache.remove = sinon.stub();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("remove_member", function() {
|
||||||
|
it("Should kill the removed members VFS connection", function (done) {
|
||||||
|
var vfs = {
|
||||||
|
id: "9c123",
|
||||||
|
uid: "123"
|
||||||
|
};
|
||||||
|
var message = JSON.stringify({
|
||||||
|
action: "remove_member",
|
||||||
|
body: {
|
||||||
|
uid: "123"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
server.handlePublish(vfs, message);
|
||||||
|
setTimeout(function() {
|
||||||
|
assert(mockCache.remove.calledWith(vfs.id));
|
||||||
|
done();
|
||||||
|
}, 150);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should not kill the other members VFS connection", function (done) {
|
||||||
|
var vfs = {
|
||||||
|
id: "9c123",
|
||||||
|
uid: "456"
|
||||||
|
};
|
||||||
|
var message = JSON.stringify({
|
||||||
|
action: "remove_member",
|
||||||
|
body: {
|
||||||
|
uid: "123"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
server.handlePublish(vfs, message);
|
||||||
|
setTimeout(function() {
|
||||||
|
assert.equal(mockCache.remove.callCount, 0);
|
||||||
|
done();
|
||||||
|
}, 150);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("update_member_access", function() {
|
||||||
|
it("Should kill the members VFS connection so they rejoin with the new access level", function (done) {
|
||||||
|
var vfs = {
|
||||||
|
id: "9c123",
|
||||||
|
uid: "123"
|
||||||
|
};
|
||||||
|
var message = JSON.stringify({
|
||||||
|
action: "update_member_access",
|
||||||
|
body: {
|
||||||
|
uid: "123"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
server.handlePublish(vfs, message);
|
||||||
|
setTimeout(function() {
|
||||||
|
assert(mockCache.remove.calledWith(vfs.id));
|
||||||
|
done();
|
||||||
|
}, 150);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
});
|
Ładowanie…
Reference in New Issue