diff --git a/actions/challengeRegistration.js b/actions/challengeRegistration.js index f50077b66..9424951ef 100644 --- a/actions/challengeRegistration.js +++ b/actions/challengeRegistration.js @@ -3,8 +3,8 @@ * * The APIs to register a challenge (studio category or software category) for the current logged-in user. * - * @version 1.7 - * @author ecnu_haozi, xjtufreeman, bugbuka, flytoj2ee, muzehyun + * @version 1.8 + * @author ecnu_haozi, xjtufreeman, bugbuka, flytoj2ee, muzehyun, GFalcon * * changes in 1.1: * Combine Challenge Registration API(BUGR-11058) @@ -27,6 +27,9 @@ * * changes in 1.7: * Avoid reliability info set if there is none for new user. + * + * changes in 1.8: + * Added the verification of the challenge's eligibility */ "use strict"; @@ -880,19 +883,31 @@ exports.registerChallenge = { } else { api.helper.checkUserActivated(connection.caller.handle, api, connection.dbConnectionMap, function (err, inactive) { var fail = err || inactive; - if (fail) cb(fail); - else api.dataAccess.executeQuery('check_challenge_exists', {challengeId: challengeId}, connection.dbConnectionMap, cb); + if (fail) { + cb(fail); + } else { + api.dataAccess.executeQuery('check_challenge_exists', {challengeId: challengeId}, connection.dbConnectionMap, cb); + } }, "You must activate your account in order to participate. Please check your e-mail in order to complete the activation process, or contact support@topcoder.com if you did not receive an e-mail."); } - }, function (result, cb) { - if (result.length > 0) { - if (result[0].is_studio) { - registerStudioChallengeAction(api, connection, next); - } else { - registerSoftwareChallengeAction(api, connection, next); - } - } else { + }, function(result, cb) { + // If the challenge is not found in the tcs_catalog:project table, + if (result.length === 0) { + // Do nothing, do not register cb(); + return; + } + var isStudio = result[0].isStudio !== 0; + api.challengeHelper.checkUserChallengeEligibility(connection, challengeId, function (err) { + cb(err, isStudio); + }); + }, function (isStudio, cb) { + if (_.isUndefined(isStudio)) { + cb(); + } else if (isStudio) { + registerStudioChallengeAction(api, connection, next); + } else { + registerSoftwareChallengeAction(api, connection, next); } } ], function (err) { diff --git a/actions/challenges.js b/actions/challenges.js index 0c40bbf2b..53266e7a8 100755 --- a/actions/challenges.js +++ b/actions/challenges.js @@ -1,9 +1,9 @@ /* * Copyright (C) 2013 - 2014 TopCoder Inc., All Rights Reserved. * - * @version 1.31 + * @version 1.32 * @author Sky_, mekanizumu, TCSASSEMBLER, freegod, Ghost_141, kurtrips, xjtufreeman, ecnu_haozi, hesibo, LazyChild, - * @author isv, muzehyun, bugbuka + * @author isv, muzehyun, bugbuka, GFalcon * @changes from 1.0 * merged with Member Registration API * changes in 1.1: @@ -79,9 +79,12 @@ * - Update challenge type filter. * Changes in 1.31: * - Remove screeningScorecardId and reviewScorecardId from search challenges api. + * Changes in 1.32: + * - validateChallenge function now checks if an user belongs to a group via + * user_group_xref for old challenges and by calling V3 API for new ones. */ "use strict"; -/*jslint stupid: true, unparam: true, continue: true */ +/*jslint stupid: true, unparam: true, continue: true, nomen: true */ require('datejs'); var fs = require('fs'); @@ -851,7 +854,7 @@ var addFilter = function (sql, filter, isMyChallenges, helper, caller) { * @since 1.10 */ function validateChallenge(api, connection, dbConnectionMap, challengeId, isStudio, callback) { - var error, sqlParams, helper = api.helper; + var error, sqlParams, helper = api.helper, userId = (connection.caller.userId || 0); async.waterfall([ function (cb) { error = helper.checkPositiveInteger(challengeId, 'challengeId') || @@ -862,31 +865,18 @@ function validateChallenge(api, connection, dbConnectionMap, challengeId, isStud } sqlParams = { challengeId: challengeId, - user_id: connection.caller.userId || 0 + user_id: userId }; - async.parallel({ - accessibility: function (cbx) { - api.dataAccess.executeQuery('check_user_challenge_accessibility', sqlParams, dbConnectionMap, cbx); - }, - exists: function (cbx) { - api.dataAccess.executeQuery('check_challenge_exists', sqlParams, dbConnectionMap, cbx); - } - }, cb); + api.dataAccess.executeQuery('check_challenge_exists', sqlParams, dbConnectionMap, cb); }, function (res, cb) { - if (res.exists.length === 0 || Boolean(res.exists[0].is_studio) !== isStudio) { + // If the record with this callengeId doesn't exist in 'project' table + // or there's a studio/software mismatch + if (res.length === 0 || Boolean(res[0].is_studio) !== isStudio) { cb(new NotFoundError("Challenge not found.")); return; } - var access = res.accessibility[0]; - if (access.is_private && !access.has_access && connection.caller.accessLevel !== "admin") { - if (connection.caller.accessLevel === "anon") { - cb(new UnauthorizedError()); - } else { - cb(new ForbiddenError()); - } - return; - } - cb(); + // Check the eligibility + api.challengeHelper.checkUserChallengeEligibility(connection, challengeId, cb); } ], callback); } diff --git a/db_scripts/test_eligibility.delete.sql b/db_scripts/test_eligibility.delete.sql new file mode 100644 index 000000000..5f77f6c44 --- /dev/null +++ b/db_scripts/test_eligibility.delete.sql @@ -0,0 +1,39 @@ +DATABASE common_oltp; + +DELETE FROM user_group_xref WHERE group_id > 3330000 AND group_id < 3330100; +DELETE FROM security_groups WHERE group_id > 3330000 AND group_id < 3330100; +DELETE FROM group_contest_eligibility WHERE contest_eligibility_id > 1110000 AND contest_eligibility_id < 1110100; +DELETE FROM contest_eligibility WHERE contest_eligibility_id > 1110000 AND contest_eligibility_id < 1110100; + +DATABASE informixoltp; + +-- UPDATE coder SET comp_country_code = NULL WHERE user_id = 132458; + +DATABASE tcs_catalog; + +DELETE FROM notification WHERE project_id > 1110000 AND project_id < 1110100; +DELETE FROM project_result WHERE project_id > 1110000 AND project_id < 1110100; +DELETE FROM project_user_audit WHERE project_id > 1110000 AND project_id < 1110100; +DELETE FROM component_inquiry WHERE project_id > 1110000 AND project_id < 1110100; +DELETE FROM resource_info WHERE resource_id IN (SELECT resource_id FROM resource WHERE project_id > 1110000 AND project_id < 1110100); +DELETE FROM resource WHERE project_id > 1110000 AND project_id < 1110100; + +DELETE FROM project_info WHERE project_id > 1110000 AND project_id < 1110100; +DELETE FROM comp_versions WHERE component_id = 3330333; +DELETE FROM comp_catalog WHERE component_id = 3330333; +DELETE FROM project_phase WHERE project_id > 1110000 AND project_id < 1110100; +DELETE FROM project WHERE project_id > 1110000 AND project_id < 1110100; + +DELETE FROM review_item_comment WHERE review_item_comment_id > 7770000 AND review_item_id < 7770100; +DELETE FROM review_item WHERE review_item_id > 5550000 AND review_item_id < 5550100; +DELETE FROM review WHERE review_id > 4440000 AND review_id < 4440100; +DELETE FROM scorecard_question WHERE scorecard_question_id = 3330333; +DELETE FROM scorecard_section WHERE scorecard_section_id = 3330333; +DELETE FROM scorecard_group WHERE scorecard_group_id = 3330333; +DELETE FROM scorecard WHERE scorecard_id = 3330333; +DELETE FROM submission WHERE submission_id > 2220000 AND submission_id < 2220100; +DELETE FROM prize WHERE project_id > 2220000 AND project_id < 2220100; +DELETE FROM upload WHERE project_id > 2220000 AND project_id < 2220100; +DELETE FROM resource WHERE project_id > 2220000 AND project_id < 2220100; +DELETE FROM project_phase WHERE project_id > 2220000 AND project_id < 2220100; +DELETE FROM project WHERE project_id > 2220000 AND project_id < 2220100; diff --git a/db_scripts/test_eligibility.insert.sql b/db_scripts/test_eligibility.insert.sql new file mode 100644 index 000000000..8bb746502 --- /dev/null +++ b/db_scripts/test_eligibility.insert.sql @@ -0,0 +1,219 @@ +DATABASE tcs_catalog; + +INSERT INTO project (project_id, project_status_id, project_category_id, create_user, create_date, modify_user, modify_date) + VALUES (2220001, 1, 14, "132456", CURRENT, "132456", CURRENT); +INSERT INTO project (project_id, project_status_id, project_category_id, create_user, create_date, modify_user, modify_date) + VALUES (2220002, 1, 14, "132456", CURRENT, "132456", CURRENT); +INSERT INTO project (project_id, project_status_id, project_category_id, create_user, create_date, modify_user, modify_date) + VALUES (2220003, 1, 14, "132456", CURRENT, "132456", CURRENT); +INSERT INTO project (project_id, project_status_id, project_category_id, create_user, create_date, modify_user, modify_date) + VALUES (2220004, 1, 14, "132456", CURRENT, "132456", CURRENT); +INSERT INTO project (project_id, project_status_id, project_category_id, create_user, create_date, modify_user, modify_date) + VALUES (2220005, 1, 14, "132456", CURRENT, "132456", CURRENT); + +INSERT INTO project_phase (project_phase_id, project_id, phase_type_id, phase_status_id, scheduled_start_time, scheduled_end_time, duration, create_user, create_date, modify_user, modify_date) + VALUES (7770001, 2220001, 17, 3, CURRENT, CURRENT, 0, "132456", CURRENT, "132456", CURRENT); +INSERT INTO project_phase (project_phase_id, project_id, phase_type_id, phase_status_id, scheduled_start_time, scheduled_end_time, duration, create_user, create_date, modify_user, modify_date) + VALUES (7770002, 2220002, 17, 3, CURRENT, CURRENT, 0, "132456", CURRENT, "132456", CURRENT); +INSERT INTO project_phase (project_phase_id, project_id, phase_type_id, phase_status_id, scheduled_start_time, scheduled_end_time, duration, create_user, create_date, modify_user, modify_date) + VALUES (7770003, 2220003, 17, 3, CURRENT, CURRENT, 0, "132456", CURRENT, "132456", CURRENT); +INSERT INTO project_phase (project_phase_id, project_id, phase_type_id, phase_status_id, scheduled_start_time, scheduled_end_time, duration, create_user, create_date, modify_user, modify_date) + VALUES (7770004, 2220004, 17, 3, CURRENT, CURRENT, 0, "132456", CURRENT, "132456", CURRENT); +INSERT INTO project_phase (project_phase_id, project_id, phase_type_id, phase_status_id, scheduled_start_time, scheduled_end_time, duration, create_user, create_date, modify_user, modify_date) + VALUES (7770005, 2220005, 17, 3, CURRENT, CURRENT, 0, "132456", CURRENT, "132456", CURRENT); + +INSERT INTO resource (resource_id, resource_role_id, project_id, project_phase_id, user_id, create_user, create_date, modify_user, modify_date) + VALUES (8880001, 20, 2220001, 7770001, 132456, "132456", CURRENT, "132456", CURRENT); +INSERT INTO resource (resource_id, resource_role_id, project_id, project_phase_id, user_id, create_user, create_date, modify_user, modify_date) + VALUES (8880002, 20, 2220002, 7770002, 132456, "132456", CURRENT, "132456", CURRENT); +INSERT INTO resource (resource_id, resource_role_id, project_id, project_phase_id, user_id, create_user, create_date, modify_user, modify_date) + VALUES (8880003, 20, 2220003, 7770003, 132456, "132456", CURRENT, "132456", CURRENT); +INSERT INTO resource (resource_id, resource_role_id, project_id, project_phase_id, user_id, create_user, create_date, modify_user, modify_date) + VALUES (8880004, 20, 2220004, 7770004, 132456, "132456", CURRENT, "132456", CURRENT); +INSERT INTO resource (resource_id, resource_role_id, project_id, project_phase_id, user_id, create_user, create_date, modify_user, modify_date) + VALUES (8880005, 20, 2220005, 7770005, 132456, "132456", CURRENT, "132456", CURRENT); + +INSERT INTO upload (upload_id, project_id, resource_id, upload_type_id, upload_status_id, parameter, create_user, create_date, modify_user, modify_date) + VALUES (9990001, 2220001, 8880001, 1, 1, "---", "132456", CURRENT, "132456", CURRENT); +INSERT INTO upload (upload_id, project_id, resource_id, upload_type_id, upload_status_id, parameter, create_user, create_date, modify_user, modify_date) + VALUES (9990002, 2220002, 8880002, 1, 1, "---", "132456", CURRENT, "132456", CURRENT); +INSERT INTO upload (upload_id, project_id, resource_id, upload_type_id, upload_status_id, parameter, create_user, create_date, modify_user, modify_date) + VALUES (9990003, 2220003, 8880003, 1, 1, "---", "132456", CURRENT, "132456", CURRENT); +INSERT INTO upload (upload_id, project_id, resource_id, upload_type_id, upload_status_id, parameter, create_user, create_date, modify_user, modify_date) + VALUES (9990004, 2220004, 8880004, 1, 1, "---", "132456", CURRENT, "132456", CURRENT); +INSERT INTO upload (upload_id, project_id, resource_id, upload_type_id, upload_status_id, parameter, create_user, create_date, modify_user, modify_date) + VALUES (9990005, 2220005, 8880005, 1, 1, "---", "132456", CURRENT, "132456", CURRENT); + +INSERT INTO prize (prize_id, project_id, place, prize_amount, prize_type_id, number_of_submissions, create_user, create_date, modify_user, modify_date) + VALUES (1110001, 2220001, 1, 1000, 14, 1, "132456", CURRENT, "132456", CURRENT); +INSERT INTO prize (prize_id, project_id, place, prize_amount, prize_type_id, number_of_submissions, create_user, create_date, modify_user, modify_date) + VALUES (1110002, 2220002, 1, 1000, 14, 1, "132456", CURRENT, "132456", CURRENT); +INSERT INTO prize (prize_id, project_id, place, prize_amount, prize_type_id, number_of_submissions, create_user, create_date, modify_user, modify_date) + VALUES (1110003, 2220003, 1, 1000, 14, 1, "132456", CURRENT, "132456", CURRENT); +INSERT INTO prize (prize_id, project_id, place, prize_amount, prize_type_id, number_of_submissions, create_user, create_date, modify_user, modify_date) + VALUES (1110004, 2220004, 1, 1000, 14, 1, "132456", CURRENT, "132456", CURRENT); +INSERT INTO prize (prize_id, project_id, place, prize_amount, prize_type_id, number_of_submissions, create_user, create_date, modify_user, modify_date) + VALUES (1110005, 2220005, 1, 1000, 14, 1, "132456", CURRENT, "132456", CURRENT); + +INSERT INTO submission (submission_id, upload_id, submission_status_id, submission_type_id, create_user, create_date, modify_user, modify_date, prize_id) + VALUES (2220001, 9990001, 1, 3, "132456", CURRENT, "132456", CURRENT, 1110001); +INSERT INTO submission (submission_id, upload_id, submission_status_id, submission_type_id, create_user, create_date, modify_user, modify_date, prize_id) + VALUES (2220002, 9990002, 1, 3, "132456", CURRENT, "132456", CURRENT, 1110002); +INSERT INTO submission (submission_id, upload_id, submission_status_id, submission_type_id, create_user, create_date, modify_user, modify_date, prize_id) + VALUES (2220003, 9990003, 1, 3, "132456", CURRENT, "132456", CURRENT, 1110003); +INSERT INTO submission (submission_id, upload_id, submission_status_id, submission_type_id, create_user, create_date, modify_user, modify_date, prize_id) + VALUES (2220004, 9990004, 1, 3, "132456", CURRENT, "132456", CURRENT, 1110004); +INSERT INTO submission (submission_id, upload_id, submission_status_id, submission_type_id, create_user, create_date, modify_user, modify_date, prize_id) + VALUES (2220005, 9990005, 1, 3, "132456", CURRENT, "132456", CURRENT, 1110005); + +INSERT INTO scorecard (scorecard_id, scorecard_status_id, scorecard_type_id, project_category_id, name, version, min_score, max_score, create_user, create_date, modify_user, modify_date, version_number) + VALUES (3330333, 1, 7, 14, "---", "---", 0, 100, "132456", CURRENT, "132456", CURRENT, 1); + +INSERT INTO scorecard_group (scorecard_group_id, scorecard_id, name, weight, sort, create_user, create_date, modify_user, modify_date, version) + VALUES (3330333, 3330333, "---", 100, 1, "132456", CURRENT, "132456", CURRENT, 1); + +INSERT INTO scorecard_section (scorecard_section_id, scorecard_group_id, name, weight, sort, create_user, create_date, modify_user, modify_date, version) + VALUES (3330333, 3330333, "---", 100, 1, "132456", CURRENT, "132456", CURRENT, 1); + +INSERT INTO scorecard_question (scorecard_question_id, scorecard_question_type_id, scorecard_section_id, description, weight, sort, upload_document, upload_document_required, create_user, create_date, modify_user, modify_date, version) + VALUES (3330333, 1, 3330333, '---', 100, 1, 0, 0, "132456", CURRENT, "132456", CURRENT, 1); + +INSERT INTO review (review_id, resource_id, submission_id, project_phase_id, scorecard_id, committed, create_user, create_date, modify_user, modify_date) + VALUES (4440001, 8880001, 2220001, 7770001, 3330333, 1, "132456", CURRENT, "132456", CURRENT); +INSERT INTO review (review_id, resource_id, submission_id, project_phase_id, scorecard_id, committed, create_user, create_date, modify_user, modify_date) + VALUES (4440002, 8880002, 2220002, 7770002, 3330333, 1, "132456", CURRENT, "132456", CURRENT); +INSERT INTO review (review_id, resource_id, submission_id, project_phase_id, scorecard_id, committed, create_user, create_date, modify_user, modify_date) + VALUES (4440003, 8880003, 2220003, 7770003, 3330333, 1, "132456", CURRENT, "132456", CURRENT); +INSERT INTO review (review_id, resource_id, submission_id, project_phase_id, scorecard_id, committed, create_user, create_date, modify_user, modify_date) + VALUES (4440004, 8880004, 2220004, 7770004, 3330333, 1, "132456", CURRENT, "132456", CURRENT); +INSERT INTO review (review_id, resource_id, submission_id, project_phase_id, scorecard_id, committed, create_user, create_date, modify_user, modify_date) + VALUES (4440005, 8880005, 2220005, 7770005, 3330333, 1, "132456", CURRENT, "132456", CURRENT); + +INSERT INTO review_item (review_item_id, review_id, scorecard_question_id, upload_id, answer, sort, create_user, create_date, modify_user, modify_date) + VALUES (5550001, 4440001, 3330333, 9990001, "---", 1, "132456", CURRENT, "132456", CURRENT); +INSERT INTO review_item (review_item_id, review_id, scorecard_question_id, upload_id, answer, sort, create_user, create_date, modify_user, modify_date) + VALUES (5550002, 4440002, 3330333, 9990002, "---", 1, "132456", CURRENT, "132456", CURRENT); +INSERT INTO review_item (review_item_id, review_id, scorecard_question_id, upload_id, answer, sort, create_user, create_date, modify_user, modify_date) + VALUES (5550003, 4440003, 3330333, 9990003, "---", 1, "132456", CURRENT, "132456", CURRENT); +INSERT INTO review_item (review_item_id, review_id, scorecard_question_id, upload_id, answer, sort, create_user, create_date, modify_user, modify_date) + VALUES (5550004, 4440004, 3330333, 9990004, "---", 1, "132456", CURRENT, "132456", CURRENT); +INSERT INTO review_item (review_item_id, review_id, scorecard_question_id, upload_id, answer, sort, create_user, create_date, modify_user, modify_date) + VALUES (5550005, 4440005, 3330333, 9990005, "---", 1, "132456", CURRENT, "132456", CURRENT); + +INSERT INTO review_item_comment (review_item_comment_id, resource_id, review_item_id, comment_type_id, content, sort, create_user, create_date, modify_user, modify_date) + VALUES (7770001, 8880001, 5550001, 1, "The current user has the right to view this challenge", 1, "132456", CURRENT, "132456", CURRENT); +INSERT INTO review_item_comment (review_item_comment_id, resource_id, review_item_id, comment_type_id, content, sort, create_user, create_date, modify_user, modify_date) + VALUES (7770002, 8880002, 5550002, 1, "The current user has the right to view this challenge", 1, "132456", CURRENT, "132456", CURRENT); +INSERT INTO review_item_comment (review_item_comment_id, resource_id, review_item_id, comment_type_id, content, sort, create_user, create_date, modify_user, modify_date) + VALUES (7770003, 8880003, 5550003, 1, "The current user has the right to view this challenge", 1, "132456", CURRENT, "132456", CURRENT); +INSERT INTO review_item_comment (review_item_comment_id, resource_id, review_item_id, comment_type_id, content, sort, create_user, create_date, modify_user, modify_date) + VALUES (7770004, 8880004, 5550004, 1, "The current user has the right to view this challenge", 1, "132456", CURRENT, "132456", CURRENT); +INSERT INTO review_item_comment (review_item_comment_id, resource_id, review_item_id, comment_type_id, content, sort, create_user, create_date, modify_user, modify_date) + VALUES (7770005, 8880005, 5550005, 1, "The current user has the right to view this challenge", 1, "132456", CURRENT, "132456", CURRENT); + +INSERT INTO project (project_id, project_status_id, project_category_id, create_user, create_date, modify_user, modify_date) + VALUES (1110001, 1, 14, "132456", CURRENT, "132456", CURRENT); +INSERT INTO project (project_id, project_status_id, project_category_id, create_user, create_date, modify_user, modify_date) + VALUES (1110002, 1, 14, "132456", CURRENT, "132456", CURRENT); +INSERT INTO project (project_id, project_status_id, project_category_id, create_user, create_date, modify_user, modify_date) + VALUES (1110003, 1, 14, "132456", CURRENT, "132456", CURRENT); +INSERT INTO project (project_id, project_status_id, project_category_id, create_user, create_date, modify_user, modify_date) + VALUES (1110004, 1, 14, "132456", CURRENT, "132456", CURRENT); +INSERT INTO project (project_id, project_status_id, project_category_id, create_user, create_date, modify_user, modify_date) + VALUES (1110005, 1, 14, "132456", CURRENT, "132456", CURRENT); + +INSERT INTO project_phase (project_phase_id, project_id, phase_type_id, phase_status_id, scheduled_start_time, scheduled_end_time, duration, create_user, create_date, modify_user, modify_date) + VALUES (2220001, 1110001, 1, 2, CURRENT, CURRENT, 1, "132456", CURRENT, "132456", CURRENT); +INSERT INTO project_phase (project_phase_id, project_id, phase_type_id, phase_status_id, scheduled_start_time, scheduled_end_time, duration, create_user, create_date, modify_user, modify_date) + VALUES (2220002, 1110002, 1, 2, CURRENT, CURRENT, 1, "132456", CURRENT, "132456", CURRENT); +INSERT INTO project_phase (project_phase_id, project_id, phase_type_id, phase_status_id, scheduled_start_time, scheduled_end_time, duration, create_user, create_date, modify_user, modify_date) + VALUES (2220003, 1110003, 1, 2, CURRENT, CURRENT, 1, "132456", CURRENT, "132456", CURRENT); +INSERT INTO project_phase (project_phase_id, project_id, phase_type_id, phase_status_id, scheduled_start_time, scheduled_end_time, duration, create_user, create_date, modify_user, modify_date) + VALUES (2220004, 1110004, 1, 2, CURRENT, CURRENT, 1, "132456", CURRENT, "132456", CURRENT); +INSERT INTO project_phase (project_phase_id, project_id, phase_type_id, phase_status_id, scheduled_start_time, scheduled_end_time, duration, create_user, create_date, modify_user, modify_date) + VALUES (2220005, 1110005, 1, 2, CURRENT, CURRENT, 1, "132456", CURRENT, "132456", CURRENT); + +INSERT INTO comp_catalog (component_id, current_version, component_name, status_id, modify_date, public_ind) + VALUES (3330333, 1, "---", 1, CURRENT, 0); + +INSERT INTO comp_versions (comp_vers_id, component_id, version, version_text, phase_id, phase_time, price, modify_date) + VALUES (4440444, 3330333, 1, "1", 113, CURRENT, 1000, CURRENT); + +INSERT INTO project_info (project_id, project_info_type_id, value, create_user, create_date, modify_user, modify_date) + VALUES (1110001, 2, "3330333", "132456", CURRENT, "132456", CURRENT); +INSERT INTO project_info (project_id, project_info_type_id, value, create_user, create_date, modify_user, modify_date) + VALUES (1110002, 2, "3330333", "132456", CURRENT, "132456", CURRENT); +INSERT INTO project_info (project_id, project_info_type_id, value, create_user, create_date, modify_user, modify_date) + VALUES (1110003, 2, "3330333", "132456", CURRENT, "132456", CURRENT); +INSERT INTO project_info (project_id, project_info_type_id, value, create_user, create_date, modify_user, modify_date) + VALUES (1110004, 2, "3330333", "132456", CURRENT, "132456", CURRENT); +INSERT INTO project_info (project_id, project_info_type_id, value, create_user, create_date, modify_user, modify_date) + VALUES (1110005, 2, "3330333", "132456", CURRENT, "132456", CURRENT); + +INSERT INTO project_info (project_id, project_info_type_id, value, create_user, create_date, modify_user, modify_date) + VALUES (1110001, 6, 3330333, "Not private", CURRENT, "132456", CURRENT); +INSERT INTO project_info (project_id, project_info_type_id, value, create_user, create_date, modify_user, modify_date) + VALUES (1110002, 6, 3330333, "Old logic - access allowed", CURRENT, "132456", CURRENT); +INSERT INTO project_info (project_id, project_info_type_id, value, create_user, create_date, modify_user, modify_date) + VALUES (1110003, 6, 3330333, "Old logic - access denied", CURRENT, "132456", CURRENT); +INSERT INTO project_info (project_id, project_info_type_id, value, create_user, create_date, modify_user, modify_date) + VALUES (1110004, 6, 3330333, "New logic - access allowed", CURRENT, "132456", CURRENT); +INSERT INTO project_info (project_id, project_info_type_id, value, create_user, create_date, modify_user, modify_date) + VALUES (1110005, 6, 3330333, "New logic - access denied", CURRENT, "132456", CURRENT); + +INSERT INTO project_info (project_id, project_info_type_id, value, create_user, create_date, modify_user, modify_date) + VALUES (1110001, 79, "---", "132456", CURRENT, "132456", CURRENT); +INSERT INTO project_info (project_id, project_info_type_id, value, create_user, create_date, modify_user, modify_date) + VALUES (1110002, 79, "---", "132456", CURRENT, "132456", CURRENT); +INSERT INTO project_info (project_id, project_info_type_id, value, create_user, create_date, modify_user, modify_date) + VALUES (1110003, 79, "---", "132456", CURRENT, "132456", CURRENT); +INSERT INTO project_info (project_id, project_info_type_id, value, create_user, create_date, modify_user, modify_date) + VALUES (1110004, 79, "---", "132456", CURRENT, "132456", CURRENT); +INSERT INTO project_info (project_id, project_info_type_id, value, create_user, create_date, modify_user, modify_date) + VALUES (1110005, 79, "---", "132456", CURRENT, "132456", CURRENT); + +INSERT INTO project_phase (project_phase_id, project_id, phase_type_id, phase_status_id, scheduled_start_time, scheduled_end_time, duration, create_user, create_date, modify_user, modify_date) + VALUES (3330001, 1110001, 2, 2, CURRENT, CURRENT, 1, "132456", CURRENT, "132456", CURRENT); +INSERT INTO project_phase (project_phase_id, project_id, phase_type_id, phase_status_id, scheduled_start_time, scheduled_end_time, duration, create_user, create_date, modify_user, modify_date) + VALUES (3330002, 1110002, 2, 2, CURRENT, CURRENT, 1, "132456", CURRENT, "132456", CURRENT); +INSERT INTO project_phase (project_phase_id, project_id, phase_type_id, phase_status_id, scheduled_start_time, scheduled_end_time, duration, create_user, create_date, modify_user, modify_date) + VALUES (3330003, 1110003, 2, 2, CURRENT, CURRENT, 1, "132456", CURRENT, "132456", CURRENT); +INSERT INTO project_phase (project_phase_id, project_id, phase_type_id, phase_status_id, scheduled_start_time, scheduled_end_time, duration, create_user, create_date, modify_user, modify_date) + VALUES (3330004, 1110004, 2, 2, CURRENT, CURRENT, 1, "132456", CURRENT, "132456", CURRENT); +INSERT INTO project_phase (project_phase_id, project_id, phase_type_id, phase_status_id, scheduled_start_time, scheduled_end_time, duration, create_user, create_date, modify_user, modify_date) + VALUES (3330005, 1110005, 2, 2, CURRENT, CURRENT, 1, "132456", CURRENT, "132456", CURRENT); + +DATABASE informixoltp; + +UPDATE coder SET comp_country_code = ( + SELECT MIN(country_code) FROM country WHERE country_name = "United States" +) WHERE coder_id = 132458; + +DATABASE common_oltp; + +INSERT INTO contest_eligibility (contest_eligibility_id, contest_id, is_studio) VALUES (1110002, 2220002, 0); +INSERT INTO contest_eligibility (contest_eligibility_id, contest_id, is_studio) VALUES (1110003, 2220003, 0); +INSERT INTO contest_eligibility (contest_eligibility_id, contest_id, is_studio) VALUES (1110004, 2220004, 0); +INSERT INTO contest_eligibility (contest_eligibility_id, contest_id, is_studio) VALUES (1110005, 2220005, 0); + +INSERT INTO security_groups (group_id, description, challenge_group_ind) VALUES (3330001, "Eligibility - Old logic - with user", 0); +INSERT INTO security_groups (group_id, description, challenge_group_ind) VALUES (3330002, "Eligibility - Old logic - no users", 0); +INSERT INTO security_groups (group_id, description, challenge_group_ind) VALUES (3330003, "Eligibility - New logic - with user", 1); +INSERT INTO security_groups (group_id, description, challenge_group_ind) VALUES (3330004, "Eligibility - New logic - no users", 1); + +INSERT INTO user_group_xref (user_group_id, login_id, group_id) VALUES (5550001, 132458, 3330001); + +INSERT INTO group_contest_eligibility (contest_eligibility_id, group_id) VALUES (1110002, 3330001); +INSERT INTO group_contest_eligibility (contest_eligibility_id, group_id) VALUES (1110003, 3330002); +INSERT INTO group_contest_eligibility (contest_eligibility_id, group_id) VALUES (1110004, 3330003); +INSERT INTO group_contest_eligibility (contest_eligibility_id, group_id) VALUES (1110005, 3330004); + +INSERT INTO contest_eligibility (contest_eligibility_id, contest_id, is_studio) VALUES (1110012, 1110002, 0); +INSERT INTO contest_eligibility (contest_eligibility_id, contest_id, is_studio) VALUES (1110013, 1110003, 0); +INSERT INTO contest_eligibility (contest_eligibility_id, contest_id, is_studio) VALUES (1110014, 1110004, 0); +INSERT INTO contest_eligibility (contest_eligibility_id, contest_id, is_studio) VALUES (1110015, 1110005, 0); + +INSERT INTO group_contest_eligibility (contest_eligibility_id, group_id) VALUES (1110012, 3330001); +INSERT INTO group_contest_eligibility (contest_eligibility_id, group_id) VALUES (1110013, 3330002); +INSERT INTO group_contest_eligibility (contest_eligibility_id, group_id) VALUES (1110014, 3330003); +INSERT INTO group_contest_eligibility (contest_eligibility_id, group_id) VALUES (1110015, 3330004); diff --git a/docs/Verification_Guide-Improve Challenge Visibility Control.doc b/docs/Verification_Guide-Improve Challenge Visibility Control.doc new file mode 100644 index 000000000..1c2913aae Binary files /dev/null and b/docs/Verification_Guide-Improve Challenge Visibility Control.doc differ diff --git a/initializers/challengeHelper.js b/initializers/challengeHelper.js index d8d94e75c..2460e3f17 100644 --- a/initializers/challengeHelper.js +++ b/initializers/challengeHelper.js @@ -1,8 +1,8 @@ /* * Copyright (C) 2013 - 2014 TopCoder Inc., All Rights Reserved. * - * @version 1.4 - * @author ecnu_haozi, bugbuka, Ghost_141, muzehyun + * @version 1.5 + * @author ecnu_haozi, bugbuka, Ghost_141, muzehyun, GFalcon * Refactor common code out from challenge.js. * * changes in 1.1: @@ -13,6 +13,9 @@ * - Avoid undefined if rows[0].copilot_type is null. * Changes in 1.4: * - Add template id to challenge terms of use. + * Changes in 1.5: + * - Add the checkUserChallengeEligibility function + * - Removee the obsolete eligibility check in getChallengeTerms */ "use strict"; @@ -135,11 +138,6 @@ exports.challengeHelper = function (api, next) { return; } - if (!rows[0].no_elgibility_req && !rows[0].user_in_eligible_group) { - cb(new ForbiddenError('You are not part of the groups eligible for this challenge.')); - return; - } - // Update check to use flag. if (requireRegOpen && !rows[0].reg_open) { cb(new ForbiddenError('Registration Phase of this challenge is not open.')); @@ -316,8 +314,71 @@ exports.challengeHelper = function (api, next) { } next(null, result.terms); }); + }, + /** + * Check if the user currently logged in has the right to access the specified challenge + * + * @param {Object} connection The connection object for the current request + * @param {Number} challengeId The challenge id. + * @param {Function} next The callback that will receive an error + * if the user is not eligible + * + * @since 1.5 + */ + checkUserChallengeEligibility: function (connection, challengeId, next) { + // Admins can access any challenge + if (connection.caller.accessLevel === 'admin') { + next(); + return; + } + // Query the accessibility information + var userId = (connection.caller.userId || 0); + api.dataAccess.executeQuery('get_challenge_accessibility_and_groups', { + challengeId: challengeId, + user_id: userId + }, connection.dbConnectionMap, function (err, res) { + if (err) { + next(err); + return; + } + // If there's no corresponding record in group_contest_eligibility + // then the challenge is available to all users + if (res.length === 0 + || _.isNull(res[0].challenge_group_ind) + || _.isUndefined(res[0].challenge_group_ind)) { + next(); + return; + } + var error = false; + // Look at the groups + async.some(res, function (record, cbx) { + // Old challenges: check by looking up in common_oltp:user_group_xref + if (record.challenge_group_ind === 0) { + cbx(!(_.isNull(record.user_group_xref_found) || _.isUndefined(record.user_group_xref_found))); + } else { + // New challenges: query the V3 API + api.v3client.isUserInGroup(connection, userId, record.group_id, function (err, result) { + if (err) { + error = err; + cbx(true); + } else { + cbx(result); + } + }); + } + }, function (eligible) { + if (error) { + next(error); + } else if (eligible) { + next(); + } else if (connection.caller.accessLevel === "anon") { + next(new UnauthorizedError()); + } else { + next(new ForbiddenError()); + } + }); + }); } - }; next(); diff --git a/initializers/middleware.js b/initializers/middleware.js index cf370e589..98fb669ce 100644 --- a/initializers/middleware.js +++ b/initializers/middleware.js @@ -2,8 +2,8 @@ /* * Copyright (C) 2013 - 2014 TopCoder Inc., All Rights Reserved. * - * @version 1.3 - * @author vangavroche, TCSASSEMBLER + * @version 1.4 + * @author vangavroche, TCSASSEMBLER, GFalcon * changes in 1.1: * - add cache support (add preCacheProcessor and postCacheProcessor) * changes in 1.2: @@ -12,6 +12,8 @@ * - add authorizationPreProcessor * changes in 1.3: * - add force refresh check for preCacheProcessor + * changes in 1.4: + * - store the authorization token in connection.authToken */ "use strict"; @@ -105,6 +107,7 @@ exports.middleware = function (api, next) { cb(null, reg.exec(authHeader)[1]); } }, function (token, cb) { + connection.authToken = token; jwt.verify(token, api.config.tcConfig.oauthClientSecret, { audience: api.config.tcConfig.oauthClientId }, diff --git a/initializers/v3client.js b/initializers/v3client.js new file mode 100644 index 000000000..dabb7759d --- /dev/null +++ b/initializers/v3client.js @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2017 TopCoder Inc., All Rights Reserved. + * + * V3 API client + * + * @version 1.0 + * @author GFalcon + */ +"use strict"; +/*jslint nomen: true*/ + +var request = require('request'); +var _ = require('underscore'); +var async = require('async'); + +/** + * The URL of the V3 API + */ +var v3url = process.env.TC_API_V3_URL || 'http://localhost:8084/v3/'; + +/** + * Cached V3 API tokens. + * + * This object stores V2 tokens as keys and V3 tokens as values + */ +var tokens = {}; + +/** + * Call the service. It handles both errors and bad response status codes. + * + * @param {Object} params - parameters for a request + * @param {Function} callback - the callback function. + * It will get either an Error object or a response body. + */ +function callService(params, callback) { + params.json = true; + request(params, function (err, response, body) { + if (err) { + callback(err); + return; + } + /*jslint eqeq: true*/ + if (response.statusCode != 200) { + /*jslint eqeq: false*/ + callback(new Error('API V3 returned ' + response.statusCode + ' ' + (response.statusMessage || ''))); + return; + } + callback(null, body); + }); +} + +/** + * Get the V3 API authorization token to use in subsequent calls + * + * @param {Object} connection - the connection object provided by ActionHero + * @param {Function} callback - this function receives either an error, + * a V3 token or nothing at all (if the current connection's user is anonymous) + */ +function getToken(connection, callback) { + // Anonymous + if (_.isUndefined(connection.authToken)) { + callback(); + return; + } + // Cached token + if (!_.isUndefined(tokens[connection.authToken])) { + callback(null, tokens[connection.authToken]); + return; + } + // Get the token by calling the API + callService({ + url: v3url + 'authorizations', + method: 'POST', + body: { + param: { + token: connection.authToken + } + } + }, function (err, body) { + if (err) { + callback(err); + } else { + tokens[connection.authToken] = body.result.content.token; + callback(null, body.result.content.token); + } + }); +} + +/** + * Get IDs of users in the specified group + * + * @param {Object} connection - the connection object provided by ActionHero + * @param {Number} groupId - the group ID + * @param {Function} callback - the callback. Receives either an error + * or the list of group's users an array of numeric IDs + */ +function getGroupMembers(connection, groupId, callback) { + getToken(connection, function (err, token) { + if (err) { + callback(err); + return; + } + callService({ + url: v3url + 'groups/' + groupId + '/members', + method: 'GET', + headers: { + 'Authorization': 'Bearer ' + token + } + }, function (err, body) { + if (err) { + callback(err); + } else { + callback(null, body.result.content.map(function (item) { + return item.memberId; + })); + } + }); + }); +} + +exports.v3client = function (api, next) { + api.v3client = { + /** + * Check if the user belongs to the group + * + * @param {Object} connection - the connection object provided by ActionHero + * @param {Number} userId - the user ID + * @param {Number} groupId - the group ID + * @param {Function} callback - the callback. The second parameter + * is boolean vwhich is true if the user is found in the group. + */ + isUserInGroup: function (connection, userId, groupId, callback) { + getGroupMembers(connection, groupId, function (err, members) { + if (err) { + callback(err); + } else { + callback(null, members.indexOf(userId) >= 0); + } + }); + } + }; + next(); +}; diff --git a/package.json b/package.json index b9daa5614..c3e6dfc2a 100644 --- a/package.json +++ b/package.json @@ -21,9 +21,11 @@ "bcrypt": "0.7.x", "bigdecimal": "0.6.x", "bignum": "0.6.x", + "body-parser": "^1.17.2", "crypto": "0.0.x", "datejs": "0.0.x", "email-templates": "0.1.x", + "express": "^4.15.3", "forums-wrapper": "git://github.com/cloudspokes/forums-wrapper.git#12b57be495c2e10431173522bc9eff60e0575959", "heapdump": "^0.3.6", "highlight.js": ">= 8.3.0", diff --git a/queries/challenge_registration_validations b/queries/challenge_registration_validations index 1b20283f4..4bd4a63de 100644 --- a/queries/challenge_registration_validations +++ b/queries/challenge_registration_validations @@ -4,8 +4,6 @@ select (pp_reg_open.project_id IS NOT NULL) as reg_open, (r.project_id IS NOT NULL) as user_registered, (us.user_id IS NOT NULL) as user_suspended, - (ce.contest_eligibility_id IS NULL) as no_elgibility_req, - (ugx.login_id IS NOT NULL) as user_in_eligible_group, (uax.user_id IS NOT NULL OR coder.coder_id IS NOT NULL) as user_country_banned, (coder2.comp_country_code IS NULL OR coder2.comp_country_code = '') as comp_country_is_null, (cop.copilot_profile_id IS NOT NULL) as user_is_copilot, @@ -28,14 +26,6 @@ left join on us.user_id = @userId@ and us.user_status_type_id = 1 and us.user_status_id = 3 --- Check if user meets eligibility requirements -left outer join ( - contest_eligibility ce join ( - group_contest_eligibility gce left outer join user_group_xref ugx - on ugx.group_id = gce.group_id and ugx.login_id = @userId@ - ) - on ce.contest_eligibility_id = gce.contest_eligibility_id -) on p.project_id = ce.contest_id -- Check user's country left outer join ( informixoltp:user_address_xref uax join ( diff --git a/queries/get_challenge_accessibility_and_groups b/queries/get_challenge_accessibility_and_groups new file mode 100644 index 000000000..6ca557db3 --- /dev/null +++ b/queries/get_challenge_accessibility_and_groups @@ -0,0 +1,21 @@ +SELECT + ce.is_studio, + sg.challenge_group_ind, + ugx.group_id AS user_group_xref_found, + sg.group_id AS group_id +FROM + ( + ( + contest_eligibility ce + LEFT JOIN group_contest_eligibility gce + ON ce.contest_eligibility_id = gce.contest_eligibility_id + ) + LEFT JOIN security_groups sg + ON gce.group_id = sg.group_id + ) + LEFT JOIN ( + SELECT group_id FROM user_group_xref WHERE login_id=@user_id@ + ) ugx + ON ugx.group_id = gce.group_id +WHERE ce.contest_id = @challengeId@ + diff --git a/queries/get_challenge_accessibility_and_groups.json b/queries/get_challenge_accessibility_and_groups.json new file mode 100644 index 000000000..218f37428 --- /dev/null +++ b/queries/get_challenge_accessibility_and_groups.json @@ -0,0 +1,5 @@ +{ + "name" : "get_challenge_accessibility_and_groups", + "db" : "tcs_catalog", + "sqlfile" : "get_challenge_accessibility_and_groups" +} \ No newline at end of file diff --git a/test/postman/New_Challenge_Visibility_Control.postman_collection.json b/test/postman/New_Challenge_Visibility_Control.postman_collection.json new file mode 100644 index 000000000..7dadfd3d1 --- /dev/null +++ b/test/postman/New_Challenge_Visibility_Control.postman_collection.json @@ -0,0 +1,386 @@ +{ + "id": "ba962be9-0d58-f187-8809-008a39bc2240", + "name": "New Challenge Visibility Control", + "description": "", + "order": [], + "folders": [ + { + "id": "712ffa63-a959-e4a3-6af9-84d4f236b2f3", + "name": "Get checkpoints", + "description": "", + "order": [ + "7c7643c6-89ab-641e-b67a-32b3ac91e09e", + "d830ec36-eb8e-9586-c546-14af77cec152", + "2af8f0d9-f3e8-c58a-ca3d-1130e4b07371", + "f545bbfc-36d7-6567-25a8-b4d6634575e7", + "a3ae5124-2077-4ff2-4e02-afae7670bbe5" + ], + "owner": "316251" + }, + { + "id": "cfbf928f-56b8-9813-f8f3-4ac4e342d965", + "name": "Register for challenges", + "description": "", + "order": [ + "4b64d85a-4c08-8ec2-9c3f-50605bd2e09e", + "5224f722-9f4f-07bb-58e7-351512cc66ea", + "60ae89de-4eb1-c0aa-b866-b28b52436e89", + "843d6759-0cc0-a0c6-9fde-60f893f56eac", + "46cf305a-8251-66aa-391c-46def82773a1" + ], + "owner": "316251" + }, + { + "id": "0eeb693c-c6b6-e23b-156d-cff5f21dbb27", + "name": "login", + "description": "", + "order": [ + "6bed8920-6800-0ae0-e63d-b39b05c7f50c", + "fd4cd936-2d4d-a272-f402-d0f7b6cab82f" + ], + "owner": "316251", + "collectionId": "6369974d-65cc-d819-459b-0026549ddb47" + } + ], + "timestamp": 1474156790593, + "owner": "316251", + "public": false, + "requests": [ + { + "id": "2af8f0d9-f3e8-c58a-ca3d-1130e4b07371", + "headers": "Authorization: Bearer {{authToken}}\n", + "headerData": [ + { + "key": "Authorization", + "value": "Bearer {{authToken}}", + "description": "", + "enabled": true + } + ], + "url": "{{url}}/develop/challenges/checkpoint/2220003", + "queryParams": [], + "preRequestScript": null, + "pathVariables": {}, + "pathVariableData": [], + "method": "GET", + "data": null, + "dataMode": "params", + "tests": null, + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1497550652259, + "name": "Old logic, access denied", + "description": "", + "collectionId": "ba962be9-0d58-f187-8809-008a39bc2240", + "responses": [], + "folder": "712ffa63-a959-e4a3-6af9-84d4f236b2f3" + }, + { + "id": "46cf305a-8251-66aa-391c-46def82773a1", + "headers": "Authorization: Bearer {{authToken}}\n", + "headerData": [ + { + "key": "Authorization", + "value": "Bearer {{authToken}}", + "description": "", + "enabled": true + } + ], + "url": "{{url}}/challenges/1110005/register", + "queryParams": [], + "preRequestScript": null, + "pathVariables": {}, + "pathVariableData": [], + "method": "POST", + "data": null, + "dataMode": "params", + "version": 2, + "tests": null, + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1497813578982, + "name": "New logic, access denied", + "description": "", + "collectionId": "ba962be9-0d58-f187-8809-008a39bc2240", + "responses": [] + }, + { + "id": "4b64d85a-4c08-8ec2-9c3f-50605bd2e09e", + "headers": "Authorization: Bearer {{authToken}}\n", + "headerData": [ + { + "key": "Authorization", + "value": "Bearer {{authToken}}", + "description": "", + "enabled": true + } + ], + "url": "{{url}}/challenges/1110001/register", + "queryParams": [], + "pathVariables": {}, + "pathVariableData": [], + "preRequestScript": null, + "method": "POST", + "collectionId": "ba962be9-0d58-f187-8809-008a39bc2240", + "data": null, + "dataMode": "params", + "name": "No groups (challenge is not private)", + "description": "", + "descriptionFormat": "html", + "time": 1497813014785, + "version": 2, + "responses": [], + "tests": null, + "currentHelper": "normal", + "helperAttributes": {}, + "folder": "cfbf928f-56b8-9813-f8f3-4ac4e342d965" + }, + { + "id": "5224f722-9f4f-07bb-58e7-351512cc66ea", + "headers": "Authorization: Bearer {{authToken}}\n", + "headerData": [ + { + "key": "Authorization", + "value": "Bearer {{authToken}}", + "description": "", + "enabled": true + } + ], + "url": "{{url}}/challenges/1110002/register", + "queryParams": [], + "preRequestScript": null, + "pathVariables": {}, + "pathVariableData": [], + "method": "POST", + "data": null, + "dataMode": "params", + "version": 2, + "tests": null, + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1497813399305, + "name": "Old logic, access allowed", + "description": "", + "collectionId": "ba962be9-0d58-f187-8809-008a39bc2240", + "responses": [] + }, + { + "id": "60ae89de-4eb1-c0aa-b866-b28b52436e89", + "headers": "Authorization: Bearer {{authToken}}\n", + "headerData": [ + { + "key": "Authorization", + "value": "Bearer {{authToken}}", + "description": "", + "enabled": true + } + ], + "url": "{{url}}/challenges/1110003/register", + "queryParams": [], + "preRequestScript": null, + "pathVariables": {}, + "pathVariableData": [], + "method": "POST", + "data": null, + "dataMode": "params", + "version": 2, + "tests": null, + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1497813480606, + "name": "Old logic, access denied", + "description": "", + "collectionId": "ba962be9-0d58-f187-8809-008a39bc2240", + "responses": [] + }, + { + "id": "6bed8920-6800-0ae0-e63d-b39b05c7f50c", + "headers": "Content-Type: application/json\n", + "url": "{{url}}/auth", + "preRequestScript": null, + "pathVariables": {}, + "method": "POST", + "data": [], + "dataMode": "raw", + "version": 2, + "tests": "var authResponse = JSON.parse(responseBody);\npostman.setEnvironmentVariable(\"authToken\", authResponse.token);\ntests[\"Status code is 200\"] = responseCode.code === 200;\nvar jsonData = JSON.parse(responseBody);\ntests[\"A valid token is returned\"] = !!jsonData.token;", + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1474159263289, + "name": "Login as admin user", + "description": "", + "collectionId": "ba962be9-0d58-f187-8809-008a39bc2240", + "responses": [], + "rawModeData": "{\n \"username\": \"heffan\", \n \"password\": \"password\"\n}", + "folder": "0eeb693c-c6b6-e23b-156d-cff5f21dbb27" + }, + { + "id": "7c7643c6-89ab-641e-b67a-32b3ac91e09e", + "headers": "Authorization: Bearer {{authToken}}\n", + "headerData": [ + { + "key": "Authorization", + "value": "Bearer {{authToken}}", + "description": "", + "enabled": true + } + ], + "url": "{{url}}/develop/challenges/checkpoint/2220001", + "queryParams": [], + "pathVariables": {}, + "pathVariableData": [], + "preRequestScript": null, + "method": "GET", + "collectionId": "ba962be9-0d58-f187-8809-008a39bc2240", + "data": null, + "dataMode": "params", + "name": "No groups (challenge is not private)", + "description": "", + "descriptionFormat": "html", + "time": 1497550504090, + "version": 2, + "responses": [], + "tests": null, + "currentHelper": "normal", + "helperAttributes": {}, + "folder": "712ffa63-a959-e4a3-6af9-84d4f236b2f3" + }, + { + "id": "843d6759-0cc0-a0c6-9fde-60f893f56eac", + "headers": "Authorization: Bearer {{authToken}}\n", + "headerData": [ + { + "key": "Authorization", + "value": "Bearer {{authToken}}", + "description": "", + "enabled": true + } + ], + "url": "{{url}}/challenges/1110004/register", + "queryParams": [], + "preRequestScript": null, + "pathVariables": {}, + "pathVariableData": [], + "method": "POST", + "data": null, + "dataMode": "params", + "version": 2, + "tests": null, + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1497813524683, + "name": "New logic, access allowed", + "description": "", + "collectionId": "ba962be9-0d58-f187-8809-008a39bc2240", + "responses": [] + }, + { + "id": "a3ae5124-2077-4ff2-4e02-afae7670bbe5", + "headers": "Authorization: Bearer {{authToken}}\n", + "headerData": [ + { + "key": "Authorization", + "value": "Bearer {{authToken}}", + "description": "", + "enabled": true + } + ], + "url": "{{url}}/develop/challenges/checkpoint/2220005", + "queryParams": [], + "preRequestScript": null, + "pathVariables": {}, + "pathVariableData": [], + "method": "GET", + "data": null, + "dataMode": "params", + "tests": null, + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1497550755372, + "name": "New logic, access denied", + "description": "", + "collectionId": "ba962be9-0d58-f187-8809-008a39bc2240", + "responses": [], + "folder": "712ffa63-a959-e4a3-6af9-84d4f236b2f3" + }, + { + "id": "d830ec36-eb8e-9586-c546-14af77cec152", + "headers": "Authorization: Bearer {{authToken}}\n", + "headerData": [ + { + "key": "Authorization", + "value": "Bearer {{authToken}}", + "description": "", + "enabled": true + } + ], + "url": "{{url}}/develop/challenges/checkpoint/2220002", + "queryParams": [], + "preRequestScript": null, + "pathVariables": {}, + "pathVariableData": [], + "method": "GET", + "data": null, + "dataMode": "params", + "tests": null, + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1497550612717, + "name": "Old logic, access allowed", + "description": "", + "collectionId": "ba962be9-0d58-f187-8809-008a39bc2240", + "responses": [], + "folder": "712ffa63-a959-e4a3-6af9-84d4f236b2f3" + }, + { + "id": "f545bbfc-36d7-6567-25a8-b4d6634575e7", + "headers": "Authorization: Bearer {{authToken}}\n", + "headerData": [ + { + "key": "Authorization", + "value": "Bearer {{authToken}}", + "description": "", + "enabled": true + } + ], + "url": "{{url}}/develop/challenges/checkpoint/2220004", + "queryParams": [], + "preRequestScript": null, + "pathVariables": {}, + "pathVariableData": [], + "method": "GET", + "data": null, + "dataMode": "params", + "tests": null, + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1497550705028, + "name": "New logic, access allowed", + "description": "", + "collectionId": "ba962be9-0d58-f187-8809-008a39bc2240", + "responses": [], + "folder": "712ffa63-a959-e4a3-6af9-84d4f236b2f3" + }, + { + "id": "fd4cd936-2d4d-a272-f402-d0f7b6cab82f", + "headers": "Content-Type: application/json\n", + "url": "{{url}}/auth", + "preRequestScript": null, + "pathVariables": {}, + "method": "POST", + "data": [], + "dataMode": "raw", + "version": 2, + "tests": "var authResponse = JSON.parse(responseBody);\npostman.setEnvironmentVariable(\"authToken\", authResponse.token);\ntests[\"Status code is 200\"] = responseCode.code === 200;\nvar jsonData = JSON.parse(responseBody);\ntests[\"A valid token is returned\"] = !!jsonData.token;", + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1474159245944, + "name": "Log in as ordinary user", + "description": "", + "collectionId": "ba962be9-0d58-f187-8809-008a39bc2240", + "responses": [], + "rawModeData": "{\n \"username\": \"user\", \n \"password\": \"password\"\n}", + "folder": "0eeb693c-c6b6-e23b-156d-cff5f21dbb27" + } + ] +} \ No newline at end of file diff --git a/test/postman/New_Challenge_Visibility_Control.postman_environment.json b/test/postman/New_Challenge_Visibility_Control.postman_environment.json new file mode 100644 index 000000000..143271c12 --- /dev/null +++ b/test/postman/New_Challenge_Visibility_Control.postman_environment.json @@ -0,0 +1,34 @@ +{ + "id": "d761e292-418f-09b5-8b27-9d93eae42f1e", + "name": "New Challenge Visibility Control", + "values": [ + { + "enabled": true, + "key": "url", + "value": "http://localhost:8080/api/v2", + "type": "text" + }, + { + "enabled": true, + "key": "adminToken", + "value": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL3NtYS5hdXRoMC5jb20vIiwic3ViIjoiYWR8MTMyNDU2IiwiYXVkIjoiQ01hQnV3U25ZMFZ1NjhQTHJXYXR2dnUzaUlpR1BoN3QiLCJleHAiOjE1MTAxNTkyNjgsImlhdCI6MTQ3NDE1OTI2OH0.KRgW9TxNOEiEu5YdQnXQO1nKFULIuy7JlzDZdq9QFQY", + "type": "text" + }, + { + "enabled": true, + "key": "userToken", + "value": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL3NtYS5hdXRoMC5jb20vIiwic3ViIjoiYWR8MTMyNDU4IiwiYXVkIjoiQ01hQnV3U25ZMFZ1NjhQTHJXYXR2dnUzaUlpR1BoN3QiLCJleHAiOjE1MTAxNzI0MDgsImlhdCI6MTQ3NDE3MjQwOH0.sIG2FoNiCldizzcTMQ9iAFh-PCigNGBAlicxms6uTkk", + "type": "text" + }, + { + "enabled": true, + "key": "authToken", + "value": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL3NtYS5hdXRoMC5jb20vIiwic3ViIjoiYWR8MTMyNDU4IiwiYXVkIjoiQ01hQnV3U25ZMFZ1NjhQTHJXYXR2dnUzaUlpR1BoN3QiLCJleHAiOjE1MTAyODI4MDMsImlhdCI6MTQ3NDI4MjgwM30.s6q_FRFryMslkWCkR0wPSWwTopkZhHH8g9R_4GPf9m4", + "type": "text" + } + ], + "timestamp": 1497565761064, + "_postman_variable_scope": "environment", + "_postman_exported_at": "2017-06-15T22:29:38.942Z", + "_postman_exported_using": "Postman/5.0.1" +} \ No newline at end of file diff --git a/test/scripts/mock_v3.js b/test/scripts/mock_v3.js new file mode 100644 index 000000000..8df5e8c02 --- /dev/null +++ b/test/scripts/mock_v3.js @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2017 TopCoder Inc., All Rights Reserved. + * + * This is the REST server that mocks some services from the V3 API + * + * @author GFalcon + * @version 1.0 + */ +"use strict"; + +var express = require('express'); +var bodyParser = require('body-parser'); + +var app = express(); + +app.use(bodyParser.json()); + +/* + * Log all incoming requests + */ +/*jslint unparam: true*/ +app.use(function (req, res, next) { + console.info('V3 Request: ' + JSON.stringify({ + path: req.path, + method: req.method, + headers: req.headers, + body: req.body + }, null, ' ')); + next(); +}); +/*jslint unparam: false*/ + +/* + * Return a fake 'authorization token' + */ +/*jslint unparam: true*/ +app.post('/v3/authorizations', function (req, res) { + res.json({ + result: { + content: { + token: 'FAKE-TOKEN' + } + } + }); +}); +/*jslint unparam: false*/ + +/* + * Get group members. Makes each group consist of one user + * (the user from the sample database whose handle is 'user') + * except one group (id 3330004) that doesn't have any users at all + */ +app.get('/v3/groups/:groupId/members', function (req, res) { + /*jslint eqeq: true*/ + if (req.params.groupId != 3330004) { + /*jslint eqeq: false*/ + res.json({ + result: { + content: [{ + memberId: 132458 + }] + } + }); + } else { + res.json({ + result: { + content: [] + } + }); + } +}); + +app.listen(8084); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy