mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-15 14:43:46 +01:00
Add in /clients and /client/:client_id status end points
This commit is contained in:
@@ -0,0 +1,37 @@
|
|||||||
|
Utils = require "./Utils"
|
||||||
|
async = require "async"
|
||||||
|
|
||||||
|
module.exports = HttpController =
|
||||||
|
# The code in this controller is hard to unit test because of a lot of
|
||||||
|
# dependencies on internal socket.io methods. It is not critical to the running
|
||||||
|
# of ShareLaTeX, and is only used for getting stats about connected clients,
|
||||||
|
# and for checking internal state in acceptance tests. The acceptances tests
|
||||||
|
# should provide appropriate coverage.
|
||||||
|
_getConnectedClientView: (ioClient, callback = (error, client) ->) ->
|
||||||
|
client_id = ioClient.id
|
||||||
|
Utils.getClientAttributes ioClient, [
|
||||||
|
"project_id", "user_id", "first_name", "last_name", "email", "connected_time"
|
||||||
|
], (error, {project_id, user_id, first_name, last_name, email, connected_time}) ->
|
||||||
|
return callback(error) if error?
|
||||||
|
client = {client_id, project_id, user_id, first_name, last_name, email, connected_time}
|
||||||
|
client.rooms = []
|
||||||
|
for name, joined of ioClient.manager.roomClients[client_id]
|
||||||
|
if joined and name != ""
|
||||||
|
client.rooms.push name.replace(/^\//, "") # Remove leading /
|
||||||
|
callback(null, client)
|
||||||
|
|
||||||
|
getConnectedClients: (req, res, next) ->
|
||||||
|
io = req.app.get("io")
|
||||||
|
ioClients = io.sockets.clients()
|
||||||
|
async.map ioClients, HttpController._getConnectedClientView, (error, clients) ->
|
||||||
|
return next(error) if error?
|
||||||
|
res.json clients
|
||||||
|
|
||||||
|
getConnectedClient: (req, res, next) ->
|
||||||
|
{client_id} = req.params
|
||||||
|
io = req.app.get("io")
|
||||||
|
ioClient = io.sockets.socket(client_id)
|
||||||
|
HttpController._getConnectedClientView ioClient, (error, client) ->
|
||||||
|
return next(error) if error?
|
||||||
|
res.json client
|
||||||
|
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
Metrics = require "metrics-sharelatex"
|
Metrics = require "metrics-sharelatex"
|
||||||
logger = require "logger-sharelatex"
|
logger = require "logger-sharelatex"
|
||||||
WebsocketController = require "./WebsocketController"
|
WebsocketController = require "./WebsocketController"
|
||||||
|
HttpController = require "./HttpController"
|
||||||
|
|
||||||
module.exports = Router =
|
module.exports = Router =
|
||||||
# We don't want to send raw errors back to the client, in case they
|
# We don't want to send raw errors back to the client, in case they
|
||||||
@@ -71,4 +72,8 @@ module.exports = Router =
|
|||||||
# Don't return raw error to prevent leaking server side info
|
# Don't return raw error to prevent leaking server side info
|
||||||
return callback {message: "Something went wrong"}
|
return callback {message: "Something went wrong"}
|
||||||
else
|
else
|
||||||
callback(null, args...)
|
callback(null, args...)
|
||||||
|
|
||||||
|
app.set("io", io)
|
||||||
|
app.get "/clients", HttpController.getConnectedClients
|
||||||
|
app.get "/clients/:client_id", HttpController.getConnectedClient
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
async = require "async"
|
||||||
|
|
||||||
|
module.exports = Utils =
|
||||||
|
getClientAttributes: (client, keys, callback = (error, attributes) ->) ->
|
||||||
|
attributes = {}
|
||||||
|
jobs = keys.map (key) ->
|
||||||
|
(callback) ->
|
||||||
|
client.get key, (error, value) ->
|
||||||
|
return callback(error) if error?
|
||||||
|
attributes[key] = value
|
||||||
|
callback()
|
||||||
|
async.series jobs, (error) ->
|
||||||
|
return callback(error) if error?
|
||||||
|
callback null, attributes
|
||||||
@@ -19,6 +19,8 @@ module.exports = WebsocketController =
|
|||||||
err = new Error("not authorized")
|
err = new Error("not authorized")
|
||||||
logger.error {err, project_id, user_id, client_id: client.id}, "user is not authorized to join project"
|
logger.error {err, project_id, user_id, client_id: client.id}, "user is not authorized to join project"
|
||||||
return callback(err)
|
return callback(err)
|
||||||
|
|
||||||
|
client.join project_id
|
||||||
|
|
||||||
client.set("privilege_level", privilegeLevel)
|
client.set("privilege_level", privilegeLevel)
|
||||||
client.set("user_id", user_id)
|
client.set("user_id", user_id)
|
||||||
@@ -67,5 +69,4 @@ module.exports = WebsocketController =
|
|||||||
_getClientData: (client, callback = (error, data) ->) ->
|
_getClientData: (client, callback = (error, data) ->) ->
|
||||||
client.get "user_id", (error, user_id) ->
|
client.get "user_id", (error, user_id) ->
|
||||||
client.get "project_id", (error, project_id) ->
|
client.get "project_id", (error, project_id) ->
|
||||||
callback null, {client_id: client.id, project_id, user_id}
|
callback null, {client_id: client.id, project_id, user_id}
|
||||||
|
|
||||||
@@ -8,6 +8,7 @@
|
|||||||
"url": "https://github.com/sharelatex/real-time-sharelatex.git"
|
"url": "https://github.com/sharelatex/real-time-sharelatex.git"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"async": "^0.9.0",
|
||||||
"connect-redis": "^2.1.0",
|
"connect-redis": "^2.1.0",
|
||||||
"express": "^4.10.1",
|
"express": "^4.10.1",
|
||||||
"express-session": "^1.9.1",
|
"express-session": "^1.9.1",
|
||||||
|
|||||||
@@ -41,6 +41,11 @@ describe "joinProject", ->
|
|||||||
it "should return the protocolVersion", ->
|
it "should return the protocolVersion", ->
|
||||||
@protocolVersion.should.equal 2
|
@protocolVersion.should.equal 2
|
||||||
|
|
||||||
|
it "should have joined the project room", (done) ->
|
||||||
|
RealTimeClient.getConnectedClient @client.socket.sessionid, (error, client) =>
|
||||||
|
expect(@project_id in client.rooms).to.equal true
|
||||||
|
done()
|
||||||
|
|
||||||
describe "when not authorized", ->
|
describe "when not authorized", ->
|
||||||
before (done) ->
|
before (done) ->
|
||||||
FixturesManager.setUpProject {
|
FixturesManager.setUpProject {
|
||||||
@@ -60,3 +65,8 @@ describe "joinProject", ->
|
|||||||
it "should return an error", ->
|
it "should return an error", ->
|
||||||
# We don't return specific errors
|
# We don't return specific errors
|
||||||
@error.message.should.equal "Something went wrong"
|
@error.message.should.equal "Something went wrong"
|
||||||
|
|
||||||
|
it "should not have joined the project room", (done) ->
|
||||||
|
RealTimeClient.getConnectedClient @client.socket.sessionid, (error, client) =>
|
||||||
|
expect(@project_id in client.rooms).to.equal false
|
||||||
|
done()
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ RealTimeClient = require "./helpers/RealTimeClient"
|
|||||||
|
|
||||||
describe "Session", ->
|
describe "Session", ->
|
||||||
describe "with an established session", ->
|
describe "with an established session", ->
|
||||||
beforeEach (done) ->
|
before (done) ->
|
||||||
@user_id = "mock-user-id"
|
@user_id = "mock-user-id"
|
||||||
RealTimeClient.setSession {
|
RealTimeClient.setSession {
|
||||||
user: { _id: @user_id }
|
user: { _id: @user_id }
|
||||||
@@ -22,9 +22,19 @@ describe "Session", ->
|
|||||||
expect(disconnected).to.equal false
|
expect(disconnected).to.equal false
|
||||||
done()
|
done()
|
||||||
, 500
|
, 500
|
||||||
|
|
||||||
|
it "should appear in the list of connected clients", (done) ->
|
||||||
|
RealTimeClient.getConnectedClients (error, clients) =>
|
||||||
|
included = false
|
||||||
|
for client in clients
|
||||||
|
if client.client_id == @client.socket.sessionid
|
||||||
|
included = true
|
||||||
|
break
|
||||||
|
expect(included).to.equal true
|
||||||
|
done()
|
||||||
|
|
||||||
describe "without an established session", ->
|
describe "without an established session", ->
|
||||||
beforeEach (done) ->
|
before (done) ->
|
||||||
RealTimeClient.unsetSession (error) =>
|
RealTimeClient.unsetSession (error) =>
|
||||||
throw error if error?
|
throw error if error?
|
||||||
@client = RealTimeClient.connect()
|
@client = RealTimeClient.connect()
|
||||||
@@ -34,8 +44,18 @@ describe "Session", ->
|
|||||||
@client.on "disconnect", () ->
|
@client.on "disconnect", () ->
|
||||||
done()
|
done()
|
||||||
|
|
||||||
|
it "not should appear in the list of connected clients", (done) ->
|
||||||
|
RealTimeClient.getConnectedClients (error, clients) =>
|
||||||
|
included = false
|
||||||
|
for client in clients
|
||||||
|
if client.client_id == @client.socket.sessionid
|
||||||
|
included = true
|
||||||
|
break
|
||||||
|
expect(included).to.equal false
|
||||||
|
done()
|
||||||
|
|
||||||
describe "without a valid user set on the session", ->
|
describe "without a valid user set on the session", ->
|
||||||
beforeEach (done) ->
|
before (done) ->
|
||||||
RealTimeClient.setSession {
|
RealTimeClient.setSession {
|
||||||
foo: "bar"
|
foo: "bar"
|
||||||
}, (error) =>
|
}, (error) =>
|
||||||
@@ -45,4 +65,14 @@ describe "Session", ->
|
|||||||
|
|
||||||
it "should get disconnected", (done) ->
|
it "should get disconnected", (done) ->
|
||||||
@client.on "disconnect", () ->
|
@client.on "disconnect", () ->
|
||||||
|
done()
|
||||||
|
|
||||||
|
it "not should appear in the list of connected clients", (done) ->
|
||||||
|
RealTimeClient.getConnectedClients (error, clients) =>
|
||||||
|
included = false
|
||||||
|
for client in clients
|
||||||
|
if client.client_id == @client.socket.sessionid
|
||||||
|
included = true
|
||||||
|
break
|
||||||
|
expect(included).to.equal false
|
||||||
done()
|
done()
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
XMLHttpRequest = require("../../libs/XMLHttpRequest").XMLHttpRequest
|
XMLHttpRequest = require("../../libs/XMLHttpRequest").XMLHttpRequest
|
||||||
io = require("socket.io-client")
|
io = require("socket.io-client")
|
||||||
|
|
||||||
|
request = require "request"
|
||||||
Settings = require "settings-sharelatex"
|
Settings = require "settings-sharelatex"
|
||||||
redis = require "redis-sharelatex"
|
redis = require "redis-sharelatex"
|
||||||
rclient = redis.createClient(Settings.redis.web)
|
rclient = redis.createClient(Settings.redis.web)
|
||||||
@@ -37,4 +38,18 @@ module.exports = Client =
|
|||||||
connect: (cookie) ->
|
connect: (cookie) ->
|
||||||
client = io.connect("http://localhost:3026", 'force new connection': true)
|
client = io.connect("http://localhost:3026", 'force new connection': true)
|
||||||
return client
|
return client
|
||||||
|
|
||||||
|
getConnectedClients: (callback = (error, clients) ->) ->
|
||||||
|
request.get {
|
||||||
|
url: "http://localhost:3026/clients"
|
||||||
|
json: true
|
||||||
|
}, (error, response, data) ->
|
||||||
|
callback error, data
|
||||||
|
|
||||||
|
getConnectedClient: (client_id, callback = (error, clients) ->) ->
|
||||||
|
request.get {
|
||||||
|
url: "http://localhost:3026/clients/#{client_id}"
|
||||||
|
json: true
|
||||||
|
}, (error, response, data) ->
|
||||||
|
callback error, data
|
||||||
|
|
||||||
|
|||||||
@@ -51,6 +51,9 @@ describe 'WebsocketController', ->
|
|||||||
.calledWith(@project_id, @user._id)
|
.calledWith(@project_id, @user._id)
|
||||||
.should.equal true
|
.should.equal true
|
||||||
|
|
||||||
|
it "should join the project room", ->
|
||||||
|
@client.join.calledWith(@project_id).should.equal true
|
||||||
|
|
||||||
it "should set the privilege level on the client", ->
|
it "should set the privilege level on the client", ->
|
||||||
@client.set.calledWith("privilege_level", @privilegeLevel).should.equal true
|
@client.set.calledWith("privilege_level", @privilegeLevel).should.equal true
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user