Skip to content
This repository was archived by the owner on Sep 2, 2021. It is now read-only.

Commit 0ada080

Browse files
ficristoficristo
authored andcommitted
Add initial support for github organizations
1 parent 8853010 commit 0ada080

File tree

9 files changed

+183
-79
lines changed

9 files changed

+183
-79
lines changed

app.js

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,16 @@ var express = require("express"),
3131
fs = require("fs"),
3232
http = require("http"),
3333
https = require("https"),
34+
url = require("url"),
3435
passport = require("passport"),
3536
GitHubStrategy = require("passport-github").Strategy,
3637
repository = require("./lib/repository"),
3738
routes = require("./lib/routes"),
3839
downloadData = require("./lib/downloadData"),
3940
logging = require("./lib/logging"),
4041
_ = require("lodash"),
41-
constants = require("constants");
42+
constants = require("constants"),
43+
request = require("request");
4244

4345
// Load cert and secret configuration
4446
var config = JSON.parse(fs.readFileSync(path.resolve(__dirname, "config/config.json"))),
@@ -119,7 +121,38 @@ passport.use(
119121
callbackURL: callbackScheme + config.hostname + ":" + callbackPort + "/auth/github/callback"
120122
},
121123
function (accessToken, refreshToken, profile, done) {
122-
done(null, "github:" + profile.username);
124+
request({
125+
method: 'GET',
126+
uri: url.parse(profile._json.organizations_url),
127+
qs: {
128+
access_token: accessToken
129+
},
130+
headers: {
131+
"User-Agent": "brackets-registry"
132+
},
133+
json: true,
134+
}, function (error, response, body) {
135+
if (error) {
136+
return done(error);
137+
}
138+
139+
// body must be an array, if not it is an error.
140+
if (!Array.isArray(body)) {
141+
return done(body);
142+
}
143+
144+
var orgs = body.map(function (item) {
145+
return {
146+
login: "github:" + item.login,
147+
id: item.id
148+
};
149+
});
150+
var user = {
151+
owner: "github:" + profile.username,
152+
orgs: orgs
153+
};
154+
done(null, user);
155+
});
123156
}
124157
)
125158
);

