Example #1
0
    def set_cookie(self, name, value, expires=None, max_age=None, domain=None, path=None, secure=True, http_only=True):
        """Set a response cookie.

        Note:
            This method can be called multiple times to add one or
            more cookies to the response.

        See Also:
            To learn more about setting cookies, see
            :ref:`Setting Cookies <setting-cookies>`. The parameters
            listed below correspond to those defined in `RFC 6265`_.

        Args:
            name (str): Cookie name
            value (str): Cookie value

        Keyword Args:
            expires (datetime): Specifies when the cookie should expire.
                By default, cookies expire when the user agent exits.

                (See also: RFC 6265, Section 4.1.2.1)
            max_age (int): Defines the lifetime of the cookie in
                seconds. By default, cookies expire when the user agent
                exits. If both `max_age` and `expires` are set, the
                latter is ignored by the user agent.

                Note:
                    Coercion to ``int`` is attempted if provided with
                    ``float`` or ``str``.

                (See also: RFC 6265, Section 4.1.2.2)

            domain (str): Restricts the cookie to a specific domain and
                any subdomains of that domain. By default, the user
                agent will return the cookie only to the origin server.
                When overriding this default behavior, the specified
                domain must include the origin server. Otherwise, the
                user agent will reject the cookie.

                (See also: RFC 6265, Section 4.1.2.3)

            path (str): Scopes the cookie to the given path plus any
                subdirectories under that path (the "/" character is
                interpreted as a directory separator). If the cookie
                does not specify a path, the user agent defaults to the
                path component of the requested URI.

                Warning:
                    User agent interfaces do not always isolate
                    cookies by path, and so this should not be
                    considered an effective security measure.

                (See also: RFC 6265, Section 4.1.2.4)

            secure (bool): Direct the client to only return the cookie
                in subsequent requests if they are made over HTTPS
                (default: ``True``). This prevents attackers from
                reading sensitive cookie data.

                Warning:
                    For the `secure` cookie attribute to be effective,
                    your application will need to enforce HTTPS.

                (See also: RFC 6265, Section 4.1.2.5)

            http_only (bool): Direct the client to only transfer the
                cookie with unscripted HTTP requests
                (default: ``True``). This is intended to mitigate some
                forms of cross-site scripting.

                (See also: RFC 6265, Section 4.1.2.6)

        Raises:
            KeyError: `name` is not a valid cookie name.
            ValueError: `value` is not a valid cookie value.

        .. _RFC 6265:
            http://tools.ietf.org/html/rfc6265

        """

        if not is_ascii_encodable(name):
            raise KeyError('"name" is not ascii encodable')
        if not is_ascii_encodable(value):
            raise ValueError('"value" is not ascii encodable')

        if PY2:
            name = str(name)
            value = str(value)

        if self._cookies is None:
            self._cookies = SimpleCookie()

        try:
            self._cookies[name] = value
        except CookieError as e:  # pragma: no cover
            # NOTE(tbug): we raise a KeyError here, to avoid leaking
            # the CookieError to the user. SimpleCookie (well, BaseCookie)
            # only throws CookieError on issues with the cookie key
            raise KeyError(str(e))

        if expires:
            # set Expires on cookie. Format is Wdy, DD Mon YYYY HH:MM:SS GMT

            # NOTE(tbug): we never actually need to
            # know that GMT is named GMT when formatting cookies.
            # It is a function call less to just write "GMT" in the fmt string:
            fmt = "%a, %d %b %Y %H:%M:%S GMT"
            if expires.tzinfo is None:
                # naive
                self._cookies[name]["expires"] = expires.strftime(fmt)
            else:
                # aware
                gmt_expires = expires.astimezone(GMT_TIMEZONE)
                self._cookies[name]["expires"] = gmt_expires.strftime(fmt)

        if max_age:
            # RFC 6265 section 5.2.2 says about the max-age value:
            #   "If the remainder of attribute-value contains a non-DIGIT
            #    character, ignore the cookie-av."
            # That is, RFC-compliant response parsers will ignore the max-age
            # attribute if the value contains a dot, as in floating point
            # numbers. Therefore, attempt to convert the value to an integer.
            self._cookies[name]["max-age"] = int(max_age)

        if domain:
            self._cookies[name]["domain"] = domain

        if path:
            self._cookies[name]["path"] = path

        if secure:
            self._cookies[name]["secure"] = secure

        if http_only:
            self._cookies[name]["httponly"] = http_only
