Skip to content

Commit b35b061

Browse files
committed
Merge pull request #445 from CodeNow/SAN-706-post-instances-id-actions-copy
San 706 post instances id actions copy
2 parents 75e2b5f + 7a73c0d commit b35b061

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+4908
-99
lines changed

configs/.env

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ REDIS_NAMESPACE="runnable:api:"
3232
CAYLEY="http://localhost:64210"
3333
DNS_JOB_QUEUE_INTERVAL=200
3434
DNS_JOB_QUEUE_INTERVAL_DELETE=60000
35+
HELLO_RUNNABLE_GITHUB_ID=10224339
3536
SLACK_BOT_IMAGE="https://avatars0.githubusercontent.com/u/2335750?v=3&s=200"
3637
SLACK_BOT_USERNAME="runnabot"
3738
HIPCHAT_BOT_USERNAME="runnabot"

lib/express-app.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ app.use(passport.session());
4141
app.use(require('./routes/auth'));
4242
app.use(require('./routes/auth/github'));
4343
app.use(require('middlewares/auth').requireAuth);
44+
app.use(require('./routes/actions/analyze/index'));
4445
app.use(require('./routes/users'));
4546
app.use(require('./routes/builds'));
4647
app.use(require('./routes/contexts'));

lib/middlewares/auth.js

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,35 @@
11
'use strict';
22

33
var Boom = require('dat-middleware').Boom;
4+
var flow = require('middleware-flow');
5+
var keypather = require('keypather')();
6+
7+
function allowExceptions (req, res, next) {
8+
// unauthorized requests GET /instances for
9+
// fetching seed instances on getting-started homepage
10+
var ownerGithubId = parseInt(keypather.get(req.query, 'owner.github'));
11+
if (/^\/instances$/i.test(req.path) &&
12+
ownerGithubId === parseInt(process.env.HELLO_RUNNABLE_GITHUB_ID) &&
13+
req.method === 'GET') {
14+
next();
15+
}
16+
else {
17+
next(Boom.unauthorized('Unauthorized'));
18+
}
19+
}
20+
21+
function validate (req, res, next) {
22+
if (!req.sessionUser) {
23+
next(Boom.unauthorized('Unauthorized'));
24+
}
25+
else {
26+
next();
27+
}
28+
}
429

530
module.exports = {
6-
requireAuth: function (req, res, next) {
7-
if (!req.sessionUser) {
8-
next(Boom.unauthorized('Unauthorized'));
9-
}
10-
else {
11-
next();
12-
}
13-
}
14-
};
31+
requireAuth: flow.or(
32+
allowExceptions,
33+
validate
34+
)
35+
};

lib/middlewares/create-class-middleware.js

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
'use strict';
22

3-
var keypather = require('keypather')();
3+
var empty = require('101/is-empty');
4+
var exists = require('101/exists');
45
var fno = require('fn-object');
5-
var isString = require('101/is-string');
66
var isObject = require('101/is-object');
7-
var exists = require('101/exists');
7+
var isString = require('101/is-string');
8+
var keypather = require('keypather')();
89

