Skip to content

Commit 3662107

Browse files
authored
Create sync model for webhook (#1736)
* This is used for Authors to track the internal processing status of each script. * Only shows up per Author i.e. nobody else and you *must* be logged in to view * Search might be incorrect atm... still tinkering with that part. * Hide some pre-existing GH items if no auth strategy present. * Eventually more is needed but this is a start. Applies to #1730 and a few related others in the past; Will eventually affect #430 by moving debugging to Author page instead of OUJS intervention. Auto-merge
1 parent dd2e7a8 commit 3662107

11 files changed

+460
-9
lines changed

controllers/scriptStorage.js

+18-2
Original file line numberDiff line numberDiff line change
@@ -2096,6 +2096,7 @@ exports.webhook = function (aReq, aRes) {
20962096
var reponame = null;
20972097
var repos = {};
20982098
var repo = null;
2099+
var update = null;
20992100

21002101
// Return if script storage is in read-only mode
21012102
if (process.env.READ_ONLY_SCRIPT_STORAGE === 'true') {
@@ -2154,6 +2155,7 @@ exports.webhook = function (aReq, aRes) {
21542155
break;
21552156
case 'push':
21562157
// Pushing a change
2158+
update = aReq.get('X-GitHub-Delivery');
21572159
break;
21582160
default:
21592161
aRes.status(400).send(); // Bad request
@@ -2193,6 +2195,11 @@ exports.webhook = function (aReq, aRes) {
21932195
return;
21942196
}
21952197

2198+
if (aUser.strategies.indexOf('github') <= -1) { // Don't rely on just `ghUsername`!
2199+
aRes.status(403).send(); // Reject due to lack of GitHub as Auth
2200+
return;
2201+
}
2202+
21962203
aRes.status(202).send(); // Close connection with Accepted but processing
21972204

21982205
// Gather the modified user scripts
@@ -2206,10 +2213,19 @@ exports.webhook = function (aReq, aRes) {
22062213

22072214
// Update modified scripts
22082215
repoManager = RepoManager.getManager(null, aUser, repos);
2209-
repoManager.loadScripts(true, function (aErr) {
2216+
2217+
repoManager.loadSyncs(update, function (aErr) {
22102218
if (aErr) {
2211-
console.error(aErr);
2219+
console.error(update, aErr);
2220+
return;
22122221
}
2222+
2223+
repoManager.loadScripts(update, function (aErr) {
2224+
if (aErr) {
2225+
console.error(update, aErr);
2226+
}
2227+
});
22132228
});
2229+
22142230
});
22152231
};

controllers/user.js

+116
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ var SPDX = require('spdx-license-ids');
2121
//--- Model inclusions
2222
var Comment = require('../models/comment').Comment;
2323
var Script = require('../models/script').Script;
24+
var Sync = require('../models/sync').Sync;
2425
var Strategy = require('../models/strategy').Strategy;
2526
var User = require('../models/user').User;
2627
var Discussion = require('../models/discussion').Discussion;
@@ -284,6 +285,7 @@ var getUserPageTasks = function (aOptions) {
284285
var user = null;
285286
var userScriptListCountQuery = null;
286287
var userCommentListCountQuery = null;
288+
var userSyncListCountQuery = null;
287289
var tasks = [];
288290

289291
// Shortcuts
@@ -299,6 +301,10 @@ var getUserPageTasks = function (aOptions) {
299301
userCommentListCountQuery = Comment.find({ _authorId: user._id, flagged: { $ne: true } });
300302
tasks.push(countTask(userCommentListCountQuery, aOptions, 'commentListCount'));
301303

304+
// userSyncListCountQuery
305+
userSyncListCountQuery = Sync.find({ _authorId: user._id });
306+
tasks.push(countTask(userSyncListCountQuery, aOptions, 'syncListCount'));
307+
302308
return tasks;
303309
};
304310

@@ -838,6 +844,100 @@ exports.userScriptListPage = function (aReq, aRes, aNext) {
838844
});
839845
};
840846

847+
exports.userSyncListPage = function (aReq, aRes, aNext) {
848+
//
849+
var username = aReq.params.username;
850+
851+
User.findOne({
852+
name: caseInsensitive(username)
853+
}, function (aErr, aUser) {
854+
function preRender() {
855+
// syncList
856+
options.syncList = _.map(options.syncList, modelParser.parseSync);
857+
858+
// Pagination
859+
options.paginationRendered = pagination.renderDefault(aReq);
860+
}
861+
862+
function render() {
863+
aRes.render('pages/userSyncListPage', options);
864+
}
865+
866+
function asyncComplete() {
867+
preRender();
868+
render();
869+
}
870+
871+
//
872+
var options = {};
873+
var authedUser = aReq.session.user;
874+
var user = null;
875+
var syncListQuery = null;
876+
var pagination = null;
877+
var tasks = [];
878+
879+
if (aErr || !aUser) {
880+
aNext();
881+
return;
882+
}
883+
884+
// Session
885+
options.authedUser = authedUser = modelParser.parseUser(authedUser);
886+
options.isMod = authedUser && authedUser.isMod;
887+
options.isAdmin = authedUser && authedUser.isAdmin;
888+
889+
// User
890+
user = options.user = modelParser.parseUser(aUser);
891+
options.isYou = authedUser && user && authedUser._id == user._id;
892+
893+
// If not you or not synacable auth strategy move along
894+
if (!options.isYou || !options.user.canSync) {
895+
aNext();
896+
return;
897+
}
898+
899+
// Page metadata
900+
pageMetadata(options, [user.name, 'Users']);
901+
options.isUserSyncListPage = true;
902+
903+
// Order dir
904+
orderDir(aReq, options, 'target', 'desc');
905+
orderDir(aReq, options, 'created', 'asc');
906+
orderDir(aReq, options, 'updated', 'asc');
907+
orderDir(aReq, options, 'response', 'desc');
908+
909+
// SyncListQuery
910+
syncListQuery = Sync.find();
911+
912+
// syncListQuery: author=user
913+
syncListQuery.find({ _authorId: user._id });
914+
915+
// syncListQuery: Defaults
916+
modelQuery.applySyncListQueryDefaults(syncListQuery, options, aReq);
917+
918+
// syncListQuery: Pagination
919+
pagination = options.pagination; // is set in modelQuery.apply___ListQueryDefaults
920+
921+
// SearchBar
922+
options.searchBarPlaceholder = 'Search Syncs from ' + user.name;
923+
options.searchBarFormAction = '';
924+
925+
//--- Tasks
926+
927+
// Pagination
928+
tasks.push(pagination.getCountTask(syncListQuery));
929+
930+
// syncListQuery
931+
tasks.push(execQueryTask(syncListQuery, options, 'syncList'));
932+
933+
// UserPage tasks
934+
tasks = tasks.concat(getUserPageTasks(options));
935+
936+
//--
937+
async.parallel(tasks, asyncComplete);
938+
});
939+
};
940+
841941
exports.userEditProfilePage = function (aReq, aRes, aNext) {
842942
var authedUser = aReq.session.user;
843943

@@ -1176,6 +1276,14 @@ exports.userGitHubRepoListPage = function (aReq, aRes, aNext) {
11761276
options.isAdmin = authedUser && authedUser.isAdmin;
11771277

11781278
// GitHub
1279+
if (!options.authedUser.hasGithub) {
1280+
statusCodePage(aReq, aRes, aNext, {
1281+
statusCode: 403,
1282+
statusMessage: 'You do not have GitHub as an auth strategy'
1283+
});
1284+
return;
1285+
}
1286+
11791287
options.githubUserId = githubUserId =
11801288
aReq.query.user || authedUser.ghUsername || authedUser.githubUserId();
11811289

@@ -1283,6 +1391,14 @@ exports.userGitHubRepoPage = function (aReq, aRes, aNext) {
12831391
options.isAdmin = authedUser && authedUser.isAdmin;
12841392

12851393
// GitHub
1394+
if (!options.authedUser.hasGithub) {
1395+
statusCodePage(aReq, aRes, aNext, {
1396+
statusCode: 403,
1397+
statusMessage: 'You do not have GitHub as an auth strategy'
1398+
});
1399+
return;
1400+
}
1401+
12861402
options.githubUserId = githubUserId =
12871403
aReq.query.user || authedUser.ghUsername || authedUser.githubUserId();
12881404

libs/modelParser.js

+29
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,7 @@ var parseUser = function (aUser) {
656656
user.userPageUrl = '/users/' + user.slugUrl;
657657
user.userCommentListPageUrl = user.userPageUrl + '/comments';
658658
user.userScriptListPageUrl = user.userPageUrl + '/scripts';
659+
user.userSyncListPageUrl = user.userPageUrl + '/syncs';
659660
user.userGitHubRepoListPageUrl = user.userPageUrl + '/github/repos';
660661
user.userGitHubRepoPageUrl = user.userPageUrl + '/github/repo';
661662
user.userGitHubImportPageUrl = user.userPageUrl + '/github/import';
@@ -668,6 +669,7 @@ var parseUser = function (aUser) {
668669
user.userPageUri = '/users/' + user.slugUri;
669670
user.userCommentListPageUri = user.userPageUri + '/comments';
670671
user.userScriptListPageUri = user.userPageUri + '/scripts';
672+
user.userSyncListPageUri = user.userPageUri + '/syncs';
671673
user.userGitHubRepoListPageUri = user.userPageUri + '/github/repos';
672674
user.userGitHubRepoPageUri = user.userPageUri + '/github/repo';
673675
user.userGitHubImportPageUri = user.userPageUri + '/github/import';
@@ -689,6 +691,8 @@ var parseUser = function (aUser) {
689691

690692
// Strategies
691693
user.userStrategies = user.strategies;
694+
user.hasGithub = user.strategies && user.strategies.indexOf('github') > -1; // NOTE: Watchpoint
695+
user.canSync = user.hasGithub;
692696

693697
// Dates
694698
parseDateProperty(user, '_since'); // Virtual
@@ -913,6 +917,31 @@ exports.renderComment = function (aComment) {
913917
aComment.contentRendered = renderMd(aComment.content);
914918
};
915919

920+
/**
921+
* Sync
922+
*/
923+
924+
//
925+
var parseSync = function (aSync) {
926+
var sync = null;
927+
928+
if (!aSync) {
929+
return;
930+
}
931+
sync = aSync.toObject ? aSync.toObject() : aSync;
932+
933+
sync.targetUrl = decodeURIComponent(sync.target);
934+
sync.targetUrlBasename = decodeURIComponent(sync.target.split('/').pop());
935+
936+
// Dates
937+
parseDateProperty(sync, 'created');
938+
parseDateProperty(sync, 'updated');
939+
940+
return sync;
941+
};
942+
parseModelFnMap.Sync = parseSync;
943+
exports.parseSync = parseSync;
944+
916945
/**
917946
* Category
918947
*/

libs/modelQuery.js

+36-1
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,14 @@ var parseCommentSearchQuery = function (aCommentListQuery, aQuery) {
151151
};
152152
exports.parseCommentSearchQuery = parseCommentSearchQuery;
153153

154+
var parseSyncSearchQuery = function (aSyncListQuery, aQuery) {
155+
parseModelListSearchQuery(aSyncListQuery, aQuery, {
156+
partialWordMatchFields: ['target'],
157+
fullWordMatchFields: []
158+
});
159+
};
160+
exports.parseSyncSearchQuery = parseSyncSearchQuery;
161+
154162
var parseUserSearchQuery = function (aUserListQuery, aQuery) {
155163
parseModelListSearchQuery(aUserListQuery, aQuery, {
156164
partialWordMatchFields: ['name'],
@@ -311,7 +319,13 @@ var applyModelListQueryDefaults = function (aModelListQuery, aOptions, aReq, aDe
311319
break;
312320
case 'size':
313321
aOptions.orderedBySize = true;
314-
// fallthrough
322+
break;
323+
case 'target':
324+
aOptions.orderedByTarget = true;
325+
break;
326+
case 'response':
327+
aOptions.orderedByResponse = true;
328+
// fallsthrough
315329
}
316330
});
317331

@@ -337,6 +351,15 @@ exports.applyCommentListQueryDefaults = function (aCommentListQuery, aOptions, a
337351
});
338352
};
339353

354+
exports.applySyncListQueryDefaults = function (aSyncListQuery, aOptions, aReq) {
355+
applyModelListQueryDefaults(aSyncListQuery, aOptions, aReq, {
356+
defaultSort: '-created',
357+
parseSearchQueryFn: parseSyncSearchQuery,
358+
searchBarPlaceholder: 'Search Syncs',
359+
filterFlaggedItems: false
360+
});
361+
};
362+
340363
exports.applyDiscussionListQueryDefaults = function (aDiscussionListQuery, aOptions, aReq) {
341364
applyModelListQueryDefaults(aDiscussionListQuery, aOptions, aReq, {
342365
defaultSort: '-updated -rating',
@@ -433,6 +456,18 @@ exports.applyRemovedItemCommentListQueryDefaults = function (aRemovedItemComment
433456
applyModelListQueryDefaults(aRemovedItemCommentListQuery, aOptions, aReq, removedItemCommentListQueryDefaults);
434457
};
435458

459+
var syncListQueryDefaults = {
460+
defaultSort: '-created',
461+
parseSearchQueryFn: parseSyncSearchQuery,
462+
searchBarPlaceholder: 'Search Syncs',
463+
searchBarFormAction: '/',
464+
filterFlaggedItems: false
465+
};
466+
exports.syncListQueryDefaults = syncListQueryDefaults;
467+
exports.applySyncListQueryDefaults = function (aSyncListQuery, aOptions, aReq) {
468+
applyModelListQueryDefaults(aSyncListQuery, aOptions, aReq, syncListQueryDefaults);
469+
};
470+
436471
var removedItemDiscussionListQueryDefaults = {
437472
defaultSort: '-removed',
438473
parseSearchQueryFn: parseRemovedItemSearchQuery,

0 commit comments

Comments
 (0)