Open siliconalchemy opened 8 years ago
Unfortunately, for now, there is no way in sdk to display different user names when collaborating. But collaboration still works, since same user can have multiple ide instances. What kind of features do you want to add to collaboration?
Collaboration not really useful or possible if everything has the same name, is it planned to fix this or is it just inherent to how it's implemented with regards to c9 users? The first thing that jumps out at me is to add better chat notifications and some kind of conversations/threads.
I was wondering the same thing. I just want a local workspace with collaboration capabilities (different users) however documentation on this topic is pretty much non existent. I see that some authentication happens in c9.vfs.standalone plugin as it just passes default user config but have no idea how to modify it to use some database.
Hi,
Great to finally see this open sourced and working. I'm interested in using this with more than one user, and happy to contribute to the project. I'm thinking the best thing to do (even as a fall back) is to enable authentication against the a PAM module on linux hosts. This would mean that if all else fails, local users can have isntances of their own, defaulting to a folder called 'c9-projects' in their home directory?
Still cant handle multiple local user ? It would be great ..
You could write a plugin for it... currently the core code uses a connect middleware that does the basic-HTTP-Auth with a single user defined in config or at runtime...
This module could easily be replaced with using the https://github.com/http-auth/http-auth or https://github.com/ciaranj/connect-auth modules to do basic authentication against a simple htpasswd-based users/auths list. Something you can easily generate just using the htpasswd
Apache CLI tool.
Taking it a bit further (with a library like connect-auth), you could even interface with an LDAP or OAuth provider (e.g. Google or GitHub) and extend the existing login functionality in the core codebase with that.
Is anyone working on this? I'm also interested in this feature, and know something about connect middleware so I could potentially help if someone is trying to implement this. I don't know anything about the plugin framework for c9, but I'd be willing to contribute where I can.
Here is a basic patch that works for me. It provides basic collaboration support: specifically, allowing individual users to be identified by their gravatar, and their edits and selections and chat posts each being identified with their name.
It assumes that individual users are using different browsers, and provides no mechanism for logging in or out, or for the Share Workspace dialog, or anything else.
After applying the patch and restarting Cloud9, individual users must each be issued with a unique ID number (>= 1), and then must each set the following cookie in their browser on your development domain. e.g. If your development Cloud9 domain is http://www.mydomain.com:3131/, then they must each navigate there (or to the subdomain), open their browser developer tools console and enter the following line of code (amend with their unique ID, and according to their personal details):
User 1:
document.cookie = '__c9_uid=' + escape( JSON.stringify({id:1, fullname:"Tom Jones", name:"tom", email:"tom.jones@mydomain.com"})) + '; Domain=.mydomain.com; Max-Age=315360000'
User 2:
document.cookie = '__c9_uid=' + escape( JSON.stringify({id:2, fullname:"Andy Williams", name:"andy", email:"andy.williams@mydomain.com"})) + '; Domain=.mydomain.com; Max-Age=315360000'
This patch relies on the assumption that logged-in user details (id, name, email etc) are initially sent from the server to the browser at UI launch time, and thereafter the browser identifies the user back to the server in subsequent API calls. Any reasonable way of letting the server deduce different user details for different individual users would be sufficient. So this patch could easily be modified to use basic authentication to look up user details in a server-side data structure.
diff --git a/plugins/c9.vfs.standalone/standalone.js b/plugins/c9.vfs.standalone/standalone.js
index 73fbdcc..c69b67a 100644
--- a/plugins/c9.vfs.standalone/standalone.js
+++ b/plugins/c9.vfs.standalone/standalone.js
@@ -52,6 +52,29 @@ function plugin(options, imports, register) {
res.end();
});
+ // Example method for creating a per-user user object.
+ // This method simply unpacks the object from the __c9_uid cookie
+ // where it is assumed to have been already set (but if unset and unpacking fails
+ // the default user object will be returned).
+ //
+ // Example javascript to run in the browser for setting the __c9_uid cookie:
+ // document.cookie = '__c9_uid=' +
+ // escape( JSON.stringify(
+ // {id:<uid>, fullname:"<fullname>", name:"<name>", email:"<email address in lowercase>"}
+ // )) + '; Domain=<cookie domain>; MaxAge=315360000'
+ api.identifyUser = api.identifyUser || function(req) {
+ var user = extend({}, options.options.user);
+
+ if(req.cookies['__c9_uid']) {
+ try {
+ return extend(user, JSON.parse(unescape(req.cookies['__c9_uid'])));
+ } catch(e) {
+ }
+ }
+
+ return user;
+ };
+
api.get("/ide.html", {
params: {
workspacetype: {
@@ -96,6 +119,12 @@ function plugin(options, imports, register) {
var collab = options.collab && req.params.collab !== 0 && req.params.nocollab != 1;
var opts = extend({}, options);
+
+ // Clone options.options and options.options.extendOptions, into opts,
+ // so as not to overwrite the defaults when api.identifyUser() is called.
+ opts.options = extend({}, opts.options);
+ opts.options.extendOptions = extend({}, opts.options.extendOptions);
+
opts.options.collab = collab;
if (req.params.packed == 1)
opts.packed = opts.options.packed = true;
@@ -110,6 +139,8 @@ function plugin(options, imports, register) {
token: req.params.token
});
+ opts.options.extendOptions.user = opts.options.user = api.identifyUser(req);
+
opts.options.debug = req.params.debug !== undefined;
res.setHeader("Cache-Control", "no-cache, no-store");
res.render(__dirname + "/views/standalone.html.ejs", {
@@ -226,6 +257,7 @@ function plugin(options, imports, register) {
api.authenticate = api.authenticate || function() {
return function(req, res, next) {
req.user = extend({}, options.options.extendOptions.user);
+ req.user = api.identifyUser(req);
next();
};
};
@@ -255,11 +287,14 @@ function plugin(options, imports, register) {
api.updatConfig = api.updatConfig || function(opts, params) {
var id = params.token;
opts.accessToken = id || "token";
- var user = opts.extendOptions.user;
- user.id = id || -1;
- user.name = id ? "user" + id : "johndoe";
- user.email = id ? "user" + id + "@c9.io" : "johndoe@example.org";
- user.fullname = id ? "User " + id : "John Doe";
+
+ // Commented out so as not to overwrite 'user'.
+ // var user = opts.extendOptions.user;
+ // user.id = id || -1;
+ // user.name = id ? "user" + id : "johndoe";
+ // user.email = id ? "user" + id + "@c9.io" : "johndoe@example.org";
+ // user.fullname = id ? "User " + id : "John Doe";
+
opts.workspaceDir = params.w ? params.w : options.workspaceDir;
opts.projectName = basename(opts.workspaceDir);
if (!options._projects) {
@@ -280,6 +315,9 @@ function plugin(options, imports, register) {
authenticate: function() {
return function(req, res, next) {
req.user = extend({}, options.options.extendOptions.user);
+ // It's unknown when/whether this code path is followed,
+ // but extend to call api.identifyUser anyway.
+ req.user = api.identifyUser(req);
next();
};
}
Not work +struanb
This, please! :)
@struanb - that works, as a pretty decent hack-around
It seems not to work. The user names change for all users (probably due to the cookie), but there is still only one user in cloud9. What we did:
plugins/c9.vfs.standalone/standalone.js
scripts/makestandalone.sh
node server.js
@richarddewit What did you do to let it run?
Glad this is working for some of you (@richarddewit) but sorry it's not working for others (@josuelmm and @sagacitysite). Not sure why - we've been running it for some months without issues.
The only thing I can think of, is how are you launching the server?
We launch with:
node server.js --listen <ip> -p 3131 -w <path/to/c9projects> --auth c9user:<somesecret> --collab --packed
N.B. I recall --collab
is required to enable the collaboration features.
Please let me know if that helps!
Speaking for @sagacitysite, I can confirm this works. The option "--collab" is the key to get it working.
Thank you so much. This is really nice!
2017-08-15 18:30 GMT+02:00 Struan Bartlett notifications@github.com:
Glad this is working for some of you (@richarddewit https://github.com/richarddewit) but sorry it's not working for others ( @josuelmm https://github.com/josuelmm and @sagacitysite https://github.com/sagacitysite). Not sure why - we've been running it for some months without issues.
The only thing I can think of, is how are you launching the server?
We launch with:
node server.js --listen
-p 3131 -w <path/to/c9projects> --auth c9user: --collab --packed N.B. I recall --collab is required to enable the collaboration features.
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/c9/core/issues/241#issuecomment-322517851, or mute the thread https://github.com/notifications/unsubscribe-auth/ABoG8l5CLdtfFhBJsomOTNN5w2Ibh7n7ks5sYcehgaJpZM4HLnzS .
diff --git a/plugins/c9.vfs.standalone/standalone.js b/plugins/c9.vfs.standalone/standalone.js
index 48955e9e..45d503d3 100644
--- a/plugins/c9.vfs.standalone/standalone.js
+++ b/plugins/c9.vfs.standalone/standalone.js
@@ -112,6 +112,7 @@ function plugin(options, imports, register) {
api.updatConfig(opts.options, {
w: req.params.w,
+ ip: req.remoteAddress,
token: req.params.token
});
@@ -260,13 +261,14 @@ function plugin(options, imports, register) {
};
};
api.updatConfig = api.updatConfig || function(opts, params) {
- var id = params.token;
+ var id = params.ip;
+ //var id = params.token;
opts.accessToken = id || "token";
var user = opts.extendOptions.user;
user.id = id || -1;
- user.name = id ? "user" + id : "johndoe";
- user.email = id ? "user" + id + "@c9.io" : "johndoe@example.org";
- user.fullname = id ? "User " + id : "John Doe";
+ user.name = id ? "user@" + id : "johndoe";
+ user.email = id ? "user@" + id: "johndoe@example.org";
+ user.fullname = id ? "User@" + id : "John Doe";
opts.workspaceDir = params.w ? params.w : options.workspaceDir;
opts.projectName = basename(opts.workspaceDir);
if (!options._projects) {
Any update on this?
c-cloud9?
I changed @struanb's code to read username from jwt_token:
--- plugins/c9.vfs.standalone/standalone.orig.js
+++ plugins/c9.vfs.standalone/standalone.js
@@ -52,6 +52,37 @@ function plugin(options, imports, regist
res.end();
});
+ // Example method for creating a per-user user object.
+ // This method simply unpacks the object from the __c9_uid cookie
+ // where it is assumed to have been already set (but if unset and unpacking fails
+ // the default user object will be returned).
+ //
+ // Example javascript to run in the browser for setting the __c9_uid cookie:
+ // document.cookie = '__c9_uid=' +
+ // escape( JSON.stringify(
+ // {id:<uid>, fullname:"<fullname>", name:"<name>", email:"<email address in lowercase>"}
+ // )) + '; Domain=<cookie domain>; MaxAge=315360000'
+ api.identifyUser = api.identifyUser || function(req) {
+ var user = extend({}, options.options.user);
+
+ if(req.cookies['jwt_token']) {
+ try {
+ var jwt = JSON.parse(new Buffer(req.cookies['jwt_token'].split('.')[1], 'base64').toString('ascii'));
+ var juser = {
+ id: jwt.sub + '@' + jwt.origin,
+ name: jwt.sub,
+ fullname: jwt.sub,
+ email: jwt.sub + '@' + jwt.origin + '.com'
+ }
+ return extend(user, juser);
+ } catch(e) {
+ console.log(e);
+ }
+ }
+
+ return user;
+ };
+
api.get("/ide.html", {
params: {
workspacetype: {
@@ -106,6 +137,12 @@ function plugin(options, imports, regist
var collab = options.collab && req.params.collab !== 0 && req.params.nocollab != 1;
var opts = extend({}, options);
+
+ // Clone options.options and options.options.extendOptions, into opts,
+ // so as not to overwrite the defaults when api.identifyUser() is called.
+ opts.options = extend({}, opts.options);
+ opts.options.extendOptions = extend({}, opts.options.extendOptions);
+
opts.options.collab = collab;
if (req.params.packed == 1)
opts.packed = opts.options.packed = true;
@@ -120,6 +157,8 @@ function plugin(options, imports, regist
token: req.params.token
});
+ opts.options.extendOptions.user = opts.options.user = api.identifyUser(req);
+
opts.options.debug = req.params.debug !== undefined;
var workspaceSettings = getSettings(configName, options);
@@ -248,6 +287,7 @@ function plugin(options, imports, regist
api.authenticate = api.authenticate || function() {
return function(req, res, next) {
req.user = extend({}, options.options.extendOptions.user);
+ req.user = api.identifyUser(req);
next();
};
};
@@ -277,11 +317,14 @@ function plugin(options, imports, regist
api.updatConfig = api.updatConfig || function(opts, params) {
var id = params.token;
opts.accessToken = id || "token";
- var user = opts.extendOptions.user;
- user.id = id || -1;
- user.name = id ? "user" + id : "johndoe";
- user.email = id ? "user" + id + "@c9.io" : "johndoe@example.org";
- user.fullname = id ? "User " + id : "John Doe";
+
+ // Commented out so as not to overwrite 'user'.
+ // var user = opts.extendOptions.user;
+ // user.id = id || -1;
+ // user.name = id ? "user" + id : "johndoe";
+ // user.email = id ? "user" + id + "@c9.io" : "johndoe@example.org";
+ // user.fullname = id ? "User " + id : "John Doe";
+
opts.workspaceDir = params.w ? params.w : options.workspaceDir;
opts.projectName = basename(opts.workspaceDir);
if (!options._projects) {
@@ -302,6 +345,9 @@ function plugin(options, imports, regist
authenticate: function() {
return function(req, res, next) {
req.user = extend({}, options.options.extendOptions.user);
+ // It's unknown when/whether this code path is followed,
+ // but extend to call api.identifyUser anyway.
+ req.user = api.identifyUser(req);
next();
};
}
Then I use Caddy with http.jwt and http.login plugin to allow Github OAuth login. Caddy with two plugins: https://caddyserver.com/download/linux/amd64?plugins=http.jwt,http.login&license=personal&telemetry=off
Caddyfile
example.com:80 {
jwt {
path /
redirect /login
deny origin github
allow sub puteulanus
allow sub xhwdnjwedjxn3743
}
login {
github client_id={client_id},client_secret={client_secret}
#template login_template.html
success_url /
logout_url /
jwt_expiry 24h
cookie_expiry 2400h
}
proxy / 127.0.0.1:8080
}
To get client_id and client_secret, you should go https://github.com/settings/developers to create an OAuth App (callback url is example.com/login).
So when you open example.com, it will like:
Then
The user in allowed:
The user not in allowed:
User John Doe will be always there.
I've created patch that extend basic auth with user db (text file):
diff -Naur cloud9/configs/standalone.js cloud9.new/configs/standalone.js
--- cloud9/configs/standalone.js 2018-07-12 00:12:05.553231357 +0300
+++ cloud9.new/configs/standalone.js 2018-07-13 22:09:16.500293584 +0300
@@ -29,10 +29,12 @@
.boolean("packed")
.default("packed", config.packed)
.alias("a", "auth")
+ .alias("f", "afile")
.boolean("hosted")
.describe("hosted", "Use default config of the hosted version")
.default("hosted", false)
.describe("auth", "Basic Auth username:password")
+ .describe("afile", "Basic Auth credentials file. Each line format: id|login|password|email|Full Name")
.describe("collab", "Whether to enable collab.")
.default("collab", config.collab)
.describe("cache", "use cached version of cdn files")
@@ -70,6 +72,7 @@
var debug = argv.d;
var readonly = argv.readonly;
var startBridge = argv.b;
+ var afile = argv.afile;
config.port = port || argv.port;
config.host = host || argv.listen;
@@ -98,7 +101,7 @@
require("child_process").exec("tmux -L cloud91.9 kill-server", function() {});
var isLocalhost = host == "localhost" || host == "127.0.0.1";
- if (!/:/.test(argv.auth) && !isLocalhost) {
+ if (!/:/.test(argv.auth) && !isLocalhost && !afile) {
console.log("Authentication is required when not running on localhost.");
console.log("If you would like to expose this service to other hosts or the Internet");
console.log("at large, please specify -a user:pass to set a username and password");
@@ -108,12 +111,22 @@
host = config.host = "127.0.0.1";
}
var auth = (argv.auth + "").split(":");
- if (!auth[1] && !isLocalhost && !process.env.C9_HOSTNAME) {
+ if (!auth[1] && !isLocalhost && !process.env.C9_HOSTNAME && !afile) {
console.log("Warning: running Cloud9 without using HTTP authentication.");
console.log("Run using --listen localhost instead to only expose Cloud9 to localhost,");
console.log("or use -a username:password to setup HTTP authentication\n");
}
+ if (afile) {
+ var fs = require('fs');
+ afile = fs.readFileSync(afile).toString().split("\n");
+ var adict = {};
+ for (var l in afile) {
+ var line = afile[l].split('|');
+ adict[line[1]] = { id: line[0], password: line[2], email: line[3], fullname: line[4] };
+ }
+ }
+
var plugins = [
{
packagePath: "connect-architect/connect",
@@ -126,7 +139,8 @@
{
packagePath: "connect-architect/connect.basicauth",
username: auth[0],
- password: auth[1]
+ password: auth[1],
+ adict: adict
},
{
packagePath: "connect-architect/connect.static",
diff -Naur cloud9/node_modules/connect-architect/connect.basicauth/basicauth-plugin.js cloud9.new/node_modules/connect-architect/connect.basicauth/basicauth-plugin.js
--- cloud9/node_modules/connect-architect/connect.basicauth/basicauth-plugin.js 2018-07-12 00:12:05.569230844 +0300
+++ cloud9.new/node_modules/connect-architect/connect.basicauth/basicauth-plugin.js 2018-07-13 22:09:59.474922346 +0300
@@ -1,11 +1,19 @@
"use strict";
module.exports = function(options, imports, register) {
- if (!options.username || !options.password)
+ if ((!options.username || !options.password) && !options.adict)
return register();
+ var callback = function(user, pass){
+ if (!options.adict[user]) return false;
+ return options.adict[user].password == pass;
+ }
var connect = imports.connect;
- connect.useSetup(connect.getModule().basicAuth(options.username, options.password));
+ if (!options.adict){
+ connect.useSetup(connect.getModule().basicAuth(options.username, options.password));
+ } else {
+ connect.useSetup(connect.getModule().basicAuth(callback, 'Cloud9 Auth Realm'));
+ }
console.log("Using basic authentication");
But I don't know how to set cookie after successful auth for multi-user. It's my first time node.js coding. Help welcome.
anyone?
Would be amazing to have an official patch for this.
I realize this is old, but can anyone find how to remove John Doe? I have an auth method set up, but I can't find how to remove John Doe.
Try https://github.com/oznu/docker-cloud9 It's a preconfigured docker container. Multi-user really works.
Aravind Natchiappan notifications@github.com schrieb am Do., 8. Aug. 2019, 06:22:
I know that this is very old, but I can't seem to get the multi user authentication to work. I have created an authfile.txt and passed that through --auth, and while everyone can have their own logins, everyone still appears as John Doe. Can anyone help with this?
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/c9/core/issues/241?email_source=notifications&email_token=AANAN4XECMHEAA3AUYHCTS3QDONR3A5CNFSM4BZOPTJKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD32MGFQ#issuecomment-519357206, or mute the thread https://github.com/notifications/unsubscribe-auth/AANAN4Q5SSFUAZ7T3ZZK6YLQDONR3ANCNFSM4BZOPTJA .
docker run \ -v </path/to/config/>:/config \ -v </path/to/home/>:/workspace \ -p 80:80 \ -p 8000-8003:9000-9003 \ oznu/cloud9
Replace the <...> using your respective paths where you want config and workspace to be saved on the host.
Aravind Natchiappan notifications@github.com schrieb am Do., 8. Aug. 2019, 18:40:
Try https://github.com/oznu/docker-cloud9 It's a preconfigured docker container. Multi-user really works. Aravind Natchiappan notifications@github.com schrieb am Do., 8. Aug. 2019, 06:22: … <#m6843113903879343845> I know that this is very old, but I can't seem to get the multi user authentication to work. I have created an authfile.txt and passed that through --auth, and while everyone can have their own logins, everyone still appears as John Doe. Can anyone help with this? — You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub <#241 https://github.com/c9/core/issues/241?email_source=notifications&email_token=AANAN4XECMHEAA3AUYHCTS3QDONR3A5CNFSM4BZOPTJKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD32MGFQ#issuecomment-519357206>, or mute the thread https://github.com/notifications/unsubscribe-auth/AANAN4Q5SSFUAZ7T3ZZK6YLQDONR3ANCNFSM4BZOPTJA .
How do I install this through docker?
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/c9/core/issues/241?email_source=notifications&email_token=AANAN4V6O5RUXTYGAC4IPPTQDRD77A5CNFSM4BZOPTJKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD34GRWI#issuecomment-519596249, or mute the thread https://github.com/notifications/unsubscribe-auth/AANAN4SJ3HYKN24QPNVXIUDQDRD77ANCNFSM4BZOPTJA .
I changed @struanb's code to read username from jwt_token:
--- plugins/c9.vfs.standalone/standalone.orig.js +++ plugins/c9.vfs.standalone/standalone.js @@ -52,6 +52,37 @@ function plugin(options, imports, regist res.end(); }); + // Example method for creating a per-user user object. + // This method simply unpacks the object from the __c9_uid cookie + // where it is assumed to have been already set (but if unset and unpacking fails + // the default user object will be returned). + // + // Example javascript to run in the browser for setting the __c9_uid cookie: + // document.cookie = '__c9_uid=' + + // escape( JSON.stringify( + // {id:<uid>, fullname:"<fullname>", name:"<name>", email:"<email address in lowercase>"} + // )) + '; Domain=<cookie domain>; MaxAge=315360000' + api.identifyUser = api.identifyUser || function(req) { + var user = extend({}, options.options.user); + + if(req.cookies['jwt_token']) { + try { + var jwt = JSON.parse(new Buffer(req.cookies['jwt_token'].split('.')[1], 'base64').toString('ascii')); + var juser = { + id: jwt.sub + '@' + jwt.origin, + name: jwt.sub, + fullname: jwt.sub, + email: jwt.sub + '@' + jwt.origin + '.com' + } + return extend(user, juser); + } catch(e) { + console.log(e); + } + } + + return user; + }; + api.get("/ide.html", { params: { workspacetype: { @@ -106,6 +137,12 @@ function plugin(options, imports, regist var collab = options.collab && req.params.collab !== 0 && req.params.nocollab != 1; var opts = extend({}, options); + + // Clone options.options and options.options.extendOptions, into opts, + // so as not to overwrite the defaults when api.identifyUser() is called. + opts.options = extend({}, opts.options); + opts.options.extendOptions = extend({}, opts.options.extendOptions); + opts.options.collab = collab; if (req.params.packed == 1) opts.packed = opts.options.packed = true; @@ -120,6 +157,8 @@ function plugin(options, imports, regist token: req.params.token }); + opts.options.extendOptions.user = opts.options.user = api.identifyUser(req); + opts.options.debug = req.params.debug !== undefined; var workspaceSettings = getSettings(configName, options); @@ -248,6 +287,7 @@ function plugin(options, imports, regist api.authenticate = api.authenticate || function() { return function(req, res, next) { req.user = extend({}, options.options.extendOptions.user); + req.user = api.identifyUser(req); next(); }; }; @@ -277,11 +317,14 @@ function plugin(options, imports, regist api.updatConfig = api.updatConfig || function(opts, params) { var id = params.token; opts.accessToken = id || "token"; - var user = opts.extendOptions.user; - user.id = id || -1; - user.name = id ? "user" + id : "johndoe"; - user.email = id ? "user" + id + "@c9.io" : "johndoe@example.org"; - user.fullname = id ? "User " + id : "John Doe"; + + // Commented out so as not to overwrite 'user'. + // var user = opts.extendOptions.user; + // user.id = id || -1; + // user.name = id ? "user" + id : "johndoe"; + // user.email = id ? "user" + id + "@c9.io" : "johndoe@example.org"; + // user.fullname = id ? "User " + id : "John Doe"; + opts.workspaceDir = params.w ? params.w : options.workspaceDir; opts.projectName = basename(opts.workspaceDir); if (!options._projects) { @@ -302,6 +345,9 @@ function plugin(options, imports, regist authenticate: function() { return function(req, res, next) { req.user = extend({}, options.options.extendOptions.user); + // It's unknown when/whether this code path is followed, + // but extend to call api.identifyUser anyway. + req.user = api.identifyUser(req); next(); }; }
Then I use Caddy with http.jwt and http.login plugin to allow Github OAuth login. Caddy with two plugins: https://caddyserver.com/download/linux/amd64?plugins=http.jwt,http.login&license=personal&telemetry=off
Caddyfile
example.com:80 { jwt { path / redirect /login deny origin github allow sub puteulanus allow sub xhwdnjwedjxn3743 } login { github client_id={client_id},client_secret={client_secret} #template login_template.html success_url / logout_url / jwt_expiry 24h cookie_expiry 2400h } proxy / 127.0.0.1:8080 }
To get client_id and client_secret, you should go https://github.com/settings/developers to create an OAuth App (callback url is example.com/login).
So when you open example.com, it will like:
Then
The user in allowed:
The user not in allowed:
User John Doe will be always there.
Not work ... Caddy configuration missing
The supplied settings/standalone.js have a single user specified - John Doe, and if I login with different browsers (logged in to separate cloud9 accounts) all browsers still register as the single John Doe, so collaboration doesn't work. I've tried running separate instances on different ports with different settings (and different users specified in each setting) and I can see different user icons at the right side of the top bar, but in the Collaborate tab I only see a single user in Workspace Members which says read-only. I'd like to have a go at adding some collaboration features but can't unless I can get collaboration working!