Example #2
0
    def set_cookie(self, name, value, expires=None, max_age=None,
                   domain=None, path=None, secure=True, http_only=True):
        """Set a response cookie.

        Note:
            This method can be called multiple times to add one or
            more cookies to the response.

        See Also:
            To learn more about setting cookies, see
            :ref:`Setting Cookies <setting-cookies>`. The parameters listed
            below correspond to those defined in `RFC 6265`_.

        Args:
            name (str):
                Cookie name
            value (str):
                Cookie value
            expires (datetime): Specifies when the cookie should expire. By
                default, cookies expire when the user agent exits.
            max_age (int): Defines the lifetime of the cookie in seconds.
                After the specified number of seconds elapse, the client
                should discard the cookie.
            domain (str): Specifies the domain for which the cookie is valid.
                An explicitly specified domain must always start with a dot.
                A value of 0 means the cookie should be discarded immediately.
            path (str): Specifies the subset of URLs to
                which this cookie applies.
            secure (bool): Direct the client to use only secure means to
                contact the origin server whenever it sends back this cookie
                (default: ``True``). Warning: You will also need to enforce
                HTTPS for the cookies to be transfered securely.
            http_only (bool): Direct the client to only transfer the cookie
                with unscripted HTTP requests (default: ``True``). This is
                intended to mitigate some forms of cross-site scripting.

        Raises:
            KeyError: `name` is not a valid cookie name.
            ValueError: `value` is not a valid cookie value.

        .. _RFC 6265:
            http://tools.ietf.org/html/rfc6265

        """

        if not is_ascii_encodable(name):
            raise KeyError('"name" is not ascii encodable')
        if not is_ascii_encodable(value):
            raise ValueError('"value" is not ascii encodable')

        if PY2:  # pragma: no cover
            name = str(name)
            value = str(value)

        if self._cookies is None:
            self._cookies = SimpleCookie()

        try:
            self._cookies[name] = value
        except CookieError as e:  # pragma: no cover
            # NOTE(tbug): we raise a KeyError here, to avoid leaking
            # the CookieError to the user. SimpleCookie (well, BaseCookie)
            # only throws CookieError on issues with the cookie key
            raise KeyError(str(e))

        if expires:
            # set Expires on cookie. Format is Wdy, DD Mon YYYY HH:MM:SS GMT

            # NOTE(tbug): we never actually need to
            # know that GMT is named GMT when formatting cookies.
            # It is a function call less to just write "GMT" in the fmt string:
            fmt = "%a, %d %b %Y %H:%M:%S GMT"
            if expires.tzinfo is None:
                # naive
                self._cookies[name]["expires"] = expires.strftime(fmt)
            else:
                # aware
                gmt_expires = expires.astimezone(GMT_TIMEZONE)
                self._cookies[name]["expires"] = gmt_expires.strftime(fmt)

        if max_age:
            self._cookies[name]["max-age"] = max_age

        if domain:
            self._cookies[name]["domain"] = domain

        if path:
            self._cookies[name]["path"] = path

        if secure:
            self._cookies[name]["secure"] = secure

        if http_only:
            self._cookies[name]["httponly"] = http_only
