def validate_file(handler): """ Ensure a file is present in the request. The file must be provided in a multipart/form and the field must be named "file". It provides the handler with a "file" argument which is a dict with 2 properties: "name" and "content" """ def handle(*args, **kwargs): return handler(*args, **kwargs) HandlerParams.initialize_handler_params(handle, handler) HandlerParams.add_handler_param(handle, "file", None, True) return handle
def validate_token(handler): """ Expects token in the request and provides user to the handler """ 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) HandlerParams.initialize_handler_params(handle, handler) HandlerParams.add_handler_param(handle, "_request", None) HandlerParams.add_handler_param(handle, "token", str) HandlerParams.remove_handler_param(handle, "user") return handle
def admin_only(handler): """ Ensure the handler is called from an admin. The `admin_token` param is required """ def handle(*args, **kwargs): admin_token = kwargs["admin_token"].strip().upper() ip = kwargs["_ip"] Validators._validate_admin_token(admin_token, ip) del kwargs["admin_token"] del kwargs["_ip"] return handler(*args, **kwargs) HandlerParams.initialize_handler_params(handle, handler) HandlerParams.add_handler_param(handle, "admin_token", str) HandlerParams.add_handler_param(handle, "_ip", str) return handle
def contest_started(handler): """ Ensure the handler is called only when the contest has been started. """ def handle(*args, **kwargs): Validators._ensure_contest_started() return handler(*args, **kwargs) return HandlerParams.initialize_handler_params(handle, handler)
def closure(handler): def handle(*args, **kwargs): if param in kwargs: thing = getter(kwargs[param]) if thing is None: BaseHandler.raise_exc(Forbidden, "FORBIDDEN", "No such " + name) del kwargs[param] else: thing = None kwargs[name] = thing return handler(*args, **kwargs) HandlerParams.initialize_handler_params(handle, handler) HandlerParams.add_handler_param(handle, param, str, required=required) # the case when the name of the model corresponds with the param if name != param: HandlerParams.remove_handler_param(handle, name) return handle
def register_user_ip(handler): """ Guess the token from the request and log the ip of the client in the database. If the token cannot be guessed nothing is logged. """ 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) HandlerParams.initialize_handler_params(handle, handler) HandlerParams.add_handler_param(handle, "_ip", str) return handle
def during_contest(handler): """ Ensure the handler is called only when the contest is running. Because the contest could end at different times for each user it needs to guess the user token from the parameters. If the guess fails the user extra time is ignored """ def handle(*args, **kwargs): token = Validators._guess_token(**kwargs) Validators._ensure_contest_running(token) return handler(*args, **kwargs) return HandlerParams.initialize_handler_params(handle, handler)