Mercurial > libervia-web
comparison libervia/server/pages.py @ 1483:595e7fef41f3
merge bookmark @
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 12 Nov 2021 17:48:30 +0100 |
parents | 095e94ca6728 |
children | 774a81a6e8b5 |
comparison
equal
deleted
inserted
replaced
1454:fc91b78b71db | 1483:595e7fef41f3 |
---|---|
544 log.info(_("{page} created").format(page=resource)) | 544 log.info(_("{page} created").format(page=resource)) |
545 else: | 545 else: |
546 log.info(_("{page} reloaded").format(page=resource)) | 546 log.info(_("{page} reloaded").format(page=resource)) |
547 | 547 |
548 def checkCSRF(self, request): | 548 def checkCSRF(self, request): |
549 csrf_token = self.host.getSessionData( | 549 session = self.host.getSessionData( |
550 request, session_iface.ISATSession | 550 request, session_iface.ISATSession |
551 ).csrf_token | 551 ) |
552 if session.profile is None: | |
553 # CSRF doesn't make sense when no user is logged | |
554 log.debug("disabling CSRF check because service profile is used") | |
555 return | |
556 csrf_token = session.csrf_token | |
552 given_csrf = request.getHeader("X-Csrf-Token") | 557 given_csrf = request.getHeader("X-Csrf-Token") |
553 if given_csrf is None: | 558 if given_csrf is None: |
554 try: | 559 try: |
555 given_csrf = self.getPostedData(request, "csrf_token") | 560 given_csrf = self.getPostedData(request, "csrf_token") |
556 except KeyError: | 561 except KeyError: |
575 template_data = request.template_data | 580 template_data = request.template_data |
576 scripts = template_data.setdefault("scripts", utils.OrderedSet()) | 581 scripts = template_data.setdefault("scripts", utils.OrderedSet()) |
577 for name, value in kwargs.items(): | 582 for name, value in kwargs.items(): |
578 if value is None: | 583 if value is None: |
579 value = "null" | 584 value = "null" |
585 elif isinstance(value, str): | |
586 # FIXME: workaround for subtype used by python-dbus (dbus.String) | |
587 # to be removed when we get rid of python-dbus | |
588 value = repr(str(value)) | |
580 else: | 589 else: |
581 value = repr(value) | 590 value = repr(value) |
582 scripts.add(Script(content=f"var {name}={value};")) | 591 scripts.add(Script(content=f"var {name}={value};")) |
583 | 592 |
584 def registerURI(self, uri_tuple, get_uri_cb): | 593 def registerURI(self, uri_tuple, get_uri_cb): |
663 redirect_url=urllib.parse.quote_plus(request.uri) | 672 redirect_url=urllib.parse.quote_plus(request.uri) |
664 if url is None | 673 if url is None |
665 else url.encode("utf-8"), | 674 else url.encode("utf-8"), |
666 ) | 675 ) |
667 | 676 |
668 def getURL(self, *args): | 677 def getURL(self, *args: str, **kwargs: str) -> str: |
669 """retrieve URL of the page set arguments | 678 """retrieve URL of the page set arguments |
670 | 679 |
671 *args(list[unicode]): argument to add to the URL as path elements | 680 @param *args: arguments to add to the URL as path elements empty or None |
672 empty or None arguments will be ignored | 681 arguments will be ignored |
682 @param **kwargs: query parameters | |
673 """ | 683 """ |
674 url_args = [quote(a) for a in args if a] | 684 url_args = [quote(a) for a in args if a] |
675 | 685 |
676 if self.name is not None and self.name in self.pages_redirects: | 686 if self.name is not None and self.name in self.pages_redirects: |
677 # we check for redirection | 687 # we check for redirection |
678 redirect_data = self.pages_redirects[self.name] | 688 redirect_data = self.pages_redirects[self.name] |
679 args_hash = tuple(args) | 689 args_hash = tuple(args) |
680 for limit in range(len(args) + 1): | 690 for limit in range(len(args), -1, -1): |
681 current_hash = args_hash[:limit] | 691 current_hash = args_hash[:limit] |
682 if current_hash in redirect_data: | 692 if current_hash in redirect_data: |
683 url_base = redirect_data[current_hash] | 693 url_base = redirect_data[current_hash] |
684 remaining = args[limit:] | 694 remaining = args[limit:] |
685 remaining_url = "/".join(remaining) | 695 remaining_url = "/".join(remaining) |
686 return os.path.join("/", url_base, remaining_url) | 696 url = urllib.parse.urljoin(url_base, remaining_url) |
687 | 697 break |
688 return os.path.join(self.url, *url_args) | 698 else: |
699 url = os.path.join(self.url, *url_args) | |
700 else: | |
701 url = os.path.join(self.url, *url_args) | |
702 | |
703 if kwargs: | |
704 encoded = urllib.parse.urlencode( | |
705 {k: v for k, v in kwargs.items()} | |
706 ) | |
707 url += f"?{encoded}" | |
708 | |
709 return self.host.checkRedirection( | |
710 self.vhost_root, | |
711 url | |
712 ) | |
689 | 713 |
690 def getCurrentURL(self, request): | 714 def getCurrentURL(self, request): |
691 """retrieve URL used to access this page | 715 """retrieve URL used to access this page |
692 | 716 |
693 @return(unicode): current URL | 717 @return(unicode): current URL |
959 if extra is None: | 983 if extra is None: |
960 extra = {} | 984 extra = {} |
961 else: | 985 else: |
962 assert not {"rsm_max", "rsm_after", "rsm_before", | 986 assert not {"rsm_max", "rsm_after", "rsm_before", |
963 C.KEY_ORDER_BY}.intersection(list(extra.keys())) | 987 C.KEY_ORDER_BY}.intersection(list(extra.keys())) |
964 extra["rsm_max"] = str(page_max) | 988 extra["rsm_max"] = params.get("page_max", str(page_max)) |
965 if order_by is not None: | 989 if order_by is not None: |
966 extra[C.KEY_ORDER_BY] = order_by | 990 extra[C.KEY_ORDER_BY] = order_by |
967 if 'after' in params: | 991 if 'after' in params: |
968 extra['rsm_after'] = params['after'] | 992 extra['rsm_after'] = params['after'] |
969 elif 'before' in params: | 993 elif 'before' in params: |
972 # RSM returns list in order (oldest first), but we want most recent first | 996 # RSM returns list in order (oldest first), but we want most recent first |
973 # so we start by the end | 997 # so we start by the end |
974 extra['rsm_before'] = "" | 998 extra['rsm_before'] = "" |
975 return extra | 999 return extra |
976 | 1000 |
977 def setPagination(self, request, pubsub_data): | 1001 def setPagination(self, request: server.Request, pubsub_data: dict) -> None: |
978 """Add to template_data if suitable | 1002 """Add to template_data if suitable |
979 | 1003 |
980 "previous_page_url" and "next_page_url" will be added using respectively | 1004 "previous_page_url" and "next_page_url" will be added using respectively |
981 "before" and "after" URL parameters | 1005 "before" and "after" URL parameters |
982 @param request(server.Request): current HTTP request | 1006 @param request: current HTTP request |
983 @param pubsub_data(dict): pubsub metadata | 1007 @param pubsub_data: pubsub metadata |
984 """ | 1008 """ |
985 template_data = request.template_data | 1009 template_data = request.template_data |
986 extra = {} | 1010 extra = {} |
987 try: | 1011 try: |
988 rsm = pubsub_data["rsm"] | 1012 rsm = pubsub_data["rsm"] |
993 | 1017 |
994 # if we have a search query, we must keep it | 1018 # if we have a search query, we must keep it |
995 search = self.getPostedData(request, 'search', raise_on_missing=False) | 1019 search = self.getPostedData(request, 'search', raise_on_missing=False) |
996 if search is not None: | 1020 if search is not None: |
997 extra['search'] = search.strip() | 1021 extra['search'] = search.strip() |
1022 | |
1023 # same for page_max | |
1024 page_max = self.getPostedData(request, 'page_max', raise_on_missing=False) | |
1025 if page_max is not None: | |
1026 extra['page_max'] = page_max | |
998 | 1027 |
999 if rsm.get("index", 1) > 0: | 1028 if rsm.get("index", 1) > 0: |
1000 # We only show previous button if it's not the first page already. | 1029 # We only show previous button if it's not the first page already. |
1001 # If we have no index, we default to display the button anyway | 1030 # If we have no index, we default to display the button anyway |
1002 # as we can't know if we are on the first page or not. | 1031 # as we can't know if we are on the first page or not. |
1707 matching value with available translations. | 1736 matching value with available translations. |
1708 """ | 1737 """ |
1709 accept_language = request.getHeader("accept-language") | 1738 accept_language = request.getHeader("accept-language") |
1710 if not accept_language: | 1739 if not accept_language: |
1711 return | 1740 return |
1712 accepted = {a.strip() for a in accept_language.split(',')} | 1741 accepted = [a.strip() for a in accept_language.split(',')] |
1713 available = [str(l) for l in self.host.renderer.translations] | 1742 available = [str(l) for l in self.host.renderer.translations] |
1714 for lang in accepted: | 1743 for lang in accepted: |
1715 lang = lang.split(';')[0].strip().lower() | 1744 lang = lang.split(';')[0].strip().lower() |
1716 if not lang: | 1745 if not lang: |
1717 continue | 1746 continue |
1783 # template_data are the variables passed to template | 1812 # template_data are the variables passed to template |
1784 if not hasattr(request, "template_data"): | 1813 if not hasattr(request, "template_data"): |
1785 # if template_data doesn't exist, it's the beginning of the request workflow | 1814 # if template_data doesn't exist, it's the beginning of the request workflow |
1786 # so we fill essential data | 1815 # so we fill essential data |
1787 session_data = self.host.getSessionData(request, session_iface.ISATSession) | 1816 session_data = self.host.getSessionData(request, session_iface.ISATSession) |
1817 profile = session_data.profile | |
1788 request.template_data = { | 1818 request.template_data = { |
1789 "profile": session_data.profile, | 1819 "profile": profile, |
1790 "csrf_token": session_data.csrf_token, | 1820 # it's important to not add CSRF token and session uuid if service profile |
1791 "session_uuid": session_data.uuid, | 1821 # is used because the page may be cached, and the token then leaked |
1822 "csrf_token": "" if profile is None else session_data.csrf_token, | |
1823 "session_uuid": "public" if profile is None else session_data.uuid, | |
1792 "breadcrumbs": [] | 1824 "breadcrumbs": [] |
1793 } | 1825 } |
1794 | 1826 |
1795 # XXX: here is the code which need to be executed once | 1827 # XXX: here is the code which need to be executed once |
1796 # at the beginning of the request hanling | 1828 # at the beginning of the request hanling |