-
Notifications
You must be signed in to change notification settings - Fork 28
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
Export user preferences on project export #3968
base: development
Are you sure you want to change the base?
Conversation
Otherwise you get exceptions such as when tasks like New CE try to use Preferences.layout
Codecov ReportAll modified and coverable lines are covered by tests ✅
❗ Your organization needs to install the Codecov GitHub app to enable full functionality. Additional details and impacted files@@ Coverage Diff @@
## development #3968 +/- ##
================================================
+ Coverage 58.17% 72.78% +14.60%
================================================
Files 1655 1935 +280
Lines 52473 66524 +14051
================================================
+ Hits 30527 48419 +17892
+ Misses 21946 18105 -3841 ☔ View full report in Codecov by Sentry. |
@@ -7,6 +7,9 @@ | |||
<div class="panel content"> | |||
<h3> Export SQL </h3> | |||
<p><em>Generate a downloadable copy of the database (PostgreSQL dump) with all data referenced in this project. Includes Community data like Sources, People, and Repositories.</em></p> | |||
|
|||
<p><em>All exported user passwords are set to</em> 'taxonworks'.</p> |
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.
Because of this (that I totally forgot about) then would be nice to add a warning that it is not a good idea at all to build a public TW instance out of the generated dump.
lib/export/project_data/sql.rb
Outdated
@@ -149,7 +149,8 @@ def self.export_users(io, project) | |||
created_by_id: user.created_by_id || 'NULL', | |||
updated_by_id: user.updated_by_id || 'NULL', | |||
is_administrator: user.is_administrator || 'NULL', | |||
hub_tab_order: "'{#{conn.escape_string(user.hub_tab_order.join(','))}}'" | |||
hub_tab_order: "'{#{conn.escape_string(user.hub_tab_order.join(','))}}'", | |||
preferences: %['"#{conn.escape_string(JSON.generate(user.preferences)).gsub('"', '\"')}"'] |
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.
Have you tried preferences: "'#{conn.escape_string(user.preferences.to_json)}'"
? I think '
is the char that needs to be escaped, not "
.
3.3.1 :017 > puts ActiveRecord::Base.connection.raw_connection.escape_string(%["hello" 'bye'])
"hello" ''bye''
As general comment, my concern with this would be if there a potential to leak semi-sensitive (or private) information from other project members. If not a problem, after doing some revisions I think it is good to merge, otherwise I'd seek to make the user model tolerant to empty preferences and initialize them properly if so. |
Correction, it would export preferences for all users, not just project members (although non-members have their email and name fields redacted). |
I think we can review preferences to ensure nothing sensitive is there. There shouldn't be, if there is we need to strike it from there and handle it elsewhere. We should never store credentials, or any personal information beyond things like "I want the form layed out this way". |
We don't save any sensitive information there, just layout preferences and copy paste shortcuts. Maybe we could add a checkbox option for this? [x] Export user preferences If it is not checked, initialize the users preferences. I'm not sure if export projects will always need export user preferences or not |
The initial motivation for this I guess was that @kleintom experienced software crashes on some tasks because preferences were not initialized. If that is the main goal here, then I think would be best to instead fix the model so User's preferences attribute returns a default set of preferences if none are stored in the database or have an invalid structure. |
Yes, that was intended already. Might just be that we have to re-initialize a legal JSON base, not sure, '{}' |
This reverts commit f994a57. Decided to go the route of making sure preferences have a default value instead - see the discussion at SpeciesFileGroup#3968
Because all passwords are set to 'taxonworks'.
Defaults are merged into any preferences being saved on
taxonworks/app/models/user/preferences.rb Lines 23 to 32 in aa82f29
The issue is that in the export/import case, users are created at the pg level directly by psql, and the default preferences in that case are With those empty preferences we get exceptions like here: Line 85 in aa82f29
preferences.layout .
I don't think we can make the default for User preferences be BASE_PREFERENCES (can we?); if preferences are non-sensitive/will stay non-sensitive, then always importing preferences, for everyone, seems to me like the easiest solution here. (I'm not clear on why non-project users are exported, maybe so you're guaranteed to have an existing administrator account?) Other thoughts? |
Based on what I'm seeing online I expected that to work, but it didn't. With the current release code, if I do If I import using But with that second imported preferences value, if I try to load a page that uses those preferences, or from the rails console I do It seems to expect the db value of preferences to be serialized json (which is what it appears to be with release code), not a json hash (though it's not clear to me in what sense the db value is a hash in this case). Schema.rb says If you update preferences to be I haven't been able to make sense of all of that yet; thoughts? |
In this case I would add this in user/preferences.rb # Assuming this method will be instance method of User, if not the case then needs to be relocated (if possible)
def preferences
prefs = read_attribute(:preferences)
return prefs unless prefs.empty?
reset_preferences
read_attribute(:preferences)
end What do you think? (cc @mjy)
Non project users are exported because housekeeping of community data might reference them. |
That fixes the exception issue, though it doesn't persist the new prefs to the database. I don't know, would you want to call save in the accessor in that case? Do we want to not export preferences then? (Could still export plus add the reader for future-proofing in other export cases.) |
No, never :). |
Would be nice to figure out exactly how is ActiveRecord serializing the preferences attribute to make sure |
I remember battling this. I just realized this is a |
It's included with all the other property accessors at https://github.com/SpeciesFileGroup/taxonworks/blob/aa82f2998430e64b97965195f8854d0e397bc1d4/app/models/user/preferences.rb#L7
Thanks to Hernán for the suggestion and code. For when preferences are empty, in this case because the project was imported via psql and so avoided the before_save check that normally would fill any unset preferences. Empty prefs lead to exceptions on things like preferences.layout reads, which assume default preferences exist. Note that in general the preferences returned here won't be saved to the database.
`change_column` is always irreversible, so we provide down here.
The issue with user preferences showing up in the database as double-quoted strings:
coder: JSON allows the serialization to be stored on a JSON field.
Seems strange that you can't insert actual json into your json column anymore (and how does it work if you only have a store accessor on one of your many json keys?). In any case, the link suggests that if your underlying field is already json, then you should use So I'm skipping exporting user preferences for now on project export, but let me know if there's more you'd like me to work on here. |
Oops, I'll check out the errors. |
I modeled the json -> jsonb migration that I wrote on previous migrations doing the same thing:
taxonworks/db/migrate/20180529170201_update_project_workbench_settings_to_preferences_jsonb.rb Line 3 in 1263c7e
Note the default set to Most of the failing tests from my previous push are at Line 397 in 1263c7e
The issue seems to be that we're trying to read the value of the footprints hash with key recently_visited when the current value of the hash is "{}" (not {} ). This would work if footprints was a store d field, but it's not (as determined by User.stored_attributes ). So in this case the default value of footprints should be {} and not '{}' . (Yuk.) Doing that fixes those tests. (Thank goodness for the tests!)
The Project migration linked above (which also renames The sqed_depiction migration I think might be in error. taxonworks/app/models/sqed_depiction.rb Line 218 in 1263c7e
metadata_map is the string "{}" (the default value) and you're trying to do an inject on it. If I change those default metadata_map to '{}' instead of "{}" then the page loads without error.
So I think the way forward is to do another migration to:
I can keep working on this - in which case let me know if everything sounds right - but it's a little hinky with the quotes vs unquotes and now the migrations are changing more, so feel free to take it if that works better. |
I tested this locally with 1) default (reset) preferences, and 2)
Two caveats, please send back to me if there's any concern:
"
in the preferences (since I'm expecting that never happens...)