def _get_user_from_sso(jwt_token, token): try: data = jwt.decode(jwt_token, Config.jwt_secret, algorithms=['HS256']) username = data["username"] name = data.get("firstName", username) surname = data.get("lastName", "") if username != token: BaseHandler.raise_exc(Forbidden, "FORBIDDEN", "Use the same username from the SSO") if Database.get_user(username) is None: Database.begin() Database.add_user(username, name, surname, sso_user=True, autocommit=False) for task in Database.get_tasks(): Database.add_user_task(username, task["name"], autocommit=False) Database.commit() Logger.info("NEW_USER", "User %s created from SSO" % username) return Database.get_user(username) except jwt.exceptions.DecodeError: BaseHandler.raise_exc(Forbidden, "FORBIDDEN", "Please login at %s" % Config.sso_url)
def test_get_user_no_current_attempt(self): Utils.start_contest(since=100, duration=200) Database.add_user("token", "", "") Database.add_task("poldo", "", "", 42, 1) Database.add_user_task("token", "poldo") res = self.handler.get_user(token="token", _ip="1.1.1.1") self.assertEqual(None, res["tasks"]["poldo"]["current_input"])
def test_get_user_windowed_partial_window(self): now = int(datetime.utcnow().timestamp()) Database.set_meta("start_time", now) Database.set_meta("contest_duration", 1000) Database.set_meta("window_duration", 100) Database.add_user("token", "", "") Database.set_start_delay("token", 990) Database.add_task("poldo", "", "", 42, 1) Database.add_user_task("token", "poldo") Database.add_input("inputid", "token", "poldo", 1, "/path", 42) Database.set_user_attempt("token", "poldo", 1) res = self.handler.get_user(token="token", _ip="1.1.1.1") end_time = datetime.fromtimestamp(now + 1000, timezone.utc).isoformat() self.assertEqual(end_time, res["end_time"])
def test_get_user_windowed_almost_finished(self): now = int(datetime.datetime.now().timestamp()) Database.set_meta("start_time", now - 90) Database.set_meta("contest_duration", 1000) Database.set_meta("window_duration", 100) Database.add_user("token", "", "") Database.set_start_delay("token", 10) Database.add_task("poldo", "", "", 42, 1) Database.add_user_task("token", "poldo") Database.add_input("inputid", "token", "poldo", 1, "/path", 42) Database.set_user_attempt("token", "poldo", 1) res = self.handler.get_user(token="token", _ip="1.1.1.1") end_time = datetime.datetime.fromtimestamp(now + 20).strftime( '%Y-%m-%dT%H:%M:%S') self.assertEqual(end_time, res["end_time"])
def test_get_user(self): now = int(datetime.utcnow().timestamp()) Database.set_meta("start_time", now) Database.set_meta("contest_duration", 1000) Database.set_meta("extra_time", 50) Database.add_user("token", "", "") Database.set_extra_time("token", 30) Database.add_task("poldo", "", "", 42, 1) Database.add_user_task("token", "poldo") Database.add_input("inputid", "token", "poldo", 1, "/path", 42) Database.set_user_attempt("token", "poldo", 1) res = self.handler.get_user(token="token", _ip="1.1.1.1") end_time = datetime.fromtimestamp(now + 1080, timezone.utc).isoformat() self.assertEqual(end_time, res["end_time"]) self.assertEqual("poldo", res["tasks"]["poldo"]["name"]) self.assertEqual("inputid", res["tasks"]["poldo"]["current_input"]["id"])
def _insert_data(self): Database.add_user("token", "", "") Database.add_task("poldo", "", "", 42, 1) Database.add_user_task("token", "poldo") Database.add_input("inputid", "token", "poldo", 1, "/path", 42)
def read_from_disk(remove_enc=True): """ Load a task from the disk and load the data into the database """ try: contest = ContestManager.import_contest(Config.contest_path) except FileNotFoundError as ex: error = ( "Contest not found, you probably need to unzip it. Missing file %s" % ex.filename) Logger.warning("CONTEST", error) shutil.rmtree(Config.statementdir, ignore_errors=True) shutil.rmtree(Config.web_statementdir, ignore_errors=True) shutil.rmtree(Config.contest_path, ignore_errors=True) if remove_enc: with suppress(Exception): os.remove(Config.encrypted_file) with suppress(Exception): os.remove(Config.decrypted_file) Database.del_meta("admin_token") BaseHandler.raise_exc(UnprocessableEntity, "CONTEST", error) if not Database.get_meta("contest_imported", default=False, type=bool): Database.begin() try: Database.set_meta("contest_duration", contest["duration"], autocommit=False) Database.set_meta("contest_name", contest.get("name", "Contest"), autocommit=False) Database.set_meta( "contest_description", contest.get("description", ""), autocommit=False, ) Database.set_meta( "window_duration", # if None the contest is not USACO-style contest.get("window_duration"), autocommit=False, ) count = 0 for task in contest["tasks"]: Database.add_task( task["name"], task["description"], task["statement_path"], task["max_score"], count, autocommit=False, ) count += 1 for user in contest["users"]: Database.add_user(user["token"], user["name"], user["surname"], autocommit=False) for user in Database.get_users(): for task in Database.get_tasks(): Database.add_user_task(user["token"], task["name"], autocommit=False) Database.set_meta("contest_imported", True, autocommit=False) Database.commit() except: Database.rollback() raise else: # TODO: check that the contest is still the same pass # store the task in the ContestManager singleton ContestManager.tasks = dict( (task["name"], task) for task in contest["tasks"]) ContestManager.has_contest = True # create the queues for the task inputs for task in ContestManager.tasks: ContestManager.input_queue[task] = gevent.queue.Queue( Config.queue_size) gevent.spawn(ContestManager.worker, task)