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

Duplicate tag is created upon updating a project #1165

Closed
ifree92 opened this issue Aug 23, 2021 · 3 comments · Fixed by #1329
Closed

Duplicate tag is created upon updating a project #1165

ifree92 opened this issue Aug 23, 2021 · 3 comments · Fixed by #1329

Comments

@ifree92
Copy link

ifree92 commented Aug 23, 2021

Bug with POST /v1/project endpoint.

Current Behavior:

Let's say you have already created a project with a specific tag mytag.
If you will update a project with no changes, e.g. just send back values that are equal to previous, then you will get duplicates.

Steps to Reproduce:

  1. Create a project
curl -X PUT "https://dtrack-api.net/api/v1/project" \
  -H "accept: application/json" \
  -H "X-Api-Key: API_KEY" \
  -H "Content-Type: application/json" \
  -d "{ \"name\": \"my-project\", \"version\": \"1.3.5\", \"classifier\": \"APPLICATION\", \"tags\": [ { \"name\": \"mytag\" } ]}"
  1. Update the project
curl -X POST "https://dtrack-api.net/api/v1/project" \
  -H "accept: application/json" \
  -H "X-Api-Key: API_KEY" \
  -H "Content-Type: application/json" \
  -d "{ \"name\": \"my-project\", \"version\": \"1.3.5\", \"classifier\": \"APPLICATION\", \"uuid\": \"6cb22bed-5f7b-4179-8510-1d7a98d87036\", \"tags\": [ { \"name\": \"mytag\" } ]}"

Response:

{
  "name": "my-project",
  "version": "1.3.5",
  "classifier": "APPLICATION",
  "uuid": "671ce55e-36fb-4a55-96bc-b83736658511",
  "properties": [],
  "tags": [{ "name": "mytag" }],
  "active": true
}
  1. Send update requests one more time
curl -X POST "https://dtrack-api.net/api/v1/project" \
  -H "accept: application/json" \
  -H "X-Api-Key: API_KEY" \
  -H "Content-Type: application/json" \
  -d "{ \"name\": \"my-project\", \"version\": \"1.3.5\", \"classifier\": \"APPLICATION\", \"uuid\": \"6cb22bed-5f7b-4179-8510-1d7a98d87036\", \"tags\": [ { \"name\": \"mytag\" } ]}"

Response:

{
  "name": "my-project",
  "version": "1.3.5",
  "classifier": "APPLICATION",
  "uuid": "671ce55e-36fb-4a55-96bc-b83736658511",
  "properties": [],
  "tags": [{ "name": "mytag" }, { "name": "mytag" }],
  "active": true
}

By repeating (3) that will create tag duplicates. At the moment (after execution 3 commands above), you will get two double mytag tags on the same project.

The same behaviour could be reproduced via UI. Just create a project. Go to project edit, add tag and click on "Update". And then again go to project edit ("View details" button) and just click "Update".

Expected Behavior:

I'm expecting to do not have duplicates.

Environment:

  • Dependency-Track Version: 4.3.2
  • Distribution: Docker
  • Database Server: PostgreSQL
@sephiroth-j
Copy link
Contributor

sephiroth-j commented Jan 12, 2022

Can be reproduced with the following test

package org.dependencytrack.resources.v1;
...
public class ProjectResourceTest extends ResourceTest {
...
	@Test
	public void updateProjectTagsTest()
	{
		var tags = Stream.of("tag1", "tag2").map(qm::createTag).collect(Collectors.toUnmodifiableList());
		var p1 = qm.createProject("ABC", "Test project", "1.0", tags, null, null, true, false);

		var jsonProject = new Project();
		jsonProject.setUuid(p1.getUuid());
		jsonProject.setName(p1.getName());
		jsonProject.setVersion(p1.getVersion());
		jsonProject.setTags(Stream.of("tag1", "tag2", "tag3").map(name ->
		{
			var t = new Tag();
			t.setName(name);
			return t;
		}).collect(Collectors.toUnmodifiableList()));

		// update the 1st time
		Response response = target(V1_PROJECT)
			.request()
			.header(X_API_KEY, apiKey)
			.post(Entity.entity(jsonProject, MediaType.APPLICATION_JSON));
		Assert.assertEquals(200, response.getStatus(), 0);
		JsonObject json = parseJsonObject(response);
		Assert.assertNotNull(json);
		Assert.assertEquals("ABC", json.getString("name"));
		Assert.assertEquals("1.0", json.getString("version"));
		Assert.assertFalse(json.containsKey("description"));
		var jsonTags = json.getJsonArray("tags");
		Assert.assertEquals(3, jsonTags.size());
		Assert.assertEquals("tag1", jsonTags.get(0).asJsonObject().getString("name"));
		Assert.assertEquals("tag2", jsonTags.get(1).asJsonObject().getString("name"));
		Assert.assertEquals("tag3", jsonTags.get(2).asJsonObject().getString("name"));

		// and repeat ... will fail. issue #1165
		response = target(V1_PROJECT)
			.request()
			.header(X_API_KEY, apiKey)
			.post(Entity.entity(jsonProject, MediaType.APPLICATION_JSON));
		json = parseJsonObject(response);
		jsonTags = json.getJsonArray("tags");
		Assert.assertEquals(3, jsonTags.size());
		Assert.assertEquals("tag1", jsonTags.get(0).asJsonObject().getString("name"));
		Assert.assertEquals("tag2", jsonTags.get(1).asJsonObject().getString("name"));
		Assert.assertEquals("tag3", jsonTags.get(2).asJsonObject().getString("name"));
	}
}

@sephiroth-j
Copy link
Contributor

The issues seems to be this code here:

project.setTags(tags);
for (final Tag tag: tags) {
tag.getProjects().add(project);
}

The tags are already associated with the projects through

Afterwards, the project is added to the (new) tags again.

project.setTags(tags);
for (final Tag tag: tags) {
tag.getProjects().add(project);
}

And after the commit


the project has 6 tags instead of 3 with each tag twice.

Will provide a PR to fix this.

sephiroth-j added a commit to sephiroth-j/dependency-track that referenced this issue Jan 13, 2022
Add a project to the list of projects of a tag only if the list does not contain the project yet.

fixes DependencyTrack#1165

Signed-off-by: Ronny Perinke <23166289+sephiroth-j@users.noreply.github.com>
@github-actions
Copy link
Contributor

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 21, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants