Repository: getsentry/sentry

Issue:
Sentry mail without username and password (reset mail settings)
## Important Details

How are you running Sentry?

Ubuntu 18.04
Installed from pip
Started with systemd

## Description
1.) Set mail configuration via gui (smtp, mailserver, username, password, ...).
2.) We need to change to a local Mailserver without authentication (exim4)
3.) Set in `/etc/sentry/config.yml` the following:
```
mail.backend: 'smtp'  # Use dummy if you want to disable email entirely
mail.host: 'localhost'
mail.port: 25
mail.username: ''
mail.password: ''
mail.use-tls: false
system.admin-email: 'admin@mydomain.com'
```
4.) Sent test E-mail -> `SMTP AUTH extension not supported by server`

The Problem ist that I can not overwrite the username and the passwort that was set previous in the gui with nothing.
If I go to `Admin -> Mail` I see the old values in `username` and `password`, but there should be `not set`.

I tried to find the "old" values in the database, but can't find anything there.
I also greped in the "/www" folder for this values and find nothing.
Where are this values stored?
How can I reset them to "nothing"?


Discussion:
>The Problem ist that I can not overwrite the username and the passwort that was set previous in the gui with nothing.

I think this was an issue with the initial setup wizard in Sentry 9.1.1 which is fixed in 9.1.2 released yesterday. Are you able to try with that?
Thanks for the help

Just updated to 9.1.2 with the same result.
The Webinterface shows me still the old values for username and password.
If I try a test mail the same error comes up (`SMTP AUTH extension not supported by server`)
Oh wait, my bad for misunderstanding the issue. As far as I know, when you enter a value from the UI, they are persisted in the DB. I'm guessing the UI doesn't allow empty values?
Hmm I made a DB dump and searched for the values so I can delete them, but I could not find anything.
Does the system maybe store this data not in plaintext?

I have a second sentry installation where I never added username/password for the mailserver config in the web ui. On this system (9.1.1) everything runs fine with the local exim4 noauth config.
So empty values should be ok, but If you fill them one times I can not find out how to get them empty again.
> If you fill them one times I can not find out how to get them empty again.  

me too. 😢


I'll try to get to this but if anyone wants to give it a try, it should not be too complicated and I'm happy to assist them in the process.

Resolving patch:
diff --git a/src/sentry/options/manager.py b/src/sentry/options/manager.py
--- a/src/sentry/options/manager.py
+++ b/src/sentry/options/manager.py
@@ -31,7 +31,7 @@ class UnknownOption(KeyError):
 # Values that must be defined for setup to be considered complete
 FLAG_REQUIRED = 1 << 4
 # If the value is defined on disk, use that and don't attempt to fetch from db.
-# This also make the value immutible to changes from web UI.
+# This also make the value immutable to changes from web UI.
 FLAG_PRIORITIZE_DISK = 1 << 5
 # If the value is allowed to be empty to be considered valid
 FLAG_ALLOW_EMPTY = 1 << 6
@@ -139,7 +139,7 @@ def get(self, key, silent=False):
             except KeyError:
                 pass
             else:
-                if result:
+                if result is not None:
                     return result
 
         if not (opt.flags & FLAG_NOSTORE):


Test patch:
diff --git a/tests/sentry/options/test_manager.py b/tests/sentry/options/test_manager.py
--- a/tests/sentry/options/test_manager.py
+++ b/tests/sentry/options/test_manager.py
@@ -198,6 +198,14 @@ def test_flag_prioritize_disk(self):
         with self.settings(SENTRY_OPTIONS={"prioritize_disk": "something-else!"}):
             assert self.manager.get("prioritize_disk") == "something-else!"
 
+        # Ensure empty values on disk are preferred over DB values (See #14557)
+        with self.settings(SENTRY_OPTIONS={"prioritize_disk": ""}):
+            assert self.manager.get("prioritize_disk") == ""
+
+        # Ensure None on disk are NOT preferred over DB (See #14557)
+        with self.settings(SENTRY_OPTIONS={"prioritize_disk": None}):
+            assert self.manager.get("prioritize_disk") == "foo"
+
     def test_db_unavailable(self):
         with patch.object(Option.objects, "get_queryset", side_effect=Exception()):
             # we can't update options if the db is unavailable