Merge remote-tracking branch 'origin/master' into api-ratelimit-collab

Conflicts:
	plugins/c9.api/collab.js
pull/365/head
Tim Robinson 2016-10-06 00:32:54 +00:00
commit 9e2b79031e
6 zmienionych plików z 169 dodań i 8 usunięć

2
node_modules/c9/git.js wygenerowano vendored
Wyświetl plik

@ -1,7 +1,5 @@
"use strict";
require("amd-loader");
var Fs = require("fs");
var Path = require("path");
var exec = require("child_process").exec;

Wyświetl plik

@ -1,7 +1,7 @@
{
"name": "c9",
"description": "New Cloud9 Client",
"version": "3.1.3131",
"version": "3.1.3140",
"author": "Ajax.org B.V. <info@ajax.org>",
"private": true,
"main": "bin/c9",
@ -71,7 +71,7 @@
"c9.ide.language.javascript.infer": "#b9c2e4bdb8",
"c9.ide.language.jsonalyzer": "#a0549e14ff",
"c9.ide.language.codeintel": "#0fe92d6f46",
"c9.ide.collab": "#54aa1cbee0",
"c9.ide.collab": "#f60595d380",
"c9.ide.local": "#9169fec157",
"c9.ide.find": "#e632ecf4be",
"c9.ide.find.infiles": "#ad9ff74638",

Wyświetl plik

@ -196,12 +196,19 @@ define(function(require, exports, module) {
return "<" + tag + " " + plugin.toXmlAttributes(attrs) + (noclose ? ">" : " />");
};
function isMd5String(str) {
return /^[0-9a-f]{32}$/.test(str);
}
/**
* Returns the gravatar url for this user
* @param {Number} size the size of the image
*/
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/"
+ md5Email + "?s=" + size + "&d=" + (defaultImage || "retro");
};

Wyświetl plik

@ -9,6 +9,7 @@ require(["lib/architect/architect", "lib/chai/chai"], function (architect, chai)
expect.setupArchitectTest([
"plugins/c9.core/ext",
"plugins/c9.core/util",
"plugins/c9.ide.ui/lib_apf",
// Mock plugins
{
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() {
var normalizePath = util.normalizePath;
it('should handle home in workspaceDir', function() {

Wyświetl plik

@ -277,7 +277,7 @@ function plugin(options, imports, register) {
var vfsid = req.params.vfsid;
var scope = req.params.scope;
var path = req.params.path;
var entry = cache.get(vfsid);
if (!entry) {
var err = new error.PreconditionFailed("VFS connection does not exist");
@ -335,10 +335,34 @@ function plugin(options, imports, register) {
user.save && user.save(function() {});
}
}
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, {
"vfs.server": {
get section() { return section; }
get section() { return section; },
get handlePublish() { return handlePublish; }
}
});
}

Wyświetl plik

@ -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);
});
});
});
});