Skip to content

Conversation

@nijel
Copy link
Member

@nijel nijel commented Jan 7, 2026

This doesn't provide upload, but tells users where to perform it. Temporary solution util #4283 is implemented.

Fixes #15695

@nijel nijel added this to the 5.15.2 milestone Jan 7, 2026
@nijel nijel self-assigned this Jan 7, 2026
@nijel nijel requested a review from Copilot January 7, 2026 14:18
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

Comment on lines +67 to +71
{% if user_can_upload_translation %}
<li>
<a class="dropdown-item" data-bs-target="#upload" data-bs-toggle="tab">{% translate "Upload translation" %}</a>
</li>
{% endif %}
Copy link

Copilot AI Jan 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new upload tab functionality for project-language pages lacks test coverage. Consider adding a test to verify that:

  1. The upload tab appears when a user has the appropriate permissions
  2. The upload tab is hidden when a user lacks permissions
  3. The informational message is displayed correctly
  4. The permission check doesn't cause runtime errors with ProjectLanguage objects

Copilot uses AI. Check for mistakes.
This doesn't provide upload, but tells users where to perform it.
Temporary solution util WeblateOrg#4283 is implemented.

Fixes WeblateOrg#15695
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

Comment on lines +510 to 519
return check_can_edit(user, permission, obj) and (
# Normal upload
check_edit_approved(user, "unit.edit", translation)
check_edit_approved(user, "unit.edit", obj)
# Suggestion upload
or check_suggestion_add(user, "suggestion.add", translation)
or check_suggestion_add(user, "suggestion.add", obj)
# Add upload
or check_suggestion_add(user, "unit.add", translation)
or check_suggestion_add(user, "unit.add", obj)
# Source upload
or translation.is_source
or (isinstance(obj, Translation) and obj.is_source)
)
Copy link

Copilot AI Jan 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The permission checks for check_upload now accept ProjectLanguage, but the function doesn't properly handle all the permission validation logic for ProjectLanguage objects. Specifically, when obj is a ProjectLanguage, the function proceeds directly to line 510 where it calls check_can_edit(user, permission, obj) and then checks various upload permissions.

However, the checks at lines 512-518 call functions like check_edit_approved, check_suggestion_add, etc., which expect either a Translation or a ProjectLanguage. While check_suggestion_add has been updated to support ProjectLanguage, these permission checks are designed to work on individual translations, not on project-language combinations. This could lead to confusing or incorrect permission results.

Consider adding explicit handling for ProjectLanguage in the check_upload function that either:

  1. Returns early with an appropriate message explaining that actual upload is not supported at this level (since this is meant to be an informational page)
  2. Implements proper permission logic that makes sense for a project-language context