Example #3
0
    def set_cookie(self, name, value, expires=None, max_age=None,
                   domain=None, path=None, secure=True, http_only=True):
        """Set a response cookie.

        Note:
            :meth:`~.set_cookie` is capable of setting multiple cookies
            with specified cookie properties on the same request.
            Currently :meth:`~.set_header` and :meth:`~.append_header` are
            not capable of this.

        Args:
            name (str):
                Cookie name
            value (str):
                Cookie value
            expires (datetime): Defines when the cookie should expire.
                the default is to expire when the browser is closed.
            max_age (int): The Max-Age attribute defines the lifetime of the
                cookie, in seconds.  The delta-seconds value is a decimal non-
                negative integer.  After delta-seconds seconds elapse,
                the client should discard the cookie.
            domain (str): The Domain attribute specifies the domain for
                which the cookie is valid.
                An explicitly specified domain must always start with a dot.
                A value of 0 means the cookie should be discarded immediately.
            path (str): The Path attribute specifies the subset of URLs to
                which this cookie applies.
            secure (bool) (default: True): The Secure attribute directs the
                user agent to use only secure means to contact the origin
                server whenever it sends back this cookie.
                Warning: You will also need to enforce HTTPS for the cookies
                to be transfered securely.
            http_only (bool) (default: True):
                The attribute http_only specifies that the cookie
                is  only transferred in HTTP requests, and is not accessible
                through JavaScript. This is intended to mitigate some forms
                of cross-site scripting.
        Note:
            Kwargs and their valid values are all
            specified in http://tools.ietf.org/html/rfc6265

        See Also:
            :ref:`Setting Cookies <setting-cookies>`

        Raises:
            KeyError if ``name`` is not a valid cookie name.

        """

        if not is_ascii_encodable(name):
            raise KeyError('"name" is not ascii encodable')
        if not is_ascii_encodable(value):
            raise ValueError('"value" is not ascii encodable')

        if six.PY2:  # pragma: no cover
            name = str(name)
            value = str(value)

        if self._cookies is None:
            self._cookies = SimpleCookie()

        try:
            self._cookies[name] = value
        except CookieError as e:  # pragma: no cover
            # NOTE(tbug): we raise a KeyError here, to avoid leaking
            # the CookieError to the user. SimpleCookie (well, BaseCookie)
            # only throws CookieError on issues with the cookie key
            raise KeyError(str(e))

        if expires:
            # set Expires on cookie. Format is Wdy, DD Mon YYYY HH:MM:SS GMT

            # NOTE(tbug): we never actually need to
            # know that GMT is named GMT when formatting cookies.
            # It is a function call less to just write "GMT" in the fmt string:
            fmt = "%a, %d %b %Y %H:%M:%S GMT"
            if expires.tzinfo is None:
                # naive
                self._cookies[name]["expires"] = expires.strftime(fmt)
            else:
                # aware
                gmt_expires = expires.astimezone(GMT_TIMEZONE)
                self._cookies[name]["expires"] = gmt_expires.strftime(fmt)

        if max_age:
            self._cookies[name]["max-age"] = max_age

        if domain:
            self._cookies[name]["domain"] = domain

        if path:
            self._cookies[name]["path"] = path

        if secure:
            self._cookies[name]["secure"] = secure

        if http_only:
            self._cookies[name]["httponly"] = http_only
Example #4
0
    def set_cookie(self, name, value, expires=None, max_age=None,
                   domain=None, path=None, secure=True, http_only=True):
        """Set a response cookie.

        Note:
            This method can be called multiple times to add one or
            more cookies to the response.

        See Also:
            To learn more about setting cookies, see
            :ref:`Setting Cookies <setting-cookies>`. The parameters listed
            below correspond to those defined in `RFC 6265`_.

        Args:
            name (str):
                Cookie name
            value (str):
                Cookie value
            expires (datetime): Specifies when the cookie should expire. By
                default, cookies expire when the user agent exits.
            max_age (int): Defines the lifetime of the cookie in seconds.
                After the specified number of seconds elapse, the client
                should discard the cookie. Coercion to `int` is attempted
                if provided with `float` or `str`.
            domain (str): Specifies the domain for which the cookie is valid.
                An explicitly specified domain must always start with a dot.
                A value of 0 means the cookie should be discarded immediately.
            path (str): Specifies the subset of URLs to
                which this cookie applies.
            secure (bool): Direct the client to only return the cookie in
                subsequent requests if they are made over HTTPS
                (default: ``True``). This prevents attackers from reading
                sensitive cookie data. Note that for the `secure` cookie
                attribute to be effective, your application will need to
                enforce HTTPS. See also: `RFC 6265, Section 4.1.2.5`_.
            http_only (bool): Direct the client to only transfer the cookie
                with unscripted HTTP requests (default: ``True``). This is
                intended to mitigate some forms of cross-site scripting.

        Raises:
            KeyError: `name` is not a valid cookie name.
            ValueError: `value` is not a valid cookie value.

        .. _RFC 6265:
            http://tools.ietf.org/html/rfc6265

        .. _RFC 6265, Section 4.1.2.5:
            https://tools.ietf.org/html/rfc6265#section-4.1.2.5

        """

        if not is_ascii_encodable(name):
            raise KeyError('"name" is not ascii encodable')
        if not is_ascii_encodable(value):
            raise ValueError('"value" is not ascii encodable')

        if PY2:
            name = str(name)
            value = str(value)

        if self._cookies is None:
            self._cookies = SimpleCookie()

        try:
            self._cookies[name] = value
        except CookieError as e:  # pragma: no cover
            # NOTE(tbug): we raise a KeyError here, to avoid leaking
            # the CookieError to the user. SimpleCookie (well, BaseCookie)
            # only throws CookieError on issues with the cookie key
            raise KeyError(str(e))

        if expires:
            # set Expires on cookie. Format is Wdy, DD Mon YYYY HH:MM:SS GMT

            # NOTE(tbug): we never actually need to
            # know that GMT is named GMT when formatting cookies.
            # It is a function call less to just write "GMT" in the fmt string:
            fmt = '%a, %d %b %Y %H:%M:%S GMT'
            if expires.tzinfo is None:
                # naive
                self._cookies[name]['expires'] = expires.strftime(fmt)
            else:
                # aware
                gmt_expires = expires.astimezone(GMT_TIMEZONE)
                self._cookies[name]['expires'] = gmt_expires.strftime(fmt)

        if max_age:
            # RFC 6265 section 5.2.2 says about the max-age value:
            #   "If the remainder of attribute-value contains a non-DIGIT
            #    character, ignore the cookie-av."
            # That is, RFC-compliant response parsers will ignore the max-age
            # attribute if the value contains a dot, as in floating point
            # numbers. Therefore, attempt to convert the value to an integer.
            self._cookies[name]['max-age'] = int(max_age)

        if domain:
            self._cookies[name]['domain'] = domain

        if path:
            self._cookies[name]['path'] = path

        if secure:
            self._cookies[name]['secure'] = secure

        if http_only:
            self._cookies[name]['httponly'] = http_only
Example #5
0
    def set_cookie(self,
                   name,
                   value,
                   expires=None,
                   max_age=None,
                   domain=None,
                   path=None,
                   secure=None,
                   http_only=True):
        """Set a response cookie.

        Note:
            This method can be called multiple times to add one or
            more cookies to the response.

        See Also:
            To learn more about setting cookies, see
            :ref:`Setting Cookies <setting-cookies>`. The parameters
            listed below correspond to those defined in `RFC 6265`_.

        Args:
            name (str): Cookie name
            value (str): Cookie value

        Keyword Args:
            expires (datetime): Specifies when the cookie should expire.
                By default, cookies expire when the user agent exits.

                (See also: RFC 6265, Section 4.1.2.1)
            max_age (int): Defines the lifetime of the cookie in
                seconds. By default, cookies expire when the user agent
                exits. If both `max_age` and `expires` are set, the
                latter is ignored by the user agent.

                Note:
                    Coercion to ``int`` is attempted if provided with
                    ``float`` or ``str``.

                (See also: RFC 6265, Section 4.1.2.2)

            domain (str): Restricts the cookie to a specific domain and
                any subdomains of that domain. By default, the user
                agent will return the cookie only to the origin server.
                When overriding this default behavior, the specified
                domain must include the origin server. Otherwise, the
                user agent will reject the cookie.

                (See also: RFC 6265, Section 4.1.2.3)

            path (str): Scopes the cookie to the given path plus any
                subdirectories under that path (the "/" character is
                interpreted as a directory separator). If the cookie
                does not specify a path, the user agent defaults to the
                path component of the requested URI.

                Warning:
                    User agent interfaces do not always isolate
                    cookies by path, and so this should not be
                    considered an effective security measure.

                (See also: RFC 6265, Section 4.1.2.4)

            secure (bool): Direct the client to only return the cookie
                in subsequent requests if they are made over HTTPS
                (default: ``True``). This prevents attackers from
                reading sensitive cookie data.

                Note:
                    The default value for this argument is normally
                    ``True``, but can be modified by setting
                    :py:attr:`~.ResponseOptions.secure_cookies_by_default`
                    via :any:`API.resp_options`.

                Warning:
                    For the `secure` cookie attribute to be effective,
                    your application will need to enforce HTTPS.

                (See also: RFC 6265, Section 4.1.2.5)

            http_only (bool): Direct the client to only transfer the
                cookie with unscripted HTTP requests
                (default: ``True``). This is intended to mitigate some
                forms of cross-site scripting.

                (See also: RFC 6265, Section 4.1.2.6)

        Raises:
            KeyError: `name` is not a valid cookie name.
            ValueError: `value` is not a valid cookie value.

        .. _RFC 6265:
            http://tools.ietf.org/html/rfc6265

        """

        if not is_ascii_encodable(name):
            raise KeyError('"name" is not ascii encodable')
        if not is_ascii_encodable(value):
            raise ValueError('"value" is not ascii encodable')

        name = str(name)
        value = str(value)

        if self._cookies is None:
            self._cookies = SimpleCookie()

        try:
            self._cookies[name] = value
        except CookieError as e:  # pragma: no cover
            # NOTE(tbug): we raise a KeyError here, to avoid leaking
            # the CookieError to the user. SimpleCookie (well, BaseCookie)
            # only throws CookieError on issues with the cookie key
            raise KeyError(str(e))

        if expires:
            # set Expires on cookie. Format is Wdy, DD Mon YYYY HH:MM:SS GMT

            # NOTE(tbug): we never actually need to
            # know that GMT is named GMT when formatting cookies.
            # It is a function call less to just write "GMT" in the fmt string:
            fmt = '%a, %d %b %Y %H:%M:%S GMT'
            if expires.tzinfo is None:
                # naive
                self._cookies[name]['expires'] = expires.strftime(fmt)
            else:
                # aware
                gmt_expires = expires.astimezone(GMT_TIMEZONE)
                self._cookies[name]['expires'] = gmt_expires.strftime(fmt)

        if max_age:
            # RFC 6265 section 5.2.2 says about the max-age value:
            #   "If the remainder of attribute-value contains a non-DIGIT
            #    character, ignore the cookie-av."
            # That is, RFC-compliant response parsers will ignore the max-age
            # attribute if the value contains a dot, as in floating point
            # numbers. Therefore, attempt to convert the value to an integer.
            self._cookies[name]['max-age'] = int(max_age)

        if domain:
            self._cookies[name]['domain'] = domain

        if path:
            self._cookies[name]['path'] = path

        if secure is None:
            is_secure = self.options.secure_cookies_by_default
        else:
            is_secure = secure

        if is_secure:
            self._cookies[name]['secure'] = True

        if http_only:
            self._cookies[name]['httponly'] = http_only
