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 _ensure_contest_running(token=None): """ Makes sure that the contest is running for the user, if any. If the user has a time window it is also checked. :param token: The optional token of the user. """ extra_time = None start_delay = None if token: Validators._ensure_window_start(token) user = Database.get_user(token) if user: extra_time = user["extra_time"] start_delay = user["contest_start_delay"] if Database.get_meta("start_time") is None: BaseHandler.raise_exc(Forbidden, "FORBIDDEN", "The contest has not started yet") contest_end = BaseHandler.get_end_time(extra_time) window_end = BaseHandler.get_window_end_time(extra_time, start_delay) now = time.time() # check the contest is not finished if contest_end < now: BaseHandler.raise_exc(Forbidden, "FORBIDDEN", "The contest has ended") # if a window is present check it's not finished if window_end and window_end < now: BaseHandler.raise_exc(Forbidden, "FORBIDDEN", "Your window has ended")
def test_sso_new_user(self): Config.jwt_secret = "lalla" self._insert_data() payload = {"username": "******", "firstName": "koh"} token = jwt.encode(payload, Config.jwt_secret) user = Validators._get_user_from_sso(token, "koh") self.assertEqual("koh", user["token"]) self.assertEqual("koh", Database.get_user("koh")["token"])
def handle(*args, **kwargs): token = Validators._guess_token(**kwargs) ip = kwargs["_ip"] if token is not None and Database.get_user(token) is not None: if Database.register_ip(token, ip): Logger.info( "LOGIN", "User %s logged in from %s for the first " "time" % (token, ip)) del kwargs["_ip"] return handler(*args, **kwargs)
def handle(*args, **kwargs): if "_request" in kwargs: request = kwargs["_request"] jwt_token = request.cookies.get("token", None) else: jwt_token = None token = kwargs["token"] user = Database.get_user(token) if not user and not Config.jwt_secret: BaseHandler.raise_exc(Forbidden, "FORBIDDEN", "No such user") elif not user and Config.jwt_secret and jwt_token: kwargs["user"] = Validators._get_user_from_sso( jwt_token, token) elif not user and Config.jwt_secret and not jwt_token: BaseHandler.raise_exc(Forbidden, "FORBIDDEN", "Please login at %s" % Config.sso_url) elif not Config.jwt_secret and not user["sso_user"]: kwargs["user"] = user elif not Config.jwt_secret and user["sso_user"]: BaseHandler.raise_exc( Forbidden, "FORBIDDEN", "No login method available for this user") elif Config.jwt_secret and not user["sso_user"]: kwargs["user"] = user elif Config.jwt_secret and user["sso_user"]: kwargs["user"] = Validators._get_user_from_sso( jwt_token, token) else: BaseHandler.raise_exc( BadRequest, # pragma: nocover "INTERNAL_ERROR", "Login failed") # makes sure the window starts if Validators._ensure_window_start(token): kwargs["user"] = Database.get_user(token) del kwargs["token"] if "_request" in kwargs: del kwargs["_request"] return handler(*args, **kwargs)
def test_set_extra_time_user(self): Database.c.execute( "INSERT INTO users (token, name, surname, extra_time) VALUES (" "'user token', 'a', 'b', 0)") self.admin_handler.set_extra_time(admin_token="ADMIN-TOKEN", extra_time=42, _ip="1.2.3.4", token="user token") user = Database.get_user("user token") self.assertEqual(42, user["extra_time"])
def _ensure_window_start(token): """ Makes sure that the window of the user has been started :param token: The token of the user :return: True if the user has been updated """ if not Database.get_meta("window_duration", None): return False user = Database.get_user(token) if not user: return False start_delay = user["contest_start_delay"] if start_delay is not None: return False start = Database.get_meta("start_time", type=int) if start is None: return False now = time.time() delay = now - start Database.set_start_delay(token, delay) Logger.info("WINDOW_START", "Contest started for %s after %d" % (token, delay)) return True