Repository: WeblateOrg/weblate

Issue:
Explain e-mail use for commits more transparently
### Describe the problem

So currently there are two e-mail fields:

* E-mail (Choose primary e-mail from verified addresses.)
* Commit e-mail (Choose commit e-mail from verified addresses.)

This could intuitively be understood as "*e-mail* is for my account and **only** the *commit e-mail* is for commits" (if left empty there is no e-mail used in the commits).

But what happens instead is that if the *commit e-mail* field is empty, then the *e-mail* becomes the *commit e-mail*, (at least for po-file exports) which is not very transparent.

It becomes a bigger problem because once you add a translation without setting the *commit e-mail* field, Weblate will internally store your *e-mail* and use that in any po export. This will even happen if you change your *commit e-mail* later, so a user who once fell into the trap outlined above, will have their *e-mail* locked into the weblate database with no way to remove/change it. Of course addresses can be changed, but in a po export, **both** e-mail addresses will appear.

I'm not a laywer, but personal data transparency could become a [GDPR](https://en.wikipedia.org/wiki/General_Data_Protection_Regulation) issue. 

### Describe the solution you'd like

Short notice: Add some very transparent text blocks to the Profile/Account page, explaining what happens with the e-mail addresses you enter, and potentially a warning that your e-mail address could potentially turn up publicly in the project's git repo that you are contributing to if you fill the fields incorrectly.

This is just a band-aid though, see below for better alternatives.

### Describe alternatives you've considered

Longer term: Add an option to edit your personal data that is stored inside the Weblate database with the option to remove/change your address after it has been added. This would solve the problem that someone could have missed the info block and still added an e-mail address they want removed or updated later.

Alternative longer term: Link the e-mail address to the account and propagate any changes on the account page to the database, so that if someone modifies their e-mail address, it will also be updated in the database. Current behavior is to just add new addresses while keeping the old ones in the database

Additional option: Give a user the option to keep their address anonymous, e.g. if no commit address is given. This could either be an omission of the email address or an anonymization like a***.b***@gmail.com. In addition to user choice this could also be a global setting for admins to set if they don't want any trouble with GDPR whatsoever, so they can avoid committing any personal information to their project repo.

### Screenshots

_No response_

### Additional context

_No response_


Discussion:
> I'm not a laywer, but personal data transparency could become a [GDPR](https://en.wikipedia.org/wiki/General_Data_Protection_Regulation) issue.

That's why there are [terms of service](https://hosted.weblate.org/legal/terms/) on our service, which clearly state this usage of e-mail. We state this also in the [overview](https://hosted.weblate.org/legal/) so that you don't read the full terms to understand this.

> Longer term: Add an option to edit your personal data that is stored inside the Weblate database with the option to remove/change your address after it has been added. This would solve the problem that someone could have missed the info block and still added an e-mail address they want removed or updated later.
> 
> Alternative longer term: Link the e-mail address to the account and propagate any changes on the account page to the database, so that if someone modifies their e-mail address, it will also be updated in the database. Current behavior is to just add new addresses while keeping the old ones in the database

There is just a single place where Weblate stores user e-mail in the database and that's the profile. The commits are not stored in Weblate, but instead in Git (or Mercurial) and pushed to the upstream repos. And there is effectively no way to change what has been pushed out of Weblate. This has been heavily discussed at https://github.com/WeblateOrg/weblate/issues/9969, so please read that first.

> In addition to user choice this could also be a global setting for admins to set if they don't want any trouble with GDPR whatsoever, so they can avoid committing any personal information to their project repo.

There already is such setting: https://docs.weblate.org/en/latest/admin/config.html#private-commit-email-opt-in. See also https://docs.weblate.org/en/latest/user/profile.html#profile
Ok, I guess it probably wouldn't hurt to add another warning/disclaimer in the profile page, in case people didn't pay attention to the terms, but I understand your argument that it's documented enough.

What I didn't know is that Weblate uses a local repo for saving the state of translations. Is this something that runs privately inside weblate hosted or is it a public repo? I was probably a bit confused because Godot uses its own repo for keeping translations, which it syncs manually. 

I didn't know there was a setting like that, but I understand it's global on Weblate hosted and not changeable per-project?
IMHO if you care about your e-mail privacy, you should read the terms of the service where you are putting it. But I've added a more prominent display of the TOS summary on registration in 3344f1538c0ad6fe95052d90e34ca362481d7a80, that should make it more obvious.

The setting applies on user creation, so it has to be site-wide, not per project.

But the e-mail configuration in the user profile could be indeed better, I will look into that.

Resolving patch:
diff --git a/weblate/accounts/forms.py b/weblate/accounts/forms.py
--- a/weblate/accounts/forms.py
+++ b/weblate/accounts/forms.py
@@ -30,7 +30,7 @@
     get_all_user_mails,
     invalidate_reset_codes,
 )
-from weblate.auth.models import Group, User, get_auth_keys
+from weblate.auth.models import Group, User
 from weblate.lang.models import Language
 from weblate.logger import LOGGER
 from weblate.trans.defines import FULLNAME_LENGTH
@@ -173,8 +173,11 @@ class CommitForm(ProfileBaseForm):
     commit_email = forms.ChoiceField(
         label=gettext_lazy("Commit e-mail"),
         choices=[("", gettext_lazy("Use account e-mail address"))],
-        help_text=gettext_lazy("Choose commit e-mail from verified addresses."),
+        help_text=gettext_lazy(
+            "Used in version control commits. The address will stay in the repository forever once changes are commited by Weblate."
+        ),
         required=False,
+        widget=forms.RadioSelect,
     )
 
     class Meta:
@@ -197,10 +200,6 @@ def __init__(self, *args, **kwargs):
         self.helper = FormHelper(self)
         self.helper.disable_csrf = True
         self.helper.form_tag = False
-        layout = ["commit_email"]
-        if "email" in get_auth_keys():
-            layout.append(Div(template="accounts/add-mail.html"))
-        self.helper.layout = Layout(*layout)
 
 
 class ProfileForm(ProfileBaseForm):
@@ -342,10 +341,13 @@ class UserForm(forms.ModelForm):
 
     username = UniqueUsernameField()
     email = forms.ChoiceField(
-        label=gettext_lazy("E-mail"),
-        help_text=gettext_lazy("Choose primary e-mail from verified addresses."),
+        label=gettext_lazy("Account e-mail"),
+        help_text=gettext_lazy(
+            "Used for e-mail notifications and as a commit e-mail if it is not not configured below."
+        ),
         choices=(("", ""),),
         required=True,
+        widget=forms.RadioSelect,
     )
     full_name = FullNameField()
 
@@ -364,10 +366,6 @@ def __init__(self, *args, **kwargs):
         self.helper = FormHelper(self)
         self.helper.disable_csrf = True
         self.helper.form_tag = False
-        layout = ["username", "email", "full_name"]
-        if "email" in get_auth_keys():
-            layout.insert(2, Div(template="accounts/add-mail.html"))
-        self.helper.layout = Layout(*layout)
 
     @classmethod
     def from_request(cls, request):


Test patch: