-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Remove lock file and cleanup file handling #1231
Conversation
0490305
to
0afa287
Compare
src/gui/DatabaseTabWidget.cpp
Outdated
updateTabName(db); | ||
updateLastDatabases(dbStruct.filePath); | ||
updateLastDatabases(dbStruct.fileInfo.absoluteFilePath()); | ||
return true; | ||
} else { | ||
return false; |
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.
Move the return a level up and drop the else clause.
src/gui/DatabaseTabWidget.cpp
Outdated
|
||
insertDatabase(db, dbStruct); | ||
|
||
if (dbStruct.readOnly) { | ||
emit messageTab(tr("File opened in read only mode."), MessageWidget::Warning); | ||
} | ||
|
||
updateLastDatabases(dbStruct.filePath); | ||
updateLastDatabases(dbStruct.fileInfo.absoluteFilePath()); | ||
|
||
if (!(pw.isNull() && keyFile.isEmpty())) { |
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.
Please reformulate this condition to !pw.isNull() || !keyFile.isEmpty()
, It's a lot easier to comprehend.
@@ -798,7 +690,7 @@ void DatabaseTabWidget::modified() | |||
Database* db = static_cast<Database*>(sender()); | |||
DatabaseManagerStruct& dbStruct = m_dbList[db]; | |||
|
|||
if (config()->get("AutoSaveAfterEveryChange").toBool() && dbStruct.saveToFilename) { | |||
if (config()->get("AutoSaveAfterEveryChange").toBool() && !dbStruct.readOnly) { | |||
saveDatabase(db); |
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.
I would like an assertion here for dbWidget->currentMode() != DatabaseWidget::LockedMode
(or perhaps even inside the saveDatabase()
method?).
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.
I put one inside saveDatabase()
in place of the interlock.
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.
Perhaps you should leave both. The assertion will ensure we notice in debug mode, but the safeguard condition will ensure it never happens in production either.
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.
I was thinking that too. Will do!
src/gui/DatabaseWidget.cpp
Outdated
MessageWidget::Error); | ||
// Mark db as modified since existing data may differ from file or file was deleted | ||
m_db->modified(); |
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 should be called setModified()
.
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 directly calls the modified signal so that both the tab widget and dbwidget get updated as "modified". There is no other way to do that in the current architecture. I will add a //hack note.
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.
Ok.
6867ef2
to
d3153e1
Compare
Made the requested changes. You'll notice that the saveDatabaseAs function shrunk. I found that a lot of the work was occurring already in saveDatabase function so I streamlined further. |
585995f
to
8385dbd
Compare
This is now ready for merge. |
8385dbd
to
7e50be2
Compare
src/gui/DatabaseTabWidget.cpp
Outdated
dbStruct.lockFile = lockFile.take(); | ||
updateTabName(db); | ||
updateLastDatabases(dbStruct.filePath); | ||
dbStruct.dbWidget->updateFilename(dbStruct.fileInfo.absoluteFilePath()); |
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.
@droidmonkey maybe we can rename this updateFilePath
?
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.
Absolutely, fixed in other places as well.
src/gui/DatabaseTabWidget.cpp
Outdated
QString fileName = fileDialog()->getSaveFileName(this, tr("Save database as"), | ||
oldFileName, tr("KeePass 2 Database").append(" (*.kdbx)"), | ||
QString newFilePath = fileDialog()->getSaveFileName(this, tr("Save database as"), | ||
oldFilePath, tr("KeePass 2 Database").append(" (*.kdbx)"), |
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.
@droidmonkey these arguments need to be realigned.
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.
done
if (db->metadata()->name().isEmpty()) { | ||
tabName = dbStruct.fileName; |
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.
@droidmonkey was there a possibility that the database was readOnly
and the fileName
was not defined?
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.
I am not sure what you mean by this. readOnly
is only defined (with these new fixes) when the database file cannot be opened using QIODevice::ReadWrite
and it can be opened using QIODevice::ReadOnly
(see Line 152).
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.
@droidmonkey nevermind, I was thinking about a possible execution path that might have occurred with the previous code.
DatabaseWidget::Mode mode = dbWidget->currentMode(); | ||
|
||
if ((mode != DatabaseWidget::ViewMode && mode != DatabaseWidget::EditMode) | ||
|| !dbWidget->dbHasKey()) { |
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.
@droidmonkey shouldn't we keep the dbHasKey()
check to prevent locking?
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.
Added back in, good idea.
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.
Tested locally, looks like it's working fine when modifying the database from 2 different locations.
{ | ||
DatabaseManagerStruct& dbStruct = m_dbList[db]; | ||
|
||
// Never allow saving a locked database; it causes corruption | ||
Q_ASSERT(dbStruct.dbWidget->currentMode() != DatabaseWidget::LockedMode); | ||
// Release build interlock | ||
if (dbStruct.dbWidget->currentMode() == DatabaseWidget::LockedMode) { |
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 if
won't be reached if true since the above assert will abort the execution. Better remove one of them
EDIT: Nevermind, the assert will only be executed in debug mode.
@droidmonkey were you planning to add some tests for that PR? |
I was going to add tests for "concurrent" access of the same file in phase 2 of these changes. Phase 2 is refactoring the saving process entirely to make it asynchronous and robust to file sync services. |
Are you going to add more changes or can this be merged? Tests maybe? |
Its ready for merging. |
OK, please rebase then. |
6209d13
to
1b09b7a
Compare
@droidmonkey can you rebase please? |
1b09b7a
to
0052755
Compare
0052755
to
1a7b874
Compare
- Add support for KDBX 4.0, Argon2 and ChaCha20 [#148, #1179, #1230, #1494] - Add SSH Agent feature [#1098, #1450, #1463] - Add preview panel with details of the selected entry [#879, #1338] - Add more and configurable columns to entry table and allow copying of values by double click [#1305] - Add KeePassXC-Browser API as a replacement for KeePassHTTP [#608] - Deprecate KeePassHTTP [#1392] - Add support for Steam one-time passwords [#1206] - Add support for multiple Auto-Type sequences for a single entry [#1390] - Adjust YubiKey HMAC-SHA1 challenge-response key generation for KDBX 4.0 [#1060] - Replace qHttp with cURL for website icon downloads [#1460] - Remove lock file [#1231] - Add option to create backup file before saving [#1385] - Ask to save a generated password before closing the entry password generator [#1499] - Resolve placeholders recursively [#1078] - Add Auto-Type button to the toolbar [#1056] - Improve window focus handling for Auto-Type dialogs [#1204, #1490] - Auto-Type dialog and password generator can now be exited with ESC [#1252, #1412] - Add optional dark tray icon [#1154] - Add new "Unsafe saving" option to work around saving problems with file sync services [#1385] - Add IBus support to AppImage and additional image formats to Windows builds [#1534, #1537] - Add diceware password generator to CLI [#1406] - Add --key-file option to CLI [#816, #824] - Add DBus interface for opening and closing KeePassXC databases [#283] - Add KDBX compression options to database settings [#1419] - Discourage use of old fixed-length key files in favor of arbitrary files [#1326, #1327] - Correct reference resolution in entry fields [#1486] - Fix window state and recent databases not being remembered on exit [#1453] - Correct history item generation when configuring TOTP for an entry [#1446] - Correct multiple TOTP bugs [#1414] - Automatic saving after every change is now a default [#279] - Allow creation of new entries during search [#1398] - Correct menu issues on macOS [#1335] - Allow compilation on OpenBSD [#1328] - Improve entry attachments view [#1139, #1298] - Fix auto lock for Gnome and Xfce [#910, #1249] - Don't remember key files in file dialogs when the setting is disabled [#1188] - Improve database merging and conflict resolution [#807, #1165] - Fix macOS pasteboard issues [#1202] - Improve startup times on some platforms [#1205] - Hide the notes field by default [#1124] - Toggle main window by clicking tray icon with the middle mouse button [#992] - Fix custom icons not copied over when databases are merged [#1008] - Allow use of DEL key to delete entries [#914] - Correct intermittent crash due to stale history items [#1527] - Sanitize newline characters in title, username and URL fields [#1502] - Reopen previously opened databases in correct order [#774] - Use system's zxcvbn library if available [#701] - Implement various i18n improvements [#690, #875, #1436]
Description
Closes #1002 by completely removing the lock file.
This PR also addresses several issues with file handling and cleans up the code to be more streamlined. One major change includes removing a prompt when locking the databases that would never occur with these corrections in place.
Motivation and context
First step to optimizing the saving of database files and also helps solve concurrent use issues reported.
How has this been tested?
Manually and with existing test cases. Future PR's will introduce testing with multiple clients open accessing the same database to ensure data integrity and accurate prompts.
Types of changes
Checklist:
-DWITH_ASAN=ON
. [REQUIRED]