Skip to content

Rejecting updates without a version #36

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

Closed
andybak opened this issue Sep 18, 2014 · 3 comments
Closed

Rejecting updates without a version #36

andybak opened this issue Sep 18, 2014 · 3 comments

Comments

@andybak
Copy link

andybak commented Sep 18, 2014

I haven't looked into the internals to see if this is difficult or even possible - but I'd like to start a discussion on the subject.

I'd like to be able to raise an exception if a versioned instance is modified without supplying a version value. This would close a loophole where there is some method or API call that I've forgotten to update to handle concurrency checks.

Our use case is a large complex codebase where we want to quickly add baseline protection against concurrent updates - a strict 'fail fast' in any situation where there is a potential for conflicts.

@saxix
Copy link
Owner

saxix commented Sep 19, 2014

should not be difficult to implement, I do not have time to make proper tests, anyway take a look at concurrency.core._select_lock() at line 44. value should be None (or 0 if first save).
It's possible to create a flag to enable this check to do not create backward incompatibility. I like the idea and I see the benefits, anyway do not think I have time now to work on that. If you want to create a proper pull request I'll be happy to merge it.

@claytondaley
Copy link
Contributor

+1

Just ran into this issue. A pre-concurrency UI was sending REST requests without a version; no errors were generated and data was overwritten. It seems like a pretty serious bug if you can defeat the entire system through omission.

This strikes me as so serious that I'd recommend a major version change to make the opposite behavior "default". If you insist on persisting a very dangerous condition in the name of backwards compatibility, maybe a setting to override the default?

@claytondaley
Copy link
Contributor

Turns out I had an issue at two different levels:

  1. Django REST Framework (DRF) was not requiring the version (even though it was required in the model) and then was "filling it in" with the value from the database. Obviously, this broke the concurrency check.

I've submitted a ticket at DRF and worked around this issue in my local copy. The logical fix from the perspective of the REST framework was to, at minimum, use the default value (if available) for any value absent in the PUT. The default for these fields is version=0. Unfortunately, that leads to the second issue:

  1. django-concurrency sees the default value and skips version checks here

I'm about to submit a PR that:

  • Creates a settings flag IGNORE_DEFAULT=True
  • Adapts the field logic to check the version unless this flag is enabled

I also had to account for an edge case (documented inline) that can occur during a create. This required a change in the way the logic flowed.

I added a test that failed under the old code. All of the old tests pass except one. As I'll reiterate in the PR, I'm not clear why the test should fail to fix the code. If you can explain, I'll update the PR accordingly.

@saxix saxix closed this as completed in 9154ba8 Jul 15, 2016
saxix added a commit that referenced this issue Jul 15, 2016
* pull-requests/66:
  update CHANGES
  tox.ini: do not install postgis if not  required
  update docs
  - Document new setting  - Fix loaddata test to pass without disabling concurrency  - Remove loaddata test that disable concurrency (now redundant)
  - fixes #36
saxix added a commit that referenced this issue Jul 15, 2016
* release/1.3:
  bump v1.3
  update CHANGES
  tox.ini: do not install postgis if not  required
  update docs
  - Document new setting  - Fix loaddata test to pass without disabling concurrency  - Remove loaddata test that disable concurrency (now redundant)
  - fixes #36
  add default value to ConcurrencyOptions.initial
  add explicit mention to MIT license
  open 1.3 alpha
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants