Coverage for app/venv/lib/python3.14/site-packages/weblate/accounts/templatetags/authnames.py: 40%

54 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-10-07 07:15 +0000

1# Copyright © Michal Čihař <michal@weblate.org> 

2# 

3# SPDX-License-Identifier: GPL-3.0-or-later 

4 

5"""Provide user friendly names for social authentication methods.""" 

6 

7from __future__ import annotations 

8 

9from typing import TYPE_CHECKING 

10 

11from django import template 

12from django.conf import settings 

13from django.contrib.staticfiles.storage import staticfiles_storage 

14from django.utils.html import format_html 

15from django.utils.safestring import mark_safe 

16from django.utils.translation import gettext_lazy 

17 

18from weblate.accounts.utils import get_key_name 

19 

20if TYPE_CHECKING: 20 ↛ 21line 20 didn't jump to line 21 because the condition on line 20 was never true

21 from django_otp.models import Device 

22 from django_stubs_ext import StrOrPromise 

23 

24 from weblate.accounts.types import DeviceType 

25 

26register = template.Library() 

27 

28SOCIALS: dict[str, dict[str, StrOrPromise]] = { 

29 "auth0": {"name": "Auth0", "image": "auth0.svg"}, 

30 "saml": {"name": "SAML", "image": "saml.svg"}, 

31 "google": {"name": "Google", "image": "google.svg"}, 

32 "google-oauth2": {"name": "Google", "image": "google.svg"}, 

33 "google-plus": {"name": "Google+", "image": "google.svg"}, 

34 "password": {"name": gettext_lazy("Password"), "image": "password.svg"}, 

35 "email": {"name": gettext_lazy("E-mail"), "image": "email.svg"}, 

36 "ubuntu": {"name": "Ubuntu", "image": "ubuntu.svg"}, 

37 "opensuse": {"name": "openSUSE", "image": "opensuse.svg"}, 

38 "fedora": {"name": "Fedora OpenID", "image": "fedora.svg"}, 

39 "fedora-oidc": {"name": "Fedora", "image": "fedora.svg"}, 

40 "facebook": {"name": "Facebook", "image": "facebook.svg"}, 

41 "github": {"name": "GitHub", "image": "github.svg"}, 

42 "github-enterprise": {"name": "GitHub Enterprise", "image": "github.svg"}, 

43 "github-org": {"name": "GitHub Organization", "image": "github.svg"}, 

44 "bitbucket": {"name": "Bitbucket", "image": "bitbucket.svg"}, 

45 "bitbucket-oauth2": {"name": "Bitbucket", "image": "bitbucket.svg"}, 

46 "azuread-oauth2": {"name": "Azure", "image": "azure.svg"}, 

47 "azuread-tenant-oauth2": {"name": "Azure", "image": "azure.svg"}, 

48 "gitlab": {"name": "GitLab", "image": "gitlab.svg"}, 

49 "amazon": {"name": "Amazon", "image": "amazon.svg"}, 

50 "twitter": {"name": "Twitter", "image": "twitter.svg"}, 

51 "stackoverflow": {"name": "Stack Overflow", "image": "stackoverflow.svg"}, 

52 "musicbrainz": {"name": "MusicBrainz", "image": "musicbrainz.svg"}, 

53 "openinfra": {"name": "OpenInfraID"}, 

54} 

55 

56SECOND_FACTORS: dict[DeviceType, StrOrPromise] = { 

57 "webauthn": gettext_lazy("Use security key (WebAuthn)"), 

58 "totp": gettext_lazy("Use authentication app (TOTP)"), 

59 "recovery": gettext_lazy("Use recovery codes"), 

60} 

61 

62IMAGE_SOCIAL_TEMPLATE = """ 

63<img class="auth-image" src="{image}" /> 

64""" 

65 

66SOCIAL_TEMPLATE = """ 

67{icon} 

68{separator} 

69{name} 

70""" 

71 

72 

73def get_auth_params(auth: str) -> dict[str, StrOrPromise]: 

74 """Generate authentication parameters.""" 

75 # Fallback values 

76 params: dict[str, StrOrPromise] = {"name": auth.title(), "image": "password.svg"} 

77 

78 # Hardcoded names 

79 if auth in SOCIALS: 

80 params.update(SOCIALS[auth]) 

81 

82 # Settings override 

83 settings_params = { 

84 "name": f"SOCIAL_AUTH_{auth.upper().replace('-', '_')}_TITLE", 

85 "image": f"SOCIAL_AUTH_{auth.upper().replace('-', '_')}_IMAGE", 

86 } 

87 for target, source in settings_params.items(): 

88 value = getattr(settings, source, None) 

89 if value: 

90 params[target] = value 

91 

92 return params 

93 

94 

95auth_name_default_separator = mark_safe("<br />") 

96 

97 

98@register.simple_tag 

99def auth_name(auth: str, separator: str = auth_name_default_separator, only: str = ""): 

100 """Create HTML markup for social authentication method.""" 

101 params = get_auth_params(auth) 

102 

103 if not params["image"].startswith("http"): 

104 params["image"] = staticfiles_storage.url("auth/" + params["image"]) 

105 params["icon"] = format_html(IMAGE_SOCIAL_TEMPLATE, separator=separator, **params) 

106 

107 if only: 

108 return params[only] 

109 

110 return format_html(SOCIAL_TEMPLATE, separator=separator, **params) 

111 

112 

113def get_auth_name(auth: str): 

114 """Get nice name for authentication backend.""" 

115 return get_auth_params(auth)["name"] 

116 

117 

118@register.simple_tag 

119def key_name(device: Device) -> str: 

120 return format_html('<span class="auth-name">{}</span>', get_key_name(device)) 

121 

122 

123@register.simple_tag 

124def second_factor_name(name: DeviceType) -> StrOrPromise: 

125 return SECOND_FACTORS[name] 

126 

127 

128@register.simple_tag(takes_context=True) 

129def format_site_title(context) -> str: 

130 style = "" 

131 site_title = context["site_title"] 

132 if context["support_status"]["is_hosted_weblate"]: 

133 style = "text-info" 

134 site_title = "Weblate cloud" 

135 

136 return format_html('<span class="{}">{}</span>', style, site_title)