-
Notifications
You must be signed in to change notification settings - Fork 81
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
Resolve #324: Prevent duplicate org and project names #526
Conversation
This looks _almost_ perfect, but I did find one funny thing. In the project add wizard, you test for project name uniqueness in the second ("add details") step of the wizard. What happens if one user gets to that step in the wizard, enters a unique project name, then goes off and has a cup of tea before finishing up the wizard, while another user creates a project with the same name? In this case, the second user's project creation goes through without problems, but when the first user comes to finally finish the project add wizard, they just get dropped back into the first step of the wizard. There's no visible error message (although I'm assuming an exception got thrown somewhere). The best solution here would probably be to take the user back to step 2 (with an explanatory message), while preserving any choices they'd already made in step 3. So, in this situation, the user would see:
If this is easy to do, this seems like the best approach. If not, and you can think of an easier way (you suggested just deduplicating the name and warning the user, which seems like it might be OK too), then do that, since this is a corner case that may never appear. |
The suggestion of throwing the user back to step 2 seems to be the best solution from the point of view of the user as they are given the chance to choose another name. But I'll have to see if this is easy to implement. I noticed a weird behavior (see new bug #530) and this might affect meta-step 5 mentioned above wherein the permissions selected at meta-step 3 are preserved. So my inclination is to just do the deduplication and message the user after the fact as this seems easier to implement and so that #530 can be fixed separately. |
That sounds like a good plan: go ahead and do the deduplication and I'll look at #530. |
Apparently, the easiest implementation is to throw the user back to step 2. This is actually the built-in behavior of the wizard. At the end of the wizard, everything gets revalidated and the user gets thrown back to the earliest step that failed the revalidation. The problem is, the existing code interferes with this behavior. In I solved this by storing the organization slug into the wizard's Diff for - self.organization = result['details-organization']
+ self.storage.extra_data['organization'] = (
+ result['details-organization']) Diff for - 'organization': self.get_cleaned_data_for_step(
- 'details').get('organization')
+ 'organization': self.storage.extra_data['organization'], Note 1: While it would be nice to provide the user with a "Someone stole your project name!" special message (by storing the fact that the user has already finished step 2 without incident), I think the normal error message is still OK since this event is a rare case anyway. Note 2: I would have liked to create a functional test for this race condition, but our current functional test framework assumes that there is only a single browser instance. To test the race condition properly, we need two instances to simulate the two racing users. And retrofitting our framework now would be too much work. But I think this would be nice to do in the future to test concurrent users scenarios. (Alternatively, we can surreptitiously insert the stealing project name in the database at the appropriate time by using the Django ORM, but I think this is not clean from the functional test point of view.) |
OK, this looks good. You can still get weird behaviour if you have two browser tabs open logged in as the same user, but that's pretty much unavoidable, because we're using session-based storage for the wizard steps. |
Proposed changes in this pull request
unique=True
to thename
field of theOrganization
modelunique_together
constraint for theorganization
andname
fields of theProject
modelRunPython
operations to deduplicate existing data, if any, in the database, one for organization names and the other for project names. The deduplication is based on theSlugModel
algorithm. This migration script was manually tested by running it against the development environment database with the following test data:ProjectAddDetails
andProjectEditDetails
forms. This explicit validation is needed because the wizard nature of these forms prevents theunique_together
validation from working resulting toIntegrityError
exceptionsProjectSerializer
and suppress the automaticunique_together
validation. This explicit validation is needed in place of the implicit validation because the implicit validation does not work due to theorganization
field beingread_only
in the serializer which conflicts with the requirement for implicitunique_together
validation that theunique_together
fields arerequired=True
OrganizationForm
test for adding a new organization with a duplicate nameProjectAddDetails
test for adding a new project with a duplicate name from the same organizationProjectAddDetails
test for adding a new project with a duplicate name from a different organizationProjectEditDetails
test for updating a project with a duplicate name from the same organizationOrganizationSerializer
test for adding a new organization with a duplicate nameOrganizationSerializer
test for updating an organization with a duplicate nameProjectSerializer
test for adding a new project with a duplicate name from the same organizationProjectSerializer
test for adding a new project with a duplicate name from a different organizationProjectSerializer
test for updating a project with a duplicate name from the same organizationOrganizationForm
unit test for testing that the organizationslug
becomes unique because organization names are now required to be unique which prevents the slug deduplication code from actually workingname
validations inOrganizationForm
,OrganizationSerializer
, andProjectSerializer
to also check during organization or project updateProjectEditDetails
OrganizationForm
test for updating an organization with a restricted nameProjectEditDetails
test for updating a project with a restricted nameOrganizationSerializer
test for updating an organization with a restricted nameProjectSerializer
test for updating a project with a restricted nameWhen should this PR be merged
Risks
Follow up actions
migrate
action is needed when you update your local repository