def test_convert_request_arguments_with_encoded_items_to_dict(): """ Assert that a dict of k/v's is correctly created when receiving encoded values. """ arguments = { "key1": [b"value1"], "key2": [b"value2"], "key3": [b"value3"], } expected = { "key1": "value1", "key2": "value2", "key3": "value3", } result = convert_request_to_dict(arguments) assert expected == result
async def authenticate( # noqa: C901 self, handler: BaseHandler, data: dict = None) -> dict: # noqa: C901 """ LTI 1.1 Authenticator. One or more consumer keys/values must be set in the jupyterhub config with the LTI11Authenticator.consumers dict. Args: handler: JupyterHub's Authenticator handler object. For LTI 1.1 requests, the handler is an instance of LTIAuthenticateHandler. data: optional data object Returns: Authentication dictionary Raises: HTTPError if the required values are not in the request """ # log deprecation warning when using the default custom_canvas_user_id setting if self.username_key == "custom_canvas_user_id": self.log.warning( dedent( """The default username_key 'custom_canvas_user_id' will be replaced by 'user_id' in a future release. Set c.LTIAuthenticator.username_key to `custom_canvas_user_id` to preserve current behavior. """)) validator = LTI11LaunchValidator(self.consumers) self.log.debug("Original arguments received in request: %s" % handler.request.arguments) # extract the request arguments to a dict args = convert_request_to_dict(handler.request.arguments) self.log.debug("Decoded args from request: %s" % args) # get the origin protocol protocol = get_client_protocol(handler) self.log.debug("Origin protocol is: %s" % protocol) # build the full launch url value required for oauth1 signatures launch_url = f"{protocol}://{handler.request.host}{handler.request.uri}" self.log.debug("Launch url is: %s" % launch_url) if validator.validate_launch_request(launch_url, handler.request.headers, args): # raise an http error if the username_key is not in the request's arguments. if self.username_key not in args.keys(): self.log.warning( "%s the specified username_key did not match any of the launch request arguments." ) # get the username_key. if empty, fetch the username from the request's user_id value. username = args.get(self.username_key) if not username: username = args.get("user_id") # if username is still empty or none, raise an http error. if not username: raise HTTPError( 400, "The %s value in the launch request is empty or None." % self.username_key, ) # return standard authentication where all launch request arguments are added to the auth_state key # except for the oauth_* arguments. return { "name": username, "auth_state": {k: v for k, v in args.items() if not k.startswith("oauth_")}, }