910
module.exports = function (Model, key) {
1011
return new ClassMiddleware(key, Model);
@@ -89,10 +90,13 @@ function valIsFunction (obj) {
8990
}
9091

9192
function replacePlaceholders (req) {
93+
function handleStringArg (arg) {
94+
var value = (empty(arg)) ? arg : keypather.get(req, arg);
95+
return exists(value) ? value : arg;
96+
}
9297
return function (arg) {
9398
if (isString(arg)) {
94-
var value = keypather.get(req, arg);
95-
return exists(value) ? value : arg;
99+
return handleStringArg(arg);
96100
}
97101
else if (Array.isArray(arg)) {
98102
return arg.map(replacePlaceholders(req));

lib/middlewares/me.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,22 @@ module.exports = createMongooseMiddleware(User, 'sessionUser', {
5252
}
5353
};
5454
},
55+
isHelloRunnable: function (modelKey) {
56+
return function (req, res, next) {
57+
var model = keypather.get(req, modelKey);
58+
var modelGithubId = model.owner.github;
59+
var userGithubId = req.sessionUser.accounts.github.id;
60+
if (modelGithubId === process.env.HELLO_RUNNABLE_GITHUB_ID) {
61+
next();
62+
}
63+
else if (userGithubId === process.env.HELLO_RUNNABLE_GITHUB_ID) {
64+
next();
65+
}
66+
else {
67+
next(Boom.forbidden('Access denied (!owner)', { githubId: modelGithubId }));
68+
}
69+
};
70+
},
5571
isRegistered: function (req, res, next) {
5672
this.permission('registered')(req, res, next);
5773
},
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
'use strict';
2+
3+
var Boom = require('dat-middleware').Boom;
4+
var User = require('models/mongo/user');
5+
var createMongooseMiddleware = require('middlewares/create-mongoose-middleware');
6+
var keypather = require('keypather')();
7+
8+
module.exports = createMongooseMiddleware(User, 'sessionUser', {
9+
isHelloRunnable: function (modelKey) {
10+
return function (req, res, next) {
11+
var model = keypather.get(req, modelKey);
12+
var modelGithubId = model.owner.github;
13+
var userGithubId = req.sessionUser.accounts.github.id;
14+
if (modelGithubId === process.env.HELLO_RUNNABLE_GITHUB_ID) {
15+
next();
16+
}
17+
else if (userGithubId === process.env.HELLO_RUNNABLE_GITHUB_ID) {
18+
next();
19+
}
20+
else {
21+
next(Boom.forbidden('Access denied (!owner)', { githubId: modelGithubId }));
22+
}
23+
};
24+
}
25+
}).isHelloRunnable;

lib/middlewares/utils.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
'use strict';
22

3+
var empty = require('101/is-empty');
4+
var flow = require('middleware-flow');
5+
var inflect = require('i')();
36
var isObject = require('101/is-object');
47
var keypather = require('keypather')();
5-
var inflect = require('i')();
68
var mw = require('dat-middleware');
7-
var flow = require('middleware-flow');
89
var transformations = require('middlewares/transformations');
10+
911
var transformToInt = transformations.toInt;
1012
var useMin = transformations.useMin;
1113
var setDefault = transformations.setDefault;
@@ -44,15 +46,18 @@ var utils = module.exports = {
4446
replacePlaceholders: function (ctx, args) {
4547
return handle(args);
4648
function handle (thing) {
49+
function handleThingString (thing) {
50+
var val = (empty(thing)) ? thing : keypather.get(ctx, thing);
51+
return utils.exists(val) ? val : thing;
52+
}
4753
if (Array.isArray(thing)) {
4854
return thing.map(handle);
4955
}
5056
else if (isObject(thing)) {
5157
return handleObject(thing);
5258
}
5359
else if (typeof thing === 'string') {
54-
var val = keypather.get(ctx, thing);
55-
return utils.exists(val) ? val : thing;
60+
return handleThingString(thing);
5661
}
5762
else {
5863
return thing;

lib/middlewares/validations.js

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,27 @@
11
'use strict';
2+
3+
var equals = require('101/equals');
4+
var exists = require('101/exists');
5+
var findIndex = require('101/find-index');
6+
var isFunction = require('101/is-function');
7+
var keypather = require('keypather')();
28
var mw = require('dat-middleware');
39
var utils = require('middlewares/utils');
4-
var keypather = require('keypather')();
5-
var exists = require('101/exists');
6-
var equals = require('101/equals');
710

811
var validations = module.exports = {
12+
/**
13+
* @param valToFind Function || (int, string)
14+
*/
15+
isInArray: function (valToFind, message) {
16+
return function (arrayToSearch) {
17+
var isPopArray = validations.isPopulatedArray(arrayToSearch);
18+
if (isPopArray) { return isPopArray; }
19+
var predicate = (isFunction(valToFind)) ? valToFind : equals(valToFind);
20+
if(findIndex(arrayToSearch, predicate) === -1) {
21+
return mw.Boom.badRequest(message || 'value: "'+valToFind+'" not found in array');
22+
}
23+
};
24+
},
925
isObjectId: function (val) {
1026
if (!utils.isObjectId(val)) {
1127
return mw.Boom.badRequest('is not an ObjectId');
@@ -138,4 +154,4 @@ function isTypeOf(type) {
138154
return typeof val === type;
139155
}
140156
};
141-
}
157+
}

lib/models/apis/github.js

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,24 @@ Github.prototype.getRepo = function (repo, cb) {
8585
}, cb);
8686
};
8787

88+
Github.prototype.getRepoContent = function (repo, fullPath, cb) {
89+
debug('getRepoFile', formatArgs(arguments));
90+
debug('getting repo "'+repo+'" file :'+fullPath);
91+
var split = repo.split('/');
92+
var userKey = keyPrefix + (this.token ? this.tokenHash : 'runnable');
93+
var usernameKey = new redisTypes.String(userKey + ':getRepo:' + repo + ':content:' + fullPath);
94+
this._runQueryAgainstCache({
95+
query: this.repos.getContent,
96+
debug: 'this.repos.getContent',
97+
opts: {
98+
user: split[0],
99+
repo: split[1],
100+
path: fullPath
101+
},
102+
stringKey: usernameKey
103+
}, cb);
104+
};
105+
88106
Github.prototype.getDeployKeys = function (repo, cb) {
89107
debug('getDeployKeys', formatArgs(arguments));
90108
debug('getting repo keys for ' + repo);
@@ -258,10 +276,16 @@ Github.prototype._runQueryAgainstCache = function (options, cb) {
258276
runQuery(false, cb);
259277
}
260278

279+
/* jshint maxcomplexity:6 */
261280
function runQuery (sendConditionalHeader, cb) {
262281
debug('runQuery; query:', options.debug);
263282
// this is a shim so we can get a hold of the full github response
264-
self._httpSend = self.httpSend;
283+
//self._httpSend = self.httpSend;
284+
if (sendConditionalHeader) {
285+
cacheQueue[stringKey.key] = self.httpSend;
286+
} else {
287+
self._httpSend = self.httpSend;
288+
}
265289
self.httpSend = function () {
266290
var args = Array.prototype.slice.call(arguments);
267291
if (typeof args[2] === 'function') {
@@ -271,21 +295,29 @@ Github.prototype._runQueryAgainstCache = function (options, cb) {
271295
httpSendCb(err, res);
272296
});
273297
}
274-
self._httpSend.apply(self, args);
298+
if (sendConditionalHeader) {
299+
cacheQueue[stringKey.key].apply(self, args);
300+
} else {
301+
self._httpSend.apply(self, args);
302+
}
275303
};
276304
if (sendConditionalHeader) {
277305
if (!opts.headers) { opts.headers = {}; }
278306
opts.headers['if-none-match'] = keypather.get(cachedData, 'meta.etag');
279307
}
280308
query(opts, function (err, data) {
309+
if (sendConditionalHeader) {
310+
self.httpSend = cacheQueue[stringKey.key];
311+
} else {
312+
self.httpSend = self._httpSend;
313+
}
281314
if (err) {
282315
if (err.code && err.message) {
283316
return cb(Boom.create(err.code, err.message));
284317
} else {
285318
return cb(err);
286319
}
287320
}
288-
self.httpSend = self._httpSend;
289321

290322
if (sendConditionalHeader && /^304.*/.test(data.meta.status)) {
291323
cache304Response(stringKey, function () {
@@ -302,6 +334,7 @@ Github.prototype._runQueryAgainstCache = function (options, cb) {
302334
}
303335
});
304336
}
337+
/* jshint maxcomplexity:5 */
305338

306339
function cache304Response(key, cb) {
307340
var cc = parseCacheControl(keypather.get(githubResponse, 'headers.cache-control'));

lib/models/apis/runnable.js

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -126,27 +126,13 @@ Runnable.prototype.destroyInstances = function (instances, cb) {
126126
}, cb);
127127
};
128128

129-
Runnable.prototype.copyInstance = function (build, parentInstance, newProps, cb) {
129+
Runnable.prototype.copyInstance = function (sessionUser, build, parentInstance, body, cb) {
130130
debug('copyInstance', formatArgs(arguments));
131-
if (newProps === 'body') {
132-
// we are using all the stuff from parentInstance and letting it gen a new name
133-
newProps = {}; // just for sanity
134-
}
135-
var body = {
136-
parent: parentInstance.shortHash,
137-
env: parentInstance.env,
138-
owner: parentInstance.owner,
139-
build: build.toJSON()._id
140-
};
141-
// little bit of sanity checking for props
142-
var newName = newProps.name;
143-
if (newName && newName !== '') {
144-
body.name = newName;
145-
}
146-
var env = newProps.env;
147-
if (env && Array.isArray(env)) {
148-
body.env = env;
149-
}
131+
body.parent = parentInstance.shortHash;
132+
body.build = build.toJSON()._id;
133+
body.env = body.env || parentInstance.env;
134+
body.owner = body.owner || parentInstance.owner;
135+
150136
// Calling out to the API to fetch the project and env, then create a new Build
151137
this.createInstance(body, cb);
152138
};

0 commit comments

Comments
 (0)