Example #6
0
    def set_cookie(self,
                   name,
                   value,
                   expires=None,
                   max_age=None,
                   domain=None,
                   path=None,
                   secure=True,
                   http_only=True):
        """Set a response cookie.

        Note:
            This method can be called multiple times to add one or
            more cookies to the response.

        See Also:
            To learn more about setting cookies, see
            :ref:`Setting Cookies <setting-cookies>`. The parameters listed
            below correspond to those defined in `RFC 6265`_.

        Args:
            name (str):
                Cookie name
            value (str):
                Cookie value
            expires (datetime): Specifies when the cookie should expire. By
                default, cookies expire when the user agent exits.
            max_age (int): Defines the lifetime of the cookie in seconds.
                After the specified number of seconds elapse, the client
                should discard the cookie. Coercion to `int` is attempted
                if provided with `float` or `str`.
            domain (str): Specifies the domain for which the cookie is valid.
                An explicitly specified domain must always start with a dot.
                A value of 0 means the cookie should be discarded immediately.
            path (str): Specifies the subset of URLs to
                which this cookie applies.
            secure (bool): Direct the client to only return the cookie in
                subsequent requests if they are made over HTTPS
                (default: ``True``). This prevents attackers from reading
                sensitive cookie data. Note that for the `secure` cookie
                attribute to be effective, your application will need to
                enforce HTTPS. See also: `RFC 6265, Section 4.1.2.5`_.
            http_only (bool): Direct the client to only transfer the cookie
                with unscripted HTTP requests (default: ``True``). This is
                intended to mitigate some forms of cross-site scripting.

        Raises:
            KeyError: `name` is not a valid cookie name.
            ValueError: `value` is not a valid cookie value.

        .. _RFC 6265:
            http://tools.ietf.org/html/rfc6265

        .. _RFC 6265, Section 4.1.2.5:
            https://tools.ietf.org/html/rfc6265#section-4.1.2.5

        """

        if not is_ascii_encodable(name):
            raise KeyError('"name" is not ascii encodable')
        if not is_ascii_encodable(value):
            raise ValueError('"value" is not ascii encodable')

        if PY2:
            name = str(name)
            value = str(value)

        if self._cookies is None:
            self._cookies = SimpleCookie()

        try:
            self._cookies[name] = value
        except CookieError as e:  # pragma: no cover
            # NOTE(tbug): we raise a KeyError here, to avoid leaking
            # the CookieError to the user. SimpleCookie (well, BaseCookie)
            # only throws CookieError on issues with the cookie key
            raise KeyError(str(e))

        if expires:
            # set Expires on cookie. Format is Wdy, DD Mon YYYY HH:MM:SS GMT

            # NOTE(tbug): we never actually need to
            # know that GMT is named GMT when formatting cookies.
            # It is a function call less to just write "GMT" in the fmt string:
            fmt = '%a, %d %b %Y %H:%M:%S GMT'
            if expires.tzinfo is None:
                # naive
                self._cookies[name]['expires'] = expires.strftime(fmt)
            else:
                # aware
                gmt_expires = expires.astimezone(GMT_TIMEZONE)
                self._cookies[name]['expires'] = gmt_expires.strftime(fmt)

        if max_age:
            # RFC 6265 section 5.2.2 says about the max-age value:
            #   "If the remainder of attribute-value contains a non-DIGIT
            #    character, ignore the cookie-av."
            # That is, RFC-compliant response parsers will ignore the max-age
            # attribute if the value contains a dot, as in floating point
            # numbers. Therefore, attempt to convert the value to an integer.
            self._cookies[name]['max-age'] = int(max_age)

        if domain:
            self._cookies[name]['domain'] = domain

        if path:
            self._cookies[name]['path'] = path

        if secure:
            self._cookies[name]['secure'] = secure

        if http_only:
            self._cookies[name]['httponly'] = http_only
