Skip to content
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

Merged
merged 4 commits into from
Jan 5, 2018

Conversation

droidmonkey
Copy link
Member

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

  • ✅ Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • ✅ I have read the CONTRIBUTING document. [REQUIRED]
  • ✅ My code follows the code style of this project. [REQUIRED]
  • ✅ All new and existing tests passed. [REQUIRED]
  • ✅ I have compiled and verified my code with -DWITH_ASAN=ON. [REQUIRED]
  • ❌ I have added tests to cover my changes.

@droidmonkey droidmonkey added this to the v2.3.0 milestone Nov 26, 2017
@droidmonkey droidmonkey force-pushed the refactor/remove-lockfile branch from 0490305 to 0afa287 Compare November 26, 2017 23:40
updateTabName(db);
updateLastDatabases(dbStruct.filePath);
updateLastDatabases(dbStruct.fileInfo.absoluteFilePath());
return true;
} else {
return false;
Copy link
Member

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.


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())) {
Copy link
Member

@phoerious phoerious Nov 26, 2017

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);
Copy link
Member

@phoerious phoerious Nov 26, 2017

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?).

Copy link
Member Author

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.

Copy link
Member

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.

Copy link
Member Author

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!

MessageWidget::Error);
// Mark db as modified since existing data may differ from file or file was deleted
m_db->modified();
Copy link
Member

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().

Copy link
Member Author

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.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok.

@droidmonkey droidmonkey force-pushed the refactor/remove-lockfile branch from 6867ef2 to d3153e1 Compare November 27, 2017 03:31
@droidmonkey
Copy link
Member Author

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.

@droidmonkey droidmonkey force-pushed the refactor/remove-lockfile branch 2 times, most recently from 585995f to 8385dbd Compare December 4, 2017 04:08
@droidmonkey
Copy link
Member Author

This is now ready for merge.

@droidmonkey droidmonkey force-pushed the refactor/remove-lockfile branch from 8385dbd to 7e50be2 Compare December 8, 2017 03:13
dbStruct.lockFile = lockFile.take();
updateTabName(db);
updateLastDatabases(dbStruct.filePath);
dbStruct.dbWidget->updateFilename(dbStruct.fileInfo.absoluteFilePath());
Copy link
Member

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?

Copy link
Member Author

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.

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)"),
Copy link
Member

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.

Copy link
Member Author

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;
Copy link
Member

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?

Copy link
Member Author

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).

Copy link
Member

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()) {
Copy link
Member

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?

Copy link
Member Author

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.

@droidmonkey droidmonkey requested review from louib and removed request for TheZ3ro December 20, 2017 15:47
Copy link
Member

@louib louib left a 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) {
Copy link
Contributor

@TheZ3ro TheZ3ro Dec 20, 2017

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.

@louib
Copy link
Member

louib commented Dec 21, 2017

@droidmonkey were you planning to add some tests for that PR?

@phoerious phoerious added the core label Dec 21, 2017
@droidmonkey
Copy link
Member Author

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.

@phoerious
Copy link
Member

Are you going to add more changes or can this be merged? Tests maybe?

@droidmonkey
Copy link
Member Author

Its ready for merging.

@phoerious
Copy link
Member

OK, please rebase then.

@droidmonkey droidmonkey force-pushed the refactor/remove-lockfile branch 2 times, most recently from 6209d13 to 1b09b7a Compare December 28, 2017 22:55
@TheZ3ro
Copy link
Contributor

TheZ3ro commented Jan 4, 2018

@droidmonkey can you rebase please?

@droidmonkey droidmonkey force-pushed the refactor/remove-lockfile branch from 1b09b7a to 0052755 Compare January 4, 2018 23:57
@droidmonkey droidmonkey force-pushed the refactor/remove-lockfile branch from 0052755 to 1a7b874 Compare January 5, 2018 00:09
@droidmonkey droidmonkey merged commit 8f99764 into develop Jan 5, 2018
@droidmonkey droidmonkey deleted the refactor/remove-lockfile branch January 5, 2018 01:55
phoerious added a commit that referenced this pull request Feb 27, 2018
- 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]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Remove lock file support
4 participants