Copilot uses AI. Check for mistakes.
Comment on lines 482 to 519
@register_perm("upload.perform")
def check_upload(
user: User, permission: str, translation: Translation
user: User, permission: str, obj: Translation | ProjectLanguage
) -> bool | PermissionResult:
"""
Check whether user can perform any upload operation.
The actual check for the method is implemented in
weblate.trans.util.check_upload_method_permissions.
"""
# Source upload
if translation.is_source and not user.has_perm("source.edit", translation):
return Denied(gettext("Insufficient privileges for editing source strings."))
# Bilingual source translations
if (
translation.is_source
and not translation.is_template
and not issubclass(translation.component.file_format_cls, BilingualUpdateMixin)
):
return Denied(
gettext("The file format does not support updating source strings.")
)
if translation.component.is_glossary:
permission = "glossary.upload"
return check_can_edit(user, permission, translation) and (
if isinstance(obj, Translation):
# Source upload
if obj.is_source and not user.has_perm("source.edit", obj):
return Denied(
gettext("Insufficient privileges for editing source strings.")
)
# Bilingual source translations
if (
obj.is_source
and not obj.is_template
and not issubclass(obj.component.file_format_cls, BilingualUpdateMixin)
):
return Denied(
gettext("The file format does not support updating source strings.")
)
if obj.component.is_glossary:
permission = "glossary.upload"

return check_can_edit(user, permission, obj) and (
# Normal upload
check_edit_approved(user, "unit.edit", translation)
check_edit_approved(user, "unit.edit", obj)
# Suggestion upload
or check_suggestion_add(user, "suggestion.add", translation)
or check_suggestion_add(user, "suggestion.add", obj)
# Add upload
or check_suggestion_add(user, "unit.add", translation)
or check_suggestion_add(user, "unit.add", obj)
# Source upload
or translation.is_source
or (isinstance(obj, Translation) and obj.is_source)
)
Copy link

Copilot AI Jan 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes to support ProjectLanguage in permission checks (check_upload, check_suggestion_add, and check_edit_approved) lack test coverage. Given that comprehensive permission tests exist in weblate/auth/tests/test_permissions.py, new tests should be added to verify that the permission checks work correctly when called with a ProjectLanguage object.

Consider adding tests that verify:

  1. upload.perform permission works correctly with ProjectLanguage objects
  2. suggestion.add permission works correctly with ProjectLanguage objects
  3. unit.edit permission works correctly with ProjectLanguage objects
  4. The informational upload tab is displayed correctly when permissions are granted/denied

Copilot uses AI. Check for mistakes.
Comment on lines +1111 to +1112
return True

Copy link

Copilot AI Jan 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The enable_suggestions property for ProjectLanguage is hardcoded to return True, which may not reflect the actual configuration of the components within the project-language combination. Some components within the project might have enable_suggestions set to False, or might have workflow settings that disable suggestions. This could lead to showing the upload tab to users even when suggestions are not actually enabled for any of the components in this project-language combination.

Consider checking if any translations within the project-language have suggestions enabled, or documenting why this always returns True is an acceptable approach for this use case.

Suggested change
return True
"""Return whether suggestions are enabled for this project-language.
Suggestions are considered enabled if any related component for this
project-language has suggestions enabled, or if workflow settings
explicitly enable them. This avoids advertising suggestions in the UI
when none of the components actually support them.
"""
# Check per-component configuration via related translations.
for translation in self.translation_set:
component = getattr(translation, "component", None)
if component is not None and getattr(component, "enable_suggestions", False):
return True
# Fallback to workflow settings, if they define suggestion behavior.
workflow = self.workflow_settings
if workflow is not None and hasattr(workflow, "enable_suggestions"):
return bool(getattr(workflow, "enable_suggestions"))
return False

Copilot uses AI. Check for mistakes.
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

weblate/auth/permissions.py:478

  • The check_suggestion_add function now accepts ProjectLanguage but only checks for contributor agreement when the object is a Translation. However, when a ProjectLanguage is passed, the function will skip the agreement check entirely and proceed directly to the permission check. This could allow users to bypass contributor agreement requirements at the project-language level. Consider adding proper handling for ProjectLanguage objects or explicitly documenting why this check is intentionally skipped for this type.
    if (
        not user.is_bot
        and isinstance(obj, Translation)
        and obj.component.agreement
        and not ContributorAgreement.objects.has_agreed(user, obj.component)
    ):
        return False

@codecov
Copy link

codecov bot commented Jan 7, 2026

Codecov Report

❌ Patch coverage is 90.90909% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 91.75%. Comparing base (d12614c) to head (05e9260).
⚠️ Report is 8 commits behind head on main.

Files with missing lines Patch % Lines
weblate/utils/stats.py 66.66% 1 Missing ⚠️

❌ Your patch status has failed because the patch coverage (90.90%) is below the target coverage (100.00%). You can increase the patch coverage or adjust the target coverage.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@nijel nijel merged commit e2f8e63 into WeblateOrg:main Jan 8, 2026
59 of 60 checks passed
@nijel nijel deleted the prj-lang-upload branch January 8, 2026 04:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

File upload in the project-language view

1 participant