Example #7
0
    def set_cookie(
        self,
        name,
        value,
        expires=None,
        max_age=None,
        domain=None,
        path=None,
        secure=None,
        http_only=True,
        same_site=None,
    ):
        """Set a response cookie.

        Note:
            This method can be called multiple times to add one or
            more cookies to the response.

        See Also:
            To learn more about setting cookies, see
            :ref:`Setting Cookies <setting-cookies>`. The parameters
            listed below correspond to those defined in `RFC 6265`_.

        Args:
            name (str): Cookie name
            value (str): Cookie value

        Keyword Args:
            expires (datetime): Specifies when the cookie should expire.
                By default, cookies expire when the user agent exits.

                (See also: RFC 6265, Section 4.1.2.1)
            max_age (int): Defines the lifetime of the cookie in
                seconds. By default, cookies expire when the user agent
                exits. If both `max_age` and `expires` are set, the
                latter is ignored by the user agent.

                Note:
                    Coercion to ``int`` is attempted if provided with
                    ``float`` or ``str``.

                (See also: RFC 6265, Section 4.1.2.2)

            domain (str): Restricts the cookie to a specific domain and
                any subdomains of that domain. By default, the user
                agent will return the cookie only to the origin server.
                When overriding this default behavior, the specified
                domain must include the origin server. Otherwise, the
                user agent will reject the cookie.

                Note:
                    Cookies do not provide isolation by port, so the domain
                    should not provide one. (See also: RFC 6265, Section 8.5)

                (See also: RFC 6265, Section 4.1.2.3)

            path (str): Scopes the cookie to the given path plus any
                subdirectories under that path (the "/" character is
                interpreted as a directory separator). If the cookie
                does not specify a path, the user agent defaults to the
                path component of the requested URI.

                Warning:
                    User agent interfaces do not always isolate
                    cookies by path, and so this should not be
                    considered an effective security measure.

                (See also: RFC 6265, Section 4.1.2.4)

            secure (bool): Direct the client to only return the cookie
                in subsequent requests if they are made over HTTPS
                (default: ``True``). This prevents attackers from
                reading sensitive cookie data.

                Note:
                    The default value for this argument is normally
                    ``True``, but can be modified by setting
                    :py:attr:`~.ResponseOptions.secure_cookies_by_default`
                    via :any:`App.resp_options`.

                Warning:
                    For the `secure` cookie attribute to be effective,
                    your application will need to enforce HTTPS.

                (See also: RFC 6265, Section 4.1.2.5)

            http_only (bool): The HttpOnly attribute limits the scope of the
                cookie to HTTP requests.  In particular, the attribute
                instructs the user agent to omit the cookie when providing
                access to cookies via "non-HTTP" APIs. This is intended to
                mitigate some forms of cross-site scripting. (default: ``True``)

                Note:
                    HttpOnly cookies are not visible to javascript scripts
                    in the browser. They are automatically sent to the server
                    on javascript ``XMLHttpRequest`` or ``Fetch`` requests.

                (See also: RFC 6265, Section 4.1.2.6)

            same_site (str): Helps protect against CSRF attacks by restricting
                when a cookie will be attached to the request by the user agent.
                When set to ``'Strict'``, the cookie will only be sent along
                with "same-site" requests.  If the value is ``'Lax'``, the
                cookie will be sent with same-site requests, and with
                "cross-site" top-level navigations.  If the value is ``'None'``,
                the cookie will be sent with same-site and cross-site requests.
                Finally, when this attribute is not set on the cookie, the
                attribute will be treated as if it had been set to ``'None'``.

                (See also: `Same-Site RFC Draft`_)

        Raises:
            KeyError: `name` is not a valid cookie name.
            ValueError: `value` is not a valid cookie value.

        .. _RFC 6265:
            http://tools.ietf.org/html/rfc6265

        .. _Same-Site RFC Draft:
            https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1.2.7

        """

        if not is_ascii_encodable(name):
            raise KeyError('name is not ascii encodable')
        if not is_ascii_encodable(value):
            raise ValueError('value is not ascii encodable')

        value = str(value)

        if self._cookies is None:
            self._cookies = http_cookies.SimpleCookie()

        try:
            self._cookies[name] = value
        except http_cookies.CookieError as e:  # pragma: no cover
            # NOTE(tbug): we raise a KeyError here, to avoid leaking
            # the CookieError to the user. SimpleCookie (well, BaseCookie)
            # only throws CookieError on issues with the cookie key
            raise KeyError(str(e))

        if expires:
            # set Expires on cookie. Format is Wdy, DD Mon YYYY HH:MM:SS GMT

            # NOTE(tbug): we never actually need to
            # know that GMT is named GMT when formatting cookies.
            # It is a function call less to just write "GMT" in the fmt string:
            fmt = '%a, %d %b %Y %H:%M:%S GMT'
            if expires.tzinfo is None:
                # naive
                self._cookies[name]['expires'] = expires.strftime(fmt)
            else:
                # aware
                gmt_expires = expires.astimezone(GMT_TIMEZONE)
                self._cookies[name]['expires'] = gmt_expires.strftime(fmt)

        if max_age:
            # RFC 6265 section 5.2.2 says about the max-age value:
            #   "If the remainder of attribute-value contains a non-DIGIT
            #    character, ignore the cookie-av."
            # That is, RFC-compliant response parsers will ignore the max-age
            # attribute if the value contains a dot, as in floating point
            # numbers. Therefore, attempt to convert the value to an integer.
            self._cookies[name]['max-age'] = int(max_age)

        if domain:
            self._cookies[name]['domain'] = domain

        if path:
            self._cookies[name]['path'] = path

        is_secure = self.options.secure_cookies_by_default if secure is None else secure

        if is_secure:
            self._cookies[name]['secure'] = True

        if http_only:
            self._cookies[name]['httponly'] = http_only

        # PERF(kgriffs): Morsel.__setitem__() will lowercase this anyway,
        #   so we can just pass this in and when __setitem__() calls
        #   lower() it will be very slightly faster.
        if same_site:
            same_site = same_site.lower()

            if same_site not in _RESERVED_SAMESITE_VALUES:
                raise ValueError(
                    "same_site must be set to either 'lax', 'strict', or 'none'"
                )

            self._cookies[name]['samesite'] = same_site.capitalize()
