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
« 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
5"""Provide user friendly names for social authentication methods."""
7from __future__ import annotations
9from typing import TYPE_CHECKING
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
18from weblate.accounts.utils import get_key_name
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
24 from weblate.accounts.types import DeviceType
26register = template.Library()
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}
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}
62IMAGE_SOCIAL_TEMPLATE = """
63<img class="auth-image" src="{image}" />
64"""
66SOCIAL_TEMPLATE = """
67{icon}
68{separator}
69{name}
70"""
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"}
78 # Hardcoded names
79 if auth in SOCIALS:
80 params.update(SOCIALS[auth])
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
92 return params
95auth_name_default_separator = mark_safe("<br />")
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)
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)
107 if only:
108 return params[only]
110 return format_html(SOCIAL_TEMPLATE, separator=separator, **params)
113def get_auth_name(auth: str):
114 """Get nice name for authentication backend."""
115 return get_auth_params(auth)["name"]
118@register.simple_tag
119def key_name(device: Device) -> str:
120 return format_html('<span class="auth-name">{}</span>', get_key_name(device))
123@register.simple_tag
124def second_factor_name(name: DeviceType) -> StrOrPromise:
125 return SECOND_FACTORS[name]
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"
136 return format_html('<span class="{}">{}</span>', style, site_title)