lib/registry_utils.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ exports.lastVersionDate = function () {
7171
*/
7272
exports.formatUserId = function () {
7373
var friendlyName;
74-
if (this.owner) {
75-
var nameComponents = this.owner.split(":");
74+
if (this.user && this.user.owner) {
75+
var nameComponents = this.user.owner.split(":");
7676
friendlyName = nameComponents[1];
7777
}
7878
return friendlyName;
@@ -86,8 +86,8 @@ exports.formatUserId = function () {
8686
*/
8787
exports.ownerLink = function () {
8888
var url;
89-
if (this.owner) {
90-
var nameComponents = this.owner.split(":");
89+
if (this.user && this.user.owner) {
90+
var nameComponents = this.user.owner.split(":");
9191
if (nameComponents[0] === "github") {
9292
url = "https://github.com/" + nameComponents[1];
9393
}

lib/repository.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ var validate = require("brackets-extensibility/package-validator").validate,
3131
semver = require("semver"),
3232
clone = require("clone"),
3333
logger = require("./logging"),
34+
user_utils = require("./user_utils"),
3435
_ = require("lodash");
3536

3637
/**
@@ -238,7 +239,7 @@ function addDownloadDataToPackage(name, newVersionDownloads, recentDownloads) {
238239
* @param {String} user identifier for the person submitting the file (e.g. "github:someusername")
239240
* @param {Function} callback (err, entry)
240241
*/
241-
function addPackage(packagePath, userID, callback) {
242+
function addPackage(packagePath, user, callback) {
242243
if (!validConfiguration(callback)) {
243244
return;
244245
}
@@ -276,7 +277,7 @@ function addPackage(packagePath, userID, callback) {
276277
entry = clone(registry[result.metadata.name]);
277278

278279
// Verify that the user is authorized to add this package
279-
if (entry.owner !== userID) {
280+
if (!user_utils.isOwner(entry, user)) {
280281
callback(new Error(Errors.NOT_AUTHORIZED), null);
281282
return;
282283
}
@@ -299,7 +300,7 @@ function addPackage(packagePath, userID, callback) {
299300
// add
300301
entry = {
301302
metadata: result.metadata,
302-
owner: userID,
303+
owner: user.owner,
303304
versions: [{
304305
version: result.metadata.version,
305306
published: new Date().toJSON()
@@ -371,14 +372,14 @@ function changePackageRequirements(entry, requirements) {
371372
* @param {string} name extension name
372373
* @param {string} userID owner or admin that is submitting the request
373374
*/
374-
function _packageManipulatorWrapper(func, name, userID) {
375+
function _packageManipulatorWrapper(func, name, user) {
375376
var callback = arguments[arguments.length - 1];
376377
var entry = registry[name];
377378
if (!entry) {
378379
callback(new Error(Errors.UNKNOWN_EXTENSION));
379380
return;
380381
}
381-
if (entry.owner !== userID && config.admins.indexOf(userID) === -1) {
382+
if (config.admins.indexOf(user.owner) === -1 && !user_utils.isOwner(entry, user)) {
382383
callback(new Error(Errors.NOT_AUTHORIZED));
383384
return;
384385
}

lib/routes.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
var passport = require("passport"),
2929
repository = require("./repository"),
3030
registry_utils = require("./registry_utils"),
31+
user_utils = require("./user_utils"),
3132
hbs = require("hbs"),
3233
fs = require("fs"),
3334
path = require("path"),
@@ -194,9 +195,9 @@ function _getRegistryList(user) {
194195
var registryList = registry_utils.sortRegistry(repository.getRegistry());
195196

196197
if (user) {
197-
var isAdmin = config.admins.indexOf(user) > -1;
198+
var isAdmin = config.admins.indexOf(user.owner) > -1;
198199
registryList = registryList.map(function (entry) {
199-
if (isAdmin || entry.owner === user) {
200+
if (isAdmin || user_utils.isOwner(entry, user)) {
200201
var newEntry = _.clone(entry);
201202
newEntry.canAdmin = true;
202203
return newEntry;
@@ -216,7 +217,7 @@ function _index(req, res) {
216217
var registryList = _getRegistryList(req.user);
217218

218219
_respond(req, res, "index", {
219-
user: registry_utils.formatUserId.call({owner: req.user}),
220+
user: registry_utils.formatUserId.call({user: req.user}),
220221
registry: registryList,
221222
repositoryBaseURL: config.repositoryBaseURL,
222223
helpURL: config.helpURL

lib/user_utils.js

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright (c) 2016 - present Adobe Systems Incorporated. All rights reserved.
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a
5+
* copy of this software and associated documentation files (the "Software"),
6+
* to deal in the Software without restriction, including without limitation
7+
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+
* and/or sell copies of the Software, and to permit persons to whom the
9+
* Software is furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in
12+
* all copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20+
* DEALINGS IN THE SOFTWARE.
21+
*
22+
*/
23+
24+
/*jslint vars: true, plusplus: true, nomen: true, node: true, indent: 4, maxerr: 50 */
25+
26+
"use strict";
27+
28+
function isUserOwner(entry, user) {
29+
if (entry.owner === user.owner) {
30+
return true;
31+
}
32+
33+
if (entry.owner === user.owner) {
34+
return true;
35+
}
36+
37+
return false;
38+
}
39+
40+
function isUserOrgOwner(entry, user) {
41+
var i;
42+
for (i = 0; i < user.orgs.length; i++) {
43+
if (entry.owner === user.orgs[i].login) {
44+
return true;
45+
}
46+
}
47+
return false;
48+
}
49+
50+
function isOwner(entry, user) {
51+
return isUserOwner(entry, user) || isUserOrgOwner(entry, user);
52+
}
53+
54+
function _createFakeUser(username) {
55+
return {
56+
owner: username,
57+
orgs: []
58+
};
59+
}
60+
61+
exports.isUserOwner = isUserOwner;
62+
exports.isUserOrgOwner = isUserOrgOwner;
63+
exports.isOwner = isOwner;
64+
exports._createFakeUser = _createFakeUser;

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
"filequeue": "~0.5.0",
3434
"bluebird": "~1.2.4",
3535
"lodash": "~2.4.1",
36-
"request": "~2.31.0",
36+
"request": "^2.74.0",
3737
"request-json": "~0.4.6",
3838
"temporary": "~0.0.8",
3939
"commander": "~2.1.0"

public/js/main.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,15 +89,15 @@ $(function () {
8989
$("body").on("click", "button.changeOwner", function (event) {
9090
var $target = $(event.target),
9191
name = $target.data("name");
92-
bootbox.prompt("Enter the GitHub username of the new owner for " + name, function (newOwner) {
92+
bootbox.prompt("Enter the GitHub username / organization of the new owner for " + name, function (newOwner) {
9393
if (newOwner === null) {
9494
return;
9595
}
9696
if (!newOwner) {
9797
displayStatus("info", "No new owner provided. No action taken.");
9898
return;
9999
}
100-
100+
101101
$.ajax("/package/" + name + "/changeOwner", {
102102
type: "POST",
103103
data: {

0 commit comments

Comments
 (0)