Example #8
0
    def set_cookie(self,
                   name,
                   value,
                   expires=None,
                   max_age=None,
                   domain=None,
                   path=None,
                   secure=True,
                   http_only=True):
        """Set a response cookie.

        Note:
            This method can be called multiple times to add one or
            more cookies to the response.

        See Also:
            To learn more about setting cookies, see
            :ref:`Setting Cookies <setting-cookies>`. The parameters listed
            below correspond to those defined in `RFC 6265`_.

        Args:
            name (str):
                Cookie name
            value (str):
                Cookie value
            expires (datetime): Specifies when the cookie should expire. By
                default, cookies expire when the user agent exits.
            max_age (int): Defines the lifetime of the cookie in seconds.
                After the specified number of seconds elapse, the client
                should discard the cookie.
            domain (str): Specifies the domain for which the cookie is valid.
                An explicitly specified domain must always start with a dot.
                A value of 0 means the cookie should be discarded immediately.
            path (str): Specifies the subset of URLs to
                which this cookie applies.
            secure (bool): Direct the client to use only secure means to
                contact the origin server whenever it sends back this cookie
                (default: ``True``). Warning: You will also need to enforce
                HTTPS for the cookies to be transfered securely.
            http_only (bool): Direct the client to only transfer the cookie
                with unscripted HTTP requests (default: ``True``). This is
                intended to mitigate some forms of cross-site scripting.

        Raises:
            KeyError: `name` is not a valid cookie name.
            ValueError: `value` is not a valid cookie value.

        .. _RFC 6265:
            http://tools.ietf.org/html/rfc6265

        """

        if not is_ascii_encodable(name):
            raise KeyError('"name" is not ascii encodable')
        if not is_ascii_encodable(value):
            raise ValueError('"value" is not ascii encodable')

        if PY2:  # pragma: no cover
            name = str(name)
            value = str(value)

        if self._cookies is None:
            self._cookies = SimpleCookie()

        try:
            self._cookies[name] = value
        except CookieError as e:  # pragma: no cover
            # NOTE(tbug): we raise a KeyError here, to avoid leaking
            # the CookieError to the user. SimpleCookie (well, BaseCookie)
            # only throws CookieError on issues with the cookie key
            raise KeyError(str(e))

        if expires:
            # set Expires on cookie. Format is Wdy, DD Mon YYYY HH:MM:SS GMT

            # NOTE(tbug): we never actually need to
            # know that GMT is named GMT when formatting cookies.
            # It is a function call less to just write "GMT" in the fmt string:
            fmt = "%a, %d %b %Y %H:%M:%S GMT"
            if expires.tzinfo is None:
                # naive
                self._cookies[name]["expires"] = expires.strftime(fmt)
            else:
                # aware
                gmt_expires = expires.astimezone(GMT_TIMEZONE)
                self._cookies[name]["expires"] = gmt_expires.strftime(fmt)

        if max_age:
            self._cookies[name]["max-age"] = max_age

        if domain:
            self._cookies[name]["domain"] = domain

        if path:
            self._cookies[name]["path"] = path

        if secure:
            self._cookies[name]["secure"] = secure

        if http_only:
            self._cookies[name]["httponly"] = http_only
