-
Notifications
You must be signed in to change notification settings - Fork 40
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Re-associate draft replies with "deleted" user account #1415
Conversation
I'll test this change out now (partly since I feel bad that I didn't catch this during QA yesterday night...) |
Follow STR in #1414
Follow STR in #1416
❌ However, upon the STR in #1416, the user is not actually deleted from the client database, and the client repeatedly logs the following error:
This is against a 2.1.0 prod server that doesn't yet have the changes in freedomofpress/securedrop#6225, so may be expected behavior pre-2.2.0 (if it represents no regression over current state and is quietly ignored, that may be OK during the brief time between SD Client 0.6.0 and SD Server 2.2.0). I've not tested with a 2.2.0 RC yet. |
I have the same experience--the
|
Super clear. Thanks for the report, both. The log message, The server, even what is currently planned to go into 2.2.0, does not provide a "deleted' user account by default- both create the account on demand. I see a couple solutions:
@eloquence and @rocodes, since you're both familiar with the problem, which solution do you prefer? In order of preference, I'm leaning towards 1, 3, and then 2. Actually, even if the server did this in 2.2.0, it still wouldn't solve the backwards compatibility issue. So we need to rule out 1. New order of preference is 3, and then 2, but I keep going back and forth on which one I prefer. 2 would make it clearer that there are multiple "deleted" users, and it would also be clearer than treating null as a deleted user. It would also allow us to make |
Thanks for the explanation, @creviera. I need to think it over and look at the code a little more (and obviously I defer to whatever your preference is since I haven't touched this part of the code), but of the options you've listed, I think I slightly prefer 2. Reasons: a) drafts only exist on the client, and this in-between state is only possible on the client, so a local solution seems preferable; and b) and it seems like keeping the option open to enforce non-null journalist IDs is a good idea, and if go with option 3 and then and want to enforce constraints on journalist_id later on, we may be setting ourselves up for more bugs/complexity. I'm a little confused about the on-demand account piece that you mentioned, since I thought that the I'll spend some more time with it before we talk again on Monday. |
Without looking at the code, option 3 intuitively makes sense to me -- as a slight variation/alternative, could it make sense to create a |
It's a good point. It is a lot easier to reason about the code if we can ensure that there is always a real account association for the sender of replies, including draft replies.
Ah, yes, the "on-demand" comment is referring to how the "deleted" user account is created by the
Yes, the |
Just discussed this with @eloquence and we agree that the internal/draft "deleted" user should have a reserved spot on the server so that it can be disallowed: https://github.com/freedomofpress/securedrop/blob/82ec17bfc062c2e3a89c8de7c83c8b8088c5a3e8/securedrop/models.py#L445 @zenmonkeykstop this would require a data migration to handle the case where an admin has created an account with the name "deleted-internal" (or whatever name we decide to reserve). Let's discuss in person so that we can potentially add this to the rc2 for 2.2.0 release. |
@legoktm offered a good suggestion for our option 2 solution: just use the username |
e5b1e6a
to
e800863
Compare
I'll keep this in draft mode until I can clean up my commits and do more testing, but the implementation for re-associated draft replies is finished. |
self.sender = user | ||
self.sender_icon.setToolTip(self.sender.fullname) | ||
self._update_styles() | ||
except sqlalchemy.orm.exc.ObjectDeletedError: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This probably isn't necessary anymore. I'll look into removing this Monday after more testing. It doesn't hurt but it's adding code complexity that isn't needed if we ensure that a Reply must always have an associated Sender account.
I'm quite late to this thread, but would love further context on why we're opting to re-associate draft replies that were written by deleted users with some sort of user account. (No urgency; I wouldn't treat my question as a blocker.) Since drafts are typically personal, and haven't been seen by the source, my intuition would have been to treat them as state that's local to the client and delete them when the author is deleted. |
c5bb288
to
2b93c90
Compare
After a code walkthrough with @rocodes today, I squashed some commits. The only thing that has changed since our walkthrough is the code in |
816e740
to
7314ad2
Compare
@gonzalo-bulnes, once things slow down a bit with QA and the release is unblocked, I think we should have a SDW group discussion about this. It leads to at least a few other interesting topics around the v2 endpoint, server version support, features like saving draft replies or resending failed replies. But to try to answer your question before we have this group discussion, drafts, at this point, are just replies that are pending or failed to send. So no draft will exist unless the user pressed the Send button. And, it helps when you can see your failed reply show up in the conversation scrollarea, so that you know you what didn't make it to the server. |
Gotcha, that makes a lot more sense that the "writing in progress" drafts I was imagining. 👍
Yes, of course. ✔️ |
Also relevant to your question @gonzalo-bulnes: #1190 |
looks like this needs a rebase... |
Signed-off-by: Allie Crevier <[email protected]>
Signed-off-by: Allie Crevier <[email protected]>
Signed-off-by: Allie Crevier <[email protected]>
Signed-off-by: Allie Crevier <[email protected]>
7314ad2
to
9414760
Compare
Environment: staging servers @ 2.1.0 Test PlanFollow STR in #1414:
Follow STR in #1416
Good news, bad news. Follow STR in #1411
|
Tested these changes against a 2.1.0 prod server, due to freedomofpress/securedrop-sdk#171. Results were:
For 1416, there were no problems with rendering the conversation pane. The specific problem I observed was a violation of this step in the "expected behavior" section of the report:
That's not what I observed. After deleting the user whose draft reply had failed to send due to broken network, I logged in as a different user, and observed that the draft reply was sent to the source, and credited to the newly logged in user. Screenshots to document: Draft reply in failed stateSent reply initially attributed to deleted user, by nameSent reply ultimately attributed to currently logged in user, who was logged in when draft sentWe should inspect the draft reply handling a bit more closely. |
Per discussion, I'll attempt to repro #1416, but I'll fully restart the client before logging back in again as a different user. |
Can't reproduce when fully restarting the app. The transition is as expected: initially still attributed and "failed to send", then the app syncs & the user is replaced with the star icon, but the reply stays "failed to send". |
Based on testing so far, I believe that the issue Conor and Ro hit appears to be a side effect of #1420, which appears to be a longstanding issue with jobs being retried when we don't expect them to be. If we can confirm that, it's IMO reasonable to consider it out of scope for the 0.6.0 release. |
Since this is not a |
@rocodes - if you're in before me tomorrow, could you confirm that #1420 is not a regression. If it is not, let's prioritize merging this PR and cutting an rc3 release. I don't think we should hold up the Let me know if you think that's a good plan or if you think it's worth delaying both releases of the server and client (and remember we haven't announced a date for the release of the server yet, which we plan to do Thursday). |
Ok, so I've left a comment in the Retries Failed Jobs issue, and we'll definitely need to spend some more time figuring out some of these edge cases around network disconnection, but the tl;dr is, as Erik indicates, this behaviour was present pre-0.6.0. I think we can do as you suggested, @creviera, and go ahead and merge these changes, then tackle the retry job issues separately afterwards. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the vigorous testing, all! Quoth @creviera:
Since this is not a 0.6.0 regression, I 100% agree that we should release the current changes as planned, on schedule, so that we don't hold up the server release.
Couldn't agree more. I'll start on the version bump to rc3.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LVGTM; we've discussed mitigating the retry issue separately, so approving. Thanks for all the incredibly helpful commenting throughout here.
session.delete(account) | ||
logger.debug(f"Deleting account for user {uuid}") | ||
logger.debug(f"Deleting account for user with uuid='{uuid}'") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small note to our future selves that we may want to log before we run the database transactions, to pinpoint exactly where the errors are
Description
Fixes #1414
Fixes #1416
Fixes #1411
This PR fixes all the issues above by ensuring that a pending or failed reply (aka "draft reply", because it exists in the
draftreplies
table) cannot have a null sender. One of the issues that came up during our testing was that we were allowing nulljournalist_id
in thedraftreplies
table. Once the data was in this state, there would be issues whenever the client would have to update badges (on authentication change, when a user's name changed, and when badge needed to be updated to show the "deleted" sparkles icon).Test Plan
In case you are a QA tester, ensure that your local database is cleaned up from running QA tests during previous release candidate testing by deleting all draft replies in the
draftreplies
table wherejournalist_id
is null.Follow STR in #1414:
Follow STR in #1416
Follow STR in #1411
Checklist
If these changes modify code paths involving cryptography, the opening of files in VMs or network (via the RPC service) traffic, Qubes testing in the staging environment is required. For fine tuning of the graphical user interface, testing in any environment in Qubes is required. Please check as applicable:
If these changes add or remove files other than client code, the AppArmor profile may need to be updated. Please check as applicable:
If these changes modify the database schema, you should include a database migration. Please check as applicable:
main
and confirmed that the migration applies cleanlymain
and would like the reviewer to do so