Example #9
0
    def set_cookie(self,
                   name,
                   value,
                   expires=None,
                   max_age=None,
                   domain=None,
                   path=None,
                   secure=True,
                   http_only=True):
        """Set a response cookie.

        Note:
            :meth:`~.set_cookie` is capable of setting multiple cookies
            with specified cookie properties on the same request.
            Currently :meth:`~.set_header` and :meth:`~.append_header` are
            not capable of this.

        Args:
            name (str):
                Cookie name
            value (str):
                Cookie value
            expires (datetime): Defines when the cookie should expire.
                the default is to expire when the browser is closed.
            max_age (int): The Max-Age attribute defines the lifetime of the
                cookie, in seconds.  The delta-seconds value is a decimal non-
                negative integer.  After delta-seconds seconds elapse,
                the client should discard the cookie.
            domain (str): The Domain attribute specifies the domain for
                which the cookie is valid.
                An explicitly specified domain must always start with a dot.
                A value of 0 means the cookie should be discarded immediately.
            path (str): The Path attribute specifies the subset of URLs to
                which this cookie applies.
            secure (bool) (default: True): The Secure attribute directs the
                user agent to use only secure means to contact the origin
                server whenever it sends back this cookie.
                Warning: You will also need to enforce HTTPS for the cookies
                to be transfered securely.
            http_only (bool) (default: True):
                The attribute http_only specifies that the cookie
                is  only transferred in HTTP requests, and is not accessible
                through JavaScript. This is intended to mitigate some forms
                of cross-site scripting.
        Note:
            Kwargs and their valid values are all
            specified in http://tools.ietf.org/html/rfc6265

        See Also:
            :ref:`Setting Cookies <setting-cookies>`

        Raises:
            KeyError if ``name`` is not a valid cookie name.

        """

        if not is_ascii_encodable(name):
            raise KeyError('"name" is not ascii encodable')
        if not is_ascii_encodable(value):
            raise ValueError('"value" is not ascii encodable')

        if six.PY2:  # pragma: no cover
            name = str(name)
            value = str(value)

        if self._cookies is None:
            self._cookies = SimpleCookie()

        try:
            self._cookies[name] = value
        except CookieError as e:  # pragma: no cover
            # NOTE(tbug): we raise a KeyError here, to avoid leaking
            # the CookieError to the user. SimpleCookie (well, BaseCookie)
            # only throws CookieError on issues with the cookie key
            raise KeyError(str(e))

        if expires:
            # set Expires on cookie. Format is Wdy, DD Mon YYYY HH:MM:SS GMT

            # NOTE(tbug): we never actually need to
            # know that GMT is named GMT when formatting cookies.
            # It is a function call less to just write "GMT" in the fmt string:
            fmt = "%a, %d %b %Y %H:%M:%S GMT"
            if expires.tzinfo is None:
                # naive
                self._cookies[name]["expires"] = expires.strftime(fmt)
            else:
                # aware
                gmt_expires = expires.astimezone(GMT_TIMEZONE)
                self._cookies[name]["expires"] = gmt_expires.strftime(fmt)

        if max_age:
            self._cookies[name]["max-age"] = max_age

        if domain:
            self._cookies[name]["domain"] = domain

        if path:
            self._cookies[name]["path"] = path

        if secure:
            self._cookies[name]["secure"] = secure

        if http_only:
            self._cookies[name]["httponly"] = http_only